summaryrefslogtreecommitdiffstats
path: root/sys-utils/lsns.c
diff options
context:
space:
mode:
authorKarel Zak2015-11-30 15:55:31 +0100
committerKarel Zak2015-11-30 15:55:31 +0100
commit304fbe8b3ca320b1447824ee104b5fe66d5eb477 (patch)
tree0ecec8828f08c6be085555e7f17dbfaf2eafc8e6 /sys-utils/lsns.c
parentlsln: allows to list namespace processes (diff)
downloadkernel-qcow2-util-linux-304fbe8b3ca320b1447824ee104b5fe66d5eb477.tar.gz
kernel-qcow2-util-linux-304fbe8b3ca320b1447824ee104b5fe66d5eb477.tar.xz
kernel-qcow2-util-linux-304fbe8b3ca320b1447824ee104b5fe66d5eb477.zip
lsns: filter by NS type
Signed-off-by: Karel Zak <kzak@redhat.com>
Diffstat (limited to 'sys-utils/lsns.c')
-rw-r--r--sys-utils/lsns.c59
1 files changed, 47 insertions, 12 deletions
diff --git a/sys-utils/lsns.c b/sys-utils/lsns.c
index 84e013a71..96baa6cfa 100644
--- a/sys-utils/lsns.c
+++ b/sys-utils/lsns.c
@@ -143,8 +143,10 @@ struct lsns {
struct list_head processes;
struct list_head namespaces;
- pid_t pid; /* filter out by PID */
- ino_t ns; /* filter out by namespace */
+ pid_t fltr_pid; /* filter out by PID */
+ ino_t fltr_ns; /* filter out by namespace */
+ int fltr_types[ARRAY_SIZE(ns_names)];
+ int fltr_ntypes;
unsigned int raw : 1,
json : 1,
@@ -159,6 +161,17 @@ static void lsns_init_debug(void)
__UL_INIT_DEBUG(lsns, LSNS_DEBUG_, 0, LSNS_DEBUG);
}
+static int ns_name2type(const char *name)
+{
+ size_t i;
+
+ for (i = 0; i < ARRAY_SIZE(ns_names); i++) {
+ if (strcmp(ns_names[i], name) == 0)
+ return i;
+ }
+ return -1;
+}
+
static int column_name_to_id(const char *name, size_t namesz)
{
size_t i;
@@ -202,6 +215,7 @@ static ino_t get_ns_ino(int dir, const char *nsname, ino_t *ino)
return 0;
}
+
static int read_process(struct lsns *ls, pid_t pid)
{
struct lsns_process *p = NULL;
@@ -249,6 +263,9 @@ static int read_process(struct lsns *ls, pid_t pid)
for (i = 0; i < ARRAY_SIZE(p->ns_ids); i++) {
INIT_LIST_HEAD(&p->ns_siblings[i]);
+ if (!ls->fltr_types[i])
+ continue;
+
rc = get_ns_ino(dirfd(dir), ns_names[i], &p->ns_ids[i]);
if (rc && rc != -EACCES)
goto done;
@@ -500,7 +517,7 @@ static int show_namespaces(struct lsns *ls)
list_for_each(p, &ls->namespaces) {
struct lsns_namespace *ns = list_entry(p, struct lsns_namespace, namespaces);
- if (ls->pid != 0 && !namespace_has_process(ns, ls->pid))
+ if (ls->fltr_pid != 0 && !namespace_has_process(ns, ls->fltr_pid))
continue;
add_scols_line(ls, tab, ns, ns->proc);
@@ -568,6 +585,7 @@ static void __attribute__ ((__noreturn__)) usage(FILE * out)
fputs(_(" -p, --task <pid> print process namespaces\n"), out);
fputs(_(" -r, --raw use the raw output format\n"), out);
fputs(_(" -u, --notruncate don't truncate text in columns\n"), out);
+ fputs(_(" -t, --type <name> namespace type (mnt, net, ipc, user, pid, uts)\n"), out);
fputs(USAGE_SEPARATOR, out);
fputs(USAGE_HELP, out);
@@ -583,13 +601,13 @@ static void __attribute__ ((__noreturn__)) usage(FILE * out)
exit(out == stderr ? EXIT_FAILURE : EXIT_SUCCESS);
}
+
int main(int argc, char *argv[])
{
struct lsns ls;
int c;
int r = 0;
char *outarg = NULL;
- ino_t ns_ino = 0;
static const struct option long_opts[] = {
{ "json", no_argument, NULL, 'J' },
{ "task", required_argument, NULL, 'p' },
@@ -600,6 +618,7 @@ int main(int argc, char *argv[])
{ "noheadings", no_argument, NULL, 'n' },
{ "list", no_argument, NULL, 'l' },
{ "raw", no_argument, NULL, 'r' },
+ { "type", required_argument, NULL, 't' },
{ NULL, 0, NULL, 0 }
};
@@ -615,13 +634,13 @@ int main(int argc, char *argv[])
atexit(close_stdout);
lsns_init_debug();
-
memset(&ls, 0, sizeof(ls));
+
INIT_LIST_HEAD(&ls.processes);
INIT_LIST_HEAD(&ls.namespaces);
while ((c = getopt_long(argc, argv,
- "Jlp:o:nruhV", long_opts, NULL)) != -1) {
+ "Jlp:o:nruhVt:", long_opts, NULL)) != -1) {
err_exclusive_options(c, long_opts, excl, excl_st);
@@ -639,7 +658,7 @@ int main(int argc, char *argv[])
printf(UTIL_LINUX_VERSION);
return EXIT_SUCCESS;
case 'p':
- ls.pid = strtos32_or_err(optarg, _("invalid PID argument"));
+ ls.fltr_pid = strtos32_or_err(optarg, _("invalid PID argument"));
break;
case 'h':
usage(stdout);
@@ -652,16 +671,32 @@ int main(int argc, char *argv[])
case 'u':
ls.notrunc = 1;
break;
+ case 't':
+ {
+ int type = ns_name2type(optarg);
+ if (type < 0)
+ errx(EXIT_FAILURE, _("unknown namespace type: %s"), optarg);
+ ls.fltr_types[type] = 1;
+ ls.fltr_ntypes++;
+ break;
+ }
case '?':
default:
usage(stderr);
}
}
+ /* no filter, enable all *
+ if (!ls.fltr_ntypes) {
+ size_t i;
+ for (i = 0; i < ARRAY_SIZE(ns_names); i++)
+ ls.fltr_types[i] = 1;
+ }*/
+
if (optind < argc) {
- if (ls.pid)
+ if (ls.fltr_pid)
errx(EXIT_FAILURE, _("--task is mutually exclusive with <namespace>"));
- ns_ino = strtou64_or_err(argv[optind], _("invalid namespace argument"));
+ ls.fltr_ns = strtou64_or_err(argv[optind], _("invalid namespace argument"));
ls.tree = ls.list ? 0 : 1;
if (!ncolumns) {
@@ -695,11 +730,11 @@ int main(int argc, char *argv[])
if (!r)
r = read_namespaces(&ls);
if (!r) {
- if (ns_ino) {
- struct lsns_namespace *ns = get_namespace(&ls, ns_ino);
+ if (ls.fltr_ns) {
+ struct lsns_namespace *ns = get_namespace(&ls, ls.fltr_ns);
if (!ns)
- err(EXIT_FAILURE, _("not found namespace: %ju"), (uintmax_t) ns_ino);
+ err(EXIT_FAILURE, _("not found namespace: %ju"), (uintmax_t) ls.fltr_ns);
r = show_namespace_processes(&ls, ns);
} else
r = show_namespaces(&ls);