Commit 9b8e796c by Michel Normand Committed by Daniel Lezcano

lxc: add --statefile opt to lxc-checkpoint/restart

based on patch from: Sukadev Bhattiprolu <sukadev@linux.vnet.ibm.com> but also: * remove the deprecated --directory one. * change liblxc api of checkpoint/restart to use fd and not string. * explicitely report error messages for the checkpoint/restart stub functions. Signed-off-by: 's avatarMichel Normand <normand@fr.ibm.com> Signed-off-by: 's avatarDaniel Lezcano <dlezcano@fr.ibm.com>
parent 9ea8066a
...@@ -25,7 +25,8 @@ ...@@ -25,7 +25,8 @@
lxc_log_define(lxc_checkpoint, lxc); lxc_log_define(lxc_checkpoint, lxc);
int lxc_checkpoint(const char *name, const char *statefile, int flags) int lxc_checkpoint(const char *name, int sfd, int flags)
{ {
return 0; ERROR("'checkpoint' function not implemented");
return -1;
} }
...@@ -142,23 +142,23 @@ extern const char *lxc_strerror(int error); ...@@ -142,23 +142,23 @@ extern const char *lxc_strerror(int error);
/* /*
* Checkpoint a container * Checkpoint a container
* @name : the name of the container being checkpointed * @name : the name of the container being checkpointed
* @statefile: string object on which the container is checkpointed * @sfd: fd on which the container is checkpointed
* @flags : checkpoint flags (an ORed value) * @flags : checkpoint flags (an ORed value)
* Returns 0 on success, < 0 otherwise * Returns 0 on success, < 0 otherwise
*/ */
extern int lxc_checkpoint(const char *name, const char *statefile, int flags); extern int lxc_checkpoint(const char *name, int sfd, int flags);
#define LXC_FLAG_PAUSE 1 #define LXC_FLAG_PAUSE 1
#define LXC_FLAG_HALT 2 #define LXC_FLAG_HALT 2
/* /*
* Restart a container * Restart a container
* @name : the name of the container being restarted * @name : the name of the container being restarted
* @statefile: string object from which the container is restarted * @sfd: fd from which the container is restarted
* @conf: lxc_conf structure. * @conf: lxc_conf structure.
* @flags : restart flags (an ORed value) * @flags : restart flags (an ORed value)
* Returns 0 on success, < 0 otherwise * Returns 0 on success, < 0 otherwise
*/ */
extern int lxc_restart(const char *, const char *, struct lxc_conf *, int); extern int lxc_restart(const char *, int, struct lxc_conf *, int);
/* /*
* Returns the version number of the library * Returns the version number of the library
......
...@@ -27,6 +27,7 @@ ...@@ -27,6 +27,7 @@
#include <errno.h> #include <errno.h>
#include <sys/stat.h> #include <sys/stat.h>
#include <sys/types.h> #include <sys/types.h>
#include <fcntl.h>
#include <lxc/lxc.h> #include <lxc/lxc.h>
#include <lxc/log.h> #include <lxc/log.h>
...@@ -52,7 +53,7 @@ static int my_parser(struct lxc_arguments* args, int c, char* arg) ...@@ -52,7 +53,7 @@ static int my_parser(struct lxc_arguments* args, int c, char* arg)
switch (c) { switch (c) {
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 'd': args->statefile = arg; break; case 'S': args->statefile = arg; break;
} }
return 0; return 0;
} }
...@@ -60,14 +61,14 @@ static int my_parser(struct lxc_arguments* args, int c, char* arg) ...@@ -60,14 +61,14 @@ static int my_parser(struct lxc_arguments* args, int c, char* arg)
static const struct option my_longopts[] = { 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'},
{"directory", required_argument, 0, 'd'}, {"statefile", required_argument, 0, 'S'},
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 --directory STATEFILE\n\ --name=NAME --statefile STATEFILE\n\
\n\ \n\
lxc-checkpoint checkpoints in STATEFILE the NAME container\n\ lxc-checkpoint checkpoints in STATEFILE the NAME container\n\
\n\ \n\
...@@ -75,7 +76,7 @@ Options :\n\ ...@@ -75,7 +76,7 @@ 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\
-d, --directory=STATEFILE where to store the statefile\n", -S, --statefile=STATEFILE file in which to store the statefile\n",
.options = my_longopts, .options = my_longopts,
.parser = my_parser, .parser = my_parser,
...@@ -84,19 +85,10 @@ Options :\n\ ...@@ -84,19 +85,10 @@ Options :\n\
.rcfile = NULL, .rcfile = NULL,
}; };
static int create_statefile(const char *dir)
{
if (mkdir(dir, 0700) == -1 && errno != EEXIST) {
ERROR("'%s' creation error : %m", dir);
return -1;
}
return 0;
}
int main(int argc, char *argv[]) int main(int argc, char *argv[])
{ {
int ret; int ret;
int sfd = -1;
ret = lxc_arguments_parse(&my_args, argc, argv); ret = lxc_arguments_parse(&my_args, argc, argv);
if (ret) if (ret)
...@@ -107,11 +99,14 @@ int main(int argc, char *argv[]) ...@@ -107,11 +99,14 @@ int main(int argc, char *argv[])
if (ret) if (ret)
return ret; return ret;
ret = create_statefile(my_args.statefile); #define OPEN_WRITE_MODE O_CREAT | O_RDWR | O_EXCL | O_CLOEXEC | O_LARGEFILE
if (ret) sfd = open(my_args.statefile, OPEN_WRITE_MODE, 0600);
return ret; if (sfd < 0) {
ERROR("'%s' open failure : %m", my_args.statefile);
return sfd;
}
ret = lxc_checkpoint(my_args.name, my_args.statefile, my_args.flags); ret = lxc_checkpoint(my_args.name, sfd, my_args.flags);
if (ret) if (ret)
ERROR("failed to checkpoint '%s'", my_args.name); ERROR("failed to checkpoint '%s'", my_args.name);
else else
......
...@@ -27,6 +27,7 @@ ...@@ -27,6 +27,7 @@
#include <unistd.h> #include <unistd.h>
#include <errno.h> #include <errno.h>
#include <sys/types.h> #include <sys/types.h>
#include <fcntl.h>
#include "log.h" #include "log.h"
#include "lxc.h" #include "lxc.h"
...@@ -52,7 +53,7 @@ static int my_checker(const struct lxc_arguments* args) ...@@ -52,7 +53,7 @@ static int my_checker(const struct lxc_arguments* args)
static int my_parser(struct lxc_arguments* args, int c, char* arg) static int my_parser(struct lxc_arguments* args, int c, char* arg)
{ {
switch (c) { switch (c) {
case 'd': args->statefile = arg; break; case 'S': args->statefile = arg; break;
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);
...@@ -62,7 +63,7 @@ static int my_parser(struct lxc_arguments* args, int c, char* arg) ...@@ -62,7 +63,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[] = {
{"directory", required_argument, 0, 'd'}, {"statefile", required_argument, 0, 'S'},
{"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'},
...@@ -72,14 +73,14 @@ static const struct option my_longopts[] = { ...@@ -72,14 +73,14 @@ 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 --directory STATEFILE\n\ --name=NAME --statefile STATEFILE\n\
\n\ \n\
lxc-restart restarts from STATEFILE the NAME container\n\ lxc-restart restarts from STATEFILE 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 release the container after the restart\n\
-d, --directory=STATEFILE for name of statefile\n\ -S, --statefile=STATEFILE file from which to read data\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,
...@@ -89,6 +90,7 @@ Options :\n\ ...@@ -89,6 +90,7 @@ Options :\n\
int main(int argc, char *argv[]) int main(int argc, char *argv[])
{ {
int sfd = -1;
char *rcfile = NULL; char *rcfile = NULL;
struct lxc_conf *conf; struct lxc_conf *conf;
...@@ -131,6 +133,12 @@ int main(int argc, char *argv[]) ...@@ -131,6 +133,12 @@ int main(int argc, char *argv[])
if (lxc_config_define_load(&defines, conf)) if (lxc_config_define_load(&defines, conf))
return -1; return -1;
return lxc_restart(my_args.name, my_args.statefile, conf, #define OPEN_READ_MODE O_RDONLY | O_CLOEXEC | O_LARGEFILE
my_args.flags); 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);
} }
...@@ -25,8 +25,8 @@ ...@@ -25,8 +25,8 @@
lxc_log_define(lxc_restart, lxc); lxc_log_define(lxc_restart, lxc);
int lxc_restart(const char *name, const char *statefile, struct lxc_conf *conf, int lxc_restart(const char *name, int sfd, struct lxc_conf *conf, int flags)
int flags)
{ {
return 0; ERROR("'restart' function not implemented");
return -1;
} }
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