diff options
Diffstat (limited to 'geo-replication/src/procdiggy.c')
| -rw-r--r-- | geo-replication/src/procdiggy.c | 136 |
1 files changed, 136 insertions, 0 deletions
diff --git a/geo-replication/src/procdiggy.c b/geo-replication/src/procdiggy.c new file mode 100644 index 00000000000..8068ef79a42 --- /dev/null +++ b/geo-replication/src/procdiggy.c @@ -0,0 +1,136 @@ +/* + Copyright (c) 2011-2012 Red Hat, Inc. <http://www.redhat.com> + This file is part of GlusterFS. + + This file is licensed to you under your choice of the GNU Lesser + General Public License, version 3 or any later version (LGPLv3 or + later), or the GNU General Public License, version 2 (GPLv2), in all + cases as published by the Free Software Foundation. +*/ + +#include <stdlib.h> +#include <stdio.h> +#include <unistd.h> +#include <string.h> +#include <ctype.h> +#include <sys/param.h> /* for PATH_MAX */ + +#include <glusterfs/common-utils.h> +#include <glusterfs/syscall.h> +#include "procdiggy.h" + +pid_t +pidinfo(pid_t pid, char **name) +{ + char buf[NAME_MAX * 2] = { + 0, + }; + FILE *f = NULL; + char path[PATH_MAX] = { + 0, + }; + char *p = NULL; + int ret = 0; + pid_t lpid = -1; + + if (name) + *name = NULL; + + snprintf(path, sizeof path, PROC "/%d/status", pid); + + f = fopen(path, "r"); + if (!f) + return -1; + + for (;;) { + size_t len; + memset(buf, 0, sizeof(buf)); + if (fgets(buf, sizeof(buf), f) == NULL || (len = strlen(buf)) == 0 || + buf[len - 1] != '\n') { + lpid = -1; + goto out; + } + buf[len - 1] = '\0'; + + if (name && !*name) { + p = strtail(buf, "Name:"); + if (p) { + while (isspace(*++p)) + ; + *name = gf_strdup(p); + if (!*name) { + lpid = -2; + goto out; + } + continue; + } + } + + p = strtail(buf, "PPid:"); + if (p) + break; + } + + while (isspace(*++p)) + ; + ret = gf_string2int(p, &lpid); + if (ret == -1) + lpid = -1; + +out: + fclose(f); + if (lpid == -1 && name && *name) + GF_FREE(*name); + if (lpid == -2) + fprintf(stderr, "out of memory\n"); + return lpid; +} + +int +prociter(int (*proch)(pid_t pid, pid_t ppid, char *tmpname, void *data), + void *data) +{ + char *name = NULL; + DIR *d = NULL; + struct dirent *de = NULL; + struct dirent scratch[2] = { + { + 0, + }, + }; + pid_t pid = -1; + pid_t ppid = -1; + int ret = 0; + + d = sys_opendir(PROC); + if (!d) + return -1; + + for (;;) { + errno = 0; + de = sys_readdir(d, scratch); + if (!de || errno != 0) + break; + + if (gf_string2int(de->d_name, &pid) != -1 && pid >= 0) { + ppid = pidinfo(pid, &name); + switch (ppid) { + case -1: + continue; + case -2: + break; + } + ret = proch(pid, ppid, name, data); + GF_FREE(name); + if (ret) + break; + } + } + sys_closedir(d); + if (!de && errno) { + fprintf(stderr, "failed to traverse " PROC " (%s)\n", strerror(errno)); + ret = -1; + } + + return ret; +} |
