summaryrefslogtreecommitdiffstats
path: root/sys-utils/lsns.c
diff options
context:
space:
mode:
Diffstat (limited to 'sys-utils/lsns.c')
-rw-r--r--sys-utils/lsns.c108
1 files changed, 104 insertions, 4 deletions
diff --git a/sys-utils/lsns.c b/sys-utils/lsns.c
index bb7d3956d..c4d806e24 100644
--- a/sys-utils/lsns.c
+++ b/sys-utils/lsns.c
@@ -28,6 +28,7 @@
#include <sys/types.h>
#include <wchar.h>
#include <libsmartcols.h>
+#include <libmount.h>
#ifdef HAVE_LINUX_NET_NAMESPACE_H
#include <stdbool.h>
@@ -78,7 +79,8 @@ enum {
COL_COMMAND,
COL_UID,
COL_USER,
- COL_NETNSID
+ COL_NETNSID,
+ COL_NSFS,
};
/* column names */
@@ -100,7 +102,8 @@ static const struct colinfo infos[] = {
[COL_COMMAND] = { "COMMAND", 0, SCOLS_FL_TRUNC, N_("command line of the PID")},
[COL_UID] = { "UID", 0, SCOLS_FL_RIGHT, N_("UID of the PID")},
[COL_USER] = { "USER", 0, 0, N_("username of the PID")},
- [COL_NETNSID] = { "NETNSID", 0, SCOLS_FL_RIGHT, N_("Net namespace ID")}
+ [COL_NETNSID] = { "NETNSID", 0, SCOLS_FL_RIGHT, N_("Net namespace ID")},
+ [COL_NSFS] = { "NSFS", 0, SCOLS_FL_WRAP, N_("Logical name established by nsfs")}
};
static int columns[ARRAY_SIZE(infos) * 2];
@@ -171,6 +174,8 @@ struct lsns {
list : 1,
notrunc : 1,
no_headings: 1;
+
+ struct libmnt_table *tab;
};
struct netnsid_cache {
@@ -612,6 +617,80 @@ static int read_namespaces(struct lsns *ls)
return 0;
}
+static int find_nsfs_in_tab(struct libmnt_fs *fs, void *data)
+{
+ return (mnt_fs_match_fstype(fs, "nsfs") &&
+ (strcmp(mnt_fs_get_root(fs), (char *)data) == 0));
+}
+
+static bool str_includes_path(const char *path_set, const char *elt,
+ const char sep)
+{
+ size_t elt_len;
+ size_t path_set_len;
+ char *tmp;
+
+
+ tmp = strstr(path_set, elt);
+ if (!tmp)
+ return false;
+
+ elt_len = strlen(elt);
+ path_set_len = strlen(path_set);
+
+ /* path_set includes only elt or
+ * path_set includes elt as the first element.
+ */
+ if (tmp == path_set
+ && ((path_set_len == elt_len)
+ || (path_set[elt_len] == sep)))
+ return true;
+ /* path_set includes elt at the middle
+ * or as the last element.
+ */
+ if ((*(tmp - 1) == sep)
+ && ((*(tmp + elt_len) == sep)
+ || (*(tmp + elt_len) == '\0')))
+ return true;
+
+ return false;
+}
+
+static int nsfs_xasputs(char **str,
+ struct lsns_namespace *ns,
+ struct libmnt_table *tab,
+ char sep)
+{
+ struct libmnt_iter *itr = mnt_new_iter(MNT_ITER_FORWARD);
+ char *expected_root;
+ char *tmp;
+
+ xasprintf(&expected_root, "%s:[%lu]", ns_names[ns->type], ns->id);
+
+ tmp = NULL;
+ while (1) {
+ struct libmnt_fs *fs = NULL;
+
+ if (mnt_table_find_next_fs(tab, itr, find_nsfs_in_tab,
+ expected_root, &fs) != 0)
+ break;
+ if (tmp == NULL) {
+ xasprintf(str, "%s", mnt_fs_get_target(fs));
+ tmp = *str;
+ } else if (!str_includes_path(*str, mnt_fs_get_target(fs),
+ sep)) {
+ *str = NULL;
+ xasprintf(str, "%s%c%s",
+ tmp, sep, mnt_fs_get_target(fs));
+ free(tmp);
+ tmp = *str;
+ }
+ }
+ free(expected_root);
+ mnt_free_iter(itr);
+
+ return 1;
+}
static void add_scols_line(struct lsns *ls, struct libscols_table *table,
struct lsns_namespace *ns, struct lsns_process *proc)
{
@@ -665,6 +744,10 @@ static void add_scols_line(struct lsns *ls, struct libscols_table *table,
if (ns->type == LSNS_ID_NET)
netnsid_xasputs(&str, proc->netnsid);
break;
+ case COL_NSFS:
+ nsfs_xasputs(&str, ns, ls->tab,
+ ls->raw ? ',' : '\n');
+ break;
default:
break;
}
@@ -697,16 +780,25 @@ static struct libscols_table *init_scols_table(struct lsns *ls)
for (i = 0; i < ncolumns; i++) {
const struct colinfo *col = get_column_info(i);
int flags = col->flags;
+ struct libscols_column *cl;
if (ls->notrunc)
flags &= ~SCOLS_FL_TRUNC;
if (ls->tree && get_column_id(i) == COL_COMMAND)
flags |= SCOLS_FL_TREE;
- if (!scols_table_new_column(tab, col->name, col->whint, flags)) {
+ cl = scols_table_new_column(tab, col->name, col->whint, flags);
+ if (cl == NULL) {
warnx(_("failed to initialize output column"));
goto err;
}
+ if (get_column_id(i) == COL_NSFS) {
+ scols_column_set_wrapfunc(cl,
+ scols_wrapnl_chunksize,
+ scols_wrapnl_nextchunk,
+ NULL);
+ scols_column_set_safechars(cl, "\n");
+ }
}
return tab;
@@ -928,8 +1020,10 @@ int main(int argc, char *argv[])
columns[ncolumns++] = COL_NPROCS;
columns[ncolumns++] = COL_PID;
columns[ncolumns++] = COL_USER;
- if (enabling_netnsid)
+ if (enabling_netnsid) {
columns[ncolumns++] = COL_NETNSID;
+ columns[ncolumns++] = COL_NSFS;
+ }
columns[ncolumns++] = COL_COMMAND;
}
@@ -956,6 +1050,11 @@ int main(int argc, char *argv[])
if (enabling_netnsid)
netlink_fd = socket(AF_NETLINK, SOCK_RAW, NETLINK_ROUTE);
#endif
+
+ ls.tab = mnt_new_table_from_file(_PATH_PROC_MOUNTINFO);
+ if (!ls.tab)
+ err(MNT_EX_FAIL, _("failed to parse %s"), _PATH_PROC_MOUNTINFO);
+
r = read_processes(&ls);
if (!r)
r = read_namespaces(&ls);
@@ -970,6 +1069,7 @@ int main(int argc, char *argv[])
r = show_namespaces(&ls);
}
+ mnt_free_table(ls.tab);
if (netlink_fd >= 0)
close(netlink_fd);
free_idcache(uid_cache);