diff options
author | Jiri Olsa <Jiri Olsa jolsa@redhat.com> | 2011-04-16 09:59:20 +0200 |
---|---|---|
committer | Jiri Olsa <Jiri Olsa jolsa@redhat.com> | 2011-04-16 09:59:20 +0200 |
commit | ea6b29bc0d4af32aea49b3ab60752dbba751d701 (patch) | |
tree | 82308e086e60f664fe0c43cb5c557a9f076c4fd1 | |
parent | 77f173cdb77fe7f749e03b892f0ee802f8c2431b (diff) | |
download | latrace-ea6b29bc0d4af32aea49b3ab60752dbba751d701.tar.gz latrace-ea6b29bc0d4af32aea49b3ab60752dbba751d701.tar.xz latrace-ea6b29bc0d4af32aea49b3ab60752dbba751d701.zip |
add threads fifo management to special directory
so the notification is not affected by other files
-rw-r--r-- | ChangeLog | 2 | ||||
-rw-r--r-- | src/config.h | 3 | ||||
-rw-r--r-- | src/fifo.c | 66 | ||||
-rw-r--r-- | src/run.c | 48 |
4 files changed, 88 insertions, 31 deletions
@@ -1,5 +1,7 @@ 2011-04-16 Jiri Olsa <olsajiri@gmail.com> * fix display of char arguments + * add threads fifo management to special directory + so the notification is not affected by other files 2011-04-06 Jiri Olsa <olsajiri@gmail.com> * fix memory leak in the argument display code diff --git a/src/config.h b/src/config.h index 9bdae88..190a590 100644 --- a/src/config.h +++ b/src/config.h @@ -302,7 +302,8 @@ int lt_run(struct lt_config_app *cfg); /* fifo */ int lt_fifo_create(struct lt_config_audit *cfg, char *dir); -int lt_fifo_open(struct lt_config_app *cfg, char *name); +int lt_fifo_open(struct lt_config_app *cfg, char *dir, char *name); +int lt_fifo_notify_fd(struct lt_config_app *cfg, char *dir); int lt_fifo_send(struct lt_config_audit *cfg, int fd, char *buf, int len); int lt_fifo_recv(struct lt_config_app *cfg, struct lt_thread *t, void *buf, int bufsize); @@ -28,16 +28,35 @@ #include <sys/stat.h> #include <fcntl.h> #include <string.h> +#include <sys/inotify.h> #include "config.h" +static char *get_notify_dir(char *dir) +{ + static char notify_dir[LT_MAXFILE]; + static int initialized = 0; + int s; + + if (initialized) + return notify_dir; + + s = snprintf(notify_dir, LT_MAXFILE, "%s/fifo", dir); + if (s >= LT_MAXFILE) + return NULL; + + initialized = 1; + return notify_dir; +} + int lt_fifo_create(struct lt_config_audit *cfg, char *dir) { int fd; char fifo[100]; - sprintf(fifo, "%s/fifo-%d", dir, (pid_t) syscall(SYS_gettid)); + sprintf(fifo, "%s/fifo-%d", get_notify_dir(dir), + (pid_t) syscall(SYS_gettid)); if (-1 == mkfifo(fifo, 0666)) { perror("mkfifo failed"); @@ -52,17 +71,58 @@ int lt_fifo_create(struct lt_config_audit *cfg, char *dir) return fd; } -int lt_fifo_open(struct lt_config_app *cfg, char *name) +int lt_fifo_open(struct lt_config_app *cfg, char *dir, char *name) { int fd; + char str_fifo[LT_MAXFILE]; - if (-1 == (fd = open(name, O_RDONLY))) + snprintf(str_fifo, LT_MAXFILE, "%s/%s", get_notify_dir(dir), name); + PRINT_VERBOSE(cfg, 1, "opening fifo: %s\n", str_fifo); + + if (-1 == (fd = open(str_fifo, O_RDONLY))) perror("open fifo failed"); PRINT_VERBOSE(cfg, 1, "pipe openned fd: %d\n", fd); return fd; } +int lt_fifo_notify_fd(struct lt_config_app *cfg, char *dir) +{ + int fd; + char *notify_dir = get_notify_dir(dir); + struct stat st; + + if (stat(notify_dir, &st)) { + if (mkdir(notify_dir, S_IRWXU)) { + perror("mkdir failed"); + return -1; + } + if (stat(notify_dir, &st)) { + perror("stat failed"); + return -1; + } + } + + if (!S_ISDIR(st.st_mode)) { + PRINT_VERBOSE(cfg, 1, "WTF '%s' is not a directory..\n", + notify_dir); + return -1; + } + + if (-1 == (fd = inotify_init())) { + perror("inotify_init failed"); + return -1; + } + + if (-1 == inotify_add_watch(fd, notify_dir, IN_CREATE)) { + perror("inotify_add_watch failed"); + return -1; + } + + PRINT_VERBOSE(cfg, 1, "fifo notification set to: %s\n", notify_dir); + return fd; +} + int lt_fifo_send(struct lt_config_audit *cfg, int fd, char *buf, int len) { static unsigned int written = 0; @@ -66,24 +66,7 @@ static int store_config(struct lt_config_app *cfg, char *file) return 0; } -static int set_dir_notify(char *dir) -{ - int fd; - - if (-1 == (fd = inotify_init())) { - perror("inotify_init failed"); - return -1; - } - - if (-1 == inotify_add_watch(fd, dir, IN_CREATE)) { - perror("inotify_add_watch failed"); - return -1; - } - - return fd; -} - -static int get_fifo_dir(char *buf, int len) +static int get_config_dir(char *buf, int len) { snprintf(buf, len , "%s-XXXXXX", CONFIG_LT_CONFIG); if (NULL == mkdtemp(buf)) { @@ -97,7 +80,6 @@ static int get_fifo_dir(char *buf, int len) static int get_fifo(struct lt_config_app *cfg, int notify_fd, char *dir, pid_t *pid) { - char str_fifo[LT_MAXFILE]; unsigned char buf[1000]; struct inotify_event *event = (struct inotify_event*) buf; @@ -107,12 +89,11 @@ static int get_fifo(struct lt_config_app *cfg, int notify_fd, } sscanf(event->name, "fifo-%d", pid); - sprintf(str_fifo, "%s/%s", dir, event->name); PRINT_VERBOSE(cfg, 1, "thread id %d, got fifo: %s\n", - *pid, str_fifo); + *pid, event->name); - return lt_fifo_open(cfg, str_fifo); + return lt_fifo_open(cfg, dir, event->name); } static int process_fifo(struct lt_config_app *cfg, struct lt_thread *t) @@ -238,6 +219,8 @@ static int remove_dir(struct lt_config_app *cfg, char *name) DIR *dir; struct dirent *d; + PRINT_VERBOSE(cfg, 1, "removing %s\n", name); + if (NULL == (dir = opendir(name))) { perror("opendir failed"); return -1; @@ -245,13 +228,24 @@ static int remove_dir(struct lt_config_app *cfg, char *name) while((d = readdir(dir))) { char file[LT_MAXFILE]; + struct stat st; if (!strcmp(".", d->d_name) || (!strcmp("..", d->d_name))) continue; sprintf(file, "%s/%s", name, d->d_name); - if (-1 == (unlink(file))) + if (stat(file, &st)) { + perror("stat failed"); + continue; + } + + if (S_ISDIR(st.st_mode)) { + remove_dir(cfg, file); + continue; + } + + if (unlink(file)) perror("unlink failed"); } @@ -271,9 +265,9 @@ int lt_run(struct lt_config_app *cfg) char str_dir[LT_MAXFILE]; char str_cfg[LT_MAXFILE]; int status; - int notify_fd = -1; + int fifo_notify_fd = -1; - if (-1 == get_fifo_dir(str_dir, LT_MAXFILE)) + if (-1 == get_config_dir(str_dir, LT_MAXFILE)) return -1; sprintf(str_cfg, "%s/config", str_dir); @@ -281,7 +275,7 @@ int lt_run(struct lt_config_app *cfg) return -1; if (lt_sh(cfg, pipe) && - (-1 == (notify_fd = set_dir_notify(str_dir)))) + (-1 == (fifo_notify_fd = lt_fifo_notify_fd(cfg, str_dir)))) return -1; gettimeofday(&tv_program_start, NULL); @@ -307,7 +301,7 @@ int lt_run(struct lt_config_app *cfg) } if (lt_sh(cfg, pipe)) - status = process(cfg, child_pid, str_dir, notify_fd); + status = process(cfg, child_pid, str_dir, fifo_notify_fd); else waitpid(child_pid, &status, 0); |