Commit e6126dbe by Michel Normand Committed by Daniel Lezcano

Add ops for start

In order to define a specific function for restart, let's create an ops where we will be able to specify a function for restart too. Signed-off-by: 's avatarMichel Normand <normand@fr.ibm.com> Signed-off-by: 's avatarDaniel Lezcano <dlezcano@fr.ibm.com>
parent fc25b815
...@@ -411,12 +411,11 @@ void lxc_abort(const char *name, struct lxc_handler *handler) ...@@ -411,12 +411,11 @@ void lxc_abort(const char *name, struct lxc_handler *handler)
kill(handler->pid, SIGKILL); kill(handler->pid, SIGKILL);
} }
int do_start(void *arg) static int do_start(void *arg)
{ {
struct start_arg *start_arg = arg; struct start_arg *start_arg = arg;
struct lxc_handler *handler = start_arg->handler; struct lxc_handler *handler = start_arg->handler;
const char *name = start_arg->name; const char *name = start_arg->name;
char *const *argv = start_arg->argv;
int *sv = start_arg->sv; int *sv = start_arg->sv;
int err = -1, sync; int err = -1, sync;
...@@ -460,10 +459,10 @@ int do_start(void *arg) ...@@ -460,10 +459,10 @@ int do_start(void *arg)
close(handler->sigfd); close(handler->sigfd);
NOTICE("exec'ing '%s'", argv[0]); /* after this call, we are in error because this
* ops should not return as it execs */
execvp(argv[0], argv); if (handler->ops->start(handler, start_arg))
SYSERROR("failed to exec %s", argv[0]); 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 */
...@@ -472,20 +471,16 @@ out_warn_father: ...@@ -472,20 +471,16 @@ out_warn_father:
return -1; return -1;
} }
int lxc_spawn(const char *name, struct lxc_handler *handler, char *const argv[]) int lxc_spawn(struct start_arg *start_arg, int flags)
{ {
int sv[2]; int sv[2];
int clone_flags; int clone_flags;
int err = -1, sync; int sync;
int failed_before_rename = 0; int failed_before_rename = 0;
const char *name = start_arg->name;
struct lxc_handler *handler = start_arg->handler;
struct start_arg start_arg = { start_arg->sv = sv;
.name = name,
.argv = argv,
.sfd = -1,
.handler = handler,
.sv = sv,
};
/* Synchro socketpair */ /* Synchro socketpair */
if (socketpair(AF_LOCAL, SOCK_STREAM, 0, sv)) { if (socketpair(AF_LOCAL, SOCK_STREAM, 0, sv)) {
...@@ -508,7 +503,7 @@ int lxc_spawn(const char *name, struct lxc_handler *handler, char *const argv[]) ...@@ -508,7 +503,7 @@ int lxc_spawn(const char *name, struct lxc_handler *handler, char *const argv[])
} }
/* Create a process in a new set of namespaces */ /* Create a process in a new set of namespaces */
handler->pid = lxc_clone(do_start, &start_arg, clone_flags); handler->pid = lxc_clone(do_start, 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;
...@@ -548,20 +543,22 @@ int lxc_spawn(const char *name, struct lxc_handler *handler, char *const argv[]) ...@@ -548,20 +543,22 @@ int lxc_spawn(const char *name, struct lxc_handler *handler, char *const argv[])
goto out_abort; goto out_abort;
} }
if (handler->ops->post_start(handler, start_arg, flags))
goto out_abort;
if (lxc_set_state(name, handler, RUNNING)) { if (lxc_set_state(name, handler, RUNNING)) {
ERROR("failed to set state to %s", ERROR("failed to set state to %s",
lxc_state2str(RUNNING)); lxc_state2str(RUNNING));
goto out_abort; goto out_abort;
} }
err = 0; close(sv[1]);
return 0;
NOTICE("'%s' started with pid '%d'", argv[0], handler->pid);
out_close: out_close:
close(sv[0]); close(sv[0]);
close(sv[1]); close(sv[1]);
return err; return -1;
out_delete_net: out_delete_net:
if (clone_flags & CLONE_NEWNET) if (clone_flags & CLONE_NEWNET)
...@@ -572,6 +569,27 @@ out_abort: ...@@ -572,6 +569,27 @@ out_abort:
return -1; return -1;
} }
static int start(struct lxc_handler *handler, struct start_arg *arg)
{
NOTICE("exec'ing '%s'", arg->argv[0]);
execvp(arg->argv[0], arg->argv);
SYSERROR("failed to exec %s", arg->argv[0]);
return 0;
}
static int post_start(struct lxc_handler *handler, struct start_arg *arg,
int flags)
{
NOTICE("'%s' started with pid '%d'", arg->argv[0], handler->pid);
return 0;
}
static struct lxc_operations start_ops = {
.start = start,
.post_start = post_start
};
int lxc_start(const char *name, char *const argv[], struct lxc_conf *conf) int lxc_start(const char *name, char *const argv[], struct lxc_conf *conf)
{ {
struct lxc_handler *handler; struct lxc_handler *handler;
...@@ -586,8 +604,16 @@ int lxc_start(const char *name, char *const argv[], struct lxc_conf *conf) ...@@ -586,8 +604,16 @@ int lxc_start(const char *name, char *const argv[], struct lxc_conf *conf)
ERROR("failed to initialize the container"); ERROR("failed to initialize the container");
return -1; return -1;
} }
handler->ops = &start_ops;
struct start_arg start_arg = {
.name = name,
.argv = argv,
.sfd = -1,
.handler = handler,
};
err = lxc_spawn(name, handler, argv); err = lxc_spawn(&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;
......
...@@ -46,10 +46,8 @@ struct start_arg { ...@@ -46,10 +46,8 @@ struct start_arg {
int sfd; int sfd;
}; };
extern int do_start(void *arg);
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(const char *name, struct lxc_handler *handler, extern int lxc_spawn(struct start_arg *start_arg, int restart_flags);
char *const argv[]);
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);
......
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