2c64c10e420366879d74cdf2330620cc39b1d285
5 #include <sys/socket.h>
11 #define UNIX_PATH_MAX 108
13 //#define SOCKETDIR "/var/run/ust/socks"
14 #define SOCKETDIR "/tmp/socks"
15 #define SOCKETDIRLEN sizeof(SOCKETDIR)
16 #define USTSIGNAL SIGIO
18 #define DBG(fmt, args...) fprintf(stderr, fmt "\n", ## args)
19 #define WARN(fmt, args...) fprintf(stderr, "usertrace: WARNING: " fmt "\n", ## args)
20 #define ERR(fmt, args...) fprintf(stderr, "usertrace: ERROR: " fmt "\n", ## args)
21 #define PERROR(call) perror("usertrace: ERROR: " call)
23 #define MAX_MSG_SIZE (100)
25 #define MSG_REGISTER_NOTIF 2
27 struct tracecmd
{ /* no padding */
32 //struct listener_arg {
37 /* size: the size of all the fields except size itself */
40 /* Only the necessary part of the payload is transferred. It
41 * may even be none of it.
47 char mysocketfile
[UNIX_PATH_MAX
] = "";
51 static void print_markers(void)
53 struct marker_iter iter
;
55 marker_iter_reset(&iter
);
56 marker_iter_start(&iter
);
59 fprintf(stderr
, "marker: %s_%s \"%s\"\n", iter
.marker
->channel
, iter
.marker
->name
, iter
.marker
->format
);
60 marker_iter_next(&iter
);
64 void do_command(struct tracecmd
*cmd
)
68 void receive_commands()
78 /* FIXME: fd_notif should probably be protected by a spinlock */
84 msg
.size
= sizeof(msg
.type
);
86 /* FIXME: don't block here */
87 result
= write(fd_notif
, &msg
, msg
.size
+sizeof(msg
.size
));
96 int listener_main(void *p
)
102 struct sockaddr_un addr
;
103 socklen_t addrlen
= sizeof(addr
);
104 char trace_name
[] = "auto";
105 char trace_type
[] = "ustrelay";
108 struct trctl_msg msg
;
111 result
= len
= recvfrom(pfd
, recvbuf
, sizeof(recvbuf
), 0, &addr
, &addrlen
);
117 if(recvbuf
[len
-1] == '\n')
118 recvbuf
[len
-1] = '\0';
120 fprintf(stderr
, "received a message! it's: %s\n", recvbuf
);
123 if(!strcmp(recvbuf
, "print_markers")) {
126 else if(!strcmp(recvbuf
, "trace_setup")) {
129 result
= ltt_trace_setup(trace_name
);
131 ERR("ltt_trace_setup failed");
135 result
= ltt_trace_set_type(trace_name
, trace_type
);
137 ERR("ltt_trace_set_type failed");
141 else if(!strcmp(recvbuf
, "trace_alloc")) {
144 result
= ltt_trace_alloc(trace_name
);
146 ERR("ltt_trace_alloc failed");
150 else if(!strcmp(recvbuf
, "trace_start")) {
153 result
= ltt_trace_start(trace_name
);
155 ERR("ltt_trace_start failed");
159 else if(!strcmp(recvbuf
, "trace_stop")) {
162 result
= ltt_trace_stop(trace_name
);
164 ERR("ltt_trace_stop failed");
168 else if(!strcmp(recvbuf
, "trace_destroy")) {
170 DBG("trace destroy");
172 result
= ltt_trace_destroy(trace_name
);
174 ERR("ltt_trace_destroy failed");
183 void create_listener(void)
186 static char listener_stack
[16384];
188 result
= clone(listener_main
, listener_stack
+sizeof(listener_stack
)-1, CLONE_FS
| CLONE_FILES
| CLONE_VM
| CLONE_SIGHAND
| CLONE_THREAD
, NULL
);
194 /* The signal handler itself. */
196 void sighandler(int sig
)
202 /* Called by the app signal handler to chain it to us. */
204 void chain_signal(void)
206 sighandler(USTSIGNAL
);
209 static int init_socket(void)
216 struct sockaddr_un addr
;
218 result
= fd
= socket(PF_UNIX
, SOCK_DGRAM
, 0);
224 addr
.sun_family
= AF_UNIX
;
226 result
= snprintf(addr
.sun_path
, UNIX_PATH_MAX
, "%s/%d", SOCKETDIR
, mypid
);
227 if(result
>= UNIX_PATH_MAX
) {
228 ERR("string overflow allocating socket name");
231 //DBG("opening socket at %s", addr.sun_path);
233 result
= bind(fd
, (struct sockaddr
*)&addr
, sizeof(addr
));
239 strcpy(mysocketfile
, addr
.sun_path
);
250 static void destroy_socket(void)
254 if(mysocketfile
[0] == '\0')
257 result
= unlink(mysocketfile
);
263 static int init_signal_handler(void)
265 /* Attempt to handler SIGIO. If the main program wants to
266 * handle it, fine, it'll override us. They it'll have to
267 * use the chaining function.
271 struct sigaction act
;
273 result
= sigemptyset(&act
.sa_mask
);
275 PERROR("sigemptyset");
279 act
.sa_handler
= sighandler
;
280 act
.sa_flags
= SA_RESTART
;
282 /* Only defer ourselves. Also, try to restart interrupted
283 * syscalls to disturb the traced program as little as possible.
285 result
= sigaction(SIGIO
, &act
, NULL
);
294 static void __attribute__((constructor
)) init()
300 if(getenv("UST_TRACE")) {
301 char trace_name
[] = "auto";
302 char trace_type
[] = "ustrelay";
304 DBG("starting early tracing");
306 /* Ensure marker control is initialized */
307 init_marker_control();
309 /* Ensure relay is initialized */
310 init_ustrelay_transport();
312 /* Ensure markers are initialized */
315 result
= ltt_marker_connect("foo", "bar", "default");
317 ERR("ltt_marker_connect");
319 result
= ltt_marker_connect("foo", "bar2", "default");
321 ERR("ltt_marker_connect");
323 result
= ltt_trace_setup(trace_name
);
325 ERR("ltt_trace_setup failed");
329 result
= ltt_trace_set_type(trace_name
, trace_type
);
331 ERR("ltt_trace_set_type failed");
335 result
= ltt_trace_alloc(trace_name
);
337 ERR("ltt_trace_alloc failed");
341 result
= ltt_trace_start(trace_name
);
343 ERR("ltt_trace_start failed");
348 /* Must create socket before signal handler to prevent races
351 result
= init_socket();
353 ERR("init_socket error");
356 result
= init_signal_handler();
358 ERR("init_signal_handler error");
364 /* should decrementally destroy stuff if error */
368 /* This is only called if we terminate normally, not with an unhandled signal,
369 * so we cannot rely on it. */
371 static void __attribute__((destructor
)) fini()
This page took 0.067067 seconds and 4 git commands to generate.