]> granicus.if.org Git - psmisc/commitdiff
fuser: Less confused about duplicate dev_id
authorCraig Small <csmall@dropbear.xyz>
Fri, 22 May 2020 06:21:10 +0000 (16:21 +1000)
committerCraig Small <csmall@dropbear.xyz>
Fri, 22 May 2020 06:29:07 +0000 (16:29 +1000)
NFS mounts from the same server have the same device ID. This means
using the -m option a process using one of those mounts will be
"found" in all of the others too.

lsof doesn't have this confusion as it checks the real path against
the mount point and only matches if they start the same.

I think it would be confused with double stacked NFS shares such
as /nfs/SHARE1/blah/SHARE2 with the open file in SHARE2 but
there are limits.

References:
 psmisc/psmisc#10

ChangeLog
src/fuser.c
src/fuser.h

index 4d13742c8651a7b5af104421ebde4abc08017051..1a88488dccb7676fdd0f04f4561dd079fe63e101 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,6 +1,7 @@
 Changes in NEXT
 ===============
        * pstree: Do not crash on missing processes !21
+       * fuser: Get less confused about duplicate dev_id !10
 
 Changes in 23.3
 ===============
index bbcbed22aa2ed9bb772e13fe1b0a7ee60005da94..70da121ddbc65932093ceaa1cd8e7fd370b29354 100644 (file)
 #define MAXSYMLINKS SYMLINK_MAX
 #endif
 
+#ifdef ENABLE_NLS
+#include <locale.h>
+#endif
+
 #include "fuser.h"
 #include "signals.h"
 #include "i18n.h"
 
 //#define DEBUG 1
 
+#ifndef PATH_MAX
+#define PATH_MAX 4096
+#endif /* PATH_MAX */
+
 #define NAME_FIELD 20          /* space reserved for file name */
 /* Function defines */
 static void add_matched_proc(struct names *name_list, const pid_t pid,
@@ -1531,12 +1539,12 @@ print_matches(struct names *names_head, const opt_type opts,
 
 static struct stat *get_pidstat(const pid_t pid, const char *filename)
 {
-       char pathname[256];
+       char pathname[PATH_MAX];
        struct stat *st;
 
        if ((st = (struct stat *)malloc(sizeof(struct stat))) == NULL)
                return NULL;
-       snprintf(pathname, 256, "/proc/%d/%s", pid, filename);
+       snprintf(pathname, PATH_MAX-1, "/proc/%d/%s", pid, filename);
        if (timeout(thestat, pathname, st, 5) != 0) {
                free(st);
                return NULL;
@@ -1558,6 +1566,7 @@ check_dir(const pid_t pid, const char *dirname, struct device_list *dev_head,
        struct stat st, lst;
        char *dirpath;
        char filepath[PATH_MAX];
+       char real_filepath[PATH_MAX];
 
        if (asprintf(&dirpath, "/proc/%d/%s", pid, dirname) < 0)
         return;
@@ -1596,6 +1605,15 @@ check_dir(const pid_t pid, const char *dirname, struct device_list *dev_head,
                             dev_tmp = dev_tmp->next) {
                                if (thedev != dev_tmp->device)
                                        continue;
+
+                               /* check the paths match */
+                               if (readlink(filepath, real_filepath, PATH_MAX-1) < 0) {
+                                   if (strncmp(dev_tmp->name->filename, filepath, strlen(dev_tmp->name->filename)) != 0)
+                                       continue;
+                               } else {
+                                   if (strncmp(dev_tmp->name->filename, real_filepath, strlen(dev_tmp->name->filename)) != 0)
+                                       continue;
+                               }
                                if (access == ACCESS_FILE
                                    && (lstat(filepath, &lst) == 0)
                                    && (lst.st_mode & S_IWUSR)) {
index 93020d54b076329ea553334adc3adcea46706937..4500ec5f957a437d73fc710f7ff98933058cbde0 100644 (file)
@@ -40,7 +40,7 @@ struct procs {
 struct names {
        char *filename;
        unsigned char name_space;
-    struct stat st;
+       struct stat st;
        struct procs *matched_procs;
        struct names *next;
 };