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",
112 retval = splice(pipe_fd[0], NULL, log_fd, NULL,
115 panic("splice() (to) failed: %s\n", strerror(errno));
116 } while (!terminate);
121 static void copy_kallsyms(void)
127 in_fd = open("/proc/kallsyms", O_RDONLY);
131 out_fd = open("kallsyms", O_CREAT | O_WRONLY | O_TRUNC,
132 S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH);
138 while ((count = read(in_fd, buf, 256)) > 0)
139 write(out_fd, buf, count);
146 panic("copy_kallsyms: %s\n", strerror(errno));
149 int main(int argc, char *argv[])
151 unsigned long nr_cpus;
157 sigemptyset(&signals);
158 sigaddset(&signals, SIGINT);
159 sigaddset(&signals, SIGTERM);
160 pthread_sigmask(SIG_BLOCK, &signals, NULL);
162 nr_cpus = sysconf(_SC_NPROCESSORS_ONLN);
164 readers = calloc(nr_cpus, sizeof(pthread_t));
166 panic("Out of memory!\n");
168 write_str("/sys/kernel/debug/kmemtrace/enabled", "0");
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 printf("Logging... Press Control-C to stop.\n");
185 while (sigwait(&signals, &signal) == 0) {
186 if (signal == SIGINT || signal == SIGTERM)
188 * No synchronization needed, we wait for
195 write_str("/sys/kernel/debug/kmemtrace/enabled", "0");
197 for (i = 0; i < nr_cpus; i++)
198 pthread_join(readers[i], NULL);