From 1f63c72d2e6a527c1207ea01dc223fc711247ba0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Zbigniew=20J=C4=99drzejewski-Szmek?= Date: Thu, 7 May 2020 13:28:39 +0200 Subject: [PATCH 01/11] man: suffix pam options with "=" where arg is required too --- man/pam_systemd.xml | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/man/pam_systemd.xml b/man/pam_systemd.xml index c823faaaed..70927d7374 100644 --- a/man/pam_systemd.xml +++ b/man/pam_systemd.xml @@ -259,31 +259,31 @@ - systemd.memory_max + systemd.memory_max= Sets unit MemoryMax=. - systemd.tasks_max + systemd.tasks_max= Sets unit TasksMax=. - systemd.cpu_weight + systemd.cpu_weight= Sets unit CPUWeight=. - systemd.io_weight + systemd.io_weight= Sets unit IOWeight=. - systemd.runtime_max_sec + systemd.runtime_max_sec= Sets unit RuntimeMaxSec=. From dd1e33c8dc30c4d30e65688dabff7c66a456675e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Zbigniew=20J=C4=99drzejewski-Szmek?= Date: Thu, 7 May 2020 13:54:10 +0200 Subject: [PATCH 02/11] meson: drop "meson-" prefix from various helper script filenames In a few cases, the prefix was originally necessary because a different helper script was used for automake, and a different one for meson. But now we use meson exclusively, and the prefix isn't useful. This also synchronizes the target name, file name, and variable name in meson.build. The targets exposed by meson didn't have the prefix, so the user interface is unchanged. (The prefix is retained in the few tools that are used for meson itself, e.g. meosn-vcs-tag.sh, meson-make-symlink.sh, etc.) --- meson.build | 18 +++++++++--------- ...suspend-update.sh => autosuspend-update.sh} | 0 ...son-check-api-docs.sh => check-api-docs.sh} | 0 ...eck-compilation.sh => check-compilation.sh} | 0 tools/{meson-check-help.sh => check-help.sh} | 0 tools/{meson-git-contrib.sh => git-contrib.sh} | 0 tools/{meson-hwdb-update.sh => hwdb-update.sh} | 0 7 files changed, 9 insertions(+), 9 deletions(-) rename tools/{meson-autosuspend-update.sh => autosuspend-update.sh} (100%) rename tools/{meson-check-api-docs.sh => check-api-docs.sh} (100%) rename tools/{meson-check-compilation.sh => check-compilation.sh} (100%) rename tools/{meson-check-help.sh => check-help.sh} (100%) rename tools/{meson-git-contrib.sh => git-contrib.sh} (100%) rename tools/{meson-hwdb-update.sh => hwdb-update.sh} (100%) diff --git a/meson.build b/meson.build index a922f9a2f1..28494c9af2 100644 --- a/meson.build +++ b/meson.build @@ -299,7 +299,7 @@ substs.set('BUILD_ROOT', project_build_root cc = meson.get_compiler('c') pkgconfig = import('pkgconfig') -check_compilation_sh = find_program('tools/meson-check-compilation.sh') +check_compilation_sh = find_program('tools/check-compilation.sh') meson_build_sh = find_program('tools/meson-build.sh') want_tests = get_option('tests') @@ -3244,8 +3244,8 @@ run_target( make_directive_index_py = find_program('tools/make-directive-index.py') make_man_index_py = find_program('tools/make-man-index.py') xml_helper_py = find_program('tools/xml_helper.py') -hwdb_update_sh = find_program('tools/meson-hwdb-update.sh') -autosuspend_update_sh = find_program('tools/meson-autosuspend-update.sh') +hwdb_update_sh = find_program('tools/hwdb-update.sh') +autosuspend_update_sh = find_program('tools/autosuspend-update.sh') subdir('sysctl.d') subdir('sysusers.d') @@ -3286,13 +3286,13 @@ meson.add_install_script('sh', '-c', 'touch $DESTDIR@0@'.format(prefixdir)) ############################################################ -meson_check_help = find_program('tools/meson-check-help.sh') +check_help = find_program('tools/check-help.sh') foreach exec : public_programs name = exec.full_path().split('/')[-1] if want_tests != 'false' test('check-help-' + name, - meson_check_help, + check_help, args : exec.full_path()) endif endforeach @@ -3371,10 +3371,10 @@ if git.found() endif if git.found() - meson_git_contrib_sh = find_program('tools/meson-git-contrib.sh') + git_contrib_sh = find_program('tools/git-contrib.sh') run_target( 'git-contrib', - command : [meson_git_contrib_sh]) + command : [git_contrib_sh]) endif if git.found() @@ -3398,11 +3398,11 @@ endif ############################################################ -meson_check_api_docs_sh = find_program('tools/meson-check-api-docs.sh') +check_api_docs_sh = find_program('tools/check-api-docs.sh') run_target( 'check-api-docs', depends : [man, libsystemd, libudev], - command : [meson_check_api_docs_sh, libsystemd.full_path(), libudev.full_path()]) + command : [check_api_docs_sh, libsystemd.full_path(), libudev.full_path()]) ############################################################ watchdog_opt = service_watchdog == '' ? 'disabled' : service_watchdog diff --git a/tools/meson-autosuspend-update.sh b/tools/autosuspend-update.sh similarity index 100% rename from tools/meson-autosuspend-update.sh rename to tools/autosuspend-update.sh diff --git a/tools/meson-check-api-docs.sh b/tools/check-api-docs.sh similarity index 100% rename from tools/meson-check-api-docs.sh rename to tools/check-api-docs.sh diff --git a/tools/meson-check-compilation.sh b/tools/check-compilation.sh similarity index 100% rename from tools/meson-check-compilation.sh rename to tools/check-compilation.sh diff --git a/tools/meson-check-help.sh b/tools/check-help.sh similarity index 100% rename from tools/meson-check-help.sh rename to tools/check-help.sh diff --git a/tools/meson-git-contrib.sh b/tools/git-contrib.sh similarity index 100% rename from tools/meson-git-contrib.sh rename to tools/git-contrib.sh diff --git a/tools/meson-hwdb-update.sh b/tools/hwdb-update.sh similarity index 100% rename from tools/meson-hwdb-update.sh rename to tools/hwdb-update.sh From 06689b8d11abaab4003f5b459b53ecc52c7be14c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Zbigniew=20J=C4=99drzejewski-Szmek?= Date: Thu, 7 May 2020 14:01:09 +0200 Subject: [PATCH 03/11] meson: rename make-man-rules.py to update-man-rules.py The name of the helper didn't match the name of the meson target, which was always confusing me. With this change, we consistenly use "update" to re-generate things which we otherwise keep in vc, and "make" for things which are generated during each build. --- man/meson.build | 2 +- man/rules/meson.build | 2 +- tools/{make-man-rules.py => update-man-rules.py} | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) rename tools/{make-man-rules.py => update-man-rules.py} (98%) diff --git a/man/meson.build b/man/meson.build index c9d511b080..215b8eeb37 100644 --- a/man/meson.build +++ b/man/meson.build @@ -217,7 +217,7 @@ if git.found() output : 'update-man-rules', command : ['sh', '-c', 'cd @0@ && '.format(meson.build_root()) + - 'python3 @0@/tools/make-man-rules.py $(git ls-files ":/man/*.xml") >t && '.format(project_source_root) + + 'python3 @0@/tools/update-man-rules.py $(git ls-files ":/man/*.xml") >t && '.format(project_source_root) + 'mv t @0@/rules/meson.build'.format(meson.current_source_dir())], depend_files : custom_entities_ent) endif diff --git a/man/rules/meson.build b/man/rules/meson.build index 0d05508e7b..0639b17df6 100644 --- a/man/rules/meson.build +++ b/man/rules/meson.build @@ -1,4 +1,4 @@ -# Do not edit. Generated by make-man-rules.py. +# Do not edit. Generated by update-man-rules.py. # Update with: # ninja -C build man/update-man-rules manpages = [ diff --git a/tools/make-man-rules.py b/tools/update-man-rules.py similarity index 98% rename from tools/make-man-rules.py rename to tools/update-man-rules.py index d86afcbc15..c404579a2a 100755 --- a/tools/make-man-rules.py +++ b/tools/update-man-rules.py @@ -50,7 +50,7 @@ def mjoin(files): return ' \\\n\t'.join(sorted(files) or '#') MESON_HEADER = '''\ -# Do not edit. Generated by make-man-rules.py. +# Do not edit. Generated by update-man-rules.py. # Update with: # ninja -C build man/update-man-rules manpages = [''' From c62e7d041fe4edec736e13e1325adb96fed8c6a4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Zbigniew=20J=C4=99drzejewski-Szmek?= Date: Thu, 7 May 2020 14:05:17 +0200 Subject: [PATCH 04/11] man: update rules Forgotten in 4f07ddfa9bc2242eaa6c288a15b8bce4e4383931. --- man/rules/meson.build | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/man/rules/meson.build b/man/rules/meson.build index 0639b17df6..5bbee35e9f 100644 --- a/man/rules/meson.build +++ b/man/rules/meson.build @@ -720,7 +720,11 @@ manpages = [ ['sd_machine_get_class', '3', ['sd_machine_get_ifindices'], ''], ['sd_notify', '3', - ['sd_notifyf', 'sd_pid_notify', 'sd_pid_notify_with_fds', 'sd_pid_notifyf', 'sd_notify_barrier'], + ['sd_notify_barrier', + 'sd_notifyf', + 'sd_pid_notify', + 'sd_pid_notify_with_fds', + 'sd_pid_notifyf'], ''], ['sd_path_lookup', '3', ['sd_path_lookup_strv'], ''], ['sd_pid_get_owner_uid', From 282230882cd0fc49b5377349f2aee22a1c9dd159 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Zbigniew=20J=C4=99drzejewski-Szmek?= Date: Thu, 7 May 2020 14:31:13 +0200 Subject: [PATCH 05/11] tools: move directive index template to separate file In the beginning, it was rather short, and reasonable to include inline. Now it is long and unwieldy, let's split it out. While at it, let's reindent and wrap using our current standards. --- man/directives-template.xml | 182 ++++++++++++++++++++++++++++++ man/meson.build | 4 +- tools/make-directive-index.py | 201 +--------------------------------- 3 files changed, 190 insertions(+), 197 deletions(-) create mode 100644 man/directives-template.xml diff --git a/man/directives-template.xml b/man/directives-template.xml new file mode 100644 index 0000000000..3583db3ef0 --- /dev/null +++ b/man/directives-template.xml @@ -0,0 +1,182 @@ + + + + + systemd.directives + systemd + + + + systemd.directives + 7 + + + + systemd.directives + Index of configuration directives + + + + Unit directives + + Directives for configuring units, used in unit files. + + + + + + Options on the kernel command line + + Kernel boot options for configuring the behaviour of the systemd process. + + + + + + Environment variables + + Environment variables understood by the systemd manager and other programs and environment + variable-compatible settings. + + + + + + EFI variables + + EFI variables understood by + systemd-boot7 + and other programs. + + + + + + UDEV directives + + Directives for configuring systemd units through the udev database. + + + + + + Network directives + + Directives for configuring network links through the net-setup-link udev builtin and networks + through systemd-networkd. + + + + + + Journal fields + + Fields in the journal events with a well known meaning. + + + + + + PAM configuration directives + + Directives for configuring PAM behaviour. + + + + + + <filename>/etc/crypttab</filename> and + <filename>/etc/fstab</filename> options + + Options which influence mounted filesystems and encrypted volumes. + + + + + + <citerefentry><refentrytitle>systemd.nspawn</refentrytitle><manvolnum>5</manvolnum></citerefentry> + directives + + Directives for configuring systemd-nspawn containers. + + + + + + Program configuration options + + Directives for configuring the behaviour of the systemd process and other tools through + configuration files. + + + + + + Command line options + + Command-line options accepted by programs in the systemd suite. + + + + + + Constants + + Various constant used and/or defined by systemd. + + + + + + Miscellaneous options and directives + + Other configuration elements which don't fit in any of the above groups. + + + + + + Files and directories + + Paths and file names referred to in the documentation. + + + + + + D-Bus interfaces + + Interfaces exposed over D-Bus. + + + + + + D-Bus methods + + Methods exposed in the D-Bus interface. + + + + + + D-Bus properties + + Properties exposed in the D-Bus interface. + + + + + + D-Bus signals + + Signals emitted in the D-Bus interface. + + + + + + Colophon + + + diff --git a/man/meson.build b/man/meson.build index 215b8eeb37..3a7143a4b6 100644 --- a/man/meson.build +++ b/man/meson.build @@ -110,9 +110,9 @@ endif systemd_directives_xml = custom_target( 'systemd.directives.xml', - input : source_xml_files, + input : ['directives-template.xml', source_xml_files], output : 'systemd.directives.xml', - command : [make_directive_index_py, '@OUTPUT@'] + source_xml_files) + command : [make_directive_index_py, '@OUTPUT@', '@INPUT@']) nonindex_xml_files = source_xml_files + [systemd_directives_xml] systemd_index_xml = custom_target( diff --git a/tools/make-directive-index.py b/tools/make-directive-index.py index ae00c8cab2..26561a2456 100755 --- a/tools/make-directive-index.py +++ b/tools/make-directive-index.py @@ -7,198 +7,6 @@ import re from xml_helper import xml_parse, xml_print, tree from copy import deepcopy -TEMPLATE = '''\ - - - - systemd.directives - systemd - - - - systemd.directives - 7 - - - - systemd.directives - Index of configuration directives - - - - Unit directives - - Directives for configuring units, used in unit - files. - - - - - - Options on the kernel command line - - Kernel boot options for configuring the behaviour of the - systemd process. - - - - - - Environment variables - - Environment variables understood by the systemd manager - and other programs and environment variable-compatible settings. - - - - - - EFI variables - - EFI variables understood by - systemd-boot7 - and other programs. - - - - - - UDEV directives - - Directives for configuring systemd units through the - udev database. - - - - - - Network directives - - Directives for configuring network links through the - net-setup-link udev builtin and networks through - systemd-networkd. - - - - - - Journal fields - - Fields in the journal events with a well known meaning. - - - - - - PAM configuration directives - - Directives for configuring PAM behaviour. - - - - - - <filename>/etc/crypttab</filename> and - <filename>/etc/fstab</filename> options - - Options which influence mounted filesystems and - encrypted volumes. - - - - - - <citerefentry><refentrytitle>systemd.nspawn</refentrytitle><manvolnum>5</manvolnum></citerefentry> - directives - - Directives for configuring systemd-nspawn containers. - - - - - - Program configuration options - - Directives for configuring the behaviour of the - systemd process and other tools through configuration files. - - - - - - Command line options - - Command-line options accepted by programs in the - systemd suite. - - - - - - Constants - - Various constant used and/or defined by systemd. - - - - - - Miscellaneous options and directives - - Other configuration elements which don't fit in - any of the above groups. - - - - - - Files and directories - - Paths and file names referred to in the - documentation. - - - - - - D-Bus interfaces - - Interfaces exposed over D-Bus. - - - - - - D-Bus methods - - Methods exposed in the D-Bus interface. - - - - - - D-Bus properties - - Properties exposed in the D-Bus interface. - - - - - - D-Bus signals - - Signals emitted in the D-Bus interface. - - - - - - Colophon - - - -''' - COLOPHON = '''\ This index contains {count} entries in {sections} sections, referring to {pages} individual manual pages. @@ -330,9 +138,9 @@ def _make_page(template, directive_groups, formatting): return template -def make_page(*xml_files): +def make_page(template_path, xml_files): "Extract directives from xml_files and return XML index tree." - template = tree.fromstring(TEMPLATE) + template = xml_parse(template_path) names = [vl.get('id') for vl in template.iterfind('.//variablelist')] directive_groups = {name:collections.defaultdict(list) for name in names} @@ -347,4 +155,7 @@ def make_page(*xml_files): if __name__ == '__main__': with open(sys.argv[1], 'wb') as f: - f.write(xml_print(make_page(*sys.argv[2:]))) + template_path = sys.argv[2] + xml_files = sys.argv[3:] + xml = make_page(template_path, xml_files) + f.write(xml_print(xml)) From 0d525a3e9366f744edeb327fec94928305b27cc4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Zbigniew=20J=C4=99drzejewski-Szmek?= Date: Thu, 7 May 2020 14:59:24 +0200 Subject: [PATCH 06/11] man: add specifiers section to directives index The hack with getparent().txt is not very pretty, but the whole thing seems to work well enough. It is useful to figure out whihc specifiers are supported where. --- man/directives-template.xml | 8 ++++++++ man/systemd.dnssd.xml | 2 +- man/systemd.unit.xml | 8 +++++--- man/sysusers.d.xml | 2 +- man/tmpfiles.d.xml | 2 +- tools/make-directive-index.py | 9 +++++++++ 6 files changed, 25 insertions(+), 6 deletions(-) diff --git a/man/directives-template.xml b/man/directives-template.xml index 3583db3ef0..5ab0beb4cf 100644 --- a/man/directives-template.xml +++ b/man/directives-template.xml @@ -135,6 +135,14 @@ + + Specifiers + + Short strings which are substituted in configuration directives. + + + + Files and directories diff --git a/man/systemd.dnssd.xml b/man/systemd.dnssd.xml index 9e11677bde..2fb0a8ee70 100644 --- a/man/systemd.dnssd.xml +++ b/man/systemd.dnssd.xml @@ -75,7 +75,7 @@ An instance name of the network service as defined in the section 4.1.1 of RFC 6763, e.g. webserver. The option supports simple specifier expansion. The following expansions are understood: - +
Specifiers available diff --git a/man/systemd.unit.xml b/man/systemd.unit.xml index 999a13c560..dd6d6af21d 100644 --- a/man/systemd.unit.xml +++ b/man/systemd.unit.xml @@ -1695,7 +1695,7 @@ and resolvable for the setting to be valid. The following specifiers are understood: -
+
Specifiers available in unit files @@ -1710,7 +1710,8 @@ - + %a Architecture A short string identifying the architecture of the local system. A string such as x86, x86-64 or arm64. See the architectures defined for ConditionArchitecture= above for a full list. @@ -1740,7 +1741,8 @@ Note that this setting is not influenced by the User= setting configurable in the [Service] section of the service unit. - + %H Host name The hostname of the running system at the point in time the unit configuration is loaded. diff --git a/man/sysusers.d.xml b/man/sysusers.d.xml index 46e860ee50..5a71d911c4 100644 --- a/man/sysusers.d.xml +++ b/man/sysusers.d.xml @@ -237,7 +237,7 @@ r - 500-900 Specifiers can be used in the "Name", "ID", "GECOS", "Home directory", and "Shell" fields. An unknown or unresolvable specifier is treated as invalid configuration. The following expansions are understood: -
+
Specifiers available diff --git a/man/tmpfiles.d.xml b/man/tmpfiles.d.xml index f45dfe0a53..2e9ba5fe90 100644 --- a/man/tmpfiles.d.xml +++ b/man/tmpfiles.d.xml @@ -618,7 +618,7 @@ w- /proc/sys/vm/swappiness - - - - 10 Specifiers can be used in the "path" and "argument" fields. An unknown or unresolvable specifier is treated as invalid configuration. The following expansions are understood: -
+
Specifiers available diff --git a/tools/make-directive-index.py b/tools/make-directive-index.py index 26561a2456..c6b2173b2e 100755 --- a/tools/make-directive-index.py +++ b/tools/make-directive-index.py @@ -87,6 +87,15 @@ def _extract_directives(directive_groups, formatting, page): storfile[name.text].append((pagename, section)) formatting[name.text] = name + storfile = directive_groups['specifiers'] + for name in t.iterfind(".//table[@class='specifiers']//entry/literal"): + if name.text[0] != '%' or name.getparent().text is not None: + continue + if name.attrib.get('index') == 'false': + continue + storfile[name.text].append((pagename, section)) + formatting[name.text] = name + def _make_section(template, name, directives, formatting): varlist = template.find(".//*[@id='{}']".format(name)) for varname, manpages in sorted(directives.items()): From 655287450600681c06d7717deca5b295a7facaa5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Zbigniew=20J=C4=99drzejewski-Szmek?= Date: Thu, 7 May 2020 15:02:02 +0200 Subject: [PATCH 07/11] man: fix indentation in sysusers.d.xml --- man/sysusers.d.xml | 82 ++++++++++++++++++++++++---------------------- 1 file changed, 42 insertions(+), 40 deletions(-) diff --git a/man/sysusers.d.xml b/man/sysusers.d.xml index 5a71d911c4..f7db34ae90 100644 --- a/man/sysusers.d.xml +++ b/man/sysusers.d.xml @@ -234,46 +234,48 @@ r - 500-900 Specifiers - Specifiers can be used in the "Name", "ID", "GECOS", "Home directory", and "Shell" fields. - An unknown or unresolvable specifier is treated as invalid configuration. - The following expansions are understood: -
- Specifiers available - - - - - - - Specifier - Meaning - Details - - - - - - - - - - - %T - Directory for temporary files - This is either /tmp or the path $TMPDIR, $TEMP or $TMP are set to. - - - - %V - Directory for larger and persistent temporary files - This is either /var/tmp or the path $TMPDIR, $TEMP or $TMP are set to. - - - - - - -
+ Specifiers can be used in the Name, ID, + GECOS, Home directory, and Shell fields. An + unknown or unresolvable specifier is treated as invalid configuration. The following expansions are + understood: + + + Specifiers available + + + + + + + Specifier + Meaning + Details + + + + + + + + + + + %T + Directory for temporary files + This is either /tmp or the path $TMPDIR, $TEMP or $TMP are set to. + + + + %V + Directory for larger and persistent temporary files + This is either /var/tmp or the path $TMPDIR, $TEMP or $TMP are set to. + + + + + + +
From 6dbf40256bd88f1c74657bd9ffbd9eaa06c08706 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Zbigniew=20J=C4=99drzejewski-Szmek?= Date: Thu, 7 May 2020 15:05:29 +0200 Subject: [PATCH 08/11] man: put all pages which mention a specifier in the index I wasn't 100% convinced that this is the right thing to do, hence the separate commit. But e.g. for paths we index all mentions, so I think it's reasonable to do the same here. --- man/systemd.mount.xml | 8 ++++---- man/systemd.swap.xml | 12 +++++++----- tools/make-directive-index.py | 3 +++ 3 files changed, 14 insertions(+), 9 deletions(-) diff --git a/man/systemd.mount.xml b/man/systemd.mount.xml index d775d74053..4200a9ed7e 100644 --- a/man/systemd.mount.xml +++ b/man/systemd.mount.xml @@ -444,9 +444,9 @@ created. (See systemd.device5 for more information.) This option is mandatory. Note that the usual specifier expansion is applied - to this setting, literal percent characters should hence be written as %%. If this - mount is a bind mount and the specified path does not exist yet it is created as - directory. + to this setting, literal percent characters should hence be written as %%. If this mount is a bind mount and the specified path does not exist + yet it is created as directory. @@ -469,7 +469,7 @@ Mount options to use when mounting. This takes a comma-separated list of options. This setting is optional. Note that the usual specifier expansion is applied to this setting, literal percent characters - should hence be written as %%. + should hence be written as %%. diff --git a/man/systemd.swap.xml b/man/systemd.swap.xml index 190fc388c0..c4160290a5 100644 --- a/man/systemd.swap.xml +++ b/man/systemd.swap.xml @@ -184,11 +184,13 @@ project='man-pages'>swapon8 for details. If this refers to a device node, a dependency on the respective device unit is automatically created. (See - systemd.device5 for more - information.) If this refers to a file, a dependency on the respective mount unit is automatically - created. (See systemd.mount5 - for more information.) This option is mandatory. Note that the usual specifier expansion is applied to this - setting, literal percent characters should hence be written as %%. + systemd.device5 + for more information.) If this refers to a file, a dependency on the respective mount unit is + automatically created. (See + systemd.mount5 for + more information.) This option is mandatory. Note that the usual specifier expansion is applied to + this setting, literal percent characters should hence be written as + %%. diff --git a/tools/make-directive-index.py b/tools/make-directive-index.py index c6b2173b2e..b04281490d 100755 --- a/tools/make-directive-index.py +++ b/tools/make-directive-index.py @@ -95,6 +95,9 @@ def _extract_directives(directive_groups, formatting, page): continue storfile[name.text].append((pagename, section)) formatting[name.text] = name + for name in t.iterfind(".//literal[@class='specifiers']"): + storfile[name.text].append((pagename, section)) + formatting[name.text] = name def _make_section(template, name, directives, formatting): varlist = template.find(".//*[@id='{}']".format(name)) From eef4b80033e9ca8e61ccb40a710babcfe9b69b26 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Zbigniew=20J=C4=99drzejewski-Szmek?= Date: Thu, 7 May 2020 17:30:02 +0200 Subject: [PATCH 09/11] Add a basic test that the configured fallback hostname is OK Ideally, assert_cc() would be used for this, so that it is not possible to even compile systemd with something like '-Dfallback-hostname=.foo'. But to do a proper check we need to call hostname_is_valid(), and we cannot depend on being able to run code (e.g. during cross-compilation). So let's do a very superficial check in meson, and a proper on in test-util. --- meson.build | 9 ++++++++- src/test/test-hostname-util.c | 9 +++++++++ 2 files changed, 17 insertions(+), 1 deletion(-) diff --git a/meson.build b/meson.build index 28494c9af2..fea226e2d6 100644 --- a/meson.build +++ b/meson.build @@ -639,7 +639,14 @@ endforeach ############################################################ -conf.set_quoted('FALLBACK_HOSTNAME', get_option('fallback-hostname')) +fallback_hostname = get_option('fallback-hostname') +if fallback_hostname == '' or fallback_hostname[0] == '.' or fallback_hostname[0] == '-' + error('Invalid fallback-hostname configuration') + # A more extensive test is done in test-hostname-util. Let's catch + # the most obvious errors here so we don't fail with an assert later. +endif +conf.set_quoted('FALLBACK_HOSTNAME', fallback_hostname) + conf.set10('ENABLE_COMPAT_GATEWAY_HOSTNAME', get_option('compat-gateway-hostname')) gateway_hostnames = ['_gateway'] + (conf.get('ENABLE_COMPAT_GATEWAY_HOSTNAME') == 1 ? ['gateway'] : []) diff --git a/src/test/test-hostname-util.c b/src/test/test-hostname-util.c index ec34f9cd71..fe1b23e1bb 100644 --- a/src/test/test-hostname-util.c +++ b/src/test/test-hostname-util.c @@ -140,6 +140,13 @@ static void test_read_etc_hostname(void) { unlink(path); } +static void test_fallback_hostname(void) { + if (!hostname_is_valid(FALLBACK_HOSTNAME, false)) { + log_error("Configured fallback hostname \"%s\" is not valid.", FALLBACK_HOSTNAME); + exit(EXIT_FAILURE); + } +} + int main(int argc, char *argv[]) { log_parse_environment(); log_open(); @@ -148,5 +155,7 @@ int main(int argc, char *argv[]) { test_hostname_cleanup(); test_read_etc_hostname(); + test_fallback_hostname(); + return 0; } From e97708fa3e029902c02676bba6e6c2f54f1eba3a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Zbigniew=20J=C4=99drzejewski-Szmek?= Date: Thu, 7 May 2020 16:16:19 +0200 Subject: [PATCH 10/11] Add %l as specifier for the hostname without any domain component As described in #15603, it is a fairly common setup to use a fqdn as the configured hostname. But it is often convenient to use just the actual hostname, i.e. until the first dot. This adds support in tmpfiles, sysusers, and unit files for %l which expands to that. Fixes #15603. --- man/standard-specifiers.xml | 5 +++++ man/systemd.unit.xml | 5 +++++ man/sysusers.d.xml | 1 + man/tmpfiles.d.xml | 1 + src/basic/hostname-util.c | 25 ++++++++++++++++++++++--- src/basic/hostname-util.h | 1 + src/core/unit-printf.c | 1 + src/shared/specifier.c | 11 +++++++++++ src/shared/specifier.h | 1 + src/sysusers/sysusers.c | 23 ++++++++++++----------- src/test/test-hostname-util.c | 11 +++++++++++ src/tmpfiles/tmpfiles.c | 1 + 12 files changed, 72 insertions(+), 14 deletions(-) diff --git a/man/standard-specifiers.xml b/man/standard-specifiers.xml index 0c258241df..3efbb6db00 100644 --- a/man/standard-specifiers.xml +++ b/man/standard-specifiers.xml @@ -24,6 +24,11 @@ Host name The hostname of the running system. + + %l + Short host name + The hostname of the running system, truncated at the first dot to remove any domain component. + %m Machine ID diff --git a/man/systemd.unit.xml b/man/systemd.unit.xml index dd6d6af21d..b451c53020 100644 --- a/man/systemd.unit.xml +++ b/man/systemd.unit.xml @@ -1747,6 +1747,11 @@ Note that this setting is not influenced by the Us Host name The hostname of the running system at the point in time the unit configuration is loaded. + + %l + Short host name + The hostname of the running system at the point in time the unit configuration is loaded, truncated at the first dot to remove any domain component. + %i Instance name diff --git a/man/sysusers.d.xml b/man/sysusers.d.xml index f7db34ae90..38a95d6e1f 100644 --- a/man/sysusers.d.xml +++ b/man/sysusers.d.xml @@ -257,6 +257,7 @@ r - 500-900 + diff --git a/man/tmpfiles.d.xml b/man/tmpfiles.d.xml index 2e9ba5fe90..90234c3d43 100644 --- a/man/tmpfiles.d.xml +++ b/man/tmpfiles.d.xml @@ -646,6 +646,7 @@ w- /proc/sys/vm/swappiness - - - - 10 This is the home directory of the user running the command. In case of the system instance this resolves to /root. + %L System or user log directory diff --git a/src/basic/hostname-util.c b/src/basic/hostname-util.c index 5a2d60f21d..90a3dfc864 100644 --- a/src/basic/hostname-util.c +++ b/src/basic/hostname-util.c @@ -31,6 +31,7 @@ bool hostname_is_set(void) { char* gethostname_malloc(void) { struct utsname u; + const char *s; /* This call tries to return something useful, either the actual hostname * or it makes something up. The only reason it might fail is OOM. @@ -38,10 +39,28 @@ char* gethostname_malloc(void) { assert_se(uname(&u) >= 0); - if (isempty(u.nodename) || streq(u.nodename, "(none)")) - return strdup(FALLBACK_HOSTNAME); + s = u.nodename; + if (isempty(s) || streq(s, "(none)")) + s = FALLBACK_HOSTNAME; - return strdup(u.nodename); + return strdup(s); +} + +char* gethostname_short_malloc(void) { + struct utsname u; + const char *s; + + /* Like above, but kills the FQDN part if present. */ + + assert_se(uname(&u) >= 0); + + s = u.nodename; + if (isempty(s) || streq(s, "(none)") || s[0] == '.') { + s = FALLBACK_HOSTNAME; + assert(s[0] != '.'); + } + + return strndup(s, strcspn(s, ".")); } int gethostname_strict(char **ret) { diff --git a/src/basic/hostname-util.h b/src/basic/hostname-util.h index 7ba386a0fd..cafd6f020b 100644 --- a/src/basic/hostname-util.h +++ b/src/basic/hostname-util.h @@ -9,6 +9,7 @@ bool hostname_is_set(void); char* gethostname_malloc(void); +char* gethostname_short_malloc(void); int gethostname_strict(char **ret); bool valid_ldh_char(char c) _const_; diff --git a/src/core/unit-printf.c b/src/core/unit-printf.c index 049a2f5596..4fee5dc6dc 100644 --- a/src/core/unit-printf.c +++ b/src/core/unit-printf.c @@ -291,6 +291,7 @@ int unit_full_printf(const Unit *u, const char *format, char **ret) { { 'm', specifier_machine_id, NULL }, { 'H', specifier_host_name, NULL }, + { 'l', specifier_short_host_name, NULL }, { 'b', specifier_boot_id, NULL }, { 'v', specifier_kernel_release, NULL }, {} diff --git a/src/shared/specifier.c b/src/shared/specifier.c index c784222be6..112cf6f8fb 100644 --- a/src/shared/specifier.c +++ b/src/shared/specifier.c @@ -160,6 +160,17 @@ int specifier_host_name(char specifier, const void *data, const void *userdata, return 0; } +int specifier_short_host_name(char specifier, const void *data, const void *userdata, char **ret) { + char *n; + + n = gethostname_short_malloc(); + if (!n) + return -ENOMEM; + + *ret = n; + return 0; +} + int specifier_kernel_release(char specifier, const void *data, const void *userdata, char **ret) { struct utsname uts; char *n; diff --git a/src/shared/specifier.h b/src/shared/specifier.h index 33c17eae67..50c6cbd6ab 100644 --- a/src/shared/specifier.h +++ b/src/shared/specifier.h @@ -18,6 +18,7 @@ int specifier_string(char specifier, const void *data, const void *userdata, cha int specifier_machine_id(char specifier, const void *data, const void *userdata, char **ret); int specifier_boot_id(char specifier, const void *data, const void *userdata, char **ret); int specifier_host_name(char specifier, const void *data, const void *userdata, char **ret); +int specifier_short_host_name(char specifier, const void *data, const void *userdata, char **ret); int specifier_kernel_release(char specifier, const void *data, const void *userdata, char **ret); int specifier_architecture(char specifier, const void *data, const void *userdata, char **ret); int specifier_os_id(char specifier, const void *data, const void *userdata, char **ret); diff --git a/src/sysusers/sysusers.c b/src/sysusers/sysusers.c index 73a710bee7..a13c35b648 100644 --- a/src/sysusers/sysusers.c +++ b/src/sysusers/sysusers.c @@ -1389,17 +1389,18 @@ static bool item_equal(Item *a, Item *b) { static int parse_line(const char *fname, unsigned line, const char *buffer) { static const Specifier specifier_table[] = { - { 'm', specifier_machine_id, NULL }, - { 'b', specifier_boot_id, NULL }, - { 'H', specifier_host_name, NULL }, - { 'v', specifier_kernel_release, NULL }, - { 'a', specifier_architecture, NULL }, - { 'o', specifier_os_id, NULL }, - { 'w', specifier_os_version_id, NULL }, - { 'B', specifier_os_build_id, NULL }, - { 'W', specifier_os_variant_id, NULL }, - { 'T', specifier_tmp_dir, NULL }, - { 'V', specifier_var_tmp_dir, NULL }, + { 'm', specifier_machine_id, NULL }, + { 'b', specifier_boot_id, NULL }, + { 'H', specifier_host_name, NULL }, + { 'l', specifier_short_host_name, NULL }, + { 'v', specifier_kernel_release, NULL }, + { 'a', specifier_architecture, NULL }, + { 'o', specifier_os_id, NULL }, + { 'w', specifier_os_version_id, NULL }, + { 'B', specifier_os_build_id, NULL }, + { 'W', specifier_os_variant_id, NULL }, + { 'T', specifier_tmp_dir, NULL }, + { 'V', specifier_var_tmp_dir, NULL }, {} }; diff --git a/src/test/test-hostname-util.c b/src/test/test-hostname-util.c index fe1b23e1bb..5ab82bba61 100644 --- a/src/test/test-hostname-util.c +++ b/src/test/test-hostname-util.c @@ -140,6 +140,16 @@ static void test_read_etc_hostname(void) { unlink(path); } +static void test_hostname_malloc(void) { + _cleanup_free_ char *h = NULL, *l = NULL; + + assert_se(h = gethostname_malloc()); + log_info("hostname_malloc: \"%s\"", h); + + assert_se(l = gethostname_short_malloc()); + log_info("hostname_short_malloc: \"%s\"", l); +} + static void test_fallback_hostname(void) { if (!hostname_is_valid(FALLBACK_HOSTNAME, false)) { log_error("Configured fallback hostname \"%s\" is not valid.", FALLBACK_HOSTNAME); @@ -154,6 +164,7 @@ int main(int argc, char *argv[]) { test_hostname_is_valid(); test_hostname_cleanup(); test_read_etc_hostname(); + test_hostname_malloc(); test_fallback_hostname(); diff --git a/src/tmpfiles/tmpfiles.c b/src/tmpfiles/tmpfiles.c index 7137e9fbd7..2702b36bdd 100644 --- a/src/tmpfiles/tmpfiles.c +++ b/src/tmpfiles/tmpfiles.c @@ -184,6 +184,7 @@ static const Specifier specifier_table[] = { { 'm', specifier_machine_id_safe, NULL }, { 'b', specifier_boot_id, NULL }, { 'H', specifier_host_name, NULL }, + { 'l', specifier_short_host_name, NULL }, { 'v', specifier_kernel_release, NULL }, { 'a', specifier_architecture, NULL }, { 'o', specifier_os_id, NULL }, From b6c93a5a4489d238a03ba70d9418951a0d379ddf Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Zbigniew=20J=C4=99drzejewski-Szmek?= Date: Thu, 7 May 2020 16:25:36 +0200 Subject: [PATCH 11/11] test-specifier: add a simple test which prints "global" specifiers ...i.e. those which can be resolved without a context parameter. --- src/test/test-specifier.c | 48 ++++++++++++++++++++++++++++++++++++++- 1 file changed, 47 insertions(+), 1 deletion(-) diff --git a/src/test/test-specifier.c b/src/test/test-specifier.c index a0ffdf6cb6..e81b12b418 100644 --- a/src/test/test-specifier.c +++ b/src/test/test-specifier.c @@ -3,6 +3,7 @@ #include "alloc-util.h" #include "log.h" #include "specifier.h" +#include "stdio-util.h" #include "string-util.h" #include "strv.h" #include "tests.h" @@ -15,6 +16,8 @@ static void test_specifier_escape_one(const char *a, const char *b) { } static void test_specifier_escape(void) { + log_info("/* %s */", __func__); + test_specifier_escape_one(NULL, NULL); test_specifier_escape_one("", ""); test_specifier_escape_one("%", "%%"); @@ -31,12 +34,54 @@ static void test_specifier_escape_strv_one(char **a, char **b) { } static void test_specifier_escape_strv(void) { + log_info("/* %s */", __func__); + test_specifier_escape_strv_one(NULL, NULL); test_specifier_escape_strv_one(STRV_MAKE(NULL), STRV_MAKE(NULL)); test_specifier_escape_strv_one(STRV_MAKE(""), STRV_MAKE("")); test_specifier_escape_strv_one(STRV_MAKE("foo"), STRV_MAKE("foo")); test_specifier_escape_strv_one(STRV_MAKE("%"), STRV_MAKE("%%")); - test_specifier_escape_strv_one(STRV_MAKE("foo", "%", "foo%", "%foo", "foo%foo", "quux", "%%%"), STRV_MAKE("foo", "%%", "foo%%", "%%foo", "foo%%foo", "quux", "%%%%%%")); + test_specifier_escape_strv_one(STRV_MAKE("foo", "%", "foo%", "%foo", "foo%foo", "quux", "%%%"), + STRV_MAKE("foo", "%%", "foo%%", "%%foo", "foo%%foo", "quux", "%%%%%%")); +} + +/* Any specifier functions which don't need an argument. */ +static const Specifier specifier_table[] = { + { 'm', specifier_machine_id, NULL }, + { 'b', specifier_boot_id, NULL }, + { 'H', specifier_host_name, NULL }, + { 'l', specifier_short_host_name, NULL }, + { 'v', specifier_kernel_release, NULL }, + { 'a', specifier_architecture, NULL }, + { 'o', specifier_os_id, NULL }, + { 'w', specifier_os_version_id, NULL }, + { 'B', specifier_os_build_id, NULL }, + { 'W', specifier_os_variant_id, NULL }, + + { 'g', specifier_group_name, NULL }, + { 'G', specifier_group_id, NULL }, + { 'U', specifier_user_id, NULL }, + { 'u', specifier_user_name, NULL }, + { 'h', specifier_user_home, NULL }, + + { 'T', specifier_tmp_dir, NULL }, + { 'V', specifier_var_tmp_dir, NULL }, + {} +}; + +static void test_specifiers(void) { + log_info("/* %s */", __func__); + + for (const Specifier *s = specifier_table; s->specifier; s++) { + char spec[3]; + _cleanup_free_ char *resolved = NULL; + + xsprintf(spec, "%%%c", s->specifier); + + assert_se(specifier_printf(spec, specifier_table, NULL, &resolved) >= 0); + + log_info("%%%c → %s", s->specifier, resolved); + } } int main(int argc, char *argv[]) { @@ -44,6 +89,7 @@ int main(int argc, char *argv[]) { test_specifier_escape(); test_specifier_escape_strv(); + test_specifiers(); return 0; }