#define ER_UNKWN -3
#define ER_OOFRA -4
+static pid_t opt_ns_pid = 0;
+
static int verbose = 0, exact = 0, interactive = 0, reg = 0,
quiet = 0, wait_until_dead = 0, process_group = 0,
ignore_case = 0;
return -1;
}
+enum ns_type {
+ IPCNS = 0,
+ MNTNS,
+ NETNS,
+ PIDNS,
+ USERNS,
+ UTSNS
+};
+
+static const char *ns_names[] = {
+ [IPCNS] = "ipc",
+ [MNTNS] = "mnt",
+ [NETNS] = "net",
+ [PIDNS] = "pid",
+ [USERNS] = "user",
+ [UTSNS] = "uts",
+};
+
+#define NUM_NS 6
+
+const char *get_ns_name(int id) {
+ if (id >= NUM_NS)
+ return NULL;
+ return ns_names[id];
+}
+
+static int get_ns(pid_t pid, int id) {
+ struct stat st;
+ char buff[50];
+ snprintf(buff, sizeof(buff), "/proc/%i/ns/%s", pid, get_ns_name(id));
+ if (stat(buff, &st))
+ return 0;
+ else
+ return st.st_ino;
+}
+
static int
match_process_uid(pid_t pid, uid_t uid)
{
uid_t puid;
FILE *f;
int re = -1;
-
+
snprintf (buf, sizeof buf, PROC_BASE "/%d/status", pid);
if (!(f = fopen (buf, "r")))
return 0;
char *path, *p, *command_buf;
int cmd_size = 128;
int okay;
-
+
if (asprintf (&path, PROC_BASE "/%d/cmdline", pid) < 0)
return -1;
if (!(file = fopen (path, "r")))
int i, j, length, got_long, error;
int pids, max_pids, pids_killed;
unsigned long found;
- regex_t *reglist = NULL;;
+ regex_t *reglist = NULL;
+ long ns_ino = 0;
#ifdef WITH_SELINUX
security_context_t lcontext=NULL;
#endif /*WITH_SELINUX*/
+ if (opt_ns_pid)
+ ns_ino = get_ns(opt_ns_pid, PIDNS);
+
if (name_count && reg)
reglist = build_regexp_list(name_count, namelist);
else
/* match by UID */
if (pwent && match_process_uid(pid_table[i], pwent->pw_uid)==0)
continue;
+ if (opt_ns_pid && ns_ino && ns_ino != get_ns(pid_table[i], PIDNS))
+ continue;
#ifdef WITH_SELINUX
/* match by SELinux context */
" -u,--user USER kill only process(es) running as USER\n"
" -v,--verbose report if the signal was successfully sent\n"
" -V,--version display version information\n"
- " -w,--wait wait for processes to die\n"));
+ " -w,--wait wait for processes to die\n"
+ " -n,--ns PID match processes that belong to the same namespaces\n"
+ " as PID or 0 for all namespaces\n"));
+
#ifdef WITH_SELINUX
fprintf(stderr, _(
" -Z,--context REGEXP kill only process(es) having context\n"
{"user", 1, NULL, 'u'},
{"verbose", 0, NULL, 'v'},
{"wait", 0, NULL, 'w'},
+ {"ns", 1, NULL, 'n' },
#ifdef WITH_SELINUX
{"context", 1, NULL, 'Z'},
#endif /*WITH_SELINUX*/
{"version", 0, NULL, 'V'},
{0,0,0,0 }};
+ opt_ns_pid = getpid();
+
/* Setup the i18n */
#ifdef ENABLE_NLS
setlocale(LC_ALL, "");
opterr = 0;
#ifdef WITH_SELINUX
- while ( (optc = getopt_long_only(argc,argv,"egy:o:ilqrs:u:vwZ:VI",options,NULL)) != -1) {
+ while ( (optc = getopt_long_only(argc,argv,"egy:o:ilqrs:u:vwZ:VIn:",options,NULL)) != -1) {
#else
- while ( (optc = getopt_long_only(argc,argv,"egy:o:ilqrs:u:vwVI",options,NULL)) != -1) {
+ while ( (optc = getopt_long_only(argc,argv,"egy:o:ilqrs:u:vwVIn:",options,NULL)) != -1) {
#endif
switch (optc) {
case 'e':
}
sig_num = get_signal (argv[optind]+1, "killall");
break;
+ case 'n':
+ opt_ns_pid = atoi(optarg);
+ break;
#ifdef WITH_SELINUX
case 'Z':
if (is_selinux_enabled()>0) {