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 daemonize;
const char *rcfile;
const char *statefile;
/* for lxc-checkpoint */
/* for lxc-checkpoint/restart */
const char *statefile;
int statefd;
int flags;
/* 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)
{
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;
}

View File

@ -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;
}