[lttng-dev] [PATCH lttng-ust 1/2] RFC: Add userspace namespace contexts

Michael Jeanson mjeanson at efficios.com
Tue Mar 6 15:53:33 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 introduced in kernel v3.8.0, if any of these context are
enabled on a system running an older kernel, zero will be returned.

Signed-off-by: Michael Jeanson <mjeanson at efficios.com>
---
 include/lttng/ust-abi.h                |   7 ++
 include/lttng/ust-events.h             |  14 ++++
 include/lttng/ust.h                    |   2 +
 liblttng-ust-fork/ustfork.c            |  50 ++++++++++++
 liblttng-ust/Makefile.am               |   7 ++
 liblttng-ust/lttng-context-cgroup-ns.c | 144 +++++++++++++++++++++++++++++++++
 liblttng-ust/lttng-context-ipc-ns.c    | 144 +++++++++++++++++++++++++++++++++
 liblttng-ust/lttng-context-mnt-ns.c    | 144 +++++++++++++++++++++++++++++++++
 liblttng-ust/lttng-context-net-ns.c    | 144 +++++++++++++++++++++++++++++++++
 liblttng-ust/lttng-context-pid-ns.c    | 122 ++++++++++++++++++++++++++++
 liblttng-ust/lttng-context-user-ns.c   | 144 +++++++++++++++++++++++++++++++++
 liblttng-ust/lttng-context-uts-ns.c    | 144 +++++++++++++++++++++++++++++++++
 liblttng-ust/lttng-context.c           |  35 ++++++++
 liblttng-ust/lttng-events.c            |  14 ++++
 liblttng-ust/lttng-tracer-core.h       |  14 ++++
 liblttng-ust/lttng-ust-comm.c          |  29 +++++++
 16 files changed, 1158 insertions(+)
 create mode 100644 liblttng-ust/lttng-context-cgroup-ns.c
 create mode 100644 liblttng-ust/lttng-context-ipc-ns.c
 create mode 100644 liblttng-ust/lttng-context-mnt-ns.c
 create mode 100644 liblttng-ust/lttng-context-net-ns.c
 create mode 100644 liblttng-ust/lttng-context-pid-ns.c
 create mode 100644 liblttng-ust/lttng-context-user-ns.c
 create mode 100644 liblttng-ust/lttng-context-uts-ns.c

diff --git a/include/lttng/ust-abi.h b/include/lttng/ust-abi.h
index 4976b1b..0e0c954 100644
--- a/include/lttng/ust-abi.h
+++ b/include/lttng/ust-abi.h
@@ -141,6 +141,13 @@ enum lttng_ust_context_type {
 	LTTNG_UST_CONTEXT_PERF_THREAD_COUNTER	= 5,
 	LTTNG_UST_CONTEXT_CPU_ID		= 6,
 	LTTNG_UST_CONTEXT_APP_CONTEXT		= 7,
+	LTTNG_UST_CONTEXT_CGROUP_NS		= 8,
+	LTTNG_UST_CONTEXT_IPC_NS		= 9,
+	LTTNG_UST_CONTEXT_MNT_NS		= 10,
+	LTTNG_UST_CONTEXT_NET_NS		= 11,
+	LTTNG_UST_CONTEXT_PID_NS		= 12,
+	LTTNG_UST_CONTEXT_USER_NS		= 13,
+	LTTNG_UST_CONTEXT_UTS_NS		= 14,
 };
 
 struct lttng_ust_perf_counter_ctx {
diff --git a/include/lttng/ust-events.h b/include/lttng/ust-events.h
index 8673350..4f1ee45 100644
--- a/include/lttng/ust-events.h
+++ b/include/lttng/ust-events.h
@@ -674,8 +674,22 @@ int lttng_add_procname_to_ctx(struct lttng_ctx **ctx);
 int lttng_add_ip_to_ctx(struct lttng_ctx **ctx);
 int lttng_add_cpu_id_to_ctx(struct lttng_ctx **ctx);
 int lttng_add_dyntest_to_ctx(struct lttng_ctx **ctx);
+int lttng_add_cgroup_ns_to_ctx(struct lttng_ctx **ctx);
+int lttng_add_ipc_ns_to_ctx(struct lttng_ctx **ctx);
+int lttng_add_mnt_ns_to_ctx(struct lttng_ctx **ctx);
+int lttng_add_net_ns_to_ctx(struct lttng_ctx **ctx);
+int lttng_add_pid_ns_to_ctx(struct lttng_ctx **ctx);
+int lttng_add_user_ns_to_ctx(struct lttng_ctx **ctx);
+int lttng_add_uts_ns_to_ctx(struct lttng_ctx **ctx);
 void lttng_context_vtid_reset(void);
 void lttng_context_vpid_reset(void);
+void lttng_context_cgroup_ns_reset(void);
+void lttng_context_ipc_ns_reset(void);
+void lttng_context_mnt_ns_reset(void);
+void lttng_context_net_ns_reset(void);
+void lttng_context_pid_ns_reset(void);
+void lttng_context_user_ns_reset(void);
+void lttng_context_uts_ns_reset(void);
 
 #ifdef LTTNG_UST_HAVE_PERF_EVENT
 int lttng_add_perf_counter_to_ctx(uint32_t type,
diff --git a/include/lttng/ust.h b/include/lttng/ust.h
index 2779d7a..0b2a897 100644
--- a/include/lttng/ust.h
+++ b/include/lttng/ust.h
@@ -32,6 +32,8 @@ extern "C" {
 extern void ust_before_fork(sigset_t *save_sigset);
 extern void ust_after_fork_parent(sigset_t *restore_sigset);
 extern void ust_after_fork_child(sigset_t *restore_sigset);
+extern void ust_after_setns(void);
+extern void ust_after_unshare(void);
 
 #ifdef __cplusplus 
 }
diff --git a/liblttng-ust-fork/ustfork.c b/liblttng-ust-fork/ustfork.c
index 71c4b86..25f9d4c 100644
--- a/liblttng-ust-fork/ustfork.c
+++ b/liblttng-ust-fork/ustfork.c
@@ -160,6 +160,56 @@ int clone(int (*fn)(void *), void *child_stack, int flags, void *arg, ...)
 	return retval;
 }
 
+int setns(int fd, int nstype)
+{
+	static int (*plibc_func)(int fd, int nstype) = NULL;
+	int retval;
+	int saved_errno;
+
+	if (plibc_func == NULL) {
+		plibc_func = dlsym(RTLD_NEXT, "setns");
+		if (plibc_func == NULL) {
+			fprintf(stderr, "libustfork: unable to find \"setns\" symbol\n");
+			errno = ENOSYS;
+			return -1;
+		}
+	}
+
+	/* Do the real setns */
+	retval = plibc_func(fd, nstype);
+	saved_errno = errno;
+
+	ust_after_setns();
+
+	errno = saved_errno;
+	return retval;
+}
+
+int unshare(int flags)
+{
+	static int (*plibc_func)(int flags) = NULL;
+	int retval;
+	int saved_errno;
+
+	if (plibc_func == NULL) {
+		plibc_func = dlsym(RTLD_NEXT, "unshare");
+		if (plibc_func == NULL) {
+			fprintf(stderr, "libustfork: unable to find \"unshare\" symbol\n");
+			errno = ENOSYS;
+			return -1;
+		}
+	}
+
+	/* Do the real setns */
+	retval = plibc_func(flags);
+	saved_errno = errno;
+
+	ust_after_unshare();
+
+	errno = saved_errno;
+	return retval;
+}
+
 #elif defined (__FreeBSD__)
 
 pid_t rfork(int flags)
diff --git a/liblttng-ust/Makefile.am b/liblttng-ust/Makefile.am
index a7edfd5..bdcc325 100644
--- a/liblttng-ust/Makefile.am
+++ b/liblttng-ust/Makefile.am
@@ -30,6 +30,13 @@ liblttng_ust_runtime_la_SOURCES = \
 	lttng-context-procname.c \
 	lttng-context-ip.c \
 	lttng-context-cpu-id.c \
+	lttng-context-cgroup-ns.c \
+	lttng-context-ipc-ns.c \
+	lttng-context-mnt-ns.c \
+	lttng-context-net-ns.c \
+	lttng-context-pid-ns.c \
+	lttng-context-user-ns.c \
+	lttng-context-uts-ns.c \
 	lttng-context.c \
 	lttng-events.c \
 	lttng-filter.c \
diff --git a/liblttng-ust/lttng-context-cgroup-ns.c b/liblttng-ust/lttng-context-cgroup-ns.c
new file mode 100644
index 0000000..e1d92ca
--- /dev/null
+++ b/liblttng-ust/lttng-context-cgroup-ns.c
@@ -0,0 +1,144 @@
+/*
+ * lttng-context-cgroup-ns.c
+ *
+ * LTTng UST 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
+ */
+
+#define _LGPL_SOURCE
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <unistd.h>
+#include <lttng/ust-events.h>
+#include <lttng/ust-tracer.h>
+#include <lttng/ringbuffer-config.h>
+#include <lttng/ust-tid.h>
+#include <urcu/tls-compat.h>
+#include "lttng-tracer-core.h"
+
+/*
+ * We cache the result to ensure we don't trigger a system call for
+ * each event.
+ */
+static DEFINE_URCU_TLS(unsigned int, cached_cgroup_ns);
+
+static
+unsigned int get_cgroup_ns(void)
+{
+	if (caa_unlikely(!URCU_TLS(cached_cgroup_ns))) {
+		struct stat sb;
+
+		/*
+		 * /proc/thread-self was introduced in kernel v3.17
+		 */
+		if (stat("/proc/thread-self/ns/cgroup", &sb) == 0) {
+			URCU_TLS(cached_cgroup_ns) = sb.st_ino;
+		} else {
+			char proc_ns_path[LTTNG_PROC_NS_PATH_MAX];
+
+			if (snprintf(proc_ns_path, LTTNG_PROC_NS_PATH_MAX,
+					"/proc/self/task/%d/ns/cgroup",
+					gettid()) < 0) {
+				goto end;
+			}
+			if (stat(proc_ns_path, &sb) == 0) {
+				URCU_TLS(cached_cgroup_ns) = sb.st_ino;
+			}
+		}
+	}
+end:
+	return URCU_TLS(cached_cgroup_ns);
+}
+
+/*
+ * The cgroup namespace can change for 3 reasons
+ *  * clone(2) called with CLONE_NEWCGROUP
+ *  * setns(2) called with the fd of a different cgroup ns
+ *  * unshare(2) called with CLONE_NEWCGROUP
+ */
+void lttng_context_cgroup_ns_reset(void)
+{
+	URCU_TLS(cached_cgroup_ns) = 0;
+}
+
+static
+size_t cgroup_ns_get_size(struct lttng_ctx_field *field, 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 lttng_ust_lib_ring_buffer_ctx *ctx,
+		 struct lttng_channel *chan)
+{
+	unsigned int cgroup_ns;
+
+	cgroup_ns = get_cgroup_ns();
+	lib_ring_buffer_align_ctx(ctx, lttng_alignof(cgroup_ns));
+	chan->ops->event_write(ctx, &cgroup_ns, sizeof(cgroup_ns));
+}
+
+static
+void cgroup_ns_get_value(struct lttng_ctx_field *field,
+		struct lttng_ctx_value *value)
+{
+	unsigned int cgroup_ns;
+
+	cgroup_ns = get_cgroup_ns();
+	value->u.s64 = cgroup_ns;
+}
+
+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);
+	return 0;
+}
+
+/*
+ *  * Force a read (imply TLS fixup for dlopen) of TLS variables.
+ *   */
+void lttng_fixup_cgroup_ns_tls(void)
+{
+	asm volatile ("" : : "m" (URCU_TLS(cached_cgroup_ns)));
+}
diff --git a/liblttng-ust/lttng-context-ipc-ns.c b/liblttng-ust/lttng-context-ipc-ns.c
new file mode 100644
index 0000000..b52994e
--- /dev/null
+++ b/liblttng-ust/lttng-context-ipc-ns.c
@@ -0,0 +1,144 @@
+/*
+ * lttng-context-ipc-ns.c
+ *
+ * LTTng UST 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
+ */
+
+#define _LGPL_SOURCE
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <unistd.h>
+#include <lttng/ust-events.h>
+#include <lttng/ust-tracer.h>
+#include <lttng/ringbuffer-config.h>
+#include <lttng/ust-tid.h>
+#include <urcu/tls-compat.h>
+#include "lttng-tracer-core.h"
+
+/*
+ * We cache the result to ensure we don't trigger a system call for
+ * each event.
+ */
+static DEFINE_URCU_TLS(unsigned int, cached_ipc_ns);
+
+static
+unsigned int get_ipc_ns(void)
+{
+	if (caa_unlikely(!URCU_TLS(cached_ipc_ns))) {
+		struct stat sb;
+
+		/*
+		 * /proc/thread-self was introduced in kernel v3.17
+		 */
+		if (stat("/proc/thread-self/ns/ipc", &sb) == 0) {
+			URCU_TLS(cached_ipc_ns) = sb.st_ino;
+		} else {
+			char proc_ns_path[LTTNG_PROC_NS_PATH_MAX];
+
+			if (snprintf(proc_ns_path, LTTNG_PROC_NS_PATH_MAX,
+					"/proc/self/task/%d/ns/ipc",
+					gettid()) < 0) {
+				goto end;
+			}
+			if (stat(proc_ns_path, &sb) == 0) {
+				URCU_TLS(cached_ipc_ns) = sb.st_ino;
+			}
+		}
+	}
+end:
+	return URCU_TLS(cached_ipc_ns);
+}
+
+/*
+ * The ipc namespace can change for 3 reasons
+ *  * clone(2) called with CLONE_NEWIPC
+ *  * setns(2) called with the fd of a different ipc ns
+ *  * unshare(2) called with CLONE_NEWIPC
+ */
+void lttng_context_ipc_ns_reset(void)
+{
+	URCU_TLS(cached_ipc_ns) = 0;
+}
+
+static
+size_t ipc_ns_get_size(struct lttng_ctx_field *field, 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 lttng_ust_lib_ring_buffer_ctx *ctx,
+		 struct lttng_channel *chan)
+{
+	unsigned int ipc_ns;
+
+	ipc_ns = get_ipc_ns();
+	lib_ring_buffer_align_ctx(ctx, lttng_alignof(ipc_ns));
+	chan->ops->event_write(ctx, &ipc_ns, sizeof(ipc_ns));
+}
+
+static
+void ipc_ns_get_value(struct lttng_ctx_field *field,
+		struct lttng_ctx_value *value)
+{
+	unsigned int ipc_ns;
+
+	ipc_ns = get_ipc_ns();
+	value->u.s64 = ipc_ns;
+}
+
+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);
+	return 0;
+}
+
+/*
+ *  * Force a read (imply TLS fixup for dlopen) of TLS variables.
+ *   */
+void lttng_fixup_ipc_ns_tls(void)
+{
+	asm volatile ("" : : "m" (URCU_TLS(cached_ipc_ns)));
+}
diff --git a/liblttng-ust/lttng-context-mnt-ns.c b/liblttng-ust/lttng-context-mnt-ns.c
new file mode 100644
index 0000000..b19e438
--- /dev/null
+++ b/liblttng-ust/lttng-context-mnt-ns.c
@@ -0,0 +1,144 @@
+/*
+ * lttng-context-mnt-ns.c
+ *
+ * LTTng UST mnt 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
+ */
+
+#define _LGPL_SOURCE
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <unistd.h>
+#include <lttng/ust-events.h>
+#include <lttng/ust-tracer.h>
+#include <lttng/ringbuffer-config.h>
+#include <lttng/ust-tid.h>
+#include <urcu/tls-compat.h>
+#include "lttng-tracer-core.h"
+
+/*
+ * We cache the result to ensure we don't trigger a system call for
+ * each event.
+ */
+static DEFINE_URCU_TLS(unsigned int, cached_mnt_ns);
+
+static
+unsigned int get_mnt_ns(void)
+{
+	if (caa_unlikely(!URCU_TLS(cached_mnt_ns))) {
+		struct stat sb;
+
+		/*
+		 * /proc/thread-self was introduced in kernel v3.17
+		 */
+		if (stat("/proc/thread-self/ns/mnt", &sb) == 0) {
+			URCU_TLS(cached_mnt_ns) = sb.st_ino;
+		} else {
+			char proc_ns_path[LTTNG_PROC_NS_PATH_MAX];
+
+			if (snprintf(proc_ns_path, LTTNG_PROC_NS_PATH_MAX,
+					"/proc/self/task/%d/ns/mnt",
+					gettid()) < 0) {
+				goto end;
+			}
+			if (stat(proc_ns_path, &sb) == 0) {
+				URCU_TLS(cached_mnt_ns) = sb.st_ino;
+			}
+		}
+	}
+end:
+	return URCU_TLS(cached_mnt_ns);
+}
+
+/*
+ * The mnt namespace can change for 3 reasons
+ *  * clone(2) called with CLONE_NEWNS
+ *  * setns(2) called with the fd of a different mnt ns
+ *  * unshare(2) called with CLONE_NEWNS
+ */
+void lttng_context_mnt_ns_reset(void)
+{
+	URCU_TLS(cached_mnt_ns) = 0;
+}
+
+static
+size_t mnt_ns_get_size(struct lttng_ctx_field *field, 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 lttng_ust_lib_ring_buffer_ctx *ctx,
+		 struct lttng_channel *chan)
+{
+	unsigned int mnt_ns;
+
+	mnt_ns = get_mnt_ns();
+	lib_ring_buffer_align_ctx(ctx, lttng_alignof(mnt_ns));
+	chan->ops->event_write(ctx, &mnt_ns, sizeof(mnt_ns));
+}
+
+static
+void mnt_ns_get_value(struct lttng_ctx_field *field,
+		struct lttng_ctx_value *value)
+{
+	unsigned int mnt_ns;
+
+	mnt_ns = get_mnt_ns();
+	value->u.s64 = mnt_ns;
+}
+
+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);
+	return 0;
+}
+
+/*
+ *  * Force a read (imply TLS fixup for dlopen) of TLS variables.
+ *   */
+void lttng_fixup_mnt_ns_tls(void)
+{
+	asm volatile ("" : : "m" (URCU_TLS(cached_mnt_ns)));
+}
diff --git a/liblttng-ust/lttng-context-net-ns.c b/liblttng-ust/lttng-context-net-ns.c
new file mode 100644
index 0000000..53512e0
--- /dev/null
+++ b/liblttng-ust/lttng-context-net-ns.c
@@ -0,0 +1,144 @@
+/*
+ * lttng-context-net-ns.c
+ *
+ * LTTng UST 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
+ */
+
+#define _LGPL_SOURCE
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <unistd.h>
+#include <lttng/ust-events.h>
+#include <lttng/ust-tracer.h>
+#include <lttng/ringbuffer-config.h>
+#include <lttng/ust-tid.h>
+#include <urcu/tls-compat.h>
+#include "lttng-tracer-core.h"
+
+/*
+ * We cache the result to ensure we don't trigger a system call for
+ * each event.
+ */
+static DEFINE_URCU_TLS(unsigned int, cached_net_ns);
+
+static
+unsigned int get_net_ns(void)
+{
+	if (caa_unlikely(!URCU_TLS(cached_net_ns))) {
+		struct stat sb;
+
+		/*
+		 * /proc/thread-self was introduced in kernel v3.17
+		 */
+		if (stat("/proc/thread-self/ns/net", &sb) == 0) {
+			URCU_TLS(cached_net_ns) = sb.st_ino;
+		} else {
+			char proc_ns_path[LTTNG_PROC_NS_PATH_MAX];
+
+			if (snprintf(proc_ns_path, LTTNG_PROC_NS_PATH_MAX,
+					"/proc/self/task/%d/ns/net",
+					gettid()) < 0) {
+				goto end;
+			}
+			if (stat(proc_ns_path, &sb) == 0) {
+				URCU_TLS(cached_net_ns) = sb.st_ino;
+			}
+		}
+	}
+end:
+	return URCU_TLS(cached_net_ns);
+}
+
+/*
+ * The net namespace can change for 3 reasons
+ *  * clone(2) called with CLONE_NEWNET
+ *  * setns(2) called with the fd of a different net ns
+ *  * unshare(2) called with CLONE_NEWNET
+ */
+void lttng_context_net_ns_reset(void)
+{
+	URCU_TLS(cached_net_ns) = 0;
+}
+
+static
+size_t net_ns_get_size(struct lttng_ctx_field *field, 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 lttng_ust_lib_ring_buffer_ctx *ctx,
+		 struct lttng_channel *chan)
+{
+	unsigned int net_ns;
+
+	net_ns = get_net_ns();
+	lib_ring_buffer_align_ctx(ctx, lttng_alignof(net_ns));
+	chan->ops->event_write(ctx, &net_ns, sizeof(net_ns));
+}
+
+static
+void net_ns_get_value(struct lttng_ctx_field *field,
+		struct lttng_ctx_value *value)
+{
+	unsigned int net_ns;
+
+	net_ns = get_net_ns();
+	value->u.s64 = net_ns;
+}
+
+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);
+	return 0;
+}
+
+/*
+ *  * Force a read (imply TLS fixup for dlopen) of TLS variables.
+ *   */
+void lttng_fixup_net_ns_tls(void)
+{
+	asm volatile ("" : : "m" (URCU_TLS(cached_net_ns)));
+}
diff --git a/liblttng-ust/lttng-context-pid-ns.c b/liblttng-ust/lttng-context-pid-ns.c
new file mode 100644
index 0000000..030cbc3
--- /dev/null
+++ b/liblttng-ust/lttng-context-pid-ns.c
@@ -0,0 +1,122 @@
+/*
+ * lttng-context-pid-ns.c
+ *
+ * LTTng UST 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
+ */
+
+#define _LGPL_SOURCE
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <unistd.h>
+#include <lttng/ust-events.h>
+#include <lttng/ust-tracer.h>
+#include <lttng/ringbuffer-config.h>
+
+/*
+ * We cache the result to ensure we don't trigger a system call for
+ * each event. The PID namespace is global to the process.
+ */
+static unsigned int cached_pid_ns;
+
+static
+unsigned int get_pid_ns(void)
+{
+	if (caa_unlikely(!cached_pid_ns)) {
+		struct stat sb;
+
+		if (stat("/proc/self/ns/pid", &sb) == 0) {
+			cached_pid_ns = sb.st_ino;
+		}
+	}
+
+	return cached_pid_ns;
+}
+
+/*
+ * A process's PID namespace membership is determined when the process is
+ * created and cannot be changed thereafter.
+ *
+ * The pid namespace can change only on clone(2) / fork(2) :
+ *  - clone(2) with the CLONE_NEWPID flag
+ *  - clone(2) / fork(2) after a call to unshare(2) with the CLONE_NEWPID flag
+ *  - clone(2) / fork(2) after a call to setns(2) with a PID namespace fd
+ */
+void lttng_context_pid_ns_reset(void)
+{
+	cached_pid_ns = 0;
+}
+
+static
+size_t pid_ns_get_size(struct lttng_ctx_field *field, 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 lttng_ust_lib_ring_buffer_ctx *ctx,
+		 struct lttng_channel *chan)
+{
+	unsigned int pid_ns;
+
+	pid_ns = get_pid_ns();
+	lib_ring_buffer_align_ctx(ctx, lttng_alignof(pid_ns));
+	chan->ops->event_write(ctx, &pid_ns, sizeof(pid_ns));
+}
+
+static
+void pid_ns_get_value(struct lttng_ctx_field *field,
+		struct lttng_ctx_value *value)
+{
+	unsigned int pid_ns;
+
+	pid_ns = get_pid_ns();
+	value->u.s64 = pid_ns;
+}
+
+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);
+	return 0;
+}
diff --git a/liblttng-ust/lttng-context-user-ns.c b/liblttng-ust/lttng-context-user-ns.c
new file mode 100644
index 0000000..e26463f
--- /dev/null
+++ b/liblttng-ust/lttng-context-user-ns.c
@@ -0,0 +1,144 @@
+/*
+ * lttng-context-user-ns.c
+ *
+ * LTTng UST 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
+ */
+
+#define _LGPL_SOURCE
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <unistd.h>
+#include <lttng/ust-events.h>
+#include <lttng/ust-tracer.h>
+#include <lttng/ringbuffer-config.h>
+#include <lttng/ust-tid.h>
+#include <urcu/tls-compat.h>
+#include "lttng-tracer-core.h"
+
+/*
+ * We cache the result to ensure we don't trigger a system call for
+ * each event.
+ */
+static DEFINE_URCU_TLS(unsigned int, cached_user_ns);
+
+static
+unsigned int get_user_ns(void)
+{
+	if (caa_unlikely(!URCU_TLS(cached_user_ns))) {
+		struct stat sb;
+
+		/*
+		 * /proc/thread-self was introduced in kernel v3.17
+		 */
+		if (stat("/proc/thread-self/ns/user", &sb) == 0) {
+			URCU_TLS(cached_user_ns) = sb.st_ino;
+		} else {
+			char proc_ns_path[LTTNG_PROC_NS_PATH_MAX];
+
+			if (snprintf(proc_ns_path, LTTNG_PROC_NS_PATH_MAX,
+					"/proc/self/task/%d/ns/user",
+					gettid()) < 0) {
+				goto end;
+			}
+			if (stat(proc_ns_path, &sb) == 0) {
+				URCU_TLS(cached_user_ns) = sb.st_ino;
+			}
+		}
+	}
+end:
+	return URCU_TLS(cached_user_ns);
+}
+
+/*
+ * The user namespace can change for 3 reasons
+ *  * clone(2) called with CLONE_NEWUSER
+ *  * setns(2) called with the fd of a different user ns
+ *  * unshare(2) called with CLONE_NEWUSER
+ */
+void lttng_context_user_ns_reset(void)
+{
+	URCU_TLS(cached_user_ns) = 0;
+}
+
+static
+size_t user_ns_get_size(struct lttng_ctx_field *field, 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 lttng_ust_lib_ring_buffer_ctx *ctx,
+		 struct lttng_channel *chan)
+{
+	unsigned int user_ns;
+
+	user_ns = get_user_ns();
+	lib_ring_buffer_align_ctx(ctx, lttng_alignof(user_ns));
+	chan->ops->event_write(ctx, &user_ns, sizeof(user_ns));
+}
+
+static
+void user_ns_get_value(struct lttng_ctx_field *field,
+		struct lttng_ctx_value *value)
+{
+	unsigned int user_ns;
+
+	user_ns = get_user_ns();
+	value->u.s64 = user_ns;
+}
+
+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);
+	return 0;
+}
+
+/*
+ *  * Force a read (imply TLS fixup for dlopen) of TLS variables.
+ *   */
+void lttng_fixup_user_ns_tls(void)
+{
+	asm volatile ("" : : "m" (URCU_TLS(cached_user_ns)));
+}
diff --git a/liblttng-ust/lttng-context-uts-ns.c b/liblttng-ust/lttng-context-uts-ns.c
new file mode 100644
index 0000000..aa79b03
--- /dev/null
+++ b/liblttng-ust/lttng-context-uts-ns.c
@@ -0,0 +1,144 @@
+/*
+ * lttng-context-uts-ns.c
+ *
+ * LTTng UST 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
+ */
+
+#define _LGPL_SOURCE
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <unistd.h>
+#include <lttng/ust-events.h>
+#include <lttng/ust-tracer.h>
+#include <lttng/ringbuffer-config.h>
+#include <lttng/ust-tid.h>
+#include <urcu/tls-compat.h>
+#include "lttng-tracer-core.h"
+
+/*
+ * We cache the result to ensure we don't trigger a system call for
+ * each event.
+ */
+static DEFINE_URCU_TLS(unsigned int, cached_uts_ns);
+
+static
+unsigned int get_uts_ns(void)
+{
+	if (caa_unlikely(!URCU_TLS(cached_uts_ns))) {
+		struct stat sb;
+
+		/*
+		 * /proc/thread-self was introduced in kernel v3.17
+		 */
+		if (stat("/proc/thread-self/ns/uts", &sb) == 0) {
+			URCU_TLS(cached_uts_ns) = sb.st_ino;
+		} else {
+			char proc_ns_path[LTTNG_PROC_NS_PATH_MAX];
+
+			if (snprintf(proc_ns_path, LTTNG_PROC_NS_PATH_MAX,
+					"/proc/self/task/%d/ns/uts",
+					gettid()) < 0) {
+				goto end;
+			}
+			if (stat(proc_ns_path, &sb) == 0) {
+				URCU_TLS(cached_uts_ns) = sb.st_ino;
+			}
+		}
+	}
+end:
+	return URCU_TLS(cached_uts_ns);
+}
+
+/*
+ * The uts namespace can change for 3 reasons
+ *  * clone(2) called with CLONE_NEWUTS
+ *  * setns(2) called with the fd of a different uts ns
+ *  * unshare(2) called with CLONE_NEWUTS
+ */
+void lttng_context_uts_ns_reset(void)
+{
+	URCU_TLS(cached_uts_ns) = 0;
+}
+
+static
+size_t uts_ns_get_size(struct lttng_ctx_field *field, 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 lttng_ust_lib_ring_buffer_ctx *ctx,
+		 struct lttng_channel *chan)
+{
+	unsigned int uts_ns;
+
+	uts_ns = get_uts_ns();
+	lib_ring_buffer_align_ctx(ctx, lttng_alignof(uts_ns));
+	chan->ops->event_write(ctx, &uts_ns, sizeof(uts_ns));
+}
+
+static
+void uts_ns_get_value(struct lttng_ctx_field *field,
+		struct lttng_ctx_value *value)
+{
+	unsigned int uts_ns;
+
+	uts_ns = get_uts_ns();
+	value->u.s64 = uts_ns;
+}
+
+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);
+	return 0;
+}
+
+/*
+ *  * Force a read (imply TLS fixup for dlopen) of TLS variables.
+ *   */
+void lttng_fixup_uts_ns_tls(void)
+{
+	asm volatile ("" : : "m" (URCU_TLS(cached_uts_ns)));
+}
diff --git a/liblttng-ust/lttng-context.c b/liblttng-ust/lttng-context.c
index eeaaae4..ad6c38f 100644
--- a/liblttng-ust/lttng-context.c
+++ b/liblttng-ust/lttng-context.c
@@ -372,6 +372,41 @@ int lttng_session_context_init(struct lttng_ctx **ctx)
 		WARN("Cannot add context lttng_add_cpu_id_to_ctx");
 		goto error;
 	}
+	ret = lttng_add_cgroup_ns_to_ctx(ctx);
+	if (ret) {
+		WARN("Cannot add context lttng_add_cgroup_ns_to_ctx");
+		goto error;
+	}
+	ret = lttng_add_ipc_ns_to_ctx(ctx);
+	if (ret) {
+		WARN("Cannot add context lttng_add_ipc_ns_to_ctx");
+		goto error;
+	}
+	ret = lttng_add_mnt_ns_to_ctx(ctx);
+	if (ret) {
+		WARN("Cannot add context lttng_add_mnt_ns_to_ctx");
+		goto error;
+	}
+	ret = lttng_add_net_ns_to_ctx(ctx);
+	if (ret) {
+		WARN("Cannot add context lttng_add_net_ns_to_ctx");
+		goto error;
+	}
+	ret = lttng_add_pid_ns_to_ctx(ctx);
+	if (ret) {
+		WARN("Cannot add context lttng_add_pid_ns_to_ctx");
+		goto error;
+	}
+	ret = lttng_add_user_ns_to_ctx(ctx);
+	if (ret) {
+		WARN("Cannot add context lttng_add_user_ns_to_ctx");
+		goto error;
+	}
+	ret = lttng_add_uts_ns_to_ctx(ctx);
+	if (ret) {
+		WARN("Cannot add context lttng_add_uts_ns_to_ctx");
+		goto error;
+	}
 	lttng_context_update(*ctx);
 	return 0;
 
diff --git a/liblttng-ust/lttng-events.c b/liblttng-ust/lttng-events.c
index 255c4b9..329aae0 100644
--- a/liblttng-ust/lttng-events.c
+++ b/liblttng-ust/lttng-events.c
@@ -1112,6 +1112,20 @@ int lttng_attach_context(struct lttng_ust_context *context_param,
 	case LTTNG_UST_CONTEXT_APP_CONTEXT:
 		return lttng_ust_add_app_context_to_ctx_rcu(uargs->app_context.ctxname,
 			ctx);
+	case LTTNG_UST_CONTEXT_CGROUP_NS:
+		return lttng_add_cgroup_ns_to_ctx(ctx);
+	case LTTNG_UST_CONTEXT_IPC_NS:
+		return lttng_add_ipc_ns_to_ctx(ctx);
+	case LTTNG_UST_CONTEXT_MNT_NS:
+		return lttng_add_mnt_ns_to_ctx(ctx);
+	case LTTNG_UST_CONTEXT_NET_NS:
+		return lttng_add_net_ns_to_ctx(ctx);
+	case LTTNG_UST_CONTEXT_PID_NS:
+		return lttng_add_pid_ns_to_ctx(ctx);
+	case LTTNG_UST_CONTEXT_USER_NS:
+		return lttng_add_user_ns_to_ctx(ctx);
+	case LTTNG_UST_CONTEXT_UTS_NS:
+		return lttng_add_uts_ns_to_ctx(ctx);
 	default:
 		return -EINVAL;
 	}
diff --git a/liblttng-ust/lttng-tracer-core.h b/liblttng-ust/lttng-tracer-core.h
index ba232f3..d249d19 100644
--- a/liblttng-ust/lttng-tracer-core.h
+++ b/liblttng-ust/lttng-tracer-core.h
@@ -30,6 +30,14 @@
 #include <lttng/ringbuffer-config.h>
 #include <usterr-signal-safe.h>
 
+/*
+ * The longuest possible namespace proc path is with the cgroup ns
+ * and the maximum theoretical linux pid of 536870912 :
+ *
+ *  /proc/self/task/536870912/ns/cgroup
+ */
+#define LTTNG_PROC_NS_PATH_MAX 40
+
 struct lttng_session;
 struct lttng_channel;
 struct lttng_event;
@@ -44,6 +52,12 @@ void ust_unlock(void);
 void lttng_fixup_event_tls(void);
 void lttng_fixup_vtid_tls(void);
 void lttng_fixup_procname_tls(void);
+void lttng_fixup_cgroup_ns_tls(void);
+void lttng_fixup_ipc_ns_tls(void);
+void lttng_fixup_mnt_ns_tls(void);
+void lttng_fixup_net_ns_tls(void);
+void lttng_fixup_user_ns_tls(void);
+void lttng_fixup_uts_ns_tls(void);
 
 const char *lttng_ust_obj_get_name(int id);
 
diff --git a/liblttng-ust/lttng-ust-comm.c b/liblttng-ust/lttng-ust-comm.c
index d4add1c..eda4904 100644
--- a/liblttng-ust/lttng-ust-comm.c
+++ b/liblttng-ust/lttng-ust-comm.c
@@ -411,6 +411,12 @@ void lttng_ust_fixup_tls(void)
 	lttng_fixup_procname_tls();
 	lttng_fixup_ust_mutex_nest_tls();
 	lttng_ust_fixup_fd_tracker_tls();
+	lttng_fixup_cgroup_ns_tls();
+	lttng_fixup_ipc_ns_tls();
+	lttng_fixup_mnt_ns_tls();
+	lttng_fixup_net_ns_tls();
+	lttng_fixup_user_ns_tls();
+	lttng_fixup_uts_ns_tls();
 }
 
 int lttng_get_notify_socket(void *owner)
@@ -1936,6 +1942,18 @@ void __attribute__((destructor)) lttng_ust_exit(void)
 	lttng_ust_cleanup(1);
 }
 
+static
+void ust_context_ns_reset(void)
+{
+	lttng_context_pid_ns_reset();
+	lttng_context_cgroup_ns_reset();
+	lttng_context_ipc_ns_reset();
+	lttng_context_mnt_ns_reset();
+	lttng_context_net_ns_reset();
+	lttng_context_user_ns_reset();
+	lttng_context_uts_ns_reset();
+}
+
 /*
  * We exclude the worker threads across fork and clone (except
  * CLONE_VM), because these system calls only keep the forking thread
@@ -2013,6 +2031,7 @@ void ust_after_fork_child(sigset_t *restore_sigset)
 		return;
 	lttng_context_vpid_reset();
 	lttng_context_vtid_reset();
+	ust_context_ns_reset();
 	DBG("process %d", getpid());
 	/* Release urcu mutexes */
 	rcu_bp_after_fork_child();
@@ -2022,6 +2041,16 @@ void ust_after_fork_child(sigset_t *restore_sigset)
 	lttng_ust_init();
 }
 
+void ust_after_setns(void)
+{
+	ust_context_ns_reset();
+}
+
+void ust_after_unshare(void)
+{
+	ust_context_ns_reset();
+}
+
 void lttng_ust_sockinfo_session_enabled(void *owner)
 {
 	struct sock_info *sock_info = owner;
-- 
2.7.4





More information about the lttng-dev mailing list