]> git.ipfire.org Git - thirdparty/lxc.git/commitdiff
Use container's /run/utmp if it exists
authorSerge E. Hallyn <serge.hallyn@canonical.com>
Sun, 7 Aug 2011 10:25:07 +0000 (12:25 +0200)
committerDaniel Lezcano <dlezcano@fr.ibm.com>
Sun, 7 Aug 2011 10:25:07 +0000 (12:25 +0200)
If /var/run is a symlink to /run in the container, then opening
/proc/<pid>/root/var/run/utmp will end up opening the host's utmp.
Therefore the hack detecting shutdown through utmp fails.

Signed-off-by: Serge Hallyn <serge.hallyn@canonical.com>
Signed-off-by: Daniel Lezcano <dlezcano@fr.ibm.com>
src/lxc/utmp.c

index 691c3ef9d7bb3a2eb1d08191136a1680153a4cc0..b6469b09a92e09b778cd251bf057c805655d2333 100644 (file)
@@ -170,6 +170,15 @@ static int utmp_get_runlevel(struct lxc_utmp *utmp_data)
        char path[MAXPATHLEN];
        struct lxc_handler *handler = utmp_data->handler;
 
+       if (snprintf(path, MAXPATHLEN, "/proc/%d/root/run/utmp",
+                    handler->pid) > MAXPATHLEN) {
+               ERROR("path is too long");
+               return -1;
+       }
+
+       if (!access(path, F_OK) && !utmpxname(path))
+               goto utmp_ok;
+
        if (snprintf(path, MAXPATHLEN, "/proc/%d/root/var/run/utmp",
                     handler->pid) > MAXPATHLEN) {
                ERROR("path is too long");
@@ -181,6 +190,8 @@ static int utmp_get_runlevel(struct lxc_utmp *utmp_data)
                return -1;
        }
 
+utmp_ok:
+
        setutxent();
 
        while ((utmpx = getutxent())) {
@@ -219,6 +230,7 @@ int lxc_utmp_mainloop_add(struct lxc_epoll_descr *descr,
                          struct lxc_handler *handler)
 {
        char path[MAXPATHLEN];
+       char path2[MAXPATHLEN];
        int fd, wd;
        struct lxc_utmp *utmp_data;
        struct lxc_conf *conf = handler->conf;
@@ -230,6 +242,19 @@ int lxc_utmp_mainloop_add(struct lxc_epoll_descr *descr,
         * in utmp at the moment, but want to watch for delete and create
         * events as well.
         */
+       if (snprintf(path, MAXPATHLEN, "/proc/%d/root/run",
+                    handler->pid) > MAXPATHLEN) {
+               ERROR("path is too long");
+               return -1;
+       }
+       if (snprintf(path2, MAXPATHLEN, "/proc/%d/root/run/utmp",
+                    handler->pid) > MAXPATHLEN) {
+               ERROR("path is too long");
+               return -1;
+       }
+       if (!access(path2, F_OK))
+               goto run_ok;
+
        if (snprintf(path, MAXPATHLEN, "/proc/%d/root/var/run",
                     handler->pid) > MAXPATHLEN) {
                ERROR("path is too long");
@@ -241,6 +266,8 @@ int lxc_utmp_mainloop_add(struct lxc_epoll_descr *descr,
                return 0;
        }
 
+run_ok:
+
        utmp_data = (struct lxc_utmp *)malloc(sizeof(struct lxc_utmp));
 
        if (NULL == utmp_data) {