Commit d5088cf2 by Christian Seiler Committed by Stéphane Graber

lxc-start: Add command to retrieve the clone flags used to start the container.

Add the LXC_COMMAND_CLONE_FLAGS that retrieves the flags passed to clone(2) when the container was started. This allows external programs to determine which namespaces the container was unshared from. Signed-off-by: 's avatarChristian Seiler <christian@iwakd.de> Cc: Daniel Lezcano <daniel.lezcano@free.fr> Acked-by: 's avatarSerge Hallyn <serge.hallyn@canonical.com>
parent 1881820a
...@@ -154,11 +154,32 @@ pid_t get_init_pid(const char *name) ...@@ -154,11 +154,32 @@ pid_t get_init_pid(const char *name)
return command.answer.pid; return command.answer.pid;
} }
int lxc_get_clone_flags(const char *name)
{
struct lxc_command command = {
.request = { .type = LXC_COMMAND_CLONE_FLAGS },
};
int ret, stopped = 0;
ret = lxc_command(name, &command, &stopped);
if (ret < 0 && stopped)
return -1;
if (ret < 0) {
ERROR("failed to send command");
return -1;
}
return command.answer.ret;
}
extern void lxc_console_remove_fd(int, struct lxc_tty_info *); extern void lxc_console_remove_fd(int, struct lxc_tty_info *);
extern int lxc_console_callback(int, struct lxc_request *, struct lxc_handler *); extern int lxc_console_callback(int, struct lxc_request *, struct lxc_handler *);
extern int lxc_stop_callback(int, struct lxc_request *, struct lxc_handler *); extern int lxc_stop_callback(int, struct lxc_request *, struct lxc_handler *);
extern int lxc_state_callback(int, struct lxc_request *, struct lxc_handler *); extern int lxc_state_callback(int, struct lxc_request *, struct lxc_handler *);
extern int lxc_pid_callback(int, struct lxc_request *, struct lxc_handler *); extern int lxc_pid_callback(int, struct lxc_request *, struct lxc_handler *);
extern int lxc_clone_flags_callback(int, struct lxc_request *, struct lxc_handler *);
static int trigger_command(int fd, struct lxc_request *request, static int trigger_command(int fd, struct lxc_request *request,
struct lxc_handler *handler) struct lxc_handler *handler)
...@@ -166,10 +187,11 @@ static int trigger_command(int fd, struct lxc_request *request, ...@@ -166,10 +187,11 @@ static int trigger_command(int fd, struct lxc_request *request,
typedef int (*callback)(int, struct lxc_request *, struct lxc_handler *); typedef int (*callback)(int, struct lxc_request *, struct lxc_handler *);
callback cb[LXC_COMMAND_MAX] = { callback cb[LXC_COMMAND_MAX] = {
[LXC_COMMAND_TTY] = lxc_console_callback, [LXC_COMMAND_TTY] = lxc_console_callback,
[LXC_COMMAND_STOP] = lxc_stop_callback, [LXC_COMMAND_STOP] = lxc_stop_callback,
[LXC_COMMAND_STATE] = lxc_state_callback, [LXC_COMMAND_STATE] = lxc_state_callback,
[LXC_COMMAND_PID] = lxc_pid_callback, [LXC_COMMAND_PID] = lxc_pid_callback,
[LXC_COMMAND_CLONE_FLAGS] = lxc_clone_flags_callback,
}; };
if (request->type < 0 || request->type >= LXC_COMMAND_MAX) if (request->type < 0 || request->type >= LXC_COMMAND_MAX)
......
...@@ -28,6 +28,7 @@ enum { ...@@ -28,6 +28,7 @@ enum {
LXC_COMMAND_STOP, LXC_COMMAND_STOP,
LXC_COMMAND_STATE, LXC_COMMAND_STATE,
LXC_COMMAND_PID, LXC_COMMAND_PID,
LXC_COMMAND_CLONE_FLAGS,
LXC_COMMAND_MAX, LXC_COMMAND_MAX,
}; };
...@@ -48,6 +49,7 @@ struct lxc_command { ...@@ -48,6 +49,7 @@ struct lxc_command {
}; };
extern pid_t get_init_pid(const char *name); extern pid_t get_init_pid(const char *name);
extern int lxc_get_clone_flags(const char *name);
extern int lxc_command(const char *name, struct lxc_command *command, extern int lxc_command(const char *name, struct lxc_command *command,
int *stopped); int *stopped);
......
...@@ -279,6 +279,29 @@ int lxc_pid_callback(int fd, struct lxc_request *request, ...@@ -279,6 +279,29 @@ int lxc_pid_callback(int fd, struct lxc_request *request,
return 0; return 0;
} }
int lxc_clone_flags_callback(int fd, struct lxc_request *request,
struct lxc_handler *handler)
{
struct lxc_answer answer;
int ret;
answer.pid = 0;
answer.ret = handler->clone_flags;
ret = send(fd, &answer, sizeof(answer), 0);
if (ret < 0) {
WARN("failed to send answer to the peer");
return -1;
}
if (ret != sizeof(answer)) {
ERROR("partial answer sent");
return -1;
}
return 0;
}
int lxc_set_state(const char *name, struct lxc_handler *handler, lxc_state_t state) int lxc_set_state(const char *name, struct lxc_handler *handler, lxc_state_t state)
{ {
handler->state = state; handler->state = state;
...@@ -558,7 +581,6 @@ out_warn_father: ...@@ -558,7 +581,6 @@ out_warn_father:
int lxc_spawn(struct lxc_handler *handler) int lxc_spawn(struct lxc_handler *handler)
{ {
int clone_flags;
int failed_before_rename = 0; int failed_before_rename = 0;
const char *name = handler->name; const char *name = handler->name;
int pinfd; int pinfd;
...@@ -566,10 +588,10 @@ int lxc_spawn(struct lxc_handler *handler) ...@@ -566,10 +588,10 @@ int lxc_spawn(struct lxc_handler *handler)
if (lxc_sync_init(handler)) if (lxc_sync_init(handler))
return -1; return -1;
clone_flags = CLONE_NEWUTS|CLONE_NEWPID|CLONE_NEWIPC|CLONE_NEWNS; handler->clone_flags = CLONE_NEWUTS|CLONE_NEWPID|CLONE_NEWIPC|CLONE_NEWNS;
if (!lxc_list_empty(&handler->conf->network)) { if (!lxc_list_empty(&handler->conf->network)) {
clone_flags |= CLONE_NEWNET; handler->clone_flags |= CLONE_NEWNET;
/* Find gateway addresses from the link device, which is /* Find gateway addresses from the link device, which is
* no longer accessible inside the container. Do this * no longer accessible inside the container. Do this
...@@ -603,7 +625,7 @@ int lxc_spawn(struct lxc_handler *handler) ...@@ -603,7 +625,7 @@ int lxc_spawn(struct lxc_handler *handler)
} }
/* Create a process in a new set of namespaces */ /* Create a process in a new set of namespaces */
handler->pid = lxc_clone(do_start, handler, clone_flags); handler->pid = lxc_clone(do_start, handler, handler->clone_flags);
if (handler->pid < 0) { if (handler->pid < 0) {
SYSERROR("failed to fork into a new namespace"); SYSERROR("failed to fork into a new namespace");
goto out_delete_net; goto out_delete_net;
...@@ -621,7 +643,7 @@ int lxc_spawn(struct lxc_handler *handler) ...@@ -621,7 +643,7 @@ int lxc_spawn(struct lxc_handler *handler)
goto out_delete_net; goto out_delete_net;
/* Create the network configuration */ /* Create the network configuration */
if (clone_flags & CLONE_NEWNET) { if (handler->clone_flags & CLONE_NEWNET) {
if (lxc_assign_network(&handler->conf->network, handler->pid)) { if (lxc_assign_network(&handler->conf->network, handler->pid)) {
ERROR("failed to create the configured network"); ERROR("failed to create the configured network");
goto out_delete_net; goto out_delete_net;
...@@ -651,7 +673,7 @@ int lxc_spawn(struct lxc_handler *handler) ...@@ -651,7 +673,7 @@ int lxc_spawn(struct lxc_handler *handler)
return 0; return 0;
out_delete_net: out_delete_net:
if (clone_flags & CLONE_NEWNET) if (handler->clone_flags & CLONE_NEWNET)
lxc_delete_network(handler); lxc_delete_network(handler);
out_abort: out_abort:
lxc_abort(name, handler); lxc_abort(name, handler);
......
...@@ -39,6 +39,7 @@ struct lxc_handler { ...@@ -39,6 +39,7 @@ struct lxc_handler {
pid_t pid; pid_t pid;
char *name; char *name;
lxc_state_t state; lxc_state_t state;
int clone_flags;
int sigfd; int sigfd;
sigset_t oldmask; sigset_t oldmask;
struct lxc_conf *conf; struct lxc_conf *conf;
......
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