diff mbox

[ovs-dev,RFC,v2,02/19] process: Retrieve process status.

Message ID 1497286187-69287-3-git-send-email-bhanuprakash.bodireddy@intel.com
State Superseded
Headers show

Commit Message

Bodireddy, Bhanuprakash June 12, 2017, 4:49 p.m. UTC
Implement helper function to retrieve the process status. This will be
used by keepalive monitoring thread to detect false alarms and to show
PMD thread state in future commits.

Signed-off-by: Bhanuprakash Bodireddy <bhanuprakash.bodireddy@intel.com>
---
 lib/process.c | 73 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 lib/process.h | 11 +++++++++
 2 files changed, 84 insertions(+)
diff mbox

Patch

diff --git a/lib/process.c b/lib/process.c
index e9d0ba9..1dbb6aa 100644
--- a/lib/process.c
+++ b/lib/process.c
@@ -50,6 +50,20 @@  struct process {
     int status;
 };
 
+struct pstate2Num {
+    char *tidState;
+    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,65 @@  process_run(void)
 #endif
 }
 
+int
+get_process_status(int tid, 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", tid);
+    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].tidState != NULL; i++) {
+                if (strcmp(pstate_map[i].tidState, value) == 0) {
+                    VLOG_WARN_ONCE("The state is %s, status is %d\n",
+                        pstate_map[i].tidState, pstate_map[i].num);
+                    *pstate = pstate_map[i].num;
+                    break;
+                }
+            }
+            break;
+        }
+        ln++;
+   }
+   return 0;
+#else
+   return ENOSYS;
+#endif
+}
+
+bool
+process_is_active(int pid)
+{
+    int pstate;
+    int err = get_process_status(pid, &pstate);
+    if (!err) {
+        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 3feac7e..33c87d0 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,8 @@  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);
 
 /* These functions are thread-safe. */
 char *process_status_msg(int);