[lttng-dev] [PATCH lttng-modules 1/3] RFC: Add namespace contexts

Michael Jeanson mjeanson at efficios.com
Thu Mar 1 17:39:08 EST 2018


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 fd representing each of them in
the proc filesystem. This was instroduced in v3.8.0 in this commit :

  commit 98f842e675f96ffac96e6c50315790912b2812be
  Author: Eric W. Biederman <ebiederm at 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.

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 at efficios.com>
---
 Kbuild.common                               |   5 ++
 Makefile                                    |  26 +++++++
 instrumentation/events/lttng-module/sched.h |  11 +--
 lttng-abi.c                                 |  14 ++++
 lttng-abi.h                                 |   7 ++
 lttng-context-cgroup-ns.c                   | 113 ++++++++++++++++++++++++++++
 lttng-context-ipc-ns.c                      | 110 +++++++++++++++++++++++++++
 lttng-context-mnt-ns.c                      | 111 +++++++++++++++++++++++++++
 lttng-context-net-ns.c                      | 110 +++++++++++++++++++++++++++
 lttng-context-pid-ns.c                      | 106 ++++++++++++++++++++++++++
 lttng-context-user-ns.c                     |  98 ++++++++++++++++++++++++
 lttng-context-uts-ns.c                      | 110 +++++++++++++++++++++++++++
 lttng-context.c                             |  28 +++++++
 lttng-events.h                              |  79 +++++++++++++++++++
 wrapper/namespace.h                         |  33 ++++++++
 15 files changed, 953 insertions(+), 8 deletions(-)
 create mode 100644 lttng-context-cgroup-ns.c
 create mode 100644 lttng-context-ipc-ns.c
 create mode 100644 lttng-context-mnt-ns.c
 create mode 100644 lttng-context-net-ns.c
 create mode 100644 lttng-context-pid-ns.c
 create mode 100644 lttng-context-user-ns.c
 create mode 100644 lttng-context-uts-ns.c
 create mode 100644 wrapper/namespace.h

diff --git a/Kbuild.common b/Kbuild.common
index c0d5409..4bb21ad 100644
--- a/Kbuild.common
+++ b/Kbuild.common
@@ -55,4 +55,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
diff --git a/Makefile b/Makefile
index b08f0bf..15f18c4 100644
--- a/Makefile
+++ b/Makefile
@@ -87,6 +87,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
diff --git a/instrumentation/events/lttng-module/sched.h b/instrumentation/events/lttng-module/sched.h
index f5c3669..19c0fe0 100644
--- a/instrumentation/events/lttng-module/sched.h
+++ b/instrumentation/events/lttng-module/sched.h
@@ -12,12 +12,7 @@
 #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
 
@@ -414,7 +409,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;
 			}))
@@ -434,7 +429,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;
 			}))
diff --git a/lttng-abi.c b/lttng-abi.c
index ea746c2..1345e93 100644
--- a/lttng-abi.c
+++ b/lttng-abi.c
@@ -247,6 +247,20 @@ long lttng_abi_add_context(struct file *file,
 		return lttng_add_preemptible_to_ctx(ctx);
 	case LTTNG_KERNEL_CONTEXT_MIGRATABLE:
 		return lttng_add_migratable_to_ctx(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;
 	}
diff --git a/lttng-abi.h b/lttng-abi.h
index dac8658..47cacec 100644
--- a/lttng-abi.h
+++ b/lttng-abi.h
@@ -146,6 +146,13 @@ enum lttng_kernel_context_type {
 	LTTNG_KERNEL_CONTEXT_PREEMPTIBLE	= 13,
 	LTTNG_KERNEL_CONTEXT_NEED_RESCHEDULE	= 14,
 	LTTNG_KERNEL_CONTEXT_MIGRATABLE		= 15,
+	LTTNG_KERNEL_CONTEXT_CGROUP_NS		= 16,
+	LTTNG_KERNEL_CONTEXT_IPC_NS		= 17,
+	LTTNG_KERNEL_CONTEXT_MNT_NS		= 18,
+	LTTNG_KERNEL_CONTEXT_NET_NS		= 19,
+	LTTNG_KERNEL_CONTEXT_PID_NS		= 20,
+	LTTNG_KERNEL_CONTEXT_USER_NS		= 21,
+	LTTNG_KERNEL_CONTEXT_UTS_NS		= 22,
 };
 
 struct lttng_kernel_perf_counter_ctx {
diff --git a/lttng-context-cgroup-ns.c b/lttng-context-cgroup-ns.c
new file mode 100644
index 0000000..124677b
--- /dev/null
+++ b/lttng-context-cgroup-ns.c
@@ -0,0 +1,113 @@
+/*
+ * lttng-context-cgroup-ns.c
+ *
+ * LTTng cgroup namespace context.
+ *
+ * Copyright (C) 2009-2012 Mathieu Desnoyers <mathieu.desnoyers at efficios.com>
+ *               2018 Michael Jeanson <mjeanson at efficios.com>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; only
+ * version 2.1 of the License.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#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;
+
+	/*
+	 * nsproxy can be NULL when scheduled out of exit.
+	 */
+	if (!current->nsproxy)
+		cgroup_ns_inum = 0;
+	else
+		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;
+
+	/*
+	 * nsproxy can be NULL when scheduled out of exit.
+	 */
+	if (!current->nsproxy)
+		cgroup_ns_inum = 0;
+	else
+		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
index 0000000..2c5ef9f
--- /dev/null
+++ b/lttng-context-ipc-ns.c
@@ -0,0 +1,110 @@
+/*
+ * lttng-context-ipc-ns.c
+ *
+ * LTTng ipc namespace context.
+ *
+ * Copyright (C) 2009-2012 Mathieu Desnoyers <mathieu.desnoyers at efficios.com>
+ *               2018 Michael Jeanson <mjeanson at efficios.com>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; only
+ * version 2.1 of the License.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#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;
+
+	/*
+	 * nsproxy can be NULL when scheduled out of exit.
+	 */
+	if (!current->nsproxy)
+		ipc_ns_inum = 0;
+	else
+		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;
+
+	/*
+	 * nsproxy can be NULL when scheduled out of exit.
+	 */
+	if (!current->nsproxy)
+		ipc_ns_inum = 0;
+	else
+		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
index 0000000..8cb301f
--- /dev/null
+++ b/lttng-context-mnt-ns.c
@@ -0,0 +1,111 @@
+/*
+ * lttng-context-mnt-ns.c
+ *
+ * LTTng mount namespace context.
+ *
+ * Copyright (C) 2009-2012 Mathieu Desnoyers <mathieu.desnoyers at efficios.com>
+ *               2018 Michael Jeanson <mjeanson at efficios.com>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; only
+ * version 2.1 of the License.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#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;
+
+	/*
+	 * nsproxy can be NULL when scheduled out of exit.
+	 */
+	if (!current->nsproxy)
+		mnt_ns_inum = 0;
+	else
+		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;
+
+	/*
+	 * nsproxy can be NULL when scheduled out of exit.
+	 */
+	if (!current->nsproxy)
+		mnt_ns_inum = 0;
+	else
+		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
index 0000000..ce01da6
--- /dev/null
+++ b/lttng-context-net-ns.c
@@ -0,0 +1,110 @@
+/*
+ * lttng-context-net-ns.c
+ *
+ * LTTng net namespace context.
+ *
+ * Copyright (C) 2009-2012 Mathieu Desnoyers <mathieu.desnoyers at efficios.com>
+ *               2018 Michael Jeanson <mjeanson at efficios.com>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; only
+ * version 2.1 of the License.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#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;
+
+	/*
+	 * nsproxy can be NULL when scheduled out of exit.
+	 */
+	if (!current->nsproxy)
+		net_ns_inum = 0;
+	else
+		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;
+
+	/*
+	 * nsproxy can be NULL when scheduled out of exit.
+	 */
+	if (!current->nsproxy)
+		net_ns_inum = 0;
+	else
+		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
index 0000000..27c6531
--- /dev/null
+++ b/lttng-context-pid-ns.c
@@ -0,0 +1,106 @@
+/*
+ * lttng-context-pid-ns.c
+ *
+ * LTTng pid namespace context.
+ *
+ * Copyright (C) 2009-2012 Mathieu Desnoyers <mathieu.desnoyers at efficios.com>
+ *               2018 Michael Jeanson <mjeanson at efficios.com>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; only
+ * version 2.1 of the License.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#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;
+
+	ns = task_active_pid_ns(current);
+
+	if (!ns) {
+		pid_ns_inum = 0;
+	} else {
+		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)
+{
+	unsigned int pid_ns_inum;
+
+	pid_ns_inum = task_active_pid_ns(current)->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
index 0000000..1b0f982
--- /dev/null
+++ b/lttng-context-user-ns.c
@@ -0,0 +1,98 @@
+/*
+ * lttng-context-user-ns.c
+ *
+ * LTTng user namespace context.
+ *
+ * Copyright (C) 2009-2012 Mathieu Desnoyers <mathieu.desnoyers at efficios.com>
+ *               2018 Michael Jeanson <mjeanson at efficios.com>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; only
+ * version 2.1 of the License.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#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;
+
+	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;
+
+	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
index 0000000..c6ee151
--- /dev/null
+++ b/lttng-context-uts-ns.c
@@ -0,0 +1,110 @@
+/*
+ * lttng-context-uts-ns.c
+ *
+ * LTTng uts namespace context.
+ *
+ * Copyright (C) 2009-2012 Mathieu Desnoyers <mathieu.desnoyers at efficios.com>
+ *               2018 Michael Jeanson <mjeanson at efficios.com>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; only
+ * version 2.1 of the License.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#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;
+
+	/*
+	 * nsproxy can be NULL when scheduled out of exit.
+	 */
+	if (!current->nsproxy)
+		uts_ns_inum = 0;
+	else
+		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;
+
+	/*
+	 * nsproxy can be NULL when scheduled out of exit.
+	 */
+	if (!current->nsproxy)
+		uts_ns_inum = 0;
+	else
+		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
diff --git a/lttng-context.c b/lttng-context.c
index 544e95f..dc91b8d 100644
--- a/lttng-context.c
+++ b/lttng-context.c
@@ -308,6 +308,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;
 }
diff --git a/lttng-events.h b/lttng-events.h
index 17dd8d3..f3b2b91 100644
--- a/lttng-events.h
+++ b/lttng-events.h
@@ -702,6 +702,85 @@ int lttng_add_migratable_to_ctx(struct lttng_ctx **ctx)
 	return -ENOSYS;
 }
 #endif
+
+#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) && (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,33))
 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
index 0000000..7e82cba
--- /dev/null
+++ b/wrapper/namespace.h
@@ -0,0 +1,33 @@
+#ifndef _LTTNG_WRAPPER_NAMESPACE_H
+#define _LTTNG_WRAPPER_NAMESPACE_H
+
+/*
+ * wrapper/namespace.h
+ *
+ * Copyright (C) 2011-2012 Mathieu Desnoyers <mathieu.desnoyers at efficios.com>
+ *               2018 Michael Jeanson <mjeanson at efficios.com>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; only
+ * version 2.1 of the License.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#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 */
-- 
2.7.4



More information about the lttng-dev mailing list