summaryrefslogtreecommitdiff
path: root/src/shared/udev-util.h
diff options
context:
space:
mode:
authorMichal Sekletár <msekleta@redhat.com>2020-08-24 11:21:44 +0200
committerZbigniew Jędrzejewski-Szmek <zbyszek@in.waw.pl>2021-06-15 18:28:28 +0200
commitb428efa54bc9f8851514c595f14020a99fcf62a7 (patch)
treea35d19685554bf3e3bc100afe896d17226dc47ce /src/shared/udev-util.h
parentb2e8fdc89604fc68f14c13c70191659140b85d92 (diff)
downloadsystemd-b428efa54bc9f8851514c595f14020a99fcf62a7.tar.gz
udev: add basic set of user-space defined tracepoints (USDT)
Debugging udev issues especially during the early boot is fairly difficult. Currently, you need to enable (at least) debug logging and start monitoring uevents, try to reproduce the issue and then analyze and correlate two (usually) huge log files. This is not ideal. This patch aims to provide much more focused debugging tool, tracepoints. More often then not we tend to have at least the basic idea about the issue we are trying to debug further, e.g. we know it is storage related. Hence all of the debug data generated for network devices is useless, adds clutter to the log files and generally slows things down. Using this set of tracepoints you can start asking very specific questions related to event processing for given device or subsystem. Tracepoints can be used with various tracing tools but I will provide examples using bpftrace. Another important aspect to consider is that using tracepoints you can debug production systems. There is no need to install test packages with added logging, no debuginfo packages, etc... Example usage (you might be asking such questions during the debug session), Q: How can I list all tracepoints? A: bpftrace -l 'usdt:/usr/lib/systemd/systemd-udevd:udev:*' Q: What are the arguments for each tracepoint? A: Look at the code and search for use of DEVICE_TRACE_POINT macro. Q: How many times we have executed external binary? A: bpftrace -e 'usdt:/usr/lib/systemd/systemd-udevd:udev:spawn_exec { @cnt = count(); }' Q: What binaries where executed while handling events for "dm-0" device? A bpftrace -e 'usdt:/usr/lib/systemd/systemd-udevd:udev:spawn_exec / str(arg1) == "dm-0"/ { @cmds[str(arg4)] = count(); }' Thanks to Thomas Weißschuh <thomas@t-8ch.de> for reviewing this patch and contributions that allowed us to drop the dependency on dtrace tool and made the resulting code much more concise.
Diffstat (limited to 'src/shared/udev-util.h')
-rw-r--r--src/shared/udev-util.h32
1 files changed, 32 insertions, 0 deletions
diff --git a/src/shared/udev-util.h b/src/shared/udev-util.h
index c2cf7caa67..d1c33b86a7 100644
--- a/src/shared/udev-util.h
+++ b/src/shared/udev-util.h
@@ -1,6 +1,11 @@
/* SPDX-License-Identifier: LGPL-2.1-or-later */
#pragma once
+#if HAVE_SYS_SDT_H
+#define SDT_USE_VARIADIC
+#include <sys/sdt.h>
+#endif
+
#include "sd-device.h"
#include "time-util.h"
@@ -46,3 +51,30 @@ int udev_resolve_subsys_kernel(const char *string, char *result, size_t maxsize,
int udev_queue_is_empty(void);
int udev_queue_init(void);
+
+#if HAVE_SYS_SDT_H
+
+/* Each trace point can have different number of additional arguments. Note that when the macro is used only
+ * additional arguments are listed in the macro invocation!
+ *
+ * Default arguments for each trace point are as follows:
+ * - arg0 - action
+ * - arg1 - sysname
+ * - arg2 - syspath
+ * - arg3 - subsystem
+ */
+#define DEVICE_TRACE_POINT(name, dev, ...) \
+ do { \
+ PROTECT_ERRNO; \
+ const char *_n = NULL, *_p = NULL, *_s = NULL; \
+ sd_device *_d = (dev); \
+ sd_device_action_t _a = _SD_DEVICE_ACTION_INVALID; \
+ (void) sd_device_get_action(_d, &_a); \
+ (void) sd_device_get_sysname(_d, &_n); \
+ (void) sd_device_get_syspath(_d, &_p); \
+ (void) sd_device_get_subsystem(_d, &_s); \
+ STAP_PROBEV(udev, name, device_action_to_string(_a), _n, _p, _s __VA_OPT__(,) __VA_ARGS__);\
+ } while(false);
+#else
+#define DEVICE_TRACE_POINT(name, dev, ...) ((void) 0)
+#endif