Merge tag 'v3.14.25' into backport/v3.14.24-ltsi-rc1+v3.14.25/snapshot-merge.wip
[platform/adaptation/renesas_rcar/renesas_kernel.git] / drivers / staging / ktap / userspace / eventdef.c
1 /*
2  * eventdef.c - ktap eventdef parser
3  *
4  * This file is part of ktap by Jovi Zhangwei.
5  *
6  * Copyright (C) 2012-2013 Jovi Zhangwei <jovi.zhangwei@gmail.com>.
7  *
8  * ktap is free software; you can redistribute it and/or modify it
9  * under the terms and conditions of the GNU General Public License,
10  * version 2, as published by the Free Software Foundation.
11  *
12  * ktap is distributed in the hope it will be useful, but WITHOUT
13  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
14  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
15  * more details.
16  *
17  * You should have received a copy of the GNU General Public License along with
18  * this program; if not, write to the Free Software Foundation, Inc.,
19  * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
20  */
21
22 #include <unistd.h>
23 #include <stdio.h>
24 #include <stdlib.h>
25 #include <string.h>
26 #include <dirent.h>
27 #include <fcntl.h>
28
29 #include "../include/ktap_types.h"
30 #include "../include/ktap_opcodes.h"
31 #include "ktapc.h"
32 #include "symbol.h"
33
34 #define TRACING_EVENTS_DIR "/sys/kernel/debug/tracing/events"
35
36 static u8 *idmap;
37 static int idmap_size = 1024; /* set init size */
38 static int id_nr = 0;
39
40 static int idmap_init(void)
41 {
42         idmap = malloc(idmap_size);
43         if (!idmap)
44                 return -1;
45
46         memset(idmap, 0, idmap_size);
47         return 0;
48 }
49
50 static void idmap_free(void)
51 {
52         free(idmap);
53 }
54
55 static inline int idmap_is_set(int id)
56 {
57         return idmap[id / 8] & (1 << (id % 8));
58 }
59
60 static void idmap_set(int id)
61 {
62         if (id >= idmap_size * 8) {
63                 int newsize = id + 100; /* allocate extra 800 id */
64                 idmap = realloc(idmap, newsize);
65                 memset(idmap + idmap_size, 0, newsize - idmap_size);
66                 idmap_size = newsize;
67         }
68
69         if (!idmap_is_set(id))
70                 id_nr++;
71
72         idmap[id / 8] = idmap[id / 8] | (1 << (id % 8));
73 }
74
75 static void idmap_clear(int id)
76 {
77         id_nr--;
78         idmap[id / 8] = idmap[id / 8] & ~ (1 << (id % 8));
79 }
80
81 static int idmap_get_max_id(void)
82 {
83         return idmap_size * 8;
84 }
85
86 static int *get_id_array()
87 {
88         int *id_array;
89         int i, j = 0;
90
91         id_array = malloc(sizeof(int) * id_nr);
92         if (!id_array)
93                 return NULL;
94
95         for (i = 0; i < idmap_get_max_id(); i++) {
96                 if (idmap_is_set(i))
97                         id_array[j++] = i;
98         }
99
100         return id_array;
101 }
102
103 static int add_event(char *evtid_path)
104 {
105         char id_buf[24];
106         int id, fd;
107
108         fd = open(evtid_path, O_RDONLY);
109         if (fd < 0) {
110                 /*
111                  * some tracepoint doesn't have id file, like ftrace,
112                  * return success in here, and don't print error.
113                  */
114                 verbose_printf("warning: cannot open file %s\n", evtid_path);
115                 return 0;
116         }
117
118         if (read(fd, id_buf, sizeof(id_buf)) < 0) {
119                 fprintf(stderr, "read file error %s\n", evtid_path);
120                 close(fd);
121                 return -1;
122         }
123
124         id = atoll(id_buf);
125
126         idmap_set(id);
127
128         close(fd);
129         return 0;
130 }
131
132 static int add_tracepoint(char *sys_name, char *evt_name)
133 {
134         char evtid_path[PATH_MAX] = {0};
135
136
137         snprintf(evtid_path, PATH_MAX, "%s/%s/%s/id", TRACING_EVENTS_DIR,
138                                         sys_name, evt_name);
139         return add_event(evtid_path);
140 }
141
142 static int add_tracepoint_multi_event(char *sys_name, char *evt_name)
143 {
144         char evt_path[PATH_MAX];
145         struct dirent *evt_ent;
146         DIR *evt_dir;
147         int ret = 0;
148
149         snprintf(evt_path, PATH_MAX, "%s/%s", TRACING_EVENTS_DIR, sys_name);
150         evt_dir = opendir(evt_path);
151         if (!evt_dir) {
152                 perror("Can't open event dir");
153                 return -1;
154         }
155
156         while (!ret && (evt_ent = readdir(evt_dir))) {
157                 if (!strcmp(evt_ent->d_name, ".")
158                     || !strcmp(evt_ent->d_name, "..")
159                     || !strcmp(evt_ent->d_name, "enable")
160                     || !strcmp(evt_ent->d_name, "filter"))
161                         continue;
162
163                 if (!strglobmatch(evt_ent->d_name, evt_name))
164                         continue;
165
166                 ret = add_tracepoint(sys_name, evt_ent->d_name);
167         }
168
169         closedir(evt_dir);
170         return ret;
171 }
172
173 static int add_tracepoint_event(char *sys_name, char *evt_name)
174 {
175         return strpbrk(evt_name, "*?") ?
176                add_tracepoint_multi_event(sys_name, evt_name) :
177                add_tracepoint(sys_name, evt_name);
178 }
179
180 static int add_tracepoint_multi_sys(char *sys_name, char *evt_name)
181 {
182         struct dirent *events_ent;
183         DIR *events_dir;
184         int ret = 0;
185
186         events_dir = opendir(TRACING_EVENTS_DIR);
187         if (!events_dir) {
188                 perror("Can't open event dir");
189                 return -1;
190         }
191
192         while (!ret && (events_ent = readdir(events_dir))) {
193                 if (!strcmp(events_ent->d_name, ".")
194                     || !strcmp(events_ent->d_name, "..")
195                     || !strcmp(events_ent->d_name, "enable")
196                     || !strcmp(events_ent->d_name, "header_event")
197                     || !strcmp(events_ent->d_name, "header_page"))
198                         continue;
199
200                 if (!strglobmatch(events_ent->d_name, sys_name))
201                         continue;
202
203                 ret = add_tracepoint_event(events_ent->d_name,
204                                            evt_name);
205         }
206
207         closedir(events_dir);
208         return ret;
209 }
210
211 static int parse_events_add_tracepoint(char *sys, char *event)
212 {
213         if (strpbrk(sys, "*?"))
214                 return add_tracepoint_multi_sys(sys, event);
215         else
216                 return add_tracepoint_event(sys, event);
217 }
218
219 enum {
220         KPROBE_EVENT,
221         UPROBE_EVENT,
222 };
223
224 struct probe_list {
225         struct probe_list *next;
226         int type;
227         char event[64];
228 };
229
230 static struct probe_list *probe_list_head; /* for cleanup resources */
231
232 /*
233  * Some symbol format cannot write to uprobe_events in debugfs, like:
234  * symbol "check_one_fd.part.0" in glibc.
235  * For those symbols, we change the format, get rid of invalid chars,
236  * "check_one_fd.part.0" -> "check_one_fd"
237  *
238  * This function copy is_good_name function in linux/kernel/trace/trace_probe.h
239  */
240 static char *format_symbol_name(const char *old_symbol)
241 {
242         char *new_name = strdup(old_symbol);
243         char *name = new_name;
244
245         if (!isalpha(*name) && *name != '_')
246                 *name = '\0';
247
248         while (*++name != '\0') {
249                 if (!isalpha(*name) && !isdigit(*name) && *name != '_') {
250                         *name = '\0';
251                         break;
252                 }
253         }
254
255         /* this is a good name */
256         return new_name;
257 }
258
259
260 #define KPROBE_EVENTS_PATH "/sys/kernel/debug/tracing/kprobe_events"
261
262 /**
263  * @return 0 on success, otherwise -1
264  */
265 static int
266 write_kprobe_event(int fd, int ret_probe, const char *symbol, char *fetch_args)
267 {
268         char probe_event[128] = {0};
269         char event[64] = {0};
270         struct probe_list *pl;
271         char event_id_path[128] = {0};
272         char *symbol_name;
273         int id_fd, ret;
274
275         /* In case some symbols cannot write to uprobe_events debugfs file */
276         symbol_name = format_symbol_name(symbol);
277
278         if (!fetch_args)
279                 fetch_args = " ";
280
281         if (ret_probe) {
282                 snprintf(event, 64, "ktap_kprobes_%d/ret_%s",
283                          getpid(), symbol_name);
284                 snprintf(probe_event, 128, "r:%s %s %s",
285                          event, symbol, fetch_args);
286         } else {
287                 snprintf(event, 64, "ktap_kprobes_%d/%s",
288                          getpid(), symbol_name);
289                 snprintf(probe_event, 128, "p:%s %s %s",
290                          event, symbol, fetch_args);
291         }
292
293         sprintf(event_id_path, "/sys/kernel/debug/tracing/events/%s/id", event);
294         /* if event id already exist, then don't write to kprobes_event again */
295         id_fd = open(event_id_path, O_RDONLY);
296         if (id_fd > 0) {
297                 close(id_fd);
298
299                 /* remember add event id to ids_array */
300                 ret = add_event(event_id_path);
301                 if (ret)
302                         goto error;
303
304                 goto out;
305         }
306
307         verbose_printf("write kprobe event %s\n", probe_event);
308
309         if (write(fd, probe_event, strlen(probe_event)) <= 0) {
310                 fprintf(stderr, "Cannot write %s to %s\n", probe_event,
311                                 KPROBE_EVENTS_PATH);
312                 goto error;
313         }
314
315         /* add to cleanup list */
316         pl = malloc(sizeof(struct probe_list));
317         if (!pl)
318                 goto error;
319
320         pl->type = KPROBE_EVENT;
321         pl->next = probe_list_head;
322         memcpy(pl->event, event, 64);
323         probe_list_head = pl;
324
325         ret = add_event(event_id_path);
326         if (ret < 0)
327                 goto error;
328
329  out:
330         free(symbol_name);
331         return 0;
332
333  error:
334         free(symbol_name);
335         return -1;
336 }
337
338 static unsigned long core_kernel_text_start;
339 static unsigned long core_kernel_text_end;
340 static unsigned long kprobes_text_start;
341 static unsigned long kprobes_text_end;
342
343 static void init_kprobe_prohibited_area(void)
344 {
345         static int once = 0;
346
347         if (once > 0)
348                 return;
349
350         once = 1;
351
352         core_kernel_text_start = find_kernel_symbol("_stext");
353         core_kernel_text_end   = find_kernel_symbol("_etext");
354         kprobes_text_start     = find_kernel_symbol("__kprobes_text_start");
355         kprobes_text_end       = find_kernel_symbol("__kprobes_text_end");
356 }
357
358 static int check_kprobe_addr_prohibited(unsigned long addr)
359 {
360         if (addr <= core_kernel_text_start || addr >= core_kernel_text_end)
361                 return -1;
362
363         if (addr >= kprobes_text_start && addr <= kprobes_text_end)
364                 return -1;
365
366         return 0;
367 }
368
369 struct probe_cb_base {
370         int fd;
371         int ret_probe;
372         const char *event;
373         char *binary;
374         char *symbol;
375         char *fetch_args;
376 };
377
378 static int kprobe_symbol_actor(void *arg, const char *name, char type,
379                                unsigned long start)
380 {
381         struct probe_cb_base *base = (struct probe_cb_base *)arg;
382
383         /* only can probe text function */
384         if (type != 't' && type != 'T')
385                 return 0;
386
387         if (!strglobmatch(name, base->symbol))
388                 return 0;
389
390         if (check_kprobe_addr_prohibited(start))
391                 return 0;
392
393         return write_kprobe_event(base->fd, base->ret_probe, name,
394                                   base->fetch_args);
395 }
396
397 static int parse_events_add_kprobe(char *event)
398 {
399         char *symbol, *end;
400         struct probe_cb_base base;
401         int fd, ret;
402
403         fd = open(KPROBE_EVENTS_PATH, O_WRONLY);
404         if (fd < 0) {
405                 fprintf(stderr, "Cannot open %s\n", KPROBE_EVENTS_PATH);
406                 return -1;
407         }
408
409         end = strpbrk(event, "% ");
410         if (end)
411                 symbol = strndup(event, end - event);
412         else
413                 symbol = strdup(event);
414
415         base.fd = fd;
416         base.ret_probe = !!strstr(event, "%return");
417         base.symbol = symbol;
418         base.fetch_args = strchr(event, ' ');
419
420         init_kprobe_prohibited_area();
421
422         ret = kallsyms_parse(&base, kprobe_symbol_actor);
423         if (ret < 0)
424                 fprintf(stderr, "cannot parse symbol \"%s\"\n", symbol);
425
426         free(symbol);
427         close(fd);
428
429         return ret;
430 }
431
432 #define UPROBE_EVENTS_PATH "/sys/kernel/debug/tracing/uprobe_events"
433
434 /**
435  * @return 0 on success, otherwise -1
436  */
437 static int
438 write_uprobe_event(int fd, int ret_probe, const char *binary,
439                    const char *symbol, unsigned long addr,
440                    char *fetch_args)
441 {
442         char probe_event[128] = {0};
443         char event[64] = {0};
444         struct probe_list *pl;
445         char event_id_path[128] = {0};
446         char *symbol_name;
447         int id_fd, ret;
448
449         /* In case some symbols cannot write to uprobe_events debugfs file */
450         symbol_name = format_symbol_name(symbol);
451
452         if (!fetch_args)
453                 fetch_args = " ";
454
455         if (ret_probe) {
456                 snprintf(event, 64, "ktap_uprobes_%d/ret_%s",
457                          getpid(), symbol_name);
458                 snprintf(probe_event, 128, "r:%s %s:0x%lx %s",
459                          event, binary, addr, fetch_args);
460         } else {
461                 snprintf(event, 64, "ktap_uprobes_%d/%s",
462                          getpid(), symbol_name);
463                 snprintf(probe_event, 128, "p:%s %s:0x%lx %s",
464                          event, binary, addr, fetch_args);
465         }
466
467         sprintf(event_id_path, "/sys/kernel/debug/tracing/events/%s/id", event);
468         /* if event id already exist, then don't write to uprobes_event again */
469         id_fd = open(event_id_path, O_RDONLY);
470         if (id_fd > 0) {
471                 close(id_fd);
472
473                 /* remember add event id to ids_array */
474                 ret = add_event(event_id_path);
475                 if (ret)
476                         goto error;
477
478                 goto out;
479         }
480
481         verbose_printf("write uprobe event %s\n", probe_event);
482
483         if (write(fd, probe_event, strlen(probe_event)) <= 0) {
484                 fprintf(stderr, "Cannot write %s to %s\n", probe_event,
485                                 UPROBE_EVENTS_PATH);
486                 goto error;
487         }
488
489         /* add to cleanup list */
490         pl = malloc(sizeof(struct probe_list));
491         if (!pl)
492                 goto error;
493
494         pl->type = UPROBE_EVENT;
495         pl->next = probe_list_head;
496         memcpy(pl->event, event, 64);
497         probe_list_head = pl;
498
499         ret = add_event(event_id_path);
500         if (ret < 0)
501                 goto error;
502
503  out:
504         free(symbol_name);
505         return 0;
506
507  error:
508         free(symbol_name);
509         return -1;
510 }
511
512 /**
513  * TODO: avoid copy-paste stuff
514  *
515  * @return 1 on success, otherwise 0
516  */
517 #ifdef NO_LIBELF
518 static int parse_events_resolve_symbol(int fd, char *event, int type)
519 {
520         char *colon, *binary, *fetch_args;
521         unsigned long symbol_address;
522
523         colon = strchr(event, ':');
524         if (!colon)
525                 return -1;
526
527         symbol_address = strtol(colon + 1 /* skip ":" */, NULL, 0);
528
529         fetch_args = strchr(event, ' ');
530
531         /**
532          * We already have address, no need in resolving.
533          */
534         if (symbol_address) {
535                 int ret;
536
537                 binary = strndup(event, colon - event);
538                 ret = write_uprobe_event(fd, !!strstr(event, "%return"), binary,
539                                          "NULL", symbol_address, fetch_args);
540                 free(binary);
541                 return ret;
542         }
543
544         fprintf(stderr, "error: cannot resolve event \"%s\" without libelf, "
545                         "please recompile ktap with NO_LIBELF disabled\n",
546                         event);
547         exit(EXIT_FAILURE);
548         return -1;
549 }
550
551 #else
552 static int uprobe_symbol_actor(const char *name, vaddr_t addr, void *arg)
553 {
554         struct probe_cb_base *base = (struct probe_cb_base *)arg;
555         int ret;
556
557         if (!strglobmatch(name, base->symbol))
558                 return 0;
559
560         verbose_printf("uprobe: binary: \"%s\" symbol \"%s\" "
561                         "resolved to 0x%lx\n",
562                         base->binary, base->symbol, addr);
563
564         ret = write_uprobe_event(base->fd, base->ret_probe, base->binary,
565                                  name, addr, base->fetch_args);
566         if (ret)
567                 return ret;
568
569         return 0;
570 }
571
572 static int parse_events_resolve_symbol(int fd, char *event, int type)
573 {
574         char *colon, *end;
575         vaddr_t symbol_address;
576         int ret;
577         struct probe_cb_base base = {
578                 .fd = fd,
579                 .event = event
580         };
581
582         colon = strchr(event, ':');
583         if (!colon)
584                 return 0;
585
586         base.ret_probe = !!strstr(event, "%return");
587         symbol_address = strtol(colon + 1 /* skip ":" */, NULL, 0);
588         base.binary = strndup(event, colon - event);
589
590         base.fetch_args = strchr(event, ' ');
591
592         /*
593          * We already have address, no need in resolving.
594          */
595         if (symbol_address) {
596                 int ret;
597                 ret = write_uprobe_event(fd, base.ret_probe, base.binary,
598                                          "NULL", symbol_address,
599                                          base.fetch_args);
600                 free(base.binary);
601                 return ret;
602         }
603
604         end = strpbrk(event, "% ");
605         if (end)
606                 base.symbol = strndup(colon + 1, end - 1 - colon);
607         else
608                 base.symbol = strdup(colon + 1);
609
610         ret = parse_dso_symbols(base.binary, type, uprobe_symbol_actor,
611                                 (void *)&base);
612         if (!ret) {
613                 fprintf(stderr, "error: cannot find symbol %s in binary %s\n",
614                         base.symbol, base.binary);
615                 ret = -1;
616         } else if(ret > 0) {
617                 /* no error found when parse symbols */
618                 ret = 0;
619         }
620
621         free(base.binary);
622         free(base.symbol);
623
624         return ret;
625 }
626 #endif
627
628 static int parse_events_add_uprobe(char *old_event, int type)
629 {
630         int ret;
631         int fd;
632
633         fd = open(UPROBE_EVENTS_PATH, O_WRONLY);
634         if (fd < 0) {
635                 fprintf(stderr, "Cannot open %s\n", UPROBE_EVENTS_PATH);
636                 return -1;
637         }
638
639         ret = parse_events_resolve_symbol(fd, old_event, type);
640
641         close(fd);
642         return ret;
643 }
644
645 static int parse_events_add_probe(char *old_event)
646 {
647         char *separator;
648
649         separator = strchr(old_event, ':');
650         if (!separator || (separator == old_event))
651                 return parse_events_add_kprobe(old_event);
652         else
653                 return parse_events_add_uprobe(old_event, FIND_SYMBOL);
654 }
655
656 static int parse_events_add_sdt(char *old_event)
657 {
658         return parse_events_add_uprobe(old_event, FIND_STAPSDT_NOTE);
659 }
660
661 static void strim(char *s)
662 {
663         size_t size;
664         char *end;
665
666         size = strlen(s);
667         if (!size)
668                 return;
669
670         end = s + size -1;
671         while (end >= s && isspace(*end))
672                 end--;
673
674         *(end + 1) = '\0';
675 }
676
677 static int get_sys_event_filter_str(char *start,
678                                     char **sys, char **event, char **filter)
679 {
680         char *separator, *separator2, *ptr, *end;
681
682         while (*start == ' ')
683                 start++;
684
685         /* find sys */
686         separator = strchr(start, ':');
687         if (!separator || (separator == start)) {
688                 return -1;
689         }
690
691         ptr = malloc(separator - start + 1);
692         if (!ptr)
693                 return -1;
694
695         strncpy(ptr, start, separator - start);
696         ptr[separator - start] = '\0';
697
698         strim(ptr);
699         *sys = ptr;
700
701         if (!strcmp(*sys, "probe") && (*(separator + 1) == '/')) {
702                 /* it's uprobe event */
703                 separator2 = strchr(separator + 1, ':');
704                 if (!separator2)
705                         return -1;
706         } else
707                 separator2 = separator;
708
709         /* find filter */
710         end = start + strlen(start);
711         while (*--end == ' ') {
712         }
713
714         if (*end == '/') {
715                 char *filter_start;
716
717                 filter_start = strchr(separator2, '/');
718                 if (filter_start == end)
719                         return -1;
720
721                 ptr = malloc(end - filter_start + 2);
722                 if (!ptr)
723                         return -1;
724
725                 memcpy(ptr, filter_start, end - filter_start + 1);
726                 ptr[end - filter_start + 1] = '\0';
727
728                 *filter = ptr;
729
730                 end = filter_start;
731         } else {
732                 *filter = NULL;
733                 end++;
734         }
735
736         /* find event */
737         ptr = malloc(end - separator);
738         if (!ptr)
739                 return -1;
740
741         memcpy(ptr, separator + 1, end - separator - 1);
742         ptr[end - separator - 1] = '\0';
743
744         strim(ptr);
745         *event = ptr;
746
747         return 0;
748 }
749
750 static char *get_next_eventdef(char *str)
751 {
752         char *separator;
753
754         separator = strchr(str, ',');
755         if (!separator)
756                 return str + strlen(str);
757
758         *separator = '\0';
759         return separator + 1;
760 }
761
762 ktap_eventdef_info *ktapc_parse_eventdef(const char *eventdef)
763 {
764         char *str = strdup(eventdef);
765         char *sys, *event, *filter, *next;
766         ktap_eventdef_info *evdef_info;
767         int ret;
768
769         idmap_init();
770
771  parse_next_eventdef:
772         next = get_next_eventdef(str);
773
774         if (get_sys_event_filter_str(str, &sys, &event, &filter))
775                 goto error;
776
777         verbose_printf("parse_eventdef: sys[%s], event[%s], filter[%s]\n",
778                        sys, event, filter);
779
780         if (!strcmp(sys, "probe"))
781                 ret = parse_events_add_probe(event);
782         else if (!strcmp(sys, "sdt"))
783                 ret = parse_events_add_sdt(event);
784         else
785                 ret = parse_events_add_tracepoint(sys, event);
786
787         if (ret)
788                 goto error;
789
790         /* don't trace ftrace:function when all tracepoints enabled */
791         if (!strcmp(sys, "*"))
792                 idmap_clear(1);
793
794
795         if (filter && *next != '\0') {
796                 fprintf(stderr, "Error: eventdef only can append one filter\n");
797                 goto error;
798         }
799
800         str = next;
801         if (*next != '\0')
802                 goto parse_next_eventdef;
803
804         evdef_info = malloc(sizeof(*evdef_info));
805         if (!evdef_info)
806                 goto error;
807
808         evdef_info->nr = id_nr;
809         evdef_info->id_arr = get_id_array();
810         evdef_info->filter = filter;
811
812         idmap_free();
813         return evdef_info;
814  error:
815         idmap_free();
816         cleanup_event_resources();
817         return NULL;
818 }
819
820 void cleanup_event_resources(void)
821 {
822         struct probe_list *pl;
823         const char *path;
824         char probe_event[128] = {0};
825         int fd, ret;
826
827         for (pl = probe_list_head; pl; pl = pl->next) {
828                 if (pl->type == KPROBE_EVENT)
829                         path = KPROBE_EVENTS_PATH;
830                 else if (pl->type == UPROBE_EVENT)
831                         path = UPROBE_EVENTS_PATH;
832                 else {
833                         fprintf(stderr, "Cannot cleanup event type %d\n",
834                                         pl->type);
835                         continue;
836                 }
837
838                 snprintf(probe_event, 128, "-:%s", pl->event);
839
840                 fd = open(path, O_WRONLY);
841                 if (fd < 0) {
842                         fprintf(stderr, "Cannot open %s\n", UPROBE_EVENTS_PATH);
843                         continue;
844                 }
845
846                 ret = write(fd, probe_event, strlen(probe_event));
847                 if (ret <= 0) {
848                         fprintf(stderr, "Cannot write %s to %s\n", probe_event,
849                                         path);
850                         close(fd);
851                         continue;
852                 }
853
854                 close(fd);
855         }
856 }
857