From dee14919e617294fb96e403dccefd86178d256dd Mon Sep 17 00:00:00 2001 From: "Dr. Werner Fink" Date: Wed, 14 Nov 2018 11:26:45 +0000 Subject: [PATCH] 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 bcd23c5..4a964aa 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 681d17a..ab6ec1a 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 9368322..55b3b3e 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