rework former submit

OBS-URL: https://build.opensuse.org/package/show/Base:System/psmisc?expand=0&rev=126
This commit is contained in:
Dr. Werner Fink 2021-01-14 12:02:55 +00:00 committed by Git OBS Bridge
parent 7391e6ffe4
commit 9da1cfeb4c
6 changed files with 242 additions and 774 deletions

View File

@ -1,17 +1,32 @@
diff -ru old/configure.ac new/configure.ac
--- old/configure.ac 2019-11-12 11:23:38.000000000 +0100
+++ new/configure.ac 2020-12-31 10:49:48.159279790 +0100
@@ -27,6 +27,9 @@
AC_DEFINE([WITH_SELINUX], [1], [Use Security-Enhanced Linux features])
AC_CHECK_LIB([selinux], [getfilecon], [SELINUX_LIB=-lselinux], [
AC_MSG_ERROR([Cannot find selinux static library]) ])
+ echo 'set has_selinux 1' > testsuite/selinux.exp
+else
+ echo 'set has_selinux 0' > testsuite/selinux.exp
fi
AC_SUBST([SELINUX_LIB])
@@ -44,6 +47,19 @@
From e5d42c39541c94c00d97ed490add24bc898ebe0a Mon Sep 17 00:00:00 2001
From: Werner Fink <werner@suse.de>
Date: Wed, 13 Jan 2021 11:59:24 +0100
Subject: [PATCH] Use mountinfo to be able to use the mount identity
which allows to distinguish different mounts with the
same device number as it happens with NFS shares.
Smaller cleanup as support of chroot environments
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 various subvolumes
On BtrFS stat(2) on binary does not see subvol dev
Allow not unique mounts as well as not unique mountpoint
Signed-off-by: Werner Fink <werner@suse.de>
---
configure.ac | 15 +
src/fuser.c | 643 ++++++++++++++++++++++++++++++++++++++++++++--------------
src/fuser.h | 27 +-
src/timeout.c | 5
4 files changed, 530 insertions(+), 160 deletions(-)
--- configure.ac
+++ configure.ac 2021-01-14 11:14:51.192122696 +0000
@@ -44,6 +44,19 @@ if test "$enable_timeout_stat" = "static
fi
AM_CONDITIONAL([WANT_TIMEOUT_STAT], [test "$enable_timeout_stat" = "static"])
@ -31,7 +46,7 @@ diff -ru old/configure.ac new/configure.ac
# Use string search for network based file systems but only if the system
# has /proc/self/mountinfo
AC_SUBST([WITH_MOUNTINFO_LIST])
@@ -85,7 +101,7 @@
@@ -85,7 +98,7 @@ dnl Checks for header files.
AC_HEADER_DIRENT
AC_HEADER_STDC
AC_HEADER_SYS_WAIT
@ -40,10 +55,8 @@ diff -ru old/configure.ac new/configure.ac
dnl Checks for typedefs, structures, and compiler characteristics.
AC_C_CONST
Only in new: .idea
diff -ru old/src/fuser.c new/src/fuser.c
--- old/src/fuser.c 2019-11-12 11:23:38.000000000 +0100
+++ new/src/fuser.c 2020-12-31 11:02:04.273256080 +0100
--- src/fuser.c
+++ src/fuser.c 2021-01-14 11:22:51.546798981 +0000
@@ -32,6 +32,10 @@
#include <stdlib.h>
#include <string.h>
@ -55,7 +68,7 @@ diff -ru old/src/fuser.c new/src/fuser.c
#include <sys/param.h>
#include <sys/types.h>
#include <sys/stat.h>
@@ -79,7 +83,7 @@
@@ -79,7 +83,7 @@ static void check_map(const pid_t pid, c
struct device_list *dev_head,
struct inode_list *ino_head, const uid_t uid,
const char access);
@ -64,7 +77,7 @@ diff -ru old/src/fuser.c new/src/fuser.c
static uid_t getpiduid(const pid_t pid);
static int print_matches(struct names *names_head, const opt_type opts,
const int sig_number);
@@ -88,9 +92,9 @@
@@ -88,9 +92,9 @@ static int kill_matched_proc(struct proc
/*int parse_mount(struct names *this_name, struct device_list **dev_list);*/
static void add_device(struct device_list **dev_list,
@ -77,7 +90,7 @@ diff -ru old/src/fuser.c new/src/fuser.c
static void atexit_clear_unix_cache();
static dev_t find_net_dev(void);
static void scan_procs(struct names *names_head, struct inode_list *ino_head,
@@ -109,9 +113,12 @@
@@ -109,9 +113,12 @@ static void debug_match_lists(struct nam
struct device_list *dev_head);
#endif
@ -91,7 +104,7 @@ diff -ru old/src/fuser.c new/src/fuser.c
static int mntstat(const char *path, struct stat *buf);
#endif
static stat_t thestat = stat;
@@ -202,6 +209,7 @@
@@ -202,6 +209,7 @@ scan_procs(struct names *names_head, str
struct stat *cwd_stat = NULL;
struct stat *exe_stat = NULL;
struct stat *root_stat = NULL;
@ -99,7 +112,7 @@ diff -ru old/src/fuser.c new/src/fuser.c
if (topproc_dent->d_name[0] < '0' || topproc_dent->d_name[0] > '9') /* Not a process */
continue;
@@ -211,9 +219,9 @@
@@ -211,9 +219,9 @@ scan_procs(struct names *names_head, str
continue;
uid = getpiduid(pid);
@ -112,7 +125,7 @@ diff -ru old/src/fuser.c new/src/fuser.c
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;
@@ -221,21 +229,33 @@
@@ -221,21 +229,33 @@ scan_procs(struct names *names_head, str
/* Scan the devices */
for (dev_tmp = dev_head; dev_tmp != NULL;
dev_tmp = dev_tmp->next) {
@ -156,7 +169,7 @@ diff -ru old/src/fuser.c new/src/fuser.c
if (exe_stat
&& exe_stat->st_dev == ino_tmp->device
&& exe_stat->st_ino == ino_tmp->inode)
@@ -244,7 +264,7 @@
@@ -244,7 +264,7 @@ scan_procs(struct names *names_head, str
}
if (root_dev == ino_tmp->device) {
if (!root_stat)
@ -165,7 +178,7 @@ diff -ru old/src/fuser.c new/src/fuser.c
if (root_stat
&& root_stat->st_dev == ino_tmp->device
&& root_stat->st_ino == ino_tmp->inode)
@@ -253,7 +273,7 @@
@@ -253,7 +273,7 @@ scan_procs(struct names *names_head, str
}
if (cwd_dev == ino_tmp->device) {
if (!cwd_stat)
@ -174,7 +187,7 @@ diff -ru old/src/fuser.c new/src/fuser.c
if (cwd_stat
&& cwd_stat->st_dev == ino_tmp->device
&& cwd_stat->st_ino == ino_tmp->inode)
@@ -294,18 +314,42 @@
@@ -294,18 +314,42 @@ add_inode(struct inode_list **ino_list,
ino_tmp->name = this_name;
ino_tmp->device = device;
ino_tmp->inode = inode;
@ -218,7 +231,7 @@ diff -ru old/src/fuser.c new/src/fuser.c
if ((dev_tmp =
(struct device_list *)malloc(sizeof(struct device_list))) == NULL)
@@ -313,6 +357,10 @@
@@ -313,6 +357,10 @@ add_device(struct device_list **dev_list
dev_head = *dev_list;
dev_tmp->name = this_name;
dev_tmp->device = device;
@ -229,7 +242,7 @@ diff -ru old/src/fuser.c new/src/fuser.c
dev_tmp->next = dev_head;
*dev_list = dev_tmp;
}
@@ -454,13 +502,15 @@
@@ -454,13 +502,15 @@ add_special_proc(struct names *name_list
int parse_file(struct names *this_name, struct inode_list **ino_list,
const opt_type opts)
{
@ -246,7 +259,7 @@ diff -ru old/src/fuser.c new/src/fuser.c
if (errno == ENOENT)
fprintf(stderr,
_("Specified filename %s does not exist.\n"),
@@ -470,10 +520,12 @@
@@ -470,10 +520,12 @@ int parse_file(struct names *this_name,
this_name->filename, strerror(errno));
return -1;
}
@ -261,7 +274,7 @@ diff -ru old/src/fuser.c new/src/fuser.c
#endif /* DEBUG */
add_inode(ino_list, this_name, this_name->st.st_dev,
this_name->st.st_ino);
@@ -505,12 +557,45 @@
@@ -505,12 +557,45 @@ parse_mounts(struct names *this_name, st
const opt_type opts)
{
dev_t match_device;
@ -308,16 +321,7 @@ diff -ru old/src/fuser.c new/src/fuser.c
return 0;
}
@@ -624,7 +709,7 @@
fprintf(stderr, _("Unknown local port AF %d\n"),
res->ai_family);
freeaddrinfo(res);
- free(lcl_port_str);
+ free(lcl_port_str);
return -1;
}
freeaddrinfo(res);
@@ -687,10 +772,12 @@
@@ -687,10 +772,12 @@ int parse_inet(struct names *this_name,
break;
#endif
}
@ -333,7 +337,7 @@ diff -ru old/src/fuser.c new/src/fuser.c
}
return 1;
}
@@ -957,6 +1044,21 @@
@@ -957,6 +1044,21 @@ free_inodes(struct inode_list **match_in
/*
* Free up structures allocated in add_device
*/
@ -355,7 +359,7 @@ diff -ru old/src/fuser.c new/src/fuser.c
static void
free_devices(struct device_list **match_devices)
{
@@ -964,6 +1066,8 @@
@@ -964,6 +1066,8 @@ free_devices(struct device_list **match_
device_tmp = *match_devices;
while(device_tmp != NULL) {
@ -364,7 +368,7 @@ diff -ru old/src/fuser.c new/src/fuser.c
device_next = device_tmp->next;
free(device_tmp);
device_tmp = device_next;
@@ -1166,16 +1270,11 @@
@@ -1166,16 +1270,11 @@ int main(int argc, char *argv[])
skip_argv = 1;
//while(option != '\0') option++;
if (strcmp(argv[argc_cnt], "tcp") == 0)
@ -386,7 +390,7 @@ diff -ru old/src/fuser.c new/src/fuser.c
else
usage(_
("Invalid namespace name"));
@@ -1215,7 +1314,7 @@
@@ -1215,7 +1314,7 @@ int main(int argc, char *argv[])
}
#if defined(WITH_MOUNTINFO_LIST)
@ -395,7 +399,7 @@ diff -ru old/src/fuser.c new/src/fuser.c
thestat = mntstat;
#endif
/* an option */
@@ -1529,7 +1628,7 @@
@@ -1529,7 +1628,7 @@ print_matches(struct names *names_head,
}
@ -404,7 +408,7 @@ diff -ru old/src/fuser.c new/src/fuser.c
{
char pathname[256];
struct stat *st;
@@ -1541,6 +1640,15 @@
@@ -1541,6 +1640,15 @@ static struct stat *get_pidstat(const pi
free(st);
return NULL;
}
@ -420,7 +424,7 @@ diff -ru old/src/fuser.c new/src/fuser.c
return st;
}
@@ -1555,7 +1663,8 @@
@@ -1555,7 +1663,8 @@ check_dir(const pid_t pid, const char *d
struct inode_list *ino_tmp;
struct device_list *dev_tmp;
struct unixsocket_list *sock_tmp;
@ -430,7 +434,7 @@ diff -ru old/src/fuser.c new/src/fuser.c
char *dirpath;
char filepath[PATH_MAX];
@@ -1594,11 +1703,27 @@
@@ -1594,11 +1703,29 @@ check_dir(const pid_t pid, const char *d
}
for (dev_tmp = dev_head; dev_tmp != NULL;
dev_tmp = dev_tmp->next) {
@ -438,6 +442,7 @@ diff -ru old/src/fuser.c new/src/fuser.c
+ 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 */
@ -446,10 +451,11 @@ diff -ru old/src/fuser.c new/src/fuser.c
+ break;
+ }
+ }
+
+
+ if (!found)
+ continue;
+ }
+
+ if (get_fdinfo(pid, direntry->d_name, &fd) != 0)
+ continue;
+ if (fd.mnt_id != dev_tmp->mnt_id)
@ -461,7 +467,7 @@ diff -ru old/src/fuser.c new/src/fuser.c
add_matched_proc(dev_tmp->name,
pid, uid,
ACCESS_FILEWR |
@@ -1620,9 +1745,10 @@
@@ -1620,9 +1747,10 @@ check_dir(const pid_t pid, const char *d
continue;
}
if (st.st_ino == ino_tmp->inode) {
@ -474,7 +480,7 @@ diff -ru old/src/fuser.c new/src/fuser.c
add_matched_proc(ino_tmp->name,
pid, uid,
ACCESS_FILEWR |
@@ -1651,31 +1777,54 @@
@@ -1651,31 +1779,54 @@ check_map(const pid_t pid, const char *f
FILE *fp;
unsigned long long tmp_inode;
unsigned int tmp_maj, tmp_min;
@ -539,7 +545,7 @@ diff -ru old/src/fuser.c new/src/fuser.c
}
fclose(fp);
}
@@ -1699,6 +1848,7 @@
@@ -1699,6 +1850,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
*/
@ -547,16 +553,16 @@ diff -ru old/src/fuser.c new/src/fuser.c
void fill_unix_cache(struct unixsocket_list **unixsocket_head)
{
FILE *fp;
@@ -1715,6 +1865,8 @@
@@ -1715,6 +1867,8 @@ void fill_unix_cache(struct unixsocket_l
while (fgets(line, BUFSIZ, fp) != NULL) {
char *path;
char *scanned_path = NULL;
+ int mnt_id = -1;
+ mntinfo_t *mountinfo;
+ int mnt_id = -1;
+ mntinfo_t *mountinfo;
if (sscanf(line, "%*x: %*x %*x %*x %*x %*d %llu %ms",
&scanned_inode, &scanned_path) != 2) {
if (scanned_path)
@@ -1730,6 +1882,8 @@
@@ -1730,6 +1884,8 @@ void fill_unix_cache(struct unixsocket_l
free(path);
continue;
}
@ -565,7 +571,7 @@ diff -ru old/src/fuser.c new/src/fuser.c
if ((newsocket = (struct unixsocket_list *)
malloc(sizeof(struct unixsocket_list))) == NULL) {
free(path);
@@ -1738,6 +1892,7 @@
@@ -1738,6 +1894,7 @@ void fill_unix_cache(struct unixsocket_l
newsocket->sun_name = strdup(scanned_path);
newsocket->inode = st.st_ino;
newsocket->dev = st.st_dev;
@ -573,7 +579,7 @@ diff -ru old/src/fuser.c new/src/fuser.c
newsocket->net_inode = scanned_inode;
newsocket->next = *unixsocket_head;
*unixsocket_head = newsocket;
@@ -1750,6 +1905,7 @@
@@ -1750,6 +1907,7 @@ void fill_unix_cache(struct unixsocket_l
/*
* Free up the list of Unix sockets
*/
@ -581,7 +587,7 @@ diff -ru old/src/fuser.c new/src/fuser.c
void clear_unix_cache(struct unixsocket_list **unixsocket_head)
{
while(*unixsocket_head != NULL) {
@@ -1921,34 +2077,24 @@
@@ -1921,34 +2079,21 @@ scan_mounts(struct names *names_head, st
{
struct device_list *dev_tmp;
struct inode_list *ino_tmp;
@ -590,14 +596,14 @@ diff -ru old/src/fuser.c new/src/fuser.c
- char *find_mountp;
- char *find_space;
struct stat st;
if ( (ino_head == NULL) && (dev_head == NULL) )
return;
+ list_t *ptr;
+ list_for_each(ptr, &mntinfo) {
+ mntinfo_t *mnt = list_entry(ptr, mntinfo_t);
+ const char *find_mountp = mnt->mpoint;
- if ( (ino_head == NULL) && (dev_head == NULL) )
- return;
-
+ list_for_each(ptr, &mntinfo) {
+ mntinfo_t *mnt = list_entry(ptr, mntinfo_t);
+ const char *find_mountp = mnt->mpoint;
- if ((fp = fopen(PROC_MOUNTS, "r")) == NULL) {
- fprintf(stderr, "Cannot open %s\n", PROC_MOUNTS);
@ -605,26 +611,26 @@ diff -ru old/src/fuser.c new/src/fuser.c
- }
- while (fgets(line, BUFSIZ, fp) != NULL) {
- if ((find_mountp = strchr(line, ' ')) == NULL)
+ if (timeout(thestat, find_mountp, &st, 5) != 0)
continue;
- continue;
- find_mountp++;
- if ((find_space = strchr(find_mountp, ' ')) == NULL)
- continue;
- *find_space = '\0';
- if (timeout(thestat, find_mountp, &st, 5) != 0) {
- continue;
+ if (timeout(thestat, find_mountp, &st, 5) != 0)
continue;
- }
+
/* Scan the devices */
for (dev_tmp = dev_head; dev_tmp != NULL;
dev_tmp = dev_tmp->next) {
- if (st.st_dev == dev_tmp->device)
+ if (st.st_dev == dev_tmp->device &&
+ mnt->id == dev_tmp->mnt_id)
+ if (st.st_dev == dev_tmp->device &&
+ mnt->id == dev_tmp->mnt_id)
add_special_proc(dev_tmp->name, PTYPE_MOUNT, 0,
find_mountp);
}
@@ -1960,7 +2106,6 @@
@@ -1960,7 +2105,6 @@ scan_mounts(struct names *names_head, st
find_mountp);
}
}
@ -632,7 +638,7 @@ diff -ru old/src/fuser.c new/src/fuser.c
}
static void
@@ -2013,16 +2158,44 @@
@@ -2013,16 +2157,44 @@ scan_swaps(struct names *names_head, str
fclose(fp);
}
@ -681,7 +687,7 @@ diff -ru old/src/fuser.c new/src/fuser.c
{
list_t *ptr, *tmp;
@@ -2033,72 +2206,247 @@
@@ -2033,72 +2205,247 @@ static void clear_mntinfo(void)
}
}
@ -741,7 +747,7 @@ diff -ru old/src/fuser.c new/src/fuser.c
+ mntinf->dev = st.st_dev; /* stat(2) on binary does not see subvol dev */
+ }
+ }
}
+ }
+#else
+ if ((mnt = fopen(PROC_MOUNTS, "r")) == (FILE *) 0)
+ return;
@ -752,7 +758,7 @@ diff -ru old/src/fuser.c new/src/fuser.c
+ if (stat(mpoint, &st) != 0) {
+ if (errno != EACCES) {
+ fprintf(stderr, _("Cannot stat %s: %s\n"),
+ mnt->mpoint, strerror(errno));
+ mpoint, strerror(errno));
+ exit(1);
+ }
+ st.st_dev = (dev_t)-1;
@ -762,7 +768,7 @@ diff -ru old/src/fuser.c new/src/fuser.c
+ if (st.st_rdev != 0 && mntinf->dev != st.st_rdev)
+ mntinf->vol = st.st_rdev;
+ }
+ }
}
+#endif
fclose(mnt);
+}
@ -772,11 +778,11 @@ diff -ru old/src/fuser.c new/src/fuser.c
+{
+ int ret = 0;
+ char pathname[256];
+ int mnt_id = 0, flags = 0;
+#if defined(HAS_FDINFO)
+ const static char delimiters[] = ": \t\n";
+ char line[BUFSIZ];
+ FILE *fp;
+ int mnt_id = 0, flags = 0;
+
+ snprintf(pathname, 256, "/proc/%d/fdinfo/%s", pid, fd);
+ if ((fp = fopen(pathname, "r")) == NULL)
@ -943,11 +949,11 @@ diff -ru old/src/fuser.c new/src/fuser.c
- 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;
@ -974,7 +980,7 @@ diff -ru old/src/fuser.c new/src/fuser.c
/*
* Determine device of links below /proc/
*/
@@ -2106,8 +2454,7 @@
@@ -2106,8 +2453,7 @@ static int mntstat(const char *path, str
{
char name[PATH_MAX + 1];
const char *use;
@ -984,7 +990,7 @@ diff -ru old/src/fuser.c new/src/fuser.c
if ((use = realpath(path, name)) == NULL || *use != '/')
{
@@ -2119,27 +2466,26 @@
@@ -2119,27 +2465,26 @@ static int mntstat(const char *path, str
errno = 0;
return stat(path, buf);
}
@ -1030,16 +1036,15 @@ diff -ru old/src/fuser.c new/src/fuser.c
}
#endif /* WITH_MOUNTINFO_LIST */
diff -ru old/src/fuser.h new/src/fuser.h
--- old/src/fuser.h 2019-11-12 11:23:38.000000000 +0100
+++ new/src/fuser.h 2020-12-31 10:49:48.159279790 +0100
@@ -37,10 +37,16 @@
--- src/fuser.h
+++ src/fuser.h 2021-01-14 11:16:13.262529434 +0000
@@ -37,10 +37,16 @@ struct procs {
#define PTYPE_KNFSD 2
#define PTYPE_SWAP 3
+struct fdinfo {
+ mode_t flags;
+ int mnt_id;
+ mode_t flags;
+ int mnt_id;
+};
+
struct names {
@ -1051,7 +1056,7 @@ diff -ru old/src/fuser.h new/src/fuser.h
struct procs *matched_procs;
struct names *next;
};
@@ -65,12 +71,21 @@
@@ -65,12 +71,21 @@ struct inode_list {
struct names *name;
dev_t device;
ino_t inode;
@ -1073,7 +1078,7 @@ diff -ru old/src/fuser.h new/src/fuser.h
struct device_list *next;
};
@@ -79,6 +94,7 @@
@@ -79,6 +94,7 @@ struct unixsocket_list {
ino_t inode;
ino_t net_inode;
dev_t dev;
@ -1081,7 +1086,7 @@ diff -ru old/src/fuser.h new/src/fuser.h
struct unixsocket_list *next;
};
@@ -87,18 +103,16 @@
@@ -87,18 +103,16 @@ struct mount_list {
struct mount_list *next;
};
@ -1103,43 +1108,31 @@ diff -ru old/src/fuser.h new/src/fuser.h
#define NAMESPACE_FILE 0
#define NAMESPACE_TCP 1
@@ -109,5 +123,6 @@
@@ -109,5 +123,6 @@ typedef struct mntinfo_s {
#endif /* PATH_MAX */
#define KNFSD_EXPORTS "/proc/fs/nfs/exports"
+#define PROC_MOUNTINFO "/proc/self/mountinfo"
#define PROC_MOUNTS "/proc/mounts"
#define PROC_SWAPS "/proc/swaps"
diff -ru old/testsuite/killall.test/killall.exp new/testsuite/killall.test/killall.exp
--- old/testsuite/killall.test/killall.exp 2019-11-12 11:23:38.000000000 +0100
+++ new/testsuite/killall.test/killall.exp 2020-12-31 10:49:48.159279790 +0100
@@ -7,7 +7,11 @@
--- src/timeout.c
+++ src/timeout.c 2021-01-14 11:14:51.196122619 +0000
@@ -67,9 +67,6 @@
# ifndef constructor
# define constructor __constructor__
# endif
-# ifndef packed
-# define packed __packed__
-# endif
# ifndef inline
# define inline __inline__
# endif
@@ -107,7 +104,7 @@ typedef struct _handle {
stat_t function;
size_t len;
char path[0];
-} attribute((packed)) handle_t;
+} handle_t;
set test "killall with no arguments"
spawn $killall
+if { $has_selinux == 0 } {
expect_pass "$test" "^Usage: killall \\\[OPTION\\\]\\.\\.\\. \\\[--\\\] NAME\\.\\.\\."
+} else {
+expect_pass "$test" "^Usage: killall \\\[ -Z CONTEXT \\\] \\\[ -u USER \\\] \\\[ -y TIME \\\] \\\[ -o TIME \\\] \\\[ -eIgiqrvw \\\]"
+}
set test "killall list signals"
spawn $killall -l
diff -ru old/testsuite/Makefile.am new/testsuite/Makefile.am
--- old/testsuite/Makefile.am 2019-11-12 11:23:38.000000000 +0100
+++ new/testsuite/Makefile.am 2020-12-31 10:49:48.159279790 +0100
@@ -1,6 +1,8 @@
AUTOMAKE_OPTIONS = dejagnu
export DEJAGNU
+EXTRA_DEJAGNU_SITE_CONFIG=$(srcdir)/selinux.exp
+
# Programs that are expected across the board.
DEJATOOL = killall
DEJATOOL += pslog
@@ -9,5 +11,4 @@
DEJATOOL += fuser
endif
-
EXTRA_DIST =
/*
* Using a forked process for doing e.g. stat(2) system call as this

View File

@ -1,7 +1,33 @@
diff -ruN old/configure.ac new/configure.ac
--- old/configure.ac 2020-12-31 11:08:34.654310080 +0100
+++ new/configure.ac 2020-12-31 11:07:25.506123358 +0100
@@ -33,20 +33,6 @@
From 9f3910df62bcc1f726b8e84f9ffc40c4d7916eac Mon Sep 17 00:00:00 2001
From: Werner Fink <werner@suse.de>
Date: Thu, 14 Jan 2021 11:37:46 +0100
Subject: [PATCH] Use new statx(2) system call to avoid hangs on NFS
Signed-off-by: Werner Fink <werner@suse.de>
---
Makefile.am | 4 -
configure.ac | 38 +++++----------
src/fuser.c | 98 +++++++++-----------------------------
src/statx.c | 149 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
src/statx.h | 68 ++++++++++++++++++++++++++
5 files changed, 258 insertions(+), 99 deletions(-)
--- Makefile.am
+++ Makefile.am 2021-01-14 11:29:22.011223930 +0000
@@ -64,8 +64,8 @@ src_fuser_SOURCES = \
src/fuser.h \
src/lists.h
-if WANT_TIMEOUT_STAT
-src_fuser_SOURCES += src/timeout.c src/timeout.h
+if HAVE_SYSCALL_STATX
+src_fuser_SOURCES += src/statx.c src/statx.h
endif
src_fuser_LDADD = @LIBINTL@
src_killall_SOURCES = src/killall.c src/comm.h src/signals.c src/signals.h src/i18n.h
--- configure.ac
+++ configure.ac 2021-01-14 11:29:22.011223930 +0000
@@ -30,20 +30,6 @@ if test "$enable_selinux" = "yes"; then
fi
AC_SUBST([SELINUX_LIB])
@ -22,7 +48,7 @@ diff -ruN old/configure.ac new/configure.ac
# Use /proc/self/mountinfo if available
if test -e /proc/self/mountinfo ; then
AC_DEFINE([HAS_MOUNTINFO], [1], [System has /proc/self/mountinfo which can used instead /proc(/self)/mounts])
@@ -60,16 +46,20 @@
@@ -57,16 +43,20 @@ fi
AC_CHECK_FUNC([name_to_handle_at],[
AC_DEFINE([HAS_NAME_TO_HANDLE_AT], [1], [System has name_to_handle_at(2) system call])])
@ -53,181 +79,8 @@ diff -ruN old/configure.ac new/configure.ac
# Enable hardened compile and link flags
AC_ARG_ENABLE([harden_flags],
diff -ruN old/.idea/workspace.xml new/.idea/workspace.xml
--- old/.idea/workspace.xml 1970-01-01 01:00:00.000000000 +0100
+++ new/.idea/workspace.xml 2020-12-31 11:08:03.610226251 +0100
@@ -0,0 +1,43 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project version="4">
+ <component name="CMakeSettings">
+ <configurations>
+ <configuration PROFILE_NAME="Debug" CONFIG_NAME="Debug" ENABLED="true" />
+ </configurations>
+ </component>
+ <component name="ChangeListManager">
+ <list default="true" id="32bb1d9d-012c-4ff2-a826-575cbff55a80" name="Default Changelist" comment="" />
+ <option name="SHOW_DIALOG" value="false" />
+ <option name="HIGHLIGHT_CONFLICTS" value="true" />
+ <option name="HIGHLIGHT_NON_ACTIVE_CHANGELIST" value="false" />
+ <option name="LAST_RESOLUTION" value="IGNORE" />
+ </component>
+ <component name="ClangdSettings">
+ <option name="formatViaClangd" value="false" />
+ </component>
+ <component name="MacroExpansionManager">
+ <option name="directoryName" value="831eyv37" />
+ </component>
+ <component name="ProjectId" id="1mPxeVlOc4KkNnRmLJwHTLvU8lE" />
+ <component name="ProjectViewState">
+ <option name="hideEmptyMiddlePackages" value="true" />
+ <option name="showLibraryContents" value="true" />
+ </component>
+ <component name="PropertiesComponent">
+ <property name="RunOnceActivity.OpenProjectViewOnStart" value="true" />
+ <property name="RunOnceActivity.ShowReadmeOnStart" value="true" />
+ <property name="cf.first.check.clang-format" value="false" />
+ </component>
+ <component name="SpellCheckerSettings" RuntimeDictionaries="0" Folders="0" CustomDictionaries="0" DefaultDictionary="application-level" UseSingleDictionary="true" transferred="true" />
+ <component name="TaskManager">
+ <task active="true" id="Default" summary="Default task">
+ <changelist id="32bb1d9d-012c-4ff2-a826-575cbff55a80" name="Default Changelist" comment="" />
+ <created>1609409125494</created>
+ <option name="number" value="Default" />
+ <option name="presentableId" value="Default" />
+ <updated>1609409125494</updated>
+ <workItem from="1609409128547" duration="155000" />
+ </task>
+ <servers />
+ </component>
+</project>
\ No newline at end of file
diff -ruN old/Makefile.am new/Makefile.am
--- old/Makefile.am 2019-11-12 11:23:38.000000000 +0100
+++ new/Makefile.am 2020-12-31 11:07:25.506123358 +0100
@@ -64,8 +64,8 @@
src/fuser.h \
src/lists.h
-if WANT_TIMEOUT_STAT
-src_fuser_SOURCES += src/timeout.c src/timeout.h
+if HAVE_SYSCALL_STATX
+src_fuser_SOURCES += src/statx.c src/statx.h
endif
src_fuser_LDADD = @LIBINTL@
src_killall_SOURCES = src/killall.c src/comm.h src/signals.c src/signals.h src/i18n.h
diff -ruN old/Makefile.am.orig new/Makefile.am.orig
--- old/Makefile.am.orig 1970-01-01 01:00:00.000000000 +0100
+++ new/Makefile.am.orig 2019-11-12 11:23:38.000000000 +0100
@@ -0,0 +1,106 @@
+
+AM_CPPFLAGS = \
+ -Wall \
+ -DLOCALEDIR=\"$(localedir)\" \
+ -I$(top_builddir)/src \
+ @HARDEN_CFLAGS@
+
+AM_LDFLAGS = @HARDEN_LDFLAGS@
+
+ACLOCAL_AMFLAGS = -I m4
+
+SUBDIRS = \
+ doc \
+ po \
+ icons \
+ testsuite
+
+bin_PROGRAMS = \
+ src/killall \
+ src/pslog \
+ src/prtstat \
+ src/pstree
+
+if WANT_FUSER
+ bin_PROGRAMS += src/fuser
+endif
+if WANT_PEEKFD_I386
+ bin_PROGRAMS += src/peekfd
+ AM_CPPFLAGS += -DI386
+endif
+if WANT_PEEKFD_X86_64
+ bin_PROGRAMS += src/peekfd
+ AM_CPPFLAGS += -DX86_64
+endif
+if WANT_PEEKFD_PPC
+ bin_PROGRAMS += src/peekfd
+ AM_CPPFLAGS += -DPPC
+endif
+if WANT_PEEKFD_ARM
+ bin_PROGRAMS += src/peekfd
+ AM_CPPFLAGS += -DARM
+endif
+
+if WANT_PEEKFD_ARM64
+ bin_PROGRAMS += src/peekfd
+ AM_CPPFLAGS += -DARM64
+endif
+
+if WANT_PEEKFD_MIPS
+ bin_PROGRAMS += src/peekfd
+ AM_CPPFLAGS += -DMIPS
+endif
+if WANT_PEEKFD_M68K
+ bin_PROGRAMS += src/peekfd
+ AM_CPPFLAGS += -DM68K
+endif
+
+src_fuser_SOURCES = \
+ src/fuser.c \
+ src/comm.h \
+ src/signals.c \
+ src/signals.h \
+ src/i18n.h \
+ src/fuser.h \
+ src/lists.h
+
+if WANT_TIMEOUT_STAT
+src_fuser_SOURCES += src/timeout.c src/timeout.h
+endif
+src_fuser_LDADD = @LIBINTL@
+src_killall_SOURCES = src/killall.c src/comm.h src/signals.c src/signals.h src/i18n.h
+src_killall_LDADD = @LIBINTL@ @SELINUX_LIB@
+src_peekfd_SOURCES = src/peekfd.c
+src_peekfd_LDADD = @LIBINTL@
+src_pslog_SOURCES = src/pslog.c
+src_pstree_SOURCES = src/pstree.c src/comm.h src/i18n.h
+src_pstree_LDADD = @LIBINTL@ @TERMCAP_LIB@ @SELINUX_LIB@
+src_prtstat_SOURCES = src/prtstat.c src/prtstat.h
+src_prtstat_LDADD = @LIBINTL@
+nodist_src_killall_SOURCES = signames.h
+
+BUILT_SOURCES = src/signames.h
+
+EXTRA_DIST = src/signames.c README.md misc/git-version-gen
+
+CLEANFILES = src/signames.h
+
+src/signames.h: src/signames.c Makefile src/$(am__dirstamp)
+ export LC_ALL=C ; \
+ @CPP@ -dM $< |\
+ tr -s '\t ' ' ' | sort -n -k 3 | sed \
+ 's:#define SIG\([A-Z][A-Z]*[0-9]*\) \([0-9][0-9]*\).*$\:{\ \2,"\1" },:p;d' | \
+ grep -v '[0-9][0-9][0-9]' >$@ || \
+ { rm -f $@; exit 1; }
+ grep '^{ 1,"HUP" },$$' $@ >/dev/null || \
+ { rm -f $@; exit 1; }
+
+src/signals.c: src/signames.h
+
+install-exec-hook:
+ cd $(DESTDIR)$(bindir) && \
+ ( [ -h pstree.x11 ] || $(LN_S) pstree pstree.x11)
+
+
+get-trans:
+ rsync -Lrtvz translationproject.org::tp/latest/psmisc/ po
diff -ruN old/src/fuser.c new/src/fuser.c
--- old/src/fuser.c 2020-12-31 11:08:34.658310092 +0100
+++ new/src/fuser.c 2020-12-31 11:07:57.282209163 +0100
--- src/fuser.c
+++ src/fuser.c 2021-01-14 11:30:10.750278604 +0000
@@ -63,7 +63,7 @@
#include "fuser.h"
#include "signals.h"
@ -237,7 +90,7 @@ diff -ruN old/src/fuser.c new/src/fuser.c
#include "comm.h"
//#define DEBUG 1
@@ -118,10 +118,6 @@
@@ -118,10 +118,6 @@ static void clear_mntinfo(void) __attrib
static void init_mntinfo(void) __attribute__ ((__constructor__));
static int get_fdinfo(const pid_t pid, const char *fd, struct fdinfo *info);
static int find_mountpoint(const char *path, mntinfo_t **mountinfo);
@ -248,16 +101,16 @@ diff -ruN old/src/fuser.c new/src/fuser.c
static char *expandpath(const char *path);
static struct unixsocket_list *unixsockets = NULL;
static struct names *names_head = NULL, *names_tail = NULL;
@@ -509,7 +505,7 @@
@@ -509,7 +505,7 @@ int parse_file(struct names *this_name,
free(this_name->filename);
this_name->filename = strdup(new);
}
- if (timeout(thestat, this_name->filename, &(this_name->st), 5) != 0 ||
+ if (statn(this_name->filename, STATX_INO, &(this_name->st)) != 0 ||
+ if (statn(this_name->filename, STATX_INO|STATX_TYPE, &(this_name->st)) != 0 ||
find_mountpoint(this_name->filename, &mountinfo) != 0) {
if (errno == ENOENT)
fprintf(stderr,
@@ -1245,9 +1241,7 @@
@@ -1245,9 +1241,7 @@ int main(int argc, char *argv[])
opts |= OPT_INTERACTIVE;
break;
case 'I':
@ -267,7 +120,7 @@ diff -ruN old/src/fuser.c new/src/fuser.c
break;
case 'k':
opts |= OPT_KILL;
@@ -1313,10 +1307,11 @@
@@ -1313,10 +1307,11 @@ int main(int argc, char *argv[])
continue;
}
@ -282,7 +135,7 @@ diff -ruN old/src/fuser.c new/src/fuser.c
/* an option */
/* Not an option, must be a file specification */
if ((this_name = malloc(sizeof(struct names))) == NULL)
@@ -1636,7 +1631,7 @@
@@ -1636,7 +1631,7 @@ static struct stat *get_pidstat(const pi
if ((st = (struct stat *)malloc(sizeof(struct stat))) == NULL)
return NULL;
snprintf(pathname, 256, "/proc/%d/%s", pid, filename);
@ -291,7 +144,7 @@ diff -ruN old/src/fuser.c new/src/fuser.c
free(st);
return NULL;
}
@@ -1683,7 +1678,7 @@
@@ -1683,7 +1678,7 @@ check_dir(const pid_t pid, const char *d
snprintf(filepath, sizeof filepath - 1, "/proc/%d/%s/%s",
pid, dirname, direntry->d_name);
@ -300,7 +153,7 @@ diff -ruN old/src/fuser.c new/src/fuser.c
if (errno != ENOENT && errno != ENOTDIR) {
fprintf(stderr, _("Cannot stat file %s: %s\n"),
filepath, strerror(errno));
@@ -1738,7 +1733,7 @@
@@ -1740,7 +1735,7 @@ check_dir(const pid_t pid, const char *d
if (thedev != ino_tmp->device)
continue;
if (!st.st_ino
@ -309,7 +162,7 @@ diff -ruN old/src/fuser.c new/src/fuser.c
fprintf(stderr,
_("Cannot stat file %s: %s\n"),
filepath, strerror(errno));
@@ -1836,11 +1831,11 @@
@@ -1838,11 +1833,11 @@ static uid_t getpiduid(const pid_t pid)
if (asprintf(&pathname, "/proc/%d", pid) < 0)
return 0;
@ -325,7 +178,7 @@ diff -ruN old/src/fuser.c new/src/fuser.c
return st.st_uid;
}
@@ -1878,7 +1873,7 @@
@@ -1880,7 +1875,7 @@ void fill_unix_cache(struct unixsocket_l
path = scanned_path;
if (*scanned_path == '@')
scanned_path++;
@ -334,7 +187,7 @@ diff -ruN old/src/fuser.c new/src/fuser.c
free(path);
continue;
}
@@ -2013,7 +2008,7 @@
@@ -2015,7 +2010,7 @@ static dev_t find_net_dev(void)
fprintf(stderr, _("Cannot open a network socket.\n"));
return -1;
}
@ -343,7 +196,7 @@ diff -ruN old/src/fuser.c new/src/fuser.c
fprintf(stderr, _("Cannot find socket's device number.\n"));
close(skt);
return -1;
@@ -2050,7 +2045,7 @@
@@ -2052,7 +2047,7 @@ scan_knfsd(struct names *names_head, str
if ((find_space = strpbrk(line, " \t")) == NULL)
continue;
*find_space = '\0';
@ -352,16 +205,16 @@ diff -ruN old/src/fuser.c new/src/fuser.c
continue;
}
/* Scan the devices */
@@ -2087,7 +2082,7 @@
mntinfo_t *mnt = list_entry(ptr, mntinfo_t);
const char *find_mountp = mnt->mpoint;
@@ -2086,7 +2081,7 @@ scan_mounts(struct names *names_head, st
mntinfo_t *mnt = list_entry(ptr, mntinfo_t);
const char *find_mountp = mnt->mpoint;
- if (timeout(thestat, find_mountp, &st, 5) != 0)
+ if (statn(find_mountp, STATX_INO, &st) != 0)
- if (timeout(thestat, find_mountp, &st, 5) != 0)
+ if (statn(find_mountp, STATX_INO, &st) != 0)
continue;
/* Scan the devices */
@@ -2137,7 +2132,7 @@
@@ -2136,7 +2131,7 @@ scan_swaps(struct names *names_head, str
if (*find_space == '\0')
continue;
}
@ -370,7 +223,7 @@ diff -ruN old/src/fuser.c new/src/fuser.c
continue;
}
/* Scan the devices */
@@ -2229,10 +2224,10 @@
@@ -2228,10 +2223,10 @@ init_mntinfo(void)
&mid, &parid, &maj, &min, &mpoint[0], &type[0], &devname[0]) == 7) {
struct stat st;
mntinf = add_mntinfo(mpoint, type, mid, parid, makedev(maj, min));
@ -383,7 +236,7 @@ diff -ruN old/src/fuser.c new/src/fuser.c
mntinf->dev = st.st_dev; /* stat(2) on binary does not see subvol dev */
}
}
@@ -2244,7 +2239,7 @@
@@ -2243,7 +2238,7 @@ init_mntinfo(void)
parid = -1;
while (fscanf (mnt, "%s %s %s %*[^\n]", &devname[0], &mpoint[0], &type[0]) == 3) {
struct stat st;
@ -391,8 +244,8 @@ diff -ruN old/src/fuser.c new/src/fuser.c
+ if (statn(mpoint, 0, &st) != 0) {
if (errno != EACCES) {
fprintf(stderr, _("Cannot stat %s: %s\n"),
mnt->mpoint, strerror(errno));
@@ -2253,7 +2248,7 @@
mpoint, strerror(errno));
@@ -2252,7 +2247,7 @@ init_mntinfo(void)
st.st_dev = (dev_t)-1;
}
mntinf = add_mntinfo(mpoint, type, mid++, parid, st.st_dev);
@ -401,7 +254,7 @@ diff -ruN old/src/fuser.c new/src/fuser.c
if (st.st_rdev != 0 && mntinf->dev != st.st_rdev)
mntinf->vol = st.st_rdev;
}
@@ -2303,7 +2298,7 @@
@@ -2302,7 +2297,7 @@ out:
struct stat lst;
snprintf(pathname, 256, "/proc/%d/fd/%s", pid, fd);
@ -410,7 +263,7 @@ diff -ruN old/src/fuser.c new/src/fuser.c
if (lst.st_mode & S_IWUSR)
info->flags |= O_WRONLY;
ret++;
@@ -2376,7 +2371,7 @@
@@ -2375,7 +2370,7 @@ find_mountpoint(const char *path, mntinf
/* could be a chroot or a container */
@ -419,7 +272,7 @@ diff -ruN old/src/fuser.c new/src/fuser.c
if (errno != EACCES) {
fprintf(stderr, _("Cannot stat %s: %s\n"),
path, strerror(errno));
@@ -2408,7 +2403,7 @@
@@ -2407,7 +2402,7 @@ find_mountpoint(const char *path, mntinf
/* could be a chroot or a container */
@ -428,7 +281,7 @@ diff -ruN old/src/fuser.c new/src/fuser.c
if (errno != EACCES) {
fprintf(stderr, _("Cannot stat %s: %s\n"),
use, strerror(errno));
@@ -2446,49 +2441,6 @@
@@ -2445,49 +2440,6 @@ out:
return ret;
}
@ -478,9 +331,8 @@ diff -ruN old/src/fuser.c new/src/fuser.c
/*
* Somehow the realpath(3) glibc function call, nevertheless
* it avoids lstat(2) system calls.
diff -ruN old/src/statx.c new/src/statx.c
--- old/src/statx.c 1970-01-01 01:00:00.000000000 +0100
+++ new/src/statx.c 2020-12-31 11:07:25.506123358 +0100
--- src/statx.c
+++ src/statx.c 2021-01-14 11:29:22.015223853 +0000
@@ -0,0 +1,149 @@
+/*
+ * statx.c - Map modern statx(2) system call to older stat(2), lstat(2),
@ -631,9 +483,8 @@ diff -ruN old/src/statx.c new/src/statx.c
+ }
+ return ret;
+}
diff -ruN old/src/statx.h new/src/statx.h
--- old/src/statx.h 1970-01-01 01:00:00.000000000 +0100
+++ new/src/statx.h 2020-12-31 11:07:25.506123358 +0100
--- src/statx.h
+++ src/statx.h 2021-01-14 11:29:22.019223776 +0000
@@ -0,0 +1,68 @@
+/*
+ * statx.h - Map modern statx(2) system call to older stat(2), lstat(2),
@ -703,428 +554,3 @@ diff -ruN old/src/statx.h new/src/statx.h
+#define STATX_ALL 0
+#endif
+#endif
diff -ruN old/src/timeout.c new/src/timeout.c
--- old/src/timeout.c 2019-11-12 11:23:38.000000000 +0100
+++ new/src/timeout.c 1970-01-01 01:00:00.000000000 +0100
@@ -1,372 +0,0 @@
-/*
- * timout.c Advanced timeout handling for file system calls
- * to avoid deadlocks on remote file shares.
- *
- * Version: 0.2 11-Dec-2012 Fink
- *
- * Copyright 2011,2012 Werner Fink, 2011,2012 SUSE LINUX Products GmbH, Germany.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * Author: Werner Fink <werner@suse.de>, 2011
- */
-
-#ifndef _GNU_SOURCE
-# define _GNU_SOURCE
-#endif
-
-#ifdef _FEATURES_H
-# error Include local config.h before any system header file
-#endif
-#include "config.h"
-
-#ifndef WITH_TIMEOUT_STAT
-# define WITH_TIMEOUT_STAT 0
-#endif
-
-#ifndef USE_SOCKETPAIR
-# define USE_SOCKETPAIR 1
-#endif
-
-#include <errno.h>
-#include <setjmp.h>
-#include <signal.h>
-#include <stdlib.h>
-#include <string.h>
-#include <sys/mman.h>
-#include <sys/time.h>
-#include <sys/types.h>
-#include <sys/select.h>
-#include <sys/stat.h>
-#include <unistd.h>
-#if USE_SOCKETPAIR
-# include <sys/socket.h>
-# include <netdb.h>
-# include <netinet/in.h>
-# ifndef SHUT_RD
-# define SHUT_RD 0
-# endif
-# ifndef SHUT_WR
-# define SHUT_WR 1
-# endif
-# undef pipe
-# define pipe(v) (((socketpair(AF_UNIX,SOCK_STREAM,0,v) < 0) || \
- (shutdown((v)[1],SHUT_RD) < 0) || (shutdown((v)[0],SHUT_WR) < 0)) ? -1 : 0)
-#endif
-#include <wait.h>
-
-#include "timeout.h"
-
-#if !defined(__STDC_VERSION__) || (__STDC_VERSION__ < 199901L)
-# ifndef destructor
-# define destructor __destructor__
-# endif
-# ifndef constructor
-# define constructor __constructor__
-# endif
-# ifndef packed
-# define packed __packed__
-# endif
-# ifndef inline
-# define inline __inline__
-# endif
-# ifndef unused
-# define unused __unused__
-# endif
-# ifndef volatile
-# define volatile __volatile__
-# endif
-#endif
-#ifndef attribute
-# define attribute(attr) __attribute__(attr)
-#endif
-
-#if defined __GNUC__
-# undef strcpy
-# define strcpy(d,s) __builtin_strcpy((d),(s)) /* Without boundary check please */
-#endif
-
-#if WITH_TIMEOUT_STAT
-static sigjmp_buf jenv;
-static void sigjump(int sig attribute((unused)))
-{
- siglongjmp(jenv, 1);
-}
-#endif
-
-#if WITH_TIMEOUT_STAT == 2
-/*
- * The structure used for communication between the processes
- */
-typedef struct _handle {
- int errcode;
- struct stat argument;
- stat_t function;
- size_t len;
- char path[0];
-} attribute((packed)) handle_t;
-
-/*
- * Using a forked process for doing e.g. stat(2) system call as this
- * allows us to send e.g. SIGKILL to this process if it hangs in `D'
- * state on a file share due a stalled NFS server. This does not work
- * with (p)threads as SIGKILL would kill all threads including main.
- */
-
-static volatile pid_t active;
-static int pipes[4] = {-1, -1, -1, -1};
-static handle_t *restrict handle;
-static const size_t buflen = PATH_MAX+sizeof(handle_t)+1;
-
-static void sigchild(int sig attribute((unused)))
-{
- pid_t pid = waitpid(active, NULL, WNOHANG|WUNTRACED);
- if (pid <= 0)
- return;
- if (errno == ECHILD)
- return;
- active = 0;
-}
-
-static void attribute((constructor)) start(void)
-{
- sigset_t sigset, oldset;
- struct sigaction act;
- char sync[1];
- ssize_t in;
-
- if (pipes[1] >= 0) close(pipes[1]);
- if (pipes[2] >= 0) close(pipes[2]);
-
- if (pipe(&pipes[0]))
- goto error;
- if (pipe(&pipes[2]))
- goto error;
-
- memset(&act, 0, sizeof(act));
- sigemptyset(&act.sa_mask);
- act.sa_flags = SA_RESTART;
- act.sa_handler = sigchild;
- sigaction(SIGCHLD, &act, 0);
-
- if (!handle)
- handle = mmap(NULL, buflen, PROT_READ|PROT_WRITE,
- MAP_ANONYMOUS|MAP_SHARED, -1, 0);
- if (handle == MAP_FAILED)
- goto error;
-
- if ((active = fork()) < 0)
- goto error;
-
- if (active) {
- close(pipes[0]);
- close(pipes[3]);
- pipes[0] = pipes[3] = -1;
- return;
- }
-
- sigemptyset(&sigset);
- sigaddset(&sigset, SIGALRM);
- sigprocmask(SIG_BLOCK, &sigset, &oldset);
-
- act.sa_handler = SIG_DFL;
- sigaction(SIGCHLD, &act, 0);
-
- close(pipes[1]);
- close(pipes[2]);
- dup2(pipes[0], STDIN_FILENO);
- dup2(pipes[3], STDOUT_FILENO);
- close(pipes[0]);
- close(pipes[3]);
- pipes[1] = pipes[2] = -1;
- pipes[0] = pipes[3] = -1;
-
- while ((in = read(STDIN_FILENO, &sync, sizeof(sync))) != 0) {
- ssize_t out;
- if (in < 0) {
- if (errno == EINTR)
- continue;
- break;
- }
- if (!handle)
- break;
- if (handle->function(handle->path, &handle->argument) < 0)
- handle->errcode = errno;
- do
- out = write(STDOUT_FILENO, &sync, sizeof(sync));
- while (out < 0 && errno == EINTR);
- }
-
- sigprocmask(SIG_SETMASK, &oldset, NULL);
- exit(0);
-error:
- if (pipes[0] >= 0) close(pipes[0]);
- if (pipes[1] >= 0) close(pipes[1]);
- if (pipes[2] >= 0) close(pipes[2]);
- if (pipes[3] >= 0) close(pipes[3]);
- if (handle && handle != MAP_FAILED)
- munmap(handle, buflen);
- handle = NULL;
-}
-
-static void /* attribute((destructor)) */ stop(void)
-{
- if (active && waitpid(active, NULL, WNOHANG|WUNTRACED) == 0)
- kill(active, SIGKILL);
-}
-
-/*
- * External routine
- *
- * Execute stat(2) system call with timeout to avoid deadlock
- * on network based file systems.
- *
- */
-int
-timeout(stat_t function, const char *path, struct stat *restrict argument, time_t seconds)
-{
- struct sigaction alrm_act, pipe_act, new_act;
- sigset_t sigset, oldset;
- char sync[1] = "x";
-
- if (active <= 0) /* Oops, last one failed therefore clear status and restart */
- start();
- if (!handle) /* No shared memory area */
- return function(path, argument);
- memset(handle, 0, sizeof(handle_t));
- handle->len = strlen(path) + 1;
- if (handle->len >= PATH_MAX) {
- errno = ENAMETOOLONG;
- goto error;
- }
- handle->errcode = 0;
- handle->argument = *argument;
- handle->function = function;
- strcpy(handle->path, path);
-
- sigemptyset(&sigset);
- sigaddset(&sigset, SIGALRM);
- sigaddset(&sigset, SIGPIPE);
- sigprocmask(SIG_UNBLOCK, &sigset, &oldset);
-
- memset(&new_act, 0, sizeof(new_act));
- sigemptyset(&new_act.sa_mask);
- new_act.sa_flags = SA_RESETHAND;
-
- if (sigsetjmp(jenv, 1))
- goto timed;
-
- new_act.sa_handler = sigjump;
- sigaction(SIGALRM, &new_act, &alrm_act);
- sigaction(SIGPIPE, &new_act, &pipe_act);
- alarm(seconds);
-
- write(pipes[1], &sync, sizeof(sync));
- read(pipes[2], &sync, sizeof(sync));
-
- alarm(0);
- sigaction(SIGPIPE, &pipe_act, NULL);
- sigaction(SIGALRM, &alrm_act, NULL);
-
- if (handle->errcode) {
- errno = handle->errcode;
- goto error;
- }
-
- *argument = handle->argument;
- sigprocmask(SIG_SETMASK, &oldset, NULL);
-
- return 0;
-timed:
- (void) alarm(0);
- sigaction(SIGPIPE, &pipe_act, NULL);
- sigaction(SIGALRM, &alrm_act, NULL);
- sigprocmask(SIG_SETMASK, &oldset, NULL);
- stop();
- errno = ETIMEDOUT;
-error:
- return -1;
-}
-#elif WITH_TIMEOUT_STAT == 1
-/*
- * External routine
- *
- * Execute stat(2) system call with timeout to avoid deadlock
- * on network based file systems.
- *
- */
-int
-timeout(stat_t function, const char *path, struct stat *restrict argument, time_t seconds)
-{
- struct sigaction alrm_act, pipe_act, new_act;
- sigset_t sigset, oldset;
- int ret = 0, pipes[4];
- pid_t pid = 0;
- ssize_t len;
-
- if (pipe(&pipes[0]) < 0)
- goto error;
- switch ((pid = fork())) {
- case -1:
- close(pipes[0]);
- close(pipes[1]);
- goto error;
- case 0:
- new_act.sa_handler = SIG_DFL;
- sigaction(SIGALRM, &new_act, NULL);
- close(pipes[0]);
- if ((ret = function(path, argument)) == 0)
- do
- len = write(pipes[1], argument, sizeof(struct stat));
- while (len < 0 && errno == EINTR);
- close(pipes[1]);
- exit(ret);
- default:
- close(pipes[1]);
-
- sigemptyset(&sigset);
- sigaddset(&sigset, SIGALRM);
- sigaddset(&sigset, SIGPIPE);
- sigprocmask(SIG_UNBLOCK, &sigset, &oldset);
-
- memset(&new_act, 0, sizeof(new_act));
- sigemptyset(&new_act.sa_mask);
-
- if (sigsetjmp(jenv, 1))
- goto timed;
-
- new_act.sa_handler = sigjump;
- sigaction(SIGALRM, &new_act, &alrm_act);
- sigaction(SIGPIPE, &new_act, &pipe_act);
- alarm(seconds);
- if (read(pipes[0], argument, sizeof(struct stat)) == 0) {
- errno = EFAULT;
- ret = -1;
- }
- (void)alarm(0);
- sigaction(SIGPIPE, &pipe_act, NULL);
- sigaction(SIGALRM, &alrm_act, NULL);
-
- close(pipes[0]);
- waitpid(pid, NULL, 0);
- break;
- }
- return ret;
-timed:
- (void)alarm(0);
- sigaction(SIGPIPE, &pipe_act, NULL);
- sigaction(SIGALRM, &alrm_act, NULL);
- if (waitpid(0, NULL, WNOHANG) == 0)
- kill(pid, SIGKILL);
- errno = ETIMEDOUT;
-error:
- return -1;
-}
-#endif
-
-/*
- * End of timeout.c
- */
diff -ruN old/src/timeout.h new/src/timeout.h
--- old/src/timeout.h 2019-11-12 11:23:38.000000000 +0100
+++ new/src/timeout.h 1970-01-01 01:00:00.000000000 +0100
@@ -1,45 +0,0 @@
-/*
- * timout.h Advanced timeout handling for file system calls
- * to avoid deadlocks on remote file shares.
- *
- * Version: 0.1 07-Sep-2011 Fink
- *
- * Copyright 2011 Werner Fink, 2011 SUSE LINUX Products GmbH, Germany.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * Author: Werner Fink <werner@suse.de>, 2011
- */
-
-#ifndef _TIMEOUT_H
-#define _TIMEOUT_H
-
-#include "config.h"
-
-#ifndef WITH_TIMEOUT_STAT
-# define WITH_TIMEOUT_STAT 0
-#endif
-
-#include <sys/types.h>
-#include <sys/stat.h>
-#include <time.h>
-#include <limits.h>
-
-#if !defined(__STDC_VERSION__) || (__STDC_VERSION__ < 199901L)
-# ifndef restrict
-# define restrict __restrict__
-# endif
-#endif
-
-typedef int (*stat_t)(const char *, struct stat *);
-
-#if WITH_TIMEOUT_STAT > 0
-extern int timeout(stat_t, const char *, struct stat *restrict, time_t);
-#else
-# define timeout(func,path,buf,dummy) (func)((path),(buf))
-#endif
-
-#endif

View File

@ -0,0 +1,38 @@
Avoid to fail on killall without any argiments in case of libselinux
--- configure.ac
+++ configure.ac 2021-01-14 12:52:33.493812041 +0100
@@ -27,6 +27,8 @@ if test "$enable_selinux" = "yes"; then
AC_DEFINE([WITH_SELINUX], [1], [Use Security-Enhanced Linux features])
AC_CHECK_LIB([selinux], [getfilecon], [SELINUX_LIB=-lselinux], [
AC_MSG_ERROR([Cannot find selinux static library]) ])
+ AC_CHECK_LIB([selinux], [getfilecon], [echo 'set has_selinux 1' > testsuite/selinux.exp],
+ [echo 'set has_selinux 0' > testsuite/selinux.exp])
fi
AC_SUBST([SELINUX_LIB])
--- testsuite/Makefile.am
+++ testsuite/Makefile.am 2021-01-14 12:53:25.962505766 +0100
@@ -1,6 +1,8 @@
AUTOMAKE_OPTIONS = dejagnu
export DEJAGNU
+EXTRA_DEJAGNU_SITE_CONFIG=$(srcdir)/selinux.exp
+
# Programs that are expected across the board.
DEJATOOL = killall
DEJATOOL += pslog
--- testsuite/killall.test/killall.exp
+++ testsuite/killall.test/killall.exp 2021-01-14 12:54:27.087313939 +0100
@@ -7,7 +7,11 @@ set fake_proc_name "afakeprocname"
set test "killall with no arguments"
spawn $killall
+if { $has_selinux == 0 } {
expect_pass "$test" "^Usage: killall \\\[OPTION\\\]\\.\\.\\. \\\[--\\\] NAME\\.\\.\\."
+} else {
+expect_pass "$test" "^Usage: killall \\\[ -Z CONTEXT \\\] \\\[ -u USER \\\] \\\[ -y TIME \\\] \\\[ -o TIME \\\] \\\[ -eIgiqrvw \\\]"
+}
set test "killall list signals"
spawn $killall -l

View File

@ -4,8 +4,8 @@
2 files changed, 5 insertions(+), 2 deletions(-)
--- configure.ac
+++ configure.ac 2018-11-02 13:34:07.811373984 +0000
@@ -132,7 +132,7 @@ AC_CHECK_MEMBERS([struct user_regs_struc
+++ configure.ac 2021-01-14 11:31:31.640709812 +0000
@@ -129,7 +129,7 @@ AC_CHECK_MEMBERS([struct user_regs_struc
struct user_regs_struct.rdi,
struct user_regs_struct.rsi,
struct user_regs_struct.rdx], [],[],
@ -15,8 +15,8 @@
AC_CHECK_MEMBERS([struct pt_regs.orig_gpr3,
struct pt_regs.gpr], [],[], [#include <linux/ptrace.h>])
--- src/fuser.c
+++ src/fuser.c 2018-11-02 13:34:07.811373984 +0000
@@ -1094,6 +1094,7 @@ int main(int argc, char *argv[])
+++ src/fuser.c 2021-01-14 11:31:31.640709812 +0000
@@ -1146,6 +1146,7 @@ int main(int argc, char *argv[])
struct option *optr;
char *nsptr;
int skip_argv;
@ -24,7 +24,7 @@
struct option options[] = {
{"all", 0, NULL, 'a'},
@@ -1137,6 +1138,7 @@ int main(int argc, char *argv[])
@@ -1189,6 +1190,7 @@ int main(int argc, char *argv[])
#endif
atexit(atexit_free_lists);
@ -32,7 +32,7 @@
for (argc_cnt = 1; argc_cnt < argc; argc_cnt++) {
current_argv = argv[argc_cnt];
if (current_argv[0] == '-') { /* its an option */
@@ -1279,6 +1281,7 @@ int main(int argc, char *argv[])
@@ -1333,6 +1335,7 @@ int main(int argc, char *argv[])
}
}
this_name->matched_procs = NULL;
@ -40,7 +40,7 @@
if (opts & (OPT_MOUNTS | OPT_ISMOUNTPOINT)
&& this_name->name_space != NAMESPACE_FILE) {
free(this_name);
@@ -1332,7 +1335,7 @@ int main(int argc, char *argv[])
@@ -1386,7 +1389,7 @@ int main(int argc, char *argv[])
names_tail->next = this_name;
names_tail = this_name;
} /* for across the argvs */

View File

@ -1,3 +1,12 @@
-------------------------------------------------------------------
Thu Jan 14 11:58:43 UTC 2021 - Dr. Werner Fink <werner@suse.de>
- Rework 0001-Use-mountinfo-to-be-able-to-use-the-mount-identity.patch
and split off the patch psmisc-v23.3-selinux.patch
- Rework 0002-Use-new-statx-2-system-call-to-avoid-hangs-on-NFS.patch
- New patch psmisc-v23.3-selinux.patch
- Rename patch psmisc-v23.2.dif which is now psmisc-v23.3.dif
-------------------------------------------------------------------
Thu Dec 31 09:40:07 UTC 2020 - Paolo Stivanin <info@paolostivanin.com>

View File

@ -1,7 +1,7 @@
#
# spec file for package psmisc
#
# Copyright (c) 2020 SUSE LLC
# Copyright (c) 2021 SUSE LLC
#
# All modifications and additions to the file contributed by third parties
# remain the property of their copyright owners, unless otherwise agreed
@ -40,6 +40,7 @@ Patch2: %{name}-22.21-pstree.patch
# https://gitlab.com/bitstreamout/psmisc/tree/mountinfo
Patch3: 0001-Use-mountinfo-to-be-able-to-use-the-mount-identity.patch
Patch4: 0002-Use-new-statx-2-system-call-to-avoid-hangs-on-NFS.patch
Patch5: psmisc-v23.3-selinux.patch
%define have_peekfd %ix86 x86_64 ppc ppc64 ppc64le %arm mipsel m68k
@ -56,8 +57,9 @@ processes that are using specified files or filesystems.
%prep
%setup -q -n %{name}-v%{version}
%patch2 -p0 -b .pstree
%patch3 -p1 -b .mntinf
%patch4 -p1 -b .statx
%patch3 -p0 -b .mntinf
%patch4 -p0 -b .statx
%patch5 -p0 -b .selx
%patch0 -p0 -b .p0
%build