mirror of
https://github.com/systemd/systemd.git
synced 2025-03-28 02:50:16 +03:00
analyze: add new fdstore verb
This commit is contained in:
parent
2ea24611b9
commit
5f43c97cd2
@ -156,6 +156,12 @@
|
||||
<arg choice="plain">malloc</arg>
|
||||
<arg choice="opt" rep="repeat"><replaceable>D-BUS SERVICE</replaceable></arg>
|
||||
</cmdsynopsis>
|
||||
<cmdsynopsis>
|
||||
<command>systemd-analyze</command>
|
||||
<arg choice="opt" rep="repeat">OPTIONS</arg>
|
||||
<arg choice="plain">fdstore</arg>
|
||||
<arg choice="opt" rep="repeat"><replaceable>UNIT</replaceable></arg>
|
||||
</cmdsynopsis>
|
||||
</refsynopsisdiv>
|
||||
|
||||
<refsect1>
|
||||
@ -803,8 +809,37 @@ $ systemd-analyze verify /tmp/source:alias.service
|
||||
}
|
||||
</programlisting>
|
||||
</example>
|
||||
|
||||
</refsect2>
|
||||
|
||||
<refsect2>
|
||||
<title><command>systemd-analyze fdstore <optional><replaceable>UNIT</replaceable>...</optional></command></title>
|
||||
|
||||
<para>Lists the current contents of the specified service unit's file descriptor store. This shows
|
||||
names, inode types, device numbers, inode numbers, paths and open modes of the open file
|
||||
descriptors. The specified units must have <varname>FileDescriptorStoreMax=</varname> enabled, see
|
||||
<citerefentry><refentrytitle>systemd.service</refentrytitle><manvolnum>5</manvolnum></citerefentry> for
|
||||
details.</para>
|
||||
|
||||
<example>
|
||||
<title>Table output</title>
|
||||
<programlisting>$ systemd-analyze fdstore systemd-journald.service
|
||||
FDNAME TYPE DEVNO INODE RDEVNO PATH FLAGS
|
||||
stored sock 0:8 4218620 - socket:[4218620] ro
|
||||
stored sock 0:8 4213198 - socket:[4213198] ro
|
||||
stored sock 0:8 4213190 - socket:[4213190] ro
|
||||
…</programlisting>
|
||||
</example>
|
||||
|
||||
<para>Note: the "DEVNO" column refers to the major/minor numbers of the device node backing the file
|
||||
system the file descriptor's inode is on. The "RDEVNO" column refers to the major/minor numbers of the
|
||||
device node itself if the file descriptor refers to one. Compare with corresponding
|
||||
<varname>.st_dev</varname> and <varname>.st_rdev</varname> fields in <type>struct stat</type> (see
|
||||
<citerefentry
|
||||
project='man-pages'><refentrytitle>stat</refentrytitle><manvolnum>2</manvolnum></citerefentry> for
|
||||
details). The listed inode numbers in the "INODE" column are on the file system indicated by
|
||||
"DEVNO".</para>
|
||||
</refsect2>
|
||||
|
||||
</refsect1>
|
||||
|
||||
<refsect1>
|
||||
|
@ -1141,7 +1141,18 @@
|
||||
fully stopped and no job is queued or being executed for it. If this option is used,
|
||||
<varname>NotifyAccess=</varname> (see above) should be set to open access to the notification socket
|
||||
provided by systemd. If <varname>NotifyAccess=</varname> is not set, it will be implicitly set to
|
||||
<option>main</option>.</para></listitem>
|
||||
<option>main</option>.</para>
|
||||
|
||||
<para>The <command>fdstore</command> command of
|
||||
<citerefentry><refentrytitle>systemd-analyze</refentrytitle><manvolnum>1</manvolnum></citerefentry>
|
||||
may be used to list the current contents of a service's file descriptor store.</para>
|
||||
|
||||
<para>Note that the service manager will only pass file descriptors contained in the file descriptor
|
||||
store to the service's own processes, never to other clients via IPC or similar. However, it does
|
||||
allow unprivileged clients to query the list of currently open file descriptors of a
|
||||
service. Sensitive data may hence be safely placed inside the referenced files, but should not be
|
||||
attached to the metadata (e.g. included in filenames) of the stored file
|
||||
descriptors.</para></listitem>
|
||||
</varlistentry>
|
||||
|
||||
<varlistentry>
|
||||
|
110
src/analyze/analyze-fdstore.c
Normal file
110
src/analyze/analyze-fdstore.c
Normal file
@ -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;
|
||||
}
|
5
src/analyze/analyze-fdstore.h
Normal file
5
src/analyze/analyze-fdstore.h
Normal file
@ -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);
|
@ -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 },
|
||||
{}
|
||||
};
|
||||
|
||||
|
@ -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',
|
||||
|
Loading…
x
Reference in New Issue
Block a user