[ovs-dev,v3,03/19] process: Add helper function to retrieve process status.

Message ID 1501834086-31829-4-git-send-email-bhanuprakash.bodireddy@intel.com
State Superseded
Headers show

Commit Message

Bodireddy, Bhanuprakash Aug. 4, 2017, 8:07 a.m.
Implement helper function to retrieve the process status. This commit
also enables the fields relating to process name, state and core the
process was last 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 | 56 ++++++++++++++++++++++++++++++++++++++++++++++++++------
 lib/process.h | 13 +++++++++++++
 2 files changed, 63 insertions(+), 6 deletions(-)

Patch

diff --git a/lib/process.c b/lib/process.c
index 0b8d195..cbf83db 100644
--- a/lib/process.c
+++ b/lib/process.c
@@ -64,7 +64,23 @@  struct raw_process_info {
     long long int uptime;       /* ms since started. */
     long long int cputime;      /* ms of CPU used during 'uptime'. */
     pid_t ppid;                 /* Parent. */
-    char name[18];              /* Name (surrounded by parentheses). */
+    char state;                 /* Process state. */
+    int core_id;                /* Core id last executed on. */
+    char name[18];              /* Name. */
+};
+
+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 },
+    { '\0', UNUSED_STATE },
 };
 
 /* Pipe used to signal child termination. */
@@ -421,8 +437,8 @@  get_raw_process_info(pid_t pid, struct raw_process_info *raw)
 
     n = fscanf(stream,
                "%*d "           /* (1. pid) */
-               "%17s "          /* 2. process name */
-               "%*c "           /* (3. state) */
+               "(%17[^)]) "     /* 2. process name */
+               "%c "            /* 3. state */
                "%lu "           /* 4. ppid */
                "%*d "           /* (5. pgid) */
                "%*d "           /* (6. sid) */
@@ -458,7 +474,7 @@  get_raw_process_info(pid_t pid, struct raw_process_info *raw)
                "%*u "           /* (36. always 0) */
                "%*u "           /* (37. always 0) */
                "%*d "           /* (38. exit_signal) */
-               "%*d "           /* (39. task_cpu) */
+               "%d "            /* 39. task_cpu */
 #if 0
                /* These are here for documentation but #if'd out to save
                 * actually parsing them from the stream for no benefit. */
@@ -468,9 +484,10 @@  get_raw_process_info(pid_t pid, struct raw_process_info *raw)
                "%*lu "          /* (43. gtime) */
                "%*ld"           /* (44. cgtime) */
 #endif
-               , raw->name, &ppid, &utime, &stime, &start_time, &vsize, &rss);
+               , raw->name, &raw->state, &ppid, &utime, &stime, &start_time,
+                  &vsize, &rss, &raw->core_id);
     fclose(stream);
-    if (n != 7) {
+    if (n != 9) {
         VLOG_ERR_ONCE("%s: fscanf failed", file_name);
         return false;
     }
@@ -496,12 +513,15 @@  get_process_info(pid_t pid, struct process_info *pinfo)
         return false;
     }
 
+    ovs_strlcpy(pinfo->name, child.name, sizeof pinfo->name);
+    pinfo->state = child.state;
     pinfo->vsz = child.vsz;
     pinfo->rss = child.rss;
     pinfo->booted = child.uptime;
     pinfo->crashes = 0;
     pinfo->uptime = child.uptime;
     pinfo->cputime = child.cputime;
+    pinfo->core_id = child.core_id;
 
     if (child.ppid) {
         struct raw_process_info parent;
@@ -579,6 +599,30 @@  process_run(void)
 #endif
 }
 
+bool
+process_is_active(int pid)
+{
+    struct process_info pinfo;
+    int pstate = UNUSED_STATE;
+
+    ovs_assert(LINUX);
+
+    int success = get_process_info(pid, &pinfo);
+    if (success) {
+        for (int i = 0; pstate_map[i].pidstate != '\0'; i++) {
+            if (pstate_map[i].pidstate == pinfo.state) {
+                VLOG_DBG_ONCE("The state is %c", pstate_map[i].pidstate);
+                pstate = pstate_map[i].num;
+                break;
+            }
+        }
+
+        if (pstate == ACTIVE_STATE) {
+            return true;
+        }
+    }
+    return false;
+}
 
 /* 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 999ac68..69ab77f 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;
 
 struct process_info {
@@ -29,6 +38,9 @@  struct process_info {
     int crashes;                /* # of crashes (usually 0). */
     long long int uptime;       /* ms since last (re)started by monitor. */
     long long int cputime;      /* ms of CPU used during 'uptime'. */
+    char state;
+    int core_id;
+    char name[18];
 };
 
 /* Starting and monitoring subprocesses.
@@ -47,6 +59,7 @@  bool process_exited(struct process *);
 int process_status(const struct process *);
 void process_run(void);
 void process_wait(struct process *);
+bool process_is_active(int);
 
 int count_crashes(pid_t);
 bool get_process_info(pid_t, struct process_info *);