handle sub volumes of the btrFS

OBS-URL: https://build.opensuse.org/package/show/Base:System/psmisc?expand=0&rev=113
This commit is contained in:
Dr. Werner Fink 2018-11-14 11:26:45 +00:00 committed by Git OBS Bridge
parent e208f05622
commit dee14919e6
3 changed files with 217 additions and 106 deletions

View File

@ -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 <werner@suse.de> From: Werner Fink <werner@suse.de>
Date: Mon, 22 Oct 2018 12:02:50 +0200 Date: Mon, 22 Oct 2018 12:02:50 +0200
Subject: [PATCH] Use mountinfo to be able to use the mount identity 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 Add support for name_to_handle_at() system call to
get the real mount ID for each file 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 <werner@suse.de> Signed-off-by: Werner Fink <werner@suse.de>
--- ---
configure.ac | 18 +- configure.ac | 18 +-
src/fuser.c | 541 +++++++++++++++++++++++++++---------- src/fuser.c | 627 ++++++++++++++++++++++++++++---------
src/fuser.h | 19 +- src/fuser.h | 27 +-
testsuite/Makefile.am | 3 +- testsuite/Makefile.am | 3 +-
testsuite/killall.test/killall.exp | 4 + 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 diff --git configure.ac configure.ac
index 176a2fc..d8d3366 100644 index 176a2fc..d8d3366 100644
@ -66,7 +66,7 @@ index 176a2fc..d8d3366 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 c44cee8..2681f74 100644 index c44cee8..970b52d 100644
--- src/fuser.c --- src/fuser.c
+++ src/fuser.c +++ src/fuser.c
@@ -32,6 +32,10 @@ @@ -32,6 +32,10 @@
@ -89,12 +89,14 @@ index c44cee8..2681f74 100644
static uid_t getpiduid(const pid_t pid); static uid_t getpiduid(const pid_t pid);
static int print_matches(struct names *names_head, const opt_type opts, static int print_matches(struct names *names_head, const opt_type opts,
const int sig_number); 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);*/ /*int parse_mount(struct names *this_name, struct device_list **dev_list);*/
static void add_device(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 fill_unix_cache(struct unixsocket_list **unixsocket_head);
-void clear_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 fill_unix_cache(struct unixsocket_list **unixsocket_head);
+static void clear_unix_cache(struct unixsocket_list **unixsocket_head); +static void clear_unix_cache(struct unixsocket_list **unixsocket_head);
static void atexit_clear_unix_cache(); static void atexit_clear_unix_cache();
@ -135,7 +137,7 @@ index c44cee8..2681f74 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;
@@ -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 */ /* 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) {
@ -148,6 +150,7 @@ index c44cee8..2681f74 100644
- if (cwd_dev == dev_tmp->device) - if (cwd_dev == dev_tmp->device)
- add_matched_proc(dev_tmp->name, pid, uid, - add_matched_proc(dev_tmp->name, pid, uid,
- ACCESS_CWD); - ACCESS_CWD);
+ struct subvol *vol_tmp;
+ char access = 0; + char access = 0;
+ if (exe_dev == dev_tmp->device && dev_tmp->mnt_id == exe_id) + if (exe_dev == dev_tmp->device && dev_tmp->mnt_id == exe_id)
+ access |= ACCESS_EXE; + access |= ACCESS_EXE;
@ -155,6 +158,17 @@ index c44cee8..2681f74 100644
+ access |= ACCESS_ROOT; + access |= ACCESS_ROOT;
+ if (cwd_dev == dev_tmp->device && dev_tmp->mnt_id == cwd_id) + if (cwd_dev == dev_tmp->device && dev_tmp->mnt_id == cwd_id)
+ access |= ACCESS_CWD; + 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) + if (access)
+ add_matched_proc(dev_tmp->name, pid, uid, access); + add_matched_proc(dev_tmp->name, pid, uid, access);
} }
@ -167,7 +181,7 @@ index c44cee8..2681f74 100644
if (exe_stat if (exe_stat
&& exe_stat->st_dev == ino_tmp->device && exe_stat->st_dev == ino_tmp->device
&& exe_stat->st_ino == ino_tmp->inode) && 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_dev == ino_tmp->device) {
if (!root_stat) if (!root_stat)
@ -176,7 +190,7 @@ index c44cee8..2681f74 100644
if (root_stat if (root_stat
&& root_stat->st_dev == ino_tmp->device && root_stat->st_dev == ino_tmp->device
&& root_stat->st_ino == ino_tmp->inode) && 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_dev == ino_tmp->device) {
if (!cwd_stat) if (!cwd_stat)
@ -185,7 +199,7 @@ index c44cee8..2681f74 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)
@@ -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->name = this_name;
ino_tmp->device = device; ino_tmp->device = device;
ino_tmp->inode = inode; ino_tmp->inode = inode;
@ -193,15 +207,54 @@ index c44cee8..2681f74 100644
ino_tmp->next = ino_head; ino_tmp->next = ino_head;
*ino_list = ino_tmp; *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_head = *dev_list;
dev_tmp->name = this_name; dev_tmp->name = this_name;
dev_tmp->device = device; 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->mnt_id = this_name->mnt_id;
dev_tmp->next = dev_head; dev_tmp->next = dev_head;
*dev_list = dev_tmp; *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, int parse_file(struct names *this_name, struct inode_list **ino_list,
const opt_type opts) const opt_type opts)
{ {
@ -218,7 +271,7 @@ index c44cee8..2681f74 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"),
@@ -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)); this_name->filename, strerror(errno));
return -1; return -1;
} }
@ -233,7 +286,7 @@ index c44cee8..2681f74 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);
@@ -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) const opt_type opts)
{ {
dev_t match_device; dev_t match_device;
@ -245,18 +298,21 @@ index c44cee8..2681f74 100644
match_device = this_name->st.st_rdev; match_device = this_name->st.st_rdev;
else else
match_device = this_name->st.st_dev; match_device = this_name->st.st_dev;
- add_device(dev_list, this_name, match_device);
+ +
+ count = 0; + count = 0;
+ 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);
+ if (match_device != mnt->dev) + if (match_device != mnt->dev && match_device != mnt->vol)
+ continue; + continue;
+ if (S_ISBLK(this_name->st.st_mode)) { + if (S_ISBLK(this_name->st.st_mode)) {
+ /* Skip mount IDs check if a block device + /* Skip mount IDs check if a block device
+ * was specified */ + * was specified */
+ this_name->mnt_id = mnt->id; + this_name->mnt_id = mnt->id;
+ add_device(dev_list, this_name, match_device); + add_device(dev_list, this_name, match_device, mnt->dev);
+ if (mnt->dev == mnt->vol)
+ count++; + count++;
+ else count = 1;
+ continue; + continue;
+ } + }
+ if (this_name->mnt_id != mnt->id) + if (this_name->mnt_id != mnt->id)
@ -282,10 +338,11 @@ index c44cee8..2681f74 100644
+ if (S_ISBLK(this_name->st.st_mode)) + if (S_ISBLK(this_name->st.st_mode))
+ return 0; + return 0;
+ this_name->mnt_id = mountinfo->id; + 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; 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"), fprintf(stderr, _("Unknown local port AF %d\n"),
res->ai_family); res->ai_family);
freeaddrinfo(res); freeaddrinfo(res);
@ -294,7 +351,7 @@ index c44cee8..2681f74 100644
return -1; return -1;
} }
freeaddrinfo(res); 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; break;
#endif #endif
} }
@ -310,7 +367,7 @@ index c44cee8..2681f74 100644
} }
return 1; 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; 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)
@ -332,7 +389,7 @@ index c44cee8..2681f74 100644
else else
usage(_ usage(_
("Invalid namespace name")); ("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) #if defined(WITH_MOUNTINFO_LIST)
@ -341,7 +398,7 @@ index c44cee8..2681f74 100644
thestat = mntstat; thestat = mntstat;
#endif #endif
/* an option */ /* 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]; char pathname[256];
struct stat *st; 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); free(st);
return NULL; return NULL;
} }
@ -366,7 +423,7 @@ index c44cee8..2681f74 100644
return st; 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 inode_list *ino_tmp;
struct device_list *dev_tmp; struct device_list *dev_tmp;
struct unixsocket_list *sock_tmp; struct unixsocket_list *sock_tmp;
@ -376,14 +433,30 @@ index c44cee8..2681f74 100644
char *dirpath; char *dirpath;
char filepath[PATH_MAX]; 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) { dev_tmp = dev_tmp->next) {
if (thedev != dev_tmp->device) - if (thedev != dev_tmp->device)
continue; + 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) + if (get_fdinfo(pid, direntry->d_name, &fd) != 0)
+ continue; + continue;
+ if (fd.mnt_id != dev_tmp->mnt_id) + if (fd.mnt_id != dev_tmp->mnt_id)
+ continue; continue;
if (access == ACCESS_FILE if (access == ACCESS_FILE
- && (lstat(filepath, &lst) == 0) - && (lstat(filepath, &lst) == 0)
- && (lst.st_mode & S_IWUSR)) { - && (lst.st_mode & S_IWUSR)) {
@ -391,7 +464,7 @@ index c44cee8..2681f74 100644
add_matched_proc(dev_tmp->name, add_matched_proc(dev_tmp->name,
pid, uid, pid, uid,
ACCESS_FILEWR | 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; continue;
} }
if (st.st_ino == ino_tmp->inode) { if (st.st_ino == ino_tmp->inode) {
@ -404,7 +477,7 @@ index c44cee8..2681f74 100644
add_matched_proc(ino_tmp->name, add_matched_proc(ino_tmp->name,
pid, uid, pid, uid,
ACCESS_FILEWR | 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; FILE *fp;
unsigned long long tmp_inode; unsigned long long tmp_inode;
unsigned int tmp_maj, tmp_min; unsigned int tmp_maj, tmp_min;
@ -412,9 +485,14 @@ index c44cee8..2681f74 100644
if (asprintf(&pathname, "/proc/%d/%s", pid, filename) < 0) if (asprintf(&pathname, "/proc/%d/%s", pid, filename) < 0)
return; return;
@@ -1657,12 +1721,25 @@ check_map(const pid_t pid, const char *filename, if ((fp = fopen(pathname, "r")) == NULL) {
} - free(pathname);
free(pathname); + free(pathname);
return;
- }
- free(pathname);
+ }
+ free(pathname);
while (fgets(line, BUFSIZ, fp)) { while (fgets(line, BUFSIZ, fp)) {
- if (sscanf(line, "%*s %*s %*s %x:%x %lld", - if (sscanf(line, "%*s %*s %*s %x:%x %lld",
- &tmp_maj, &tmp_min, &tmp_inode) == 3) { - &tmp_maj, &tmp_min, &tmp_inode) == 3) {
@ -435,14 +513,26 @@ index c44cee8..2681f74 100644
+ } + }
+ +
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)
- if (dev_tmp->device == tmp_device) - if (dev_tmp->device == tmp_device)
+ dev_tmp = dev_tmp->next) {
+ struct subvol *vol_tmp;
+ if (dev_tmp->device == tmp_device && + if (dev_tmp->device == tmp_device &&
+ mnt_id == dev_tmp->mnt_id) + mnt_id == dev_tmp->mnt_id)
add_matched_proc(dev_tmp->name, pid, add_matched_proc(dev_tmp->name, pid,
uid, access); 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; 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) && ino_tmp->inode == tmp_inode)
add_matched_proc(ino_tmp->name, pid, add_matched_proc(ino_tmp->name, pid,
uid, access); uid, access);
@ -452,7 +542,7 @@ index c44cee8..2681f74 100644
} }
fclose(fp); 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 * 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
*/ */
@ -460,7 +550,7 @@ index c44cee8..2681f74 100644
void fill_unix_cache(struct unixsocket_list **unixsocket_head) void fill_unix_cache(struct unixsocket_list **unixsocket_head)
{ {
FILE *fp; 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) { while (fgets(line, BUFSIZ, fp) != NULL) {
char *path; char *path;
char *scanned_path = NULL; char *scanned_path = NULL;
@ -469,7 +559,7 @@ index c44cee8..2681f74 100644
if (sscanf(line, "%*x: %*x %*x %*x %*x %*d %d %ms", if (sscanf(line, "%*x: %*x %*x %*x %*x %*d %d %ms",
&scanned_inode, &scanned_path) != 2) { &scanned_inode, &scanned_path) != 2) {
if (scanned_path) 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); free(path);
continue; continue;
} }
@ -478,7 +568,7 @@ index c44cee8..2681f74 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);
@@ -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->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;
@ -486,7 +576,7 @@ index c44cee8..2681f74 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;
@@ -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 * Free up the list of Unix sockets
*/ */
@ -494,7 +584,7 @@ index c44cee8..2681f74 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) {
@@ -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 device_list *dev_tmp;
struct inode_list *ino_tmp; struct inode_list *ino_tmp;
@ -535,7 +625,7 @@ index c44cee8..2681f74 100644
add_special_proc(dev_tmp->name, PTYPE_MOUNT, 0, add_special_proc(dev_tmp->name, PTYPE_MOUNT, 0,
find_mountp); 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); find_mountp);
} }
} }
@ -543,7 +633,7 @@ index c44cee8..2681f74 100644
} }
static void 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); 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)) + if (strncmp("nfs", type, 3) == 0 || strncmp("afs", type, 3) == 0 || strncmp("autofs", type, 6))
+ mnt->isremote = 1; + mnt->isremote = 1;
+ else mnt->isremote = 0; + else mnt->isremote = 0;
+ if (!mnt->isremote) { + /* E.g. sub volumes of BtrFS do not show main device number in
+ /* E.g. sub volumes of BtrFS do not show correct device + /proc/self/mountinfo, for now just map the device to this */
+ * numbers in /proc/self/mountinfo */ + mnt->vol = dev;
+ struct stat st;
+ if (stat(mpoint, &st) >= 0)
+ mnt->dev = st.st_dev;
+ }
+
+ return mnt; + return mnt;
+} +}
@ -597,7 +682,7 @@ index c44cee8..2681f74 100644
{ {
list_t *ptr, *tmp; 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 type[256];
char mpoint[PATH_MAX *4 + 1]; // octal escaping takes 4 chars per 1 char char mpoint[PATH_MAX *4 + 1]; // octal escaping takes 4 chars per 1 char
- int mid, parid, max = 0; - int mid, parid, max = 0;
+ char devname[PATH_MAX];
+ int mid, parid; + int mid, parid;
+ mntinfo_t *mntinf;
+#if defined(HAS_MOUNTINFO) +#if defined(HAS_MOUNTINFO)
uint maj, min; uint maj, min;
- list_t sort; - list_t sort;
@ -634,23 +721,13 @@ index c44cee8..2681f74 100644
- ("Cannot allocate memory for matched proc: %s\n"), - ("Cannot allocate memory for matched proc: %s\n"),
- strerror(errno)); - strerror(errno));
- exit(1); - exit(1);
+ (mnt, "%i %i %u:%u %*s %s %*[^-] - %s %*[^\n]", + (mnt, "%i %i %u:%u %*s %s %*[^-] - %s %s %*[^\n]",
+ &mid, &parid, &maj, &min, &mpoint[0], &type[0]) == 6) + &mid, &parid, &maj, &min, &mpoint[0], &type[0], &devname[0]) == 7) {
+ (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) {
+ struct stat st; + struct stat st;
+ if (stat(mpoint, &st) != 0) { + mntinf = add_mntinfo(mpoint, type, mid, parid, makedev(maj, min));
+ if (errno != EACCES) { + if (mntinf && strncmp(devname, "/dev/", 5) == 0 && stat(devname, &st) == 0) {
+ fprintf(stderr, _("Cannot stat %s: %s\n"), + if (st.st_rdev != 0 && mntinf->dev != st.st_rdev)
+ mnt->mpoint, strerror(errno)); + mntinf->vol = st.st_rdev;
+ exit(1);
+ }
+ st.st_dev = (dev_t)-1;
} }
- append(mnt, mntinfo); - append(mnt, mntinfo);
- mnt->mpoint = ((char *)mnt) + alignof(mntinfo_t); - mnt->mpoint = ((char *)mnt) + alignof(mntinfo_t);
@ -661,17 +738,32 @@ index c44cee8..2681f74 100644
- mnt->id = mid; - mnt->id = mid;
- if (mid > max) - if (mid > max)
- max = mid; - 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 +#endif
fclose(mnt); 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 +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)
+{ +{
@ -761,7 +853,12 @@ index c44cee8..2681f74 100644
+ int ret = -1; + int ret = -1;
+ +
+ *mountinfo = NULL; + *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 defined(HAS_NAME_TO_HANDLE_AT)
+ if (mnt_id >= 0) { + if (mnt_id >= 0) {
+ list_t *ptr; + list_t *ptr;
@ -843,12 +940,12 @@ index c44cee8..2681f74 100644
- if (mid != mnt->parid) - if (mid != mnt->parid)
+ +
+ if (nlen != mnt->nlen) + if (nlen != mnt->nlen)
+ continue;
+
+ if (strcmp(use, mnt->mpoint))
continue; continue;
- move_head(ptr, &sort); - move_head(ptr, &sort);
+ +
+ if (strcmp(use, mnt->mpoint))
+ continue;
+
+ ret = 0; + ret = 0;
+ errno = 0; + errno = 0;
+ *mountinfo = mnt; + *mountinfo = mnt;
@ -874,7 +971,7 @@ index c44cee8..2681f74 100644
/* /*
* Determine device of links below /proc/ * 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]; char name[PATH_MAX + 1];
const char *use; const char *use;
@ -884,7 +981,7 @@ index c44cee8..2681f74 100644
if ((use = realpath(path, name)) == NULL || *use != '/') 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; errno = 0;
return stat(path, buf); return stat(path, buf);
} }
@ -931,7 +1028,7 @@ index c44cee8..2681f74 100644
#endif /* WITH_MOUNTINFO_LIST */ #endif /* WITH_MOUNTINFO_LIST */
diff --git src/fuser.h src/fuser.h diff --git src/fuser.h src/fuser.h
index 93020d5..51c6770 100644 index 93020d5..ca20081 100644
--- src/fuser.h --- src/fuser.h
+++ src/fuser.h +++ src/fuser.h
@@ -37,10 +37,16 @@ struct procs { @@ -37,10 +37,16 @@ struct procs {
@ -952,7 +1049,7 @@ index 93020d5..51c6770 100644
struct procs *matched_procs; struct procs *matched_procs;
struct names *next; struct names *next;
}; };
@@ -65,12 +71,14 @@ struct inode_list { @@ -65,12 +71,21 @@ struct inode_list {
struct names *name; struct names *name;
dev_t device; dev_t device;
ino_t inode; ino_t inode;
@ -960,14 +1057,21 @@ index 93020d5..51c6770 100644
struct inode_list *next; struct inode_list *next;
}; };
+struct subvol {
+ dev_t device;
+ int mnt_id;
+ struct subvol *next;
+};
+
struct device_list { struct device_list {
struct names *name; struct names *name;
+ struct subvol *vol;
dev_t device; dev_t device;
+ int mnt_id; + int mnt_id;
struct device_list *next; struct device_list *next;
}; };
@@ -79,6 +87,7 @@ struct unixsocket_list { @@ -79,6 +94,7 @@ struct unixsocket_list {
ino_t inode; ino_t inode;
ino_t net_inode; ino_t net_inode;
dev_t dev; dev_t dev;
@ -975,7 +1079,7 @@ index 93020d5..51c6770 100644
struct unixsocket_list *next; struct unixsocket_list *next;
}; };
@@ -87,18 +96,15 @@ struct mount_list { @@ -87,18 +103,16 @@ struct mount_list {
struct mount_list *next; struct mount_list *next;
}; };
@ -988,6 +1092,7 @@ index 93020d5..51c6770 100644
+ char isremote; + char isremote;
dev_t dev; dev_t dev;
size_t nlen; size_t nlen;
+ dev_t vol;
char *mpoint; char *mpoint;
} mntinfo_t; } mntinfo_t;
-#else -#else
@ -996,7 +1101,7 @@ index 93020d5..51c6770 100644
#define NAMESPACE_FILE 0 #define NAMESPACE_FILE 0
#define NAMESPACE_TCP 1 #define NAMESPACE_TCP 1
@@ -109,5 +115,6 @@ typedef struct mntinfo_s { @@ -109,5 +123,6 @@ typedef struct mntinfo_s {
#endif /* PATH_MAX */ #endif /* PATH_MAX */
#define KNFSD_EXPORTS "/proc/fs/nfs/exports" #define KNFSD_EXPORTS "/proc/fs/nfs/exports"

View File

@ -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 <werner@suse.de> From: Werner Fink <werner@suse.de>
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 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 d8d3366..81d3674 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 2681f74..92ffa37 100644 index 970b52d..e2d14bf 100644
--- src/fuser.c --- src/fuser.c
+++ src/fuser.c +++ src/fuser.c
@@ -63,7 +63,7 @@ @@ -63,7 +63,7 @@
@ -113,7 +113,7 @@ index 2681f74..92ffa37 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;
@@ -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); free(this_name->filename);
this_name->filename = strdup(new); this_name->filename = strdup(new);
} }
@ -122,7 +122,7 @@ index 2681f74..92ffa37 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,
@@ -1193,9 +1189,7 @@ int main(int argc, char *argv[]) @@ -1233,9 +1229,7 @@ int main(int argc, char *argv[])
opts |= OPT_INTERACTIVE; opts |= OPT_INTERACTIVE;
break; break;
case 'I': case 'I':
@ -132,7 +132,7 @@ index 2681f74..92ffa37 100644
break; break;
case 'k': case 'k':
opts |= OPT_KILL; opts |= OPT_KILL;
@@ -1261,10 +1255,11 @@ int main(int argc, char *argv[]) @@ -1301,10 +1295,11 @@ int main(int argc, char *argv[])
continue; continue;
} }
@ -147,7 +147,7 @@ index 2681f74..92ffa37 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)
@@ -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) if ((st = (struct stat *)malloc(sizeof(struct stat))) == NULL)
return NULL; return NULL;
snprintf(pathname, 256, "/proc/%d/%s", pid, filename); snprintf(pathname, 256, "/proc/%d/%s", pid, filename);
@ -156,7 +156,7 @@ index 2681f74..92ffa37 100644
free(st); free(st);
return NULL; 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", snprintf(filepath, sizeof filepath - 1, "/proc/%d/%s/%s",
pid, dirname, direntry->d_name); pid, dirname, direntry->d_name);
@ -165,7 +165,7 @@ index 2681f74..92ffa37 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));
@@ -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) if (thedev != ino_tmp->device)
continue; continue;
if (!st.st_ino if (!st.st_ino
@ -174,7 +174,7 @@ index 2681f74..92ffa37 100644
fprintf(stderr, fprintf(stderr,
_("Cannot stat file %s: %s\n"), _("Cannot stat file %s: %s\n"),
filepath, strerror(errno)); 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) if (asprintf(&pathname, "/proc/%d", pid) < 0)
return 0; return 0;
@ -190,7 +190,7 @@ index 2681f74..92ffa37 100644
return st.st_uid; 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; path = scanned_path;
if (*scanned_path == '@') if (*scanned_path == '@')
scanned_path++; scanned_path++;
@ -199,7 +199,7 @@ index 2681f74..92ffa37 100644
free(path); free(path);
continue; 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")); fprintf(stderr, _("Cannot open a network socket.\n"));
return -1; return -1;
} }
@ -208,7 +208,7 @@ index 2681f74..92ffa37 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;
@@ -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) if ((find_space = strpbrk(line, " \t")) == NULL)
continue; continue;
*find_space = '\0'; *find_space = '\0';
@ -217,7 +217,7 @@ index 2681f74..92ffa37 100644
continue; continue;
} }
/* Scan the devices */ /* 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); 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 2681f74..92ffa37 100644
continue; continue;
/* Scan the devices */ /* 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') if (*find_space == '\0')
continue; continue;
} }
@ -235,7 +235,7 @@ index 2681f74..92ffa37 100644
continue; continue;
} }
/* Scan the devices */ /* Scan the devices */
@@ -2209,7 +2204,7 @@ out: @@ -2279,7 +2274,7 @@ out:
struct stat lst; struct stat lst;
snprintf(pathname, 256, "/proc/%d/fd/%s", pid, fd); snprintf(pathname, 256, "/proc/%d/fd/%s", pid, fd);
@ -244,7 +244,7 @@ index 2681f74..92ffa37 100644
if (lst.st_mode & S_IWUSR) if (lst.st_mode & S_IWUSR)
info->flags |= O_WRONLY; info->flags |= O_WRONLY;
ret++; ret++;
@@ -2352,49 +2347,6 @@ out: @@ -2422,49 +2417,6 @@ out:
return ret; return ret;
} }

View File

@ -1,3 +1,9 @@
-------------------------------------------------------------------
Wed Nov 14 07:44:55 UTC 2018 - Dr. Werner Fink <werner@suse.de>
- 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 <werner@suse.de> Mon Nov 5 07:48:25 UTC 2018 - Dr. Werner Fink <werner@suse.de>