mirror of
https://git.proxmox.com/git/mirror_lxc
synced 2025-08-10 22:30:21 +00:00
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:
parent
affaa6da9d
commit
883a816820
@ -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 */
|
||||||
|
@ -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;
|
||||||
}
|
}
|
||||||
|
@ -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;
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user