X-Git-Url: http://git.liburcu.org/?p=lttng-modules.git;a=blobdiff_plain;f=lttng-statedump-impl.c;h=f3ae1937b1faa5da94683d891311bc1013eb1bb8;hp=dddd34ddf054cd25a12de60d95a7b3c26f45f62b;hb=edfdcb685c3f56dde803244449f79ad7bed03798;hpb=84c7055e17f9bf7628fe1004db732d932ed2a77b diff --git a/lttng-statedump-impl.c b/lttng-statedump-impl.c index dddd34dd..f3ae1937 100644 --- a/lttng-statedump-impl.c +++ b/lttng-statedump-impl.c @@ -1,4 +1,5 @@ -/* +/* SPDX-License-Identifier: (GPL-2.0 or LGPL-2.1) + * * lttng-statedump.c * * Linux Trace Toolkit Next Generation Kernel State Dump @@ -6,20 +7,6 @@ * Copyright 2005 Jean-Hugues Deschenes * Copyright 2006-2012 Mathieu Desnoyers * - * 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 - * * Changes: * Eric Clement: Add listing of network IP interface * 2006, 2007 Mathieu Desnoyers Fix kernel threads @@ -41,23 +28,21 @@ #include #include #include -#include #include #include #include #include -#include "lttng-events.h" -#include "lttng-tracer.h" -#include "wrapper/irqdesc.h" -#include "wrapper/spinlock.h" -#include "wrapper/fdtable.h" -#include "wrapper/nsproxy.h" -#include "wrapper/irq.h" -#include "wrapper/tracepoint.h" -#include "wrapper/genhd.h" -#include "wrapper/file.h" -#include "wrapper/time.h" +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include #ifdef CONFIG_LTTNG_HAS_LIST_IRQ #include @@ -65,10 +50,10 @@ /* Define the tracepoints, but do not build the probes */ #define CREATE_TRACE_POINTS -#define TRACE_INCLUDE_PATH ../instrumentation/events/lttng-module +#define TRACE_INCLUDE_PATH instrumentation/events/lttng-module #define TRACE_INCLUDE_FILE lttng-statedump #define LTTNG_INSTRUMENTATION -#include "instrumentation/events/lttng-module/lttng-statedump.h" +#include DEFINE_TRACE(lttng_statedump_block_device); DEFINE_TRACE(lttng_statedump_end); @@ -76,7 +61,21 @@ DEFINE_TRACE(lttng_statedump_interrupt); DEFINE_TRACE(lttng_statedump_file_descriptor); DEFINE_TRACE(lttng_statedump_start); DEFINE_TRACE(lttng_statedump_process_state); +DEFINE_TRACE(lttng_statedump_process_pid_ns); +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(4,6,0)) +DEFINE_TRACE(lttng_statedump_process_cgroup_ns); +#endif +DEFINE_TRACE(lttng_statedump_process_ipc_ns); +#ifndef LTTNG_MNT_NS_MISSING_HEADER +DEFINE_TRACE(lttng_statedump_process_mnt_ns); +#endif +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_network_interface); +#ifdef LTTNG_HAVE_STATEDUMP_CPU_TOPOLOGY +DEFINE_TRACE(lttng_statedump_cpu_topology); +#endif struct lttng_fd_ctx { char *page; @@ -293,6 +292,28 @@ int lttng_enumerate_file_descriptors(struct lttng_session *session) return 0; } +#ifdef LTTNG_HAVE_STATEDUMP_CPU_TOPOLOGY +static +int lttng_enumerate_cpu_topology(struct lttng_session *session) +{ + int cpu; + const cpumask_t *cpumask = cpu_possible_mask; + + for (cpu = cpumask_first(cpumask); cpu < nr_cpu_ids; + cpu = cpumask_next(cpu, cpumask)) { + trace_lttng_statedump_cpu_topology(session, &cpu_data(cpu)); + } + + return 0; +} +#else +static +int lttng_enumerate_cpu_topology(struct lttng_session *session) +{ + return 0; +} +#endif + #if 0 /* * FIXME: we cannot take a mmap_sem while in a RCU read-side critical section @@ -343,10 +364,6 @@ int lttng_enumerate_vm_maps(struct lttng_session *session) #ifdef CONFIG_LTTNG_HAS_LIST_IRQ -#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,39)) -#define irq_desc_get_chip(desc) get_irq_desc_chip(desc) -#endif - static int lttng_list_interrupts(struct lttng_session *session) { @@ -362,12 +379,12 @@ int lttng_list_interrupts(struct lttng_session *session) irq_desc_get_chip(desc)->name ? : "unnamed_irq_chip"; local_irq_save(flags); - wrapper_desc_spin_lock(&desc->lock); + raw_spin_lock(&desc->lock); for (action = desc->action; action; action = action->next) { trace_lttng_statedump_interrupt(session, irq, irq_chip_name, action); } - wrapper_desc_spin_unlock(&desc->lock); + raw_spin_unlock(&desc->lock); local_irq_restore(flags); } return 0; @@ -382,6 +399,10 @@ int lttng_list_interrupts(struct lttng_session *session) #endif /* + * Statedump the task's namespaces using the proc filesystem inode number as + * the unique identifier. The user and pid ns are nested and will be dumped + * recursively. + * * Called with task lock held. */ static @@ -394,6 +415,34 @@ void lttng_statedump_process_ns(struct lttng_session *session, { struct nsproxy *proxy; struct pid_namespace *pid_ns; + struct user_namespace *user_ns; + + /* + * The pid and user namespaces are special, they are nested and + * accessed with specific functions instead of the nsproxy struct + * like the other namespaces. + */ + pid_ns = task_active_pid_ns(p); + do { + trace_lttng_statedump_process_pid_ns(session, p, pid_ns); + pid_ns = pid_ns ? pid_ns->parent : NULL; + } while (pid_ns); + + + user_ns = task_cred_xxx(p, user_ns); + do { + trace_lttng_statedump_process_user_ns(session, p, user_ns); + /* + * trace_lttng_statedump_process_user_ns() internally + * checks whether user_ns is NULL. While this does not + * appear to be a possible return value for + * task_cred_xxx(), err on the safe side and check + * for NULL here as well to be consistent with the + * paranoid behavior of + * trace_lttng_statedump_process_user_ns(). + */ + user_ns = user_ns ? user_ns->lttng_user_ns_parent : NULL; + } while (user_ns); /* * Back and forth on locking strategy within Linux upstream for nsproxy. @@ -403,26 +452,28 @@ void lttng_statedump_process_ns(struct lttng_session *session, */ #if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,17,0) || \ LTTNG_UBUNTU_KERNEL_RANGE(3,13,11,36, 3,14,0,0) || \ - LTTNG_UBUNTU_KERNEL_RANGE(3,16,0,11, 3,17,0,0)) + LTTNG_UBUNTU_KERNEL_RANGE(3,16,1,11, 3,17,0,0) || \ + LTTNG_RHEL_KERNEL_RANGE(3,10,0,229,13,0, 3,11,0,0,0,0)) proxy = p->nsproxy; #else rcu_read_lock(); proxy = task_nsproxy(p); #endif if (proxy) { - pid_ns = lttng_get_proxy_pid_ns(proxy); - do { - trace_lttng_statedump_process_state(session, - p, type, mode, submode, status, pid_ns); - pid_ns = pid_ns->parent; - } while (pid_ns); - } else { - trace_lttng_statedump_process_state(session, - p, type, mode, submode, status, NULL); +#if (LINUX_VERSION_CODE >= KERNEL_VERSION(4,6,0)) + trace_lttng_statedump_process_cgroup_ns(session, p, proxy->cgroup_ns); +#endif + trace_lttng_statedump_process_ipc_ns(session, p, proxy->ipc_ns); +#ifndef LTTNG_MNT_NS_MISSING_HEADER + trace_lttng_statedump_process_mnt_ns(session, p, proxy->mnt_ns); +#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(3,17,0) || \ LTTNG_UBUNTU_KERNEL_RANGE(3,13,11,36, 3,14,0,0) || \ - LTTNG_UBUNTU_KERNEL_RANGE(3,16,0,11, 3,17,0,0)) + LTTNG_UBUNTU_KERNEL_RANGE(3,16,1,11, 3,17,0,0) || \ + LTTNG_RHEL_KERNEL_RANGE(3,10,0,229,13,0, 3,11,0,0,0,0)) /* (nothing) */ #else rcu_read_unlock(); @@ -478,6 +529,9 @@ int lttng_enumerate_process_states(struct lttng_session *session) type = LTTNG_USER_THREAD; else type = LTTNG_KERNEL_THREAD; + + trace_lttng_statedump_process_state(session, + p, type, mode, submode, status); lttng_statedump_process_ns(session, p, type, mode, submode, status); task_unlock(p); @@ -530,6 +584,9 @@ int do_lttng_statedump(struct lttng_session *session) default: return ret; } + ret = lttng_enumerate_cpu_topology(session); + if (ret) + return ret; /* TODO lttng_dump_idt_table(session); */ /* TODO lttng_dump_softirq_vec(session); */ @@ -588,7 +645,7 @@ module_exit(lttng_statedump_exit); MODULE_LICENSE("GPL and additional rights"); MODULE_AUTHOR("Jean-Hugues Deschenes"); -MODULE_DESCRIPTION("Linux Trace Toolkit Next Generation Statedump"); +MODULE_DESCRIPTION("LTTng statedump provider"); MODULE_VERSION(__stringify(LTTNG_MODULES_MAJOR_VERSION) "." __stringify(LTTNG_MODULES_MINOR_VERSION) "." __stringify(LTTNG_MODULES_PATCHLEVEL_VERSION)