[lxc-devel] [PATCH] Refactor lxc-snapshot

Christian Brauner christianvanbrauner at gmail.com
Thu Aug 6 13:47:04 UTC 2015


- 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 <christianvanbrauner at 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



More information about the lxc-devel mailing list