summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJiri Olsa <Jiri Olsa jolsa@redhat.com>2011-04-16 09:59:20 +0200
committerJiri Olsa <Jiri Olsa jolsa@redhat.com>2011-04-16 09:59:20 +0200
commitea6b29bc0d4af32aea49b3ab60752dbba751d701 (patch)
tree82308e086e60f664fe0c43cb5c557a9f076c4fd1
parent77f173cdb77fe7f749e03b892f0ee802f8c2431b (diff)
downloadlatrace-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--ChangeLog2
-rw-r--r--src/config.h3
-rw-r--r--src/fifo.c66
-rw-r--r--src/run.c48
4 files changed, 88 insertions, 31 deletions
diff --git a/ChangeLog b/ChangeLog
index 20acfbb..e52814d 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -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);
diff --git a/src/fifo.c b/src/fifo.c
index 672042b..bb4a26d 100644
--- a/src/fifo.c
+++ b/src/fifo.c
@@ -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;
diff --git a/src/run.c b/src/run.c
index 8bea6c8..f9f4f32 100644
--- a/src/run.c
+++ b/src/run.c
@@ -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);