fix problem with threads
This commit is contained in:
parent
b2d859f860
commit
0ccc9f3c53
@ -1,7 +1,7 @@
|
||||
Summary: A utility which lists open files on a Linux/UNIX system.
|
||||
Name: lsof
|
||||
Version: 4.78
|
||||
Release: 1
|
||||
Release: 2
|
||||
License: Free
|
||||
%define lsofrh lsof_4.78C-rh
|
||||
Group: Development/Debuggers
|
||||
@ -12,6 +12,8 @@ BuildRoot: %{_tmppath}/%{name}-root
|
||||
|
||||
BuildRequires: libselinux-devel
|
||||
|
||||
Patch1: lsof_4.78C-threads.patch
|
||||
|
||||
%description
|
||||
Lsof stands for LiSt Open Files, and it does just that: it lists
|
||||
information about files that are open by the processes running on a
|
||||
@ -20,6 +22,8 @@ UNIX system.
|
||||
%prep
|
||||
%setup -q -n %{lsofrh}
|
||||
|
||||
%patch1 -p1 -b .kzak
|
||||
|
||||
%build
|
||||
LSOF_VSTR=2.6.16 LINUX_BASE=/proc ./Configure -n linux
|
||||
|
||||
@ -42,6 +46,9 @@ rm -rf ${RPM_BUILD_ROOT}
|
||||
%{_mandir}/man*/*
|
||||
|
||||
%changelog
|
||||
* Wed Aug 9 2006 Karel Zak <kzak@redhat.com> 4.78-2
|
||||
- fix #184338 - allow lsof access nptl threads
|
||||
|
||||
* Wed Jul 19 2006 Karel Zak <kzak@redhat.com> 4.78-1
|
||||
- rebuild
|
||||
|
||||
|
124
lsof_4.78C-threads.patch
Normal file
124
lsof_4.78C-threads.patch
Normal file
@ -0,0 +1,124 @@
|
||||
--- lsof_4.78C-rh/dialects/linux/dproc.c.kzak 2006-06-12 19:10:05.000000000 +0200
|
||||
+++ lsof_4.78C-rh/dialects/linux/dproc.c 2006-08-09 23:25:14.000000000 +0200
|
||||
@@ -69,7 +69,8 @@
|
||||
_PROTOTYPE(static int read_proc_stat,(char *p, int pid, char **cmd, int *ppid,
|
||||
int *pgid));
|
||||
_PROTOTYPE(static int statEx,(char *p, struct stat *s, int *ss));
|
||||
-
|
||||
+_PROTOTYPE(static int get_other_thread,(int pid, char **tid));
|
||||
+
|
||||
|
||||
#if defined(HASSELINUX)
|
||||
_PROTOTYPE(static int cmp_cntx_eq,(char *pcntx, char *ucntx));
|
||||
@@ -148,6 +149,7 @@
|
||||
static char *path = (char *)NULL;
|
||||
static int pathl = 0;
|
||||
int pgid, pid, ppid;
|
||||
+ char *tid = NULL;
|
||||
static char *pidpath = (char *)NULL;
|
||||
static MALLOC_S pidpathl = 0;
|
||||
static MALLOC_S pidx = 0;
|
||||
@@ -253,6 +255,13 @@
|
||||
}
|
||||
if (f)
|
||||
continue;
|
||||
+
|
||||
+ tid = NULL;
|
||||
+ if (get_other_thread(pid, &tid) < 0)
|
||||
+ continue;
|
||||
+ if (tid)
|
||||
+ n += sizeof("task/") + strlen(tid);
|
||||
+
|
||||
/*
|
||||
* Build path to PID's directory.
|
||||
*/
|
||||
@@ -266,7 +275,14 @@
|
||||
Exit(1);
|
||||
}
|
||||
}
|
||||
- (void) snpf(pidpath + pidx, pidpathl - pidx, "%s/", dp->d_name);
|
||||
+ if (tid) {
|
||||
+ /* /proc/<pid> is useless (zombie), we have to use /proc/<pid>/task/<tid>
|
||||
+ * where is still running thread
|
||||
+ */
|
||||
+ (void) snpf(pidpath + pidx, pidpathl - pidx, "%s/task/%s/", dp->d_name, tid);
|
||||
+ free(tid);
|
||||
+ } else
|
||||
+ (void) snpf(pidpath + pidx, pidpathl - pidx, "%s/", dp->d_name);
|
||||
n += (pidx + 1);
|
||||
/*
|
||||
* Process the PID's stat info.
|
||||
@@ -897,6 +913,60 @@
|
||||
(void) fclose(ms);
|
||||
}
|
||||
|
||||
+/* fill tid if the initial thread is zombie,
|
||||
+ * but other thread still alive
|
||||
+ *
|
||||
+ * returns -1=error, 0=nothing, 1=ok
|
||||
+ */
|
||||
+static int
|
||||
+get_other_thread(pid, tid)
|
||||
+ int pid;
|
||||
+ char **tid;
|
||||
+{
|
||||
+ char path[MAXPATHLEN];
|
||||
+ DIR *tdp;
|
||||
+ struct dirent *td;
|
||||
+ char pstate;
|
||||
+ FILE *f;
|
||||
+ int _pid;
|
||||
+ int re = 0;
|
||||
+
|
||||
+ snpf(path, sizeof(path), "%s/%d/stat", PROCFS, pid);
|
||||
+ if (!(f = fopen(path, "r")))
|
||||
+ return;
|
||||
+ fscanf(f, "%d %*s %c", &_pid, &pstate);
|
||||
+ fclose(f);
|
||||
+ if (_pid != pid)
|
||||
+ return -1; /* corrupted /proc? */
|
||||
+ if (pstate!='Z')
|
||||
+ return 0; /* ignore normal proceses */
|
||||
+
|
||||
+ snpf(path, sizeof(path), "%s/%d/task", PROCFS, pid);
|
||||
+
|
||||
+ /* open /proc/<pid>/task */
|
||||
+ if (!(tdp = opendir(path)))
|
||||
+ return 0; /* kernel < 2.6.x */
|
||||
+
|
||||
+ /* look for first alive thread */
|
||||
+ while ((td = readdir(tdp))) {
|
||||
+ if (strcmp(td->d_name, ".")==0 || strcmp(td->d_name, "..")==0)
|
||||
+ continue;
|
||||
+
|
||||
+ /* /proc/<pid>/task/<tid>/stat */
|
||||
+ snpf(path, sizeof(path), "%s/%d/task/%s/stat", PROCFS, pid, td->d_name);
|
||||
+ if (!(f = fopen(path, "r")))
|
||||
+ continue;
|
||||
+ fscanf(f, "%*d %*s %c", &pstate);
|
||||
+ fclose(f);
|
||||
+ if (pstate!='Z') {
|
||||
+ re = 1;
|
||||
+ *tid = strdup(td->d_name);
|
||||
+ break;
|
||||
+ }
|
||||
+ }
|
||||
+ closedir(tdp);
|
||||
+ return re;
|
||||
+}
|
||||
|
||||
/*
|
||||
* read_proc_stat() - read process status
|
||||
@@ -931,12 +1001,6 @@
|
||||
if ((nf = get_fields(buf, (char *)NULL, &fp, (int *)NULL, 0)) < 5)
|
||||
return(1);
|
||||
/*
|
||||
- * Convert the first field to an integer; its conversion must match the
|
||||
- * PID argument.
|
||||
- */
|
||||
- if (atoi(fp[0]) != pid)
|
||||
- return(1);
|
||||
-/*
|
||||
* Get the command name from the second field. Strip a starting '(' and
|
||||
* an ending ')'. Allocate space to hold the result and return the space
|
||||
* pointer.
|
Loading…
Reference in New Issue
Block a user