Add namespace contexts
authorMichael Jeanson <mjeanson@efficios.com>
Tue, 12 Feb 2019 14:43:24 +0000 (09:43 -0500)
committerJonathan Rajotte <jonathan.rajotte-julien@efficios.com>
Wed, 1 May 2019 21:29:07 +0000 (17:29 -0400)
Add a context for each available kernel namespace which currently are :
cgroup, ipc, mnt, net, pid, user and uts. The id chosen to identify the
namespaces is the inode number of the file representing each one of them
in the proc filesystem. This was instroduced in v3.8.0 in this commit :

  commit 98f842e675f96ffac96e6c50315790912b2812be
  Author: Eric W. Biederman <ebiederm@xmission.com>
  Date:   Wed Jun 15 10:21:48 2011 -0700

    proc: Usable inode numbers for the namespace file descriptors.

    Assign a unique proc inode to each namespace, and use that
    inode number to ensure we only allocate at most one proc
    inode for every namespace in proc.

    A single proc inode per namespace allows userspace to test
    to see if two processes are in the same namespace.

    ...

Prior to this there is no unique identifier for a namespace that is
available to both the kernel and userspace. Enabling any of these
contexts on a kernel that is too old or doesn't have the proper features
enabled will fail and return -ENOSYS.

Per namespace particularities :

  - Cgroup
    - Introduced in 4.6.0
    - CONFIG_CGROUPS

  - IPC
    - Introduced in 2.6.25
    - CONFIG_IPC_NS

  - MNT
    - Introduced in 2.6.20
    - The mnt_namespace struct is defined in a private header

  - NET
    - Introduced in 2.6.24
    - CONFIG_NET_NS

  - PID
    - Introduced in 2.6.20
    - CONFIG_PID_NS

  - User
    - Introduced in 2.6.23
    - CONFIG_USER_NS

  - UTS
    - Introduced in 2.6.19
    - CONFIG_UTS_NS

Signed-off-by: Michael Jeanson <mjeanson@efficios.com>
15 files changed:
Kbuild.common
Makefile
instrumentation/events/lttng-module/sched.h
lttng-abi.c
lttng-abi.h
lttng-context-cgroup-ns.c [new file with mode: 0644]
lttng-context-ipc-ns.c [new file with mode: 0644]
lttng-context-mnt-ns.c [new file with mode: 0644]
lttng-context-net-ns.c [new file with mode: 0644]
lttng-context-pid-ns.c [new file with mode: 0644]
lttng-context-user-ns.c [new file with mode: 0644]
lttng-context-uts-ns.c [new file with mode: 0644]
lttng-context.c
lttng-events.h
wrapper/namespace.h [new file with mode: 0644]

index c7cbd0b24aae7b376b45d53f2d7b0c09e5d953b8..e2934e20f4880d94266a7f3d1ca39682abd56a8b 100644 (file)
@@ -71,4 +71,9 @@ ifneq ($(CONFIG_DYNAMIC_FTRACE),)
   endif
 endif
 
+mnt_ns_dep = $(srctree)/fs/mount.h
+ifeq ($(wildcard $(mnt_ns_dep)),)
+    ccflags-y += -DLTTNG_MNT_NS_MISSING_HEADER
+endif
+
 # vim:syntax=make
index c7b8a41712b528e55dc237161de844502d15ee2e..9b3e6c222eb712cf16f070bfd6097ea78c8aa135 100644 (file)
--- a/Makefile
+++ b/Makefile
@@ -83,6 +83,32 @@ ifneq ($(KERNELRELEASE),)
       -o \( $(VERSION) -eq 3 -a $(PATCHLEVEL) -ge 15 \) ] ; then \
       echo "lttng-tracepoint.o" ; fi;)
 
+  lttng-tracer-objs += lttng-context-cgroup-ns.o
+
+  ifneq ($(CONFIG_IPC_NS),)
+    lttng-tracer-objs += lttng-context-ipc-ns.o
+  endif
+
+  ifneq ($(wildcard $(mnt_ns_dep)),)
+     lttng-tracer-objs += lttng-context-mnt-ns.o
+  endif
+
+  ifneq ($(CONFIG_NET_NS),)
+    lttng-tracer-objs += lttng-context-net-ns.o
+  endif
+
+  ifneq ($(CONFIG_PID_NS),)
+    lttng-tracer-objs += lttng-context-pid-ns.o
+  endif
+
+  ifneq ($(CONFIG_USER_NS),)
+    lttng-tracer-objs += lttng-context-user-ns.o
+  endif
+
+  ifneq ($(CONFIG_UTS_NS),)
+    lttng-tracer-objs += lttng-context-uts-ns.o
+  endif
+
   obj-$(CONFIG_LTTNG) += lttng-statedump.o
   lttng-statedump-objs := lttng-statedump-impl.o wrapper/irqdesc.o \
                           wrapper/fdtable.o
index 77d77b2aeeddbe6ac34e2228b077734721f45b18..ce4d6ccf295e9b43540e43297b6993f32b75d8f6 100644 (file)
 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,9,0))
 #include <linux/sched/rt.h>
 #endif
-
-#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,19,0))
-#define lttng_proc_inum ns.inum
-#else
-#define lttng_proc_inum proc_inum
-#endif
+#include <wrapper/namespace.h>
 
 #define LTTNG_MAX_PID_NS_LEVEL 32
 
@@ -381,7 +376,7 @@ LTTNG_TRACEPOINT_EVENT_CODE(sched_process_fork,
                                        pid_ns = task_active_pid_ns(parent);
                                        if (pid_ns)
                                                parent_ns_inum =
-                                                       pid_ns->lttng_proc_inum;
+                                                       pid_ns->lttng_ns_inum;
                                }
                                parent_ns_inum;
                        }))
@@ -401,7 +396,7 @@ LTTNG_TRACEPOINT_EVENT_CODE(sched_process_fork,
                                        pid_ns = task_active_pid_ns(child);
                                        if (pid_ns)
                                                child_ns_inum =
-                                                       pid_ns->lttng_proc_inum;
+                                                       pid_ns->lttng_ns_inum;
                                }
                                child_ns_inum;
                        }))
index ca943791fdc9f2875cfd6c9412c2686bd22e85ff..132ded96ddcc472b17118ec0cfa58c41f83c700d 100644 (file)
@@ -236,6 +236,20 @@ long lttng_abi_add_context(struct file *file,
        case LTTNG_KERNEL_CONTEXT_CALLSTACK_KERNEL:
        case LTTNG_KERNEL_CONTEXT_CALLSTACK_USER:
                return lttng_add_callstack_to_ctx(ctx, context_param->ctx);
+       case LTTNG_KERNEL_CONTEXT_CGROUP_NS:
+               return lttng_add_cgroup_ns_to_ctx(ctx);
+       case LTTNG_KERNEL_CONTEXT_IPC_NS:
+               return lttng_add_ipc_ns_to_ctx(ctx);
+       case LTTNG_KERNEL_CONTEXT_MNT_NS:
+               return lttng_add_mnt_ns_to_ctx(ctx);
+       case LTTNG_KERNEL_CONTEXT_NET_NS:
+               return lttng_add_net_ns_to_ctx(ctx);
+       case LTTNG_KERNEL_CONTEXT_PID_NS:
+               return lttng_add_pid_ns_to_ctx(ctx);
+       case LTTNG_KERNEL_CONTEXT_USER_NS:
+               return lttng_add_user_ns_to_ctx(ctx);
+       case LTTNG_KERNEL_CONTEXT_UTS_NS:
+               return lttng_add_uts_ns_to_ctx(ctx);
        default:
                return -EINVAL;
        }
index 83bf93180bc6d97c8a048f561051f2a9a06d038e..b8802c13ff4deae9677196b02bca47f999c65abe 100644 (file)
@@ -151,6 +151,13 @@ enum lttng_kernel_context_type {
        LTTNG_KERNEL_CONTEXT_MIGRATABLE         = 15,
        LTTNG_KERNEL_CONTEXT_CALLSTACK_KERNEL   = 16,
        LTTNG_KERNEL_CONTEXT_CALLSTACK_USER     = 17,
+       LTTNG_KERNEL_CONTEXT_CGROUP_NS          = 18,
+       LTTNG_KERNEL_CONTEXT_IPC_NS             = 19,
+       LTTNG_KERNEL_CONTEXT_MNT_NS             = 20,
+       LTTNG_KERNEL_CONTEXT_NET_NS             = 21,
+       LTTNG_KERNEL_CONTEXT_PID_NS             = 22,
+       LTTNG_KERNEL_CONTEXT_USER_NS            = 23,
+       LTTNG_KERNEL_CONTEXT_UTS_NS             = 24,
 };
 
 struct lttng_kernel_perf_counter_ctx {
diff --git a/lttng-context-cgroup-ns.c b/lttng-context-cgroup-ns.c
new file mode 100644 (file)
index 0000000..81486e5
--- /dev/null
@@ -0,0 +1,105 @@
+/* SPDX-License-Identifier: (GPL-2.0 or LGPL-2.1)
+ *
+ * lttng-context-cgroup-ns.c
+ *
+ * LTTng cgroup namespace context.
+ *
+ * Copyright (C) 2009-2012 Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
+ *               2019 Michael Jeanson <mjeanson@efficios.com>
+ *
+ */
+
+#include <linux/module.h>
+#include <linux/slab.h>
+#include <linux/sched.h>
+#include <linux/cgroup.h>
+#include <lttng-events.h>
+#include <wrapper/ringbuffer/frontend_types.h>
+#include <wrapper/vmalloc.h>
+#include <wrapper/namespace.h>
+#include <lttng-tracer.h>
+
+#if defined(CONFIG_CGROUPS) && \
+       ((LINUX_VERSION_CODE >= KERNEL_VERSION(4,6,0)) || \
+        LTTNG_UBUNTU_KERNEL_RANGE(4,4,0,0, 4,5,0,0))
+
+static
+size_t cgroup_ns_get_size(size_t offset)
+{
+       size_t size = 0;
+
+       size += lib_ring_buffer_align(offset, lttng_alignof(unsigned int));
+       size += sizeof(unsigned int);
+       return size;
+}
+
+static
+void cgroup_ns_record(struct lttng_ctx_field *field,
+                struct lib_ring_buffer_ctx *ctx,
+                struct lttng_channel *chan)
+{
+       unsigned int cgroup_ns_inum = 0;
+
+       /*
+        * nsproxy can be NULL when scheduled out of exit.
+        *
+        * As documented in 'linux/nsproxy.h' namespaces access rules, no
+        * precautions should be taken when accessing the current task's
+        * namespaces, just dereference the pointers.
+        */
+       if (current->nsproxy)
+               cgroup_ns_inum = current->nsproxy->cgroup_ns->lttng_ns_inum;
+
+       lib_ring_buffer_align_ctx(ctx, lttng_alignof(cgroup_ns_inum));
+       chan->ops->event_write(ctx, &cgroup_ns_inum, sizeof(cgroup_ns_inum));
+}
+
+static
+void cgroup_ns_get_value(struct lttng_ctx_field *field,
+               struct lttng_probe_ctx *lttng_probe_ctx,
+               union lttng_ctx_value *value)
+{
+       unsigned int cgroup_ns_inum = 0;
+
+       /*
+        * nsproxy can be NULL when scheduled out of exit.
+        *
+        * As documented in 'linux/nsproxy.h' namespaces access rules, no
+        * precautions should be taken when accessing the current task's
+        * namespaces, just dereference the pointers.
+        */
+       if (current->nsproxy)
+               cgroup_ns_inum = current->nsproxy->cgroup_ns->lttng_ns_inum;
+
+       value->s64 = cgroup_ns_inum;
+}
+
+int lttng_add_cgroup_ns_to_ctx(struct lttng_ctx **ctx)
+{
+       struct lttng_ctx_field *field;
+
+       field = lttng_append_context(ctx);
+       if (!field)
+               return -ENOMEM;
+       if (lttng_find_context(*ctx, "cgroup_ns")) {
+               lttng_remove_context_field(ctx, field);
+               return -EEXIST;
+       }
+       field->event_field.name = "cgroup_ns";
+       field->event_field.type.atype = atype_integer;
+       field->event_field.type.u.basic.integer.size = sizeof(unsigned int) * CHAR_BIT;
+       field->event_field.type.u.basic.integer.alignment = lttng_alignof(unsigned int) * CHAR_BIT;
+       field->event_field.type.u.basic.integer.signedness = lttng_is_signed_type(unsigned int);
+       field->event_field.type.u.basic.integer.reverse_byte_order = 0;
+       field->event_field.type.u.basic.integer.base = 10;
+       field->event_field.type.u.basic.integer.encoding = lttng_encode_none;
+       field->get_size = cgroup_ns_get_size;
+       field->record = cgroup_ns_record;
+       field->get_value = cgroup_ns_get_value;
+       lttng_context_update(*ctx);
+       wrapper_vmalloc_sync_all();
+       return 0;
+}
+EXPORT_SYMBOL_GPL(lttng_add_cgroup_ns_to_ctx);
+
+#endif
diff --git a/lttng-context-ipc-ns.c b/lttng-context-ipc-ns.c
new file mode 100644 (file)
index 0000000..78d5966
--- /dev/null
@@ -0,0 +1,104 @@
+/* SPDX-License-Identifier: (GPL-2.0 or LGPL-2.1)
+ *
+ * lttng-context-ipc-ns.c
+ *
+ * LTTng ipc namespace context.
+ *
+ * Copyright (C) 2009-2012 Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
+ *               2019 Michael Jeanson <mjeanson@efficios.com>
+ *
+ */
+
+#include <linux/module.h>
+#include <linux/slab.h>
+#include <linux/sched.h>
+#include <linux/ipc_namespace.h>
+#include <lttng-events.h>
+#include <wrapper/ringbuffer/frontend_types.h>
+#include <wrapper/vmalloc.h>
+#include <wrapper/namespace.h>
+#include <lttng-tracer.h>
+
+#if defined(CONFIG_IPC_NS) && \
+       (LINUX_VERSION_CODE >= KERNEL_VERSION(3,8,0))
+
+static
+size_t ipc_ns_get_size(size_t offset)
+{
+       size_t size = 0;
+
+       size += lib_ring_buffer_align(offset, lttng_alignof(unsigned int));
+       size += sizeof(unsigned int);
+       return size;
+}
+
+static
+void ipc_ns_record(struct lttng_ctx_field *field,
+                struct lib_ring_buffer_ctx *ctx,
+                struct lttng_channel *chan)
+{
+       unsigned int ipc_ns_inum = 0;
+
+       /*
+        * nsproxy can be NULL when scheduled out of exit.
+        *
+        * As documented in 'linux/nsproxy.h' namespaces access rules, no
+        * precautions should be taken when accessing the current task's
+        * namespaces, just dereference the pointers.
+        */
+       if (current->nsproxy)
+               ipc_ns_inum = current->nsproxy->ipc_ns->lttng_ns_inum;
+
+       lib_ring_buffer_align_ctx(ctx, lttng_alignof(ipc_ns_inum));
+       chan->ops->event_write(ctx, &ipc_ns_inum, sizeof(ipc_ns_inum));
+}
+
+static
+void ipc_ns_get_value(struct lttng_ctx_field *field,
+               struct lttng_probe_ctx *lttng_probe_ctx,
+               union lttng_ctx_value *value)
+{
+       unsigned int ipc_ns_inum = 0;
+
+       /*
+        * nsproxy can be NULL when scheduled out of exit.
+        *
+        * As documented in 'linux/nsproxy.h' namespaces access rules, no
+        * precautions should be taken when accessing the current task's
+        * namespaces, just dereference the pointers.
+        */
+       if (current->nsproxy)
+               ipc_ns_inum = current->nsproxy->ipc_ns->lttng_ns_inum;
+
+       value->s64 = ipc_ns_inum;
+}
+
+int lttng_add_ipc_ns_to_ctx(struct lttng_ctx **ctx)
+{
+       struct lttng_ctx_field *field;
+
+       field = lttng_append_context(ctx);
+       if (!field)
+               return -ENOMEM;
+       if (lttng_find_context(*ctx, "ipc_ns")) {
+               lttng_remove_context_field(ctx, field);
+               return -EEXIST;
+       }
+       field->event_field.name = "ipc_ns";
+       field->event_field.type.atype = atype_integer;
+       field->event_field.type.u.basic.integer.size = sizeof(unsigned int) * CHAR_BIT;
+       field->event_field.type.u.basic.integer.alignment = lttng_alignof(unsigned int) * CHAR_BIT;
+       field->event_field.type.u.basic.integer.signedness = lttng_is_signed_type(unsigned int);
+       field->event_field.type.u.basic.integer.reverse_byte_order = 0;
+       field->event_field.type.u.basic.integer.base = 10;
+       field->event_field.type.u.basic.integer.encoding = lttng_encode_none;
+       field->get_size = ipc_ns_get_size;
+       field->record = ipc_ns_record;
+       field->get_value = ipc_ns_get_value;
+       lttng_context_update(*ctx);
+       wrapper_vmalloc_sync_all();
+       return 0;
+}
+EXPORT_SYMBOL_GPL(lttng_add_ipc_ns_to_ctx);
+
+#endif
diff --git a/lttng-context-mnt-ns.c b/lttng-context-mnt-ns.c
new file mode 100644 (file)
index 0000000..98d5b8e
--- /dev/null
@@ -0,0 +1,105 @@
+/* SPDX-License-Identifier: (GPL-2.0 or LGPL-2.1)
+ *
+ * lttng-context-mnt-ns.c
+ *
+ * LTTng mount namespace context.
+ *
+ * Copyright (C) 2009-2012 Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
+ *               2019 Michael Jeanson <mjeanson@efficios.com>
+ *
+ */
+
+#include <linux/module.h>
+#include <linux/slab.h>
+#include <linux/sched.h>
+#include <lttng-events.h>
+#include <wrapper/ringbuffer/frontend_types.h>
+#include <wrapper/vmalloc.h>
+#include <wrapper/namespace.h>
+#include <lttng-tracer.h>
+
+#if !defined(LTTNG_MNT_NS_MISSING_HEADER) && \
+       (LINUX_VERSION_CODE >= KERNEL_VERSION(3,8,0))
+
+#include <../fs/mount.h>
+
+static
+size_t mnt_ns_get_size(size_t offset)
+{
+       size_t size = 0;
+
+       size += lib_ring_buffer_align(offset, lttng_alignof(unsigned int));
+       size += sizeof(unsigned int);
+       return size;
+}
+
+static
+void mnt_ns_record(struct lttng_ctx_field *field,
+                struct lib_ring_buffer_ctx *ctx,
+                struct lttng_channel *chan)
+{
+       unsigned int mnt_ns_inum = 0;
+
+       /*
+        * nsproxy can be NULL when scheduled out of exit.
+        *
+        * As documented in 'linux/nsproxy.h' namespaces access rules, no
+        * precautions should be taken when accessing the current task's
+        * namespaces, just dereference the pointers.
+        */
+       if (current->nsproxy)
+               mnt_ns_inum = current->nsproxy->mnt_ns->lttng_ns_inum;
+
+       lib_ring_buffer_align_ctx(ctx, lttng_alignof(mnt_ns_inum));
+       chan->ops->event_write(ctx, &mnt_ns_inum, sizeof(mnt_ns_inum));
+}
+
+static
+void mnt_ns_get_value(struct lttng_ctx_field *field,
+               struct lttng_probe_ctx *lttng_probe_ctx,
+               union lttng_ctx_value *value)
+{
+       unsigned int mnt_ns_inum = 0;
+
+       /*
+        * nsproxy can be NULL when scheduled out of exit.
+        *
+        * As documented in 'linux/nsproxy.h' namespaces access rules, no
+        * precautions should be taken when accessing the current task's
+        * namespaces, just dereference the pointers.
+        */
+       if (current->nsproxy)
+               mnt_ns_inum = current->nsproxy->mnt_ns->lttng_ns_inum;
+
+       value->s64 = mnt_ns_inum;
+}
+
+int lttng_add_mnt_ns_to_ctx(struct lttng_ctx **ctx)
+{
+       struct lttng_ctx_field *field;
+
+       field = lttng_append_context(ctx);
+       if (!field)
+               return -ENOMEM;
+       if (lttng_find_context(*ctx, "mnt_ns")) {
+               lttng_remove_context_field(ctx, field);
+               return -EEXIST;
+       }
+       field->event_field.name = "mnt_ns";
+       field->event_field.type.atype = atype_integer;
+       field->event_field.type.u.basic.integer.size = sizeof(unsigned int) * CHAR_BIT;
+       field->event_field.type.u.basic.integer.alignment = lttng_alignof(unsigned int) * CHAR_BIT;
+       field->event_field.type.u.basic.integer.signedness = lttng_is_signed_type(unsigned int);
+       field->event_field.type.u.basic.integer.reverse_byte_order = 0;
+       field->event_field.type.u.basic.integer.base = 10;
+       field->event_field.type.u.basic.integer.encoding = lttng_encode_none;
+       field->get_size = mnt_ns_get_size;
+       field->record = mnt_ns_record;
+       field->get_value = mnt_ns_get_value;
+       lttng_context_update(*ctx);
+       wrapper_vmalloc_sync_all();
+       return 0;
+}
+EXPORT_SYMBOL_GPL(lttng_add_mnt_ns_to_ctx);
+
+#endif
diff --git a/lttng-context-net-ns.c b/lttng-context-net-ns.c
new file mode 100644 (file)
index 0000000..24d7ae3
--- /dev/null
@@ -0,0 +1,104 @@
+/* SPDX-License-Identifier: (GPL-2.0 or LGPL-2.1)
+ *
+ * lttng-context-net-ns.c
+ *
+ * LTTng net namespace context.
+ *
+ * Copyright (C) 2009-2012 Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
+ *               2019 Michael Jeanson <mjeanson@efficios.com>
+ *
+ */
+
+#include <linux/module.h>
+#include <linux/slab.h>
+#include <linux/sched.h>
+#include <net/net_namespace.h>
+#include <lttng-events.h>
+#include <wrapper/ringbuffer/frontend_types.h>
+#include <wrapper/vmalloc.h>
+#include <wrapper/namespace.h>
+#include <lttng-tracer.h>
+
+#if defined(CONFIG_NET_NS) && \
+       (LINUX_VERSION_CODE >= KERNEL_VERSION(3,8,0))
+
+static
+size_t net_ns_get_size(size_t offset)
+{
+       size_t size = 0;
+
+       size += lib_ring_buffer_align(offset, lttng_alignof(unsigned int));
+       size += sizeof(unsigned int);
+       return size;
+}
+
+static
+void net_ns_record(struct lttng_ctx_field *field,
+                struct lib_ring_buffer_ctx *ctx,
+                struct lttng_channel *chan)
+{
+       unsigned int net_ns_inum = 0;
+
+       /*
+        * nsproxy can be NULL when scheduled out of exit.
+        *
+        * As documented in 'linux/nsproxy.h' namespaces access rules, no
+        * precautions should be taken when accessing the current task's
+        * namespaces, just dereference the pointers.
+        */
+       if (current->nsproxy)
+               net_ns_inum = current->nsproxy->net_ns->lttng_ns_inum;
+
+       lib_ring_buffer_align_ctx(ctx, lttng_alignof(net_ns_inum));
+       chan->ops->event_write(ctx, &net_ns_inum, sizeof(net_ns_inum));
+}
+
+static
+void net_ns_get_value(struct lttng_ctx_field *field,
+               struct lttng_probe_ctx *lttng_probe_ctx,
+               union lttng_ctx_value *value)
+{
+       unsigned int net_ns_inum = 0;
+
+       /*
+        * nsproxy can be NULL when scheduled out of exit.
+        *
+        * As documented in 'linux/nsproxy.h' namespaces access rules, no
+        * precautions should be taken when accessing the current task's
+        * namespaces, just dereference the pointers.
+        */
+       if (current->nsproxy)
+               net_ns_inum = current->nsproxy->net_ns->lttng_ns_inum;
+
+       value->s64 = net_ns_inum;
+}
+
+int lttng_add_net_ns_to_ctx(struct lttng_ctx **ctx)
+{
+       struct lttng_ctx_field *field;
+
+       field = lttng_append_context(ctx);
+       if (!field)
+               return -ENOMEM;
+       if (lttng_find_context(*ctx, "net_ns")) {
+               lttng_remove_context_field(ctx, field);
+               return -EEXIST;
+       }
+       field->event_field.name = "net_ns";
+       field->event_field.type.atype = atype_integer;
+       field->event_field.type.u.basic.integer.size = sizeof(unsigned int) * CHAR_BIT;
+       field->event_field.type.u.basic.integer.alignment = lttng_alignof(unsigned int) * CHAR_BIT;
+       field->event_field.type.u.basic.integer.signedness = lttng_is_signed_type(unsigned int);
+       field->event_field.type.u.basic.integer.reverse_byte_order = 0;
+       field->event_field.type.u.basic.integer.base = 10;
+       field->event_field.type.u.basic.integer.encoding = lttng_encode_none;
+       field->get_size = net_ns_get_size;
+       field->record = net_ns_record;
+       field->get_value = net_ns_get_value;
+       lttng_context_update(*ctx);
+       wrapper_vmalloc_sync_all();
+       return 0;
+}
+EXPORT_SYMBOL_GPL(lttng_add_net_ns_to_ctx);
+
+#endif
diff --git a/lttng-context-pid-ns.c b/lttng-context-pid-ns.c
new file mode 100644 (file)
index 0000000..f039f26
--- /dev/null
@@ -0,0 +1,106 @@
+/* SPDX-License-Identifier: (GPL-2.0 or LGPL-2.1)
+ *
+ * lttng-context-pid-ns.c
+ *
+ * LTTng pid namespace context.
+ *
+ * Copyright (C) 2009-2012 Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
+ *               2019 Michael Jeanson <mjeanson@efficios.com>
+ *
+ */
+
+#include <linux/module.h>
+#include <linux/slab.h>
+#include <linux/sched.h>
+#include <linux/pid_namespace.h>
+#include <lttng-events.h>
+#include <wrapper/ringbuffer/frontend_types.h>
+#include <wrapper/vmalloc.h>
+#include <wrapper/namespace.h>
+#include <lttng-tracer.h>
+
+#if defined(CONFIG_PID_NS) && \
+       (LINUX_VERSION_CODE >= KERNEL_VERSION(3,8,0))
+
+static
+size_t pid_ns_get_size(size_t offset)
+{
+       size_t size = 0;
+
+       size += lib_ring_buffer_align(offset, lttng_alignof(unsigned int));
+       size += sizeof(unsigned int);
+       return size;
+}
+
+static
+void pid_ns_record(struct lttng_ctx_field *field,
+                struct lib_ring_buffer_ctx *ctx,
+                struct lttng_channel *chan)
+{
+       struct pid_namespace *ns;
+       unsigned int pid_ns_inum = 0;
+
+       /*
+        * The pid namespace is an exception -- it's accessed using
+        * task_active_pid_ns. The pid namespace in nsproxy is the
+        * namespace that children will use.
+        */
+       ns = task_active_pid_ns(current);
+
+       if (ns)
+               pid_ns_inum = ns->lttng_ns_inum;
+
+       lib_ring_buffer_align_ctx(ctx, lttng_alignof(pid_ns_inum));
+       chan->ops->event_write(ctx, &pid_ns_inum, sizeof(pid_ns_inum));
+}
+
+static
+void pid_ns_get_value(struct lttng_ctx_field *field,
+               struct lttng_probe_ctx *lttng_probe_ctx,
+               union lttng_ctx_value *value)
+{
+       struct pid_namespace *ns;
+       unsigned int pid_ns_inum = 0;
+
+       /*
+        * The pid namespace is an exception -- it's accessed using
+        * task_active_pid_ns. The pid namespace in nsproxy is the
+        * namespace that children will use.
+        */
+       ns = task_active_pid_ns(current);
+
+       if (ns)
+               pid_ns_inum = ns->lttng_ns_inum;
+
+       value->s64 = pid_ns_inum;
+}
+
+int lttng_add_pid_ns_to_ctx(struct lttng_ctx **ctx)
+{
+       struct lttng_ctx_field *field;
+
+       field = lttng_append_context(ctx);
+       if (!field)
+               return -ENOMEM;
+       if (lttng_find_context(*ctx, "pid_ns")) {
+               lttng_remove_context_field(ctx, field);
+               return -EEXIST;
+       }
+       field->event_field.name = "pid_ns";
+       field->event_field.type.atype = atype_integer;
+       field->event_field.type.u.basic.integer.size = sizeof(unsigned int) * CHAR_BIT;
+       field->event_field.type.u.basic.integer.alignment = lttng_alignof(unsigned int) * CHAR_BIT;
+       field->event_field.type.u.basic.integer.signedness = lttng_is_signed_type(unsigned int);
+       field->event_field.type.u.basic.integer.reverse_byte_order = 0;
+       field->event_field.type.u.basic.integer.base = 10;
+       field->event_field.type.u.basic.integer.encoding = lttng_encode_none;
+       field->get_size = pid_ns_get_size;
+       field->record = pid_ns_record;
+       field->get_value = pid_ns_get_value;
+       lttng_context_update(*ctx);
+       wrapper_vmalloc_sync_all();
+       return 0;
+}
+EXPORT_SYMBOL_GPL(lttng_add_pid_ns_to_ctx);
+
+#endif
diff --git a/lttng-context-user-ns.c b/lttng-context-user-ns.c
new file mode 100644 (file)
index 0000000..746e4d9
--- /dev/null
@@ -0,0 +1,90 @@
+/* SPDX-License-Identifier: (GPL-2.0 or LGPL-2.1)
+ *
+ * lttng-context-user-ns.c
+ *
+ * LTTng user namespace context.
+ *
+ * Copyright (C) 2009-2012 Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
+ *               2019 Michael Jeanson <mjeanson@efficios.com>
+ *
+ */
+
+#include <linux/module.h>
+#include <linux/slab.h>
+#include <linux/sched.h>
+#include <linux/user_namespace.h>
+#include <lttng-events.h>
+#include <wrapper/ringbuffer/frontend_types.h>
+#include <wrapper/vmalloc.h>
+#include <wrapper/namespace.h>
+#include <lttng-tracer.h>
+
+#if defined(CONFIG_USER_NS) && \
+       (LINUX_VERSION_CODE >= KERNEL_VERSION(3,8,0))
+
+static
+size_t user_ns_get_size(size_t offset)
+{
+       size_t size = 0;
+
+       size += lib_ring_buffer_align(offset, lttng_alignof(unsigned int));
+       size += sizeof(unsigned int);
+       return size;
+}
+
+static
+void user_ns_record(struct lttng_ctx_field *field,
+                struct lib_ring_buffer_ctx *ctx,
+                struct lttng_channel *chan)
+{
+       unsigned int user_ns_inum = 0;
+
+       if (current_user_ns())
+               user_ns_inum = current_user_ns()->lttng_ns_inum;
+
+       lib_ring_buffer_align_ctx(ctx, lttng_alignof(user_ns_inum));
+       chan->ops->event_write(ctx, &user_ns_inum, sizeof(user_ns_inum));
+}
+
+static
+void user_ns_get_value(struct lttng_ctx_field *field,
+               struct lttng_probe_ctx *lttng_probe_ctx,
+               union lttng_ctx_value *value)
+{
+       unsigned int user_ns_inum = 0;
+
+       if (current_user_ns())
+               user_ns_inum = current_user_ns()->lttng_ns_inum;
+
+       value->s64 = user_ns_inum;
+}
+
+int lttng_add_user_ns_to_ctx(struct lttng_ctx **ctx)
+{
+       struct lttng_ctx_field *field;
+
+       field = lttng_append_context(ctx);
+       if (!field)
+               return -ENOMEM;
+       if (lttng_find_context(*ctx, "user_ns")) {
+               lttng_remove_context_field(ctx, field);
+               return -EEXIST;
+       }
+       field->event_field.name = "user_ns";
+       field->event_field.type.atype = atype_integer;
+       field->event_field.type.u.basic.integer.size = sizeof(unsigned int) * CHAR_BIT;
+       field->event_field.type.u.basic.integer.alignment = lttng_alignof(unsigned int) * CHAR_BIT;
+       field->event_field.type.u.basic.integer.signedness = lttng_is_signed_type(unsigned int);
+       field->event_field.type.u.basic.integer.reverse_byte_order = 0;
+       field->event_field.type.u.basic.integer.base = 10;
+       field->event_field.type.u.basic.integer.encoding = lttng_encode_none;
+       field->get_size = user_ns_get_size;
+       field->record = user_ns_record;
+       field->get_value = user_ns_get_value;
+       lttng_context_update(*ctx);
+       wrapper_vmalloc_sync_all();
+       return 0;
+}
+EXPORT_SYMBOL_GPL(lttng_add_user_ns_to_ctx);
+
+#endif
diff --git a/lttng-context-uts-ns.c b/lttng-context-uts-ns.c
new file mode 100644 (file)
index 0000000..7352a3d
--- /dev/null
@@ -0,0 +1,104 @@
+/* SPDX-License-Identifier: (GPL-2.0 or LGPL-2.1)
+ *
+ * lttng-context-uts-ns.c
+ *
+ * LTTng uts namespace context.
+ *
+ * Copyright (C) 2009-2012 Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
+ *               2019 Michael Jeanson <mjeanson@efficios.com>
+ *
+ */
+
+#include <linux/module.h>
+#include <linux/slab.h>
+#include <linux/sched.h>
+#include <linux/utsname.h>
+#include <lttng-events.h>
+#include <wrapper/ringbuffer/frontend_types.h>
+#include <wrapper/vmalloc.h>
+#include <wrapper/namespace.h>
+#include <lttng-tracer.h>
+
+#if defined(CONFIG_UTS_NS) && \
+       (LINUX_VERSION_CODE >= KERNEL_VERSION(3,8,0))
+
+static
+size_t uts_ns_get_size(size_t offset)
+{
+       size_t size = 0;
+
+       size += lib_ring_buffer_align(offset, lttng_alignof(unsigned int));
+       size += sizeof(unsigned int);
+       return size;
+}
+
+static
+void uts_ns_record(struct lttng_ctx_field *field,
+                struct lib_ring_buffer_ctx *ctx,
+                struct lttng_channel *chan)
+{
+       unsigned int uts_ns_inum = 0;
+
+       /*
+        * nsproxy can be NULL when scheduled out of exit.
+        *
+        * As documented in 'linux/nsproxy.h' namespaces access rules, no
+        * precautions should be taken when accessing the current task's
+        * namespaces, just dereference the pointers.
+        */
+       if (current->nsproxy)
+               uts_ns_inum = current->nsproxy->uts_ns->lttng_ns_inum;
+
+       lib_ring_buffer_align_ctx(ctx, lttng_alignof(uts_ns_inum));
+       chan->ops->event_write(ctx, &uts_ns_inum, sizeof(uts_ns_inum));
+}
+
+static
+void uts_ns_get_value(struct lttng_ctx_field *field,
+               struct lttng_probe_ctx *lttng_probe_ctx,
+               union lttng_ctx_value *value)
+{
+       unsigned int uts_ns_inum = 0;
+
+       /*
+        * nsproxy can be NULL when scheduled out of exit.
+        *
+        * As documented in 'linux/nsproxy.h' namespaces access rules, no
+        * precautions should be taken when accessing the current task's
+        * namespaces, just dereference the pointers.
+        */
+       if (current->nsproxy)
+               uts_ns_inum = current->nsproxy->uts_ns->lttng_ns_inum;
+
+       value->s64 = uts_ns_inum;
+}
+
+int lttng_add_uts_ns_to_ctx(struct lttng_ctx **ctx)
+{
+       struct lttng_ctx_field *field;
+
+       field = lttng_append_context(ctx);
+       if (!field)
+               return -ENOMEM;
+       if (lttng_find_context(*ctx, "uts_ns")) {
+               lttng_remove_context_field(ctx, field);
+               return -EEXIST;
+       }
+       field->event_field.name = "uts_ns";
+       field->event_field.type.atype = atype_integer;
+       field->event_field.type.u.basic.integer.size = sizeof(unsigned int) * CHAR_BIT;
+       field->event_field.type.u.basic.integer.alignment = lttng_alignof(unsigned int) * CHAR_BIT;
+       field->event_field.type.u.basic.integer.signedness = lttng_is_signed_type(unsigned int);
+       field->event_field.type.u.basic.integer.reverse_byte_order = 0;
+       field->event_field.type.u.basic.integer.base = 10;
+       field->event_field.type.u.basic.integer.encoding = lttng_encode_none;
+       field->get_size = uts_ns_get_size;
+       field->record = uts_ns_record;
+       field->get_value = uts_ns_get_value;
+       lttng_context_update(*ctx);
+       wrapper_vmalloc_sync_all();
+       return 0;
+}
+EXPORT_SYMBOL_GPL(lttng_add_uts_ns_to_ctx);
+
+#endif
index 869496d8ce0f222925afd2b4535ba15b2168ec87..eb4534cbfce2c778c992a6b2bd018f58d2bf575a 100644 (file)
@@ -303,6 +303,34 @@ int lttng_context_init(void)
        if (ret && ret != -ENOSYS) {
                printk(KERN_WARNING "Cannot add context lttng_add_migratable_to_ctx");
        }
+       ret = lttng_add_cgroup_ns_to_ctx(&lttng_static_ctx);
+       if (ret && ret != -ENOSYS) {
+               printk(KERN_WARNING "Cannot add context lttng_add_cgroup_ns_to_ctx");
+       }
+       ret = lttng_add_ipc_ns_to_ctx(&lttng_static_ctx);
+       if (ret && ret != -ENOSYS) {
+               printk(KERN_WARNING "Cannot add context lttng_add_ipc_ns_to_ctx");
+       }
+       ret = lttng_add_mnt_ns_to_ctx(&lttng_static_ctx);
+       if (ret && ret != -ENOSYS) {
+               printk(KERN_WARNING "Cannot add context lttng_add_mnt_ns_to_ctx");
+       }
+       ret = lttng_add_net_ns_to_ctx(&lttng_static_ctx);
+       if (ret && ret != -ENOSYS) {
+               printk(KERN_WARNING "Cannot add context lttng_add_net_ns_to_ctx");
+       }
+       ret = lttng_add_pid_ns_to_ctx(&lttng_static_ctx);
+       if (ret && ret != -ENOSYS) {
+               printk(KERN_WARNING "Cannot add context lttng_add_pid_ns_to_ctx");
+       }
+       ret = lttng_add_user_ns_to_ctx(&lttng_static_ctx);
+       if (ret && ret != -ENOSYS) {
+               printk(KERN_WARNING "Cannot add context lttng_add_user_ns_to_ctx");
+       }
+       ret = lttng_add_uts_ns_to_ctx(&lttng_static_ctx);
+       if (ret && ret != -ENOSYS) {
+               printk(KERN_WARNING "Cannot add context lttng_add_uts_ns_to_ctx");
+       }
        /* TODO: perf counters for filtering */
        return 0;
 }
index 19037062d8f4b6c08348aa885c4bbc54b04b4182..062d1c59bbc123dd434455d39d8669f355f5a564 100644 (file)
@@ -716,6 +716,84 @@ int lttng_add_migratable_to_ctx(struct lttng_ctx **ctx)
 
 int lttng_add_callstack_to_ctx(struct lttng_ctx **ctx, int type);
 
+#if defined(CONFIG_CGROUPS) && \
+       ((LINUX_VERSION_CODE >= KERNEL_VERSION(4,6,0)) || \
+        LTTNG_UBUNTU_KERNEL_RANGE(4,4,0,0, 4,5,0,0))
+int lttng_add_cgroup_ns_to_ctx(struct lttng_ctx **ctx);
+#else
+static inline
+int lttng_add_cgroup_ns_to_ctx(struct lttng_ctx **ctx)
+{
+       return -ENOSYS;
+}
+#endif
+
+#if defined(CONFIG_IPC_NS) && \
+       (LINUX_VERSION_CODE >= KERNEL_VERSION(3,8,0))
+int lttng_add_ipc_ns_to_ctx(struct lttng_ctx **ctx);
+#else
+static inline
+int lttng_add_ipc_ns_to_ctx(struct lttng_ctx **ctx)
+{
+       return -ENOSYS;
+}
+#endif
+
+#if !defined(LTTNG_MNT_NS_MISSING_HEADER) && \
+       (LINUX_VERSION_CODE >= KERNEL_VERSION(3,8,0))
+int lttng_add_mnt_ns_to_ctx(struct lttng_ctx **ctx);
+#else
+static inline
+int lttng_add_mnt_ns_to_ctx(struct lttng_ctx **ctx)
+{
+       return -ENOSYS;
+}
+#endif
+
+#if defined(CONFIG_NET_NS) && \
+       (LINUX_VERSION_CODE >= KERNEL_VERSION(3,8,0))
+int lttng_add_net_ns_to_ctx(struct lttng_ctx **ctx);
+#else
+static inline
+int lttng_add_net_ns_to_ctx(struct lttng_ctx **ctx)
+{
+       return -ENOSYS;
+}
+#endif
+
+#if defined(CONFIG_PID_NS) && \
+       (LINUX_VERSION_CODE >= KERNEL_VERSION(3,8,0))
+int lttng_add_pid_ns_to_ctx(struct lttng_ctx **ctx);
+#else
+static inline
+int lttng_add_pid_ns_to_ctx(struct lttng_ctx **ctx)
+{
+       return -ENOSYS;
+}
+#endif
+
+#if defined(CONFIG_USER_NS) && \
+       (LINUX_VERSION_CODE >= KERNEL_VERSION(3,8,0))
+int lttng_add_user_ns_to_ctx(struct lttng_ctx **ctx);
+#else
+static inline
+int lttng_add_user_ns_to_ctx(struct lttng_ctx **ctx)
+{
+       return -ENOSYS;
+}
+#endif
+
+#if defined(CONFIG_UTS_NS) && \
+       (LINUX_VERSION_CODE >= KERNEL_VERSION(3,8,0))
+int lttng_add_uts_ns_to_ctx(struct lttng_ctx **ctx);
+#else
+static inline
+int lttng_add_uts_ns_to_ctx(struct lttng_ctx **ctx)
+{
+       return -ENOSYS;
+}
+#endif
+
 #if defined(CONFIG_PERF_EVENTS)
 int lttng_add_perf_counter_to_ctx(uint32_t type,
                                  uint64_t config,
diff --git a/wrapper/namespace.h b/wrapper/namespace.h
new file mode 100644 (file)
index 0000000..36dbf4c
--- /dev/null
@@ -0,0 +1,21 @@
+/* SPDX-License-Identifier: (GPL-2.0 or LGPL-2.1)
+ *
+ * wrapper/namespace.h
+ *
+ * Copyright (C) 2011-2012 Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
+ *               2019 Michael Jeanson <mjeanson@efficios.com>
+ *
+ */
+
+#ifndef _LTTNG_WRAPPER_NAMESPACE_H
+#define _LTTNG_WRAPPER_NAMESPACE_H
+
+#include <linux/version.h>
+
+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,19,0))
+#define lttng_ns_inum ns.inum
+#else
+#define lttng_ns_inum proc_inum
+#endif
+
+#endif /* _LTTNG_WRAPPER_NAMESPACE_H */
This page took 0.039185 seconds and 5 git commands to generate.