replace common start_arg by private start_arg

the following patch moves the start argument in private
structs which are opaque to lxc_spawn(). To achieve this goal,
we need to move the sv[2] socketpair and lxc_handler

Signed-off-by: Cedric Le Goater <clg@fr.ibm.com>
Signed-off-by: Daniel Lezcano <dlezcano@fr.ibm.com>
This commit is contained in:
Cedric Le Goater 2010-05-26 16:54:48 +02:00 committed by Daniel Lezcano
parent ffe1e01a50
commit 23c53af96d
2 changed files with 38 additions and 37 deletions

View File

@ -413,8 +413,7 @@ void lxc_abort(const char *name, struct lxc_handler *handler)
static int do_start(void *data) static int do_start(void *data)
{ {
struct start_arg *arg = data; struct lxc_handler *handler = data;
struct lxc_handler *handler = arg->handler;
int err = -1, sync; int err = -1, sync;
if (sigprocmask(SIG_SETMASK, &handler->oldmask, NULL)) { if (sigprocmask(SIG_SETMASK, &handler->oldmask, NULL)) {
@ -422,19 +421,19 @@ static int do_start(void *data)
return -1; return -1;
} }
close(arg->sv[1]); close(handler->sv[1]);
/* Be sure we don't inherit this after the exec */ /* Be sure we don't inherit this after the exec */
fcntl(arg->sv[0], F_SETFD, FD_CLOEXEC); fcntl(handler->sv[0], F_SETFD, FD_CLOEXEC);
/* Tell our father he can begin to configure the container */ /* Tell our father he can begin to configure the container */
if (write(arg->sv[0], &sync, sizeof(sync)) < 0) { if (write(handler->sv[0], &sync, sizeof(sync)) < 0) {
SYSERROR("failed to write socket"); SYSERROR("failed to write socket");
return -1; return -1;
} }
/* Wait for the father to finish the configuration */ /* Wait for the father to finish the configuration */
if (read(arg->sv[0], &sync, sizeof(sync)) < 0) { if (read(handler->sv[0], &sync, sizeof(sync)) < 0) {
SYSERROR("failed to read socket"); SYSERROR("failed to read socket");
return -1; return -1;
} }
@ -459,17 +458,17 @@ static int do_start(void *data)
/* after this call, we are in error because this /* after this call, we are in error because this
* ops should not return as it execs */ * ops should not return as it execs */
if (handler->ops->start(handler, arg)) if (handler->ops->start(handler, handler->data))
return -1; return -1;
out_warn_father: out_warn_father:
/* If the exec fails, tell that to our father */ /* If the exec fails, tell that to our father */
if (write(arg->sv[0], &err, sizeof(err)) < 0) if (write(handler->sv[0], &err, sizeof(err)) < 0)
SYSERROR("failed to write the socket"); SYSERROR("failed to write the socket");
return -1; return -1;
} }
int lxc_spawn(struct lxc_handler *handler, struct start_arg *arg, int flags) int lxc_spawn(struct lxc_handler *handler)
{ {
int clone_flags; int clone_flags;
int sync; int sync;
@ -477,7 +476,7 @@ int lxc_spawn(struct lxc_handler *handler, struct start_arg *arg, int flags)
const char *name = handler->name; const char *name = handler->name;
/* Synchro socketpair */ /* Synchro socketpair */
if (socketpair(AF_LOCAL, SOCK_STREAM, 0, arg->sv)) { if (socketpair(AF_LOCAL, SOCK_STREAM, 0, handler->sv)) {
SYSERROR("failed to create communication socketpair"); SYSERROR("failed to create communication socketpair");
return -1; return -1;
} }
@ -492,25 +491,24 @@ int lxc_spawn(struct lxc_handler *handler, struct start_arg *arg, int flags)
*/ */
if (lxc_create_network(&handler->conf->network)) { if (lxc_create_network(&handler->conf->network)) {
ERROR("failed to create the network"); ERROR("failed to create the network");
close(arg->sv[0]); close(handler->sv[0]);
close(arg->sv[1]); close(handler->sv[1]);
return -1; return -1;
} }
} }
/* Create a process in a new set of namespaces */ /* Create a process in a new set of namespaces */
arg->handler = handler; handler->pid = lxc_clone(do_start, handler, clone_flags);
handler->pid = lxc_clone(do_start, arg, 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;
} }
close(arg->sv[0]); close(handler->sv[0]);
/* Wait for the child to be ready */ /* Wait for the child to be ready */
if (read(arg->sv[1], &sync, sizeof(sync)) <= 0) { if (read(handler->sv[1], &sync, sizeof(sync)) <= 0) {
ERROR("sync read failure : %m"); ERROR("sync read failure : %m");
failed_before_rename = 1; failed_before_rename = 1;
} }
@ -530,18 +528,18 @@ int lxc_spawn(struct lxc_handler *handler, struct start_arg *arg, int flags)
} }
/* Tell the child to continue its initialization */ /* Tell the child to continue its initialization */
if (write(arg->sv[1], &sync, sizeof(sync)) < 0) { if (write(handler->sv[1], &sync, sizeof(sync)) < 0) {
SYSERROR("failed to write the socket"); SYSERROR("failed to write the socket");
goto out_abort; goto out_abort;
} }
/* Wait for the child to exec or returning an error */ /* Wait for the child to exec or returning an error */
if (read(arg->sv[1], &sync, sizeof(sync)) < 0) { if (read(handler->sv[1], &sync, sizeof(sync)) < 0) {
ERROR("failed to read the socket"); ERROR("failed to read the socket");
goto out_abort; goto out_abort;
} }
if (handler->ops->post_start(handler, arg, flags)) if (handler->ops->post_start(handler, handler->data))
goto out_abort; goto out_abort;
if (lxc_set_state(name, handler, RUNNING)) { if (lxc_set_state(name, handler, RUNNING)) {
@ -550,7 +548,7 @@ int lxc_spawn(struct lxc_handler *handler, struct start_arg *arg, int flags)
goto out_abort; goto out_abort;
} }
close(arg->sv[1]); close(handler->sv[1]);
return 0; return 0;
out_delete_net: out_delete_net:
@ -558,12 +556,18 @@ out_delete_net:
lxc_delete_network(&handler->conf->network); lxc_delete_network(&handler->conf->network);
out_abort: out_abort:
lxc_abort(name, handler); lxc_abort(name, handler);
close(arg->sv[1]); close(handler->sv[1]);
return -1; return -1;
} }
static int start(struct lxc_handler *handler, struct start_arg *arg) struct start_arg {
char *const *argv;
};
static int start(struct lxc_handler *handler, void* data)
{ {
struct start_arg *arg = data;
NOTICE("exec'ing '%s'", arg->argv[0]); NOTICE("exec'ing '%s'", arg->argv[0]);
execvp(arg->argv[0], arg->argv); execvp(arg->argv[0], arg->argv);
@ -571,9 +575,10 @@ static int start(struct lxc_handler *handler, struct start_arg *arg)
return 0; return 0;
} }
static int post_start(struct lxc_handler *handler, struct start_arg *arg, static int post_start(struct lxc_handler *handler, void* data)
int flags)
{ {
struct start_arg *arg = data;
NOTICE("'%s' started with pid '%d'", arg->argv[0], handler->pid); NOTICE("'%s' started with pid '%d'", arg->argv[0], handler->pid);
return 0; return 0;
} }
@ -588,6 +593,9 @@ int lxc_start(const char *name, char *const argv[], struct lxc_conf *conf)
struct lxc_handler *handler; struct lxc_handler *handler;
int err = -1; int err = -1;
int status; int status;
struct start_arg start_arg = {
.argv = argv,
};
if (lxc_check_inherited(-1)) if (lxc_check_inherited(-1))
return -1; return -1;
@ -598,12 +606,9 @@ int lxc_start(const char *name, char *const argv[], struct lxc_conf *conf)
return -1; return -1;
} }
handler->ops = &start_ops; handler->ops = &start_ops;
handler->data = &start_arg;
struct start_arg start_arg = { err = lxc_spawn(handler);
.argv = argv,
};
err = lxc_spawn(handler, &start_arg, 0);
if (err) { if (err) {
ERROR("failed to spawn '%s'", argv[0]); ERROR("failed to spawn '%s'", argv[0]);
goto out_fini; goto out_fini;

View File

@ -32,8 +32,8 @@ struct start_arg;
struct lxc_handler; struct lxc_handler;
struct lxc_operations { struct lxc_operations {
int (*start)(struct lxc_handler *, struct start_arg *); int (*start)(struct lxc_handler *, void *);
int (*post_start)(struct lxc_handler *, struct start_arg *, int); int (*post_start)(struct lxc_handler *, void *);
}; };
struct lxc_handler { struct lxc_handler {
@ -45,18 +45,14 @@ struct lxc_handler {
sigset_t oldmask; sigset_t oldmask;
struct lxc_conf *conf; struct lxc_conf *conf;
struct lxc_operations *ops; struct lxc_operations *ops;
}; void *data;
struct start_arg {
struct lxc_handler *handler;
int sv[2]; int sv[2];
char *const *argv; char *const *argv;
int sfd; int sfd;
}; };
extern struct lxc_handler *lxc_init(const char *name, struct lxc_conf *); extern struct lxc_handler *lxc_init(const char *name, struct lxc_conf *);
extern int lxc_spawn(struct lxc_handler *, struct start_arg *start_arg, extern int lxc_spawn(struct lxc_handler *);
int restart_flags);
extern int lxc_poll(const char *name, struct lxc_handler *handler); extern int lxc_poll(const char *name, struct lxc_handler *handler);
extern void lxc_abort(const char *name, struct lxc_handler *handler); extern void lxc_abort(const char *name, struct lxc_handler *handler);