summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorLennart Poettering <lennart@poettering.net>2023-03-27 18:16:03 +0200
committerLennart Poettering <lennart@poettering.net>2023-03-29 19:09:10 +0200
commit5f43c97cd24b25f846d005eccd7837a2cd279230 (patch)
treee5e87e70e647b676fc81bb4d434a3e24071108d7 /src
parent2ea24611b99d12955ba374f072148b9ad6d644dc (diff)
downloadsystemd-5f43c97cd24b25f846d005eccd7837a2cd279230.tar.gz
analyze: add new fdstore verb
Diffstat (limited to 'src')
-rw-r--r--src/analyze/analyze-fdstore.c110
-rw-r--r--src/analyze/analyze-fdstore.h5
-rw-r--r--src/analyze/analyze.c9
-rw-r--r--src/analyze/meson.build1
4 files changed, 122 insertions, 3 deletions
diff --git a/src/analyze/analyze-fdstore.c b/src/analyze/analyze-fdstore.c
new file mode 100644
index 0000000000..13db7f5088
--- /dev/null
+++ b/src/analyze/analyze-fdstore.c
@@ -0,0 +1,110 @@
+/* SPDX-License-Identifier: LGPL-2.1-or-later */
+
+#include "analyze-fdstore.h"
+#include "analyze.h"
+#include "bus-error.h"
+#include "bus-locator.h"
+#include "fd-util.h"
+#include "format-table.h"
+
+static int dump_fdstore(sd_bus *bus, const char *arg) {
+ _cleanup_(sd_bus_error_free) sd_bus_error error = SD_BUS_ERROR_NULL;
+ _cleanup_(sd_bus_message_unrefp) sd_bus_message *reply = NULL;
+ _cleanup_(table_unrefp) Table *table = NULL;
+ _cleanup_free_ char *unit = NULL;
+ int r;
+
+ assert(bus);
+ assert(arg);
+
+ r = unit_name_mangle_with_suffix(arg, NULL, UNIT_NAME_MANGLE_GLOB, ".service", &unit);
+ if (r < 0)
+ return log_error_errno(r, "Failed to mangle name '%s': %m", arg);
+
+ r = bus_call_method(
+ bus,
+ bus_systemd_mgr,
+ "DumpUnitFileDescriptorStore",
+ &error,
+ &reply,
+ "s", unit);
+ if (r < 0)
+ return log_error_errno(r, "Failed to call DumpUnitFileDescriptorStore: %s",
+ bus_error_message(&error, r));
+
+ r = sd_bus_message_enter_container(reply, 'a', "(suuutuusu)");
+ if (r < 0)
+ return bus_log_parse_error(r);
+
+ table = table_new("fdname", "type", "devno", "inode", "rdevno", "path", "flags");
+ if (!table)
+ return log_oom();
+
+ table_set_ersatz_string(table, TABLE_ERSATZ_DASH);
+
+ (void) table_set_align_percent(table, TABLE_HEADER_CELL(3), 100);
+
+ for (;;) {
+ uint32_t mode, major, minor, rmajor, rminor, flags;
+ const char *fdname, *path;
+ uint64_t inode;
+
+ r = sd_bus_message_read(
+ reply,
+ "(suuutuusu)",
+ &fdname,
+ &mode,
+ &major, &minor,
+ &inode,
+ &rmajor, &rminor,
+ &path,
+ &flags);
+ if (r < 0)
+ return bus_log_parse_error(r);
+ if (r == 0)
+ break;
+
+ r = table_add_many(
+ table,
+ TABLE_STRING, fdname,
+ TABLE_MODE_INODE_TYPE, mode,
+ TABLE_DEVNUM, makedev(major, minor),
+ TABLE_UINT64, inode,
+ TABLE_DEVNUM, makedev(rmajor, rminor),
+ TABLE_PATH, path,
+ TABLE_STRING, accmode_to_string(flags));
+ if (r < 0)
+ return table_log_add_error(r);
+ }
+
+ r = sd_bus_message_exit_container(reply);
+ if (r < 0)
+ return r;
+
+ if (FLAGS_SET(arg_json_format_flags, JSON_FORMAT_OFF) && table_get_rows(table) <= 0)
+ log_info("No file descriptors in fdstore of '%s'.", unit);
+ else {
+ r = table_print_with_pager(table, arg_json_format_flags, arg_pager_flags, /* show_header= */true);
+ if (r < 0)
+ return log_error_errno(r, "Failed to output table: %m");
+ }
+
+ return EXIT_SUCCESS;
+}
+
+int verb_fdstore(int argc, char *argv[], void *userdata) {
+ _cleanup_(sd_bus_flush_close_unrefp) sd_bus *bus = NULL;
+ int r;
+
+ r = acquire_bus(&bus, NULL);
+ if (r < 0)
+ return bus_log_connect_error(r, arg_transport);
+
+ STRV_FOREACH(arg, strv_skip(argv, 1)) {
+ r = dump_fdstore(bus, *arg);
+ if (r < 0)
+ return r;
+ }
+
+ return EXIT_SUCCESS;
+}
diff --git a/src/analyze/analyze-fdstore.h b/src/analyze/analyze-fdstore.h
new file mode 100644
index 0000000000..0b990db395
--- /dev/null
+++ b/src/analyze/analyze-fdstore.h
@@ -0,0 +1,5 @@
+/* SPDX-License-Identifier: LGPL-2.1-or-later */
+
+#include "sd-bus.h"
+
+int verb_fdstore(int argc, char *argv[], void *userdata);
diff --git a/src/analyze/analyze.c b/src/analyze/analyze.c
index 12c0bd653f..0246da4b45 100644
--- a/src/analyze/analyze.c
+++ b/src/analyze/analyze.c
@@ -17,11 +17,13 @@
#include "analyze-calendar.h"
#include "analyze-capability.h"
#include "analyze-cat-config.h"
+#include "analyze-compare-versions.h"
#include "analyze-condition.h"
#include "analyze-critical-chain.h"
#include "analyze-dot.h"
#include "analyze-dump.h"
#include "analyze-exit-status.h"
+#include "analyze-fdstore.h"
#include "analyze-filesystems.h"
#include "analyze-inspect-elf.h"
#include "analyze-log-control.h"
@@ -36,7 +38,6 @@
#include "analyze-timestamp.h"
#include "analyze-unit-files.h"
#include "analyze-unit-paths.h"
-#include "analyze-compare-versions.h"
#include "analyze-verify.h"
#include "build.h"
#include "bus-error.h"
@@ -229,6 +230,7 @@ static int help(int argc, char *argv[], void *userdata) {
" security [UNIT...] Analyze security of unit\n"
" inspect-elf FILE... Parse and print ELF package metadata\n"
" malloc [D-BUS SERVICE...] Dump malloc stats of a D-Bus service\n"
+ " fdstore SERVICE... Show file descriptor store contents of service\n"
"\nOptions:\n"
" --recursive-errors=MODE Control which units are verified\n"
" --offline=BOOL Perform a security review on unit file(s)\n"
@@ -531,9 +533,9 @@ static int parse_argv(int argc, char *argv[]) {
return log_error_errno(SYNTHETIC_ERRNO(EINVAL),
"Option --offline= is only supported for security right now.");
- if (arg_json_format_flags != JSON_FORMAT_OFF && !STRPTR_IN_SET(argv[optind], "security", "inspect-elf", "plot"))
+ if (arg_json_format_flags != JSON_FORMAT_OFF && !STRPTR_IN_SET(argv[optind], "security", "inspect-elf", "plot", "fdstore"))
return log_error_errno(SYNTHETIC_ERRNO(EINVAL),
- "Option --json= is only supported for security, inspect-elf, and plot right now.");
+ "Option --json= is only supported for security, inspect-elf, plot, and fdstore right now.");
if (arg_threshold != 100 && !streq_ptr(argv[optind], "security"))
return log_error_errno(SYNTHETIC_ERRNO(EINVAL),
@@ -620,6 +622,7 @@ static int run(int argc, char *argv[]) {
{ "security", VERB_ANY, VERB_ANY, 0, verb_security },
{ "inspect-elf", 2, VERB_ANY, 0, verb_elf_inspection },
{ "malloc", VERB_ANY, VERB_ANY, 0, verb_malloc },
+ { "fdstore", 2, VERB_ANY, 0, verb_fdstore },
{}
};
diff --git a/src/analyze/meson.build b/src/analyze/meson.build
index ac40600a6d..695089a0be 100644
--- a/src/analyze/meson.build
+++ b/src/analyze/meson.build
@@ -11,6 +11,7 @@ systemd_analyze_sources = files(
'analyze-dot.c',
'analyze-dump.c',
'analyze-exit-status.c',
+ 'analyze-fdstore.c',
'analyze-filesystems.c',
'analyze-inspect-elf.c',
'analyze-log-control.c',