]> git.ipfire.org Git - thirdparty/lxc.git/commitdiff
restart the container at reboot
authorDaniel Lezcano <daniel.lezcano@free.fr>
Thu, 8 Apr 2010 07:44:23 +0000 (09:44 +0200)
committerDaniel Lezcano <dlezcano@fr.ibm.com>
Thu, 8 Apr 2010 07:44:23 +0000 (09:44 +0200)
When the reboot is detected, reboot the container.
That needs to set all file descriptor opened by lxc-start
to be flagged with the close-on-exec flag, otherwise when
re-execing ourself, we inherit our own fd.

Signed-off-by: Daniel Lezcano <dlezcano@fr.ibm.com>
src/lxc/commands.c
src/lxc/conf.c
src/lxc/conf.h
src/lxc/confile.c
src/lxc/lxc.h
src/lxc/lxc_start.c
src/lxc/mainloop.c
src/lxc/start.c
src/lxc/utmp.c

index 54e1826035ebdbfaf9adcde1ae1ef0b1022bddf3..7c24c8170ec782f833cd410a0d63937b5b682b7d 100644 (file)
@@ -25,6 +25,7 @@
 #include <errno.h>
 #include <unistd.h>
 #include <signal.h>
+#include <fcntl.h>
 #include <sys/socket.h>
 #include <sys/un.h>
 #include <sys/poll.h>
@@ -232,6 +233,12 @@ extern int lxc_command_mainloop_add(const char *name,
                return -1;
        }
 
+       if (fcntl(fd, F_SETFD, FD_CLOEXEC)) {
+               SYSERROR("failed to set sigfd to close-on-exec");
+               close(fd);
+               return -1;
+       }
+
        ret = lxc_mainloop_add_handler(descr, fd, incoming_command_handler,
                                       handler);
        if (ret) {
index 3242f17b6b2c3b7b17513d6284401a11a1eeacac..7747afc113f859194563e9c8984352930a21723a 100644 (file)
@@ -1089,12 +1089,6 @@ struct lxc_conf *lxc_conf_init(void)
        }
        memset(new, 0, sizeof(*new));
 
-       new->rootfs = NULL;
-       new->pivotdir = NULL;
-       new->fstab = NULL;
-       new->utsname = NULL;
-       new->tty = 0;
-       new->pts = 0;
        new->console.path = NULL;
        new->console.peer = -1;
        new->console.master = -1;
index 3a560fda38e553fe21ebfada0c25cb5aeb49519b..d0232dbcc8091a6806961873ff32d4020730f051 100644 (file)
@@ -183,6 +183,7 @@ struct lxc_conf {
        char *fstab;
        int tty;
        int pts;
+       int reboot;
        struct utsname *utsname;
        struct lxc_list cgroup;
        struct lxc_list network;
index 80da62540b4656105c5713c4c3939b12516b5988..e44f2cda7df8b18d9a027d02fe06ad1c3a38f423 100644 (file)
@@ -708,22 +708,34 @@ static int config_utsname(const char *key, char *value, struct lxc_conf *lxc_con
 static int parse_line(char *buffer, void *data)
 {
        struct config *config;
-       char *line = buffer;
+       char *line;
        char *dot;
        char *key;
        char *value;
+       int ret = -1;
 
-       if (lxc_is_line_empty(line))
+       if (lxc_is_line_empty(buffer))
                return 0;
 
+       /* we have to dup the buffer otherwise, at the re-exec for reboot we modified
+        * the original string on the stack by replacing '=' by '\0' below
+        */
+       line = strdup(buffer);
+       if (!line) {
+               SYSERROR("failed to allocate memory for '%s'", buffer);
+               goto out;
+       }
+
        line += lxc_char_left_gc(line, strlen(line));
-       if (line[0] == '#')
-               return 0;
+       if (line[0] == '#') {
+               ret = 0;
+               goto out;
+       }
 
        dot = strstr(line, "=");
        if (!dot) {
                ERROR("invalid configuration line: %s", line);
-               return -1;
+               goto out;
        }
 
        *dot = '\0';
@@ -738,10 +750,14 @@ static int parse_line(char *buffer, void *data)
        config = getconfig(key);
        if (!config) {
                ERROR("unknow key %s", key);
-               return -1;
+               goto out;
        }
 
-       return config->cb(key, value, data);
+       ret = config->cb(key, value, data);
+
+out:
+       free(line);
+       return ret;
 }
 
 int lxc_config_readline(char *buffer, struct lxc_conf *conf)
index d89102fe31bb0846d1e0fa9cebcdf4da4a531c3d..a091baaebf7c7b8bcbcc26d858a7e1fef17582c3 100644 (file)
@@ -43,9 +43,10 @@ struct lxc_conf;
  * Start the specified command inside a container
  * @name     : the name of the container
  * @argv     : an array of char * corresponding to the commande line
+ * @conf     : configuration
  * Returns 0 on sucess, < 0 otherwise
  */
-extern int lxc_start(const char *name, char *const argv[], struct lxc_conf *);
+extern int lxc_start(const char *name, char *const argv[], struct lxc_conf *conf);
 
 /*
  * Stop the container previously started with lxc_start, all
index 37f9fd8c2f3b8e24dbaf24b34d028cb0c264c544..5cc03db041e477bcc5fada792c598b902a76c796 100644 (file)
@@ -90,17 +90,15 @@ Options :\n\
 
 int main(int argc, char *argv[])
 {
-       char *const *args;
        int err = -1;
-
+       struct lxc_conf *conf;
+       char *const *args;
+       char *rcfile = NULL;
        char *const default_args[] = {
                "/sbin/init",
                '\0',
        };
 
-       char *rcfile = NULL;
-       struct lxc_conf *conf;
-
        lxc_list_init(&defines);
 
        if (lxc_arguments_parse(&my_args, argc, argv))
@@ -176,6 +174,17 @@ int main(int argc, char *argv[])
 
        err = lxc_start(my_args.name, args, conf);
 
+       /*
+        * exec ourself, that requires to have all opened fd
+        * with the close-on-exec flag set
+        */
+       if (conf->reboot) {
+               INFO("rebooting container");
+               execvp(argv[0], argv);
+               SYSERROR("failed to exec");
+               err = -1;
+       }
+
        return err;
 }
 
index 7a8a941a52f9da8bd64cfc8ec66d8cbd06517824..986762cae6e1ba8e35efd8f6386c4501de99b8e9 100644 (file)
@@ -24,6 +24,7 @@
 #include <string.h>
 #include <stdlib.h>
 #include <errno.h>
+#include <fcntl.h>
 #include <unistd.h>
 #include <sys/epoll.h>
 
@@ -132,6 +133,11 @@ int lxc_mainloop_open(struct lxc_epoll_descr *descr)
        if (descr->epfd < 0)
                return -1;
 
+       if (fcntl(descr->epfd, F_SETFD, FD_CLOEXEC)) {
+               close(descr->epfd);
+               return -1;
+       }
+
        lxc_list_init(&descr->handlers);
        return 0;
 }
index 0ce82371de854323decbcbd520ac8ea120767dd4..3b5023c9f616dd0cca9eb3f1beaee93592242517 100644 (file)
@@ -556,6 +556,9 @@ int lxc_start(const char *name, char *const argv[], struct lxc_conf *conf)
        while (waitpid(handler->pid, &status, 0) < 0 && errno == EINTR)
                continue;
 
+       if (sigprocmask(SIG_SETMASK, &handler->oldmask, NULL))
+               WARN("failed to restore sigprocmask");
+
        err =  lxc_error_set_and_log(handler->pid, status);
 out_fini:
        lxc_fini(name, handler);
index 0c4e6f8cd55ac5776cc35bc67b8d0fcef39010f0..86cd5a00d3ec02b4bc1d4a5ebfcb0318168d5036 100644 (file)
@@ -94,7 +94,8 @@ static int utmp_handler(int fd, void *data, struct lxc_epoll_descr *descr)
                }
 
                if (currun_level == '6') {
-                       INFO("container has reboot");
+                       INFO("container has rebooted");
+                       conf->reboot = 1;
                        kill(handler->pid, SIGKILL);
                }
        }