Work on bsc#1194172

OBS-URL: https://build.opensuse.org/package/show/Base:System/psmisc?expand=0&rev=138
This commit is contained in:
Dr. Werner Fink 2022-02-01 12:42:17 +00:00 committed by Git OBS Bridge
parent c53acbc14b
commit 3269f8ae05
3 changed files with 130 additions and 91 deletions

View File

@ -1,6 +1,6 @@
From bfa17afa43fc1b98c2bbc9c54416db9ccb505028 Mon Sep 17 00:00:00 2001 From fe73905beaf1f7a7ec5a5c2796031987e5336fd7 Mon Sep 17 00:00:00 2001
From: Werner Fink <werner@suse.de> From: Werner Fink <werner@suse.de>
Date: Fri, 7 May 2021 16:25:13 +0200 Date: Tue, 1 Feb 2022 13:15:39 +0100
Subject: [PATCH] Use mountinfo to be able to use the mount identity Subject: [PATCH] Use mountinfo to be able to use the mount identity
which allows to distinguish different mounts with the which allows to distinguish different mounts with the
@ -22,13 +22,16 @@ such as qcow2 files. Patch from Ali Abdallah <ali.abdallah@suse.com>
Correct last change by using our own namespace to Correct last change by using our own namespace to
determine the appropriate mount ID for e.g. qcow2 files. determine the appropriate mount ID for e.g. qcow2 files.
Determine the namespace of a process only once to speed
up the parsing of fdinfo.
Signed-off-by: Werner Fink <werner@suse.de> Signed-off-by: Werner Fink <werner@suse.de>
--- ---
configure.ac | 15 +- configure.ac | 15 +-
src/fuser.c | 683 +++++++++++++++++++++++++++++++++++++++----------- src/fuser.c | 701 +++++++++++++++++++++++++++++++++++++++-----------
src/fuser.h | 25 +- src/fuser.h | 25 +-
src/timeout.c | 5 +- src/timeout.c | 5 +-
4 files changed, 567 insertions(+), 161 deletions(-) 4 files changed, 585 insertions(+), 161 deletions(-)
diff --git configure.ac configure.ac diff --git configure.ac configure.ac
index 182a0df..d4dee51 100644 index 182a0df..d4dee51 100644
@ -64,7 +67,7 @@ index 182a0df..d4dee51 100644
dnl Checks for typedefs, structures, and compiler characteristics. dnl Checks for typedefs, structures, and compiler characteristics.
AC_C_CONST AC_C_CONST
diff --git src/fuser.c src/fuser.c diff --git src/fuser.c src/fuser.c
index 03e6237..dd928d2 100644 index 03e6237..79d44ef 100644
--- src/fuser.c --- src/fuser.c
+++ src/fuser.c +++ src/fuser.c
@@ -32,6 +32,8 @@ @@ -32,6 +32,8 @@
@ -98,7 +101,7 @@ index 03e6237..dd928d2 100644
static void atexit_clear_unix_cache(); static void atexit_clear_unix_cache();
static dev_t find_net_dev(void); static dev_t find_net_dev(void);
static void scan_procs(struct names *names_head, struct inode_list *ino_head, static void scan_procs(struct names *names_head, struct inode_list *ino_head,
@@ -117,9 +119,15 @@ static void debug_match_lists(struct names *names_head, @@ -117,9 +119,16 @@ static void debug_match_lists(struct names *names_head,
struct device_list *dev_head); struct device_list *dev_head);
#endif #endif
@ -106,8 +109,9 @@ index 03e6237..dd928d2 100644
+static list_t mntinfo = { &mntinfo, &mntinfo }; +static list_t mntinfo = { &mntinfo, &mntinfo };
static void clear_mntinfo(void) __attribute__ ((__destructor__)); static void clear_mntinfo(void) __attribute__ ((__destructor__));
static void init_mntinfo(void) __attribute__ ((__constructor__)); static void init_mntinfo(void) __attribute__ ((__constructor__));
+static int get_fdinfo(const pid_t pid, const char *fd, struct fdinfo *info); +static int get_fdinfo(const pid_t pid, const char *fd, struct fdinfo *info, const ino_t ns);
+#if defined(HAS_NAME_TO_HANDLE_AT) +#if defined(HAS_NAME_TO_HANDLE_AT)
+static ino_t get_namespace(const pid_t pid);
+static int get_mountid(const char *path); +static int get_mountid(const char *path);
+#endif +#endif
+static int find_mountpoint(const char *path, mntinfo_t **mountinfo); +static int find_mountpoint(const char *path, mntinfo_t **mountinfo);
@ -115,7 +119,7 @@ index 03e6237..dd928d2 100644
static int mntstat(const char *path, struct stat *buf); static int mntstat(const char *path, struct stat *buf);
#endif #endif
static stat_t thestat = stat; static stat_t thestat = stat;
@@ -210,6 +218,7 @@ scan_procs(struct names *names_head, struct inode_list *ino_head, @@ -210,6 +219,7 @@ scan_procs(struct names *names_head, struct inode_list *ino_head,
struct stat *cwd_stat = NULL; struct stat *cwd_stat = NULL;
struct stat *exe_stat = NULL; struct stat *exe_stat = NULL;
struct stat *root_stat = NULL; struct stat *root_stat = NULL;
@ -123,7 +127,7 @@ index 03e6237..dd928d2 100644
if (topproc_dent->d_name[0] < '0' || topproc_dent->d_name[0] > '9') /* Not a process */ if (topproc_dent->d_name[0] < '0' || topproc_dent->d_name[0] > '9') /* Not a process */
continue; continue;
@@ -219,9 +228,9 @@ scan_procs(struct names *names_head, struct inode_list *ino_head, @@ -219,9 +229,9 @@ scan_procs(struct names *names_head, struct inode_list *ino_head,
continue; continue;
uid = getpiduid(pid); uid = getpiduid(pid);
@ -136,7 +140,7 @@ index 03e6237..dd928d2 100644
cwd_dev = cwd_stat ? cwd_stat->st_dev : 0; cwd_dev = cwd_stat ? cwd_stat->st_dev : 0;
exe_dev = exe_stat ? exe_stat->st_dev : 0; exe_dev = exe_stat ? exe_stat->st_dev : 0;
root_dev = root_stat ? root_stat->st_dev : 0; root_dev = root_stat ? root_stat->st_dev : 0;
@@ -229,39 +238,51 @@ scan_procs(struct names *names_head, struct inode_list *ino_head, @@ -229,39 +239,51 @@ scan_procs(struct names *names_head, struct inode_list *ino_head,
/* Scan the devices */ /* Scan the devices */
for (dev_tmp = dev_head; dev_tmp != NULL; for (dev_tmp = dev_head; dev_tmp != NULL;
dev_tmp = dev_tmp->next) { dev_tmp = dev_tmp->next) {
@ -203,7 +207,7 @@ index 03e6237..dd928d2 100644
if (cwd_stat if (cwd_stat
&& cwd_stat->st_dev == ino_tmp->device && cwd_stat->st_dev == ino_tmp->device
&& cwd_stat->st_ino == ino_tmp->inode) && cwd_stat->st_ino == ino_tmp->inode)
@@ -302,18 +323,42 @@ add_inode(struct inode_list **ino_list, struct names *this_name, @@ -302,18 +324,42 @@ add_inode(struct inode_list **ino_list, struct names *this_name,
ino_tmp->name = this_name; ino_tmp->name = this_name;
ino_tmp->device = device; ino_tmp->device = device;
ino_tmp->inode = inode; ino_tmp->inode = inode;
@ -247,7 +251,7 @@ index 03e6237..dd928d2 100644
if ((dev_tmp = if ((dev_tmp =
(struct device_list *)malloc(sizeof(struct device_list))) == NULL) (struct device_list *)malloc(sizeof(struct device_list))) == NULL)
@@ -321,6 +366,10 @@ add_device(struct device_list **dev_list, struct names *this_name, dev_t device) @@ -321,6 +367,10 @@ add_device(struct device_list **dev_list, struct names *this_name, dev_t device)
dev_head = *dev_list; dev_head = *dev_list;
dev_tmp->name = this_name; dev_tmp->name = this_name;
dev_tmp->device = device; dev_tmp->device = device;
@ -258,7 +262,7 @@ index 03e6237..dd928d2 100644
dev_tmp->next = dev_head; dev_tmp->next = dev_head;
*dev_list = dev_tmp; *dev_list = dev_tmp;
} }
@@ -462,13 +511,15 @@ add_special_proc(struct names *name_list, const char ptype, const uid_t uid, @@ -462,13 +512,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, int parse_file(struct names *this_name, struct inode_list **ino_list,
const opt_type opts) const opt_type opts)
{ {
@ -275,7 +279,7 @@ index 03e6237..dd928d2 100644
if (errno == ENOENT) if (errno == ENOENT)
fprintf(stderr, fprintf(stderr,
_("Specified filename %s does not exist.\n"), _("Specified filename %s does not exist.\n"),
@@ -478,10 +529,12 @@ int parse_file(struct names *this_name, struct inode_list **ino_list, @@ -478,10 +530,12 @@ int parse_file(struct names *this_name, struct inode_list **ino_list,
this_name->filename, strerror(errno)); this_name->filename, strerror(errno));
return -1; return -1;
} }
@ -290,7 +294,7 @@ index 03e6237..dd928d2 100644
#endif /* DEBUG */ #endif /* DEBUG */
add_inode(ino_list, this_name, this_name->st.st_dev, add_inode(ino_list, this_name, this_name->st.st_dev,
this_name->st.st_ino); this_name->st.st_ino);
@@ -513,12 +566,43 @@ parse_mounts(struct names *this_name, struct device_list **dev_list, @@ -513,12 +567,43 @@ parse_mounts(struct names *this_name, struct device_list **dev_list,
const opt_type opts) const opt_type opts)
{ {
dev_t match_device; dev_t match_device;
@ -335,7 +339,7 @@ index 03e6237..dd928d2 100644
return 0; return 0;
} }
@@ -695,10 +779,12 @@ int parse_inet(struct names *this_name, struct ip_connections **ip_list) @@ -695,10 +780,12 @@ int parse_inet(struct names *this_name, struct ip_connections **ip_list)
break; break;
#endif #endif
} }
@ -351,7 +355,7 @@ index 03e6237..dd928d2 100644
} }
return 1; return 1;
} }
@@ -965,6 +1051,21 @@ free_inodes(struct inode_list **match_inodes) @@ -965,6 +1052,21 @@ free_inodes(struct inode_list **match_inodes)
/* /*
* Free up structures allocated in add_device * Free up structures allocated in add_device
*/ */
@ -373,7 +377,7 @@ index 03e6237..dd928d2 100644
static void static void
free_devices(struct device_list **match_devices) free_devices(struct device_list **match_devices)
{ {
@@ -972,6 +1073,8 @@ free_devices(struct device_list **match_devices) @@ -972,6 +1074,8 @@ free_devices(struct device_list **match_devices)
device_tmp = *match_devices; device_tmp = *match_devices;
while(device_tmp != NULL) { while(device_tmp != NULL) {
@ -382,7 +386,7 @@ index 03e6237..dd928d2 100644
device_next = device_tmp->next; device_next = device_tmp->next;
free(device_tmp); free(device_tmp);
device_tmp = device_next; device_tmp = device_next;
@@ -1174,16 +1277,11 @@ int main(int argc, char *argv[]) @@ -1174,16 +1278,11 @@ int main(int argc, char *argv[])
skip_argv = 1; skip_argv = 1;
//while(option != '\0') option++; //while(option != '\0') option++;
if (strcmp(argv[argc_cnt], "tcp") == 0) if (strcmp(argv[argc_cnt], "tcp") == 0)
@ -404,7 +408,7 @@ index 03e6237..dd928d2 100644
else else
usage(_ usage(_
("Invalid namespace name")); ("Invalid namespace name"));
@@ -1223,7 +1321,7 @@ int main(int argc, char *argv[]) @@ -1223,7 +1322,7 @@ int main(int argc, char *argv[])
} }
#if defined(WITH_MOUNTINFO_LIST) #if defined(WITH_MOUNTINFO_LIST)
@ -413,7 +417,7 @@ index 03e6237..dd928d2 100644
thestat = mntstat; thestat = mntstat;
#endif #endif
/* an option */ /* an option */
@@ -1537,7 +1635,7 @@ print_matches(struct names *names_head, const opt_type opts, @@ -1537,7 +1636,7 @@ print_matches(struct names *names_head, const opt_type opts,
} }
@ -422,7 +426,7 @@ index 03e6237..dd928d2 100644
{ {
char pathname[PATH_MAX]; char pathname[PATH_MAX];
struct stat *st; struct stat *st;
@@ -1549,6 +1647,15 @@ static struct stat *get_pidstat(const pid_t pid, const char *filename) @@ -1549,6 +1648,15 @@ static struct stat *get_pidstat(const pid_t pid, const char *filename)
free(st); free(st);
return NULL; return NULL;
} }
@ -438,7 +442,7 @@ index 03e6237..dd928d2 100644
return st; return st;
} }
@@ -1563,7 +1670,7 @@ check_dir(const pid_t pid, const char *dirname, struct device_list *dev_head, @@ -1563,10 +1671,11 @@ check_dir(const pid_t pid, const char *dirname, struct device_list *dev_head,
struct inode_list *ino_tmp; struct inode_list *ino_tmp;
struct device_list *dev_tmp; struct device_list *dev_tmp;
struct unixsocket_list *sock_tmp; struct unixsocket_list *sock_tmp;
@ -447,7 +451,24 @@ index 03e6237..dd928d2 100644
char *dirpath; char *dirpath;
char filepath[PATH_MAX]; char filepath[PATH_MAX];
char real_filepath[PATH_MAX]; char real_filepath[PATH_MAX];
@@ -1589,6 +1696,9 @@ check_dir(const pid_t pid, const char *dirname, struct device_list *dev_head, + ino_t ns;
if (asprintf(&dirpath, "/proc/%d/%s", pid, dirname) < 0)
return;
@@ -1576,6 +1685,12 @@ check_dir(const pid_t pid, const char *dirname, struct device_list *dev_head,
}
free(dirpath);
+#if defined(HAS_NAME_TO_HANDLE_AT)
+ ns = get_namespace(pid);
+#else
+ ns = -1;
+#endif
+
while ((direntry = readdir(dirp)) != NULL) {
if (direntry->d_name[0] < '0' || direntry->d_name[0] > '9')
continue;
@@ -1589,6 +1704,9 @@ check_dir(const pid_t pid, const char *dirname, struct device_list *dev_head,
filepath, strerror(errno)); filepath, strerror(errno));
} }
} else { } else {
@ -457,13 +478,13 @@ index 03e6237..dd928d2 100644
thedev = st.st_dev; thedev = st.st_dev;
if (thedev == netdev) { if (thedev == netdev) {
for (sock_tmp = sockets; sock_tmp != NULL; for (sock_tmp = sockets; sock_tmp != NULL;
@@ -1601,10 +1711,29 @@ check_dir(const pid_t pid, const char *dirname, struct device_list *dev_head, @@ -1601,10 +1719,29 @@ check_dir(const pid_t pid, const char *dirname, struct device_list *dev_head,
} }
} }
} }
+ +
+ memset(&fd, 0, sizeof(struct fdinfo)); + memset(&fd, 0, sizeof(struct fdinfo));
+ fdret = get_fdinfo(pid, direntry->d_name, &fd); + fdret = get_fdinfo(pid, direntry->d_name, &fd, ns);
+ +
for (dev_tmp = dev_head; dev_tmp != NULL; for (dev_tmp = dev_head; dev_tmp != NULL;
dev_tmp = dev_tmp->next) { dev_tmp = dev_tmp->next) {
@ -489,7 +510,7 @@ index 03e6237..dd928d2 100644
/* check the paths match if it is not a block device */ /* check the paths match if it is not a block device */
if (! S_ISBLK(dev_tmp->name->st.st_mode)) { if (! S_ISBLK(dev_tmp->name->st.st_mode)) {
@@ -1616,9 +1745,14 @@ check_dir(const pid_t pid, const char *dirname, struct device_list *dev_head, @@ -1616,9 +1753,14 @@ check_dir(const pid_t pid, const char *dirname, struct device_list *dev_head,
continue; continue;
} }
} }
@ -506,7 +527,7 @@ index 03e6237..dd928d2 100644
add_matched_proc(dev_tmp->name, add_matched_proc(dev_tmp->name,
pid, uid, pid, uid,
ACCESS_FILEWR | ACCESS_FILEWR |
@@ -1640,9 +1774,10 @@ check_dir(const pid_t pid, const char *dirname, struct device_list *dev_head, @@ -1640,9 +1782,10 @@ check_dir(const pid_t pid, const char *dirname, struct device_list *dev_head,
continue; continue;
} }
if (st.st_ino == ino_tmp->inode) { if (st.st_ino == ino_tmp->inode) {
@ -519,7 +540,7 @@ index 03e6237..dd928d2 100644
add_matched_proc(ino_tmp->name, add_matched_proc(ino_tmp->name,
pid, uid, pid, uid,
ACCESS_FILEWR | ACCESS_FILEWR |
@@ -1671,31 +1806,54 @@ check_map(const pid_t pid, const char *filename, @@ -1671,31 +1814,54 @@ check_map(const pid_t pid, const char *filename,
FILE *fp; FILE *fp;
unsigned long long tmp_inode; unsigned long long tmp_inode;
unsigned int tmp_maj, tmp_min; unsigned int tmp_maj, tmp_min;
@ -584,7 +605,7 @@ index 03e6237..dd928d2 100644
} }
fclose(fp); fclose(fp);
} }
@@ -1719,6 +1877,7 @@ static uid_t getpiduid(const pid_t pid) @@ -1719,6 +1885,7 @@ static uid_t getpiduid(const pid_t pid)
* fill_unix_cache : Create a list of Unix sockets * fill_unix_cache : Create a list of Unix sockets
* This list is used later for matching purposes * This list is used later for matching purposes
*/ */
@ -592,7 +613,7 @@ index 03e6237..dd928d2 100644
void fill_unix_cache(struct unixsocket_list **unixsocket_head) void fill_unix_cache(struct unixsocket_list **unixsocket_head)
{ {
FILE *fp; FILE *fp;
@@ -1735,6 +1894,8 @@ void fill_unix_cache(struct unixsocket_list **unixsocket_head) @@ -1735,6 +1902,8 @@ void fill_unix_cache(struct unixsocket_list **unixsocket_head)
while (fgets(line, BUFSIZ, fp) != NULL) { while (fgets(line, BUFSIZ, fp) != NULL) {
char *path; char *path;
char *scanned_path = NULL; char *scanned_path = NULL;
@ -601,7 +622,7 @@ index 03e6237..dd928d2 100644
if (sscanf(line, "%*x: %*x %*x %*x %*x %*d %llu %ms", if (sscanf(line, "%*x: %*x %*x %*x %*x %*d %llu %ms",
&scanned_inode, &scanned_path) != 2) { &scanned_inode, &scanned_path) != 2) {
if (scanned_path) if (scanned_path)
@@ -1750,6 +1911,8 @@ void fill_unix_cache(struct unixsocket_list **unixsocket_head) @@ -1750,6 +1919,8 @@ void fill_unix_cache(struct unixsocket_list **unixsocket_head)
free(path); free(path);
continue; continue;
} }
@ -610,7 +631,7 @@ index 03e6237..dd928d2 100644
if ((newsocket = (struct unixsocket_list *) if ((newsocket = (struct unixsocket_list *)
malloc(sizeof(struct unixsocket_list))) == NULL) { malloc(sizeof(struct unixsocket_list))) == NULL) {
free(path); free(path);
@@ -1758,6 +1921,7 @@ void fill_unix_cache(struct unixsocket_list **unixsocket_head) @@ -1758,6 +1929,7 @@ void fill_unix_cache(struct unixsocket_list **unixsocket_head)
newsocket->sun_name = strdup(scanned_path); newsocket->sun_name = strdup(scanned_path);
newsocket->inode = st.st_ino; newsocket->inode = st.st_ino;
newsocket->dev = st.st_dev; newsocket->dev = st.st_dev;
@ -618,7 +639,7 @@ index 03e6237..dd928d2 100644
newsocket->net_inode = scanned_inode; newsocket->net_inode = scanned_inode;
newsocket->next = *unixsocket_head; newsocket->next = *unixsocket_head;
*unixsocket_head = newsocket; *unixsocket_head = newsocket;
@@ -1770,6 +1934,7 @@ void fill_unix_cache(struct unixsocket_list **unixsocket_head) @@ -1770,6 +1942,7 @@ void fill_unix_cache(struct unixsocket_list **unixsocket_head)
/* /*
* Free up the list of Unix sockets * Free up the list of Unix sockets
*/ */
@ -626,7 +647,7 @@ index 03e6237..dd928d2 100644
void clear_unix_cache(struct unixsocket_list **unixsocket_head) void clear_unix_cache(struct unixsocket_list **unixsocket_head)
{ {
while(*unixsocket_head != NULL) { while(*unixsocket_head != NULL) {
@@ -1941,34 +2106,21 @@ scan_mounts(struct names *names_head, struct inode_list *ino_head, @@ -1941,34 +2114,21 @@ scan_mounts(struct names *names_head, struct inode_list *ino_head,
{ {
struct device_list *dev_tmp; struct device_list *dev_tmp;
struct inode_list *ino_tmp; struct inode_list *ino_tmp;
@ -669,7 +690,7 @@ index 03e6237..dd928d2 100644
add_special_proc(dev_tmp->name, PTYPE_MOUNT, 0, add_special_proc(dev_tmp->name, PTYPE_MOUNT, 0,
find_mountp); find_mountp);
} }
@@ -1980,7 +2132,6 @@ scan_mounts(struct names *names_head, struct inode_list *ino_head, @@ -1980,7 +2140,6 @@ scan_mounts(struct names *names_head, struct inode_list *ino_head,
find_mountp); find_mountp);
} }
} }
@ -677,7 +698,7 @@ index 03e6237..dd928d2 100644
} }
static void static void
@@ -2033,16 +2184,44 @@ scan_swaps(struct names *names_head, struct inode_list *ino_head, @@ -2033,16 +2192,44 @@ scan_swaps(struct names *names_head, struct inode_list *ino_head,
fclose(fp); fclose(fp);
} }
@ -726,7 +747,7 @@ index 03e6237..dd928d2 100644
{ {
list_t *ptr, *tmp; list_t *ptr, *tmp;
@@ -2053,72 +2232,276 @@ static void clear_mntinfo(void) @@ -2053,72 +2240,286 @@ static void clear_mntinfo(void)
} }
} }
@ -817,10 +838,10 @@ index 03e6237..dd928d2 100644
+} +}
+ +
+static int +static int
+get_fdinfo(const pid_t pid, const char *fd, struct fdinfo *info) +get_fdinfo(const pid_t pid, const char *fd, struct fdinfo *info, const ino_t ns)
+{ +{
+ int ret = 0; + int ret = 0;
+ char pathname[256]; + char pathname[512];
+ int mnt_id = 0, flags = 0; + int mnt_id = 0, flags = 0;
+#if defined(HAS_FDINFO) /* Here we get the private namespace as well */ +#if defined(HAS_FDINFO) /* Here we get the private namespace as well */
+ const static char delimiters[] = ": \t\n"; + const static char delimiters[] = ": \t\n";
@ -839,7 +860,7 @@ index 03e6237..dd928d2 100644
+ mynamespace = st.st_ino; + mynamespace = st.st_ino;
+ } + }
+# endif +# endif
+ snprintf(pathname, 256, "/proc/%d/fdinfo/%s", pid, fd); + snprintf(pathname, sizeof(pathname)-1, "/proc/%d/fdinfo/%s", pid, fd);
+ if ((fp = fopen(pathname, "r")) == NULL) + if ((fp = fopen(pathname, "r")) == NULL)
+ goto out; /* forbidden namesspace, try our own namespace */ + goto out; /* forbidden namesspace, try our own namespace */
+ while (fgets(line, BUFSIZ, fp) && ret < 2) { + while (fgets(line, BUFSIZ, fp) && ret < 2) {
@ -865,10 +886,9 @@ index 03e6237..dd928d2 100644
+ fclose(fp); + fclose(fp);
+out: +out:
+# if defined(HAS_NAME_TO_HANDLE_AT) +# if defined(HAS_NAME_TO_HANDLE_AT)
+ snprintf(pathname, 256, "/proc/%d/ns/mnt", pid); + if (mynamespace != ns) {
+ if (stat(pathname, &st) == 0 && mynamespace != st.st_ino) {
+ char *realname; + char *realname;
+ snprintf(pathname, 256, "/proc/%d/fd/%s", pid, fd); + snprintf(pathname, sizeof(pathname)-1, "/proc/%d/fd/%s", pid, fd);
+ realname = expandpath(pathname); + realname = expandpath(pathname);
+ if (realname) { /* Use our namespace for mount ID <sigh> */ + if (realname) { /* Use our namespace for mount ID <sigh> */
+ info->mnt_id = get_mountid(realname); + info->mnt_id = get_mountid(realname);
@ -880,7 +900,7 @@ index 03e6237..dd928d2 100644
+ if (!flags || !mnt_id) { + if (!flags || !mnt_id) {
+ struct stat lst; + struct stat lst;
+ +
+ snprintf(pathname, 256, "/proc/%d/fd/%s", pid, fd); + snprintf(pathname, sizeof(pathname)-1, "/proc/%d/fd/%s", pid, fd);
+ if (!flags && lstat(pathname, &lst) == 0) { + if (!flags && lstat(pathname, &lst) == 0) {
+ if (lst.st_mode & S_IWUSR) + if (lst.st_mode & S_IWUSR)
+ info->flags |= O_WRONLY; + info->flags |= O_WRONLY;
@ -900,13 +920,19 @@ index 03e6237..dd928d2 100644
+ } + }
+ return ret == 2 ? 0 : -1; + 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) +#if defined(HAS_NAME_TO_HANDLE_AT)
+static ino_t
+get_namespace(const pid_t pid)
+{
+ char pathname[512];
+ struct stat st;
+ snprintf(pathname, sizeof(pathname)-1, "/proc/%d/ns/mnt", pid);
+ if (stat(pathname, &st) == 0)
+ return st.st_ino;
+ return -1;
+}
+
+static int +static int
+get_mountid(const char *path) +get_mountid(const char *path)
+{ +{
@ -938,7 +964,12 @@ index 03e6237..dd928d2 100644
+#if defined(HAS_NAME_TO_HANDLE_AT) +#if defined(HAS_NAME_TO_HANDLE_AT)
+ if (mnt_id >= 0) { + if (mnt_id >= 0) {
+ list_t *ptr; + list_t *ptr;
+
- /* 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) {
+ errno = ENOENT; + errno = ENOENT;
+ list_for_each(ptr, &mntinfo) { + list_for_each(ptr, &mntinfo) {
mntinfo_t *mnt = list_entry(ptr, mntinfo_t); mntinfo_t *mnt = list_entry(ptr, mntinfo_t);
@ -1016,11 +1047,11 @@ index 03e6237..dd928d2 100644
- if (mid != mnt->parid) - if (mid != mnt->parid)
+ +
+ if (nlen != mnt->nlen) + if (nlen != mnt->nlen)
continue; + continue;
- move_head(ptr, &sort);
+ +
+ if (strcmp(use, mnt->mpoint)) + if (strcmp(use, mnt->mpoint))
+ continue; continue;
- move_head(ptr, &sort);
+ +
+ ret = 0; + ret = 0;
+ errno = 0; + errno = 0;
@ -1047,7 +1078,7 @@ index 03e6237..dd928d2 100644
/* /*
* Determine device of links below /proc/ * Determine device of links below /proc/
*/ */
@@ -2126,8 +2509,7 @@ static int mntstat(const char *path, struct stat *buf) @@ -2126,8 +2527,7 @@ static int mntstat(const char *path, struct stat *buf)
{ {
char name[PATH_MAX + 1]; char name[PATH_MAX + 1];
const char *use; const char *use;
@ -1057,7 +1088,7 @@ index 03e6237..dd928d2 100644
if ((use = realpath(path, name)) == NULL || *use != '/') if ((use = realpath(path, name)) == NULL || *use != '/')
{ {
@@ -2139,27 +2521,26 @@ static int mntstat(const char *path, struct stat *buf) @@ -2139,27 +2539,26 @@ static int mntstat(const char *path, struct stat *buf)
errno = 0; errno = 0;
return stat(path, buf); return stat(path, buf);
} }

View File

@ -1,6 +1,6 @@
From f2ada8ea7939bc8f607d88a10c92d5bb96a700b8 Mon Sep 17 00:00:00 2001 From ab950c00ff36acf1731330f3b55863b3102cfe6a Mon Sep 17 00:00:00 2001
From: Werner Fink <werner@suse.de> From: Werner Fink <werner@suse.de>
Date: Fri, 7 May 2021 16:36:28 +0200 Date: Tue, 1 Feb 2022 13:34:41 +0100
Subject: [PATCH] Use new statx(2) system call to avoid hangs on NFS Subject: [PATCH] Use new statx(2) system call to avoid hangs on NFS
Signed-off-by: Werner Fink <werner@suse.de> Signed-off-by: Werner Fink <werner@suse.de>
@ -90,7 +90,7 @@ index d4dee51..eda0e62 100644
# Enable hardened compile and link flags # Enable hardened compile and link flags
AC_ARG_ENABLE([harden_flags], AC_ARG_ENABLE([harden_flags],
diff --git src/fuser.c src/fuser.c diff --git src/fuser.c src/fuser.c
index dd928d2..d08f7a9 100644 index 79d44ef..21b4695 100644
--- src/fuser.c --- src/fuser.c
+++ src/fuser.c +++ src/fuser.c
@@ -65,7 +65,7 @@ @@ -65,7 +65,7 @@
@ -102,7 +102,7 @@ index dd928d2..d08f7a9 100644
#include "comm.h" #include "comm.h"
//#define DEBUG 1 //#define DEBUG 1
@@ -127,10 +127,6 @@ static int get_fdinfo(const pid_t pid, const char *fd, struct fdinfo *info); @@ -128,10 +128,6 @@ static ino_t get_namespace(const pid_t pid);
static int get_mountid(const char *path); static int get_mountid(const char *path);
#endif #endif
static int find_mountpoint(const char *path, mntinfo_t **mountinfo); static int find_mountpoint(const char *path, mntinfo_t **mountinfo);
@ -113,7 +113,7 @@ index dd928d2..d08f7a9 100644
static char *expandpath(const char *path); static char *expandpath(const char *path);
static struct unixsocket_list *unixsockets = NULL; static struct unixsocket_list *unixsockets = NULL;
static struct names *names_head = NULL, *names_tail = NULL; static struct names *names_head = NULL, *names_tail = NULL;
@@ -518,7 +514,7 @@ int parse_file(struct names *this_name, struct inode_list **ino_list, @@ -519,7 +515,7 @@ int parse_file(struct names *this_name, struct inode_list **ino_list,
free(this_name->filename); free(this_name->filename);
this_name->filename = strdup(new); this_name->filename = strdup(new);
} }
@ -122,7 +122,7 @@ index dd928d2..d08f7a9 100644
find_mountpoint(this_name->filename, &mountinfo) != 0) { find_mountpoint(this_name->filename, &mountinfo) != 0) {
if (errno == ENOENT) if (errno == ENOENT)
fprintf(stderr, fprintf(stderr,
@@ -1252,9 +1248,7 @@ int main(int argc, char *argv[]) @@ -1253,9 +1249,7 @@ int main(int argc, char *argv[])
opts |= OPT_INTERACTIVE; opts |= OPT_INTERACTIVE;
break; break;
case 'I': case 'I':
@ -132,7 +132,7 @@ index dd928d2..d08f7a9 100644
break; break;
case 'k': case 'k':
opts |= OPT_KILL; opts |= OPT_KILL;
@@ -1320,10 +1314,11 @@ int main(int argc, char *argv[]) @@ -1321,10 +1315,11 @@ int main(int argc, char *argv[])
continue; continue;
} }
@ -147,7 +147,7 @@ index dd928d2..d08f7a9 100644
/* an option */ /* an option */
/* Not an option, must be a file specification */ /* Not an option, must be a file specification */
if ((this_name = malloc(sizeof(struct names))) == NULL) if ((this_name = malloc(sizeof(struct names))) == NULL)
@@ -1643,7 +1638,7 @@ static struct stat *get_pidstat(const pid_t pid, const char *filename, int *id) @@ -1644,7 +1639,7 @@ static struct stat *get_pidstat(const pid_t pid, const char *filename, int *id)
if ((st = (struct stat *)malloc(sizeof(struct stat))) == NULL) if ((st = (struct stat *)malloc(sizeof(struct stat))) == NULL)
return NULL; return NULL;
snprintf(pathname, PATH_MAX-1, "/proc/%d/%s", pid, filename); snprintf(pathname, PATH_MAX-1, "/proc/%d/%s", pid, filename);
@ -156,7 +156,7 @@ index dd928d2..d08f7a9 100644
free(st); free(st);
return NULL; return NULL;
} }
@@ -1690,7 +1685,7 @@ check_dir(const pid_t pid, const char *dirname, struct device_list *dev_head, @@ -1698,7 +1693,7 @@ check_dir(const pid_t pid, const char *dirname, struct device_list *dev_head,
snprintf(filepath, sizeof filepath - 1, "/proc/%d/%s/%s", snprintf(filepath, sizeof filepath - 1, "/proc/%d/%s/%s",
pid, dirname, direntry->d_name); pid, dirname, direntry->d_name);
@ -165,7 +165,7 @@ index dd928d2..d08f7a9 100644
if (errno != ENOENT && errno != ENOTDIR) { if (errno != ENOENT && errno != ENOTDIR) {
fprintf(stderr, _("Cannot stat file %s: %s\n"), fprintf(stderr, _("Cannot stat file %s: %s\n"),
filepath, strerror(errno)); filepath, strerror(errno));
@@ -1767,7 +1762,7 @@ check_dir(const pid_t pid, const char *dirname, struct device_list *dev_head, @@ -1775,7 +1770,7 @@ check_dir(const pid_t pid, const char *dirname, struct device_list *dev_head,
if (thedev != ino_tmp->device) if (thedev != ino_tmp->device)
continue; continue;
if (!st.st_ino if (!st.st_ino
@ -174,7 +174,7 @@ index dd928d2..d08f7a9 100644
fprintf(stderr, fprintf(stderr,
_("Cannot stat file %s: %s\n"), _("Cannot stat file %s: %s\n"),
filepath, strerror(errno)); filepath, strerror(errno));
@@ -1865,11 +1860,11 @@ static uid_t getpiduid(const pid_t pid) @@ -1873,11 +1868,11 @@ static uid_t getpiduid(const pid_t pid)
if (asprintf(&pathname, "/proc/%d", pid) < 0) if (asprintf(&pathname, "/proc/%d", pid) < 0)
return 0; return 0;
@ -190,7 +190,7 @@ index dd928d2..d08f7a9 100644
return st.st_uid; return st.st_uid;
} }
@@ -1907,7 +1902,7 @@ void fill_unix_cache(struct unixsocket_list **unixsocket_head) @@ -1915,7 +1910,7 @@ void fill_unix_cache(struct unixsocket_list **unixsocket_head)
path = scanned_path; path = scanned_path;
if (*scanned_path == '@') if (*scanned_path == '@')
scanned_path++; scanned_path++;
@ -199,7 +199,7 @@ index dd928d2..d08f7a9 100644
free(path); free(path);
continue; continue;
} }
@@ -2042,7 +2037,7 @@ static dev_t find_net_dev(void) @@ -2050,7 +2045,7 @@ static dev_t find_net_dev(void)
fprintf(stderr, _("Cannot open a network socket.\n")); fprintf(stderr, _("Cannot open a network socket.\n"));
return -1; return -1;
} }
@ -208,7 +208,7 @@ index dd928d2..d08f7a9 100644
fprintf(stderr, _("Cannot find socket's device number.\n")); fprintf(stderr, _("Cannot find socket's device number.\n"));
close(skt); close(skt);
return -1; return -1;
@@ -2079,7 +2074,7 @@ scan_knfsd(struct names *names_head, struct inode_list *ino_head, @@ -2087,7 +2082,7 @@ scan_knfsd(struct names *names_head, struct inode_list *ino_head,
if ((find_space = strpbrk(line, " \t")) == NULL) if ((find_space = strpbrk(line, " \t")) == NULL)
continue; continue;
*find_space = '\0'; *find_space = '\0';
@ -217,7 +217,7 @@ index dd928d2..d08f7a9 100644
continue; continue;
} }
/* Scan the devices */ /* Scan the devices */
@@ -2113,7 +2108,7 @@ scan_mounts(struct names *names_head, struct inode_list *ino_head, @@ -2121,7 +2116,7 @@ scan_mounts(struct names *names_head, struct inode_list *ino_head,
mntinfo_t *mnt = list_entry(ptr, mntinfo_t); mntinfo_t *mnt = list_entry(ptr, mntinfo_t);
const char *find_mountp = mnt->mpoint; const char *find_mountp = mnt->mpoint;
@ -226,7 +226,7 @@ index dd928d2..d08f7a9 100644
continue; continue;
/* Scan the devices */ /* Scan the devices */
@@ -2163,7 +2158,7 @@ scan_swaps(struct names *names_head, struct inode_list *ino_head, @@ -2171,7 +2166,7 @@ scan_swaps(struct names *names_head, struct inode_list *ino_head,
if (*find_space == '\0') if (*find_space == '\0')
continue; continue;
} }
@ -235,7 +235,7 @@ index dd928d2..d08f7a9 100644
continue; continue;
} }
/* Scan the devices */ /* Scan the devices */
@@ -2260,10 +2255,10 @@ init_mntinfo(void) @@ -2268,10 +2263,10 @@ init_mntinfo(void)
&mid, &parid, &maj, &min, &mpoint[0], &type[0], &devname[0]) == 7) { &mid, &parid, &maj, &min, &mpoint[0], &type[0], &devname[0]) == 7) {
struct stat st; struct stat st;
mntinf = add_mntinfo(mpoint, type, mid, parid, makedev(maj, min)); mntinf = add_mntinfo(mpoint, type, mid, parid, makedev(maj, min));
@ -248,7 +248,7 @@ index dd928d2..d08f7a9 100644
mntinf->dev = st.st_dev; /* stat(2) on binary does not see subvol dev */ mntinf->dev = st.st_dev; /* stat(2) on binary does not see subvol dev */
} }
} }
@@ -2275,7 +2270,7 @@ init_mntinfo(void) @@ -2283,7 +2278,7 @@ init_mntinfo(void)
parid = -1; parid = -1;
while (fscanf (mnt, "%s %s %s %*[^\n]", &devname[0], &mpoint[0], &type[0]) == 3) { while (fscanf (mnt, "%s %s %s %*[^\n]", &devname[0], &mpoint[0], &type[0]) == 3) {
struct stat st; struct stat st;
@ -257,7 +257,7 @@ index dd928d2..d08f7a9 100644
if (errno != EACCES) { if (errno != EACCES) {
fprintf(stderr, _("Cannot stat %s: %s\n"), fprintf(stderr, _("Cannot stat %s: %s\n"),
mpoint, strerror(errno)); mpoint, strerror(errno));
@@ -2284,7 +2279,7 @@ init_mntinfo(void) @@ -2292,7 +2287,7 @@ init_mntinfo(void)
st.st_dev = (dev_t)-1; st.st_dev = (dev_t)-1;
} }
mntinf = add_mntinfo(mpoint, type, mid++, parid, st.st_dev); mntinf = add_mntinfo(mpoint, type, mid++, parid, st.st_dev);
@ -266,7 +266,7 @@ index dd928d2..d08f7a9 100644
if (st.st_rdev != 0 && mntinf->dev != st.st_rdev) if (st.st_rdev != 0 && mntinf->dev != st.st_rdev)
mntinf->vol = st.st_rdev; mntinf->vol = st.st_rdev;
} }
@@ -2308,7 +2303,7 @@ get_fdinfo(const pid_t pid, const char *fd, struct fdinfo *info) @@ -2316,7 +2311,7 @@ get_fdinfo(const pid_t pid, const char *fd, struct fdinfo *info, const ino_t ns)
struct stat st; struct stat st;
if (!mynamespace) { if (!mynamespace) {
@ -275,25 +275,25 @@ index dd928d2..d08f7a9 100644
fprintf(stderr, _("Cannot stat %s: %s\n"), fprintf(stderr, _("Cannot stat %s: %s\n"),
"/proc/self/ns/mnt", strerror(errno)); "/proc/self/ns/mnt", strerror(errno));
exit(1); exit(1);
@@ -2343,7 +2338,7 @@ get_fdinfo(const pid_t pid, const char *fd, struct fdinfo *info) @@ -2365,7 +2360,7 @@ out:
out:
# if defined(HAS_NAME_TO_HANDLE_AT)
snprintf(pathname, 256, "/proc/%d/ns/mnt", pid);
- if (stat(pathname, &st) == 0 && mynamespace != st.st_ino) {
+ if (statn(pathname, STATX_INO, &st) == 0 && mynamespace != st.st_ino) {
char *realname;
snprintf(pathname, 256, "/proc/%d/fd/%s", pid, fd);
realname = expandpath(pathname);
@@ -2358,7 +2353,7 @@ out:
struct stat lst; struct stat lst;
snprintf(pathname, 256, "/proc/%d/fd/%s", pid, fd); snprintf(pathname, sizeof(pathname)-1, "/proc/%d/fd/%s", pid, fd);
- if (!flags && lstat(pathname, &lst) == 0) { - if (!flags && lstat(pathname, &lst) == 0) {
+ if (!flags && lstatn(pathname, STATX_MODE, &lst) == 0) { + if (!flags && lstatn(pathname, STATX_MODE, &lst) == 0) {
if (lst.st_mode & S_IWUSR) if (lst.st_mode & S_IWUSR)
info->flags |= O_WRONLY; info->flags |= O_WRONLY;
ret++; ret++;
@@ -2431,7 +2426,7 @@ find_mountpoint(const char *path, mntinfo_t **mountinfo) @@ -2392,7 +2387,7 @@ get_namespace(const pid_t pid)
char pathname[512];
struct stat st;
snprintf(pathname, sizeof(pathname)-1, "/proc/%d/ns/mnt", pid);
- if (stat(pathname, &st) == 0)
+ if (statn(pathname, STATX_INO, &st) == 0)
return st.st_ino;
return -1;
}
@@ -2449,7 +2444,7 @@ find_mountpoint(const char *path, mntinfo_t **mountinfo)
/* could be a chroot or a container */ /* could be a chroot or a container */
@ -302,7 +302,7 @@ index dd928d2..d08f7a9 100644
if (errno != EACCES) { if (errno != EACCES) {
fprintf(stderr, _("Cannot stat %s: %s\n"), fprintf(stderr, _("Cannot stat %s: %s\n"),
path, strerror(errno)); path, strerror(errno));
@@ -2463,7 +2458,7 @@ find_mountpoint(const char *path, mntinfo_t **mountinfo) @@ -2481,7 +2476,7 @@ find_mountpoint(const char *path, mntinfo_t **mountinfo)
/* could be a chroot or a container */ /* could be a chroot or a container */
@ -311,7 +311,7 @@ index dd928d2..d08f7a9 100644
if (errno != EACCES) { if (errno != EACCES) {
fprintf(stderr, _("Cannot stat %s: %s\n"), fprintf(stderr, _("Cannot stat %s: %s\n"),
use, strerror(errno)); use, strerror(errno));
@@ -2501,49 +2496,6 @@ out: @@ -2519,49 +2514,6 @@ out:
return ret; return ret;
} }

View File

@ -1,3 +1,11 @@
-------------------------------------------------------------------
Tue Feb 1 12:39:16 UTC 2022 - Dr. Werner Fink <werner@suse.de>
- Change patch 0001-Use-mountinfo-to-be-able-to-use-the-mount-identity.patch
* Determine the namespace of a process only once to speed
up the parsing of fdinfo (bsc#1194172).
- Adopt patch 0002-Use-new-statx-2-system-call-to-avoid-hangs-on-NFS.patch
------------------------------------------------------------------- -------------------------------------------------------------------
Thu Jan 20 13:57:13 UTC 2022 - Dr. Werner Fink <werner@suse.de> Thu Jan 20 13:57:13 UTC 2022 - Dr. Werner Fink <werner@suse.de>