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</tmp/sf
===

Signed-off-by: Michel Normand <normand@fr.ibm.com>
Signed-off-by: Daniel Lezcano <dlezcano@fr.ibm.com>
This commit is contained in:
Michel Normand 2010-04-29 10:03:59 +02:00 committed by Daniel Lezcano
parent affaa6da9d
commit 883a816820
3 changed files with 79 additions and 21 deletions

View File

@ -44,9 +44,10 @@ struct lxc_arguments {
int quiet; int quiet;
int daemonize; int daemonize;
const char *rcfile; const char *rcfile;
const char *statefile;
/* for lxc-checkpoint */ /* for lxc-checkpoint/restart */
const char *statefile;
int statefd;
int flags; int flags;
/* for lxc-console */ /* for lxc-console */

View File

@ -40,11 +40,16 @@ lxc_log_define(lxc_checkpoint_ui, lxc_checkpoint);
static int my_checker(const struct lxc_arguments* args) static int my_checker(const struct lxc_arguments* args)
{ {
if (!args->statefile) { if ((!args->statefile) && (args->statefd == -1)) {
lxc_error(args, "no statefile specified"); lxc_error(args, "no statefile specified");
return -1; return -1;
} }
if ((args->statefile) && (args->statefd != -1)) {
lxc_error(args, "--statefile AND --statefd abnormally set");
return -1;
}
return 0; 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 'k': args->flags = LXC_FLAG_HALT; break;
case 'p': args->flags = LXC_FLAG_PAUSE; break; case 'p': args->flags = LXC_FLAG_PAUSE; break;
case 'S': args->statefile = arg; 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; return 0;
} }
@ -62,27 +79,29 @@ static const struct option my_longopts[] = {
{"kill", no_argument, 0, 'k'}, {"kill", no_argument, 0, 'k'},
{"pause", no_argument, 0, 'p'}, {"pause", no_argument, 0, 'p'},
{"statefile", required_argument, 0, 'S'}, {"statefile", required_argument, 0, 'S'},
{"statefd", required_argument, 0, 'd'},
LXC_COMMON_OPTIONS LXC_COMMON_OPTIONS
}; };
static struct lxc_arguments my_args = { static struct lxc_arguments my_args = {
.progname = "lxc-checkpoint", .progname = "lxc-checkpoint",
.help = "\ .help = "\
--name=NAME --statefile STATEFILE\n\ --name=NAME --statefile FILE\n\
\n\ \n\
lxc-checkpoint checkpoints in STATEFILE the NAME container\n\ lxc-checkpoint checkpoints in FILE the NAME container\n\
\n\ \n\
Options :\n\ Options :\n\
-n, --name=NAME NAME for name of the container\n\ -n, --name=NAME NAME for name of the container\n\
-k, --kill stop the container after checkpoint\n\ -k, --kill stop the container after checkpoint\n\
-p, --pause don't unfreeze the container after the 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, .options = my_longopts,
.parser = my_parser, .parser = my_parser,
.checker = my_checker, .checker = my_checker,
.rcfile = NULL, .statefd = -1,
}; };
int main(int argc, char *argv[]) int main(int argc, char *argv[])
@ -99,12 +118,17 @@ int main(int argc, char *argv[])
if (ret) if (ret)
return 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 #define OPEN_WRITE_MODE O_CREAT | O_RDWR | O_EXCL | O_CLOEXEC | O_LARGEFILE
if (my_args.statefile) {
sfd = open(my_args.statefile, OPEN_WRITE_MODE, 0600); sfd = open(my_args.statefile, OPEN_WRITE_MODE, 0600);
if (sfd < 0) { if (sfd < 0) {
ERROR("'%s' open failure : %m", my_args.statefile); ERROR("'%s' open failure : %m", my_args.statefile);
return sfd; return sfd;
} }
}
ret = lxc_checkpoint(my_args.name, sfd, my_args.flags); ret = lxc_checkpoint(my_args.name, sfd, my_args.flags);
if (ret) if (ret)
@ -112,5 +136,7 @@ int main(int argc, char *argv[])
else else
INFO("'%s' checkpointed", my_args.name); INFO("'%s' checkpointed", my_args.name);
if (my_args.statefile)
close(sfd);
return ret; return ret;
} }

View File

@ -42,11 +42,16 @@ static struct lxc_list defines;
static int my_checker(const struct lxc_arguments* args) static int my_checker(const struct lxc_arguments* args)
{ {
if (!args->statefile) { if ((!args->statefile) && (args->statefd == -1)) {
lxc_error(args, "no statefile specified"); lxc_error(args, "no statefile specified");
return -1; return -1;
} }
if ((args->statefile) && (args->statefd != -1)) {
lxc_error(args, "--statefile AND --statefd abnormally set");
return -1;
}
return 0; 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 'f': args->rcfile = arg; break;
case 'p': args->flags = LXC_FLAG_PAUSE; break; case 'p': args->flags = LXC_FLAG_PAUSE; break;
case 's': return lxc_config_define_add(&defines, arg); 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; return 0;
@ -64,6 +81,7 @@ static int my_parser(struct lxc_arguments* args, int c, char* arg)
static const struct option my_longopts[] = { static const struct option my_longopts[] = {
{"statefile", required_argument, 0, 'S'}, {"statefile", required_argument, 0, 'S'},
{"statefd", required_argument, 0, 'd'},
{"rcfile", required_argument, 0, 'f'}, {"rcfile", required_argument, 0, 'f'},
{"pause", no_argument, 0, 'p'}, {"pause", no_argument, 0, 'p'},
{"define", required_argument, 0, 's'}, {"define", required_argument, 0, 's'},
@ -73,24 +91,28 @@ static const struct option my_longopts[] = {
static struct lxc_arguments my_args = { static struct lxc_arguments my_args = {
.progname = "lxc-restart", .progname = "lxc-restart",
.help = "\ .help = "\
--name=NAME --statefile STATEFILE\n\ --name=NAME --statefile FILE\n\
\n\ \n\
lxc-restart restarts from STATEFILE the NAME container\n\ lxc-restart restarts from FILE the NAME container\n\
\n\ \n\
Options :\n\ Options :\n\
-n, --name=NAME NAME for name of the container\n\ -n, --name=NAME NAME for name of the container\n\
-p, --pause do not release the container after the restart\n\ -p, --pause do not unfreeze the container after the restart\n\
-S, --statefile=STATEFILE file from which to read data\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\ -f, --rcfile=FILE Load configuration file FILE\n\
-s, --define KEY=VAL Assign VAL to configuration variable KEY\n", -s, --define KEY=VAL Assign VAL to configuration variable KEY\n",
.options = my_longopts, .options = my_longopts,
.parser = my_parser, .parser = my_parser,
.checker = my_checker, .checker = my_checker,
.statefd = -1,
}; };
int main(int argc, char *argv[]) int main(int argc, char *argv[])
{ {
int sfd = -1; int sfd = -1;
int ret;
char *rcfile = NULL; char *rcfile = NULL;
struct lxc_conf *conf; struct lxc_conf *conf;
@ -133,12 +155,21 @@ int main(int argc, char *argv[])
if (lxc_config_define_load(&defines, conf)) if (lxc_config_define_load(&defines, conf))
return -1; return -1;
if (my_args.statefd != -1)
sfd = my_args.statefd;
#define OPEN_READ_MODE O_RDONLY | O_CLOEXEC | O_LARGEFILE #define OPEN_READ_MODE O_RDONLY | O_CLOEXEC | O_LARGEFILE
if (my_args.statefile) {
sfd = open(my_args.statefile, OPEN_READ_MODE, 0); sfd = open(my_args.statefile, OPEN_READ_MODE, 0);
if (sfd < 0) { if (sfd < 0) {
ERROR("'%s' open failure : %m", my_args.statefile); ERROR("'%s' open failure : %m", my_args.statefile);
return sfd; 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;
} }