[Devel] [PATCH 3/4][user-cr] Move main() in restart.c to restart-main.c

Sukadev Bhattiprolu sukadev at linux.vnet.ibm.com
Wed Feb 24 00:36:52 PST 2010


>From 6553b7da33f56e9cb6927e7469af22df56b7f55f Mon Sep 17 00:00:00 2001
From: Sukadev Bhattiprolu <sukadev at linux.vnet.ibm.com>
Date: Tue, 23 Feb 2010 15:55:34 -0800
Subject: [PATCH 3/4][user-cr] Move main() in restart.c to restart-main.c

This would enable us to put restart.o into a library.

TODO:
	restart.c still has a whole bunch of external variables that
	would need to be addressed (maybe encapsulate in structure)

Signed-off-by: Sukadev Bhattiprolu <sukadev at linux.vnet.ibm.com>
---
 Makefile       |    2 +
 restart-main.c |  312 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 restart.c      |  293 ----------------------------------------------------
 3 files changed, 314 insertions(+), 293 deletions(-)
 create mode 100644 restart-main.c

diff --git a/Makefile b/Makefile
index b312358..4449081 100644
--- a/Makefile
+++ b/Makefile
@@ -21,6 +21,8 @@ CFLAGS += -g $(WARNS) $(CKPT_INCLUDE) $(DEBUG)
 BIN_INSTALL_DIR = /bin
 LIB_INSTALL_DIR = /lib
 
+restart: restart.o restart-main.o
+
 ECLONE_PROGS = restart nsexec
 PROGS =	checkpoint ckptinfo $(ECLONE_PROGS)
 LIB_ECLONE = libeclone.a
diff --git a/restart-main.c b/restart-main.c
new file mode 100644
index 0000000..805920f
--- /dev/null
+++ b/restart-main.c
@@ -0,0 +1,312 @@
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <errno.h>
+#include <signal.h>
+#include <getopt.h>
+#include <limits.h>
+
+#include "usercr.h"
+#include "restart.h"
+#include "clone.h"
+
+extern int global_verbose;
+extern int global_send_sigint;
+
+static char usage_str[] =
+"usage: restart [opts]\n"
+"  restart restores from a checkpoint image by first creating in userspace\n"
+"  the original tasks tree, and then calling sys_restart by each task.\n"
+"Options:\n"
+"  -h,--help             print this help message\n"
+"  -p,--pidns            create a new pid namspace (default with --pids)\n"
+"  -P,--no-pidns         do not create a new pid namespace (default)\n"
+"     --pids             restore original pids (default with --pidns)\n"
+"     --self             restart a single task, usually from self-checkpoint\n"
+"  -r,--root=ROOT        restart under the directory ROOT instead of current\n"
+"     --signal=SIG       send SIG to root task on SIGINT (default: SIGKILL\n"
+"                        to container root, SIGINT otherwise)\n"
+"     --mntns            restart under a private mounts namespace\n"
+"     --mount-pty        start in a new devpts namespace to supprt ptys\n"
+"  -w,--wait             wait for root task to termiate (default)\n"
+"     --show-status      show exit status of root task (implies -w)\n"
+"     --copy-status      imitate exit status of root task (implies -w)\n"
+"  -W,--no-wait          do not wait for root task to terminate\n"
+"  -k,--keeplsm          try to recreate original LSM labels on all objects\n"
+"  -F,--freezer=CGROUP   freeze tasks in freezer group CGROUP on success\n"
+"  -i,--input=FILE       read data from FILE instead of standard input\n"
+"     --input-fd=FD      read data from file descriptor FD (instead of stdin)\n"
+"  -l,--logfile=FILE     write error and debug data to FILE (default=none)\n"
+"     --logfile-fd=FD    write error and debug data to file desctiptor FD\n"
+"     --inspect          inspect image on-the-fly for error records\n"
+"  -v,--verbose          verbose output\n"
+"  -d,--debug            debugging output\n"
+"     --skip-COND        skip condition COND, and proceed anyway\n"
+"     --warn-COND        warn on condition COND, but proceed anyway\n"
+"     --fail-COND        warn on condition COND, and abort operation\n"
+"  	  COND=any:        any condition\n"
+"  	  COND=pidzero:    task with sid/pgid zero in a --no-pidns restart\n"
+"  	  COND=mntproc:    /proc isn't already mounted at restart (def: warn)\n"
+"";
+
+static void usage(char *str)
+{
+	fprintf(stderr, "%s", str);
+	exit(1);
+}
+
+/* negative retval means error */
+static int str2num(char *str)
+{
+	char *nptr;
+	int num;
+
+	num = strtol(str, &nptr, 10);
+	if (nptr - str != strlen(str))
+		num = -1;
+	return num;
+}
+
+static long cond_to_mask(const char *cond)
+{
+	static struct {
+		char *cond;
+		long mask;
+	} conditions[] = {
+		{"pidzero", CKPT_COND_PIDZERO},
+		{"mntproc", CKPT_COND_MNTPROC},
+		{"any", CKPT_COND_ANY},
+		{NULL, 0}
+	};
+
+	int i;
+
+	for (i = 0; conditions[i].cond; i++)
+		if (!strcmp(cond, conditions[i].cond))
+			return conditions[i].mask;
+
+	printf("restart: invalid warn/fail condition '%s'\n", cond);
+	exit(1);
+}
+
+extern struct signal_array signal_array[];
+extern int global_debug;
+
+static int str2sig(char *str)
+{
+	int sig = 0;
+
+	do {
+		if (!strcmp(signal_array[sig].sigstr, str))
+			return signal_array[sig].signum;
+	} while (signal_array[++sig].signum >= 0);
+
+	return -1;
+}
+
+static void parse_args(struct restart_args *args, int argc, char *argv[])
+{
+	static struct option opts[] = {
+		{ "help",	no_argument,		NULL, 'h' },
+		{ "pidns",	no_argument,		NULL, 'p' },
+		{ "no-pidns",	no_argument,		NULL, 'P' },
+		{ "pids",	no_argument,		NULL, 3 },
+		{ "self",	no_argument,		NULL, 6},
+		{ "signal",	required_argument,	NULL, 4 },
+		{ "inspect",	no_argument,		NULL, 5 },
+		{ "keeplsm",	no_argument,		NULL, 'k' },
+		{ "input",	required_argument,	NULL, 'i' },
+		{ "input-fd",	required_argument,	NULL, 7 },
+		{ "logfile",	required_argument,	NULL, 'l' },
+		{ "logfile-fd",	required_argument,	NULL, 8 },
+		{ "root",	required_argument,	NULL, 'r' },
+		{ "mntns",	no_argument,		NULL, 11 },
+		{ "wait",	no_argument,		NULL, 'w' },
+		{ "show-status",	no_argument,	NULL, 1 },
+		{ "copy-status",	no_argument,	NULL, 2 },
+		{ "no-wait",	no_argument,		NULL, 'W' },
+		{ "freezer",	required_argument,	NULL, 'F' },
+		{ "verbose",	no_argument,		NULL, 'v' },
+		{ "debug",	no_argument,		NULL, 'd' },
+		{ "warn-pidzero",	no_argument,	NULL, 9 },
+		{ "fail-pidzero",	no_argument,	NULL, 10 },
+		{ "mount-pty",	no_argument,		NULL, 12 },
+		{ NULL,		0,			NULL, 0 }
+	};
+	static char optc[] = "hdvkpPwWF:r:i:l:";
+
+	int optind;
+	int sig;
+
+	/* defaults */
+	memset(args, 0, sizeof(*args));
+	args->wait = 1;
+	args->infd = -1;
+	args->logfd = -1;
+	args->warn = CKPT_COND_WARN;
+	args->fail = CKPT_COND_FAIL;
+
+	while (1) {
+		int c = getopt_long(argc, argv, optc, opts, &optind);
+		if (c == -1)
+			break;
+		switch (c) {
+		case '?':
+			exit(1);
+		case 'h':
+			usage(usage_str);
+		case 'v':
+			global_verbose = 1;
+			break;
+		case 5:  /* --inspect */
+			args->inspect = 1;
+			break;
+		case 'i':
+			args->input = optarg;
+			break;
+		case 7:
+			args->infd = str2num(optarg);
+			if (args->infd < 0) {
+				printf("restart: invalid file descriptor\n");
+				exit(1);
+			}
+			break;
+		case 'l':
+			args->logfile = optarg;
+			break;
+		case 8:
+			args->logfd = str2num(optarg);
+			if (args->logfd < 0) {
+				printf("restart: invalid file descriptor\n");
+				exit(1);
+			}
+			break;
+		case 'p':
+			args->pidns = 1;
+			break;
+		case 'P':
+			args->no_pidns = 1;
+			break;
+		case 6:  /* --self */
+			args->self = 1;
+			break;
+		case 4:  /* --signal */
+			sig = str2sig(optarg);
+			if (sig < 0)
+				sig = str2num(optarg);
+			if (sig < 0 || sig >= NSIG) {
+				printf("restart: invalid signal\n");
+				exit(1);
+			}
+			global_send_sigint = sig;
+			break;
+		case 3:  /* --pids */
+			args->pids = 1;
+			args->pidns = 1;  /* implied */
+			break;
+		case 'r':
+			args->root = optarg;
+			break;
+		case 'w':
+			args->wait = 1;
+			break;
+		case 'W':
+			args->wait = 0;
+			break;
+		case 'k':
+			args->keep_lsm = 1;
+			break;
+		case 1:  /* --show-status */
+			args->wait = 1;
+			args->show_status = 1;
+			break;
+		case 2: /* --copy-status */
+			args->wait = 1;
+			args->copy_status = 1;
+			break;
+		case 'd':
+			global_debug = 1;
+			break;
+		case 'F':
+			args->freezer = optarg;
+			break;
+		case 9:
+			args->warn |= cond_to_mask(&opts[optind].name[5]);
+			break;
+		case 10:
+			args->fail |= cond_to_mask(&opts[optind].name[5]);
+			break;
+		case 11:
+			args->mntns = 1;
+			break;
+		case 12:
+			args->mnt_pty = 1;
+			break;
+		default:
+			usage(usage_str);
+		}
+	}
+
+	if (args->no_pidns)
+		args->pidns = 0;
+
+#ifndef CLONE_NEWPID
+	if (args->pidns) {
+		printf("This version of restart was compiled without "
+		       "support for --pidns.\n");
+		exit(1);
+	}
+#endif
+
+#ifndef CHECKPOINT_DEBUG
+	if (global_debug) {
+		printf("This version of restart was compiled without "
+		       "support for --debug.\n");
+		exit(1);
+	}
+#endif
+
+	if (args->pidns)
+		args->pids = 1;
+
+#if 0   /* Defered until __NR_eclone makes it to standard headers */
+#ifndef __NR_eclone
+	if (args->pids) {
+		printf("This version of restart was compiled without "
+		       "support for --pids.\n");
+		exit(1);
+	}
+#endif
+#endif
+
+	if (args->self &&
+	    (args->pids || args->pidns || args->no_pidns ||
+	     args->show_status || args->copy_status || args->freezer)) {
+		printf("Invalid mix of --self with multiprocess options\n");
+		exit(1);
+	}
+
+	if (args->input && args->infd >= 0) {
+		printf("Invalid used of both -i/--input and --input-fd\n");
+		exit(1);
+	}
+
+	if (args->logfile && args->logfd >= 0) {
+		printf("Invalid used of both -l/--logfile and --logfile-fd\n");
+		exit(1);
+	}
+
+	if (args->mnt_pty)
+		args->mntns = 1;
+}
+
+int main(int argc, char *argv[])
+{
+	struct restart_args args;
+
+	parse_args(&args, argc, argv);
+
+	return app_restart(&args);
+}
+
diff --git a/restart.c b/restart.c
index b2281fb..b1518f2 100644
--- a/restart.c
+++ b/restart.c
@@ -42,42 +42,6 @@
 #include "restart.h"
 #include "usercr.h"
 
-static char usage_str[] =
-"usage: restart [opts]\n"
-"  restart restores from a checkpoint image by first creating in userspace\n"
-"  the original tasks tree, and then calling sys_restart by each task.\n"
-"Options:\n"
-"  -h,--help             print this help message\n"
-"  -p,--pidns            create a new pid namspace (default with --pids)\n"
-"  -P,--no-pidns         do not create a new pid namespace (default)\n"
-"     --pids             restore original pids (default with --pidns)\n"
-"     --self             restart a single task, usually from self-checkpoint\n"
-"  -r,--root=ROOT        restart under the directory ROOT instead of current\n"
-"     --signal=SIG       send SIG to root task on SIGINT (default: SIGKILL\n"
-"                        to container root, SIGINT otherwise)\n"
-"     --mntns            restart under a private mounts namespace\n"
-"     --mount-pty        start in a new devpts namespace to supprt ptys\n"
-"  -w,--wait             wait for root task to termiate (default)\n"
-"     --show-status      show exit status of root task (implies -w)\n"
-"     --copy-status      imitate exit status of root task (implies -w)\n"
-"  -W,--no-wait          do not wait for root task to terminate\n"
-"  -k,--keeplsm          try to recreate original LSM labels on all objects\n"
-"  -F,--freezer=CGROUP   freeze tasks in freezer group CGROUP on success\n"
-"  -i,--input=FILE       read data from FILE instead of standard input\n"
-"     --input-fd=FD      read data from file descriptor FD (instead of stdin)\n"
-"  -l,--logfile=FILE     write error and debug data to FILE (default=none)\n"
-"     --logfile-fd=FD    write error and debug data to file desctiptor FD\n"
-"     --inspect          inspect image on-the-fly for error records\n"
-"  -v,--verbose          verbose output\n"
-"  -d,--debug            debugging output\n"
-"     --skip-COND        skip condition COND, and proceed anyway\n"
-"     --warn-COND        warn on condition COND, but proceed anyway\n"
-"     --fail-COND        warn on condition COND, and abort operation\n"
-"  	  COND=any:        any condition\n"
-"  	  COND=pidzero:    task with sid/pgid zero in a --no-pidns restart\n"
-"  	  COND=mntproc:    /proc isn't already mounted at restart (def: warn)\n"
-"";
-
 /*
  * By default, 'restart' creates a new pid namespace in which the
  * restart takes place, using the original pids from the time of the
@@ -176,18 +140,6 @@ static char *sig2str(int sig)
 	return "UNKNOWN SIGNAL";
 }
 
-static int str2sig(char *str)
-{
-	int sig = 0;
-
-	do {
-		if (!strcmp(signal_array[sig].sigstr, str))
-			return signal_array[sig].signum;
-	} while (signal_array[++sig].signum >= 0);
-
-	return -1;
-}
-
 inline static int restart(pid_t pid, int fd, unsigned long flags, int logfd)
 {
 	return syscall(__NR_restart, pid, fd, flags, logfd);
@@ -311,46 +263,6 @@ struct pid_swap {
 	pid_t new;
 };
 
-static void usage(char *str)
-{
-	fprintf(stderr, "%s", str);
-	exit(1);
-}
-
-/* negative retval means error */
-static int str2num(char *str)
-{
-	char *nptr;
-	int num;
-
-	num = strtol(str, &nptr, 10);
-	if (nptr - str != strlen(str))
-		num = -1;
-	return num;
-}
-
-static long cond_to_mask(const char *cond)
-{
-	static struct {
-		char *cond;
-		long mask;
-	} conditions[] = {
-		{"pidzero", CKPT_COND_PIDZERO},
-		{"mntproc", CKPT_COND_MNTPROC},
-		{"any", CKPT_COND_ANY},
-		{NULL, 0}
-	};
-
-	int i;
-
-	for (i = 0; conditions[i].cond; i++)
-		if (!strcmp(cond, conditions[i].cond))
-			return conditions[i].mask;
-
-	printf("restart: invalid warn/fail condition '%s'\n", cond);
-	exit(1);
-}
-
 static inline int ckpt_cond_warn(struct ckpt_ctx *ctx, long mask)
 {
 	return (ctx->args->warn & mask);
@@ -361,202 +273,6 @@ static inline int ckpt_cond_fail(struct ckpt_ctx *ctx, long mask)
 	return (ctx->args->fail & mask);
 }
 
-static void parse_args(struct restart_args *args, int argc, char *argv[])
-{
-	static struct option opts[] = {
-		{ "help",	no_argument,		NULL, 'h' },
-		{ "pidns",	no_argument,		NULL, 'p' },
-		{ "no-pidns",	no_argument,		NULL, 'P' },
-		{ "pids",	no_argument,		NULL, 3 },
-		{ "self",	no_argument,		NULL, 6},
-		{ "signal",	required_argument,	NULL, 4 },
-		{ "inspect",	no_argument,		NULL, 5 },
-		{ "keeplsm",	no_argument,		NULL, 'k' },
-		{ "input",	required_argument,	NULL, 'i' },
-		{ "input-fd",	required_argument,	NULL, 7 },
-		{ "logfile",	required_argument,	NULL, 'l' },
-		{ "logfile-fd",	required_argument,	NULL, 8 },
-		{ "root",	required_argument,	NULL, 'r' },
-		{ "mntns",	no_argument,		NULL, 11 },
-		{ "wait",	no_argument,		NULL, 'w' },
-		{ "show-status",	no_argument,	NULL, 1 },
-		{ "copy-status",	no_argument,	NULL, 2 },
-		{ "no-wait",	no_argument,		NULL, 'W' },
-		{ "freezer",	required_argument,	NULL, 'F' },
-		{ "verbose",	no_argument,		NULL, 'v' },
-		{ "debug",	no_argument,		NULL, 'd' },
-		{ "warn-pidzero",	no_argument,	NULL, 9 },
-		{ "fail-pidzero",	no_argument,	NULL, 10 },
-		{ "mount-pty",	no_argument,		NULL, 12 },
-		{ NULL,		0,			NULL, 0 }
-	};
-	static char optc[] = "hdvkpPwWF:r:i:l:";
-
-	int optind;
-	int sig;
-
-	/* defaults */
-	memset(args, 0, sizeof(*args));
-	args->wait = 1;
-	args->infd = -1;
-	args->logfd = -1;
-	args->warn = CKPT_COND_WARN;
-	args->fail = CKPT_COND_FAIL;
-
-	while (1) {
-		int c = getopt_long(argc, argv, optc, opts, &optind);
-		if (c == -1)
-			break;
-		switch (c) {
-		case '?':
-			exit(1);
-		case 'h':
-			usage(usage_str);
-		case 'v':
-			global_verbose = 1;
-			break;
-		case 5:  /* --inspect */
-			args->inspect = 1;
-			break;
-		case 'i':
-			args->input = optarg;
-			break;
-		case 7:
-			args->infd = str2num(optarg);
-			if (args->infd < 0) {
-				printf("restart: invalid file descriptor\n");
-				exit(1);
-			}
-			break;
-		case 'l':
-			args->logfile = optarg;
-			break;
-		case 8:
-			args->logfd = str2num(optarg);
-			if (args->logfd < 0) {
-				printf("restart: invalid file descriptor\n");
-				exit(1);
-			}
-			break;
-		case 'p':
-			args->pidns = 1;
-			break;
-		case 'P':
-			args->no_pidns = 1;
-			break;
-		case 6:  /* --self */
-			args->self = 1;
-			break;
-		case 4:  /* --signal */
-			sig = str2sig(optarg);
-			if (sig < 0)
-				sig = str2num(optarg);
-			if (sig < 0 || sig >= NSIG) {
-				printf("restart: invalid signal\n");
-				exit(1);
-			}
-			global_send_sigint = sig;
-			break;
-		case 3:  /* --pids */
-			args->pids = 1;
-			args->pidns = 1;  /* implied */
-			break;
-		case 'r':
-			args->root = optarg;
-			break;
-		case 'w':
-			args->wait = 1;
-			break;
-		case 'W':
-			args->wait = 0;
-			break;
-		case 'k':
-			args->keep_lsm = 1;
-			break;
-		case 1:  /* --show-status */
-			args->wait = 1;
-			args->show_status = 1;
-			break;
-		case 2: /* --copy-status */
-			args->wait = 1;
-			args->copy_status = 1;
-			break;
-		case 'd':
-			global_debug = 1;
-			break;
-		case 'F':
-			args->freezer = optarg;
-			break;
-		case 9:
-			args->warn |= cond_to_mask(&opts[optind].name[5]);
-			break;
-		case 10:
-			args->fail |= cond_to_mask(&opts[optind].name[5]);
-			break;
-		case 11:
-			args->mntns = 1;
-			break;
-		case 12:
-			args->mnt_pty = 1;
-			break;
-		default:
-			usage(usage_str);
-		}
-	}
-
-	if (args->no_pidns)
-		args->pidns = 0;
-
-#ifndef CLONE_NEWPID
-	if (args->pidns) {
-		printf("This version of restart was compiled without "
-		       "support for --pidns.\n");
-		exit(1);
-	}
-#endif
-
-#ifndef CHECKPOINT_DEBUG
-	if (global_debug) {
-		printf("This version of restart was compiled without "
-		       "support for --debug.\n");
-		exit(1);
-	}
-#endif
-
-	if (args->pidns)
-		args->pids = 1;
-
-#if 0   /* Defered until __NR_eclone makes it to standard headers */
-#ifndef __NR_eclone
-	if (args->pids) {
-		printf("This version of restart was compiled without "
-		       "support for --pids.\n");
-		exit(1);
-	}
-#endif
-#endif
-
-	if (args->self &&
-	    (args->pids || args->pidns || args->no_pidns ||
-	     args->show_status || args->copy_status || args->freezer)) {
-		printf("Invalid mix of --self with multiprocess options\n");
-		exit(1);
-	}
-
-	if (args->input && args->infd >= 0) {
-		printf("Invalid used of both -i/--input and --input-fd\n");
-		exit(1);
-	}
-
-	if (args->logfile && args->logfd >= 0) {
-		printf("Invalid used of both -l/--logfile and --logfile-fd\n");
-		exit(1);
-	}
-
-	if (args->mnt_pty)
-		args->mntns = 1;
-}
-
 static void report_exit_status(int status, char *str, int debug)
 {
 	char msg[64];
@@ -689,15 +405,6 @@ static int freezer_register(struct ckpt_ctx *ctx, pid_t pid)
 	return ret;
 }
 
-int main(int argc, char *argv[])
-{
-	struct restart_args args;
-
-	parse_args(&args, argc, argv);
-
-	return app_restart(&args);
-}
-
 int app_restart(struct restart_args *args)
 {
 	struct ckpt_ctx ctx;
-- 
1.6.6.1

_______________________________________________
Containers mailing list
Containers at lists.linux-foundation.org
https://lists.linux-foundation.org/mailman/listinfo/containers




More information about the Devel mailing list