Commit 91480a0f by Daniel Lezcano Committed by Daniel Lezcano

restart the container at reboot

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: 's avatarDaniel Lezcano <dlezcano@fr.ibm.com>
parent 563f2f2c
...@@ -25,6 +25,7 @@ ...@@ -25,6 +25,7 @@
#include <errno.h> #include <errno.h>
#include <unistd.h> #include <unistd.h>
#include <signal.h> #include <signal.h>
#include <fcntl.h>
#include <sys/socket.h> #include <sys/socket.h>
#include <sys/un.h> #include <sys/un.h>
#include <sys/poll.h> #include <sys/poll.h>
...@@ -232,6 +233,12 @@ extern int lxc_command_mainloop_add(const char *name, ...@@ -232,6 +233,12 @@ extern int lxc_command_mainloop_add(const char *name,
return -1; 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, ret = lxc_mainloop_add_handler(descr, fd, incoming_command_handler,
handler); handler);
if (ret) { if (ret) {
......
...@@ -1089,12 +1089,6 @@ struct lxc_conf *lxc_conf_init(void) ...@@ -1089,12 +1089,6 @@ struct lxc_conf *lxc_conf_init(void)
} }
memset(new, 0, sizeof(*new)); 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.path = NULL;
new->console.peer = -1; new->console.peer = -1;
new->console.master = -1; new->console.master = -1;
......
...@@ -183,6 +183,7 @@ struct lxc_conf { ...@@ -183,6 +183,7 @@ struct lxc_conf {
char *fstab; char *fstab;
int tty; int tty;
int pts; int pts;
int reboot;
struct utsname *utsname; struct utsname *utsname;
struct lxc_list cgroup; struct lxc_list cgroup;
struct lxc_list network; struct lxc_list network;
......
...@@ -708,22 +708,34 @@ static int config_utsname(const char *key, char *value, struct lxc_conf *lxc_con ...@@ -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) static int parse_line(char *buffer, void *data)
{ {
struct config *config; struct config *config;
char *line = buffer; char *line;
char *dot; char *dot;
char *key; char *key;
char *value; char *value;
int ret = -1;
if (lxc_is_line_empty(line)) if (lxc_is_line_empty(buffer))
return 0; 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)); line += lxc_char_left_gc(line, strlen(line));
if (line[0] == '#') if (line[0] == '#') {
return 0; ret = 0;
goto out;
}
dot = strstr(line, "="); dot = strstr(line, "=");
if (!dot) { if (!dot) {
ERROR("invalid configuration line: %s", line); ERROR("invalid configuration line: %s", line);
return -1; goto out;
} }
*dot = '\0'; *dot = '\0';
...@@ -738,10 +750,14 @@ static int parse_line(char *buffer, void *data) ...@@ -738,10 +750,14 @@ static int parse_line(char *buffer, void *data)
config = getconfig(key); config = getconfig(key);
if (!config) { if (!config) {
ERROR("unknow key %s", key); 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) int lxc_config_readline(char *buffer, struct lxc_conf *conf)
......
...@@ -43,9 +43,10 @@ struct lxc_conf; ...@@ -43,9 +43,10 @@ struct lxc_conf;
* Start the specified command inside a container * Start the specified command inside a container
* @name : the name of the container * @name : the name of the container
* @argv : an array of char * corresponding to the commande line * @argv : an array of char * corresponding to the commande line
* @conf : configuration
* Returns 0 on sucess, < 0 otherwise * 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 * Stop the container previously started with lxc_start, all
......
...@@ -90,17 +90,15 @@ Options :\n\ ...@@ -90,17 +90,15 @@ Options :\n\
int main(int argc, char *argv[]) int main(int argc, char *argv[])
{ {
char *const *args;
int err = -1; int err = -1;
struct lxc_conf *conf;
char *const *args;
char *rcfile = NULL;
char *const default_args[] = { char *const default_args[] = {
"/sbin/init", "/sbin/init",
'\0', '\0',
}; };
char *rcfile = NULL;
struct lxc_conf *conf;
lxc_list_init(&defines); lxc_list_init(&defines);
if (lxc_arguments_parse(&my_args, argc, argv)) if (lxc_arguments_parse(&my_args, argc, argv))
...@@ -176,6 +174,17 @@ int main(int argc, char *argv[]) ...@@ -176,6 +174,17 @@ int main(int argc, char *argv[])
err = lxc_start(my_args.name, args, conf); 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; return err;
} }
...@@ -24,6 +24,7 @@ ...@@ -24,6 +24,7 @@
#include <string.h> #include <string.h>
#include <stdlib.h> #include <stdlib.h>
#include <errno.h> #include <errno.h>
#include <fcntl.h>
#include <unistd.h> #include <unistd.h>
#include <sys/epoll.h> #include <sys/epoll.h>
...@@ -132,6 +133,11 @@ int lxc_mainloop_open(struct lxc_epoll_descr *descr) ...@@ -132,6 +133,11 @@ int lxc_mainloop_open(struct lxc_epoll_descr *descr)
if (descr->epfd < 0) if (descr->epfd < 0)
return -1; return -1;
if (fcntl(descr->epfd, F_SETFD, FD_CLOEXEC)) {
close(descr->epfd);
return -1;
}
lxc_list_init(&descr->handlers); lxc_list_init(&descr->handlers);
return 0; return 0;
} }
......
...@@ -556,6 +556,9 @@ int lxc_start(const char *name, char *const argv[], struct lxc_conf *conf) ...@@ -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) while (waitpid(handler->pid, &status, 0) < 0 && errno == EINTR)
continue; continue;
if (sigprocmask(SIG_SETMASK, &handler->oldmask, NULL))
WARN("failed to restore sigprocmask");
err = lxc_error_set_and_log(handler->pid, status); err = lxc_error_set_and_log(handler->pid, status);
out_fini: out_fini:
lxc_fini(name, handler); lxc_fini(name, handler);
......
...@@ -94,7 +94,8 @@ static int utmp_handler(int fd, void *data, struct lxc_epoll_descr *descr) ...@@ -94,7 +94,8 @@ static int utmp_handler(int fd, void *data, struct lxc_epoll_descr *descr)
} }
if (currun_level == '6') { if (currun_level == '6') {
INFO("container has reboot"); INFO("container has rebooted");
conf->reboot = 1;
kill(handler->pid, SIGKILL); kill(handler->pid, SIGKILL);
} }
} }
......
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