Use readlink() instead of stat() to check processes. This shold avoid
hanging if NFS mounts are not responding. Default to showing processes in the uninterruptable state (D). The -z flag no longer affects whether processes in D state are shown. The -z flag does still toggle whether zombie (Z) processes are shown.
This commit is contained in:
parent
665e707f51
commit
0b695c7e0b
@ -66,9 +66,12 @@ a status of true or false to indicate whether a matching PID was found.
|
|||||||
Scripts too - this causes the program to also return process id's of
|
Scripts too - this causes the program to also return process id's of
|
||||||
shells running the named scripts.
|
shells running the named scripts.
|
||||||
.IP \-z
|
.IP \-z
|
||||||
Try to detect processes which are stuck in uninterruptible (D) or zombie (Z)
|
Try to detect processes which are stuck in zombie (Z)
|
||||||
status. Usually these processes are skipped as trying to deal with them can cause
|
status. Usually these processes are skipped as trying to deal with them can cause
|
||||||
pidof to hang.
|
pidof or related tools to hang. Note: In the past pidof would ignore processes
|
||||||
|
in the uninterruptable state (D), unless the \-z flag was specified. This is no
|
||||||
|
longer the case. The pidof program will find and report processes in the D state
|
||||||
|
whether \-z is specified or not.
|
||||||
.IP "-d \fIsep\fP"
|
.IP "-d \fIsep\fP"
|
||||||
Tells \fIpidof\fP to use \fIsep\fP as an output separator if more than one PID
|
Tells \fIpidof\fP to use \fIsep\fP as an output separator if more than one PID
|
||||||
is shown. The default separator is a space.
|
is shown. The default separator is a space.
|
||||||
|
@ -67,9 +67,6 @@
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
#define STATNAMELEN 15
|
#define STATNAMELEN 15
|
||||||
#define DO_NETFS 2
|
|
||||||
#define DO_STAT 1
|
|
||||||
#define NO_STAT 0
|
|
||||||
|
|
||||||
/* Info about a process. */
|
/* Info about a process. */
|
||||||
typedef struct proc {
|
typedef struct proc {
|
||||||
@ -79,8 +76,6 @@ typedef struct proc {
|
|||||||
char *argv1; /* Name as found out from argv[1] */
|
char *argv1; /* Name as found out from argv[1] */
|
||||||
char *argv1base; /* `basename argv[1]` */
|
char *argv1base; /* `basename argv[1]` */
|
||||||
char *statname; /* the statname without braces */
|
char *statname; /* the statname without braces */
|
||||||
ino_t ino; /* Inode number */
|
|
||||||
dev_t dev; /* Device it is on */
|
|
||||||
pid_t pid; /* Process ID. */
|
pid_t pid; /* Process ID. */
|
||||||
pid_t sid; /* Session ID. */
|
pid_t sid; /* Session ID. */
|
||||||
char kernel; /* Kernel thread or zombie. */
|
char kernel; /* Kernel thread or zombie. */
|
||||||
@ -481,19 +476,17 @@ int readarg(FILE *fp, char *buf, int sz)
|
|||||||
* Read the proc filesystem.
|
* Read the proc filesystem.
|
||||||
* CWD must be /proc to avoid problems if / is affected by the killing (ie depend on fuse).
|
* CWD must be /proc to avoid problems if / is affected by the killing (ie depend on fuse).
|
||||||
*/
|
*/
|
||||||
int readproc(int do_stat)
|
int readproc()
|
||||||
{
|
{
|
||||||
DIR *dir;
|
DIR *dir;
|
||||||
FILE *fp;
|
FILE *fp;
|
||||||
PROC *p, *n;
|
PROC *p, *n;
|
||||||
struct dirent *d;
|
struct dirent *d;
|
||||||
struct stat st;
|
|
||||||
char path[PATH_MAX+1];
|
char path[PATH_MAX+1];
|
||||||
char buf[PATH_MAX+1];
|
char buf[PATH_MAX+1];
|
||||||
char *s, *q;
|
char *s, *q;
|
||||||
unsigned long startcode, endcode;
|
unsigned long startcode, endcode;
|
||||||
int pid, f;
|
int pid, f;
|
||||||
ssize_t len;
|
|
||||||
char process_status[11];
|
char process_status[11];
|
||||||
|
|
||||||
/* Open the /proc directory. */
|
/* Open the /proc directory. */
|
||||||
@ -600,12 +593,8 @@ int readproc(int do_stat)
|
|||||||
p->kernel = 1;
|
p->kernel = 1;
|
||||||
fclose(fp);
|
fclose(fp);
|
||||||
if ( (! list_dz_processes) &&
|
if ( (! list_dz_processes) &&
|
||||||
( (strchr(process_status, 'D') != NULL) ||
|
(strchr(process_status, 'Z') != NULL) ) {
|
||||||
(strchr(process_status, 'Z') != NULL) ) ){
|
/* Ignore zombie processes */
|
||||||
/* Ignore zombie processes or processes in
|
|
||||||
disk sleep, as attempts
|
|
||||||
to access the stats of these will
|
|
||||||
sometimes fail. */
|
|
||||||
if (p->argv0) free(p->argv0);
|
if (p->argv0) free(p->argv0);
|
||||||
if (p->argv1) free(p->argv1);
|
if (p->argv1) free(p->argv1);
|
||||||
if (p->statname) free(p->statname);
|
if (p->statname) free(p->statname);
|
||||||
@ -672,54 +661,9 @@ int readproc(int do_stat)
|
|||||||
|
|
||||||
/* Try to stat the executable. */
|
/* Try to stat the executable. */
|
||||||
snprintf(path, sizeof(path), "/proc/%s/exe", d->d_name);
|
snprintf(path, sizeof(path), "/proc/%s/exe", d->d_name);
|
||||||
|
p->pathname = (char *)xmalloc(PATH_MAX);
|
||||||
p->nfs = 0;
|
if (readlink(path, p->pathname, PATH_MAX) == -1) {
|
||||||
|
p->pathname = NULL;
|
||||||
switch (do_stat) {
|
|
||||||
case DO_NETFS:
|
|
||||||
if ((p->nfs = check4nfs(path, buf)))
|
|
||||||
goto link;
|
|
||||||
/* else fall through */
|
|
||||||
case DO_STAT:
|
|
||||||
if (stat(path, &st) != 0) {
|
|
||||||
char * ptr;
|
|
||||||
|
|
||||||
len = readlink(path, buf, PATH_MAX);
|
|
||||||
if (len <= 0)
|
|
||||||
break;
|
|
||||||
buf[len] = '\0';
|
|
||||||
|
|
||||||
ptr = strstr(buf, " (deleted)");
|
|
||||||
if (!ptr)
|
|
||||||
break;
|
|
||||||
*ptr = '\0';
|
|
||||||
len -= strlen(" (deleted)");
|
|
||||||
|
|
||||||
if (stat(buf, &st) != 0)
|
|
||||||
break;
|
|
||||||
p->dev = st.st_dev;
|
|
||||||
p->ino = st.st_ino;
|
|
||||||
p->pathname = (char *)xmalloc(len + 1);
|
|
||||||
memcpy(p->pathname, buf, len);
|
|
||||||
p->pathname[len] = '\0';
|
|
||||||
|
|
||||||
/* All done */
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
p->dev = st.st_dev;
|
|
||||||
p->ino = st.st_ino;
|
|
||||||
|
|
||||||
/* Fall through */
|
|
||||||
default:
|
|
||||||
link:
|
|
||||||
len = readlink(path, buf, PATH_MAX);
|
|
||||||
if (len > 0) {
|
|
||||||
p->pathname = (char *)xmalloc(len + 1);
|
|
||||||
memcpy(p->pathname, buf, len);
|
|
||||||
p->pathname[len] = '\0';
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Link it into the list. */
|
/* Link it into the list. */
|
||||||
@ -783,30 +727,21 @@ PIDQ_HEAD *pidof(char *prog)
|
|||||||
{
|
{
|
||||||
PROC *p;
|
PROC *p;
|
||||||
PIDQ_HEAD *q;
|
PIDQ_HEAD *q;
|
||||||
struct stat st;
|
|
||||||
char *s;
|
char *s;
|
||||||
int nfs = 0;
|
int nfs = 0;
|
||||||
int dostat = 0;
|
int dostat = 0;
|
||||||
int foundone = 0;
|
int foundone = 0;
|
||||||
int ok = 0;
|
int ok = 0;
|
||||||
const int root = (getuid() == 0);
|
const int root = (getuid() == 0);
|
||||||
char real[PATH_MAX+1];
|
char real_path[PATH_MAX+1];
|
||||||
|
|
||||||
if (! prog)
|
if (! prog)
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
/* Try to stat the executable. */
|
/* Try to stat the executable. */
|
||||||
if (prog[0] == '/') {
|
if ( (prog[0] == '/') && ( realpath(prog, real_path) ) ) {
|
||||||
memset(&real[0], 0, sizeof(real));
|
memset(&real_path[0], 0, sizeof(real_path));
|
||||||
|
dostat++;
|
||||||
if (check4nfs(prog, real))
|
|
||||||
nfs++;
|
|
||||||
|
|
||||||
if (real[0] != '\0')
|
|
||||||
prog = &real[0]; /* Binary located on network FS. */
|
|
||||||
|
|
||||||
if ((nfs == 0) && (stat(prog, &st) == 0))
|
|
||||||
dostat++; /* Binary located on a local FS. */
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Get basename of program. */
|
/* Get basename of program. */
|
||||||
@ -822,11 +757,9 @@ PIDQ_HEAD *pidof(char *prog)
|
|||||||
q = init_pid_q(q);
|
q = init_pid_q(q);
|
||||||
|
|
||||||
/* First try to find a match based on dev/ino pair. */
|
/* First try to find a match based on dev/ino pair. */
|
||||||
if (dostat && !nfs) {
|
if (dostat) {
|
||||||
for (p = plist; p; p = p->next) {
|
for (p = plist; p; p = p->next) {
|
||||||
if (p->nfs)
|
if (p->pathname && strcmp(real_path, p->pathname) == 0) {
|
||||||
continue;
|
|
||||||
if (p->dev == st.st_dev && p->ino == st.st_ino) {
|
|
||||||
add_pid_to_q(q, p);
|
add_pid_to_q(q, p);
|
||||||
foundone++;
|
foundone++;
|
||||||
}
|
}
|
||||||
@ -1086,7 +1019,7 @@ int main_pidof(int argc, char **argv)
|
|||||||
init_nfs(); /* Which network based FS are online? */
|
init_nfs(); /* Which network based FS are online? */
|
||||||
|
|
||||||
/* Print out process-ID's one by one. */
|
/* Print out process-ID's one by one. */
|
||||||
readproc((flags & PIDOF_NETFS) ? DO_NETFS : DO_STAT);
|
readproc();
|
||||||
|
|
||||||
for(f = 0; f < argc; f++) {
|
for(f = 0; f < argc; f++) {
|
||||||
if ((q = pidof(argv[f])) != NULL) {
|
if ((q = pidof(argv[f])) != NULL) {
|
||||||
@ -1224,7 +1157,7 @@ int main(int argc, char **argv)
|
|||||||
sent_sigstop = 1;
|
sent_sigstop = 1;
|
||||||
|
|
||||||
/* Read /proc filesystem */
|
/* Read /proc filesystem */
|
||||||
if (readproc(NO_STAT) < 0) {
|
if (readproc() < 0) {
|
||||||
kill(-1, SIGCONT);
|
kill(-1, SIGCONT);
|
||||||
return(1);
|
return(1);
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user