static int lxc_monitord_fifo_create(struct lxc_monitor *mon)
{
+ struct flock lk;
char fifo_path[PATH_MAX];
int ret;
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;
}
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;
}
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]);
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)
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);