mirror of
https://github.com/systemd/systemd.git
synced 2024-12-23 21:35:11 +03:00
analyze: add 'cat-config' verb
This is used as 'systemd-analyze show-config systemd/logind.conf', which will dump /etc/systemd/system/user@.service /etc/systemd/system/user@.service.d/*.conf /run/systemd/system/user@.service.d/*.conf /usr/local/lib/systemd/system/user@.service.d/*.conf /usr/lib/systemd/system/user@.service.d/*.conf The idea is to make it easy to dump the configuration using the same locations and order that systemd programs use themselves (including masking, in the right order, etc.). This is the generic variant that works with any configuration scheme that follows the same general rules: $ systemd-analyze cat-config systemd/system.conf $ systemd-analyze cat-config systemd/user.conf $ systemd-analyze cat-config systemd/logind.conf $ systemd-analyze cat-config systemd/sleep.conf $ systemd-analyze cat-config systemd/journald.conf $ systemd-analyze cat-config systemd/journal-remote.conf $ systemd-analyze cat-config systemd/journal-upload.conf $ systemd-analyze cat-config systemd/coredump.conf $ systemd-analyze cat-config systemd/resolved.conf $ systemd-analyze cat-config systemd/timesyncd.conf $ systemd-analyze cat-config udev/udev.conf
This commit is contained in:
parent
81f5e51368
commit
854a42fb2e
@ -78,6 +78,12 @@
|
||||
<arg choice="opt" rep="repeat">OPTIONS</arg>
|
||||
<arg choice="plain">dump</arg>
|
||||
</cmdsynopsis>
|
||||
<cmdsynopsis>
|
||||
<command>systemd-analyze</command>
|
||||
<arg choice="opt" rep="repeat">OPTIONS</arg>
|
||||
<arg choice="plain">cat-config</arg>
|
||||
<arg choice="plain" rep="repeat"><replaceable>NAME</replaceable></arg>
|
||||
</cmdsynopsis>
|
||||
<cmdsynopsis>
|
||||
<command>systemd-analyze</command>
|
||||
<arg choice="opt" rep="repeat">OPTIONS</arg>
|
||||
@ -180,6 +186,30 @@
|
||||
state. Its format is subject to change without notice and should
|
||||
not be parsed by applications.</para>
|
||||
|
||||
<para><command>systemd-analyze cat-config</command> is similar
|
||||
to <command>systemctl cat</command>, but operates on config files.
|
||||
It will copy the contents of a config file and any drop-ins to standard
|
||||
output, using the usual systemd set of directories and rules for
|
||||
precedence.</para>
|
||||
|
||||
<example>
|
||||
<title>Showing logind configuration</title>
|
||||
<programlisting>$ systemd-analyze cat-config systemd/logind.conf
|
||||
# /etc/systemd/logind.conf
|
||||
# This file is part of systemd.
|
||||
...
|
||||
[Login]
|
||||
NAutoVTs=8
|
||||
...
|
||||
|
||||
# /usr/lib/systemd/logind.conf.d/20-test.conf
|
||||
... some override from another package
|
||||
|
||||
# /etc/systemd/logind.conf.d/50-override.conf
|
||||
... some adminstrator override
|
||||
</programlisting>
|
||||
</example>
|
||||
|
||||
<para><command>systemd-analyze unit-paths</command> outputs a list of all
|
||||
directories from which unit files, <filename>.d</filename> overrides, and
|
||||
<filename>.wants</filename>, <filename>.requires</filename> symlinks may be
|
||||
|
@ -19,12 +19,14 @@
|
||||
#include "bus-unit-util.h"
|
||||
#include "bus-util.h"
|
||||
#include "calendarspec.h"
|
||||
#include "conf-files.h"
|
||||
#include "glob-util.h"
|
||||
#include "hashmap.h"
|
||||
#include "locale-util.h"
|
||||
#include "log.h"
|
||||
#include "pager.h"
|
||||
#include "parse-util.h"
|
||||
#include "path-util.h"
|
||||
#if HAVE_SECCOMP
|
||||
#include "seccomp-util.h"
|
||||
#endif
|
||||
@ -1312,6 +1314,29 @@ static int dump(int argc, char *argv[], void *userdata) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int cat_config(int argc, char *argv[], void *userdata) {
|
||||
char **arg;
|
||||
int r;
|
||||
|
||||
(void) pager_open(arg_no_pager, false);
|
||||
|
||||
STRV_FOREACH(arg, argv + 1) {
|
||||
if (arg != argv + 1)
|
||||
puts("");
|
||||
|
||||
if (path_is_absolute(*arg)) {
|
||||
log_error("Arguments must be config file names (relative to /etc/");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
r = conf_files_cat(*arg);
|
||||
if (r < 0)
|
||||
return r;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int set_log_level(int argc, char *argv[], void *userdata) {
|
||||
_cleanup_(sd_bus_error_free) sd_bus_error error = SD_BUS_ERROR_NULL;
|
||||
_cleanup_(sd_bus_flush_close_unrefp) sd_bus *bus = NULL;
|
||||
@ -1643,6 +1668,7 @@ static int help(int argc, char *argv[], void *userdata) {
|
||||
" log-level [LEVEL] Get/set logging threshold for manager\n"
|
||||
" log-target [TARGET] Get/set logging target for manager\n"
|
||||
" dump Output state serialization of service manager\n"
|
||||
" cat-config Show configuration file and drop-ins\n"
|
||||
" unit-paths List load directories for units\n"
|
||||
" syscall-filter [NAME...] Print list of syscalls in seccomp filter\n"
|
||||
" verify FILE... Check unit files for correctness\n"
|
||||
@ -1819,6 +1845,7 @@ int main(int argc, char *argv[]) {
|
||||
{ "set-log-target", 2, 2, 0, set_log_target },
|
||||
{ "get-log-target", VERB_ANY, 1, 0, get_log_target },
|
||||
{ "dump", VERB_ANY, 1, 0, dump },
|
||||
{ "cat-config", 2, VERB_ANY, 0, cat_config },
|
||||
{ "unit-paths", 1, 1, 0, dump_unit_paths },
|
||||
{ "syscall-filter", VERB_ANY, VERB_ANY, 0, dump_syscall_filters },
|
||||
{ "verify", 2, VERB_ANY, 0, do_verify },
|
||||
|
@ -13,6 +13,7 @@
|
||||
#include <string.h>
|
||||
|
||||
#include "conf-files.h"
|
||||
#include "def.h"
|
||||
#include "dirent-util.h"
|
||||
#include "fd-util.h"
|
||||
#include "hashmap.h"
|
||||
@ -23,6 +24,7 @@
|
||||
#include "stat-util.h"
|
||||
#include "string-util.h"
|
||||
#include "strv.h"
|
||||
#include "terminal-util.h"
|
||||
#include "util.h"
|
||||
|
||||
static int files_add(Hashmap *h, const char *suffix, const char *root, unsigned flags, const char *path) {
|
||||
@ -256,3 +258,33 @@ int conf_files_list_nulstr(char ***strv, const char *suffix, const char *root, u
|
||||
|
||||
return conf_files_list_strv_internal(strv, suffix, root, flags, d);
|
||||
}
|
||||
|
||||
int conf_files_cat(const char *name) {
|
||||
_cleanup_strv_free_ char **dirs = NULL, **files = NULL;
|
||||
const char *dir;
|
||||
char **t;
|
||||
int r;
|
||||
|
||||
NULSTR_FOREACH(dir, CONF_PATHS_NULSTR("")) {
|
||||
assert(endswith(dir, "/"));
|
||||
r = strv_extendf(&dirs, "%s%s.d", dir, name);
|
||||
if (r < 0)
|
||||
return log_error("Failed to build directory list: %m");
|
||||
}
|
||||
|
||||
r = conf_files_list_strv(&files, ".conf", NULL, 0, (const char* const*) dirs);
|
||||
if (r < 0)
|
||||
return log_error_errno(r, "Failed to query file list: %m");
|
||||
|
||||
name = strjoina("/etc/", name);
|
||||
|
||||
if (DEBUG_LOGGING) {
|
||||
log_debug("Looking for configuration in:");
|
||||
log_debug(" %s", name);
|
||||
STRV_FOREACH(t, dirs)
|
||||
log_debug(" %s/*.conf", *t);
|
||||
}
|
||||
|
||||
/* show */
|
||||
return cat_files(name, files, CAT_FLAGS_MAIN_FILE_OPTIONAL);
|
||||
}
|
||||
|
@ -17,3 +17,4 @@ int conf_files_list_strv(char ***ret, const char *suffix, const char *root, unsi
|
||||
int conf_files_list_nulstr(char ***ret, const char *suffix, const char *root, unsigned flags, const char *dirs);
|
||||
int conf_files_insert(char ***strv, const char *root, char **dirs, const char *path);
|
||||
int conf_files_insert_nulstr(char ***strv, const char *root, const char *dirs, const char *path);
|
||||
int conf_files_cat(const char *name);
|
||||
|
@ -1381,13 +1381,18 @@ static int cat_file(const char *filename, bool newline) {
|
||||
return copy_bytes(fd, STDOUT_FILENO, (uint64_t) -1, 0);
|
||||
}
|
||||
|
||||
int cat_files(const char *file, char **dropins) {
|
||||
int cat_files(const char *file, char **dropins, CatFlags flags) {
|
||||
char **path;
|
||||
int r;
|
||||
|
||||
if (file) {
|
||||
r = cat_file(file, false);
|
||||
if (r < 0)
|
||||
if (r == -ENOENT && (flags & CAT_FLAGS_MAIN_FILE_OPTIONAL))
|
||||
printf("%s# config file %s not found%s\n",
|
||||
ansi_highlight_magenta(),
|
||||
file,
|
||||
ansi_normal());
|
||||
else if (r < 0)
|
||||
return log_warning_errno(r, "Failed to cat %s: %m", file);
|
||||
}
|
||||
|
||||
|
@ -133,6 +133,7 @@ DEFINE_ANSI_FUNC(highlight_red, HIGHLIGHT_RED);
|
||||
DEFINE_ANSI_FUNC(highlight_green, HIGHLIGHT_GREEN);
|
||||
DEFINE_ANSI_FUNC(highlight_yellow, HIGHLIGHT_YELLOW);
|
||||
DEFINE_ANSI_FUNC(highlight_blue, HIGHLIGHT_BLUE);
|
||||
DEFINE_ANSI_FUNC(highlight_magenta, HIGHLIGHT_MAGENTA);
|
||||
DEFINE_ANSI_FUNC(normal, NORMAL);
|
||||
|
||||
DEFINE_ANSI_FUNC_UNDERLINE(underline, UNDERLINE, NORMAL);
|
||||
@ -160,4 +161,8 @@ int vt_reset_keyboard(int fd);
|
||||
int terminal_urlify(const char *url, const char *text, char **ret);
|
||||
int terminal_urlify_path(const char *path, const char *text, char **ret);
|
||||
|
||||
int cat_files(const char *file, char **files);
|
||||
typedef enum CatFlags {
|
||||
CAT_FLAGS_MAIN_FILE_OPTIONAL = 1 << 1,
|
||||
} CatFlags;
|
||||
|
||||
int cat_files(const char *file, char **dropins, CatFlags flags);
|
||||
|
@ -5376,7 +5376,7 @@ static int cat(int argc, char *argv[], void *userdata) {
|
||||
arg_scope == UNIT_FILE_SYSTEM ? "" : " --user",
|
||||
ansi_normal());
|
||||
|
||||
r = cat_files(fragment_path, dropin_paths);
|
||||
r = cat_files(fragment_path, dropin_paths, 0);
|
||||
if (r < 0)
|
||||
return r;
|
||||
}
|
||||
|
@ -78,10 +78,11 @@ static void test_terminal_urlify(void) {
|
||||
}
|
||||
|
||||
static void test_cat_files(void) {
|
||||
assert_se(cat_files("/no/such/file", NULL) == -ENOENT);
|
||||
assert_se(cat_files("/no/such/file", NULL, 0) == -ENOENT);
|
||||
assert_se(cat_files("/no/such/file", NULL, CAT_FLAGS_MAIN_FILE_OPTIONAL) == 0);
|
||||
|
||||
if (access("/etc/fstab", R_OK) >= 0)
|
||||
assert_se(cat_files("/etc/fstab", STRV_MAKE("/etc/fstab", "/etc/fstab")) == 0);
|
||||
assert_se(cat_files("/etc/fstab", STRV_MAKE("/etc/fstab", "/etc/fstab"), 0) == 0);
|
||||
}
|
||||
|
||||
int main(int argc, char *argv[]) {
|
||||
|
Loading…
Reference in New Issue
Block a user