opcontrol.cpp revision 48ae5fc270ea3bbb965b4bd07cb1691a5c115642
1/*
2 * opcontrol/opcontrol.cpp
3 */
4
5#include "op_config.h"
6
7#include <stdlib.h>
8#include <fcntl.h>
9#include <stdio.h>
10#include <string.h>
11#include <unistd.h>
12#include <errno.h>
13#include <assert.h>
14#include <dirent.h>
15#include <sys/stat.h>
16
17static int usage(const char* name);
18static int echo(const char* str, const char* file);
19static int read_num(const char* file);
20
21static int start_profiler(int argc, char const * argv[]);
22static int stop_profiler();
23static int reset_profiler();
24static int status_profiler();
25
26int main(int argc, char const * argv[])
27{
28    if (argc < 2)
29        return usage(argv[0]);
30
31    const char* tool = argv[1];
32
33    int ret = 0;
34    if (!strcmp("start", tool))        ret = start_profiler(argc-2, argv+2);
35    else if (!strcmp("stop", tool))    ret = stop_profiler();
36    else if (!strcmp("reset", tool))   ret = reset_profiler();
37    else if (!strcmp("status", tool))  ret = status_profiler();
38
39    return ret ? usage(argv[0]) : 0;
40}
41
42int usage(const char* name)
43{
44    printf("usage: %s [start [-e event][-p type][-c depth][-i names]"
45            " | stop | reset | status]\n", name);
46    return 0;
47}
48
49
50int start_profiler(int argc, char const * argv[])
51{
52    char const* backtrace_depth = "0";
53    if (argc&1)
54        return -1;
55
56    while (argc>0) {
57        if (!strcmp("-c", argv[0]))
58            backtrace_depth = argv[1];
59        else if (!strcmp("-p", argv[0]))
60            ; // type
61        else if (!strcmp("-e", argv[0]))
62            ; // event
63        else if (!strcmp("-i", argv[0]))
64            ; // images
65        argc-=2;
66        argv+=2;
67    }
68
69    int err;
70
71    err = echo(backtrace_depth, OP_DRIVER_BASE"/backtrace_depth");
72    if (err) {
73        printf("couldn't set backtrace depth. backtraces disabled.\n");
74    }
75
76    err = echo("1", OP_DRIVER_BASE"/enable");
77    if (err) {
78        printf("couldn't start profiling, is the oprofile driver installed?\n");
79        return -1;
80    }
81
82    // XXX: start daemon with all good options ...
83
84    mkdir(OP_BASE_DIR, 644);
85    return 0;
86}
87
88int stop_profiler()
89{
90    int dump, stop;
91    dump = echo("1", OP_DRIVER_BASE"/dump");
92        // XXX: should wait for complete_dump
93    usleep(250000);
94    stop = echo("0", OP_DRIVER_BASE"/enable");
95    if (dump || stop) {
96        printf("couldn't stop profiling, is the oprofile driver installed?\n");
97        return -1;
98    }
99    int num = read_num(OP_DRIVER_BASE"/stats/cpu0/sample_received");
100    printf("profiler stopped with %u samples received\n", num);
101    return 0;
102}
103
104int rm_dir_content(const char* path)
105{
106    DIR* d = opendir(path);
107    if (d) {
108        struct dirent* de;
109        while ((de = readdir(d))) {
110            if(de->d_name[0] == '.') continue;
111            struct stat s;
112            char* tmp = (char*)malloc(strlen(path)+strlen(de->d_name)+2);
113            if (tmp) {
114                sprintf(tmp, "%s/%s", path, de->d_name);
115                if (lstat(tmp, &s) == 0) {
116                    int mode = s.st_mode & S_IFMT;
117                    if (mode == S_IFDIR) {
118                        rm_dir_content(tmp);
119                        rmdir(tmp);
120                    } else if (mode == S_IFLNK) {
121                    } else if (mode == S_IFSOCK) {
122                    } else if (mode == S_IFREG) {
123                        unlink(tmp);
124                    }
125                }
126                free(tmp);
127            }
128        }
129        closedir(d);
130    }
131    return 0;
132}
133
134int reset_profiler()
135{
136    echo("1", OP_DRIVER_BASE"/dump");
137    usleep(250000);
138    // should erase all samples
139    rm_dir_content(OP_BASE_DIR);
140    return 0;
141}
142
143
144int status_profiler()
145{
146    int num = read_num(OP_DRIVER_BASE"/enable");
147    if (num >= 0) {
148        printf("profiler %s\n", num ? "started" : "not started");
149        num = read_num(OP_DRIVER_BASE"/stats/cpu0/sample_received");
150        printf("  %9u samples received\n", num);
151        num = read_num(OP_DRIVER_BASE"/stats/cpu0/backtrace_aborted");
152        printf("  %9u backtrace aborted\n", num);
153        num = read_num(OP_DRIVER_BASE"/stats/cpu0/sample_lost_overflow");
154        printf("  %9u samples lost overflow\n", num);
155        num = read_num(OP_DRIVER_BASE"/backtrace_depth");
156        printf("  %9u backtrace_depth\n", num);
157        return 0;
158    }
159    printf("couldn't get profiling status, is the oprofile driver installed?\n");
160    return -1;
161
162}
163
164int echo(const char* str, const char* file)
165{
166    int fd = open(file, O_WRONLY);
167    if (fd<0)
168        return fd;
169    write(fd, str, strlen(str));
170    close(fd);
171    return 0;
172}
173
174int read_num(const char* file)
175{
176    char buffer[256];
177    int fd = open(file, O_RDONLY);
178    if (fd<0) return -1;
179    int rd = read(fd, buffer, sizeof(buffer)-1);
180    buffer[rd] = 0;
181    return atoi(buffer);
182}
183
184