]> git.ipfire.org Git - thirdparty/util-linux.git/commitdiff
lsfd: (refactor) store a mnt_namespace object to struct process
authorMasatake YAMATO <yamato@redhat.com>
Thu, 4 Jan 2024 22:59:04 +0000 (07:59 +0900)
committerMasatake YAMATO <yamato@redhat.com>
Sat, 24 Feb 2024 17:11:06 +0000 (02:11 +0900)
Signed-off-by: Masatake YAMATO <yamato@redhat.com>
misc-utils/lsfd.c
misc-utils/lsfd.h

index eb1e5ec8098e6d10fb3aeac855f1c22b6fcf1ac3..6481945fe19177ff9af35e3a31cbbcb61fc842c2 100644 (file)
@@ -100,9 +100,12 @@ struct nodev_table {
 static struct nodev_table nodev_table;
 
 struct mnt_namespace {
+       bool read_mountinfo;
        ino_t id;
 };
 
+static struct mnt_namespace *find_mnt_ns(ino_t id);
+static struct mnt_namespace *add_mnt_ns(ino_t id);
 static void *mnt_namespaces;   /* for tsearch/tfind */
 
 struct name_manager {
@@ -847,9 +850,11 @@ static struct file *collect_file_symlink(struct path_cxt *pc,
        if (f->is_error)
                return f;
 
-       if (is_association(f, NS_MNT))
-               proc->ns_mnt = f->stat.st_ino;
-       else if (is_association(f, NS_NET))
+       if (is_association(f, NS_MNT)) {
+               proc->ns_mnt = find_mnt_ns(f->stat.st_ino);
+               if (proc->ns_mnt == NULL)
+                       proc->ns_mnt = add_mnt_ns(f->stat.st_ino);
+       } else if (is_association(f, NS_NET))
                load_sock_xinfo(pc, name, f->stat.st_ino);
 
        else if (assoc >= 0) {
@@ -1067,6 +1072,7 @@ static struct mnt_namespace *new_mnt_ns(ino_t id)
        struct mnt_namespace *mnt_ns = xmalloc(sizeof(*mnt_ns));
 
        mnt_ns->id = id;
+       mnt_ns->read_mountinfo = false;
 
        return mnt_ns;
 }
@@ -1788,22 +1794,27 @@ static void read_process(struct lsfd_control *ctl, struct path_cxt *pc,
         * The information is available in a mountinfo file.
         */
 
-       /* 1/3. read /proc/$pid/ns/mnt */
-       if (proc->ns_mnt == 0)
+       /* 1/3. Read /proc/$pid/ns/mnt */
+       if (proc->ns_mnt == NULL)
                collect_namespace_files_tophalf(pc, proc);
 
-       /* 2/3. read /proc/$pid/mountinfo */
-       if (proc->ns_mnt == 0 || !find_mnt_ns(proc->ns_mnt)) {
+       /* 2/3. read /proc/$pid/mountinfo unless we have read it already.
+        * The backing device for "nsfs" is solved here.
+        */
+       if (proc->ns_mnt == NULL || !proc->ns_mnt->read_mountinfo) {
                FILE *mnt = ul_path_fopen(pc, "r", "mountinfo");
                if (mnt) {
                        read_mountinfo(mnt);
                        if (proc->ns_mnt)
-                               add_mnt_ns(proc->ns_mnt);
+                               proc->ns_mnt->read_mountinfo = true;
                        fclose(mnt);
                }
        }
 
-       /* 3/3. read /proc/$pid/ns/{the other than mnt} */
+       /* 3/3. read /proc/$pid/ns/{the other namespaces including net}
+        * When reading the information about the net namespace,
+        * backing device for "nsfs" must be solved.
+        */
        collect_namespace_files_bottomhalf(pc, proc);
 
        /* If kcmp is not available,
index 6fc83f3480eab13fc3cabd066fb6db527cd2b36e..1a180fe05e577178736f78c8db1160c08cb6b2ae 100644 (file)
@@ -157,7 +157,7 @@ struct proc {
        struct proc * leader;
        char *command;
        uid_t uid;
-       ino_t ns_mnt;
+       struct mnt_namespace *ns_mnt;
        struct list_head procs;
        struct list_head files;
        unsigned int kthread: 1;