[Devel] [PATCH 2/3] restart: add --warn-* and --fail-* command line switches

Oren Laadan orenl at librato.com
Tue Nov 10 14:04:51 PST 2009


Signed-off-by: Oren Laadan <orenl at cs.columbia.edu>
---
 restart.c |   74 ++++++++++++++++++++++++++++++++++++++++++++++++++++--------
 1 files changed, 64 insertions(+), 10 deletions(-)

diff --git a/restart.c b/restart.c
index 5871bbf..2efe879 100644
--- a/restart.c
+++ b/restart.c
@@ -79,6 +79,10 @@ static char usage_str[] =
 "     --inspect          inspect image on-the-fly for error records\n"
 "  -v,--verbose          verbose output\n"
 "  -d,--debug            debugging output\n"
+"     --warn-COND        warn on condition COND, but proceed anyways\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"
 "";
 
 /*
@@ -359,8 +363,13 @@ struct args {
 	int infd;
 	char *logfile;
 	int logfd;
+	long warn;
+	long fail;
 };
 
+#define CKPT_COND_PIDZERO  0x1
+#define CKPT_COND_ANY      ULONG_MAX
+
 static void usage(char *str)
 {
 	fprintf(stderr, "%s", str);
@@ -379,6 +388,37 @@ static int str2num(char *str)
 	return num;
 }
 
+static long cond_to_mask(const char *cond)
+{
+	static struct {
+		char *cond;
+		long mask;
+	} conditions[] = {
+		{"pidzero", CKPT_COND_PIDZERO},
+		{"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);
+}
+		
+static inline int ckpt_cond_fail(struct ckpt_ctx *ctx, long mask)
+{
+	return (ctx->args->fail & mask);
+}
+
 static void parse_args(struct args *args, int argc, char *argv[])
 {
 	static struct option opts[] = {
@@ -401,10 +441,13 @@ static void parse_args(struct args *args, int argc, char *argv[])
 		{ "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 },
 		{ NULL,		0,			NULL, 0 }
 	};
 	static char optc[] = "hdvpPwWF:r:i:l:";
 
+	int optind;
 	int sig;
 
 	/* defaults */
@@ -414,7 +457,7 @@ static void parse_args(struct args *args, int argc, char *argv[])
 	args->logfd = -1;
 
 	while (1) {
-		int c = getopt_long(argc, argv, optc, opts, NULL);
+		int c = getopt_long(argc, argv, optc, opts, &optind);
 		if (c == -1)
 			break;
 		switch (c) {
@@ -494,6 +537,12 @@ static void parse_args(struct args *args, int argc, char *argv[])
 		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;
 		default:
 			usage(usage_str);
 		}
@@ -1171,15 +1220,21 @@ static int ckpt_setup_task(struct ckpt_ctx *ctx, pid_t pid, pid_t ppid)
 	return 0;
 }
 
-static inline int ckpt_valid_pid(pid_t pid, int pidns, char *which, int i)
+static int ckpt_valid_pid(struct ckpt_ctx *ctx, pid_t pid, char *which, int i)
 {
 	if (pid < 0) {
 		ckpt_err("Invalid %s %d (for task#%d)\n", which, pid, i);
 		return 0;
 	}
-	if (!pidns && pid == 0) {
-		ckpt_err("Zero %s (task#%d) requires pid-ns\n", which, i + 1);
-		return 0;
+	if (!ctx->args->pidns && pid == 0) {
+		if (ckpt_cond_fail(ctx, CKPT_COND_PIDZERO)) {
+			ckpt_err("[err] task # %d with %s zero"
+				 " (requires --pidns)\n", i + 1, which);
+			return 0;
+		} else if (ckpt_cond_warn(ctx, CKPT_COND_PIDZERO)) {
+			ckpt_err("[warn] task # %d with %s zero"
+				 " (consider --pidns)\n", i + 1, which);
+		}
 	}
 	return 1;
 }
@@ -1188,7 +1243,6 @@ static int ckpt_init_tree(struct ckpt_ctx *ctx)
 {
 	struct ckpt_pids *pids_arr = ctx->pids_arr;
 	int pids_nr = ctx->pids_nr;
-	int pidns = ctx->args->pidns;
 	struct task *task;
 	pid_t root_pid;
 	pid_t root_sid;
@@ -1225,13 +1279,13 @@ static int ckpt_init_tree(struct ckpt_ctx *ctx)
 
 		task->flags = 0;
 
-		if (!ckpt_valid_pid(pids_arr[i].vpid, pidns, "pid", i))
+		if (!ckpt_valid_pid(ctx, pids_arr[i].vpid, "pid", i))
 			return -1;
-		else if (!ckpt_valid_pid(pids_arr[i].vtgid, pidns, "tgid", i))
+		else if (!ckpt_valid_pid(ctx, pids_arr[i].vtgid, "tgid", i))
 			return -1;
-		else if (!ckpt_valid_pid(pids_arr[i].vsid, pidns, "sid", i))
+		else if (!ckpt_valid_pid(ctx, pids_arr[i].vsid, "sid", i))
 			return -1;
-		else if (!ckpt_valid_pid(pids_arr[i].vpgid, pidns, "pgid", i))
+		else if (!ckpt_valid_pid(ctx, pids_arr[i].vpgid, "pgid", i))
 			return -1;
 
 		/* zero references to root_sid (root_sid != root_pid) */
-- 
1.6.0.4

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




More information about the Devel mailing list