Commit 4cb05a60 by Serge E. Hallyn Committed by Daniel Lezcano

Use container's /run/utmp if it exists

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: 's avatarSerge Hallyn <serge.hallyn@canonical.com> Signed-off-by: 's avatarDaniel Lezcano <dlezcano@fr.ibm.com>
parent 3e9c97c1
...@@ -170,6 +170,15 @@ static int utmp_get_runlevel(struct lxc_utmp *utmp_data) ...@@ -170,6 +170,15 @@ static int utmp_get_runlevel(struct lxc_utmp *utmp_data)
char path[MAXPATHLEN]; char path[MAXPATHLEN];
struct lxc_handler *handler = utmp_data->handler; 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", if (snprintf(path, MAXPATHLEN, "/proc/%d/root/var/run/utmp",
handler->pid) > MAXPATHLEN) { handler->pid) > MAXPATHLEN) {
ERROR("path is too long"); ERROR("path is too long");
...@@ -181,6 +190,8 @@ static int utmp_get_runlevel(struct lxc_utmp *utmp_data) ...@@ -181,6 +190,8 @@ static int utmp_get_runlevel(struct lxc_utmp *utmp_data)
return -1; return -1;
} }
utmp_ok:
setutxent(); setutxent();
while ((utmpx = getutxent())) { while ((utmpx = getutxent())) {
...@@ -219,6 +230,7 @@ int lxc_utmp_mainloop_add(struct lxc_epoll_descr *descr, ...@@ -219,6 +230,7 @@ int lxc_utmp_mainloop_add(struct lxc_epoll_descr *descr,
struct lxc_handler *handler) struct lxc_handler *handler)
{ {
char path[MAXPATHLEN]; char path[MAXPATHLEN];
char path2[MAXPATHLEN];
int fd, wd; int fd, wd;
struct lxc_utmp *utmp_data; struct lxc_utmp *utmp_data;
struct lxc_conf *conf = handler->conf; struct lxc_conf *conf = handler->conf;
...@@ -230,6 +242,19 @@ int lxc_utmp_mainloop_add(struct lxc_epoll_descr *descr, ...@@ -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 * in utmp at the moment, but want to watch for delete and create
* events as well. * 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", if (snprintf(path, MAXPATHLEN, "/proc/%d/root/var/run",
handler->pid) > MAXPATHLEN) { handler->pid) > MAXPATHLEN) {
ERROR("path is too long"); ERROR("path is too long");
...@@ -241,6 +266,8 @@ int lxc_utmp_mainloop_add(struct lxc_epoll_descr *descr, ...@@ -241,6 +266,8 @@ int lxc_utmp_mainloop_add(struct lxc_epoll_descr *descr,
return 0; return 0;
} }
run_ok:
utmp_data = (struct lxc_utmp *)malloc(sizeof(struct lxc_utmp)); utmp_data = (struct lxc_utmp *)malloc(sizeof(struct lxc_utmp));
if (NULL == utmp_data) { if (NULL == utmp_data) {
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment