From 4bef00e8f39ef127ff8922d0931e7ffd95950d20 Mon Sep 17 00:00:00 2001 From: Stef Walter Date: Tue, 18 May 2004 16:23:45 +0000 Subject: Tested on FreeBSD 5.2.1. Fixed bugs. --- srcx/jkill.c | 117 ++++++++++++++++++++++++++++++++++++++--------------------- 1 file changed, 75 insertions(+), 42 deletions(-) (limited to 'srcx/jkill.c') diff --git a/srcx/jkill.c b/srcx/jkill.c index 46b1815..fd3c110 100644 --- a/srcx/jkill.c +++ b/srcx/jkill.c @@ -1,9 +1,11 @@ + #include #include #include #include #include #include +#include #include #include @@ -29,6 +31,12 @@ int g_timeout = DEFAULT_TIMEOUT; /* Supress warnings */ int g_quiet = 0; +int g_verbose = 0; + +static void kill_jail_processes(kvm_t* kd, int sig); +static int kill_jail(const char* jail, int restart, int force); +static int check_running_processes(kvm_t* kd); +static void usage(); int main(int argc, char* argv[]) { @@ -36,9 +44,10 @@ int main(int argc, char* argv[]) int ret = 0; int restart = 0; int force = 0; + int verbose = 0; pid_t child; - while((ch = getopt(argc, argv, "fhqrt:")) != -1) + while((ch = getopt(argc, argv, "fhqrt:v")) != -1) { switch(ch) { @@ -46,15 +55,16 @@ int main(int argc, char* argv[]) force = 1; break; - case 'q': - g_quiet = 1; - break; - case 'h': /* dummy for compatibility with killjail */ warnx("the '-h' option has been depreciated"); break; + case 'q': + g_quiet = 1; + g_verbose = 0; + break; + case 'r': restart = 1; break; @@ -66,6 +76,11 @@ int main(int argc, char* argv[]) errx(2, "invalid timeout argument: %s", optarg); break; + case 'v': + g_verbose = 1; + g_quiet = 0; + break; + case '?': default: usage(); @@ -79,13 +94,16 @@ int main(int argc, char* argv[]) if(argc == 0) usage(); + if(running_in_jail()) + errx(1, "can't run inside jail"); + /* For each jail */ - while(argc > 0) + for(; argc > 0; argc--, argv++) { - jid = translate_jail(argv[0]); + jid = translate_jail_name(argv[0]); if(jid == -1) { - warnx(1, "unknown jail host name: %s", argv[0]); + warnx("unknown jail host name: %s", argv[0]); ret = 1; continue; } @@ -94,7 +112,7 @@ int main(int argc, char* argv[]) * We fork and the child goes into the jail and * does the dirty work. */ - +#ifdef _DEBUG switch((child = fork())) { /* Error condition */ @@ -104,22 +122,25 @@ int main(int argc, char* argv[]) /* The child */ case 0: +#endif if(jail_attach(jid) == -1) err(1, "couldn't attach to jail"); - r = kill_jail(restart, force, argv[0]); + r = kill_jail(argv[0], restart, force); exit(r); +#ifdef _DEBUG break; /* The parent */ default: - if(waitpid(child, &r, options) == -1) + if(waitpid(child, &r, 0) == -1) err(1, "error waiting for child process"); - if(r != 0) - ret = r; + if(WEXITSTATUS(r) != 0) + ret = WEXITSTATUS(r); break; }; +#endif argc--; argv++; @@ -128,13 +149,20 @@ int main(int argc, char* argv[]) return ret; } -int kill_jail(int restart, int force, const char* name) +#define SHUTDOWN_SCRIPT "/etc/rc.shutdown" +static char* SHUTDOWN_ARGS[] = { _PATH_BSHELL, SHUTDOWN_SCRIPT }; + +#define START_SCRIPT "/etc/rc" +static char* START_ARGS[] = { _PATH_BSHELL, START_SCRIPT }; + +static int kill_jail(const char* jail, int restart, int force) { kvm_t* kd = NULL; char errbuf[_POSIX2_LINE_MAX]; int pass = 0; int timeout = 0; int ret = 0; + int cmdargs = JAIL_RUN_CONSOLE; /* Open the kernel interface */ kd = kvm_openfiles(_PATH_DEVNULL, _PATH_DEVNULL, _PATH_DEVNULL, @@ -142,11 +170,14 @@ int kill_jail(int restart, int force, const char* name) if(kd == NULL) errx(1, "couldn't connect to kernel: %s", errbuf); + if(g_verbose) + cmdargs |= JAIL_RUN_STDERR; + /* * Multiple passes are used to do different things. * Each time the jails processes are listed. */ - while(true) + while(1) { while(timeout > 0) { @@ -163,8 +194,8 @@ int kill_jail(int restart, int force, const char* name) case 0: /* Check if we have an executable shutdown script */ - if(check_jail_command(name, "/etc/rc.shutdown")) - run_jail_command(name, "/etc/rc.shutdown", NULL, JAIL_OUT_CONSOLE); + if(check_jail_command(jail, SHUTDOWN_SCRIPT)) + run_jail_command(jail, SHUTDOWN_ARGS[0], SHUTDOWN_ARGS, cmdargs); break; @@ -174,14 +205,20 @@ int kill_jail(int restart, int force, const char* name) timeout = g_timeout; break; - /* Okay now we force kill the processes if necessary */ + /* ... and again ... */ case 2: + kill_jail_processes(kd, SIGTERM); + timeout = g_timeout; + break; + + /* Okay now we force kill the processes if necessary */ + case 3: if(force) { /* If we get here, jailer looks like it's really irresponsive */ if(!g_quiet) - warnx("%s: jail won't stop. forcing jail termination...", name); + warnx("%s: jail won't stop. forcing jail termination...", jail); kill_jail_processes(kd, SIGKILL); timeout = g_timeout; @@ -189,27 +226,14 @@ int kill_jail(int restart, int force, const char* name) break; + case 4: - case 3: - - if(check_running_processes(kd)) - { - /* And if that didn't do it, well then give up */ - if(!g_quiet) - warnx("%s: couldn't stop jail, processes wouldn't die", name); - - ret = 1; - goto done; - } - - else if(restart) - { - /* Check if we have an executable shutdown script */ - if(check_jail_command(name, "/etc/rc")) - run_jail_command(name, "/etc/rc", NULL, JAIL_OUT_CONSOLE); + /* And if that didn't do it, well then give up */ + if(!g_quiet) + warnx("%s: couldn't stop jail, processes wouldn't die", jail); - goto done; - } + ret = 1; + goto done; } pass++; @@ -219,13 +243,20 @@ int kill_jail(int restart, int force, const char* name) } done: + if(restart) + { + /* Check if we have an executable shutdown script */ + if(check_jail_command(jail, START_SCRIPT)) + run_jail_command(jail, START_ARGS[0], START_ARGS, cmdargs); + } + if(kd != NULL) kvm_close(kd); return ret; } -void kill_jail_processes(kvm_t* kd, int sig) +static void kill_jail_processes(kvm_t* kd, int sig) { struct kinfo_proc* kp; int nentries, i; @@ -251,7 +282,7 @@ void kill_jail_processes(kvm_t* kd, int sig) } } -int check_running_processes(kvm_t* kd) +static int check_running_processes(kvm_t* kd) { struct kinfo_proc* kp; int nentries, i; @@ -263,7 +294,7 @@ int check_running_processes(kvm_t* kd) if((kp = kvm_getprocs(kd, KERN_PROC_ALL, 0, &nentries)) == 0) errx(1, "couldn't list processes: %s", kvm_geterr(kd)); - if(&nentries != 1) + if(nentries != 1) return 1; /* Okay now loop and look at each process' jail */ @@ -278,6 +309,8 @@ int check_running_processes(kvm_t* kd) static void usage() { - fprintf(stderr, "usage: killjail [ -r ] [ -t timeout ] [ -qf ] jailname ...\n"); + fprintf(stderr, "usage: killjail [-fqrv] [-t timeout] jailname ...\n"); exit(2); } + + -- cgit v1.2.3