]> git.ipfire.org Git - thirdparty/lxc.git/commitdiff
add --statefd option to lxc-checkpoint/restart
authorMichel Normand <normand@fr.ibm.com>
Thu, 29 Apr 2010 08:03:59 +0000 (10:03 +0200)
committerDaniel Lezcano <dlezcano@fr.ibm.com>
Thu, 29 Apr 2010 08:03:59 +0000 (10:03 +0200)
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>
src/lxc/arguments.h
src/lxc/lxc_checkpoint.c
src/lxc/lxc_restart.c

index 3bc027d473b82fe47ee832543ba7828a45e1b9d6..1c5de4a61d00ff87733f38da439ce8fe77753d3e 100644 (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 */
index b67a53d070efb4b1395627bec136ed158ac8eb7e..1ed5325fdadb0bdcd7b53fd381b5a35dec5911b2 100644 (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;
 }
index 6ce5cafd586a7a4b84652e77bccd16e3d5680c28..ae03d0fe333094a3ce6e46ae0bbe3f60cf60f600 100644 (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;
 }