2 * Copyright (C) 2008 Pekka Enberg, Eduard - Gabriel Munteanu
4 * This file is released under GPL version 2.
22 #include <sys/types.h>
23 #include <sys/syscall.h>
24 #include <sys/sendfile.h>
28 #include "kmemtrace.h"
30 static volatile int terminate
;
32 static void write_str(const char *filename
, const char *value
)
36 fd
= open(filename
, O_RDWR
);
38 panic("Could not open() file %s: %s\n", filename
, strerror(errno
));
40 if (write(fd
, value
, strlen(value
)) < 0)
41 panic("Could not write() to file %s: %s\n", filename
, strerror(errno
));
46 static int open_channel(int cpu
)
48 char filename
[PATH_MAX
];
51 sprintf(filename
, "/sys/kernel/debug/kmemtrace/cpu%d", cpu
);
52 fd
= open(filename
, O_RDONLY
| O_NONBLOCK
);
54 panic("Could not open() file %s: %s\n", filename
, strerror(errno
));
58 static int open_log(int cpu
)
60 char filename
[PATH_MAX
];
63 sprintf(filename
, "cpu%d.out", cpu
);
64 fd
= open(filename
, O_CREAT
| O_WRONLY
| O_TRUNC
,
65 S_IRUSR
| S_IWUSR
| S_IRGRP
| S_IROTH
);
67 panic("Could not open() file %s: %s\n",
68 filename
, strerror(errno
));
73 static void reader_set_affinity(unsigned long cpu
)
79 CPU_SET(cpu
, &cpumask
);
80 err
= sched_setaffinity(syscall(SYS_gettid
),
81 sizeof(cpu_set_t
), &cpumask
);
84 panic("reader_set_affinity: %s\n", strerror(errno
));
87 static void *reader_thread(void *data
)
89 unsigned long cpu
= (unsigned long) data
;
94 reader_set_affinity(cpu
);
96 relay_fd
= open_channel(cpu
);
97 log_fd
= open_log(cpu
);
100 panic("pipe() failed: %s\n", strerror(errno
));
104 * We don't strip extra features (due to ABI changes) from
105 * events; do that when actually parsing the data.
107 retval
= splice(relay_fd
, NULL
, pipe_fd
[1], NULL
,
110 panic("splice() (from) failed: %s\n",
114 retval
= splice(pipe_fd
[0], NULL
, log_fd
, NULL
,
117 panic("splice() (to) failed: %s\n", strerror(errno
));
118 } while (!terminate
);
123 static void copy_kallsyms(void)
129 in_fd
= open("/proc/kallsyms", O_RDONLY
);
133 out_fd
= open("kallsyms", O_CREAT
| O_WRONLY
| O_TRUNC
,
134 S_IRUSR
| S_IWUSR
| S_IRGRP
| S_IROTH
);
140 while ((count
= read(in_fd
, buf
, 256)) > 0)
141 write(out_fd
, buf
, count
);
148 panic("copy_kallsyms: %s\n", strerror(errno
));
151 int main(int argc
, char *argv
[])
153 unsigned long nr_cpus
;
159 sigemptyset(&signals
);
160 sigaddset(&signals
, SIGINT
);
161 sigaddset(&signals
, SIGTERM
);
162 pthread_sigmask(SIG_BLOCK
, &signals
, NULL
);
164 nr_cpus
= sysconf(_SC_NPROCESSORS_ONLN
);
166 readers
= calloc(nr_cpus
, sizeof(pthread_t
));
168 panic("Out of memory!\n");
170 printf("Copying /proc/kallsyms...\n");
173 for (i
= 0; i
< nr_cpus
; i
++) {
176 err
= pthread_create(&readers
[i
], NULL
, reader_thread
,
179 panic("Could not pthread_create(): %s!\n",
183 write_str("/sys/kernel/debug/kmemtrace/enabled", "1");
185 printf("Logging... Press Control-C to stop.\n");
187 while (sigwait(&signals
, &signal
) == 0) {
188 if (signal
== SIGINT
|| signal
== SIGTERM
)
190 * No synchronization needed, we wait for
197 write_str("/sys/kernel/debug/kmemtrace/enabled", "0");
199 for (i
= 0; i
< nr_cpus
; i
++)
200 pthread_join(readers
[i
], NULL
);