Quoting Oren Laadan (orenl@xxxxxxxxxxx): > When restartinig in --wait mode, an interrupt to the coordinator > translates to a signal to the root task. This patch fixes and > imrpoves the interface and logic of sending such signals. > > Signed-off-by: Oren Laadan <orenl@xxxxxxxxxxxxxxx> Acked-by: Serge Hallyn <serue@xxxxxxxxxx> > --- > restart.c | 132 ++++++++++++++++++++++++++++++++++++++++++++++++++----------- > 1 files changed, 109 insertions(+), 23 deletions(-) > > diff --git a/restart.c b/restart.c > index fbcc299..a25aaa9 100644 > --- a/restart.c > +++ b/restart.c > @@ -58,21 +58,22 @@ 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" > -"\tOptions:\n" > -"\t -h,--help print this help message\n" > -"\t -p,--pidns create a new pid namspace (default with --pids)\n" > -"\t -P,--no-pidns do not create a new pid namspace (default)\n" > -"\t --pidns-intr=SIG send SIG to root task on SIGINT (default: SIGKILL)\n" > -"\t --pids restore original pids (default with --pidns)\n" > -"\t -i,--inspect inspect image on-the-fly for error records\n" > -"\t -r,--root=ROOT restart under the directory ROOT instead of current\n" > -"\t -w,--wait wait for (root) task to termiate (default)\n" > -"\t --show-status show exit status of (root) task (implies -w)\n" > -"\t --copy-status imitate exit status of (root) task (implies -w)\n" > -"\t -W,--no-wait do not wait for (root) task to terminate\n" > -"\t -F,--freezer=CGROUP freeze tasks in freezer group CGROUP on success\n" > -"\t -v,--verbose verbose output\n" > -"\t -d,--debug debugging output\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" > +" -i,--inspect inspect image on-the-fly for error records\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" > +" -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" > +" -F,--freezer=CGROUP freeze tasks in freezer group CGROUP on success\n" > +" -v,--verbose verbose output\n" > +" -d,--debug debugging output\n" > ""; > > /* > @@ -128,6 +129,69 @@ static char usage_str[] = > printf(__VA_ARGS__); \ > } while(0) > > +#define SIGNAL_ENTRY(signal) { SIG ## signal, #signal } > + > +struct { > + int signum; > + char *sigstr; > +} signal_array[] = { > + { 0, "NONE" }, > + SIGNAL_ENTRY(ALRM), > + SIGNAL_ENTRY(HUP), > + SIGNAL_ENTRY(INT), > + SIGNAL_ENTRY(KILL), > + SIGNAL_ENTRY(PIPE), > + SIGNAL_ENTRY(POLL), > + SIGNAL_ENTRY(PROF), > + SIGNAL_ENTRY(TERM), > + SIGNAL_ENTRY(USR1), > + SIGNAL_ENTRY(USR2), > + SIGNAL_ENTRY(VTALRM), > + SIGNAL_ENTRY(STKFLT), > + SIGNAL_ENTRY(PWR), > + SIGNAL_ENTRY(WINCH), > + SIGNAL_ENTRY(CHLD), > + SIGNAL_ENTRY(URG), > + SIGNAL_ENTRY(TTIN), > + SIGNAL_ENTRY(TTOU), > + SIGNAL_ENTRY(STOP), > + SIGNAL_ENTRY(CONT), > + SIGNAL_ENTRY(ABRT), > + SIGNAL_ENTRY(FPE), > + SIGNAL_ENTRY(ILL), > + SIGNAL_ENTRY(QUIT), > + SIGNAL_ENTRY(SEGV), > + SIGNAL_ENTRY(TRAP), > + SIGNAL_ENTRY(SYS), > + SIGNAL_ENTRY(BUS), > + SIGNAL_ENTRY(XCPU), > + SIGNAL_ENTRY(XFSZ), > + { -1, "LAST" }, > +}; > + > +static char *sig2str(int sig) > +{ > + int i = 0; > + > + do { > + if (signal_array[i].signum == sig) > + return signal_array[i].sigstr; > + } while (signal_array[++i].signum >= 0); > + 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) > { > return syscall(__NR_restart, pid, fd, flags); > @@ -287,14 +351,26 @@ static void usage(char *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 void parse_args(struct args *args, int argc, char *argv[]) > { > static struct option opts[] = { > { "help", no_argument, NULL, 'h' }, > { "pidns", no_argument, NULL, 'p' }, > - { "pidns-signal", required_argument, NULL, '4' }, > { "no-pidns", no_argument, NULL, 'P' }, > { "pids", no_argument, NULL, 3 }, > + { "signal", required_argument, NULL, 4 }, > { "inspect", no_argument, NULL, 'i' }, > { "root", required_argument, NULL, 'r' }, > { "wait", no_argument, NULL, 'w' }, > @@ -336,9 +412,11 @@ static void parse_args(struct args *args, int argc, char *argv[]) > args->no_pidns = 1; > break; > case 4: > - sig = atoi(optarg); > + sig = str2sig(optarg); > + if (sig < 0) > + sig = str2num(optarg); > if (sig < 0 || sig >= NSIG) { > - printf("restart: invalid signal number\n"); > + printf("restart: invalid signal\n"); > exit(1); > } > global_send_sigint = sig; > @@ -461,13 +539,21 @@ static void sigint_handler(int sig) > { > pid_t pid = global_child_pid; > > - ckpt_verbose("SIGINT sent to restarted tasks\n"); > + sig = global_send_sigint; > + if (!sig) { > + ckpt_verbose("Interrupt attempt .. ignored.\n"); > + return; > + } > + > + ckpt_verbose("Interrupted: sent SIG%s to " > + "restarted tasks\n", sig2str(sig)); > > if (pid) { > - ckpt_dbg("delegating SIGINT to child %d " > - "(coordinator or root task)\n", pid); > - kill(-pid, SIGINT); > - kill(pid, SIGINT); > + ckpt_dbg("delegating SIG%s to child %d " > + "(coordinator/root task)\n", > + sig2str(sig), pid); > + kill(-pid, sig); > + kill(pid, sig); > } > } > > -- > 1.6.0.4 > > _______________________________________________ > Containers mailing list > Containers@xxxxxxxxxxxxxxxxxxxxxxxxxx > https://lists.linux-foundation.org/mailman/listinfo/containers _______________________________________________ Containers mailing list Containers@xxxxxxxxxxxxxxxxxxxxxxxxxx https://lists.linux-foundation.org/mailman/listinfo/containers