[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