diff --git a/src/lxc/lxc_monitord.c b/src/lxc/lxc_monitord.c index f6d99d57e..8f7e6b0a2 100644 --- a/src/lxc/lxc_monitord.c +++ b/src/lxc/lxc_monitord.c @@ -75,6 +75,7 @@ static int quit; static int lxc_monitord_fifo_create(struct lxc_monitor *mon) { + struct flock lk; char fifo_path[PATH_MAX]; int ret; @@ -83,8 +84,8 @@ static int lxc_monitord_fifo_create(struct lxc_monitor *mon) return ret; ret = mknod(fifo_path, S_IFIFO|S_IRUSR|S_IWUSR, 0); - if (ret < 0) { - INFO("monitor fifo %s exists, already running?", fifo_path); + if (ret < 0 && errno != EEXIST) { + INFO("failed to mknod monitor fifo %s %s", fifo_path, strerror(errno)); return -1; } @@ -94,6 +95,17 @@ static int lxc_monitord_fifo_create(struct lxc_monitor *mon) ERROR("failed to open monitor fifo"); return -1; } + + lk.l_type = F_WRLCK; + lk.l_whence = SEEK_SET; + lk.l_start = 0; + lk.l_len = 0; + if (fcntl(mon->fifofd, F_SETLK, &lk) != 0) { + /* another lxc-monitord is already running, don't start up */ + DEBUG("lxc-monitord already running on lxcpath %s", mon->lxcpath); + close(mon->fifofd); + return -1; + } return 0; } @@ -264,8 +276,8 @@ static void lxc_monitord_delete(struct lxc_monitor *mon) lxc_monitord_sock_delete(mon); lxc_mainloop_del_handler(&mon->descr, mon->fifofd); - close(mon->fifofd); lxc_monitord_fifo_delete(mon); + close(mon->fifofd); for (i = 0; i < mon->clientfds_cnt; i++) { lxc_mainloop_del_handler(&mon->descr, mon->clientfds[i]); @@ -401,7 +413,7 @@ int main(int argc, char *argv[]) goto out; } - NOTICE("monitoring lxcpath %s", mon.lxcpath); + NOTICE("pid:%d monitoring lxcpath %s", getpid(), mon.lxcpath); for(;;) { ret = lxc_mainloop(&mon.descr, 1000 * 30); if (mon.clientfds_cnt <= 0) diff --git a/src/lxc/monitor.c b/src/lxc/monitor.c index e45b5cfb1..4ca4000cd 100644 --- a/src/lxc/monitor.c +++ b/src/lxc/monitor.c @@ -95,14 +95,20 @@ static void lxc_monitor_fifo_send(struct lxc_msg *msg, const char *lxcpath) if (ret < 0) return; - fd = open(fifo_path, O_WRONLY); + /* open the fifo nonblock in case the monitor is dead, we don't want + * the open to wait for a reader since it may never come. + */ + fd = open(fifo_path, O_WRONLY|O_NONBLOCK); if (fd < 0) { - /* it is normal for this open to fail when there is no monitor - * running, so we don't log it + /* it is normal for this open to fail ENXIO when there is no + * monitor running, so we don't log it */ return; } + if (fcntl(fd, F_SETFL, O_WRONLY) < 0) + return; + ret = write(fd, msg, sizeof(*msg)); if (ret != sizeof(*msg)) { close(fd);