`vpid`::
Virtual process ID: process ID as seen from the point of view of
- the process namespace.
+ the current man:pid_namespaces(7).
`vtid`::
Virtual thread ID: thread ID as seen from the point of view of
- the process namespace.
+ the current man:pid_namespaces(7).
+
+The following man:namespaces(7) context fields are supported by LTTng-UST:
+
+`cgroup_ns`::
+ Cgroup root directory namespace: inode number of the current
+ man:cgroup_namespaces(7) in the proc filesystem.
+
+`ipc_ns`::
+ System V IPC, POSIX message queues namespace: inode number of the
+ current IPC namespace in the proc filesystem.
+
+`mnt_ns`::
+ Mount points namespace: inode number of the current Mount namespace
+ in the proc filesystem.
+
+`net_ns`::
+ Network devices, stacks, ports namespace: inode number of the
+ current Network namespace in the proc filesystem.
+
+`pid_ns`::
+ Process IDs namespace: inode number of the current
+ man:pid_namespaces(7) in the proc filesystem.
+
+`user_ns`::
+ User and group IDs namespace: inode number of the current
+ man:user_namespaces(7) in the proc filesystem.
+
+`uts_ns`::
+ Hostname and NIS domain name namespace: inode number of the
+ current UTS namespace in the proc filesystem.
[[state-dump]]
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 {
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_procname_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,
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
}
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)
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 \
lttng-ust-tracelog-provider.h \
getenv.h \
string-utils.c \
- string-utils.h
+ string-utils.h \
+ ns.h
if HAVE_PERF_EVENT
liblttng_ust_runtime_la_SOURCES += \
--- /dev/null
+/*
+ * lttng-context-cgroup-ns.c
+ *
+ * LTTng UST cgroup namespace context.
+ *
+ * Copyright (C) 2009-2012 Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
+ * 2019 Michael Jeanson <mjeanson@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"
+#include "ns.h"
+
+
+/*
+ * We cache the result to ensure we don't stat(2) the proc filesystem on
+ * each event.
+ */
+static DEFINE_URCU_TLS(ino_t, cached_cgroup_ns) = NS_INO_UNINITIALIZED;
+
+static
+ino_t get_cgroup_ns(void)
+{
+ struct stat sb;
+ ino_t cgroup_ns;
+
+ cgroup_ns = CMM_LOAD_SHARED(URCU_TLS(cached_cgroup_ns));
+
+ /*
+ * If the cache is populated, do nothing and return the
+ * cached inode number.
+ */
+ if (caa_likely(cgroup_ns != NS_INO_UNINITIALIZED))
+ return cgroup_ns;
+
+ /*
+ * At this point we have to populate the cache, set the initial
+ * value to NS_INO_UNAVAILABLE (0), if we fail to get the inode
+ * number from the proc filesystem, this is the value we will
+ * cache.
+ */
+ cgroup_ns = NS_INO_UNAVAILABLE;
+
+ /*
+ * /proc/thread-self was introduced in kernel v3.17
+ */
+ if (stat("/proc/thread-self/ns/cgroup", &sb) == 0) {
+ 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",
+ lttng_gettid()) >= 0) {
+
+ if (stat(proc_ns_path, &sb) == 0) {
+ cgroup_ns = sb.st_ino;
+ }
+ }
+ }
+
+ /*
+ * And finally, store the inode number in the cache.
+ */
+ CMM_STORE_SHARED(URCU_TLS(cached_cgroup_ns), cgroup_ns);
+
+ return 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)
+{
+ CMM_STORE_SHARED(URCU_TLS(cached_cgroup_ns), NS_INO_UNINITIALIZED);
+}
+
+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(ino_t));
+ size += sizeof(ino_t);
+ return size;
+}
+
+static
+void cgroup_ns_record(struct lttng_ctx_field *field,
+ struct lttng_ust_lib_ring_buffer_ctx *ctx,
+ struct lttng_channel *chan)
+{
+ ino_t 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)
+{
+ value->u.s64 = get_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(ino_t) * CHAR_BIT;
+ field->event_field.type.u.basic.integer.alignment = lttng_alignof(ino_t) * CHAR_BIT;
+ field->event_field.type.u.basic.integer.signedness = lttng_is_signed_type(ino_t);
+ 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)));
+}
--- /dev/null
+/*
+ * lttng-context-ipc-ns.c
+ *
+ * LTTng UST ipc namespace context.
+ *
+ * Copyright (C) 2009-2012 Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
+ * 2019 Michael Jeanson <mjeanson@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"
+#include "ns.h"
+
+
+/*
+ * We cache the result to ensure we don't stat(2) the proc filesystem on
+ * each event.
+ */
+static DEFINE_URCU_TLS(ino_t, cached_ipc_ns) = NS_INO_UNINITIALIZED;
+
+static
+ino_t get_ipc_ns(void)
+{
+ struct stat sb;
+ ino_t ipc_ns;
+
+ ipc_ns = CMM_LOAD_SHARED(URCU_TLS(cached_ipc_ns));
+
+ /*
+ * If the cache is populated, do nothing and return the
+ * cached inode number.
+ */
+ if (caa_likely(ipc_ns != NS_INO_UNINITIALIZED))
+ return ipc_ns;
+
+ /*
+ * At this point we have to populate the cache, set the initial
+ * value to NS_INO_UNAVAILABLE (0), if we fail to get the inode
+ * number from the proc filesystem, this is the value we will
+ * cache.
+ */
+ ipc_ns = NS_INO_UNAVAILABLE;
+
+ /*
+ * /proc/thread-self was introduced in kernel v3.17
+ */
+ if (stat("/proc/thread-self/ns/ipc", &sb) == 0) {
+ 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",
+ lttng_gettid()) >= 0) {
+
+ if (stat(proc_ns_path, &sb) == 0) {
+ ipc_ns = sb.st_ino;
+ }
+ }
+ }
+
+ /*
+ * And finally, store the inode number in the cache.
+ */
+ CMM_STORE_SHARED(URCU_TLS(cached_ipc_ns), ipc_ns);
+
+ return 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)
+{
+ CMM_STORE_SHARED(URCU_TLS(cached_ipc_ns), NS_INO_UNINITIALIZED);
+}
+
+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(ino_t));
+ size += sizeof(ino_t);
+ return size;
+}
+
+static
+void ipc_ns_record(struct lttng_ctx_field *field,
+ struct lttng_ust_lib_ring_buffer_ctx *ctx,
+ struct lttng_channel *chan)
+{
+ ino_t 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)
+{
+ value->u.s64 = get_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(ino_t) * CHAR_BIT;
+ field->event_field.type.u.basic.integer.alignment = lttng_alignof(ino_t) * CHAR_BIT;
+ field->event_field.type.u.basic.integer.signedness = lttng_is_signed_type(ino_t);
+ 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)));
+}
--- /dev/null
+/*
+ * lttng-context-mnt-ns.c
+ *
+ * LTTng UST mnt namespace context.
+ *
+ * Copyright (C) 2009-2012 Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
+ * 2019 Michael Jeanson <mjeanson@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 "ns.h"
+
+/*
+ * We cache the result to ensure we don't stat(2) the proc filesystem on
+ * each event. The mount namespace is global to the process.
+ */
+static ino_t cached_mnt_ns = NS_INO_UNINITIALIZED;
+
+static
+ino_t get_mnt_ns(void)
+{
+ struct stat sb;
+ ino_t mnt_ns;
+
+ mnt_ns = CMM_LOAD_SHARED(cached_mnt_ns);
+
+ /*
+ * If the cache is populated, do nothing and return the
+ * cached inode number.
+ */
+ if (caa_likely(mnt_ns != NS_INO_UNINITIALIZED))
+ return mnt_ns;
+
+ /*
+ * At this point we have to populate the cache, set the initial
+ * value to NS_INO_UNAVAILABLE (0), if we fail to get the inode
+ * number from the proc filesystem, this is the value we will
+ * cache.
+ */
+ mnt_ns = NS_INO_UNAVAILABLE;
+
+ if (stat("/proc/self/ns/mnt", &sb) == 0) {
+ mnt_ns = sb.st_ino;
+ }
+
+ /*
+ * And finally, store the inode number in the cache.
+ */
+ CMM_STORE_SHARED(cached_mnt_ns, mnt_ns);
+
+ return 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)
+{
+ CMM_STORE_SHARED(cached_mnt_ns, NS_INO_UNINITIALIZED);
+}
+
+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(ino_t));
+ size += sizeof(ino_t);
+ return size;
+}
+
+static
+void mnt_ns_record(struct lttng_ctx_field *field,
+ struct lttng_ust_lib_ring_buffer_ctx *ctx,
+ struct lttng_channel *chan)
+{
+ ino_t 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)
+{
+ value->u.s64 = get_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(ino_t) * CHAR_BIT;
+ field->event_field.type.u.basic.integer.alignment = lttng_alignof(ino_t) * CHAR_BIT;
+ field->event_field.type.u.basic.integer.signedness = lttng_is_signed_type(ino_t);
+ 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;
+}
--- /dev/null
+/*
+ * lttng-context-net-ns.c
+ *
+ * LTTng UST net namespace context.
+ *
+ * Copyright (C) 2009-2012 Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
+ * 2019 Michael Jeanson <mjeanson@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"
+#include "ns.h"
+
+
+/*
+ * We cache the result to ensure we don't stat(2) the proc filesystem on
+ * each event.
+ */
+static DEFINE_URCU_TLS(ino_t, cached_net_ns) = NS_INO_UNINITIALIZED;
+
+static
+ino_t get_net_ns(void)
+{
+ struct stat sb;
+ ino_t net_ns;
+
+ net_ns = CMM_LOAD_SHARED(URCU_TLS(cached_net_ns));
+
+ /*
+ * If the cache is populated, do nothing and return the
+ * cached inode number.
+ */
+ if (caa_likely(net_ns != NS_INO_UNINITIALIZED))
+ return net_ns;
+
+ /*
+ * At this point we have to populate the cache, set the initial
+ * value to NS_INO_UNAVAILABLE (0), if we fail to get the inode
+ * number from the proc filesystem, this is the value we will
+ * cache.
+ */
+ net_ns = NS_INO_UNAVAILABLE;
+
+ /*
+ * /proc/thread-self was introduced in kernel v3.17
+ */
+ if (stat("/proc/thread-self/ns/net", &sb) == 0) {
+ 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",
+ lttng_gettid()) >= 0) {
+
+ if (stat(proc_ns_path, &sb) == 0) {
+ net_ns = sb.st_ino;
+ }
+ }
+ }
+
+ /*
+ * And finally, store the inode number in the cache.
+ */
+ CMM_STORE_SHARED(URCU_TLS(cached_net_ns), net_ns);
+
+ return 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)
+{
+ CMM_STORE_SHARED(URCU_TLS(cached_net_ns), NS_INO_UNINITIALIZED);
+}
+
+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(ino_t));
+ size += sizeof(ino_t);
+ return size;
+}
+
+static
+void net_ns_record(struct lttng_ctx_field *field,
+ struct lttng_ust_lib_ring_buffer_ctx *ctx,
+ struct lttng_channel *chan)
+{
+ ino_t 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)
+{
+ value->u.s64 = get_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(ino_t) * CHAR_BIT;
+ field->event_field.type.u.basic.integer.alignment = lttng_alignof(ino_t) * CHAR_BIT;
+ field->event_field.type.u.basic.integer.signedness = lttng_is_signed_type(ino_t);
+ 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)));
+}
--- /dev/null
+/*
+ * lttng-context-pid-ns.c
+ *
+ * LTTng UST pid namespace context.
+ *
+ * Copyright (C) 2009-2012 Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
+ * 2019 Michael Jeanson <mjeanson@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 "ns.h"
+
+/*
+ * We cache the result to ensure we don't stat(2) the proc filesystem on
+ * each event. The PID namespace is global to the process.
+ */
+static ino_t cached_pid_ns = NS_INO_UNINITIALIZED;
+
+static
+ino_t get_pid_ns(void)
+{
+ struct stat sb;
+ ino_t pid_ns;
+
+ pid_ns = CMM_LOAD_SHARED(cached_pid_ns);
+
+ /*
+ * If the cache is populated, do nothing and return the
+ * cached inode number.
+ */
+ if (caa_likely(pid_ns != NS_INO_UNINITIALIZED))
+ return pid_ns;
+
+ /*
+ * At this point we have to populate the cache, set the initial
+ * value to NS_INO_UNAVAILABLE (0), if we fail to get the inode
+ * number from the proc filesystem, this is the value we will
+ * cache.
+ */
+ pid_ns = NS_INO_UNAVAILABLE;
+
+ if (stat("/proc/self/ns/pid", &sb) == 0) {
+ pid_ns = sb.st_ino;
+ }
+
+ /*
+ * And finally, store the inode number in the cache.
+ */
+ CMM_STORE_SHARED(cached_pid_ns, pid_ns);
+
+ return 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)
+{
+ CMM_STORE_SHARED(cached_pid_ns, NS_INO_UNINITIALIZED);
+}
+
+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(ino_t));
+ size += sizeof(ino_t);
+ return size;
+}
+
+static
+void pid_ns_record(struct lttng_ctx_field *field,
+ struct lttng_ust_lib_ring_buffer_ctx *ctx,
+ struct lttng_channel *chan)
+{
+ ino_t 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)
+{
+ value->u.s64 = get_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(ino_t) * CHAR_BIT;
+ field->event_field.type.u.basic.integer.alignment = lttng_alignof(ino_t) * CHAR_BIT;
+ field->event_field.type.u.basic.integer.signedness = lttng_is_signed_type(ino_t);
+ 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;
+}
--- /dev/null
+/*
+ * lttng-context-user-ns.c
+ *
+ * LTTng UST user namespace context.
+ *
+ * Copyright (C) 2009-2012 Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
+ * 2019 Michael Jeanson <mjeanson@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 "ns.h"
+
+/*
+ * We cache the result to ensure we don't stat(2) the proc filesystem on
+ * each event. The user namespace is global to the process.
+ */
+static ino_t cached_user_ns = NS_INO_UNINITIALIZED;
+
+static
+ino_t get_user_ns(void)
+{
+ struct stat sb;
+ ino_t user_ns;
+
+ user_ns = CMM_LOAD_SHARED(cached_user_ns);
+
+ /*
+ * If the cache is populated, do nothing and return the
+ * cached inode number.
+ */
+ if (caa_likely(user_ns != NS_INO_UNINITIALIZED))
+ return user_ns;
+
+ /*
+ * At this point we have to populate the cache, set the initial
+ * value to NS_INO_UNAVAILABLE (0), if we fail to get the inode
+ * number from the proc filesystem, this is the value we will
+ * cache.
+ */
+ user_ns = NS_INO_UNAVAILABLE;
+
+ if (stat("/proc/self/ns/user", &sb) == 0) {
+ user_ns = sb.st_ino;
+ }
+
+ /*
+ * And finally, store the inode number in the cache.
+ */
+ CMM_STORE_SHARED(cached_user_ns, user_ns);
+
+ return 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)
+{
+ CMM_STORE_SHARED(cached_user_ns, NS_INO_UNINITIALIZED);
+}
+
+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(ino_t));
+ size += sizeof(ino_t);
+ return size;
+}
+
+static
+void user_ns_record(struct lttng_ctx_field *field,
+ struct lttng_ust_lib_ring_buffer_ctx *ctx,
+ struct lttng_channel *chan)
+{
+ ino_t 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)
+{
+ value->u.s64 = get_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(ino_t) * CHAR_BIT;
+ field->event_field.type.u.basic.integer.alignment = lttng_alignof(ino_t) * CHAR_BIT;
+ field->event_field.type.u.basic.integer.signedness = lttng_is_signed_type(ino_t);
+ 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;
+}
--- /dev/null
+/*
+ * lttng-context-uts-ns.c
+ *
+ * LTTng UST uts namespace context.
+ *
+ * Copyright (C) 2009-2012 Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
+ * 2019 Michael Jeanson <mjeanson@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"
+#include "ns.h"
+
+
+/*
+ * We cache the result to ensure we don't stat(2) the proc filesystem on
+ * each event.
+ */
+static DEFINE_URCU_TLS(ino_t, cached_uts_ns) = NS_INO_UNINITIALIZED;
+
+static
+ino_t get_uts_ns(void)
+{
+ struct stat sb;
+ ino_t uts_ns;
+
+ uts_ns = CMM_LOAD_SHARED(URCU_TLS(cached_uts_ns));
+
+ /*
+ * If the cache is populated, do nothing and return the
+ * cached inode number.
+ */
+ if (caa_likely(uts_ns != NS_INO_UNINITIALIZED))
+ return uts_ns;
+
+ /*
+ * At this point we have to populate the cache, set the initial
+ * value to NS_INO_UNAVAILABLE (0), if we fail to get the inode
+ * number from the proc filesystem, this is the value we will
+ * cache.
+ */
+ uts_ns = NS_INO_UNAVAILABLE;
+
+ /*
+ * /proc/thread-self was introduced in kernel v3.17
+ */
+ if (stat("/proc/thread-self/ns/uts", &sb) == 0) {
+ 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",
+ lttng_gettid()) >= 0) {
+
+ if (stat(proc_ns_path, &sb) == 0) {
+ uts_ns = sb.st_ino;
+ }
+ }
+ }
+
+ /*
+ * And finally, store the inode number in the cache.
+ */
+ CMM_STORE_SHARED(URCU_TLS(cached_uts_ns), uts_ns);
+
+ return 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)
+{
+ CMM_STORE_SHARED(URCU_TLS(cached_uts_ns), NS_INO_UNINITIALIZED);
+}
+
+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(ino_t));
+ size += sizeof(ino_t);
+ return size;
+}
+
+static
+void uts_ns_record(struct lttng_ctx_field *field,
+ struct lttng_ust_lib_ring_buffer_ctx *ctx,
+ struct lttng_channel *chan)
+{
+ ino_t 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)
+{
+ value->u.s64 = get_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(ino_t) * CHAR_BIT;
+ field->event_field.type.u.basic.integer.alignment = lttng_alignof(ino_t) * CHAR_BIT;
+ field->event_field.type.u.basic.integer.signedness = lttng_is_signed_type(ino_t);
+ 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)));
+}
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;
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;
}
#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;
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_net_ns_tls(void);
+void lttng_fixup_uts_ns_tls(void);
const char *lttng_ust_obj_get_name(int id);
lttng_fixup_ust_mutex_nest_tls();
lttng_ust_fixup_perf_counter_tls();
lttng_ust_fixup_fd_tracker_tls();
+ lttng_fixup_cgroup_ns_tls();
+ lttng_fixup_ipc_ns_tls();
+ lttng_fixup_net_ns_tls();
+ lttng_fixup_uts_ns_tls();
}
int lttng_get_notify_socket(void *owner)
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
lttng_context_vpid_reset();
lttng_context_vtid_reset();
lttng_context_procname_reset();
+ ust_context_ns_reset();
DBG("process %d", getpid());
/* Release urcu mutexes */
urcu_bp_after_fork_child();
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;
--- /dev/null
+#ifndef _LTTNG_NS_H
+#define _LTTNG_NS_H
+
+/*
+ * Copyright (c) 2019 - Michael Jeanson <mjeanson@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
+ */
+
+
+/*
+ * The lowest valid inode number that can be allocated in the proc filesystem
+ * is 0xF0000000. Any number below can be used internally as an error code.
+ *
+ * Zero is used in the kernel as an error code, it's the value we will return
+ * when we fail to read the proper inode number.
+ *
+ * One is used internally to identify an uninitialized cache entry, it should
+ * never be returned.
+ */
+
+enum ns_ino_state {
+ NS_INO_UNAVAILABLE = 0x0,
+ NS_INO_UNINITIALIZED = 0x1,
+ NS_INO_MIN = 0xF0000000,
+};
+
+#endif /* _LTTNG_NS_H */