@@ -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. */
@@ -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);
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 <bhanuprakash.bodireddy@intel.com> --- lib/process.c | 152 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ lib/process.h | 13 +++++ 2 files changed, 165 insertions(+)