Implement helper functions to retrieve the process status, name and last core the process was scheduled. The APIs will be used by keepalive monitoring framework in future commits.
Signed-off-by: Bhanuprakash Bodireddy <[email protected]> --- lib/process.c | 152 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ lib/process.h | 13 +++++ 2 files changed, 165 insertions(+) diff --git a/lib/process.c b/lib/process.c index e9d0ba9..4c029c1 100644 --- a/lib/process.c +++ b/lib/process.c @@ -50,6 +50,20 @@ struct process { int status; }; +struct pstate2Num { + char *pidstate; + int num; +}; + +const struct pstate2Num pstate_map[] = { + { "S", STOPPED_STATE }, + { "R", ACTIVE_STATE }, + { "t", TRACED_STATE }, + { "Z", DEFUNC_STATE }, + { "D", UNINTERRUPTIBLE_SLEEP_STATE }, + { "NULL", UNUSED_STATE }, +}; + /* Pipe used to signal child termination. */ static int fds[2]; @@ -390,6 +404,144 @@ process_run(void) #endif } +int +get_process_status(int pid, int *pstate) +{ +#ifdef __linux__ + static char process_name[20]; + FILE *stream; + char line[75]; + char Name[15], value[5], status[20]; + int i, ln; + + snprintf(process_name, sizeof(process_name), + "/proc/%d/status", pid); + stream = fopen(process_name, "r"); + if (stream == NULL) { + VLOG_WARN_ONCE("%s: open failed: %s", process_name, + ovs_strerror(errno)); + return errno; + } + + ln=0; + while (fgets(line, sizeof line, stream)) { + if (!ovs_scan(line, + "%6s %2s %14s\n", + Name, value, status)) { + VLOG_WARN_ONCE("%s: could not parse line %d: %s", + process_name, ln, line); + continue; + } + if (!strcmp(Name, "State:")) { + for (i=0; pstate_map[i].pidstate != NULL; i++) { + if (strcmp(pstate_map[i].pidstate, value) == 0) { + VLOG_WARN_ONCE("The state is %s, status is %d\n", + pstate_map[i].pidstate, pstate_map[i].num); + *pstate = pstate_map[i].num; + break; + } + } + break; + } + ln++; + } + return 0; +#else + return ENOSYS; +#endif +} + +bool +process_is_active(int pid) +{ +#ifdef __linux__ + int pstate; + int err = get_process_status(pid, &pstate); + if (!err) { + if (pstate == ACTIVE_STATE) { + return true; + } + } + return false; +#else + return false; +#endif +} + +char * +get_process_name(int pid) +{ +#ifdef __linux__ + static char proc_path[PATH_MAX]; + FILE *stream; + char line[20]; + char *pname = xmalloc(20); + + if (pid == -1) { + VLOG_ERR("Invalid process id : %d", pid); + return NULL; + } + + snprintf(proc_path, sizeof(proc_path), + "/proc/%d/task/%d/comm", pid, pid); + stream = fopen(proc_path, "r"); + if (!stream) { + VLOG_WARN("%s: open failed: %s", proc_path, ovs_strerror(errno)); + return NULL; + } + + if (fgets(line, sizeof line, stream) != NULL) { + if (ovs_scan(line, "%s", pname)) { + return pname; + } + } + return NULL; +#else + return NULL; +#endif +} + +/* Retrieve the last core id that executed the process. + * + * Refer http://man7.org/linux/man-pages/man5/proc.5.html + * and the processor field in /proc/[pid]/stat. + */ +int +get_cpu_num(int pid) +{ +#ifdef __linux__ + static char proc_path[PATH_MAX]; + FILE *stream; + char line[500]; + + snprintf(proc_path, sizeof(proc_path), + "/proc/%d/stat", pid); + stream = fopen(proc_path, "r"); + if (!stream) { + VLOG_WARN_ONCE("%s: open failed: %s", proc_path, ovs_strerror(errno)); + return errno; + } + + int i; + int cpu_id = -1; + if (fgets(line, sizeof line, stream) != NULL) { + char *tok, *endptr = NULL; + for (tok = strtok_r(line, " ", &endptr), i = 1; tok != NULL; + tok = strtok_r(NULL, " ", &endptr), i++) { + VLOG_DBG("token :%s", tok); + if (i == 39) { + cpu_id = atoi(tok); + break; + } + } + } + + ovs_assert(cpu_id >= 0) + return cpu_id; +#else + return ENOSYS; +#endif +} /* Causes the next call to poll_block() to wake up when process 'p' has * exited. */ diff --git a/lib/process.h b/lib/process.h index 3feac7e..041767d 100644 --- a/lib/process.h +++ b/lib/process.h @@ -20,6 +20,15 @@ #include <stdbool.h> #include <sys/types.h> +enum process_states { + UNUSED_STATE, + STOPPED_STATE, + ACTIVE_STATE, + TRACED_STATE, + DEFUNC_STATE, + UNINTERRUPTIBLE_SLEEP_STATE +}; + struct process; /* Starting and monitoring subprocesses. @@ -38,6 +47,10 @@ bool process_exited(struct process *); int process_status(const struct process *); void process_run(void); void process_wait(struct process *); +int get_process_status(int, int *); +bool process_is_active(int pid); +char *get_process_name(int); +int get_cpu_num(int pid); /* These functions are thread-safe. */ char *process_status_msg(int); -- 2.4.11 _______________________________________________ dev mailing list [email protected] https://mail.openvswitch.org/mailman/listinfo/ovs-dev
