diff options
author | Craig Small <csmall@enc.com.au> | 2013-09-11 21:34:05 +1000 |
---|---|---|
committer | Craig Small <csmall@enc.com.au> | 2013-09-11 21:34:05 +1000 |
commit | dd6f24dbed12e95235b3df49e550b5039e74e6d8 (patch) | |
tree | 457b8c6008fecf53166f3fa1d5ff3c80f07b0e7e /skill.c | |
parent | 5e4d9d5a926c46e69e9ce03cf42de08a399ea5c6 (diff) | |
parent | 91d225f3b8fcfa514f1ef20239af7b0ada64c01c (diff) | |
download | procps-ng-dd6f24dbed12e95235b3df49e550b5039e74e6d8.tar.gz |
Merge commit 'refs/merge-requests/13' of git://gitorious.org/procps/procps into merge-requests/13
Conflicts:
pgrep.c
ps/output.c
ps/ps.1
Diffstat (limited to 'skill.c')
-rw-r--r-- | skill.c | 88 |
1 files changed, 86 insertions, 2 deletions
@@ -36,6 +36,7 @@ #include "c.h" #include "fileutils.h" +#include "nsutils.h" #include "strutils.h" #include "nls.h" #include "xalloc.h" @@ -43,6 +44,7 @@ #include "proc/sig.h" #include "proc/devname.h" #include "proc/procps.h" /* char *user_from_uid(uid_t uid) */ +#include "proc/readproc.h" #include "proc/version.h" /* procps_version */ #include "rpmatch.h" @@ -56,11 +58,14 @@ struct run_time_conf_t { int noaction; int debugging; }; -static int tty_count, uid_count, cmd_count, pid_count; +static int tty_count, uid_count, cmd_count, pid_count, namespace_count; static int *ttys; static uid_t *uids; static const char **cmds; static int *pids; +static char **namespaces; +static int ns_pid; +static proc_t ns_task; #define ENLIST(thing,addme) do{ \ if(!thing##s) thing##s = xmalloc(sizeof(*thing##s)*saved_argc); \ @@ -85,6 +90,39 @@ static void display_kill_version(void) fprintf(stdout, PROCPS_NG_VERSION); } +static int ns_flags = 0x3f; +static int parse_namespaces(char *optarg) +{ + char *ptr = optarg, *tmp; + int len, id; + + ns_flags = 0; + while (1) { + if (strchr(ptr, ',') == NULL) { + len = -1; + tmp = strdup(ptr); + } else { + len = strchr(ptr, ',') - ptr; + tmp = strndup(ptr, len); + } + + id = get_ns_id(tmp); + if (id == -1) { + fprintf(stderr, "%s is not a valid namespace\n", tmp); + free(tmp); + return 1; + } + ns_flags |= (1 << id); + ENLIST(namespace, tmp); + + if (len == -1) + break; + + ptr+= len + 1; + } + return 0; +} + /* kill or nice a process */ static void hurt_proc(int tty, int uid, int pid, const char *restrict const cmd, struct run_time_conf_t *run_time) @@ -131,6 +169,7 @@ static void check_proc(int pid, struct run_time_conf_t *run_time) { char buf[128]; struct stat statbuf; + proc_t task; char *tmp; int tty; int fd; @@ -183,6 +222,16 @@ static void check_proc(int pid, struct run_time_conf_t *run_time) if (i == -1) goto closure; } + if (ns_pid) { + if (ns_read(pid, &task)) + goto closure; + for (i = 0; i < NUM_NS; i++) { + if (ns_flags & (1 << i)) { + if (task.ns[i] != ns_task.ns[i]) + goto closure; + } + } + } /* This is where we kill/nice something. */ /* for debugging purposes? fprintf(stderr, "PID %d, UID %d, TTY %d,%d, COMM %s\n", @@ -317,6 +366,15 @@ static void __attribute__ ((__noreturn__)) skillsnice_usage(FILE * out) " -t, --tty <tty> expression is a terminal\n" " -u, --user <username> expression is a username\n"), out); fputs(USAGE_SEPARATOR, out); + fputs(_("Alternatively, expression can be:\n" + " --ns <pid> match the processes that belong to the same\n" + " namespace as <pid>\n" + " --nslist <ns,...> list which namespaces will be considered for\n" + " the --ns option.\n" + " Available namespaces: ipc, mnt, net, pid, user, uts\n"), out); + + fputs(USAGE_SEPARATOR, out); + fputs(USAGE_SEPARATOR, out); fputs(USAGE_HELP, out); fputs(USAGE_VERSION, out); if (program == PROG_SKILL) { @@ -488,6 +546,11 @@ static void skillsnice_parse(int argc, int prino = DEFAULT_NICE; int ch, i; + enum { + NS_OPTION = CHAR_MAX + 1, + NSLIST_OPTION, + }; + static const struct option longopts[] = { {"command", required_argument, NULL, 'c'}, {"debug", no_argument, NULL, 'd'}, @@ -499,6 +562,8 @@ static void skillsnice_parse(int argc, {"table", no_argument, NULL, 'L'}, {"tty", required_argument, NULL, 't'}, {"user", required_argument, NULL, 'u'}, + {"ns", required_argument, NULL, NS_OPTION}, + {"nslist", required_argument, NULL, NSLIST_OPTION}, {"verbose", no_argument, NULL, 'v'}, {"warnings", no_argument, NULL, 'w'}, {"help", no_argument, NULL, 'h'}, @@ -572,6 +637,25 @@ static void skillsnice_parse(int argc, } } break; + case NS_OPTION: + ns_pid = atoi(optarg); + if (ns_pid == 0) { + xwarnx(_("invalid pid number %i"), optarg); + kill_usage(stderr); + } + if (ns_read(ns_pid, &ns_task)) { + xwarnx(_("error reading reference namespace " + "information")); + kill_usage(stderr); + } + + break; + case NSLIST_OPTION: + if (parse_namespaces(optarg)) { + xwarnx(_("invalid namespace list")); + kill_usage(stderr); + } + break; case 'v': run_time->verbose = 1; break; @@ -605,7 +689,7 @@ static void skillsnice_parse(int argc, } /* No more arguments to process. Must sanity check. */ - if (!tty_count && !uid_count && !cmd_count && !pid_count) + if (!tty_count && !uid_count && !cmd_count && !pid_count && !ns_pid) xerrx(EXIT_FAILURE, _("no process selection criteria")); if ((run_time->fast | run_time->interactive | run_time-> verbose | run_time->warnings | run_time->noaction) & ~1) |