diff --git a/man/meson.build b/man/meson.build
index 3a7143a4b6..3c2c7023ed 100644
--- a/man/meson.build
+++ b/man/meson.build
@@ -202,11 +202,17 @@ if dbus_docs.length() > 0
custom_target(
'update-dbus-docs',
output : 'update-dbus-docs',
- command : ['python3',
- '@0@/tools/update-dbus-docs.py'.format(project_source_root),
+ command : [update_dbus_docs_py,
'--build-dir=@0@'.format(project_build_root),
'@INPUT@'],
input : dbus_docs)
+
+ if conf.get('DEVELOPER_MODE') == 1
+ test('dbus-docs-fresh',
+ update_dbus_docs_py,
+ args : ['--build-dir=@0@'.format(project_build_root),
+ '--test'] + dbus_docs)
+ endif
endif
############################################################
diff --git a/man/org.freedesktop.systemd1.xml b/man/org.freedesktop.systemd1.xml
index cee79700ef..97629c0470 100644
--- a/man/org.freedesktop.systemd1.xml
+++ b/man/org.freedesktop.systemd1.xml
@@ -2567,6 +2567,10 @@ node /org/freedesktop/systemd1/unit/avahi_2ddaemon_2eservice {
@org.freedesktop.DBus.Property.EmitsChangedSignal("const")
readonly b RemoveIPC = ...;
@org.freedesktop.DBus.Property.EmitsChangedSignal("const")
+ readonly a(say) SetCredential = [...];
+ @org.freedesktop.DBus.Property.EmitsChangedSignal("const")
+ readonly a(ss) LoadCredential = [...];
+ @org.freedesktop.DBus.Property.EmitsChangedSignal("const")
readonly as SupplementaryGroups = ['...', ...];
@org.freedesktop.DBus.Property.EmitsChangedSignal("const")
readonly s PAMName = '...';
@@ -2673,6 +2677,10 @@ node /org/freedesktop/systemd1/unit/avahi_2ddaemon_2eservice {
@org.freedesktop.DBus.Property.EmitsChangedSignal("const")
readonly s KeyringMode = '...';
@org.freedesktop.DBus.Property.EmitsChangedSignal("const")
+ readonly s ProtectProc = '...';
+ @org.freedesktop.DBus.Property.EmitsChangedSignal("const")
+ readonly s ProcSubset = '...';
+ @org.freedesktop.DBus.Property.EmitsChangedSignal("const")
readonly b ProtectHostname = ...;
@org.freedesktop.DBus.Property.EmitsChangedSignal("const")
readonly s NetworkNamespacePath = '...';
@@ -3068,6 +3076,10 @@ node /org/freedesktop/systemd1/unit/avahi_2ddaemon_2eservice {
+
+
+
+
@@ -3172,6 +3184,10 @@ node /org/freedesktop/systemd1/unit/avahi_2ddaemon_2eservice {
+
+
+
+
@@ -3616,6 +3632,10 @@ node /org/freedesktop/systemd1/unit/avahi_2ddaemon_2eservice {
+
+
+
+
@@ -3722,6 +3742,10 @@ node /org/freedesktop/systemd1/unit/avahi_2ddaemon_2eservice {
+
+
+
+
@@ -4236,6 +4260,10 @@ node /org/freedesktop/systemd1/unit/avahi_2ddaemon_2esocket {
@org.freedesktop.DBus.Property.EmitsChangedSignal("const")
readonly b RemoveIPC = ...;
@org.freedesktop.DBus.Property.EmitsChangedSignal("const")
+ readonly a(say) SetCredential = [...];
+ @org.freedesktop.DBus.Property.EmitsChangedSignal("const")
+ readonly a(ss) LoadCredential = [...];
+ @org.freedesktop.DBus.Property.EmitsChangedSignal("const")
readonly as SupplementaryGroups = ['...', ...];
@org.freedesktop.DBus.Property.EmitsChangedSignal("const")
readonly s PAMName = '...';
@@ -4342,6 +4370,10 @@ node /org/freedesktop/systemd1/unit/avahi_2ddaemon_2esocket {
@org.freedesktop.DBus.Property.EmitsChangedSignal("const")
readonly s KeyringMode = '...';
@org.freedesktop.DBus.Property.EmitsChangedSignal("const")
+ readonly s ProtectProc = '...';
+ @org.freedesktop.DBus.Property.EmitsChangedSignal("const")
+ readonly s ProcSubset = '...';
+ @org.freedesktop.DBus.Property.EmitsChangedSignal("const")
readonly b ProtectHostname = ...;
@org.freedesktop.DBus.Property.EmitsChangedSignal("const")
readonly s NetworkNamespacePath = '...';
@@ -4757,6 +4789,10 @@ node /org/freedesktop/systemd1/unit/avahi_2ddaemon_2esocket {
+
+
+
+
@@ -4861,6 +4897,10 @@ node /org/freedesktop/systemd1/unit/avahi_2ddaemon_2esocket {
+
+
+
+
@@ -5303,6 +5343,10 @@ node /org/freedesktop/systemd1/unit/avahi_2ddaemon_2esocket {
+
+
+
+
@@ -5409,6 +5453,10 @@ node /org/freedesktop/systemd1/unit/avahi_2ddaemon_2esocket {
+
+
+
+
@@ -5859,6 +5907,10 @@ node /org/freedesktop/systemd1/unit/home_2emount {
@org.freedesktop.DBus.Property.EmitsChangedSignal("const")
readonly b RemoveIPC = ...;
@org.freedesktop.DBus.Property.EmitsChangedSignal("const")
+ readonly a(say) SetCredential = [...];
+ @org.freedesktop.DBus.Property.EmitsChangedSignal("const")
+ readonly a(ss) LoadCredential = [...];
+ @org.freedesktop.DBus.Property.EmitsChangedSignal("const")
readonly as SupplementaryGroups = ['...', ...];
@org.freedesktop.DBus.Property.EmitsChangedSignal("const")
readonly s PAMName = '...';
@@ -5965,6 +6017,10 @@ node /org/freedesktop/systemd1/unit/home_2emount {
@org.freedesktop.DBus.Property.EmitsChangedSignal("const")
readonly s KeyringMode = '...';
@org.freedesktop.DBus.Property.EmitsChangedSignal("const")
+ readonly s ProtectProc = '...';
+ @org.freedesktop.DBus.Property.EmitsChangedSignal("const")
+ readonly s ProcSubset = '...';
+ @org.freedesktop.DBus.Property.EmitsChangedSignal("const")
readonly b ProtectHostname = ...;
@org.freedesktop.DBus.Property.EmitsChangedSignal("const")
readonly s NetworkNamespacePath = '...';
@@ -6310,6 +6366,10 @@ node /org/freedesktop/systemd1/unit/home_2emount {
+
+
+
+
@@ -6414,6 +6474,10 @@ node /org/freedesktop/systemd1/unit/home_2emount {
+
+
+
+
@@ -6778,6 +6842,10 @@ node /org/freedesktop/systemd1/unit/home_2emount {
+
+
+
+
@@ -6884,6 +6952,10 @@ node /org/freedesktop/systemd1/unit/home_2emount {
+
+
+
+
@@ -7453,6 +7525,10 @@ node /org/freedesktop/systemd1/unit/dev_2dsda3_2eswap {
@org.freedesktop.DBus.Property.EmitsChangedSignal("const")
readonly b RemoveIPC = ...;
@org.freedesktop.DBus.Property.EmitsChangedSignal("const")
+ readonly a(say) SetCredential = [...];
+ @org.freedesktop.DBus.Property.EmitsChangedSignal("const")
+ readonly a(ss) LoadCredential = [...];
+ @org.freedesktop.DBus.Property.EmitsChangedSignal("const")
readonly as SupplementaryGroups = ['...', ...];
@org.freedesktop.DBus.Property.EmitsChangedSignal("const")
readonly s PAMName = '...';
@@ -7559,6 +7635,10 @@ node /org/freedesktop/systemd1/unit/dev_2dsda3_2eswap {
@org.freedesktop.DBus.Property.EmitsChangedSignal("const")
readonly s KeyringMode = '...';
@org.freedesktop.DBus.Property.EmitsChangedSignal("const")
+ readonly s ProtectProc = '...';
+ @org.freedesktop.DBus.Property.EmitsChangedSignal("const")
+ readonly s ProcSubset = '...';
+ @org.freedesktop.DBus.Property.EmitsChangedSignal("const")
readonly b ProtectHostname = ...;
@org.freedesktop.DBus.Property.EmitsChangedSignal("const")
readonly s NetworkNamespacePath = '...';
@@ -7890,6 +7970,10 @@ node /org/freedesktop/systemd1/unit/dev_2dsda3_2eswap {
+
+
+
+
@@ -7994,6 +8078,10 @@ node /org/freedesktop/systemd1/unit/dev_2dsda3_2eswap {
+
+
+
+
@@ -8344,6 +8432,10 @@ node /org/freedesktop/systemd1/unit/dev_2dsda3_2eswap {
+
+
+
+
@@ -8450,6 +8542,10 @@ node /org/freedesktop/systemd1/unit/dev_2dsda3_2eswap {
+
+
+
+
diff --git a/meson.build b/meson.build
index cd2b02488b..6837540313 100644
--- a/meson.build
+++ b/meson.build
@@ -38,6 +38,9 @@ relative_source_path = run_command('realpath',
project_source_root).stdout().strip()
conf.set_quoted('RELATIVE_SOURCE_PATH', relative_source_path)
+conf.set10('DEVELOPER_MODE', get_option('mode') == 'developer',
+ description : 'enable additional checks only suitable in development')
+
want_ossfuzz = get_option('oss-fuzz')
want_libfuzzer = get_option('llvm-fuzz')
if want_ossfuzz + want_libfuzzer > 1
@@ -1634,6 +1637,7 @@ make_directive_index_py = find_program('tools/make-directive-index.py')
make_man_index_py = find_program('tools/make-man-index.py')
syscall_names_update_sh = find_program('tools/syscall-names-update.sh')
xml_helper_py = find_program('tools/xml_helper.py')
+update_dbus_docs_py = find_program('tools/update-dbus-docs.py')
############################################################
diff --git a/meson_options.txt b/meson_options.txt
index fd73d5e681..1ad0969a1a 100644
--- a/meson_options.txt
+++ b/meson_options.txt
@@ -4,6 +4,9 @@
option('version-tag', type : 'string',
description : 'override the git version string')
+option('mode', type : 'combo', choices : ['default', 'developer'],
+ description : 'enable additional checks suitable for systemd development')
+
option('split-usr', type : 'combo', choices : ['auto', 'true', 'false'],
description : '''/bin, /sbin aren't symlinks into /usr''')
option('split-bin', type : 'combo', choices : ['auto', 'true', 'false'],
diff --git a/src/basic/missing_capability.h b/src/basic/missing_capability.h
index b31e736390..c52cd44933 100644
--- a/src/basic/missing_capability.h
+++ b/src/basic/missing_capability.h
@@ -5,32 +5,35 @@
/* 3a101b8de0d39403b2c7e5c23fd0b005668acf48 (3.16) */
#ifndef CAP_AUDIT_READ
-#define CAP_AUDIT_READ 37
-
-#undef CAP_LAST_CAP
-#define CAP_LAST_CAP CAP_AUDIT_READ
+# define CAP_AUDIT_READ 37
#endif
/* 980737282232b752bb14dab96d77665c15889c36 (5.8) */
#ifndef CAP_PERFMON
-#define CAP_PERFMON 38
-
-#undef CAP_LAST_CAP
-#define CAP_LAST_CAP CAP_PERFMON
+# define CAP_PERFMON 38
#endif
/* a17b53c4a4b55ec322c132b6670743612229ee9c (5.8) */
#ifndef CAP_BPF
-#define CAP_BPF 39
-
-#undef CAP_LAST_CAP
-#define CAP_LAST_CAP CAP_BPF
+# define CAP_BPF 39
#endif
/* 124ea650d3072b005457faed69909221c2905a1f (5.9) */
#ifndef CAP_CHECKPOINT_RESTORE
-#define CAP_CHECKPOINT_RESTORE 40
-
-#undef CAP_LAST_CAP
-#define CAP_LAST_CAP CAP_CHECKPOINT_RESTORE
+# define CAP_CHECKPOINT_RESTORE 40
+#endif
+
+#define SYSTEMD_CAP_LAST_CAP CAP_CHECKPOINT_RESTORE
+
+#ifdef CAP_LAST_CAP
+# if CAP_LAST_CAP > SYSTEMD_CAP_LAST_CAP
+# if DEVELOPER_MODE && defined(TEST_CAPABILITY_C)
+# warning "The capability list here is outdated"
+# endif
+# else
+# undef CAP_LAST_CAP
+# endif
+#endif
+#ifndef CAP_LAST_CAP
+# define CAP_LAST_CAP SYSTEMD_CAP_LAST_CAP
#endif
diff --git a/src/test/test-capability.c b/src/test/test-capability.c
index 249323f8cf..2d47c77f46 100644
--- a/src/test/test-capability.c
+++ b/src/test/test-capability.c
@@ -7,6 +7,8 @@
#include
#include
+#define TEST_CAPABILITY_C
+
#include "alloc-util.h"
#include "capability-util.h"
#include "errno-util.h"
diff --git a/src/test/test-path.c b/src/test/test-path.c
index 1075f31bc6..cf89d89482 100644
--- a/src/test/test-path.c
+++ b/src/test/test-path.c
@@ -350,7 +350,7 @@ int main(int argc, char *argv[]) {
assert_se(set_unit_path(test_path) >= 0);
assert_se(runtime_dir = setup_fake_runtime_dir());
- for (const test_function_t *test = tests; test && *test; test++) {
+ for (const test_function_t *test = tests; *test; test++) {
Manager *m = NULL;
int r;
diff --git a/tools/update-dbus-docs.py b/tools/update-dbus-docs.py
index f95faaaf22..3500d9ce5e 100755
--- a/tools/update-dbus-docs.py
+++ b/tools/update-dbus-docs.py
@@ -1,6 +1,7 @@
#!/usr/bin/env python3
# SPDX-License-Identifier: LGPL-2.1+
+import argparse
import collections
import sys
import os
@@ -14,8 +15,6 @@ PARSER = etree.XMLParser(no_network=True,
strip_cdata=False,
resolve_entities=False)
-PRINT_ERRORS = True
-
class NoCommand(Exception):
pass
@@ -37,7 +36,7 @@ def print_method(declarations, elem, *, prefix, file, is_signal=False):
argname = arg.get('name')
if argname is None:
- if PRINT_ERRORS:
+ if opts.print_errors:
print(f'method {name}: argument {num+1} has no name', file=sys.stderr)
argname = 'UNNAMED'
@@ -120,9 +119,11 @@ def document_has_elem_with_text(document, elem, item_repr):
else:
return False
-def check_documented(document, declarations):
+def check_documented(document, declarations, stats):
missing = []
for klass, items in declarations.items():
+ stats['total'] += len(items)
+
for item in items:
if klass == 'method':
elem = 'function'
@@ -137,10 +138,12 @@ def check_documented(document, declarations):
assert False, (klass, item)
if not document_has_elem_with_text(document, elem, item_repr):
- if PRINT_ERRORS:
+ if opts.print_errors:
print(f'{klass} {item} is not documented :(')
missing.append((klass, item))
+ stats['missing'] += len(missing)
+
return missing
def xml_to_text(destination, xml, *, only_interface=None):
@@ -165,7 +168,7 @@ def xml_to_text(destination, xml, *, only_interface=None):
return file.getvalue(), declarations, interfaces
-def subst_output(document, programlisting):
+def subst_output(document, programlisting, stats):
executable = programlisting.get('executable', None)
if executable is None:
# Not our thing
@@ -174,7 +177,7 @@ def subst_output(document, programlisting):
node = programlisting.get('node')
interface = programlisting.get('interface')
- argv = [f'{build_dir}/{executable}', f'--bus-introspect={interface}']
+ argv = [f'{opts.build_dir}/{executable}', f'--bus-introspect={interface}']
print(f'COMMAND: {shlex.join(argv)}')
try:
@@ -189,7 +192,7 @@ def subst_output(document, programlisting):
programlisting.text = '\n' + new_text + ' '
if declarations:
- missing = check_documented(document, declarations)
+ missing = check_documented(document, declarations, stats)
parent = programlisting.getparent()
# delete old comments
@@ -253,9 +256,11 @@ def process(page):
if xml.tag != 'refentry':
return
+ stats = collections.Counter()
+
pls = xml.findall('.//programlisting')
for pl in pls:
- subst_output(xml, pl)
+ subst_output(xml, pl, stats)
out_text = etree.tostring(xml, encoding='unicode')
# massage format to avoid some lxml whitespace handling idiosyncrasies
@@ -264,20 +269,44 @@ def process(page):
out_text[out_text.find('