lttng_statedump_process_state for each PID NS
authorJulien Desfossez <jdesfossez@efficios.com>
Thu, 23 Aug 2012 21:11:35 +0000 (17:11 -0400)
committerMathieu Desnoyers <mathieu.desnoyers@efficios.com>
Thu, 23 Aug 2012 21:11:35 +0000 (17:11 -0400)
When a process is in a namespace, its pid, tid and ppid are relative to
the namespace. Since namespaces can be nested, we need to know the
representation of each process in each namespace.

This patch changes the lttng_enumerate_task_fd to iterate over each
PID namespace of a process if any, that way we generate, in the
statedump, an entry for each process in each namespace it belongs.
To know the nesting level, the field "level" is added to the
lttng_statedump_process_state event, 0 being the top-level.
For processes running on the top-level namespace, the statedump
behaviour is unchanged (except the added "level" field).

For example (no nesting, just one level of namespace) :
lttng_statedump_process_state: {
        tid = 32185, vtid = 1, pid = 32185,
        vpid = 1, ppid = 32173, vppid = 0,
        level = 1, name = "init" }
lttng_statedump_process_state: {
        tid = 32185, vtid = 32185, pid = 32185,
        vpid = 32185, ppid = 32173, vppid = 32173,
        level = 0, name = "init" }

Confirmed that the process 32173 in the top-level namespace is indeed
the lxc-start command that created the container and its namespace.

[ Edit by Mathieu Desnoyers: Minor cleanups ]

Signed-off-by: Julien Desfossez <jdesfossez@efficios.com>
Signed-off-by: Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
instrumentation/events/lttng-module/lttng-statedump.h
lttng-statedump-impl.c

index 5fc15a88be8234d7a7e576be12ef5e1f8d4a4ad0..ea0b6d9d99eeeade8aaec9be89cee228c85e729f 100644 (file)
@@ -6,6 +6,7 @@
 
 #include <linux/tracepoint.h>
 #include <linux/nsproxy.h>
+#include <linux/pid_namespace.h>
 
 TRACE_EVENT(lttng_statedump_start,
        TP_PROTO(struct lttng_session *session),
@@ -30,8 +31,9 @@ TRACE_EVENT(lttng_statedump_end,
 TRACE_EVENT(lttng_statedump_process_state,
        TP_PROTO(struct lttng_session *session,
                struct task_struct *p,
-               int type, int mode, int submode, int status),
-       TP_ARGS(session, p, type, mode, submode, status),
+               int type, int mode, int submode, int status,
+               struct pid_namespace *pid_ns),
+       TP_ARGS(session, p, type, mode, submode, status, pid_ns),
        TP_STRUCT__entry(
                __field(pid_t, tid)
                __field(pid_t, vtid)
@@ -44,38 +46,13 @@ TRACE_EVENT(lttng_statedump_process_state,
                __field(int, mode)
                __field(int, submode)
                __field(int, status)
+               __field(int, ns_level)
        ),
        TP_fast_assign(
                tp_assign(tid, p->pid)
-               tp_assign(vtid,
-                       ({
-                               struct nsproxy *proxy;
-                               pid_t ret = 0;
-
-                               rcu_read_lock();
-                               proxy = task_nsproxy(p);
-                               if (proxy) {
-                                       ret = task_pid_nr_ns(p,
-                                               proxy->pid_ns);
-                               }
-                               rcu_read_unlock();
-                               ret;
-                       }))
+               tp_assign(vtid, pid_ns ? task_pid_nr_ns(p, pid_ns) : 0)
                tp_assign(pid, p->tgid)
-               tp_assign(vpid,
-                       ({
-                                struct nsproxy *proxy;
-                                pid_t ret = 0;
-
-                                rcu_read_lock();
-                                proxy = task_nsproxy(p);
-                                if (proxy) {
-                                        ret = task_tgid_nr_ns(p,
-                                                proxy->pid_ns);
-                                }
-                                rcu_read_unlock();
-                                ret;
-                        }))
+               tp_assign(vpid, pid_ns ? task_tgid_nr_ns(p, pid_ns) : 0)
                tp_assign(ppid,
                        ({
                                pid_t ret;
@@ -88,16 +65,11 @@ TRACE_EVENT(lttng_statedump_process_state,
                tp_assign(vppid,
                        ({
                                struct task_struct *parent;
-                               struct nsproxy *proxy;
                                pid_t ret = 0;
 
                                rcu_read_lock();
                                parent = rcu_dereference(p->real_parent);
-                               proxy = task_nsproxy(parent);
-                               if (proxy) {
-                                       ret = task_tgid_nr_ns(parent,
-                                               proxy->pid_ns);
-                               }
+                               ret = task_tgid_nr_ns(parent, pid_ns);
                                rcu_read_unlock();
                                ret;
                        }))
@@ -106,6 +78,7 @@ TRACE_EVENT(lttng_statedump_process_state,
                tp_assign(mode, mode)
                tp_assign(submode, submode)
                tp_assign(status, status)
+               tp_assign(ns_level, pid_ns ? pid_ns->level : 0)
        ),
        TP_printk("")
 )
index e042a96deaceed9e941f1db06afbf4ea620892a7..89b55e53c369abeae1b3d5a34d6ee824b528b58f 100644 (file)
@@ -272,6 +272,32 @@ void list_interrupts(struct lttng_session *session)
 }
 #endif
 
+static
+void lttng_statedump_process_ns(struct lttng_session *session,
+               struct task_struct *p,
+               enum lttng_thread_type type,
+               enum lttng_execution_mode mode,
+               enum lttng_execution_submode submode,
+               enum lttng_process_status status)
+{
+       struct nsproxy *proxy;
+       struct pid_namespace *pid_ns;
+
+       rcu_read_lock();
+       proxy = task_nsproxy(p);
+       if (proxy) {
+               pid_ns = proxy->pid_ns;
+               do {
+                       trace_lttng_statedump_process_state(session,
+                               p, type, mode, submode, status, pid_ns);
+               } while (pid_ns);
+       } else {
+               trace_lttng_statedump_process_state(session,
+                       p, type, mode, submode, status, NULL);
+       }
+       rcu_read_unlock();
+}
+
 static
 int lttng_enumerate_process_states(struct lttng_session *session)
 {
@@ -321,7 +347,7 @@ int lttng_enumerate_process_states(struct lttng_session *session)
                                type = LTTNG_USER_THREAD;
                        else
                                type = LTTNG_KERNEL_THREAD;
-                       trace_lttng_statedump_process_state(session,
+                       lttng_statedump_process_ns(session,
                                p, type, mode, submode, status);
                        task_unlock(p);
                } while_each_thread(g, p);
This page took 0.02756 seconds and 4 git commands to generate.