Add time namespace context
authorMichael Jeanson <mjeanson@efficios.com>
Wed, 12 Feb 2020 21:23:41 +0000 (16:23 -0500)
committerMathieu Desnoyers <mathieu.desnoyers@efficios.com>
Mon, 6 Jul 2020 21:27:07 +0000 (17:27 -0400)
Add a context for the new time namespace introduced in v5.6.

Change-Id: Ic3393f65702b80c87670bb21049ee2a19413111d
Signed-off-by: Michael Jeanson <mjeanson@efficios.com>
Signed-off-by: Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
include/instrumentation/events/lttng-statedump.h
include/lttng/abi.h
include/lttng/events.h
src/Kbuild
src/lttng-abi.c
src/lttng-context-time-ns.c [new file with mode: 0644]
src/lttng-context.c
src/lttng-statedump-impl.c

index 23fdd0e8094dbe3843ffeb3f5e9c46d796bc9270..451314c9724560f46dcbd0ced776e25bfbcdb5f5 100644 (file)
@@ -17,6 +17,9 @@
 #include <linux/version.h>
 #include <wrapper/namespace.h>
 #include <wrapper/user_namespace.h>
+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(5,6,0))
+#include <linux/time_namespace.h>
+#endif
 
 #ifndef LTTNG_MNT_NS_MISSING_HEADER
 # ifndef ONCE_LTTNG_FS_MOUNT_H
@@ -179,6 +182,19 @@ LTTNG_TRACEPOINT_EVENT(lttng_statedump_process_uts_ns,
        )
 )
 
+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(5,6,0))
+LTTNG_TRACEPOINT_EVENT(lttng_statedump_process_time_ns,
+       TP_PROTO(struct lttng_session *session,
+               struct task_struct *p,
+               struct time_namespace *time_ns),
+       TP_ARGS(session, p, time_ns),
+       TP_FIELDS(
+               ctf_integer(pid_t, tid, p->pid)
+               ctf_integer(unsigned int, ns_inum, time_ns ? time_ns->lttng_ns_inum : 0)
+       )
+)
+#endif
+
 LTTNG_TRACEPOINT_EVENT(lttng_statedump_file_descriptor,
        TP_PROTO(struct lttng_session *session,
                struct files_struct *files,
index b8e2db398a53f2b0b7ce35b8b8acb8a5e21f37a4..7456f4a12550b1ef3f31d6c9a31265b1b5ff660e 100644 (file)
@@ -180,6 +180,7 @@ enum lttng_kernel_context_type {
        LTTNG_KERNEL_CONTEXT_VGID               = 34,
        LTTNG_KERNEL_CONTEXT_VEGID              = 35,
        LTTNG_KERNEL_CONTEXT_VSGID              = 36,
+       LTTNG_KERNEL_CONTEXT_TIME_NS            = 37,
 };
 
 struct lttng_kernel_perf_counter_ctx {
index 80358e920d3d7a83f646c1da63d01c5364177d59..605a48a5d3bdd16c7023678797ddefa0ae48b77f 100644 (file)
@@ -805,6 +805,17 @@ int lttng_add_uts_ns_to_ctx(struct lttng_ctx **ctx)
 }
 #endif
 
+#if defined(CONFIG_TIME_NS) && \
+       (LINUX_VERSION_CODE >= KERNEL_VERSION(5,6,0))
+int lttng_add_time_ns_to_ctx(struct lttng_ctx **ctx);
+#else
+static inline
+int lttng_add_time_ns_to_ctx(struct lttng_ctx **ctx)
+{
+       return -ENOSYS;
+}
+#endif
+
 int lttng_add_uid_to_ctx(struct lttng_ctx **ctx);
 int lttng_add_euid_to_ctx(struct lttng_ctx **ctx);
 int lttng_add_suid_to_ctx(struct lttng_ctx **ctx);
index fad44601c6e2397457d9080a22edef6f69c35465..a48e1cb13196dccc877c34b68f536c17ecd8d551 100644 (file)
@@ -105,6 +105,10 @@ ifneq ($(CONFIG_UTS_NS),)
   lttng-tracer-objs += lttng-context-uts-ns.o
 endif
 
+ifneq ($(CONFIG_TIME_NS),)
+  lttng-tracer-objs += lttng-context-time-ns.o
+endif
+
 obj-$(CONFIG_LTTNG) += lttng-statedump.o
 lttng-statedump-objs := lttng-statedump-impl.o
 
index c3721b93e428ce7d48bf94f40ff9ebd0a6585ef4..312372fcb9bbc5d83bcc59011ad5834e6131d626 100644 (file)
@@ -281,6 +281,8 @@ long lttng_abi_add_context(struct file *file,
                return lttng_add_vegid_to_ctx(ctx);
        case LTTNG_KERNEL_CONTEXT_VSGID:
                return lttng_add_vsgid_to_ctx(ctx);
+       case LTTNG_KERNEL_CONTEXT_TIME_NS:
+               return lttng_add_time_ns_to_ctx(ctx);
        default:
                return -EINVAL;
        }
diff --git a/src/lttng-context-time-ns.c b/src/lttng-context-time-ns.c
new file mode 100644 (file)
index 0000000..d3133ac
--- /dev/null
@@ -0,0 +1,104 @@
+/* SPDX-License-Identifier: (GPL-2.0-only or LGPL-2.1-only)
+ *
+ * lttng-context-time-ns.c
+ *
+ * LTTng time namespace context.
+ *
+ * Copyright (C) 2009-2012 Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
+ *               2020 Michael Jeanson <mjeanson@efficios.com>
+ *
+ */
+
+#include <linux/module.h>
+#include <linux/slab.h>
+#include <linux/sched.h>
+#include <linux/nsproxy.h>
+#include <linux/time_namespace.h>
+#include <lttng/events.h>
+#include <ringbuffer/frontend_types.h>
+#include <wrapper/vmalloc.h>
+#include <wrapper/namespace.h>
+#include <lttng/tracer.h>
+
+#if defined(CONFIG_TIME_NS)
+
+static
+size_t time_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 time_ns_record(struct lttng_ctx_field *field,
+                struct lib_ring_buffer_ctx *ctx,
+                struct lttng_channel *chan)
+{
+       unsigned int time_ns_inum = 0;
+
+       /*
+        * nsproxy can be NULL when scheduled out of exit.
+        *
+        * As documented in 'linux/nsproxy.h' namespaces access rules, no
+        * precautions should be taken when accessing the current task's
+        * namespaces, just dereference the pointers.
+        */
+       if (current->nsproxy)
+               time_ns_inum = current->nsproxy->time_ns->lttng_ns_inum;
+
+       lib_ring_buffer_align_ctx(ctx, lttng_alignof(time_ns_inum));
+       chan->ops->event_write(ctx, &time_ns_inum, sizeof(time_ns_inum));
+}
+
+static
+void time_ns_get_value(struct lttng_ctx_field *field,
+               struct lttng_probe_ctx *lttng_probe_ctx,
+               union lttng_ctx_value *value)
+{
+       unsigned int time_ns_inum = 0;
+
+       /*
+        * nsproxy can be NULL when scheduled out of exit.
+        *
+        * As documented in 'linux/nsproxy.h' namespaces access rules, no
+        * precautions should be taken when accessing the current task's
+        * namespaces, just dereference the pointers.
+        */
+       if (current->nsproxy)
+               time_ns_inum = current->nsproxy->time_ns->lttng_ns_inum;
+
+       value->s64 = time_ns_inum;
+}
+
+int lttng_add_time_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, "time_ns")) {
+               lttng_remove_context_field(ctx, field);
+               return -EEXIST;
+       }
+       field->event_field.name = "time_ns";
+       field->event_field.type.atype = atype_integer;
+       field->event_field.type.u.integer.size = sizeof(unsigned int) * CHAR_BIT;
+       field->event_field.type.u.integer.alignment = lttng_alignof(unsigned int) * CHAR_BIT;
+       field->event_field.type.u.integer.signedness = lttng_is_signed_type(unsigned int);
+       field->event_field.type.u.integer.reverse_byte_order = 0;
+       field->event_field.type.u.integer.base = 10;
+       field->event_field.type.u.integer.encoding = lttng_encode_none;
+       field->get_size = time_ns_get_size;
+       field->record = time_ns_record;
+       field->get_value = time_ns_get_value;
+       lttng_context_update(*ctx);
+       wrapper_vmalloc_sync_mappings();
+       return 0;
+}
+EXPORT_SYMBOL_GPL(lttng_add_time_ns_to_ctx);
+
+#endif
index 9d6b71e0fdd7304491a0c541e2b3abaa420a99aa..4b948ef8001277b53346d651ee08efc0497f8ef8 100644 (file)
@@ -342,6 +342,10 @@ int lttng_context_init(void)
        if (ret && ret != -ENOSYS) {
                printk(KERN_WARNING "Cannot add context lttng_add_uts_ns_to_ctx");
        }
+       ret = lttng_add_time_ns_to_ctx(&lttng_static_ctx);
+       if (ret && ret != -ENOSYS) {
+               printk(KERN_WARNING "Cannot add context lttng_add_time_ns_to_ctx");
+       }
        /* TODO: perf counters for filtering */
        return 0;
 }
index 4105374e640d19e848bf2bc424e8ad4dc2f04261..153ddf8e9de83719b8471b97174ff72646e6f85c 100644 (file)
@@ -72,6 +72,7 @@ DEFINE_TRACE(lttng_statedump_process_mnt_ns);
 DEFINE_TRACE(lttng_statedump_process_net_ns);
 DEFINE_TRACE(lttng_statedump_process_user_ns);
 DEFINE_TRACE(lttng_statedump_process_uts_ns);
+DEFINE_TRACE(lttng_statedump_process_time_ns);
 DEFINE_TRACE(lttng_statedump_network_interface);
 #ifdef LTTNG_HAVE_STATEDUMP_CPU_TOPOLOGY
 DEFINE_TRACE(lttng_statedump_cpu_topology);
@@ -453,6 +454,9 @@ void lttng_statedump_process_ns(struct lttng_session *session,
 #endif
                trace_lttng_statedump_process_net_ns(session, p, proxy->net_ns);
                trace_lttng_statedump_process_uts_ns(session, p, proxy->uts_ns);
+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(5,6,0))
+               trace_lttng_statedump_process_time_ns(session, p, proxy->time_ns);
+#endif
        }
 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,17,0) || \
                LTTNG_UBUNTU_KERNEL_RANGE(3,13,11,36, 3,14,0,0) || \
This page took 0.034478 seconds and 4 git commands to generate.