This patch allows to shutdown the container when the system
is powered off in the container.

Signed-off-by: Daniel Lezcano <dlezc...@fr.ibm.com>
---
 src/lxc/Makefile.am |    6 +-
 src/lxc/start.c     |   11 +++
 src/lxc/utmp.c      |  156 ++++++++++++++++++++++++++++++++++++++++++++++++++++
 src/lxc/utmp.h      |   28 +++++++++
 4 files changed, 198 insertions(+), 3 deletions(-)

Index: lxc/src/lxc/Makefile.am
===================================================================
--- lxc.orig/src/lxc/Makefile.am
+++ lxc/src/lxc/Makefile.am
@@ -18,7 +18,7 @@ so_PROGRAMS = liblxc.so
 liblxc_so_SOURCES = \
        arguments.c arguments.h \
        commands.c commands.h \
-       start.c \
+       start.c start.h \
        stop.c \
        monitor.c monitor.h \
        console.c \
@@ -43,7 +43,9 @@ liblxc_so_SOURCES = \
         genl.c genl.h \
        \
        mainloop.c mainloop.h \
-       af_unix.c af_unix.h
+       af_unix.c af_unix.h \
+       \
+       utmp.c utmp.h
 
 AM_CFLAGS=-I$(top_srcdir)/src
 
Index: lxc/src/lxc/start.c
===================================================================
--- lxc.orig/src/lxc/start.c
+++ lxc/src/lxc/start.c
@@ -91,10 +91,12 @@ int signalfd(int fd, const sigset_t *mas
 #include "start.h"
 #include "conf.h"
 #include "log.h"
+#include "cgroup.h"
 #include "error.h"
 #include "af_unix.h"
 #include "mainloop.h"
 #include "utils.h"
+#include "utmp.h"
 #include "monitor.h"
 #include "commands.h"
 #include "console.h"
@@ -172,8 +174,15 @@ int lxc_poll(const char *name, struct lx
                goto out_mainloop_open;
        }
 
-       if (lxc_command_mainloop_add(name, &descr, handler))
+       if (lxc_command_mainloop_add(name, &descr, handler)) {
+               ERROR("failed to add command handler to mainloop");
                goto out_mainloop_open;
+       }
+
+       if (lxc_utmp_mainloop_add(&descr, handler)) {
+               ERROR("failed to add utmp handler to mainloop");
+               goto out_mainloop_open;
+       }
 
        return lxc_mainloop(&descr);
 
Index: lxc/src/lxc/utmp.c
===================================================================
--- /dev/null
+++ lxc/src/lxc/utmp.c
@@ -0,0 +1,156 @@
+/*
+ * lxc: linux Container library
+ *
+ * (C) Copyright IBM Corp. 2007, 2008
+ *
+ * Authors:
+ * Daniel Lezcano <dlezcano at fr.ibm.com>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#include <stdio.h>
+#include <unistd.h>
+#include <errno.h>
+#include <signal.h>
+#include <stdlib.h>
+#include <fcntl.h>
+#include <sys/inotify.h>
+
+#include "conf.h"
+#include "cgroup.h"
+#include "start.h"
+#include "mainloop.h"
+#include "lxc.h"
+#include "log.h"
+#define __USE_GNU
+#include <utmpx.h>
+#undef __USE_GNU
+
+lxc_log_define(lxc_utmp, lxc);
+
+static int utmp_handler(int fd, void *data, struct lxc_epoll_descr *descr)
+{
+       struct inotify_event ie;
+       struct utmpx *utmpx;
+       struct lxc_handler *handler = (struct lxc_handler *)data;
+       struct lxc_conf *conf = handler->conf;
+       char prevrun_level = 'N', currun_level = 'N';
+       int ntasks, ret;
+       char path[MAXPATHLEN];
+
+       if (read(fd, &ie, sizeof(ie)) < 0) {
+               SYSERROR("failed to read utmp notification");
+               return -1;
+       }
+
+       if (snprintf(path, MAXPATHLEN, "%s/var/run/utmp", conf->rootfs) >
+           MAXPATHLEN) {
+               ERROR("path is too long");
+               return -1;
+       }
+
+       if (utmpxname(path)) {
+               SYSERROR("failed to 'utmpxname'");
+               return -1;
+       }
+
+       setutxent();
+
+       while ((utmpx = getutxent())) {
+
+               if (utmpx->ut_type == RUN_LVL) {
+                       prevrun_level = utmpx->ut_pid / 256;
+                       currun_level = utmpx->ut_pid % 256;
+               }
+       }
+
+       ntasks = lxc_cgroup_nrtasks(handler->name);
+       if (ntasks < 0) {
+               ERROR("failed to get the number of tasks");
+               goto out;
+       }
+
+       if (ntasks == 1 && prevrun_level == '3') {
+
+               DEBUG("run level is %c/%c", prevrun_level, currun_level);
+               DEBUG("there is %d tasks remaining", ntasks);
+
+               if (currun_level == '0') {
+                       INFO("container has shutdown");
+                       kill(handler->pid, SIGKILL);
+               }
+
+               if (currun_level == '6') {
+                       INFO("container has reboot");
+                       kill(handler->pid, SIGKILL);
+               }
+       }
+
+       ret = 0;
+out:
+       endutxent();
+
+       return ret;
+}
+
+int lxc_utmp_mainloop_add(struct lxc_epoll_descr *descr,
+                         struct lxc_handler *handler)
+{
+       struct lxc_conf *conf = handler->conf;
+       char path[MAXPATHLEN];
+       int fd, wd;
+
+       if (!conf->rootfs)
+               return 0;
+
+       if (snprintf(path, MAXPATHLEN, "%s/var/run/utmp", conf->rootfs) >
+           MAXPATHLEN) {
+               ERROR("path is too long");
+               return -1;
+       }
+
+       if (access(path, F_OK)) {
+               WARN("'%s' not found", path);
+               return 0;
+       }
+
+       fd = inotify_init();
+       if (fd < 0) {
+               SYSERROR("failed to inotify_init");
+               return -1;
+       }
+
+       if (fcntl(fd, F_SETFD, FD_CLOEXEC)) {
+               SYSERROR("failed to set inotify fd to close-on-exec");
+               close(fd);
+               return -1;
+       }
+
+       wd = inotify_add_watch(fd, path, IN_MODIFY);
+       if (wd < 0) {
+               SYSERROR("failed to add watch for '%s'", path);
+               close(fd);
+               return -1;
+       }
+
+       if (lxc_mainloop_add_handler(descr, fd, utmp_handler, handler)) {
+               SYSERROR("failed to add mainloop");
+               close(fd);
+               return -1;
+       }
+
+       return 0;
+}
Index: lxc/src/lxc/utmp.h
===================================================================
--- /dev/null
+++ lxc/src/lxc/utmp.h
@@ -0,0 +1,28 @@
+/*
+ * lxc: linux Container library
+ *
+ * (C) Copyright IBM Corp. 2007, 2008
+ *
+ * Authors:
+ * Daniel Lezcano <dlezcano at fr.ibm.com>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+struct lxc_handler;
+struct lxc_epoll_descr;
+
+int lxc_utmp_mainloop_add(struct lxc_epoll_descr *descr,
+                         struct lxc_handler *handler);


------------------------------------------------------------------------------
The Planet: dedicated and managed hosting, cloud storage, colocation
Stay online with enterprise data centers and the best network in the business
Choose flexible plans and management services without long-term contracts
Personal 24x7 support from experience hosting pros just a phone call away.
http://p.sf.net/sfu/theplanet-com
_______________________________________________
Lxc-devel mailing list
Lxc-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/lxc-devel

Reply via email to