Add namespace contexts
authorMichael Jeanson <mjeanson@efficios.com>
Tue, 12 Feb 2019 14:43:24 +0000 (09:43 -0500)
committerMathieu Desnoyers <mathieu.desnoyers@efficios.com>
Fri, 18 Oct 2019 15:16:22 +0000 (11:16 -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>
Signed-off-by: Mathieu Desnoyers <mathieu.desnoyers@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 5b4313a98983bc71cbc649c3e84812aca9921acd..0f34ff15700782428349b9c2a638d16150811666 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
 
@@ -437,7 +432,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;
                        }))
@@ -457,7 +452,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 5624b6c4f99839a81f289dd45bc6a5c8e7181b2e..34dd8f80d348d3a859939f4d267abbc12052b19d 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 c292de01bb2192a520c616894862c56b7c3fd2cc..91fe67f7ea333e55f33a9848e66feaa21dee9fc1 100644 (file)
@@ -161,6 +161,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 8fe36a7326121f7f7325112c7d77b0105e1eb9ea..fe6e284930153cc681bee9b46e466c3c5b54b4fb 100644 (file)
@@ -718,6 +718,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.040088 seconds and 5 git commands to generate.