Updated version as PR on github.
On Thu, Aug 06, 2015 at 03:47:04PM +0200, Christian Brauner wrote: > - lxc_snapshot.c lacked necessary members in the associated lxc_arguments > struct > in arguments.h. This commit extends the lxc_arguments struct to include > several parameters used by lxc-snapshot which allows a rewrite that is more > consistent with the rest of the lxc-* executables. > - All tests have been moved beyond the call to lxc_log_init() to allow for the > messages to be printed or saved. > - Some small changes to the my_args struct. (The enum task is set to > SNAP (for snapshot) per default and variables illustrating the usage of the > command line flags are written in all caps.) > > Signed-off-by: Christian Brauner <christianvanbrau...@gmail.com> > --- > src/lxc/arguments.h | 8 ++ > src/lxc/lxc_snapshot.c | 317 > +++++++++++++++++++++++++++---------------------- > 2 files changed, 182 insertions(+), 143 deletions(-) > > diff --git a/src/lxc/arguments.h b/src/lxc/arguments.h > index cc85f86..86fd02e 100644 > --- a/src/lxc/arguments.h > +++ b/src/lxc/arguments.h > @@ -94,12 +94,20 @@ struct lxc_arguments { > int list; > char *groups; > > + /* lxc-snapshot and lxc-clone */ > + enum task {DESTROY, LIST, RESTORE, SNAP, } task; > + int print_comments; > + char *commentfile; > + char *newname; > + char *snapname; > + > /* remaining arguments */ > char *const *argv; > int argc; > > /* private arguments */ > void *data; > + > }; > > #define LXC_COMMON_OPTIONS \ > diff --git a/src/lxc/lxc_snapshot.c b/src/lxc/lxc_snapshot.c > index a03c0c0..99cbe48 100644 > --- a/src/lxc/lxc_snapshot.c > +++ b/src/lxc/lxc_snapshot.c > @@ -16,8 +16,8 @@ > * with this program; if not, write to the Free Software Foundation, Inc., > * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. > */ > -#include "config.h" > > +#include "confile.h" > #include <stdio.h> > #include <libgen.h> > #include <unistd.h> > @@ -35,18 +35,148 @@ > > lxc_log_define(lxc_snapshot_ui, lxc); > > -static char *newname; > -static char *snapshot; > +static int my_parser(struct lxc_arguments *args, int c, char *arg); > > -#define DO_SNAP 0 > -#define DO_LIST 1 > -#define DO_RESTORE 2 > -#define DO_DESTROY 3 > -static int action; > -static int print_comments; > -static char *commentfile; > +static const struct option my_longopts[] = { > + {"list", no_argument, 0, 'L'}, > + {"restore", required_argument, 0, 'r'}, > + {"destroy", required_argument, 0, 'd'}, > + {"comment", required_argument, 0, 'c'}, > + {"showcomments", no_argument, 0, 'C'}, > + LXC_COMMON_OPTIONS}; > + > +static struct lxc_arguments my_args = { > + .progname = "lxc-snapshot", > + .help = "\ > +--name=NAME [-P lxcpath] [-L [-C]] [-c commentfile] [-r snapname > [newname]]\n\ > +\n\ > +lxc-snapshot snapshots a container\n\ > +\n\ > +Options :\n\ > + -n, --name=NAME NAME for name of the container\n\ > + -L, --list list all snapshots\n\ > + -C, --showcomments show snapshot comments\n\ > + -c, --comment=FILE add FILE as a comment\n\ > + -r, --restore=NAME restore snapshot NAME, e.g. 'snap0'\n\ > + -d, --destroy=NAME destroy snapshot NAME, e.g. 'snap0'\n\ > + use ALL to destroy all snapshots\n", > + .options = my_longopts, > + .parser = my_parser, > + .checker = NULL, > + .task = SNAP, > +}; > + > +static int do_destroy_snapshots(struct lxc_container *c, char *snapname); > +static int do_list_snapshots(struct lxc_container *c, int print_comments); > +static int do_restore_snapshots(struct lxc_container *c, char *snapname, > + char *newname); > +static int do_snapshot(struct lxc_container *c, char *commentfile); > +static int do_snapshot_task(struct lxc_container *c, enum task task); > +static void print_file(char *path); > + > +int main(int argc, char *argv[]) > +{ > + struct lxc_container *c; > + int ret; > + > + if (lxc_arguments_parse(&my_args, argc, argv)) > + exit(EXIT_FAILURE); > + > + if (!my_args.log_file) > + my_args.log_file = "none"; > + > + if (lxc_log_init(my_args.name, my_args.log_file, my_args.log_priority, > + my_args.progname, my_args.quiet, my_args.lxcpath[0])) > + exit(EXIT_FAILURE); > + lxc_log_options_no_override(); > + > + if (geteuid()) { > + if (access(my_args.lxcpath[0], O_RDWR) < 0) { > + fprintf(stderr, "You lack access to %s\n", > + my_args.lxcpath[0]); > + exit(EXIT_FAILURE); > + } > + } > + > + if (my_args.argc > 1) { > + ERROR("Too many arguments"); > + exit(EXIT_FAILURE); > + } > + > + if (my_args.argc == 1) > + my_args.newname = my_args.argv[0]; > + > + c = lxc_container_new(my_args.name, my_args.lxcpath[0]); > + if (!c) { > + fprintf(stderr, "System error loading container\n"); > + exit(EXIT_FAILURE); > + } > + > + if (!c->may_control(c)) { > + fprintf(stderr, "Insufficent privileges to control %s\n", > + my_args.name); > + lxc_container_put(c); > + exit(EXIT_FAILURE); > + } > + > + ret = do_snapshot_task(c, my_args.task); > + > + lxc_container_put(c); > + > + if (ret == 0) > + exit(EXIT_SUCCESS); > + exit(EXIT_FAILURE); > +} > + > +static int do_snapshot_task(struct lxc_container *c, enum task task) > +{ > + int ret = 0; > + > + switch (task) { > + case DESTROY: > + ret = do_destroy_snapshots(c, my_args.snapname); > + break; > + case LIST: > + ret = do_list_snapshots(c, my_args.print_comments); > + break; > + case RESTORE: > + ret = > + do_restore_snapshots(c, my_args.snapname, my_args.newname); > + break; > + case SNAP: > + ret = do_snapshot(c, my_args.commentfile); > + break; > + } > + > + return ret; > +} > > -static int do_snapshot(struct lxc_container *c) > +static int my_parser(struct lxc_arguments *args, int c, char *arg) > +{ > + switch (c) { > + case 'L': > + args->task = LIST; > + break; > + case 'r': > + args->task = RESTORE; > + args->snapname = arg; > + break; > + case 'd': > + args->task = DESTROY; > + args->snapname = arg; > + break; > + case 'c': > + args->commentfile = arg; > + break; > + case 'C': > + args->print_comments = 1; > + break; > + } > + > + return 0; > +} > + > +static int do_snapshot(struct lxc_container *c, char *commentfile) > { > int ret; > > @@ -57,26 +187,11 @@ static int do_snapshot(struct lxc_container *c) > } > > INFO("Created snapshot snap%d", ret); > - return 0; > -} > > -static void print_file(char *path) > -{ > - if (!path) > - return; > - FILE *f = fopen(path, "r"); > - char *line = NULL; > - size_t sz = 0; > - if (!f) > - return; > - while (getline(&line, &sz, f) != -1) { > - printf("%s", line); > - } > - free(line); > - fclose(f); > + return 0; > } > > -static int do_list_snapshots(struct lxc_container *c) > +static int do_list_snapshots(struct lxc_container *c, int print_comments) > { > struct lxc_snapshot *s; > int i, n; > @@ -90,148 +205,64 @@ static int do_list_snapshots(struct lxc_container *c) > printf("No snapshots\n"); > return 0; > } > - for (i=0; i<n; i++) { > + > + for (i = 0; i < n; i++) { > printf("%s (%s) %s\n", s[i].name, s[i].lxcpath, s[i].timestamp); > if (print_comments) > print_file(s[i].comment_pathname); > s[i].free(&s[i]); > } > + > free(s); > + > return 0; > } > > -static int do_restore_snapshots(struct lxc_container *c) > +static int do_restore_snapshots(struct lxc_container *c, char *snapname, > + char *newname) > { > - if (c->snapshot_restore(c, snapshot, newname)) > + if (c->snapshot_restore(c, snapname, newname)) > return 0; > > - ERROR("Error restoring snapshot %s", snapshot); > + ERROR("Error restoring snapshot %s", snapname); > + > return -1; > } > > -static int do_destroy_snapshots(struct lxc_container *c) > +static int do_destroy_snapshots(struct lxc_container *c, char *snapname) > { > - bool bret; > - if (strcmp(snapshot, "ALL") == 0) > - bret = c->snapshot_destroy_all(c); > + bool ret; > + > + if (strcmp(snapname, "ALL") == 0) > + ret = c->snapshot_destroy_all(c); > else > - bret = c->snapshot_destroy(c, snapshot); > + ret = c->snapshot_destroy(c, snapname); > > - if (bret) > + if (ret) > return 0; > > - ERROR("Error destroying snapshot %s", snapshot); > - return -1; > -} > + ERROR("Error destroying snapshot %s", snapname); > > -static int my_parser(struct lxc_arguments* args, int c, char* arg) > -{ > - switch (c) { > - case 'L': action = DO_LIST; break; > - case 'r': snapshot = arg; action = DO_RESTORE; break; > - case 'd': snapshot = arg; action = DO_DESTROY; break; > - case 'c': commentfile = arg; break; > - case 'C': print_comments = true; break; > - } > - return 0; > + return -1; > } > > -static const struct option my_longopts[] = { > - {"list", no_argument, 0, 'L'}, > - {"restore", required_argument, 0, 'r'}, > - {"destroy", required_argument, 0, 'd'}, > - {"comment", required_argument, 0, 'c'}, > - {"showcomments", no_argument, 0, 'C'}, > - LXC_COMMON_OPTIONS > -}; > - > - > -static struct lxc_arguments my_args = { > - .progname = "lxc-snapshot", > - .help = "\ > ---name=NAME [-P lxcpath] [-L [-C]] [-c commentfile] [-r snapname > [newname]]\n\ > -\n\ > -lxc-snapshot snapshots a container\n\ > -\n\ > -Options :\n\ > - -n, --name=NAME NAME for name of the container\n\ > - -L, --list list snapshots\n\ > - -C, --showcomments show snapshot comments in list\n\ > - -c, --comment=file add file as a comment\n\ > - -r, --restore=name restore snapshot name, i.e. 'snap0'\n\ > - -d, --destroy=name destroy snapshot name, i.e. 'snap0'\n\ > - use ALL to destroy all snapshots\n", > - .options = my_longopts, > - .parser = my_parser, > - .checker = NULL, > -}; > - > -/* > - * lxc-snapshot -P lxcpath -n container > - * lxc-snapshot -P lxcpath -n container -l > - * lxc-snapshot -P lxcpath -n container -r snap3 recovered_1 > - */ > - > -int main(int argc, char *argv[]) > +static void print_file(char *path) > { > - struct lxc_container *c; > - int ret = 0; > - > - if (lxc_arguments_parse(&my_args, argc, argv)) > - exit(1); > - > - if (!my_args.log_file) > - my_args.log_file = "none"; > - > - if (my_args.argc > 1) { > - ERROR("Too many arguments"); > - exit(1); > - } > - if (my_args.argc == 1) > - newname = my_args.argv[0]; > - > - if (lxc_log_init(my_args.name, my_args.log_file, my_args.log_priority, > - my_args.progname, my_args.quiet, my_args.lxcpath[0])) > - exit(1); > - lxc_log_options_no_override(); > - > - if (geteuid()) { > - if (access(my_args.lxcpath[0], O_RDWR) < 0) { > - fprintf(stderr, "You lack access to %s\n", > my_args.lxcpath[0]); > - exit(1); > - } > - } > + if (!path) > + return; > > - c = lxc_container_new(my_args.name, my_args.lxcpath[0]); > - if (!c) { > - fprintf(stderr, "System error loading container\n"); > - exit(1); > - } > + FILE *f = fopen(path, "r"); > + char *line = NULL; > + size_t sz = 0; > > - if (!c->may_control(c)) { > - fprintf(stderr, "Insufficent privileges to control %s\n", > my_args.name); > - lxc_container_put(c); > - exit(1); > - } > + if (!f) > + return; > > - switch(action) { > - case DO_SNAP: > - ret = do_snapshot(c); > - break; > - case DO_LIST: > - ret = do_list_snapshots(c); > - break; > - case DO_RESTORE: > - ret = do_restore_snapshots(c); > - break; > - case DO_DESTROY: > - ret = do_destroy_snapshots(c); > - break; > + while (getline(&line, &sz, f) != -1) { > + printf("%s", line); > } > > - lxc_container_put(c); > - > - if (ret == 0) > - exit(EXIT_SUCCESS); > - exit(EXIT_FAILURE); > + free(line); > + fclose(f); > } > + > -- > 2.5.0 >
signature.asc
Description: PGP signature
_______________________________________________ lxc-devel mailing list lxc-devel@lists.linuxcontainers.org http://lists.linuxcontainers.org/listinfo/lxc-devel