184 lines
5.1 KiB
Diff
184 lines
5.1 KiB
Diff
---
|
|
src/fuser.c | 93 +++++++++++++++++++++++++++++++---------------
|
|
src/fuser.h | 1
|
|
testsuite/config/unix.exp | 19 +++++++++
|
|
3 files changed, 83 insertions(+), 30 deletions(-)
|
|
|
|
--- src/fuser.c
|
|
+++ src/fuser.c 2022-11-25 11:42:29.019144216 +0000
|
|
@@ -1741,8 +1741,9 @@ check_dir(const pid_t pid, const char *d
|
|
continue;
|
|
}
|
|
|
|
- /* check the paths match if it is not a block device */
|
|
- if (! S_ISBLK(dev_tmp->name->st.st_mode)) {
|
|
+ /* check the paths match if it is not a block device or socket */
|
|
+ if (! S_ISBLK(dev_tmp->name->st.st_mode)
|
|
+ & !S_ISSOCK(st.st_mode)) {
|
|
if (readlink(filepath, real_filepath, PATH_MAX-1) < 0) {
|
|
if (strncmp(dev_tmp->name->filename, filepath, strlen(dev_tmp->name->filename)) != 0)
|
|
continue;
|
|
@@ -1750,13 +1751,14 @@ check_dir(const pid_t pid, const char *d
|
|
if (strncmp(dev_tmp->name->filename, real_filepath, strlen(dev_tmp->name->filename)) != 0)
|
|
continue;
|
|
}
|
|
- }
|
|
|
|
- if (fdret != 0)
|
|
+ if (fdret != 0)
|
|
continue;
|
|
- if (fd.mnt_id != dev_tmp->mnt_id)
|
|
+ if (fd.mnt_id != dev_tmp->mnt_id)
|
|
continue;
|
|
|
|
+ }
|
|
+
|
|
if (access == ACCESS_FILE
|
|
&& (fd.flags & (O_WRONLY|O_RDWR))) {
|
|
add_matched_proc(dev_tmp->name,
|
|
@@ -2310,22 +2312,12 @@ get_fdinfo(const pid_t pid, const char *
|
|
char line[BUFSIZ];
|
|
FILE *fp;
|
|
# if defined(HAS_NAME_TO_HANDLE_AT)
|
|
- static ino_t mynamespace;
|
|
- struct stat st;
|
|
-
|
|
- if (!mynamespace) {
|
|
- if (statn("/proc/self/ns/mnt", STATX_INO, &st) != 0) {
|
|
- fprintf(stderr, _("Cannot stat %s: %s\n"),
|
|
- "/proc/self/ns/mnt", strerror(errno));
|
|
- exit(1);
|
|
- }
|
|
- mynamespace = st.st_ino;
|
|
- }
|
|
+ char *realname;
|
|
# endif
|
|
snprintf(pathname, sizeof(pathname)-1, "/proc/%d/fdinfo/%s", pid, fd);
|
|
if ((fp = fopen(pathname, "r")) == NULL)
|
|
goto out; /* forbidden namesspace, try our own namespace */
|
|
- while (fgets(line, BUFSIZ, fp) && ret < 2) {
|
|
+ while (fgets(line, BUFSIZ, fp) && ret < 1) {
|
|
char *xp, *vp, *ep;
|
|
unsigned long ul;
|
|
xp = strtok(&line[0], delimiters);
|
|
@@ -2338,24 +2330,18 @@ get_fdinfo(const pid_t pid, const char *
|
|
info->flags = (mode_t)ul;
|
|
flags++;
|
|
ret++;
|
|
- }
|
|
- if (strcmp(xp, "mnt_id") == 0 && (ul = strtoul(vp, &ep, 0)) != ULONG_MAX && ep && *ep == 0) {
|
|
- info->mnt_id = (int)ul;
|
|
- mnt_id++;
|
|
- ret++;
|
|
+ break;
|
|
}
|
|
}
|
|
fclose(fp);
|
|
out:
|
|
# if defined(HAS_NAME_TO_HANDLE_AT)
|
|
- if (mynamespace != ns) {
|
|
- char *realname;
|
|
- snprintf(pathname, sizeof(pathname)-1, "/proc/%d/fd/%s", pid, fd);
|
|
- realname = expandpath(pathname);
|
|
- if (realname) { /* Use our namespace for mount ID <sigh> */
|
|
- info->mnt_id = get_mountid(realname);
|
|
- mnt_id++;
|
|
- }
|
|
+ snprintf(pathname, sizeof(pathname)-1, "/proc/%d/fd/%s", pid, fd);
|
|
+ realname = expandpath(pathname);
|
|
+ if (realname) { /* Use our namespace for mount ID <sigh> */
|
|
+ info->mnt_id = get_mountid(realname);
|
|
+ mnt_id++;
|
|
+ ret++;
|
|
}
|
|
# endif
|
|
#endif
|
|
@@ -2625,6 +2611,53 @@ char *expandpath(const char *path)
|
|
}
|
|
lnkbuf[n] = '\0'; /* Don't be fooled by readlink(2) */
|
|
|
|
+ /*
|
|
+ * Expand to real path of named socket if any
|
|
+ */
|
|
+ if (lnkbuf[0] != '/' && strncmp("socket:[", lnkbuf, 8) == 0)
|
|
+ {
|
|
+ FILE *fp;
|
|
+ char *inode;
|
|
+ char line[BUFSIZ];
|
|
+ if ((inode = strchr(&lnkbuf[8], ']')))
|
|
+ {
|
|
+ *inode = '\0';
|
|
+ inode = &lnkbuf[8];
|
|
+ }
|
|
+
|
|
+ if (!inode || (fp = fopen(PROC_SOCKETS, "r")) == NULL)
|
|
+ {
|
|
+ /*fprintf(stderr, "Cannot open %s\n", PROC_SOCKETS); */
|
|
+ return (char *)0;
|
|
+ }
|
|
+ while (fgets(line, BUFSIZ, fp) != NULL)
|
|
+ {
|
|
+ char *named = NULL;
|
|
+ unsigned long snode;
|
|
+
|
|
+ if (*line == 'N')
|
|
+ continue;
|
|
+
|
|
+ if (sscanf(line, "%*x: %*x %*x %*x %*x %*x %lu %ms",
|
|
+ &snode, &named) == 2)
|
|
+ {
|
|
+ char *ep;
|
|
+ unsigned long oul = strtoul(inode, &ep, 0);
|
|
+ if (oul == snode) {
|
|
+ ep = named;
|
|
+ if (*ep == '@')
|
|
+ ep++;
|
|
+ n = strlen(ep);
|
|
+ memcpy(lnkbuf, ep, n);
|
|
+ lnkbuf[n] = '\0';
|
|
+ }
|
|
+ free (named);
|
|
+ }
|
|
+ }
|
|
+ fclose(fp);
|
|
+ }
|
|
+
|
|
+
|
|
len = strlen(end);
|
|
if ((n + len) > PATH_MAX) {
|
|
errno = ENAMETOOLONG;
|
|
--- src/fuser.h
|
|
+++ src/fuser.h 2022-11-25 11:26:23.523783208 +0000
|
|
@@ -124,5 +124,6 @@ typedef struct mntinfo_s {
|
|
|
|
#define KNFSD_EXPORTS "/proc/fs/nfs/exports"
|
|
#define PROC_MOUNTINFO "/proc/self/mountinfo"
|
|
+#define PROC_SOCKETS "/proc/self/net/unix"
|
|
#define PROC_MOUNTS "/proc/mounts"
|
|
#define PROC_SWAPS "/proc/swaps"
|
|
--- testsuite/config/unix.exp
|
|
+++ testsuite/config/unix.exp 2022-11-25 10:07:30.595008557 +0000
|
|
@@ -29,3 +29,22 @@ proc expect_nothing { test } {
|
|
eof { pass "$test" }
|
|
}
|
|
}
|
|
+
|
|
+proc kill_process pid {
|
|
+ set cmdline "kill $pid"
|
|
+ if { [catch { exec /bin/sh -c $cmdline } msg]} {
|
|
+ warning "Could not kill process: $msg\n"
|
|
+ }
|
|
+}
|
|
+
|
|
+proc make_socketproc { sktpath } {
|
|
+ global topdir socketproc_pid socketproc_spawnid testsocket_path
|
|
+
|
|
+ set testproc_realpath "nc"
|
|
+ set socketproc_pid [ spawn $testproc_realpath -lU $sktpath ]
|
|
+}
|
|
+
|
|
+proc kill_socketproc { } {
|
|
+ global socketproc_pid
|
|
+ kill_process $socketproc_pid
|
|
+}
|