From: Craig Small Date: Fri, 22 May 2020 06:21:10 +0000 (+1000) Subject: fuser: Less confused about duplicate dev_id X-Git-Tag: v23.4rc1~14 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=5c979b38253d187a8ecb8e52a0878b8bb668894f;p=psmisc fuser: Less confused about duplicate dev_id 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 --- diff --git a/ChangeLog b/ChangeLog index 4d13742..1a88488 100644 --- 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 =============== diff --git a/src/fuser.c b/src/fuser.c index bbcbed2..70da121 100644 --- a/src/fuser.c +++ b/src/fuser.c @@ -56,6 +56,10 @@ #define MAXSYMLINKS SYMLINK_MAX #endif +#ifdef ENABLE_NLS +#include +#endif + #include "fuser.h" #include "signals.h" #include "i18n.h" @@ -64,6 +68,10 @@ //#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)) { diff --git a/src/fuser.h b/src/fuser.h index 93020d5..4500ec5 100644 --- a/src/fuser.h +++ b/src/fuser.h @@ -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; };