From: Michel Normand Date: Thu, 29 Apr 2010 08:03:59 +0000 (+0200) Subject: add --statefd option to lxc-checkpoint/restart X-Git-Tag: lxc-0.7.0~103 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=883a816820b9384f475a8a82d10b07482d5cf340;p=thirdparty%2Flxc.git add --statefd option to lxc-checkpoint/restart This new option is to have user to pass a fd in place of statefile name. Simple usage with file open in bash: === $rm -f *.log; lxc-execute -n foo -- pi1 44444 $rm -rf /tmp/sf; lxc-checkpoint -n foo -k --statefd 3 3>/tmp/sf && lxc-restart -n bar --statefd 4 4 Signed-off-by: Daniel Lezcano --- diff --git a/src/lxc/arguments.h b/src/lxc/arguments.h index 3bc027d47..1c5de4a61 100644 --- a/src/lxc/arguments.h +++ b/src/lxc/arguments.h @@ -44,9 +44,10 @@ struct lxc_arguments { int quiet; int daemonize; const char *rcfile; - const char *statefile; - /* for lxc-checkpoint */ + /* for lxc-checkpoint/restart */ + const char *statefile; + int statefd; int flags; /* for lxc-console */ diff --git a/src/lxc/lxc_checkpoint.c b/src/lxc/lxc_checkpoint.c index b67a53d07..1ed5325fd 100644 --- a/src/lxc/lxc_checkpoint.c +++ b/src/lxc/lxc_checkpoint.c @@ -40,11 +40,16 @@ lxc_log_define(lxc_checkpoint_ui, lxc_checkpoint); static int my_checker(const struct lxc_arguments* args) { - if (!args->statefile) { + if ((!args->statefile) && (args->statefd == -1)) { lxc_error(args, "no statefile specified"); return -1; } + if ((args->statefile) && (args->statefd != -1)) { + lxc_error(args, "--statefile AND --statefd abnormally set"); + return -1; + } + return 0; } @@ -54,6 +59,18 @@ static int my_parser(struct lxc_arguments* args, int c, char* arg) case 'k': args->flags = LXC_FLAG_HALT; break; case 'p': args->flags = LXC_FLAG_PAUSE; break; case 'S': args->statefile = arg; break; + case 'd': { + long val; + errno = 0; + val = strtol(arg, (char **)NULL, 10); + if (errno) { + lxc_error(args, "invalid statefd '%s' : %m\n", + arg); + return -1; + } + args->statefd = (int)val; + break; + } } return 0; } @@ -62,27 +79,29 @@ static const struct option my_longopts[] = { {"kill", no_argument, 0, 'k'}, {"pause", no_argument, 0, 'p'}, {"statefile", required_argument, 0, 'S'}, + {"statefd", required_argument, 0, 'd'}, LXC_COMMON_OPTIONS }; static struct lxc_arguments my_args = { .progname = "lxc-checkpoint", .help = "\ ---name=NAME --statefile STATEFILE\n\ +--name=NAME --statefile FILE\n\ \n\ -lxc-checkpoint checkpoints in STATEFILE the NAME container\n\ +lxc-checkpoint checkpoints in FILE the NAME container\n\ \n\ Options :\n\ -n, --name=NAME NAME for name of the container\n\ -k, --kill stop the container after checkpoint\n\ -p, --pause don't unfreeze the container after the checkpoint\n\ - -S, --statefile=STATEFILE file in which to store the statefile\n", + -S, --statefile=FILE write the container state into this file, or\n\ + -d, --statefd=FD write the container state into this file descriptor\n", .options = my_longopts, .parser = my_parser, .checker = my_checker, - .rcfile = NULL, + .statefd = -1, }; int main(int argc, char *argv[]) @@ -99,11 +118,16 @@ int main(int argc, char *argv[]) if (ret) return ret; + if (my_args.statefd != -1) + sfd = my_args.statefd; + #define OPEN_WRITE_MODE O_CREAT | O_RDWR | O_EXCL | O_CLOEXEC | O_LARGEFILE - sfd = open(my_args.statefile, OPEN_WRITE_MODE, 0600); - if (sfd < 0) { - ERROR("'%s' open failure : %m", my_args.statefile); - return sfd; + if (my_args.statefile) { + sfd = open(my_args.statefile, OPEN_WRITE_MODE, 0600); + if (sfd < 0) { + ERROR("'%s' open failure : %m", my_args.statefile); + return sfd; + } } ret = lxc_checkpoint(my_args.name, sfd, my_args.flags); @@ -112,5 +136,7 @@ int main(int argc, char *argv[]) else INFO("'%s' checkpointed", my_args.name); + if (my_args.statefile) + close(sfd); return ret; } diff --git a/src/lxc/lxc_restart.c b/src/lxc/lxc_restart.c index 6ce5cafd5..ae03d0fe3 100644 --- a/src/lxc/lxc_restart.c +++ b/src/lxc/lxc_restart.c @@ -42,11 +42,16 @@ static struct lxc_list defines; static int my_checker(const struct lxc_arguments* args) { - if (!args->statefile) { + if ((!args->statefile) && (args->statefd == -1)) { lxc_error(args, "no statefile specified"); return -1; } + if ((args->statefile) && (args->statefd != -1)) { + lxc_error(args, "--statefile AND --statefd abnormally set"); + return -1; + } + return 0; } @@ -57,6 +62,18 @@ static int my_parser(struct lxc_arguments* args, int c, char* arg) case 'f': args->rcfile = arg; break; case 'p': args->flags = LXC_FLAG_PAUSE; break; case 's': return lxc_config_define_add(&defines, arg); + case 'd': { + long val; + errno = 0; + val = strtol(arg, (char **)NULL, 10); + if (errno) { + lxc_error(args, "invalid statefd '%s' : %m\n", + arg); + return -1; + } + args->statefd = (int)val; + break; + } } return 0; @@ -64,6 +81,7 @@ static int my_parser(struct lxc_arguments* args, int c, char* arg) static const struct option my_longopts[] = { {"statefile", required_argument, 0, 'S'}, + {"statefd", required_argument, 0, 'd'}, {"rcfile", required_argument, 0, 'f'}, {"pause", no_argument, 0, 'p'}, {"define", required_argument, 0, 's'}, @@ -73,24 +91,28 @@ static const struct option my_longopts[] = { static struct lxc_arguments my_args = { .progname = "lxc-restart", .help = "\ ---name=NAME --statefile STATEFILE\n\ +--name=NAME --statefile FILE\n\ \n\ -lxc-restart restarts from STATEFILE the NAME container\n\ +lxc-restart restarts from FILE the NAME container\n\ \n\ Options :\n\ -n, --name=NAME NAME for name of the container\n\ - -p, --pause do not release the container after the restart\n\ - -S, --statefile=STATEFILE file from which to read data\n\ + -p, --pause do not unfreeze the container after the restart\n\ + -S, --statefile=FILE read the container state from this file, or\n\ + -d, --statefd=FD read the container state from this file descriptor\n\ -f, --rcfile=FILE Load configuration file FILE\n\ -s, --define KEY=VAL Assign VAL to configuration variable KEY\n", .options = my_longopts, .parser = my_parser, .checker = my_checker, + + .statefd = -1, }; int main(int argc, char *argv[]) { int sfd = -1; + int ret; char *rcfile = NULL; struct lxc_conf *conf; @@ -133,12 +155,21 @@ int main(int argc, char *argv[]) if (lxc_config_define_load(&defines, conf)) return -1; + if (my_args.statefd != -1) + sfd = my_args.statefd; + #define OPEN_READ_MODE O_RDONLY | O_CLOEXEC | O_LARGEFILE - sfd = open(my_args.statefile, OPEN_READ_MODE, 0); - if (sfd < 0) { - ERROR("'%s' open failure : %m", my_args.statefile); - return sfd; + if (my_args.statefile) { + sfd = open(my_args.statefile, OPEN_READ_MODE, 0); + if (sfd < 0) { + ERROR("'%s' open failure : %m", my_args.statefile); + return sfd; + } } - return lxc_restart(my_args.name, sfd, conf, my_args.flags); + ret = lxc_restart(my_args.name, sfd, conf, my_args.flags); + + if (my_args.statefile) + close(sfd); + return ret; }