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 <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
)
)
+#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,
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 {
}
#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);
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
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;
}
--- /dev/null
+/* 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
if (ret && ret != -ENOSYS) {
printk(KERN_WARNING "Cannot add context lttng_add_uts_ns_to_ctx");
}
+ ret = lttng_add_time_ns_to_ctx(<tng_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;
}
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);
#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) || \