From e9de8d3bc1a4e198c4dc46999546b5f41ef3e2f5 Mon Sep 17 00:00:00 2001 From: Karel Zak Date: Tue, 30 Nov 2021 15:02:10 +0100 Subject: [PATCH] lsns: fix compilation on old systems without linux/nsfs.h Addresses: https://github.com/util-linux/util-linux/pull/1521 Reported-by: Anatoly Pugachev Signed-off-by: Karel Zak --- sys-utils/lsns.c | 131 ++++++++++++++++++++++++++--------------------- 1 file changed, 73 insertions(+), 58 deletions(-) diff --git a/sys-utils/lsns.c b/sys-utils/lsns.c index ba2a58ef59..1a7e9f3334 100644 --- a/sys-utils/lsns.c +++ b/sys-utils/lsns.c @@ -31,15 +31,16 @@ #include #ifdef HAVE_LINUX_NET_NAMESPACE_H -#include -#include -#include -#include -#include +# include +# include +# include +# include +# include #endif #ifdef HAVE_LINUX_NSFS_H -#include +# include +# define USE_NS_GET_API 1 #endif #include "pathnames.h" @@ -296,7 +297,7 @@ static int get_ns_ino(int dir, const char *nsname, ino_t *ino, ino_t *pino, ino_ *pino = 0; *oino = 0; -#ifdef HAVE_LINUX_NSFS_H +#ifdef USE_NS_GET_API int fd, pfd, ofd; fd = openat(dir, path, 0); if (fd < 0) @@ -684,6 +685,7 @@ static int netnsid_xasputs(char **str, int netnsid) return 0; } +#ifdef USE_NS_GET_API static int clone_type_to_lsns_type(int clone_type) { switch (clone_type) { @@ -799,12 +801,67 @@ static void interpolate_missing_namespaces(struct lsns *ls, struct lsns_namespac close(fd_missing); } -static int read_namespaces(struct lsns *ls) +static void read_related_namespaces(struct lsns *ls) { struct list_head *p; struct lsns_namespace *orphan[2] = {NULL, NULL}; int rela; + list_for_each(p, &ls->namespaces) { + struct lsns_namespace *ns = list_entry(p, struct lsns_namespace, namespaces); + struct list_head *pp; + list_for_each(pp, &ls->namespaces) { + struct lsns_namespace *pns = list_entry(pp, struct lsns_namespace, namespaces); + if (ns->type == LSNS_ID_USER + || ns->type == LSNS_ID_PID) { + if (ns->related_id[RELA_PARENT] == pns->id) + ns->related_ns[RELA_PARENT] = pns; + if (ns->related_id[RELA_OWNER] == pns->id) + ns->related_ns[RELA_OWNER] = pns; + if (ns->related_ns[RELA_PARENT] && ns->related_ns[RELA_OWNER]) + break; + } else { + if (ns->related_id[RELA_OWNER] == pns->id) { + ns->related_ns[RELA_OWNER] = pns; + break; + } + } + } + + /* lsns scans /proc/[0-9]+ for finding namespaces. + * So if a namespace has no process, lsns cannot + * find it. Here we call it a missing namespace. + * + * If the id for a related namesspce is known but + * namespace for the id is not found, there must + * be orphan namespaces. A missing namespace is an + * owner or a parent of the orphan namespace. + */ + for (rela = 0; rela < MAX_RELA; rela++) { + if (ns->related_id[rela] != 0 + && ns->related_ns[rela] == NULL) { + ns->related_ns[rela] = orphan[rela]; + orphan[rela] = ns; + } + } + } + + for (rela = 0; rela < MAX_RELA; rela++) { + while (orphan[rela]) { + struct lsns_namespace *current = orphan[rela]; + orphan[rela] = orphan[rela]->related_ns[rela]; + current->related_ns[rela] = NULL; + interpolate_missing_namespaces(ls, current, rela); + } + } +} + +#endif /* USE_NS_GET_API */ + +static int read_namespaces(struct lsns *ls) +{ + struct list_head *p; + DBG(NS, ul_debug("reading namespace")); list_for_each(p, &ls->processes) { @@ -825,56 +882,10 @@ static int read_namespaces(struct lsns *ls) } } - if (ls->tree == LSNS_TREE_OWNER || ls->tree == LSNS_TREE_PARENT) { - list_for_each(p, &ls->namespaces) { - struct lsns_namespace *ns = list_entry(p, struct lsns_namespace, namespaces); - struct list_head *pp; - list_for_each(pp, &ls->namespaces) { - struct lsns_namespace *pns = list_entry(pp, struct lsns_namespace, namespaces); - if (ns->type == LSNS_ID_USER - || ns->type == LSNS_ID_PID) { - if (ns->related_id[RELA_PARENT] == pns->id) - ns->related_ns[RELA_PARENT] = pns; - if (ns->related_id[RELA_OWNER] == pns->id) - ns->related_ns[RELA_OWNER] = pns; - if (ns->related_ns[RELA_PARENT] && ns->related_ns[RELA_OWNER]) - break; - } else { - if (ns->related_id[RELA_OWNER] == pns->id) { - ns->related_ns[RELA_OWNER] = pns; - break; - } - } - } - - /* lsns scans /proc/[0-9]+ for finding namespaces. - * So if a namespace has no process, lsns cannot - * find it. Here we call it a missing namespace. - * - * If the id for a related namesspce is known but - * namespace for the id is not found, there must - * be orphan namespaces. A missing namespace is an - * owner or a parent of the orphan namespace. - */ - for (rela = 0; rela < MAX_RELA; rela++) { - if (ns->related_id[rela] != 0 - && ns->related_ns[rela] == NULL) { - ns->related_ns[rela] = orphan[rela]; - orphan[rela] = ns; - } - } - } - } - - for (rela = 0; rela < MAX_RELA; rela++) { - while (orphan[rela]) { - struct lsns_namespace *current = orphan[rela]; - orphan[rela] = orphan[rela]->related_ns[rela]; - current->related_ns[rela] = NULL; - interpolate_missing_namespaces(ls, current, rela); - } - } - +#ifdef USE_NS_GET_API + if (ls->tree == LSNS_TREE_OWNER || ls->tree == LSNS_TREE_PARENT) + read_related_namespaces(ls); +#endif list_sort(&ls->namespaces, cmp_namespaces, NULL); return 0; @@ -1377,6 +1388,10 @@ int main(int argc, char *argv[]) ls.tree = LSNS_TREE_PROCESS; } +#ifndef USE_NS_GET_API + if (ls.tree && ls.tree != LSNS_TREE_PROCESS) + errx(EXIT_FAILURE, _("--tree={parent|owner} is unsupported for your system")); +#endif if (outarg && string_add_to_idarray(outarg, columns, ARRAY_SIZE(columns), &ncolumns, column_name_to_id) < 0) return EXIT_FAILURE; -- 2.47.3