OBS User unknown 2008-08-08 00:14:10 +00:00 committed by Git OBS Bridge
parent fc09b5b977
commit fb9d74c195
4 changed files with 278 additions and 110 deletions

View File

@ -1,5 +1,5 @@
--- doc/fuser.1 --- doc/fuser.1
+++ doc/fuser.1 2008-05-16 15:18:59.027600905 +0200 +++ doc/fuser.1 2008-05-16 15:18:59.000000000 +0200
@@ -80,8 +80,14 @@ List all known signal names. @@ -80,8 +80,14 @@ List all known signal names.
\fIname\fP specifies a file on a mounted file system or a block device that \fIname\fP specifies a file on a mounted file system or a block device that
is mounted. All processes accessing files on that file system are listed. is mounted. All processes accessing files on that file system are listed.
@ -33,7 +33,7 @@
cannot report on any processes that it doesn't have permission to look at cannot report on any processes that it doesn't have permission to look at
the file descriptor table for. The most common time this problem occurs the file descriptor table for. The most common time this problem occurs
--- src/fuser.c --- src/fuser.c
+++ src/fuser.c 2007-12-19 18:45:34.954694000 +0100 +++ src/fuser.c 2008-08-07 14:47:58.126764924 +0200
@@ -32,6 +32,7 @@ @@ -32,6 +32,7 @@
#include <stdlib.h> #include <stdlib.h>
#include <string.h> #include <string.h>
@ -51,34 +51,41 @@
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, const int sig_number); static int print_matches(struct names *names_head, const opt_type opts, const int sig_number);
static void kill_matched_proc(struct procs *pptr, const opt_type opts, const int sig_number); static void kill_matched_proc(struct procs *pptr, const opt_type opts, const int sig_number);
@@ -72,13 +73,16 @@ static void add_device(struct device_lis @@ -72,13 +73,15 @@ static void add_device(struct device_lis
void scan_mount_devices(const opt_type opts, struct mountdev_list **mount_devices); void scan_mount_devices(const opt_type opts, struct mountdev_list **mount_devices);
void fill_unix_cache(struct unixsocket_list **unixsocket_head); void fill_unix_cache(struct unixsocket_list **unixsocket_head);
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, struct device_list *dev_head); -static void scan_procs(struct names *names_head, struct inode_list *ino_head, struct device_list *dev_head);
+static void scan_procs(const opt_type opts, struct names *names_head, struct inode_list *ino_head, struct device_list *dev_head); +static void scan_procs(const opt_type opts, struct names *names_head, struct inode_list *ino_head, struct device_list *dev_head, struct mountdev_list *mounts);
#ifdef NFS_CHECKS #ifdef NFS_CHECKS
static void scan_knfsd(struct names *names_head, struct device_list *dev_head); static void scan_knfsd(struct names *names_head, struct device_list *dev_head);
#endif /* NFS_CHECKS */ #endif /* NFS_CHECKS */
#ifdef DEBUG #ifdef DEBUG
static void debug_match_lists(struct names *names_head, struct inode_list *ino_head, struct device_list *dev_head); -static void debug_match_lists(struct names *names_head, struct inode_list *ino_head, struct device_list *dev_head);
+static void debug_match_lists(struct names *names_head, struct inode_list *ino_head, struct device_list *dev_head, struct mountdev_list *mounts);
#endif #endif
+static struct nfs_points *mnts; +static struct nfs_points *mnts;
+static void init_nfs(void);
+static int check4nfs(const char * path, char * real); +static int check4nfs(const char * path, char * real);
static void usage (const char *errormsg) static void usage (const char *errormsg)
{ {
@@ -127,7 +131,7 @@ void print_version() @@ -127,7 +130,14 @@ void print_version()
"For more information about these matters, see the files named COPYING.\n")); "For more information about these matters, see the files named COPYING.\n"));
} }
-static void scan_procs(struct names *names_head, struct inode_list *ino_head, struct device_list *dev_head) -static void scan_procs(struct names *names_head, struct inode_list *ino_head, struct device_list *dev_head)
+static void scan_procs(const opt_type opts, struct names *names_head, struct inode_list *ino_head, struct device_list *dev_head) +static int islocatedon(const char * path, const char * loc)
+{
+ if (!path || *path == '\0')
+ return 0;
+ return (strstr(path, loc) == path);
+}
+
+static void scan_procs(const opt_type opts, struct names *names_head, struct inode_list *ino_head, struct device_list *dev_head, struct mountdev_list *mounts)
{ {
DIR *topproc_dir; DIR *topproc_dir;
struct dirent *topproc_dent; struct dirent *topproc_dent;
@@ -137,6 +141,9 @@ static void scan_procs(struct names *nam @@ -137,6 +147,9 @@ static void scan_procs(struct names *nam
pid_t pid, my_pid; pid_t pid, my_pid;
uid_t uid; uid_t uid;
struct stat *cwd_stat, *exe_stat, *root_stat; struct stat *cwd_stat, *exe_stat, *root_stat;
@ -88,7 +95,7 @@
if ( (fd_dirpath = malloc(MAX_PATHNAME)) == NULL) if ( (fd_dirpath = malloc(MAX_PATHNAME)) == NULL)
return; return;
@@ -157,19 +164,30 @@ static void scan_procs(struct names *nam @@ -157,9 +170,10 @@ static void scan_procs(struct names *nam
continue; continue;
uid = getpiduid(pid); uid = getpiduid(pid);
@ -101,50 +108,43 @@
+ exe_stat = get_pidstat(opts, pid, "exe", exe_real); + exe_stat = get_pidstat(opts, pid, "exe", exe_real);
/* Scan the devices */ /* Scan the devices */
for (dev_tmp = dev_head ; dev_tmp != NULL ; dev_tmp = dev_tmp->next) { for (dev_tmp = dev_head ; dev_tmp != NULL ; dev_tmp = dev_tmp->next) {
+ const char* filename = dev_tmp->name->filename;
+ size_t len = strlen(filename);
if (exe_stat != NULL && exe_stat->st_dev == dev_tmp->device) if (exe_stat != NULL && exe_stat->st_dev == dev_tmp->device)
add_matched_proc(dev_tmp->name, pid, uid, ACCESS_EXE); @@ -168,6 +182,14 @@ static void scan_procs(struct names *nam
if (root_stat != NULL && root_stat->st_dev == dev_tmp->device)
add_matched_proc(dev_tmp->name, pid, uid, ACCESS_ROOT); add_matched_proc(dev_tmp->name, pid, uid, ACCESS_ROOT);
if (cwd_stat != NULL && cwd_stat->st_dev == dev_tmp->device) if (cwd_stat != NULL && cwd_stat->st_dev == dev_tmp->device)
add_matched_proc(dev_tmp->name, pid, uid, ACCESS_CWD); add_matched_proc(dev_tmp->name, pid, uid, ACCESS_CWD);
+ if (exe_real[0] != '\0' && !strncmp(&exe_real[0], filename, len)) + if ((dev_tmp->name->name_space & NAMESPACE_NFS) == 0)
+ continue;
+ if (islocatedon(&exe_real[0], dev_tmp->name->filename))
+ add_matched_proc(dev_tmp->name, pid, uid, ACCESS_EXE); + add_matched_proc(dev_tmp->name, pid, uid, ACCESS_EXE);
+ if (root_real[0] != '\0' && !strncmp(&root_real[0], filename, len)) + if (islocatedon(&root_real[0], dev_tmp->name->filename))
+ add_matched_proc(dev_tmp->name, pid, uid, ACCESS_ROOT); + add_matched_proc(dev_tmp->name, pid, uid, ACCESS_ROOT);
+ if (cwd_real[0] != '\0' && !strncmp(&cwd_real[0], filename, len)) + if (islocatedon(&cwd_real[0], dev_tmp->name->filename))
+ add_matched_proc(dev_tmp->name, pid, uid, ACCESS_CWD); + add_matched_proc(dev_tmp->name, pid, uid, ACCESS_CWD);
} }
for (ino_tmp = ino_head ; ino_tmp != NULL ; ino_tmp = ino_tmp->next) { for (ino_tmp = ino_head ; ino_tmp != NULL ; ino_tmp = ino_tmp->next) {
+ const char* filename = ino_tmp->name->filename;
+ size_t len = strlen(filename);
if (exe_stat != NULL) { if (exe_stat != NULL) {
if (exe_stat->st_dev == ino_tmp->device && exe_stat->st_ino == ino_tmp->inode) { @@ -186,9 +208,19 @@ static void scan_procs(struct names *nam
add_matched_proc(ino_tmp->name, pid, uid, ACCESS_EXE);
@@ -186,6 +204,21 @@ static void scan_procs(struct names *nam
add_matched_proc(ino_tmp->name, pid, uid, ACCESS_CWD); add_matched_proc(ino_tmp->name, pid, uid, ACCESS_CWD);
} }
} }
+ if (exe_real[0] != '\0') { + if ((ino_tmp->name->name_space & NAMESPACE_NFS) == 0)
+ if (!strncmp(&exe_real[0], filename, len)) { + continue;
+ if (islocatedon(&exe_real[0], ino_tmp->name->filename))
+ add_matched_proc(ino_tmp->name, pid, uid, ACCESS_EXE); + add_matched_proc(ino_tmp->name, pid, uid, ACCESS_EXE);
+ } + if (islocatedon(&root_real[0], ino_tmp->name->filename))
+ }
+ if (root_real[0] != '\0') {
+ if (!strncmp(&root_real[0], filename, len)) {
+ add_matched_proc(ino_tmp->name, pid, uid, ACCESS_ROOT); + add_matched_proc(ino_tmp->name, pid, uid, ACCESS_ROOT);
+ } + if (islocatedon(&cwd_real[0], ino_tmp->name->filename))
+ }
+ if (cwd_real[0] != '\0') {
+ if (!strncmp(&cwd_real[0], filename, len)) {
+ add_matched_proc(ino_tmp->name, pid, uid, ACCESS_CWD); + add_matched_proc(ino_tmp->name, pid, uid, ACCESS_CWD);
+ }
+ }
} }
+#ifndef __linux__
check_dir(pid, "lib", dev_head, ino_head, uid, ACCESS_MMAP); check_dir(pid, "lib", dev_head, ino_head, uid, ACCESS_MMAP);
check_dir(pid, "mmap", dev_head, ino_head, uid, ACCESS_MMAP); check_dir(pid, "mmap", dev_head, ino_head, uid, ACCESS_MMAP);
@@ -325,10 +358,26 @@ int parse_mount(struct names *this_name, +#endif
check_dir(pid, "fd", dev_head, ino_head, uid, ACCESS_FILE);
check_map(pid, "maps", dev_head, ino_head, uid, ACCESS_MMAP);
@@ -325,10 +357,26 @@ int parse_mount(struct names *this_name,
return 0; return 0;
} }
@ -172,7 +172,7 @@
if (stat(this_name->filename, &st) != 0) { if (stat(this_name->filename, &st) != 0) {
fprintf(stderr,_("Cannot stat %s: %s\n"), this_name->filename, fprintf(stderr,_("Cannot stat %s: %s\n"), this_name->filename,
strerror(errno)); strerror(errno));
@@ -342,34 +391,44 @@ int parse_file(struct names *this_name, @@ -342,34 +390,44 @@ int parse_file(struct names *this_name,
return 0; return 0;
} }
@ -224,7 +224,7 @@
if (stat(this_name->filename, &st) != 0) { if (stat(this_name->filename, &st) != 0) {
fprintf(stderr,_("Cannot stat %s: %s\n"), this_name->filename, fprintf(stderr,_("Cannot stat %s: %s\n"), this_name->filename,
@@ -388,6 +447,16 @@ int parse_mounts(struct names *this_name @@ -388,6 +446,16 @@ int parse_mounts(struct names *this_name
} }
} }
return 0; return 0;
@ -232,8 +232,8 @@
+ match_device = -1; + match_device = -1;
+ for (mountptr = mounts ; mountptr != NULL ; mountptr = mountptr->next) { + for (mountptr = mounts ; mountptr != NULL ; mountptr = mountptr->next) {
+ if (strcmp(mountptr->dir, real) == 0) { + if (strcmp(mountptr->dir, real) == 0) {
+ printf("Debug: adding parse_mounts() adding %s\n", + /*printf("Debug: adding parse_mounts() adding %s\n",
+ this_name->filename); + this_name->filename);*/
+ add_device(dev_list, this_name, match_device); + add_device(dev_list, this_name, match_device);
+ } + }
+ } + }
@ -241,47 +241,10 @@
} }
#ifdef WITH_IPV6 #ifdef WITH_IPV6
@@ -652,6 +721,117 @@ void find_net6_sockets(struct inode_list @@ -652,6 +720,80 @@ void find_net6_sockets(struct inode_list
} }
#endif #endif
+/*
+ * Remember all NFS typed partitions.
+ */
+static void init_nfs(void)
+{
+ struct stat st;
+ struct mntent * ent;
+ FILE * mnt;
+
+ mnts = (struct nfs_points*)0;
+
+ if (stat("/proc/version", &st) < 0)
+ return;
+ if ((mnt = setmntent("/proc/mounts", "r")) == (FILE*)0)
+ return;
+
+ while ((ent = getmntent(mnt))) {
+ if (!strcasecmp(MNTTYPE_NFS, ent->mnt_type)) {
+ struct nfs_points * p = (struct nfs_points*)malloc(sizeof(struct nfs_points));
+ if (!p)
+ goto out;
+ p->name = (char*)malloc(strlen(ent->mnt_dir)+1);
+ if (!p->name)
+ goto out;
+ strcpy(p->name, ent->mnt_dir);
+ p->nlen = strlen(p->name);
+ if (mnts)
+ mnts->prev = p;
+ p->next = mnts;
+ p->prev = (struct nfs_points*)0;
+ mnts = p;
+ }
+ }
+out:
+ endmntent(mnt);
+}
+
+/* +/*
+ * Check path is located on a NFS partition. + * Check path is located on a NFS partition.
+ */ + */
@ -359,7 +322,7 @@
int main(int argc, char *argv[]) int main(int argc, char *argv[])
{ {
opt_type opts; opt_type opts;
@@ -664,7 +844,7 @@ int main(int argc, char *argv[]) @@ -664,7 +806,7 @@ int main(int argc, char *argv[])
struct device_list *match_devices = NULL; struct device_list *match_devices = NULL;
struct unixsocket_list *unixsockets = NULL; struct unixsocket_list *unixsockets = NULL;
@ -368,7 +331,7 @@
struct ip_connections *tcp_connection_list = NULL; struct ip_connections *tcp_connection_list = NULL;
struct ip_connections *udp_connection_list = NULL; struct ip_connections *udp_connection_list = NULL;
#ifdef WITH_IPV6 #ifdef WITH_IPV6
@@ -691,10 +871,6 @@ int main(int argc, char *argv[]) @@ -691,10 +833,6 @@ int main(int argc, char *argv[])
textdomain(PACKAGE); textdomain(PACKAGE);
#endif #endif
@ -379,19 +342,18 @@
/* getopt doesnt like things like -SIGBLAH */ /* getopt doesnt like things like -SIGBLAH */
for(optc = 1; optc < argc; optc++) { for(optc = 1; optc < argc; optc++) {
if (argv[optc][0] == '-') { /* its an option */ if (argv[optc][0] == '-') { /* its an option */
@@ -782,6 +958,11 @@ int main(int argc, char *argv[]) @@ -782,6 +920,10 @@ int main(int argc, char *argv[])
} }
continue; continue;
} }
+ +
+ init_nfs();
+ scan_mount_devices(opts, &mount_devices); + scan_mount_devices(opts, &mount_devices);
+ fill_unix_cache(&unixsockets); + fill_unix_cache(&unixsockets);
+ +
/* File specifications */ /* File specifications */
if ( (this_name = malloc(sizeof(struct names))) == NULL) if ( (this_name = malloc(sizeof(struct names))) == NULL)
continue; continue;
@@ -828,8 +1009,8 @@ int main(int argc, char *argv[]) @@ -828,8 +970,8 @@ int main(int argc, char *argv[])
break; break;
default: /* FILE */ default: /* FILE */
this_name->filename = strdup(argv[optc]); this_name->filename = strdup(argv[optc]);
@ -402,7 +364,7 @@
if (opts & OPT_MOUNTPOINT || opts & OPT_MOUNTS) if (opts & OPT_MOUNTPOINT || opts & OPT_MOUNTS)
parse_mounts(this_name, mount_devices, &match_devices, opts); parse_mounts(this_name, mount_devices, &match_devices, opts);
break; break;
@@ -857,22 +1038,22 @@ int main(int argc, char *argv[]) @@ -857,22 +999,22 @@ int main(int argc, char *argv[])
if (!ipv4_only) { if (!ipv4_only) {
#endif #endif
if (tcp_connection_list != NULL) if (tcp_connection_list != NULL)
@ -423,14 +385,15 @@
} }
#endif #endif
#ifdef DEBUG #ifdef DEBUG
debug_match_lists(names_head, match_inodes, match_devices); - debug_match_lists(names_head, match_inodes, match_devices);
+ debug_match_lists(names_head, match_inodes, match_devices, mount_devices);
#endif #endif
- scan_procs(names_head, match_inodes, match_devices); - scan_procs(names_head, match_inodes, match_devices);
+ scan_procs(opts, names_head, match_inodes, match_devices); + scan_procs(opts, names_head, match_inodes, match_devices, mount_devices);
#ifdef NFS_CHECKS #ifdef NFS_CHECKS
scan_knfsd(names_head, match_devices); scan_knfsd(names_head, match_devices);
#endif /* NFS_CHECKS */ #endif /* NFS_CHECKS */
@@ -978,7 +1159,7 @@ static int print_matches(struct names *n @@ -978,7 +1120,7 @@ static int print_matches(struct names *n
} }
@ -439,7 +402,7 @@
{ {
char pathname[256]; char pathname[256];
struct stat *st; struct stat *st;
@@ -986,6 +1167,10 @@ static struct stat *get_pidstat(const pi @@ -986,6 +1128,10 @@ static struct stat *get_pidstat(const pi
if ( (st = malloc(sizeof(struct stat))) == NULL) if ( (st = 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);
@ -450,7 +413,14 @@
if (stat(pathname, st) != 0) if (stat(pathname, st) != 0)
return NULL; return NULL;
else else
@@ -1019,6 +1204,8 @@ static void check_dir(const pid_t pid, c @@ -1012,13 +1158,14 @@ static void check_dir(const pid_t pid, c
while ( (direntry = readdir(dirp)) != NULL) {
if (direntry->d_name[0] < '0' || direntry->d_name[0] > '9')
continue;
-
snprintf(filepath, MAX_PATHNAME, "/proc/%d/%s/%s",
pid, dirname, direntry->d_name);
if (stat(filepath, &st) != 0) {
fprintf(stderr, _("Cannot stat file %s: %s\n"),filepath, strerror(errno)); fprintf(stderr, _("Cannot stat file %s: %s\n"),filepath, strerror(errno));
} else { } else {
for (dev_tmp = dev_head ; dev_tmp != NULL ; dev_tmp = dev_tmp->next) { for (dev_tmp = dev_head ; dev_tmp != NULL ; dev_tmp = dev_tmp->next) {
@ -459,7 +429,7 @@
if (st.st_dev == dev_tmp->device) { if (st.st_dev == dev_tmp->device) {
if (access == ACCESS_FILE && (lstat(filepath, &lst)==0) && (lst.st_mode & S_IWUSR)) { if (access == ACCESS_FILE && (lstat(filepath, &lst)==0) && (lst.st_mode & S_IWUSR)) {
add_matched_proc(dev_tmp->name, pid,uid, ACCESS_FILEWR|access); add_matched_proc(dev_tmp->name, pid,uid, ACCESS_FILEWR|access);
@@ -1028,6 +1215,8 @@ static void check_dir(const pid_t pid, c @@ -1028,6 +1175,8 @@ static void check_dir(const pid_t pid, c
} }
} }
for (ino_tmp = ino_head ; ino_tmp != NULL ; ino_tmp = ino_tmp->next) { for (ino_tmp = ino_head ; ino_tmp != NULL ; ino_tmp = ino_tmp->next) {
@ -468,7 +438,16 @@
if (st.st_dev == ino_tmp->device && st.st_ino == ino_tmp->inode) { if (st.st_dev == ino_tmp->device && st.st_ino == ino_tmp->inode) {
if (access == ACCESS_FILE && (lstat(filepath, &lst)==0) && (lst.st_mode & S_IWUSR)) { if (access == ACCESS_FILE && (lstat(filepath, &lst)==0) && (lst.st_mode & S_IWUSR)) {
add_matched_proc(ino_tmp->name, pid,uid, ACCESS_FILEWR|access); add_matched_proc(ino_tmp->name, pid,uid, ACCESS_FILEWR|access);
@@ -1059,12 +1248,18 @@ static void check_map(const pid_t pid, c @@ -1039,6 +1188,8 @@ static void check_dir(const pid_t pid, c
}
} /* while fd_dent */
closedir(dirp);
+ free(dirpath);
+ free(filepath);
}
static void check_map(const pid_t pid, const char *filename, struct device_list *dev_head, struct inode_list *ino_head, const uid_t uid, const char access)
@@ -1059,12 +1210,18 @@ static void check_map(const pid_t pid, c
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) {
tmp_device = tmp_maj * 256 + tmp_min; tmp_device = tmp_maj * 256 + tmp_min;
@ -489,39 +468,62 @@
} }
} }
fclose(fp); fclose(fp);
@@ -1144,6 +1339,7 @@ void scan_mount_devices(const opt_type o @@ -1144,22 +1301,48 @@ void scan_mount_devices(const opt_type o
FILE *mntfp; FILE *mntfp;
struct mntent *mnt_ptr; struct mntent *mnt_ptr;
struct stat st; struct stat st;
+ char real[PATH_MAX+1] = ""; -
- if ( (mntfp = setmntent("/etc/mtab","r")) == NULL) {
if ( (mntfp = setmntent("/etc/mtab","r")) == NULL) { - fprintf(stderr, _("Cannot open /etc/mtab: %s\n"),
fprintf(stderr, _("Cannot open /etc/mtab: %s\n"), - strerror(errno));
@@ -1151,10 +1347,22 @@ void scan_mount_devices(const opt_type o +
+ if (stat("/proc/version", &st) < 0)
+ mntfp = setmntent("/etc/mtab","r");
+ else
+ mntfp = setmntent("/proc/mounts", "r");
+ if (mntfp == NULL) {
+ fprintf(stderr, _("Cannot open /etc/mtab: %s\n"), strerror(errno));
return; return;
} }
while ( (mnt_ptr = getmntent(mntfp)) != NULL) { while ( (mnt_ptr = getmntent(mntfp)) != NULL) {
+ real[0] = '\0'; + if (!strcasecmp(MNTTYPE_NFS, mnt_ptr->mnt_type)) {
+ if (check4nfs(mnt_ptr->mnt_dir, real)) { + /*
+ * Remember all NFS typed partitions.
+ */
+ struct nfs_points * p = (struct nfs_points*)malloc(sizeof(struct nfs_points));
+ if (!p)
+ goto out;
+ p->name = strdup(mnt_ptr->mnt_dir);
+ if (!p->name)
+ goto out;
+ p->nlen = strlen(p->name);
+ if (mnts)
+ mnts->prev = p;
+ p->next = mnts;
+ p->prev = (struct nfs_points*)0;
+ mnts = p;
+ if ((opts & (OPT_MOUNTPOINT|OPT_MOUNTS)) == 0) { + if ((opts & (OPT_MOUNTPOINT|OPT_MOUNTS)) == 0) {
+ add_mount_device(mount_devices, mnt_ptr->mnt_fsname, real, (dev_t)-1); + add_mount_device(mount_devices, mnt_ptr->mnt_fsname, mnt_ptr->mnt_dir, (dev_t)-1);
+ continue; + continue;
+ } + }
+ }
+ if ((real[0] != '\0') && (stat(real, &st) == 0)) {
+ add_mount_device(mount_devices, mnt_ptr->mnt_fsname, real, st.st_dev);
+ continue;
+ } + }
if (stat(mnt_ptr->mnt_dir, &st) == 0) { if (stat(mnt_ptr->mnt_dir, &st) == 0) {
add_mount_device(mount_devices, mnt_ptr->mnt_fsname, mnt_ptr->mnt_dir, st.st_dev); add_mount_device(mount_devices, mnt_ptr->mnt_fsname, mnt_ptr->mnt_dir, st.st_dev);
} }
} }
+out:
+ endmntent(mntfp); + endmntent(mntfp);
} }
#ifdef DEBUG #ifdef DEBUG
/* often not used, doesnt need translation */
-static void debug_match_lists(struct names *names_head, struct inode_list *ino_head, struct device_list *dev_head)
+static void debug_match_lists(struct names *names_head, struct inode_list *ino_head, struct device_list *dev_head, )
{
struct names *nptr;
struct inode_list *iptr;
--- src/fuser.h --- src/fuser.h
+++ src/fuser.h 2007-12-19 18:50:05.501016000 +0100 +++ src/fuser.h 2008-08-07 14:26:47.587191317 +0200
@@ -80,9 +80,16 @@ struct unixsocket_list { @@ -80,9 +80,16 @@ struct unixsocket_list {
struct unixsocket_list *next; struct unixsocket_list *next;
}; };

148
psmisc-22.6-writeonly.patch Normal file
View File

@ -0,0 +1,148 @@
--- doc/fuser.1
+++ doc/fuser.1 2008-08-07 14:51:18.000000000 +0200
@@ -10,6 +10,7 @@ fuser \- identify processes using files
.IR space\ ]
.RB [ \-k
.RB [ \-i ]
+.RB [ \-w ]
.RB [ \- \fIsignal
] ]
.RB [ \-muvf ]
@@ -74,6 +75,9 @@ other \fBfuser\fP processes. The effecti
.IP \fB\-i\fP
Ask the user for confirmation before killing a process. This option is
silently ignored if \fB\-k\fP is not present too.
+.IP \fB\-w\fP
+Kill only processes which have write access. This option is
+silently ignored if \fB\-k\fP is not present too.
.IP \fB\-l\fP
List all known signal names.
.IP \fB\-m\fP
--- src/fuser.c
+++ src/fuser.c 2008-08-07 15:49:28.714368021 +0200
@@ -66,7 +66,7 @@ static void check_map(const pid_t pid, c
static struct stat *get_pidstat(const opt_type opts, const pid_t pid, const char *filename, char *real);
static uid_t getpiduid(const pid_t pid);
static int print_matches(struct names *names_head, const opt_type opts, const int sig_number);
-static void kill_matched_proc(struct procs *pptr, const opt_type opts, const int sig_number);
+static int kill_matched_proc(struct procs *pptr, const opt_type opts, const int sig_number);
int parse_mount(struct names *this_name, struct device_list **dev_list);
static void add_device(struct device_list **dev_list, struct names *this_name, dev_t device);
@@ -89,7 +89,7 @@ static void usage (const char *errormsg)
fprintf(stderr, "%s\n", errormsg);
fprintf (stderr, _(
- "Usage: fuser [ -a | -s | -c ] [ -n SPACE ] [ -SIGNAL ] [ -kimuv ] NAME...\n"
+ "Usage: fuser [ -a | -s | -c ] [ -n SPACE ] [ -SIGNAL ] [ -kimuvw ] NAME...\n"
" [ - ] [ -n SPACE ] [ -SIGNAL ] [ -kimuv ] NAME...\n"
" fuser -l\n"
" fuser -V\n"
@@ -106,6 +106,7 @@ static void usage (const char *errormsg)
" -SIGNAL send this signal instead of SIGKILL\n"
" -u display user IDs\n"
" -v verbose output\n"
+ " -w kill only processes with write access\n"
" -V display version information\n"));
#ifdef WITH_IPV6
fprintf (stderr, _(
@@ -901,6 +902,9 @@ int main(int argc, char *argv[])
case 'v':
opts |= OPT_VERBOSE;
break;
+ case 'w':
+ opts |= OPT_WRITE;
+ break;
case 'V':
print_version();
return 0;
@@ -1033,6 +1037,7 @@ static int print_matches(struct names *n
int len = 0;
struct passwd *pwent = NULL;
int have_match = 0;
+ int have_kill = 0;
for (nptr = names_head; nptr != NULL ; nptr = nptr->next) {
if (opts & OPT_SILENT) {
@@ -1103,21 +1108,23 @@ static int print_matches(struct names *n
len = 0;
first = 0;
}
- if (opts & OPT_VERBOSE) {
- /* put a newline if showing all files and no procs*/
- if (nptr->matched_procs == NULL && (opts & OPT_ALLFILES))
- putc('\n', stderr);
- } else {
- if (nptr->matched_procs != NULL || (opts & OPT_ALLFILES))
- putc('\n', stderr);
- }
+ if (opts & OPT_VERBOSE) {
+ /* put a newline if showing all files and no procs*/
+ if (nptr->matched_procs == NULL && (opts & OPT_ALLFILES))
+ putc('\n', stderr);
+ } else {
+ if (nptr->matched_procs != NULL || (opts & OPT_ALLFILES))
+ putc('\n', stderr);
+ }
} /* be silent */
if (opts & OPT_KILL)
- kill_matched_proc(nptr->matched_procs, opts, sig_number);
+ have_kill = kill_matched_proc(nptr->matched_procs, opts, sig_number);
} /* next name */
- return (have_match==1?0:1);
-
+ if (opts & OPT_KILL)
+ return (have_kill==1?0:1);
+ else
+ return (have_match==1?0:1);
}
static struct stat *get_pidstat(const opt_type opts, const pid_t pid, const char *filename, char *real)
@@ -1403,21 +1410,26 @@ static int ask(const pid_t pid)
} /* while */
}
-static void kill_matched_proc(struct procs *proc_head, const opt_type opts, const int sig_number)
+static int kill_matched_proc(struct procs *proc_head, const opt_type opts, const int sig_number)
{
struct procs *pptr;
+ int ret = 0;
for (pptr = proc_head ; pptr != NULL ; pptr = pptr->next ) {
if ( (opts & OPT_INTERACTIVE) && (ask(pptr->pid) == 0))
continue;
+ if ((opts & OPT_WRITE) && ((pptr->access & ACCESS_FILEWR) == 0))
+ continue;
if ( kill (pptr->pid, sig_number) < 0) {
fprintf(stderr, _("Could not kill process %d: %s\n"),
pptr->pid,
strerror(errno)
);
+ continue;
}
-
+ ret = 1;
}
+ return ret;
}
static dev_t find_net_dev(void)
--- src/fuser.h
+++ src/fuser.h 2008-08-07 14:26:48.000000000 +0200
@@ -1,6 +1,6 @@
/* Option Flags */
-typedef unsigned char opt_type;
+typedef unsigned short opt_type;
#define OPT_VERBOSE 1
#define OPT_ALLFILES 2
@@ -10,6 +10,7 @@ typedef unsigned char opt_type;
#define OPT_SILENT 32
#define OPT_USER 64
#define OPT_MOUNTPOINT 128
+#define OPT_WRITE 256
struct procs {

View File

@ -1,3 +1,9 @@
-------------------------------------------------------------------
Thu Aug 7 15:12:14 CEST 2008 - werner@suse.de
- Refine NFS patch
- Add option -w for killing only procs with write access
------------------------------------------------------------------- -------------------------------------------------------------------
Fri May 16 17:19:31 CEST 2008 - werner@suse.de Fri May 16 17:19:31 CEST 2008 - werner@suse.de

View File

@ -2,9 +2,16 @@
# spec file for package psmisc (Version 22.6) # spec file for package psmisc (Version 22.6)
# #
# Copyright (c) 2008 SUSE LINUX Products GmbH, Nuernberg, Germany. # Copyright (c) 2008 SUSE LINUX Products GmbH, Nuernberg, Germany.
# This file and all modifications and additions to the pristine
# package are under the same license as the package itself.
# #
# All modifications and additions to the file contributed by third parties
# remain the property of their copyright owners, unless otherwise agreed
# upon. The license for this file, and modifications and additions to the
# file, is the same license as for the pristine package itself (unless the
# license for the pristine package is not an Open Source License, in which
# case the license is the MIT License). An "Open Source License" is a
# license that conforms to the Open Source Definition (Version 1.9)
# published by the Open Source Initiative.
# Please submit bugfixes or comments via http://bugs.opensuse.org/ # Please submit bugfixes or comments via http://bugs.opensuse.org/
# #
@ -19,7 +26,7 @@ Group: System/Monitoring
PreReq: %fillup_prereq %insserv_prereq PreReq: %fillup_prereq %insserv_prereq
AutoReqProv: on AutoReqProv: on
Version: 22.6 Version: 22.6
Release: 28 Release: 42
Provides: ps:/usr/bin/killall Provides: ps:/usr/bin/killall
Summary: Utilities for managing processes on your system Summary: Utilities for managing processes on your system
Source: http://switch.dl.sourceforge.net/sourceforge/psmisc/psmisc-%{version}.tar.bz2 Source: http://switch.dl.sourceforge.net/sourceforge/psmisc/psmisc-%{version}.tar.bz2
@ -27,6 +34,7 @@ Patch0: %name-%version.dif
Patch1: %name-22.5-pstree.patch Patch1: %name-22.5-pstree.patch
Patch2: %name-22.6-nfs4fuser.patch Patch2: %name-22.6-nfs4fuser.patch
Patch3: %name-22.6-netunix.patch Patch3: %name-22.6-netunix.patch
Patch4: %name-22.6-writeonly.patch
BuildRoot: %{_tmppath}/%{name}-%{version}-build BuildRoot: %{_tmppath}/%{name}-%{version}-build
%define nopeek s390 s390x ia64 %define nopeek s390 s390x ia64
@ -49,6 +57,7 @@ Authors:
%patch1 -p0 -b .pstree %patch1 -p0 -b .pstree
%patch2 -p0 -b .nfs4fuser %patch2 -p0 -b .nfs4fuser
%patch3 -p0 -b .netunix %patch3 -p0 -b .netunix
%patch4 -p0 -b .wrtonly
%patch0 -p0 %patch0 -p0
%build %build
@ -91,6 +100,9 @@ rm -rf $RPM_BUILD_ROOT
%{_mandir}/man1/pstree.1* %{_mandir}/man1/pstree.1*
%changelog %changelog
* Thu Aug 07 2008 werner@suse.de
- Refine NFS patch
- Add option -w for killing only procs with write access
* Fri May 16 2008 werner@suse.de * Fri May 16 2008 werner@suse.de
- Add a warning about fusers option -m due NFS locks - Add a warning about fusers option -m due NFS locks
- Strip @ symbol from file names read from /proc/net/unix - Strip @ symbol from file names read from /proc/net/unix