if BUILD_KILL
bin_PROGRAMS += kill
dist_man_MANS += kill.1
-kill_SOURCES = skill.c lib/strutils.c lib/fileutils.c lib/nsutils.c lib/signals.c
+kill_SOURCES = skill.c lib/strutils.c lib/fileutils.c lib/signals.c
else
EXTRA_DIST += kill.1
endif
bin_PROGRAMS += \
skill \
snice
-skill_SOURCES = skill.c lib/strutils.c lib/fileutils.c lib/nsutils.c lib/signals.c
-snice_SOURCES = skill.c lib/strutils.c lib/fileutils.c lib/nsutils.c lib/signals.c
+skill_SOURCES = skill.c lib/strutils.c lib/fileutils.c lib/signals.c
+snice_SOURCES = skill.c lib/strutils.c lib/fileutils.c lib/signals.c
dist_man_MANS += \
skill.1 \
snice.1
endif
free_SOURCES = free.c lib/strutils.c lib/fileutils.c
-pgrep_SOURCES = pgrep.c lib/fileutils.c lib/nsutils.c lib/signals.c
-pkill_SOURCES = pgrep.c lib/fileutils.c lib/nsutils.c lib/signals.c
+pgrep_SOURCES = pgrep.c lib/fileutils.c lib/signals.c
+pkill_SOURCES = pgrep.c lib/fileutils.c lib/signals.c
pmap_SOURCES = pmap.c lib/fileutils.c
pwdx_SOURCES = pwdx.c lib/fileutils.c
pwdx_LDADD=
proc/procps-private.h \
proc/meminfo.c \
proc/meminfo.h \
+ proc/namespace.c \
+ proc/namespace.h \
proc/pids.c \
proc/pids.h \
proc/procps.h \
noinst_PROGRAMS = \
lib/test_strutils \
lib/test_fileutils \
- lib/test_nsutils \
lib/test_process \
- proc/test_sysinfo
+ proc/test_sysinfo \
+ proc/test_namespace
lib_test_strutils_SOURCES = lib/test_strutils.c lib/strutils.c
lib_test_strutils_LDADD =
lib_test_fileutils_SOURCES = lib/test_fileutils.c lib/fileutils.c
lib_test_fileutils_LDADD =
-lib_test_nsutils_SOURCES = lib/test_nsutils.c lib/nsutils.c
-lib_test_nsutils_LDADD =
lib_test_process_SOURCES = lib/test_process.c
lib_test_process_LDADD =
proc_test_sysinfo_SOURCES = proc/test_sysinfo.c
proc_test_sysinfo_LDADD = proc/libprocps.la
+proc_test_namespace_SOURCES = proc/test_namespace.c
+proc_test_namespace_LDADD = proc/libprocps.la
if EXAMPLE_FILES
sysconf_DATA = sysctl.conf
endif
BUILT_SOURCES = $(top_srcdir)/.version
-TESTS = proc/test_sysinfo
+TESTS = proc/test_sysinfo \
+ proc/test_namespace
$(top_srcdir)/.version:
touch $(top_srcdir)/.version
c.h \
fileutils.h \
nls.h \
- nsutils.h \
rpmatch.h \
signals.h \
strutils.h \
+++ /dev/null
-#ifndef PROCPS_NG_NSUTILS
-#define PROCPS_NG_NSUTILS
-
-#include "proc/readproc.h"
-int ns_read(pid_t pid, proc_t *ns_task);
-
-#endif
+++ /dev/null
-#include <stdio.h>
-#include <errno.h>
-#include <stdlib.h>
-#include <sys/types.h>
-#include <sys/stat.h>
-#include <unistd.h>
-
-#include "proc/readproc.h"
-#include "nsutils.h"
-
-/* we need to fill in only namespace information */
-int ns_read(pid_t pid, proc_t *ns_task)
-{
- struct stat st;
- char buff[50];
- int i, rc = 0;
-
- for (i = 0; i < NUM_NS; i++) {
- snprintf(buff, sizeof(buff), "/proc/%i/ns/%s", pid,
- get_ns_name(i));
- if (stat(buff, &st)) {
- if (errno != ENOENT)
- rc = errno;
- ns_task->ns[i] = 0;
- continue;
- }
- ns_task->ns[i] = st.st_ino;
- }
- return rc;
-}
+++ /dev/null
-#include <stdio.h>
-#include <stdlib.h>
-
-#include "nsutils.h"
-
-const char *get_ns_name(int id)
-{
- return NULL;
-}
-
-int main(int argc, char *argv[])
-{
- printf("Hello, World!\n");
- return EXIT_SUCCESS;
-}
#include "c.h"
#include "fileutils.h"
-#include "nsutils.h"
#include "nls.h"
#include "signals.h"
#include "xalloc.h"
#include "proc/readproc.h"
#include "proc/devname.h"
#include "proc/sysinfo.h"
+#include <proc/namespace.h>
static int i_am_pkill = 0;
int id;
ns_flags = 0;
- id = get_ns_id(name);
+ id = procps_ns_get_id(name);
if (id == -1)
return 0;
ns_flags |= (1 << id);
return found;
}
-static int match_ns (const proc_t *task, const proc_t *ns_task)
+static int match_ns (const proc_t *task,
+ const struct procps_namespaces *namespaces)
{
int found = 1;
int i;
for (i = 0; i < NUM_NS; i++) {
if (ns_flags & (1 << i)) {
- if (task->ns[i] != ns_task->ns[i])
+ if (task->ns.ns[i] != namespaces->ns[i])
found = 0;
}
}
char cmdline[CMDSTRSIZE];
char cmdsearch[CMDSTRSIZE];
char cmdoutput[CMDSTRSIZE];
- proc_t ns_task;
+ struct procps_namespaces namespaces;
ptp = do_openproc();
preg = do_regcomp();
if (opt_newest) saved_pid = 0;
if (opt_oldest) saved_pid = INT_MAX;
- if (opt_ns_pid && ns_read(opt_ns_pid, &ns_task)) {
+ if (opt_ns_pid && procps_ns_read_pid(opt_ns_pid, &namespaces) < 0) {
fputs(_("Error reading reference namespace information\n"),
stderr);
exit (EXIT_FATAL);
match = 0;
else if (opt_sid && ! match_numlist (task.session, opt_sid))
match = 0;
- else if (opt_ns_pid && ! match_ns (&task, &ns_task))
+ else if (opt_ns_pid && ! match_ns (&task, &namespaces))
match = 0;
else if (opt_term) {
if (task.tty == 0) {
test_sysinfo
+test_namespace
escape_strlist;
escaped_copy;
freeproc;
- get_ns_id;
- get_ns_name;
get_pid_digits;
look_up_our_self;
lookup_wchan;
procps_meminfo_getstack;
procps_meminfo_stack_fill;
procps_meminfo_stack_alloc;
+ procps_ns_get_name;
+ procps_ns_get_id;
+ procps_ns_read_pid;
procps_pids_new;
procps_pids_read_next;
procps_pids_read_open;
--- /dev/null
+/*
+ * libprocps - Library to read proc filesystem
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#include <errno.h>
+#include <stdio.h>
+#include <string.h>
+#include <sys/stat.h>
+
+#include <proc/namespace.h>
+#include "proc/procps-private.h"
+
+#define NSPATHLEN 64
+
+static const char *ns_names[] = {
+ [PROCPS_NS_IPC] = "ipc",
+ [PROCPS_NS_MNT] = "mnt",
+ [PROCPS_NS_NET] = "net",
+ [PROCPS_NS_PID] = "pid",
+ [PROCPS_NS_USER] = "user",
+ [PROCPS_NS_UTS] = "uts",
+};
+
+
+/*
+ * procps_ns_get_name:
+ *
+ * Find the name of the namespace with the given ID
+ *
+ * @id: The ID of the required namespace, see
+ * namespace_type
+ *
+ * Returns: static string of the namespace
+ */
+PROCPS_EXPORT const char *procps_ns_get_name(const int id)
+{
+ if (id >= PROCPS_NS_COUNT || id < 0)
+ return NULL;
+ return ns_names[id];
+}
+
+/*
+ * procps_ns_get_id:
+ *
+ * Find the namespace ID that matches the given
+ * name.
+ *
+ * @name: the name of the required namespace
+ *
+ * Returns: ID of found name
+ * < 0 means error
+ */
+PROCPS_EXPORT int procps_ns_get_id(const char *name)
+{
+ int i;
+
+ if (name == NULL)
+ return -EINVAL;
+ for (i=0; i < PROCPS_NS_COUNT; i++)
+ if (!strcmp(ns_names[i], name))
+ return i;
+ return -EINVAL;
+}
+
+/*
+ * procs_ns_read_pid:
+ *
+ * Find all namespaces for the given process.
+ * @pid: Process ID for required process
+ * @nsp: Pointer to the struct procps_namespaces
+ *
+ * Returns:
+ * 0 on success
+ * < 0 on error
+ */
+PROCPS_EXPORT int procps_ns_read_pid(
+ const int pid,
+ struct procps_namespaces *nsp)
+{
+ char path[NSPATHLEN+1];
+ struct stat st;
+ int i;
+
+ if (nsp == NULL)
+ return -EINVAL;
+ if (pid < 1)
+ return -EINVAL;
+
+ for (i=0; i < PROCPS_NS_COUNT; i++) {
+ snprintf(path, NSPATHLEN, "/proc/%d/ns/%s", pid, ns_names[i]);
+ if (0 == stat(path, &st))
+ nsp->ns[i] = (long)st.st_ino;
+ else
+ nsp->ns[i] = 0;
+ }
+}
--- /dev/null
+/*
+ * libprocps - Library to read proc filesystem
+ *
+ * Copyright (C) 1996 Charles Blake <cblake@bbn.com>
+ * Copyright (C) 1998 Michael K. Johnson
+ * Copyright (C) 1998-2003 Albert Cahalan
+ * Copyright (C) 2015 Craig Small <csmall@enc.com.au>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+#ifndef PROC_NAMESPACE_H
+#define PROC_NAMESPACE_H
+
+#include <proc/procps.h>
+
+__BEGIN_DECLS
+
+enum namespace_type {
+ PROCPS_NS_IPC,
+ PROCPS_NS_MNT,
+ PROCPS_NS_NET,
+ PROCPS_NS_PID,
+ PROCPS_NS_USER,
+ PROCPS_NS_UTS,
+ PROCPS_NS_COUNT // total namespaces (fencepost)
+};
+
+struct procps_namespaces {
+ long ns[PROCPS_NS_COUNT];
+};
+
+const char *procps_ns_get_name(const int id);
+
+int procps_ns_get_id(const char *name);
+
+int procps_ns_read_pid(const int pid, struct procps_namespaces *nsp);
+__END_DECLS
+
+#endif
CVT_set(MEM_VIRT_KIB, ul_int, size)
REG_set(NICE, sl_int, nice)
REG_set(NLWP, s_int, nlwp)
-REG_set(NS_IPC, ul_int, ns[0])
-REG_set(NS_MNT, ul_int, ns[1])
-REG_set(NS_NET, ul_int, ns[2])
-REG_set(NS_PID, ul_int, ns[3])
-REG_set(NS_USER, ul_int, ns[4])
-REG_set(NS_UTS, ul_int, ns[5])
+REG_set(NS_IPC, ul_int, ns.ns[0])
+REG_set(NS_MNT, ul_int, ns.ns[1])
+REG_set(NS_NET, ul_int, ns.ns[2])
+REG_set(NS_PID, ul_int, ns.ns[3])
+REG_set(NS_USER, ul_int, ns.ns[4])
+REG_set(NS_UTS, ul_int, ns.ns[5])
REG_set(OOM_ADJ, s_int, oom_adj)
REG_set(OOM_SCORE, s_int, oom_score)
REG_set(PRIORITY, s_int, priority)
#ifdef WITH_SYSTEMD
#include <systemd/sd-login.h>
#endif
+#include <proc/namespace.h>
// sometimes it's easier to do this manually, w/o gcc helping
#ifdef PROF
}
///////////////////////////////////////////////////////////////////////
-static const char *ns_names[] = {
- [IPCNS] = "ipc",
- [MNTNS] = "mnt",
- [NETNS] = "net",
- [PIDNS] = "pid",
- [USERNS] = "user",
- [UTSNS] = "uts",
-};
-
-const char *get_ns_name(int id) {
- if (id >= NUM_NS)
- return NULL;
- return ns_names[id];
-}
-
-int get_ns_id(const char *name) {
- int i;
-
- for (i = 0; i < NUM_NS; i++)
- if (!strcmp(ns_names[i], name))
- return i;
- return -1;
-}
-
-static void ns2proc(const char *directory, proc_t *restrict p) {
- char path[PROCPATHLEN];
- struct stat sb;
- int i;
-
- for (i = 0; i < NUM_NS; i++) {
- snprintf(path, sizeof(path), "%s/ns/%s", directory, ns_names[i]);
- if (0 == stat(path, &sb))
- p->ns[i] = (long)sb.st_ino;
-#if 0
- else // this allows a caller to distinguish
- p->ns[i] = -errno; // between the ENOENT or EACCES errors
-#endif
- }
-}
-
#ifdef WITH_SYSTEMD
static void sd2proc(proc_t *restrict p) {
char buf[64];
}
if (unlikely(flags & PROC_FILLNS)) // read /proc/#/ns/*
- ns2proc(path, p);
+ procps_ns_read_pid(p->tid, &(p->ns));
+
#ifdef WITH_SYSTEMD
if (unlikely(flags & PROC_FILLSYSTEMD)) // get sd-login.h stuff
}
if (unlikely(flags & PROC_FILLNS)) // read /proc/#/task/#/ns/*
- ns2proc(path, t);
+ procps_ns_read_pid(t->tid, &(t->ns));
return t;
next_task:
#include <proc/procps.h>
#include <proc/pwcache.h>
+#include <proc/namespace.h>
#define SIGNAL_STRING
//#define QUICK_THREADS /* copy (vs. read) some thread info from parent proc_t */
int
oom_score, // oom_score (badness for OOM killer)
oom_adj; // oom_adj (adjustment to OOM score)
- long
- ns[NUM_NS]; // (ns subdir) inode number of namespaces
+ struct procps_namespaces ns; // (ns subdir) inode number of namespaces
char
*sd_mach, // n/a systemd vm/container name
*sd_ouid, // n/a systemd session owner uid
--- /dev/null
+/*
+ * libprocps - Library to read proc filesystem
+ * Tests for namespace library calls
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+
+#include <proc/namespace.h>
+
+struct test_func {
+ int (*func)(void *data);
+ char *name;
+};
+
+int check_name_minus(void *data)
+{
+ return (procps_ns_get_name(-1) == NULL);
+}
+
+int check_name_over(void *data)
+{
+ return (procps_ns_get_name(999) == NULL);
+}
+
+int check_name_ipc(void *data)
+{
+ return (strcmp(procps_ns_get_name(PROCPS_NS_IPC),"ipc")==0);
+}
+
+int check_id_null(void *data)
+{
+ return (procps_ns_get_id(NULL) < 0);
+}
+
+int check_id_unfound(void *data)
+{
+ return (procps_ns_get_id("foobar") < 0);
+}
+
+int check_id_mnt(void *data)
+{
+ return (procps_ns_get_id("mnt") == PROCPS_NS_MNT);
+}
+
+struct test_func tests[] = {
+ { check_name_minus, "procps_ns_get_name() negative id"},
+ { check_name_over, "procps_ns_get_name() id over limit"},
+ { check_name_ipc, "procps_ns_get_name() ipc"},
+ { check_id_null, "procps_ns_get_id(NULL)"},
+ { check_id_unfound, "procps_ns_get_id(unknown)"},
+ { check_id_mnt, "procps_ns_get_id(mnt)"},
+ { NULL, NULL}
+};
+
+int main(int argc, char *argv[])
+{
+ int i;
+ struct test_func *current;
+
+ for(i=0; tests[i].func != NULL; i++) {
+ current = &tests[i];
+ if (!current->func(NULL)) {
+ fprintf(stderr, "FAIL: %s\n", current->name);
+ return EXIT_FAILURE;
+ } else {
+ fprintf(stderr, "PASS: %s\n", current->name);
+ }
+ }
+ return EXIT_SUCCESS;
+}
+
+
#define CMP_NS(NAME, ID) \
static int sr_ ## NAME (const proc_t* P, const proc_t* Q) { \
- if (P->ns[ID] < Q->ns[ID]) return -1; \
- if (P->ns[ID] > Q->ns[ID]) return 1; \
+ if (P->ns.ns[ID] < Q->ns.ns[ID]) return -1; \
+ if (P->ns.ns[ID] > Q->ns.ns[ID]) return 1; \
return 0; \
}
#define _pr_ns(NAME, ID)\
static int pr_##NAME(char *restrict const outbuf, const proc_t *restrict const pp) {\
- if (pp->ns[ID])\
- return snprintf(outbuf, COLWID, "%li", pp->ns[ID]);\
+ if (pp->ns.ns[ID])\
+ return snprintf(outbuf, COLWID, "%li", pp->ns.ns[ID]);\
else\
return snprintf(outbuf, COLWID, "-");\
}
#include "c.h"
#include "fileutils.h"
-#include "nsutils.h"
#include "signals.h"
#include "strutils.h"
#include "nls.h"
#include "xalloc.h"
#include "proc/pwcache.h"
#include "proc/devname.h"
+#include <proc/namespace.h>
#include "rpmatch.h"
#define DEFAULT_NICE 4
static int *pids;
static char **namespaces;
static int ns_pid;
-static proc_t ns_task;
+static struct procps_namespaces ns;
#define ENLIST(thing,addme) do{ \
if(!thing##s) thing##s = xmalloc(sizeof(*thing##s)*saved_argc); \
tmp = strndup(ptr, len);
}
- id = get_ns_id(tmp);
+ id = procps_ns_get_id(tmp);
if (id == -1) {
fprintf(stderr, "%s is not a valid namespace\n", tmp);
free(tmp);
{
char buf[128];
struct stat statbuf;
- proc_t task;
+ struct procps_namespaces pid_ns;
char *tmp;
int tty;
int fd;
goto closure;
}
if (ns_pid) {
- if (ns_read(pid, &task))
+ if (procps_ns_read_pid(pid, &pid_ns) < 0)
goto closure;
- for (i = 0; i < NUM_NS; i++) {
+ for (i = 0; i < PROCPS_NS_COUNT; i++) {
if (ns_flags & (1 << i)) {
- if (task.ns[i] != ns_task.ns[i])
+ if (pid_ns.ns[i] != ns.ns[i])
goto closure;
}
}
xwarnx(_("invalid pid number %s"), optarg);
kill_usage(stderr);
}
- if (ns_read(ns_pid, &ns_task)) {
+ if (procps_ns_read_pid(ns_pid, &ns) < 0) {
xwarnx(_("error reading reference namespace "
"information"));
kill_usage(stderr);