[lxc-devel] [PATCH] Watch utmp if /var/run is not shared

David Ward david.ward at ll.mit.edu
Tue Mar 1 00:08:05 UTC 2011


lxc watches /var/run/utmp in the container to monitor its runlevel, so that
it can stop or "reboot" the container when appropriate. This should not
happen though if the container shares /var/run/utmp with the system (which
should only be the case if the container does not run init).

Currently this is avoided by requiring that the container has a separate
filesystem root (i.e. "lxc.rootfs" is configured) in order to watch utmp.
However it is also sufficient to share the filesystem root, but to re-mount
/var/run so that there is a separate utmp file. (In the case of Upstart,
/etc/init can be re-mounted as well to allow the container to have its own
set of init scripts. The remainder of the filesystem can still be shared.)

With this change, lxc checks the device ID and inode number of /var/run to
see if the container has re-mounted it as a pre-condition of watching utmp.
This replaces the check for "lxc.rootfs" in the configuration.

Signed-off-by: David Ward <david.ward at ll.mit.edu>
---
 src/lxc/utmp.c |   21 ++++++++++++++++-----
 1 files changed, 16 insertions(+), 5 deletions(-)

diff --git a/src/lxc/utmp.c b/src/lxc/utmp.c
index 691c3ef..3356396 100644
--- a/src/lxc/utmp.c
+++ b/src/lxc/utmp.c
@@ -30,6 +30,7 @@
 #include <sys/inotify.h>
 #include <sys/ioctl.h>
 #include <sys/timerfd.h>
+#include <sys/stat.h>
 
 #include "conf.h"
 #include "cgroup.h"
@@ -221,10 +222,7 @@ int lxc_utmp_mainloop_add(struct lxc_epoll_descr *descr,
 	char path[MAXPATHLEN];
 	int fd, wd;
 	struct lxc_utmp *utmp_data;
-	struct lxc_conf *conf = handler->conf;
-
-	if (!conf->rootfs.path)
-		return 0;
+	struct stat container_utmp_stat, system_utmp_stat;
 
 	/* We set up a watch for the /var/run directory. We're only interested
 	 * in utmp at the moment, but want to watch for delete and create
@@ -236,11 +234,24 @@ int lxc_utmp_mainloop_add(struct lxc_epoll_descr *descr,
 		return -1;
 	}
 
-	if (access(path, F_OK)) {
+	if (stat(path, &container_utmp_stat)) {
 		WARN("'%s' not found", path);
 		return 0;
 	}
 
+	if (stat("/var/run", &system_utmp_stat)) {
+		WARN("'/var/run' not found");
+		return 0;
+	}
+
+	/* Do not watch the /var/run directory if the container shares it with
+	 * the system.
+	 */
+	if ((container_utmp_stat.st_dev == system_utmp_stat.st_dev)
+	    && (container_utmp_stat.st_ino == system_utmp_stat.st_ino)) {
+		return 0;
+	}
+
 	utmp_data = (struct lxc_utmp *)malloc(sizeof(struct lxc_utmp));
 
 	if (NULL == utmp_data) {
-- 
1.7.4





More information about the lxc-devel mailing list