#include <libmount.h>
#ifdef HAVE_LINUX_NET_NAMESPACE_H
-#include <stdbool.h>
-#include <sys/socket.h>
-#include <linux/netlink.h>
-#include <linux/rtnetlink.h>
-#include <linux/net_namespace.h>
+# include <stdbool.h>
+# include <sys/socket.h>
+# include <linux/netlink.h>
+# include <linux/rtnetlink.h>
+# include <linux/net_namespace.h>
#endif
#ifdef HAVE_LINUX_NSFS_H
-#include <linux/nsfs.h>
+# include <linux/nsfs.h>
+# define USE_NS_GET_API 1
#endif
#include "pathnames.h"
*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)
return 0;
}
+#ifdef USE_NS_GET_API
static int clone_type_to_lsns_type(int clone_type)
{
switch (clone_type) {
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) {
}
}
- 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;
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;