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>
#include <errno.h>
#include <unistd.h>
#include <signal.h>
+#include <fcntl.h>
#include <sys/socket.h>
#include <sys/un.h>
#include <sys/poll.h>
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) {
}
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;
char *fstab;
int tty;
int pts;
+ int reboot;
struct utsname *utsname;
struct lxc_list cgroup;
struct lxc_list network;
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';
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)
* 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
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))
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;
}
#include <string.h>
#include <stdlib.h>
#include <errno.h>
+#include <fcntl.h>
#include <unistd.h>
#include <sys/epoll.h>
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;
}
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);
}
if (currun_level == '6') {
- INFO("container has reboot");
+ INFO("container has rebooted");
+ conf->reboot = 1;
kill(handler->pid, SIGKILL);
}
}