From 614e4d92857d7f586c8920e3f113020f2c6d7bd9e99feba3f0feaa52cc022718 Mon Sep 17 00:00:00 2001 From: "Dr. Werner Fink" Date: Mon, 5 Nov 2018 08:39:03 +0000 Subject: [PATCH 1/3] let it build even without statx around OBS-URL: https://build.opensuse.org/package/show/Base:System/psmisc?expand=0&rev=111 --- ...-2-system-call-to-avoid-hangs-on-NFS.patch | 43 ++++++++++--------- 1 file changed, 22 insertions(+), 21 deletions(-) diff --git a/0002-Use-new-statx-2-system-call-to-avoid-hangs-on-NFS.patch b/0002-Use-new-statx-2-system-call-to-avoid-hangs-on-NFS.patch index e77000f..713c1fe 100644 --- a/0002-Use-new-statx-2-system-call-to-avoid-hangs-on-NFS.patch +++ b/0002-Use-new-statx-2-system-call-to-avoid-hangs-on-NFS.patch @@ -1,4 +1,4 @@ -From 7181b4125fc2a1057dffffaa643e6bcb549fd0eb Mon Sep 17 00:00:00 2001 +From f6e5c845e75ffda1381b3a72b068ce806d01d751 Mon Sep 17 00:00:00 2001 From: Werner Fink Date: Fri, 2 Nov 2018 14:27:00 +0100 Subject: [PATCH] Use new statx(2) system call to avoid hangs on NFS @@ -12,7 +12,7 @@ Signed-off-by: Werner Fink src/statx.h | 66 +++++++++++ src/timeout.c | 372 ---------------------------------------------------------- src/timeout.h | 45 ------- - 7 files changed, 247 insertions(+), 511 deletions(-) + 7 files changed, 248 insertions(+), 510 deletions(-) create mode 100644 src/statx.c create mode 100644 src/statx.h delete mode 100644 src/timeout.c @@ -90,7 +90,7 @@ index d8d3366..81d3674 100644 # Enable hardened compile and link flags AC_ARG_ENABLE([harden_flags], diff --git src/fuser.c src/fuser.c -index 2681f74..c717e19 100644 +index 2681f74..92ffa37 100644 --- src/fuser.c +++ src/fuser.c @@ -63,7 +63,7 @@ @@ -132,21 +132,22 @@ index 2681f74..c717e19 100644 break; case 'k': opts |= OPT_KILL; -@@ -1261,10 +1255,9 @@ int main(int argc, char *argv[]) +@@ -1261,10 +1255,11 @@ int main(int argc, char *argv[]) continue; } -#if defined(WITH_MOUNTINFO_LIST) - if ((opts & (OPT_MOUNTS|OPT_ALWAYSSTAT)) == OPT_MOUNTS) - thestat = mntstat; --#endif ++#if defined(HAVE_DECL_SYS_STATX) && HAVE_DECL_SYS_STATX == 1 + if ((opts & OPT_ALWAYSSTAT)) + stat_flags = 0; /* Triggers sync with e.g. remote NFS server even on autofs */ + #endif + /* an option */ /* Not an option, must be a file specification */ if ((this_name = malloc(sizeof(struct names))) == NULL) -@@ -1584,7 +1577,7 @@ static struct stat *get_pidstat(const pid_t pid, const char *filename, int *id) +@@ -1584,7 +1579,7 @@ static struct stat *get_pidstat(const pid_t pid, const char *filename, int *id) if ((st = (struct stat *)malloc(sizeof(struct stat))) == NULL) return NULL; snprintf(pathname, 256, "/proc/%d/%s", pid, filename); @@ -155,7 +156,7 @@ index 2681f74..c717e19 100644 free(st); return NULL; } -@@ -1631,7 +1624,7 @@ check_dir(const pid_t pid, const char *dirname, struct device_list *dev_head, +@@ -1631,7 +1626,7 @@ check_dir(const pid_t pid, const char *dirname, struct device_list *dev_head, snprintf(filepath, sizeof filepath - 1, "/proc/%d/%s/%s", pid, dirname, direntry->d_name); @@ -164,7 +165,7 @@ index 2681f74..c717e19 100644 if (errno != ENOENT && errno != ENOTDIR) { fprintf(stderr, _("Cannot stat file %s: %s\n"), filepath, strerror(errno)); -@@ -1673,7 +1666,7 @@ check_dir(const pid_t pid, const char *dirname, struct device_list *dev_head, +@@ -1673,7 +1668,7 @@ check_dir(const pid_t pid, const char *dirname, struct device_list *dev_head, if (thedev != ino_tmp->device) continue; if (!st.st_ino @@ -173,7 +174,7 @@ index 2681f74..c717e19 100644 fprintf(stderr, _("Cannot stat file %s: %s\n"), filepath, strerror(errno)); -@@ -1761,11 +1754,11 @@ static uid_t getpiduid(const pid_t pid) +@@ -1761,11 +1756,11 @@ static uid_t getpiduid(const pid_t pid) if (asprintf(&pathname, "/proc/%d", pid) < 0) return 0; @@ -189,7 +190,7 @@ index 2681f74..c717e19 100644 return st.st_uid; } -@@ -1803,7 +1796,7 @@ void fill_unix_cache(struct unixsocket_list **unixsocket_head) +@@ -1803,7 +1798,7 @@ void fill_unix_cache(struct unixsocket_list **unixsocket_head) path = scanned_path; if (*scanned_path == '@') scanned_path++; @@ -198,7 +199,7 @@ index 2681f74..c717e19 100644 free(path); continue; } -@@ -1938,7 +1931,7 @@ static dev_t find_net_dev(void) +@@ -1938,7 +1933,7 @@ static dev_t find_net_dev(void) fprintf(stderr, _("Cannot open a network socket.\n")); return -1; } @@ -207,7 +208,7 @@ index 2681f74..c717e19 100644 fprintf(stderr, _("Cannot find socket's device number.\n")); close(skt); return -1; -@@ -1971,7 +1964,7 @@ scan_knfsd(struct names *names_head, struct inode_list *ino_head, +@@ -1971,7 +1966,7 @@ scan_knfsd(struct names *names_head, struct inode_list *ino_head, if ((find_space = strpbrk(line, " \t")) == NULL) continue; *find_space = '\0'; @@ -216,7 +217,7 @@ index 2681f74..c717e19 100644 continue; } /* Scan the devices */ -@@ -2006,7 +1999,7 @@ scan_mounts(struct names *names_head, struct inode_list *ino_head, +@@ -2006,7 +2001,7 @@ scan_mounts(struct names *names_head, struct inode_list *ino_head, mntinfo_t *mnt = list_entry(ptr, mntinfo_t); const char *find_mountp = mnt->mpoint; @@ -225,7 +226,7 @@ index 2681f74..c717e19 100644 continue; /* Scan the devices */ -@@ -2053,7 +2046,7 @@ scan_swaps(struct names *names_head, struct inode_list *ino_head, +@@ -2053,7 +2048,7 @@ scan_swaps(struct names *names_head, struct inode_list *ino_head, if (*find_space == '\0') continue; } @@ -234,7 +235,7 @@ index 2681f74..c717e19 100644 continue; } /* Scan the devices */ -@@ -2209,7 +2202,7 @@ out: +@@ -2209,7 +2204,7 @@ out: struct stat lst; snprintf(pathname, 256, "/proc/%d/fd/%s", pid, fd); @@ -243,7 +244,7 @@ index 2681f74..c717e19 100644 if (lst.st_mode & S_IWUSR) info->flags |= O_WRONLY; ret++; -@@ -2352,49 +2345,6 @@ out: +@@ -2352,49 +2347,6 @@ out: return ret; } @@ -448,7 +449,7 @@ index 0000000..2554da7 +} diff --git src/statx.h src/statx.h new file mode 100644 -index 0000000..548583d +index 0000000..bc9eda7 --- /dev/null +++ src/statx.h @@ -0,0 +1,66 @@ @@ -488,19 +489,19 @@ index 0000000..548583d +extern int lstatn(const char*, unsigned int, struct stat*); +#else +extern inline int -+statn(const char *path, unsigned int mask __atribute__((unused)), struct stat *st) ++statn(const char *path, unsigned int mask __attribute__((unused)), struct stat *st) +{ + return stat(path, st); +} +extern inline int -+fstatn(int fd, unsigned int mask __atribute__((unused)), struct stat *st) ++fstatn(int fd, unsigned int mask __attribute__((unused)), struct stat *st) +{ + return fstat(fd, st); +} +extern inline int -+lstatn(const char *path, unsigned int mask __atribute__((unused)), struct stat *st) ++lstatn(const char *path, unsigned int mask __attribute__((unused)), struct stat *st) +{ -+ lstat(path, st); ++ return lstat(path, st); +} +#define STATX_TYPE 0 +#define STATX_MODE 0 From b313a9b2d60d0a620cc1bfc470e0aa776fed5fabb0d5fee4c82ce03d0e75e1e5 Mon Sep 17 00:00:00 2001 From: "Dr. Werner Fink" Date: Wed, 14 Nov 2018 11:26:45 +0000 Subject: [PATCH 2/3] handle sub volumes of the btrFS OBS-URL: https://build.opensuse.org/package/show/Base:System/psmisc?expand=0&rev=113 --- ...to-be-able-to-use-the-mount-identity.patch | 283 ++++++++++++------ ...-2-system-call-to-avoid-hangs-on-NFS.patch | 34 +-- psmisc.changes | 6 + 3 files changed, 217 insertions(+), 106 deletions(-) diff --git a/0001-Use-mountinfo-to-be-able-to-use-the-mount-identity.patch b/0001-Use-mountinfo-to-be-able-to-use-the-mount-identity.patch index 272e333..4bbecc4 100644 --- a/0001-Use-mountinfo-to-be-able-to-use-the-mount-identity.patch +++ b/0001-Use-mountinfo-to-be-able-to-use-the-mount-identity.patch @@ -1,4 +1,4 @@ -From d220bd127a595287be2893e5808c4d53505e65af Mon Sep 17 00:00:00 2001 +From b746c58eb31e00d1a5545e3d90bea0b768265ad7 Mon Sep 17 00:00:00 2001 From: Werner Fink Date: Mon, 22 Oct 2018 12:02:50 +0200 Subject: [PATCH] Use mountinfo to be able to use the mount identity @@ -11,16 +11,16 @@ and older systems. Add support for name_to_handle_at() system call to get the real mount ID for each file -Support also btrfs with its subvolumes +Support also BtrFS with its various subvolumes Signed-off-by: Werner Fink --- configure.ac | 18 +- - src/fuser.c | 541 +++++++++++++++++++++++++++---------- - src/fuser.h | 19 +- + src/fuser.c | 627 ++++++++++++++++++++++++++++--------- + src/fuser.h | 27 +- testsuite/Makefile.am | 3 +- testsuite/killall.test/killall.exp | 4 + - 5 files changed, 440 insertions(+), 145 deletions(-) + 5 files changed, 526 insertions(+), 153 deletions(-) diff --git configure.ac configure.ac index 176a2fc..d8d3366 100644 @@ -66,7 +66,7 @@ index 176a2fc..d8d3366 100644 dnl Checks for typedefs, structures, and compiler characteristics. AC_C_CONST diff --git src/fuser.c src/fuser.c -index c44cee8..2681f74 100644 +index c44cee8..970b52d 100644 --- src/fuser.c +++ src/fuser.c @@ -32,6 +32,10 @@ @@ -89,12 +89,14 @@ index c44cee8..2681f74 100644 static uid_t getpiduid(const pid_t pid); static int print_matches(struct names *names_head, const opt_type opts, const int sig_number); -@@ -89,8 +93,8 @@ static int kill_matched_proc(struct procs *pptr, const opt_type opts, +@@ -88,9 +92,9 @@ static int kill_matched_proc(struct procs *pptr, const opt_type opts, + /*int parse_mount(struct names *this_name, struct device_list **dev_list);*/ static void add_device(struct device_list **dev_list, - struct names *this_name, dev_t device); +- struct names *this_name, dev_t device); -void fill_unix_cache(struct unixsocket_list **unixsocket_head); -void clear_unix_cache(struct unixsocket_list **unixsocket_head); ++ struct names *this_name, dev_t device, dev_t subvol); +static void fill_unix_cache(struct unixsocket_list **unixsocket_head); +static void clear_unix_cache(struct unixsocket_list **unixsocket_head); static void atexit_clear_unix_cache(); @@ -135,7 +137,7 @@ index c44cee8..2681f74 100644 cwd_dev = cwd_stat ? cwd_stat->st_dev : 0; exe_dev = exe_stat ? exe_stat->st_dev : 0; root_dev = root_stat ? root_stat->st_dev : 0; -@@ -218,21 +226,21 @@ scan_procs(struct names *names_head, struct inode_list *ino_head, +@@ -218,21 +226,33 @@ scan_procs(struct names *names_head, struct inode_list *ino_head, /* Scan the devices */ for (dev_tmp = dev_head; dev_tmp != NULL; dev_tmp = dev_tmp->next) { @@ -148,6 +150,7 @@ index c44cee8..2681f74 100644 - if (cwd_dev == dev_tmp->device) - add_matched_proc(dev_tmp->name, pid, uid, - ACCESS_CWD); ++ struct subvol *vol_tmp; + char access = 0; + if (exe_dev == dev_tmp->device && dev_tmp->mnt_id == exe_id) + access |= ACCESS_EXE; @@ -155,6 +158,17 @@ index c44cee8..2681f74 100644 + access |= ACCESS_ROOT; + if (cwd_dev == dev_tmp->device && dev_tmp->mnt_id == cwd_id) + access |= ACCESS_CWD; ++ for (vol_tmp = dev_tmp->vol; vol_tmp != NULL; ++ vol_tmp = vol_tmp->next) { ++ /* For BtrFS sub volumes there are different ++ mount ids for the same device */ ++ if (exe_dev == vol_tmp->device && vol_tmp->mnt_id == exe_id) ++ access |= ACCESS_EXE; ++ if (root_dev == vol_tmp->device && vol_tmp->mnt_id == root_id) ++ access |= ACCESS_ROOT; ++ if (cwd_dev == vol_tmp->device && vol_tmp->mnt_id == cwd_id) ++ access |= ACCESS_CWD; ++ } + if (access) + add_matched_proc(dev_tmp->name, pid, uid, access); } @@ -167,7 +181,7 @@ index c44cee8..2681f74 100644 if (exe_stat && exe_stat->st_dev == ino_tmp->device && exe_stat->st_ino == ino_tmp->inode) -@@ -241,7 +249,7 @@ scan_procs(struct names *names_head, struct inode_list *ino_head, +@@ -241,7 +261,7 @@ scan_procs(struct names *names_head, struct inode_list *ino_head, } if (root_dev == ino_tmp->device) { if (!root_stat) @@ -176,7 +190,7 @@ index c44cee8..2681f74 100644 if (root_stat && root_stat->st_dev == ino_tmp->device && root_stat->st_ino == ino_tmp->inode) -@@ -250,7 +258,7 @@ scan_procs(struct names *names_head, struct inode_list *ino_head, +@@ -250,7 +270,7 @@ scan_procs(struct names *names_head, struct inode_list *ino_head, } if (cwd_dev == ino_tmp->device) { if (!cwd_stat) @@ -185,7 +199,7 @@ index c44cee8..2681f74 100644 if (cwd_stat && cwd_stat->st_dev == ino_tmp->device && cwd_stat->st_ino == ino_tmp->inode) -@@ -291,6 +299,7 @@ add_inode(struct inode_list **ino_list, struct names *this_name, +@@ -291,18 +311,42 @@ add_inode(struct inode_list **ino_list, struct names *this_name, ino_tmp->name = this_name; ino_tmp->device = device; ino_tmp->inode = inode; @@ -193,15 +207,54 @@ index c44cee8..2681f74 100644 ino_tmp->next = ino_head; *ino_list = ino_tmp; } -@@ -310,6 +319,7 @@ add_device(struct device_list **dev_list, struct names *this_name, dev_t device) ++ ++static void ++add_subvol(struct subvol **head, dev_t device, int mnt_id) ++{ ++ struct subvol *vol_tmp, *vol_head; ++ ++ if ((vol_tmp = ++ (struct subvol *)malloc(sizeof(struct subvol))) == NULL) ++ return; ++ vol_head = *head; ++ vol_tmp->device = device; ++ vol_tmp->mnt_id = mnt_id; ++ vol_tmp->next = vol_head; ++ *head = vol_tmp; ++} + + static void +-add_device(struct device_list **dev_list, struct names *this_name, dev_t device) ++add_device(struct device_list **dev_list, struct names *this_name, dev_t device, dev_t subvol) + { + struct device_list *dev_tmp, *dev_head; + #ifdef DEBUG + fprintf(stderr, "add_device(%s %u\n", this_name->filename, + (unsigned int)device); + #endif /* DEBUG */ ++ /* For BtrFS there are many sub volumes all on the same block device */ ++ for (dev_tmp = *dev_list; dev_tmp != NULL; dev_tmp = dev_tmp->next) ++ if (dev_tmp->device == device) { ++ if (dev_tmp->device != subvol) ++ add_subvol(&dev_tmp->vol, subvol, this_name->mnt_id); ++ *dev_list = dev_tmp; ++ return; ++ } + + if ((dev_tmp = + (struct device_list *)malloc(sizeof(struct device_list))) == NULL) +@@ -310,6 +354,10 @@ add_device(struct device_list **dev_list, struct names *this_name, dev_t device) dev_head = *dev_list; dev_tmp->name = this_name; dev_tmp->device = device; ++ dev_tmp->mnt_id = this_name->mnt_id; ++ if (dev_tmp->device != subvol) ++ add_subvol(&dev_tmp->vol, subvol, this_name->mnt_id); + dev_tmp->mnt_id = this_name->mnt_id; dev_tmp->next = dev_head; *dev_list = dev_tmp; } -@@ -451,13 +461,15 @@ add_special_proc(struct names *name_list, const char ptype, const uid_t uid, +@@ -451,13 +499,15 @@ add_special_proc(struct names *name_list, const char ptype, const uid_t uid, int parse_file(struct names *this_name, struct inode_list **ino_list, const opt_type opts) { @@ -218,7 +271,7 @@ index c44cee8..2681f74 100644 if (errno == ENOENT) fprintf(stderr, _("Specified filename %s does not exist.\n"), -@@ -467,10 +479,12 @@ int parse_file(struct names *this_name, struct inode_list **ino_list, +@@ -467,10 +517,12 @@ int parse_file(struct names *this_name, struct inode_list **ino_list, this_name->filename, strerror(errno)); return -1; } @@ -233,7 +286,7 @@ index c44cee8..2681f74 100644 #endif /* DEBUG */ add_inode(ino_list, this_name, this_name->st.st_dev, this_name->st.st_ino); -@@ -502,11 +516,51 @@ parse_mounts(struct names *this_name, struct device_list **dev_list, +@@ -502,12 +554,54 @@ parse_mounts(struct names *this_name, struct device_list **dev_list, const opt_type opts) { dev_t match_device; @@ -245,18 +298,21 @@ index c44cee8..2681f74 100644 match_device = this_name->st.st_rdev; else match_device = this_name->st.st_dev; +- add_device(dev_list, this_name, match_device); + + count = 0; + list_for_each(ptr, &mntinfo) { + mntinfo_t *mnt = list_entry(ptr, mntinfo_t); -+ if (match_device != mnt->dev) ++ if (match_device != mnt->dev && match_device != mnt->vol) + continue; + if (S_ISBLK(this_name->st.st_mode)) { + /* Skip mount IDs check if a block device + * was specified */ + this_name->mnt_id = mnt->id; -+ add_device(dev_list, this_name, match_device); -+ count++; ++ add_device(dev_list, this_name, match_device, mnt->dev); ++ if (mnt->dev == mnt->vol) ++ count++; ++ else count = 1; + continue; + } + if (this_name->mnt_id != mnt->id) @@ -282,10 +338,11 @@ index c44cee8..2681f74 100644 + if (S_ISBLK(this_name->st.st_mode)) + return 0; + this_name->mnt_id = mountinfo->id; - add_device(dev_list, this_name, match_device); ++ add_device(dev_list, this_name, match_device, match_device); return 0; } -@@ -621,7 +675,7 @@ int parse_inet(struct names *this_name, struct ip_connections **ip_list) + +@@ -621,7 +715,7 @@ int parse_inet(struct names *this_name, struct ip_connections **ip_list) fprintf(stderr, _("Unknown local port AF %d\n"), res->ai_family); freeaddrinfo(res); @@ -294,7 +351,7 @@ index c44cee8..2681f74 100644 return -1; } freeaddrinfo(res); -@@ -684,10 +738,12 @@ int parse_inet(struct names *this_name, struct ip_connections **ip_list) +@@ -684,10 +778,12 @@ int parse_inet(struct names *this_name, struct ip_connections **ip_list) break; #endif } @@ -310,7 +367,7 @@ index c44cee8..2681f74 100644 } return 1; } -@@ -1162,16 +1218,11 @@ int main(int argc, char *argv[]) +@@ -1162,16 +1258,11 @@ int main(int argc, char *argv[]) skip_argv = 1; //while(option != '\0') option++; if (strcmp(argv[argc_cnt], "tcp") == 0) @@ -332,7 +389,7 @@ index c44cee8..2681f74 100644 else usage(_ ("Invalid namespace name")); -@@ -1211,7 +1262,7 @@ int main(int argc, char *argv[]) +@@ -1211,7 +1302,7 @@ int main(int argc, char *argv[]) } #if defined(WITH_MOUNTINFO_LIST) @@ -341,7 +398,7 @@ index c44cee8..2681f74 100644 thestat = mntstat; #endif /* an option */ -@@ -1525,7 +1576,7 @@ print_matches(struct names *names_head, const opt_type opts, +@@ -1525,7 +1616,7 @@ print_matches(struct names *names_head, const opt_type opts, } @@ -350,7 +407,7 @@ index c44cee8..2681f74 100644 { char pathname[256]; struct stat *st; -@@ -1537,6 +1588,15 @@ static struct stat *get_pidstat(const pid_t pid, const char *filename) +@@ -1537,6 +1628,15 @@ static struct stat *get_pidstat(const pid_t pid, const char *filename) free(st); return NULL; } @@ -366,7 +423,7 @@ index c44cee8..2681f74 100644 return st; } -@@ -1551,7 +1611,8 @@ check_dir(const pid_t pid, const char *dirname, struct device_list *dev_head, +@@ -1551,7 +1651,8 @@ check_dir(const pid_t pid, const char *dirname, struct device_list *dev_head, struct inode_list *ino_tmp; struct device_list *dev_tmp; struct unixsocket_list *sock_tmp; @@ -376,14 +433,30 @@ index c44cee8..2681f74 100644 char *dirpath; char filepath[PATH_MAX]; -@@ -1592,9 +1653,12 @@ check_dir(const pid_t pid, const char *dirname, struct device_list *dev_head, +@@ -1590,11 +1691,27 @@ check_dir(const pid_t pid, const char *dirname, struct device_list *dev_head, + } + for (dev_tmp = dev_head; dev_tmp != NULL; dev_tmp = dev_tmp->next) { - if (thedev != dev_tmp->device) - continue; +- if (thedev != dev_tmp->device) ++ if (thedev != dev_tmp->device) { ++ struct subvol *vol_tmp; ++ int found = 0; ++ for (vol_tmp = dev_tmp->vol; vol_tmp != NULL; ++ vol_tmp = vol_tmp->next) { ++ /* Check for BtrFS sub volumes as well */ ++ if (thedev == vol_tmp->device) { ++ found++; ++ break; ++ } ++ } ++ ++ if (!found) ++ continue; ++ } + if (get_fdinfo(pid, direntry->d_name, &fd) != 0) + continue; + if (fd.mnt_id != dev_tmp->mnt_id) -+ continue; + continue; if (access == ACCESS_FILE - && (lstat(filepath, &lst) == 0) - && (lst.st_mode & S_IWUSR)) { @@ -391,7 +464,7 @@ index c44cee8..2681f74 100644 add_matched_proc(dev_tmp->name, pid, uid, ACCESS_FILEWR | -@@ -1616,9 +1680,10 @@ check_dir(const pid_t pid, const char *dirname, struct device_list *dev_head, +@@ -1616,9 +1733,10 @@ check_dir(const pid_t pid, const char *dirname, struct device_list *dev_head, continue; } if (st.st_ino == ino_tmp->inode) { @@ -404,7 +477,7 @@ index c44cee8..2681f74 100644 add_matched_proc(ino_tmp->name, pid, uid, ACCESS_FILEWR | -@@ -1647,7 +1712,6 @@ check_map(const pid_t pid, const char *filename, +@@ -1647,31 +1765,54 @@ check_map(const pid_t pid, const char *filename, FILE *fp; unsigned long long tmp_inode; unsigned int tmp_maj, tmp_min; @@ -412,9 +485,14 @@ index c44cee8..2681f74 100644 if (asprintf(&pathname, "/proc/%d/%s", pid, filename) < 0) return; -@@ -1657,12 +1721,25 @@ check_map(const pid_t pid, const char *filename, - } - free(pathname); + if ((fp = fopen(pathname, "r")) == NULL) { +- free(pathname); ++ free(pathname); + return; +- } +- free(pathname); ++ } ++ free(pathname); while (fgets(line, BUFSIZ, fp)) { - if (sscanf(line, "%*s %*s %*s %x:%x %lld", - &tmp_maj, &tmp_min, &tmp_inode) == 3) { @@ -435,14 +513,26 @@ index c44cee8..2681f74 100644 + } + for (dev_tmp = dev_head; dev_tmp != NULL; - dev_tmp = dev_tmp->next) +- dev_tmp = dev_tmp->next) - if (dev_tmp->device == tmp_device) ++ dev_tmp = dev_tmp->next) { ++ struct subvol *vol_tmp; + if (dev_tmp->device == tmp_device && + mnt_id == dev_tmp->mnt_id) add_matched_proc(dev_tmp->name, pid, uid, access); ++ for (vol_tmp = dev_tmp->vol; vol_tmp != NULL; ++ vol_tmp = vol_tmp->next) { ++ /* For BtrFS sub volumes there are different ++ mount ids for the same device */ ++ if (vol_tmp->device == tmp_device && mnt_id == vol_tmp->mnt_id) ++ add_matched_proc(dev_tmp->name, pid, ++ uid, access); ++ } ++ } for (ino_tmp = ino_head; ino_tmp != NULL; -@@ -1671,7 +1748,8 @@ check_map(const pid_t pid, const char *filename, + ino_tmp = ino_tmp->next) + if (ino_tmp->device == tmp_device && ino_tmp->inode == tmp_inode) add_matched_proc(ino_tmp->name, pid, uid, access); @@ -452,7 +542,7 @@ index c44cee8..2681f74 100644 } fclose(fp); } -@@ -1695,6 +1773,7 @@ static uid_t getpiduid(const pid_t pid) +@@ -1695,6 +1836,7 @@ static uid_t getpiduid(const pid_t pid) * fill_unix_cache : Create a list of Unix sockets * This list is used later for matching purposes */ @@ -460,7 +550,7 @@ index c44cee8..2681f74 100644 void fill_unix_cache(struct unixsocket_list **unixsocket_head) { FILE *fp; -@@ -1711,6 +1790,8 @@ void fill_unix_cache(struct unixsocket_list **unixsocket_head) +@@ -1711,6 +1853,8 @@ void fill_unix_cache(struct unixsocket_list **unixsocket_head) while (fgets(line, BUFSIZ, fp) != NULL) { char *path; char *scanned_path = NULL; @@ -469,7 +559,7 @@ index c44cee8..2681f74 100644 if (sscanf(line, "%*x: %*x %*x %*x %*x %*d %d %ms", &scanned_inode, &scanned_path) != 2) { if (scanned_path) -@@ -1726,6 +1807,8 @@ void fill_unix_cache(struct unixsocket_list **unixsocket_head) +@@ -1726,6 +1870,8 @@ void fill_unix_cache(struct unixsocket_list **unixsocket_head) free(path); continue; } @@ -478,7 +568,7 @@ index c44cee8..2681f74 100644 if ((newsocket = (struct unixsocket_list *) malloc(sizeof(struct unixsocket_list))) == NULL) { free(path); -@@ -1734,6 +1817,7 @@ void fill_unix_cache(struct unixsocket_list **unixsocket_head) +@@ -1734,6 +1880,7 @@ void fill_unix_cache(struct unixsocket_list **unixsocket_head) newsocket->sun_name = strdup(scanned_path); newsocket->inode = st.st_ino; newsocket->dev = st.st_dev; @@ -486,7 +576,7 @@ index c44cee8..2681f74 100644 newsocket->net_inode = scanned_inode; newsocket->next = *unixsocket_head; *unixsocket_head = newsocket; -@@ -1746,6 +1830,7 @@ void fill_unix_cache(struct unixsocket_list **unixsocket_head) +@@ -1746,6 +1893,7 @@ void fill_unix_cache(struct unixsocket_list **unixsocket_head) /* * Free up the list of Unix sockets */ @@ -494,7 +584,7 @@ index c44cee8..2681f74 100644 void clear_unix_cache(struct unixsocket_list **unixsocket_head) { while(*unixsocket_head != NULL) { -@@ -1913,30 +1998,22 @@ scan_mounts(struct names *names_head, struct inode_list *ino_head, +@@ -1913,30 +2061,22 @@ scan_mounts(struct names *names_head, struct inode_list *ino_head, { struct device_list *dev_tmp; struct inode_list *ino_tmp; @@ -535,7 +625,7 @@ index c44cee8..2681f74 100644 add_special_proc(dev_tmp->name, PTYPE_MOUNT, 0, find_mountp); } -@@ -1948,7 +2025,6 @@ scan_mounts(struct names *names_head, struct inode_list *ino_head, +@@ -1948,7 +2088,6 @@ scan_mounts(struct names *names_head, struct inode_list *ino_head, find_mountp); } } @@ -543,7 +633,7 @@ index c44cee8..2681f74 100644 } static void -@@ -1998,16 +2074,49 @@ scan_swaps(struct names *names_head, struct inode_list *ino_head, +@@ -1998,16 +2137,44 @@ scan_swaps(struct names *names_head, struct inode_list *ino_head, fclose(fp); } @@ -580,14 +670,9 @@ index c44cee8..2681f74 100644 + if (strncmp("nfs", type, 3) == 0 || strncmp("afs", type, 3) == 0 || strncmp("autofs", type, 6)) + mnt->isremote = 1; + else mnt->isremote = 0; -+ if (!mnt->isremote) { -+ /* E.g. sub volumes of BtrFS do not show correct device -+ * numbers in /proc/self/mountinfo */ -+ struct stat st; -+ if (stat(mpoint, &st) >= 0) -+ mnt->dev = st.st_dev; -+ } -+ ++ /* E.g. sub volumes of BtrFS do not show main device number in ++ /proc/self/mountinfo, for now just map the device to this */ ++ mnt->vol = dev; + return mnt; +} @@ -597,7 +682,7 @@ index c44cee8..2681f74 100644 { list_t *ptr, *tmp; -@@ -2018,72 +2127,232 @@ static void clear_mntinfo(void) +@@ -2018,72 +2185,244 @@ static void clear_mntinfo(void) } } @@ -608,7 +693,9 @@ index c44cee8..2681f74 100644 + char type[256]; char mpoint[PATH_MAX *4 + 1]; // octal escaping takes 4 chars per 1 char - int mid, parid, max = 0; ++ char devname[PATH_MAX]; + int mid, parid; ++ mntinfo_t *mntinf; +#if defined(HAS_MOUNTINFO) uint maj, min; - list_t sort; @@ -634,23 +721,13 @@ index c44cee8..2681f74 100644 - ("Cannot allocate memory for matched proc: %s\n"), - strerror(errno)); - exit(1); -+ (mnt, "%i %i %u:%u %*s %s %*[^-] - %s %*[^\n]", -+ &mid, &parid, &maj, &min, &mpoint[0], &type[0]) == 6) -+ (void)add_mntinfo(mpoint, type, mid, parid, makedev(maj, min)); -+#else -+ if ((mnt = fopen(PROC_MOUNTS, "r")) == (FILE *) 0) -+ return; -+ mid = 1; -+ parid = -1; -+ while (fscanf (mnt, "%*s %s %s %*[^\n]", &mpoint[0], &type[0]) == 2) { ++ (mnt, "%i %i %u:%u %*s %s %*[^-] - %s %s %*[^\n]", ++ &mid, &parid, &maj, &min, &mpoint[0], &type[0], &devname[0]) == 7) { + struct stat st; -+ if (stat(mpoint, &st) != 0) { -+ if (errno != EACCES) { -+ fprintf(stderr, _("Cannot stat %s: %s\n"), -+ mnt->mpoint, strerror(errno)); -+ exit(1); -+ } -+ st.st_dev = (dev_t)-1; ++ mntinf = add_mntinfo(mpoint, type, mid, parid, makedev(maj, min)); ++ if (mntinf && strncmp(devname, "/dev/", 5) == 0 && stat(devname, &st) == 0) { ++ if (st.st_rdev != 0 && mntinf->dev != st.st_rdev) ++ mntinf->vol = st.st_rdev; } - append(mnt, mntinfo); - mnt->mpoint = ((char *)mnt) + alignof(mntinfo_t); @@ -661,17 +738,32 @@ index c44cee8..2681f74 100644 - mnt->id = mid; - if (mid > max) - max = mid; -+ (void)add_mntinfo(mpoint, type, mid++, parid, st.st_dev); } ++#else ++ if ((mnt = fopen(PROC_MOUNTS, "r")) == (FILE *) 0) ++ return; ++ mid = 1; ++ parid = -1; ++ while (fscanf (mnt, "%s %s %s %*[^\n]", &devname[0], &mpoint[0], &type[0]) == 3) { ++ struct stat st; ++ if (stat(mpoint, &st) != 0) { ++ if (errno != EACCES) { ++ fprintf(stderr, _("Cannot stat %s: %s\n"), ++ mnt->mpoint, strerror(errno)); ++ exit(1); ++ } ++ st.st_dev = (dev_t)-1; ++ } ++ mntinf = add_mntinfo(mpoint, type, mid++, parid, st.st_dev); ++ if (mntinf && strncmp(devname, "/dev/", 5) == 0 && stat(devname, &st) == 0) { ++ if (st.st_rdev != 0 && mntinf->dev != st.st_rdev) ++ mntinf->vol = st.st_rdev; ++ } ++ } +#endif fclose(mnt); +} - -- /* Sort mount points accordingly to the reverse mount order */ -- initial(&sort); -- for (mid = 1; mid <= max; mid++) { -- list_t *ptr, *tmp; -- list_for_each_safe(ptr, tmp, &mntinfo) { ++ +static int +get_fdinfo(const pid_t pid, const char *fd, struct fdinfo *info) +{ @@ -761,7 +853,12 @@ index c44cee8..2681f74 100644 + int ret = -1; + + *mountinfo = NULL; -+ + +- /* Sort mount points accordingly to the reverse mount order */ +- initial(&sort); +- for (mid = 1; mid <= max; mid++) { +- list_t *ptr, *tmp; +- list_for_each_safe(ptr, tmp, &mntinfo) { +#if defined(HAS_NAME_TO_HANDLE_AT) + if (mnt_id >= 0) { + list_t *ptr; @@ -843,12 +940,12 @@ index c44cee8..2681f74 100644 - if (mid != mnt->parid) + + if (nlen != mnt->nlen) -+ continue; -+ -+ if (strcmp(use, mnt->mpoint)) continue; - move_head(ptr, &sort); + ++ if (strcmp(use, mnt->mpoint)) ++ continue; ++ + ret = 0; + errno = 0; + *mountinfo = mnt; @@ -874,7 +971,7 @@ index c44cee8..2681f74 100644 /* * Determine device of links below /proc/ */ -@@ -2091,8 +2360,7 @@ static int mntstat(const char *path, struct stat *buf) +@@ -2091,8 +2430,7 @@ static int mntstat(const char *path, struct stat *buf) { char name[PATH_MAX + 1]; const char *use; @@ -884,7 +981,7 @@ index c44cee8..2681f74 100644 if ((use = realpath(path, name)) == NULL || *use != '/') { -@@ -2104,27 +2372,26 @@ static int mntstat(const char *path, struct stat *buf) +@@ -2104,27 +2442,26 @@ static int mntstat(const char *path, struct stat *buf) errno = 0; return stat(path, buf); } @@ -931,7 +1028,7 @@ index c44cee8..2681f74 100644 #endif /* WITH_MOUNTINFO_LIST */ diff --git src/fuser.h src/fuser.h -index 93020d5..51c6770 100644 +index 93020d5..ca20081 100644 --- src/fuser.h +++ src/fuser.h @@ -37,10 +37,16 @@ struct procs { @@ -952,7 +1049,7 @@ index 93020d5..51c6770 100644 struct procs *matched_procs; struct names *next; }; -@@ -65,12 +71,14 @@ struct inode_list { +@@ -65,12 +71,21 @@ struct inode_list { struct names *name; dev_t device; ino_t inode; @@ -960,14 +1057,21 @@ index 93020d5..51c6770 100644 struct inode_list *next; }; ++struct subvol { ++ dev_t device; ++ int mnt_id; ++ struct subvol *next; ++}; ++ struct device_list { struct names *name; ++ struct subvol *vol; dev_t device; + int mnt_id; struct device_list *next; }; -@@ -79,6 +87,7 @@ struct unixsocket_list { +@@ -79,6 +94,7 @@ struct unixsocket_list { ino_t inode; ino_t net_inode; dev_t dev; @@ -975,7 +1079,7 @@ index 93020d5..51c6770 100644 struct unixsocket_list *next; }; -@@ -87,18 +96,15 @@ struct mount_list { +@@ -87,18 +103,16 @@ struct mount_list { struct mount_list *next; }; @@ -988,6 +1092,7 @@ index 93020d5..51c6770 100644 + char isremote; dev_t dev; size_t nlen; ++ dev_t vol; char *mpoint; } mntinfo_t; -#else @@ -996,7 +1101,7 @@ index 93020d5..51c6770 100644 #define NAMESPACE_FILE 0 #define NAMESPACE_TCP 1 -@@ -109,5 +115,6 @@ typedef struct mntinfo_s { +@@ -109,5 +123,6 @@ typedef struct mntinfo_s { #endif /* PATH_MAX */ #define KNFSD_EXPORTS "/proc/fs/nfs/exports" diff --git a/0002-Use-new-statx-2-system-call-to-avoid-hangs-on-NFS.patch b/0002-Use-new-statx-2-system-call-to-avoid-hangs-on-NFS.patch index 713c1fe..e71f2ae 100644 --- a/0002-Use-new-statx-2-system-call-to-avoid-hangs-on-NFS.patch +++ b/0002-Use-new-statx-2-system-call-to-avoid-hangs-on-NFS.patch @@ -1,6 +1,6 @@ -From f6e5c845e75ffda1381b3a72b068ce806d01d751 Mon Sep 17 00:00:00 2001 +From 9c6fbdcb126ed8d0567ac3b88dac1bf34d4036fb Mon Sep 17 00:00:00 2001 From: Werner Fink -Date: Fri, 2 Nov 2018 14:27:00 +0100 +Date: Wed, 14 Nov 2018 08:49:45 +0100 Subject: [PATCH] Use new statx(2) system call to avoid hangs on NFS Signed-off-by: Werner Fink @@ -90,7 +90,7 @@ index d8d3366..81d3674 100644 # Enable hardened compile and link flags AC_ARG_ENABLE([harden_flags], diff --git src/fuser.c src/fuser.c -index 2681f74..92ffa37 100644 +index 970b52d..e2d14bf 100644 --- src/fuser.c +++ src/fuser.c @@ -63,7 +63,7 @@ @@ -113,7 +113,7 @@ index 2681f74..92ffa37 100644 static char *expandpath(const char *path); static struct unixsocket_list *unixsockets = NULL; static struct names *names_head = NULL, *names_tail = NULL; -@@ -468,7 +464,7 @@ int parse_file(struct names *this_name, struct inode_list **ino_list, +@@ -506,7 +502,7 @@ int parse_file(struct names *this_name, struct inode_list **ino_list, free(this_name->filename); this_name->filename = strdup(new); } @@ -122,7 +122,7 @@ index 2681f74..92ffa37 100644 find_mountpoint(this_name->filename, &mountinfo) != 0) { if (errno == ENOENT) fprintf(stderr, -@@ -1193,9 +1189,7 @@ int main(int argc, char *argv[]) +@@ -1233,9 +1229,7 @@ int main(int argc, char *argv[]) opts |= OPT_INTERACTIVE; break; case 'I': @@ -132,7 +132,7 @@ index 2681f74..92ffa37 100644 break; case 'k': opts |= OPT_KILL; -@@ -1261,10 +1255,11 @@ int main(int argc, char *argv[]) +@@ -1301,10 +1295,11 @@ int main(int argc, char *argv[]) continue; } @@ -147,7 +147,7 @@ index 2681f74..92ffa37 100644 /* an option */ /* Not an option, must be a file specification */ if ((this_name = malloc(sizeof(struct names))) == NULL) -@@ -1584,7 +1579,7 @@ static struct stat *get_pidstat(const pid_t pid, const char *filename, int *id) +@@ -1624,7 +1619,7 @@ static struct stat *get_pidstat(const pid_t pid, const char *filename, int *id) if ((st = (struct stat *)malloc(sizeof(struct stat))) == NULL) return NULL; snprintf(pathname, 256, "/proc/%d/%s", pid, filename); @@ -156,7 +156,7 @@ index 2681f74..92ffa37 100644 free(st); return NULL; } -@@ -1631,7 +1626,7 @@ check_dir(const pid_t pid, const char *dirname, struct device_list *dev_head, +@@ -1671,7 +1666,7 @@ check_dir(const pid_t pid, const char *dirname, struct device_list *dev_head, snprintf(filepath, sizeof filepath - 1, "/proc/%d/%s/%s", pid, dirname, direntry->d_name); @@ -165,7 +165,7 @@ index 2681f74..92ffa37 100644 if (errno != ENOENT && errno != ENOTDIR) { fprintf(stderr, _("Cannot stat file %s: %s\n"), filepath, strerror(errno)); -@@ -1673,7 +1668,7 @@ check_dir(const pid_t pid, const char *dirname, struct device_list *dev_head, +@@ -1726,7 +1721,7 @@ check_dir(const pid_t pid, const char *dirname, struct device_list *dev_head, if (thedev != ino_tmp->device) continue; if (!st.st_ino @@ -174,7 +174,7 @@ index 2681f74..92ffa37 100644 fprintf(stderr, _("Cannot stat file %s: %s\n"), filepath, strerror(errno)); -@@ -1761,11 +1756,11 @@ static uid_t getpiduid(const pid_t pid) +@@ -1824,11 +1819,11 @@ static uid_t getpiduid(const pid_t pid) if (asprintf(&pathname, "/proc/%d", pid) < 0) return 0; @@ -190,7 +190,7 @@ index 2681f74..92ffa37 100644 return st.st_uid; } -@@ -1803,7 +1798,7 @@ void fill_unix_cache(struct unixsocket_list **unixsocket_head) +@@ -1866,7 +1861,7 @@ void fill_unix_cache(struct unixsocket_list **unixsocket_head) path = scanned_path; if (*scanned_path == '@') scanned_path++; @@ -199,7 +199,7 @@ index 2681f74..92ffa37 100644 free(path); continue; } -@@ -1938,7 +1933,7 @@ static dev_t find_net_dev(void) +@@ -2001,7 +1996,7 @@ static dev_t find_net_dev(void) fprintf(stderr, _("Cannot open a network socket.\n")); return -1; } @@ -208,7 +208,7 @@ index 2681f74..92ffa37 100644 fprintf(stderr, _("Cannot find socket's device number.\n")); close(skt); return -1; -@@ -1971,7 +1966,7 @@ scan_knfsd(struct names *names_head, struct inode_list *ino_head, +@@ -2034,7 +2029,7 @@ scan_knfsd(struct names *names_head, struct inode_list *ino_head, if ((find_space = strpbrk(line, " \t")) == NULL) continue; *find_space = '\0'; @@ -217,7 +217,7 @@ index 2681f74..92ffa37 100644 continue; } /* Scan the devices */ -@@ -2006,7 +2001,7 @@ scan_mounts(struct names *names_head, struct inode_list *ino_head, +@@ -2069,7 +2064,7 @@ scan_mounts(struct names *names_head, struct inode_list *ino_head, mntinfo_t *mnt = list_entry(ptr, mntinfo_t); const char *find_mountp = mnt->mpoint; @@ -226,7 +226,7 @@ index 2681f74..92ffa37 100644 continue; /* Scan the devices */ -@@ -2053,7 +2048,7 @@ scan_swaps(struct names *names_head, struct inode_list *ino_head, +@@ -2116,7 +2111,7 @@ scan_swaps(struct names *names_head, struct inode_list *ino_head, if (*find_space == '\0') continue; } @@ -235,7 +235,7 @@ index 2681f74..92ffa37 100644 continue; } /* Scan the devices */ -@@ -2209,7 +2204,7 @@ out: +@@ -2279,7 +2274,7 @@ out: struct stat lst; snprintf(pathname, 256, "/proc/%d/fd/%s", pid, fd); @@ -244,7 +244,7 @@ index 2681f74..92ffa37 100644 if (lst.st_mode & S_IWUSR) info->flags |= O_WRONLY; ret++; -@@ -2352,49 +2347,6 @@ out: +@@ -2422,49 +2417,6 @@ out: return ret; } diff --git a/psmisc.changes b/psmisc.changes index 962bb6a..b07f5af 100644 --- a/psmisc.changes +++ b/psmisc.changes @@ -1,3 +1,9 @@ +------------------------------------------------------------------- +Wed Nov 14 07:44:55 UTC 2018 - Dr. Werner Fink + +- Modify patch 0001-Use-mountinfo-to-be-able-to-use-the-mount-identity.patch + to handle sub volumes of the btrFS (bsc#1112780) + ------------------------------------------------------------------- Mon Nov 5 07:48:25 UTC 2018 - Dr. Werner Fink From 333ab58c9f675a911ac714f3ab10334c54fc284f618538d5ce6b4a45381d5914 Mon Sep 17 00:00:00 2001 From: "Dr. Werner Fink" Date: Thu, 15 Nov 2018 06:48:52 +0000 Subject: [PATCH 3/3] handle sub volumes of the btrFS OBS-URL: https://build.opensuse.org/package/show/Base:System/psmisc?expand=0&rev=114 --- ...to-be-able-to-use-the-mount-identity.patch | 99 ++++++++++++------- ...-2-system-call-to-avoid-hangs-on-NFS.patch | 32 +++--- 2 files changed, 81 insertions(+), 50 deletions(-) diff --git a/0001-Use-mountinfo-to-be-able-to-use-the-mount-identity.patch b/0001-Use-mountinfo-to-be-able-to-use-the-mount-identity.patch index 4bbecc4..906f727 100644 --- a/0001-Use-mountinfo-to-be-able-to-use-the-mount-identity.patch +++ b/0001-Use-mountinfo-to-be-able-to-use-the-mount-identity.patch @@ -1,4 +1,4 @@ -From b746c58eb31e00d1a5545e3d90bea0b768265ad7 Mon Sep 17 00:00:00 2001 +From 2588a03273329961e5eefe6fed695b8f80a352e3 Mon Sep 17 00:00:00 2001 From: Werner Fink Date: Mon, 22 Oct 2018 12:02:50 +0200 Subject: [PATCH] Use mountinfo to be able to use the mount identity @@ -16,11 +16,11 @@ Support also BtrFS with its various subvolumes Signed-off-by: Werner Fink --- configure.ac | 18 +- - src/fuser.c | 627 ++++++++++++++++++++++++++++--------- + src/fuser.c | 644 ++++++++++++++++++++++++++++--------- src/fuser.h | 27 +- testsuite/Makefile.am | 3 +- testsuite/killall.test/killall.exp | 4 + - 5 files changed, 526 insertions(+), 153 deletions(-) + 5 files changed, 543 insertions(+), 153 deletions(-) diff --git configure.ac configure.ac index 176a2fc..d8d3366 100644 @@ -66,7 +66,7 @@ index 176a2fc..d8d3366 100644 dnl Checks for typedefs, structures, and compiler characteristics. AC_C_CONST diff --git src/fuser.c src/fuser.c -index c44cee8..970b52d 100644 +index c44cee8..7ee9b49 100644 --- src/fuser.c +++ src/fuser.c @@ -32,6 +32,10 @@ @@ -250,7 +250,7 @@ index c44cee8..970b52d 100644 + dev_tmp->mnt_id = this_name->mnt_id; + if (dev_tmp->device != subvol) + add_subvol(&dev_tmp->vol, subvol, this_name->mnt_id); -+ dev_tmp->mnt_id = this_name->mnt_id; ++ else dev_tmp->vol = NULL; dev_tmp->next = dev_head; *dev_list = dev_tmp; } @@ -367,7 +367,38 @@ index c44cee8..970b52d 100644 } return 1; } -@@ -1162,16 +1258,11 @@ int main(int argc, char *argv[]) +@@ -953,6 +1049,21 @@ free_inodes(struct inode_list **match_inodes) + /* + * Free up structures allocated in add_device + */ ++ ++static void ++free_subvol(struct subvol **volumes) ++{ ++ struct subvol *vol_tmp, *vol_next; ++ ++ vol_tmp = *volumes; ++ while (vol_tmp != NULL) { ++ vol_next = vol_tmp->next; ++ free(vol_tmp); ++ vol_tmp = vol_next; ++ } ++ *volumes =NULL; ++} ++ + static void + free_devices(struct device_list **match_devices) + { +@@ -960,6 +1071,8 @@ free_devices(struct device_list **match_devices) + + device_tmp = *match_devices; + while(device_tmp != NULL) { ++ if (device_tmp->vol) ++ free_subvol(&device_tmp->vol); + device_next = device_tmp->next; + free(device_tmp); + device_tmp = device_next; +@@ -1162,16 +1275,11 @@ int main(int argc, char *argv[]) skip_argv = 1; //while(option != '\0') option++; if (strcmp(argv[argc_cnt], "tcp") == 0) @@ -389,7 +420,7 @@ index c44cee8..970b52d 100644 else usage(_ ("Invalid namespace name")); -@@ -1211,7 +1302,7 @@ int main(int argc, char *argv[]) +@@ -1211,7 +1319,7 @@ int main(int argc, char *argv[]) } #if defined(WITH_MOUNTINFO_LIST) @@ -398,7 +429,7 @@ index c44cee8..970b52d 100644 thestat = mntstat; #endif /* an option */ -@@ -1525,7 +1616,7 @@ print_matches(struct names *names_head, const opt_type opts, +@@ -1525,7 +1633,7 @@ print_matches(struct names *names_head, const opt_type opts, } @@ -407,7 +438,7 @@ index c44cee8..970b52d 100644 { char pathname[256]; struct stat *st; -@@ -1537,6 +1628,15 @@ static struct stat *get_pidstat(const pid_t pid, const char *filename) +@@ -1537,6 +1645,15 @@ static struct stat *get_pidstat(const pid_t pid, const char *filename) free(st); return NULL; } @@ -423,7 +454,7 @@ index c44cee8..970b52d 100644 return st; } -@@ -1551,7 +1651,8 @@ check_dir(const pid_t pid, const char *dirname, struct device_list *dev_head, +@@ -1551,7 +1668,8 @@ check_dir(const pid_t pid, const char *dirname, struct device_list *dev_head, struct inode_list *ino_tmp; struct device_list *dev_tmp; struct unixsocket_list *sock_tmp; @@ -433,7 +464,7 @@ index c44cee8..970b52d 100644 char *dirpath; char filepath[PATH_MAX]; -@@ -1590,11 +1691,27 @@ check_dir(const pid_t pid, const char *dirname, struct device_list *dev_head, +@@ -1590,11 +1708,27 @@ check_dir(const pid_t pid, const char *dirname, struct device_list *dev_head, } for (dev_tmp = dev_head; dev_tmp != NULL; dev_tmp = dev_tmp->next) { @@ -464,7 +495,7 @@ index c44cee8..970b52d 100644 add_matched_proc(dev_tmp->name, pid, uid, ACCESS_FILEWR | -@@ -1616,9 +1733,10 @@ check_dir(const pid_t pid, const char *dirname, struct device_list *dev_head, +@@ -1616,9 +1750,10 @@ check_dir(const pid_t pid, const char *dirname, struct device_list *dev_head, continue; } if (st.st_ino == ino_tmp->inode) { @@ -477,7 +508,7 @@ index c44cee8..970b52d 100644 add_matched_proc(ino_tmp->name, pid, uid, ACCESS_FILEWR | -@@ -1647,31 +1765,54 @@ check_map(const pid_t pid, const char *filename, +@@ -1647,31 +1782,54 @@ check_map(const pid_t pid, const char *filename, FILE *fp; unsigned long long tmp_inode; unsigned int tmp_maj, tmp_min; @@ -542,7 +573,7 @@ index c44cee8..970b52d 100644 } fclose(fp); } -@@ -1695,6 +1836,7 @@ static uid_t getpiduid(const pid_t pid) +@@ -1695,6 +1853,7 @@ static uid_t getpiduid(const pid_t pid) * fill_unix_cache : Create a list of Unix sockets * This list is used later for matching purposes */ @@ -550,7 +581,7 @@ index c44cee8..970b52d 100644 void fill_unix_cache(struct unixsocket_list **unixsocket_head) { FILE *fp; -@@ -1711,6 +1853,8 @@ void fill_unix_cache(struct unixsocket_list **unixsocket_head) +@@ -1711,6 +1870,8 @@ void fill_unix_cache(struct unixsocket_list **unixsocket_head) while (fgets(line, BUFSIZ, fp) != NULL) { char *path; char *scanned_path = NULL; @@ -559,7 +590,7 @@ index c44cee8..970b52d 100644 if (sscanf(line, "%*x: %*x %*x %*x %*x %*d %d %ms", &scanned_inode, &scanned_path) != 2) { if (scanned_path) -@@ -1726,6 +1870,8 @@ void fill_unix_cache(struct unixsocket_list **unixsocket_head) +@@ -1726,6 +1887,8 @@ void fill_unix_cache(struct unixsocket_list **unixsocket_head) free(path); continue; } @@ -568,7 +599,7 @@ index c44cee8..970b52d 100644 if ((newsocket = (struct unixsocket_list *) malloc(sizeof(struct unixsocket_list))) == NULL) { free(path); -@@ -1734,6 +1880,7 @@ void fill_unix_cache(struct unixsocket_list **unixsocket_head) +@@ -1734,6 +1897,7 @@ void fill_unix_cache(struct unixsocket_list **unixsocket_head) newsocket->sun_name = strdup(scanned_path); newsocket->inode = st.st_ino; newsocket->dev = st.st_dev; @@ -576,7 +607,7 @@ index c44cee8..970b52d 100644 newsocket->net_inode = scanned_inode; newsocket->next = *unixsocket_head; *unixsocket_head = newsocket; -@@ -1746,6 +1893,7 @@ void fill_unix_cache(struct unixsocket_list **unixsocket_head) +@@ -1746,6 +1910,7 @@ void fill_unix_cache(struct unixsocket_list **unixsocket_head) /* * Free up the list of Unix sockets */ @@ -584,7 +615,7 @@ index c44cee8..970b52d 100644 void clear_unix_cache(struct unixsocket_list **unixsocket_head) { while(*unixsocket_head != NULL) { -@@ -1913,30 +2061,22 @@ scan_mounts(struct names *names_head, struct inode_list *ino_head, +@@ -1913,30 +2078,22 @@ scan_mounts(struct names *names_head, struct inode_list *ino_head, { struct device_list *dev_tmp; struct inode_list *ino_tmp; @@ -625,7 +656,7 @@ index c44cee8..970b52d 100644 add_special_proc(dev_tmp->name, PTYPE_MOUNT, 0, find_mountp); } -@@ -1948,7 +2088,6 @@ scan_mounts(struct names *names_head, struct inode_list *ino_head, +@@ -1948,7 +2105,6 @@ scan_mounts(struct names *names_head, struct inode_list *ino_head, find_mountp); } } @@ -633,7 +664,7 @@ index c44cee8..970b52d 100644 } static void -@@ -1998,16 +2137,44 @@ scan_swaps(struct names *names_head, struct inode_list *ino_head, +@@ -1998,16 +2154,44 @@ scan_swaps(struct names *names_head, struct inode_list *ino_head, fclose(fp); } @@ -682,7 +713,7 @@ index c44cee8..970b52d 100644 { list_t *ptr, *tmp; -@@ -2018,72 +2185,244 @@ static void clear_mntinfo(void) +@@ -2018,72 +2202,244 @@ static void clear_mntinfo(void) } } @@ -824,7 +855,12 @@ index c44cee8..970b52d 100644 + } + return ret == 2 ? 0 : -1; +} -+ + +- /* Sort mount points accordingly to the reverse mount order */ +- initial(&sort); +- for (mid = 1; mid <= max; mid++) { +- list_t *ptr, *tmp; +- list_for_each_safe(ptr, tmp, &mntinfo) { +#if defined(HAS_NAME_TO_HANDLE_AT) +static int +get_mountid(const char *path) @@ -853,12 +889,7 @@ index c44cee8..970b52d 100644 + int ret = -1; + + *mountinfo = NULL; - -- /* Sort mount points accordingly to the reverse mount order */ -- initial(&sort); -- for (mid = 1; mid <= max; mid++) { -- list_t *ptr, *tmp; -- list_for_each_safe(ptr, tmp, &mntinfo) { ++ +#if defined(HAS_NAME_TO_HANDLE_AT) + if (mnt_id >= 0) { + list_t *ptr; @@ -940,11 +971,11 @@ index c44cee8..970b52d 100644 - if (mid != mnt->parid) + + if (nlen != mnt->nlen) - continue; -- move_head(ptr, &sort); ++ continue; + + if (strcmp(use, mnt->mpoint)) -+ continue; + continue; +- move_head(ptr, &sort); + + ret = 0; + errno = 0; @@ -971,7 +1002,7 @@ index c44cee8..970b52d 100644 /* * Determine device of links below /proc/ */ -@@ -2091,8 +2430,7 @@ static int mntstat(const char *path, struct stat *buf) +@@ -2091,8 +2447,7 @@ static int mntstat(const char *path, struct stat *buf) { char name[PATH_MAX + 1]; const char *use; @@ -981,7 +1012,7 @@ index c44cee8..970b52d 100644 if ((use = realpath(path, name)) == NULL || *use != '/') { -@@ -2104,27 +2442,26 @@ static int mntstat(const char *path, struct stat *buf) +@@ -2104,27 +2459,26 @@ static int mntstat(const char *path, struct stat *buf) errno = 0; return stat(path, buf); } diff --git a/0002-Use-new-statx-2-system-call-to-avoid-hangs-on-NFS.patch b/0002-Use-new-statx-2-system-call-to-avoid-hangs-on-NFS.patch index e71f2ae..20ec8a8 100644 --- a/0002-Use-new-statx-2-system-call-to-avoid-hangs-on-NFS.patch +++ b/0002-Use-new-statx-2-system-call-to-avoid-hangs-on-NFS.patch @@ -1,6 +1,6 @@ -From 9c6fbdcb126ed8d0567ac3b88dac1bf34d4036fb Mon Sep 17 00:00:00 2001 +From d4b2099ffd77d1fdea380ac42326b11a5be35e72 Mon Sep 17 00:00:00 2001 From: Werner Fink -Date: Wed, 14 Nov 2018 08:49:45 +0100 +Date: Thu, 15 Nov 2018 07:41:23 +0100 Subject: [PATCH] Use new statx(2) system call to avoid hangs on NFS Signed-off-by: Werner Fink @@ -90,7 +90,7 @@ index d8d3366..81d3674 100644 # Enable hardened compile and link flags AC_ARG_ENABLE([harden_flags], diff --git src/fuser.c src/fuser.c -index 970b52d..e2d14bf 100644 +index 7ee9b49..3f512de 100644 --- src/fuser.c +++ src/fuser.c @@ -63,7 +63,7 @@ @@ -122,7 +122,7 @@ index 970b52d..e2d14bf 100644 find_mountpoint(this_name->filename, &mountinfo) != 0) { if (errno == ENOENT) fprintf(stderr, -@@ -1233,9 +1229,7 @@ int main(int argc, char *argv[]) +@@ -1250,9 +1246,7 @@ int main(int argc, char *argv[]) opts |= OPT_INTERACTIVE; break; case 'I': @@ -132,7 +132,7 @@ index 970b52d..e2d14bf 100644 break; case 'k': opts |= OPT_KILL; -@@ -1301,10 +1295,11 @@ int main(int argc, char *argv[]) +@@ -1318,10 +1312,11 @@ int main(int argc, char *argv[]) continue; } @@ -147,7 +147,7 @@ index 970b52d..e2d14bf 100644 /* an option */ /* Not an option, must be a file specification */ if ((this_name = malloc(sizeof(struct names))) == NULL) -@@ -1624,7 +1619,7 @@ static struct stat *get_pidstat(const pid_t pid, const char *filename, int *id) +@@ -1641,7 +1636,7 @@ static struct stat *get_pidstat(const pid_t pid, const char *filename, int *id) if ((st = (struct stat *)malloc(sizeof(struct stat))) == NULL) return NULL; snprintf(pathname, 256, "/proc/%d/%s", pid, filename); @@ -156,7 +156,7 @@ index 970b52d..e2d14bf 100644 free(st); return NULL; } -@@ -1671,7 +1666,7 @@ check_dir(const pid_t pid, const char *dirname, struct device_list *dev_head, +@@ -1688,7 +1683,7 @@ check_dir(const pid_t pid, const char *dirname, struct device_list *dev_head, snprintf(filepath, sizeof filepath - 1, "/proc/%d/%s/%s", pid, dirname, direntry->d_name); @@ -165,7 +165,7 @@ index 970b52d..e2d14bf 100644 if (errno != ENOENT && errno != ENOTDIR) { fprintf(stderr, _("Cannot stat file %s: %s\n"), filepath, strerror(errno)); -@@ -1726,7 +1721,7 @@ check_dir(const pid_t pid, const char *dirname, struct device_list *dev_head, +@@ -1743,7 +1738,7 @@ check_dir(const pid_t pid, const char *dirname, struct device_list *dev_head, if (thedev != ino_tmp->device) continue; if (!st.st_ino @@ -174,7 +174,7 @@ index 970b52d..e2d14bf 100644 fprintf(stderr, _("Cannot stat file %s: %s\n"), filepath, strerror(errno)); -@@ -1824,11 +1819,11 @@ static uid_t getpiduid(const pid_t pid) +@@ -1841,11 +1836,11 @@ static uid_t getpiduid(const pid_t pid) if (asprintf(&pathname, "/proc/%d", pid) < 0) return 0; @@ -190,7 +190,7 @@ index 970b52d..e2d14bf 100644 return st.st_uid; } -@@ -1866,7 +1861,7 @@ void fill_unix_cache(struct unixsocket_list **unixsocket_head) +@@ -1883,7 +1878,7 @@ void fill_unix_cache(struct unixsocket_list **unixsocket_head) path = scanned_path; if (*scanned_path == '@') scanned_path++; @@ -199,7 +199,7 @@ index 970b52d..e2d14bf 100644 free(path); continue; } -@@ -2001,7 +1996,7 @@ static dev_t find_net_dev(void) +@@ -2018,7 +2013,7 @@ static dev_t find_net_dev(void) fprintf(stderr, _("Cannot open a network socket.\n")); return -1; } @@ -208,7 +208,7 @@ index 970b52d..e2d14bf 100644 fprintf(stderr, _("Cannot find socket's device number.\n")); close(skt); return -1; -@@ -2034,7 +2029,7 @@ scan_knfsd(struct names *names_head, struct inode_list *ino_head, +@@ -2051,7 +2046,7 @@ scan_knfsd(struct names *names_head, struct inode_list *ino_head, if ((find_space = strpbrk(line, " \t")) == NULL) continue; *find_space = '\0'; @@ -217,7 +217,7 @@ index 970b52d..e2d14bf 100644 continue; } /* Scan the devices */ -@@ -2069,7 +2064,7 @@ scan_mounts(struct names *names_head, struct inode_list *ino_head, +@@ -2086,7 +2081,7 @@ scan_mounts(struct names *names_head, struct inode_list *ino_head, mntinfo_t *mnt = list_entry(ptr, mntinfo_t); const char *find_mountp = mnt->mpoint; @@ -226,7 +226,7 @@ index 970b52d..e2d14bf 100644 continue; /* Scan the devices */ -@@ -2116,7 +2111,7 @@ scan_swaps(struct names *names_head, struct inode_list *ino_head, +@@ -2133,7 +2128,7 @@ scan_swaps(struct names *names_head, struct inode_list *ino_head, if (*find_space == '\0') continue; } @@ -235,7 +235,7 @@ index 970b52d..e2d14bf 100644 continue; } /* Scan the devices */ -@@ -2279,7 +2274,7 @@ out: +@@ -2296,7 +2291,7 @@ out: struct stat lst; snprintf(pathname, 256, "/proc/%d/fd/%s", pid, fd); @@ -244,7 +244,7 @@ index 970b52d..e2d14bf 100644 if (lst.st_mode & S_IWUSR) info->flags |= O_WRONLY; ret++; -@@ -2422,49 +2417,6 @@ out: +@@ -2439,49 +2434,6 @@ out: return ret; }