From 691abc5ea83c79ca27cda5a6f15ab151fef424c8 Mon Sep 17 00:00:00 2001 From: Daan De Meyer Date: Thu, 15 May 2025 13:23:54 +0200 Subject: [PATCH 1/8] journal-remote: Allow building without microhttpd support systemd-journal-remote is useful even if the microhttpd related features are not enabled so let's not skip it entirely if microhttpd is not available. --- meson.build | 20 ++++++++++---------- src/journal-remote/journal-remote-main.c | 19 +++++++++++++++++++ src/journal-remote/meson.build | 2 -- src/journal-remote/microhttpd-util.c | 4 ++++ src/journal-remote/microhttpd-util.h | 4 ++++ 5 files changed, 37 insertions(+), 12 deletions(-) diff --git a/meson.build b/meson.build index 81e494ee04..83442da079 100644 --- a/meson.build +++ b/meson.build @@ -1569,17 +1569,17 @@ have = have and conf.get('HAVE_PAM') == 1 conf.set10('ENABLE_PAM_HOME', have) feature = get_option('remote') -have_deps = [conf.get('HAVE_MICROHTTPD') == 1, - conf.get('HAVE_LIBCURL') == 1] -# sd-j-remote requires µhttpd, and sd-j-upload requires libcurl, so -# it's possible to build one without the other. Complain only if -# support was explicitly requested. The auxiliary files like sysusers -# config should be installed when any of the programs are built. -if feature.enabled() and not (have_deps[0] and have_deps[1]) - error('remote support was requested, but dependencies are not available') +if feature.enabled() + if conf.get('HAVE_MICROHTTPD') != 1 + error('remote support was requested, but microhttpd is not available') + endif + if conf.get('HAVE_LIBCURL') != 1 + error('remote support was requested, but libcurl is not available') + endif endif -have = feature.allowed() and (have_deps[0] or have_deps[1]) -conf.set10('ENABLE_REMOTE', have) +# A more minimal version of systemd-journal-remote can always be built, even if neither +# libcurl nor microhttpd are available. +conf.set10('ENABLE_REMOTE', feature.allowed()) feature = get_option('vmspawn').disable_auto_if(conf.get('BUILD_MODE_DEVELOPER') == 0) conf.set10('ENABLE_VMSPAWN', feature.allowed()) diff --git a/src/journal-remote/journal-remote-main.c b/src/journal-remote/journal-remote-main.c index e5ede19e03..2eb1e07f0e 100644 --- a/src/journal-remote/journal-remote-main.c +++ b/src/journal-remote/journal-remote-main.c @@ -86,6 +86,8 @@ static const char* const journal_write_split_mode_table[_JOURNAL_WRITE_SPLIT_MAX DEFINE_PRIVATE_STRING_TABLE_LOOKUP(journal_write_split_mode, JournalWriteSplitMode); static DEFINE_CONFIG_PARSE_ENUM(config_parse_write_split_mode, journal_write_split_mode, JournalWriteSplitMode); +#if HAVE_MICROHTTPD + typedef struct MHDDaemonWrapper { uint64_t fd; struct MHD_Daemon *daemon; @@ -114,6 +116,8 @@ DEFINE_PRIVATE_HASH_OPS_WITH_VALUE_DESTRUCTOR( uint64_t, uint64_hash_func, uint64_compare_func, MHDDaemonWrapper, MHDDaemonWrapper_free); +#endif + /********************************************************************** ********************************************************************** **********************************************************************/ @@ -184,6 +188,8 @@ static int spawn_getter(const char *getter) { ********************************************************************** **********************************************************************/ +#if HAVE_MICROHTTPD + static int null_timer_event_handler(sd_event_source *s, uint64_t usec, void *userdata); @@ -449,11 +455,15 @@ static mhd_result request_handler( return MHD_YES; } +#endif + static int setup_microhttpd_server(RemoteServer *s, int fd, const char *key, const char *cert, const char *trust) { + +#if HAVE_MICROHTTPD struct MHD_OptionItem opts[] = { { MHD_OPTION_EXTERNAL_LOGGER, (intptr_t) microhttpd_logger}, { MHD_OPTION_NOTIFY_COMPLETED, (intptr_t) request_meta_free}, @@ -564,6 +574,9 @@ static int setup_microhttpd_server(RemoteServer *s, TAKE_PTR(d); s->active++; return 0; +#else + return log_error_errno(SYNTHETIC_ERRNO(EOPNOTSUPP), "microhttpd support not compiled in"); +#endif } static int setup_microhttpd_socket(RemoteServer *s, @@ -580,6 +593,8 @@ static int setup_microhttpd_socket(RemoteServer *s, return setup_microhttpd_server(s, fd, key, cert, trust); } +#if HAVE_MICROHTTPD + static int null_timer_event_handler(sd_event_source *timer_event, uint64_t usec, void *userdata) { @@ -615,6 +630,8 @@ static int dispatch_http_event(sd_event_source *event, return 1; /* work to do */ } +#endif + /********************************************************************** ********************************************************************** **********************************************************************/ @@ -1149,11 +1166,13 @@ static int run(int argc, char **argv) { journal_browse_prepare(); +#if HAVE_MICROHTTPD if (arg_listen_http || arg_listen_https) { r = setup_gnutls_logger(arg_gnutls_log); if (r < 0) return r; } +#endif if (arg_listen_https || https_socket >= 0) { r = load_certificates(&key, &cert, &trust); diff --git a/src/journal-remote/meson.build b/src/journal-remote/meson.build index 7916e9b313..64cccd2355 100644 --- a/src/journal-remote/meson.build +++ b/src/journal-remote/meson.build @@ -52,7 +52,6 @@ executables += [ libexec_template + { 'name' : 'systemd-journal-remote', 'public' : true, - 'conditions' : ['HAVE_MICROHTTPD'], 'sources' : [systemd_journal_remote_sources, systemd_journal_remote_extract_sources], 'extract' : systemd_journal_remote_extract_sources, 'dependencies' : common_deps + [libmicrohttpd], @@ -71,7 +70,6 @@ executables += [ }, fuzz_template + { 'sources' : files('fuzz-journal-remote.c'), - 'conditions' : ['HAVE_MICROHTTPD'], 'objects' : ['systemd-journal-remote'], 'dependencies' : common_deps + [libmicrohttpd], }, diff --git a/src/journal-remote/microhttpd-util.c b/src/journal-remote/microhttpd-util.c index 9f68cc65ca..4bf52ad200 100644 --- a/src/journal-remote/microhttpd-util.c +++ b/src/journal-remote/microhttpd-util.c @@ -15,6 +15,8 @@ #include "string-util.h" #include "strv.h" +#if HAVE_MICROHTTPD + void microhttpd_logger(void *arg, const char *fmt, va_list ap) { char *f; @@ -297,3 +299,5 @@ int setup_gnutls_logger(char **categories) { return 0; } #endif + +#endif diff --git a/src/journal-remote/microhttpd-util.h b/src/journal-remote/microhttpd-util.h index 57396ad9b6..ba466edcd6 100644 --- a/src/journal-remote/microhttpd-util.h +++ b/src/journal-remote/microhttpd-util.h @@ -1,6 +1,8 @@ /* SPDX-License-Identifier: LGPL-2.1-or-later */ #pragma once +#if HAVE_MICROHTTPD + #include #include @@ -108,3 +110,5 @@ int setup_gnutls_logger(char **categories); DEFINE_TRIVIAL_CLEANUP_FUNC_FULL(struct MHD_Daemon*, MHD_stop_daemon, NULL); DEFINE_TRIVIAL_CLEANUP_FUNC_FULL(struct MHD_Response*, MHD_destroy_response, NULL); + +#endif From a583b344161b03352762d23c90ef0ab93620d393 Mon Sep 17 00:00:00 2001 From: Daan De Meyer Date: Thu, 15 May 2025 14:16:57 +0200 Subject: [PATCH 2/8] meson: Extract more objects instead of compiling multiple times Also, let's deflatten the lists of sources in preparation for the next commit at the same time. In systemctl, we split out systemctl-main.c to make sure the definition of main() is in a separate object which allows us to extract the systemctl.c object and link it in the fuzzer target without getting a multiple definition error when linking. --- src/analyze/meson.build | 2 +- src/busctl/meson.build | 2 +- src/coredump/meson.build | 2 +- src/hibernate-resume/meson.build | 13 +- src/home/meson.build | 2 +- src/import/meson.build | 2 +- src/integritysetup/meson.build | 7 +- src/journal-remote/meson.build | 48 ++--- src/journal/meson.build | 2 +- src/libsystemd-network/meson.build | 13 +- src/locale/meson.build | 2 +- src/login/meson.build | 2 +- src/machine/meson.build | 2 +- src/network/meson.build | 2 +- src/nspawn/meson.build | 3 +- src/nsresourced/meson.build | 2 +- src/oom/meson.build | 2 +- src/resolve/meson.build | 2 +- src/shutdown/meson.build | 4 +- src/sleep/meson.build | 2 +- src/systemctl/meson.build | 31 +-- src/systemctl/systemctl-main.c | 267 ++++++++++++++++++++++++ src/systemctl/systemctl.c | 234 --------------------- src/systemctl/systemctl.h | 1 + src/sysupdate/meson.build | 10 +- src/test/meson.build | 7 +- src/timesync/meson.build | 2 +- src/tmpfiles/meson.build | 4 +- src/udev/meson.build | 8 +- src/vmspawn/meson.build | 2 +- src/xdg-autostart-generator/meson.build | 6 +- 31 files changed, 356 insertions(+), 332 deletions(-) create mode 100644 src/systemctl/systemctl-main.c diff --git a/src/analyze/meson.build b/src/analyze/meson.build index b84d064d33..7d437953d9 100644 --- a/src/analyze/meson.build +++ b/src/analyze/meson.build @@ -44,7 +44,7 @@ executables += [ executable_template + { 'name' : 'systemd-analyze', 'public' : conf.get('ENABLE_ANALYZE') == 1, - 'sources' : [systemd_analyze_sources, systemd_analyze_extract_sources], + 'sources' : systemd_analyze_sources + systemd_analyze_extract_sources, 'extract' : systemd_analyze_extract_sources, 'include_directories' : core_includes, 'link_with' : [ diff --git a/src/busctl/meson.build b/src/busctl/meson.build index 8c8e110360..e47531cf02 100644 --- a/src/busctl/meson.build +++ b/src/busctl/meson.build @@ -11,7 +11,7 @@ executables += [ executable_template + { 'name' : 'busctl', 'public' : true, - 'sources' : [busctl_sources, busctl_extract_sources], + 'sources' : busctl_sources + busctl_extract_sources, 'extract' : busctl_extract_sources, }, test_template + { diff --git a/src/coredump/meson.build b/src/coredump/meson.build index e1667e19a9..1896d22c25 100644 --- a/src/coredump/meson.build +++ b/src/coredump/meson.build @@ -21,7 +21,7 @@ common_dependencies = [ executables += [ libexec_template + { 'name' : 'systemd-coredump', - 'sources' : [systemd_coredump_sources, systemd_coredump_extract_sources], + 'sources' : systemd_coredump_sources + systemd_coredump_extract_sources, 'extract' : systemd_coredump_extract_sources, 'link_with' : [libshared], 'dependencies' : common_dependencies + [libacl], diff --git a/src/hibernate-resume/meson.build b/src/hibernate-resume/meson.build index ce3430d2c3..0aa085a806 100644 --- a/src/hibernate-resume/meson.build +++ b/src/hibernate-resume/meson.build @@ -5,18 +5,17 @@ if conf.get('ENABLE_HIBERNATE') != 1 endif executables += [ - generator_template + { - 'name' : 'systemd-hibernate-resume-generator', - 'sources' : files( - 'hibernate-resume-generator.c', - 'hibernate-resume-config.c', - ), - }, libexec_template + { 'name' : 'systemd-hibernate-resume', 'sources' : files( 'hibernate-resume.c', 'hibernate-resume-config.c', ), + 'extract' : files('hibernate-resume-config.c'), + }, + generator_template + { + 'name' : 'systemd-hibernate-resume-generator', + 'sources' : files('hibernate-resume-generator.c'), + 'objects' : ['systemd-hibernate-resume'], }, ] diff --git a/src/home/meson.build b/src/home/meson.build index acbefef054..10e794bd70 100644 --- a/src/home/meson.build +++ b/src/home/meson.build @@ -67,7 +67,7 @@ executables += [ libexec_template + { 'name' : 'systemd-homed', 'dbus' : true, - 'sources' : [systemd_homed_sources, systemd_homed_extract_sources], + 'sources' : systemd_homed_sources + systemd_homed_extract_sources, 'include_directories' : includes + include_directories('.'), 'extract' : systemd_homed_extract_sources, diff --git a/src/import/meson.build b/src/import/meson.build index 65e1ff2e12..a2bb54992b 100644 --- a/src/import/meson.build +++ b/src/import/meson.build @@ -50,7 +50,7 @@ executables += [ libexec_template + { 'name' : 'systemd-importd', 'dbus' : true, - 'sources' : [systemd_importd_sources, systemd_importd_extract_sources], + 'sources' : systemd_importd_sources + systemd_importd_extract_sources, 'extract' : systemd_importd_extract_sources, 'dependencies' : [common_deps, threads], }, diff --git a/src/integritysetup/meson.build b/src/integritysetup/meson.build index d72474a2a2..a81c17e845 100644 --- a/src/integritysetup/meson.build +++ b/src/integritysetup/meson.build @@ -11,13 +11,12 @@ executables += [ 'integrity-util.c', 'integritysetup.c', ), + 'extract' : files('integrity-util.c'), 'dependencies' : libcryptsetup, }, generator_template + { 'name' : 'systemd-integritysetup-generator', - 'sources' : files( - 'integrity-util.c', - 'integritysetup-generator.c', - ), + 'sources' : files('integritysetup-generator.c'), + 'objects' : ['systemd-integritysetup'], }, ] diff --git a/src/journal-remote/meson.build b/src/journal-remote/meson.build index 64cccd2355..04b0f6e881 100644 --- a/src/journal-remote/meson.build +++ b/src/journal-remote/meson.build @@ -4,13 +4,11 @@ if conf.get('ENABLE_REMOTE') != 1 subdir_done() endif -systemd_journal_upload_sources = files( - 'journal-compression-util.c', - 'journal-upload-journal.c', - 'journal-upload.c', +systemd_journal_gatewayd_sources = files( + 'journal-gatewayd.c', ) -systemd_journal_upload_extract_sources = files( - 'journal-header-util.c', +systemd_journal_gatewayd_extract_sources = files( + 'microhttpd-util.c', ) systemd_journal_remote_sources = files('journal-remote-main.c') @@ -21,15 +19,12 @@ systemd_journal_remote_extract_sources = files( 'journal-remote.c', ) -if conf.get('HAVE_MICROHTTPD') == 1 - systemd_journal_remote_extract_sources += files( - 'microhttpd-util.c', - ) -endif - -systemd_journal_gatewayd_sources = files( - 'journal-gatewayd.c', - 'microhttpd-util.c', +systemd_journal_upload_sources = files( + 'journal-upload-journal.c', + 'journal-upload.c', +) +systemd_journal_upload_extract_sources = files( + 'journal-header-util.c', ) common_deps = [ @@ -42,26 +37,29 @@ common_deps = [ executables += [ libexec_template + { - 'name' : 'systemd-journal-upload', + 'name' : 'systemd-journal-gatewayd', 'public' : true, - 'conditions' : ['HAVE_LIBCURL'], - 'sources' : [systemd_journal_upload_sources, systemd_journal_upload_extract_sources], - 'extract' : systemd_journal_upload_extract_sources, - 'dependencies' : common_deps + [libcurl], + 'conditions' : ['HAVE_MICROHTTPD'], + 'sources' : systemd_journal_gatewayd_sources + systemd_journal_gatewayd_extract_sources, + 'extract' : systemd_journal_gatewayd_extract_sources, + 'dependencies' : common_deps + [libmicrohttpd], }, libexec_template + { 'name' : 'systemd-journal-remote', 'public' : true, - 'sources' : [systemd_journal_remote_sources, systemd_journal_remote_extract_sources], + 'sources' : systemd_journal_remote_sources + systemd_journal_remote_extract_sources, + 'objects' : conf.get('HAVE_MICROHTTPD') == 1 ? ['systemd-journal-gatewayd'] : [], 'extract' : systemd_journal_remote_extract_sources, 'dependencies' : common_deps + [libmicrohttpd], }, libexec_template + { - 'name' : 'systemd-journal-gatewayd', + 'name' : 'systemd-journal-upload', 'public' : true, - 'conditions' : ['HAVE_MICROHTTPD'], - 'sources' : systemd_journal_gatewayd_sources, - 'dependencies' : common_deps + [libmicrohttpd], + 'conditions' : ['HAVE_LIBCURL'], + 'sources' : systemd_journal_upload_sources + systemd_journal_upload_extract_sources, + 'objects' : ['systemd-journal-remote'], + 'extract' : systemd_journal_upload_extract_sources, + 'dependencies' : common_deps + [libcurl], }, test_template + { 'sources' : files('test-journal-header-util.c'), diff --git a/src/journal/meson.build b/src/journal/meson.build index d0122c8495..cbce43fc54 100644 --- a/src/journal/meson.build +++ b/src/journal/meson.build @@ -64,7 +64,7 @@ journal_fuzz_template = fuzz_template + { executables += [ libexec_template + { 'name' : 'systemd-journald', - 'sources' : [systemd_journald_sources, systemd_journald_extract_sources], + 'sources' : systemd_journald_sources + systemd_journald_extract_sources, 'include_directories' : [libexec_template['include_directories'], include_directories('.')], 'extract' : systemd_journald_extract_sources, 'dependencies' : [ diff --git a/src/libsystemd-network/meson.build b/src/libsystemd-network/meson.build index 333b3e0541..a6de329627 100644 --- a/src/libsystemd-network/meson.build +++ b/src/libsystemd-network/meson.build @@ -95,12 +95,11 @@ executables += [ 'test-ndisc-ra.c', 'icmp6-test-util.c', ), + 'extract' : files('icmp6-test-util.c'), }, network_test_template + { - 'sources' : files( - 'test-ndisc-rs.c', - 'icmp6-test-util.c', - ), + 'sources' : files('test-ndisc-rs.c'), + 'objects' : ['test-ndisc-ra'], }, network_test_template + { 'sources' : files('test-ndisc-send.c'), @@ -125,9 +124,7 @@ executables += [ 'sources' : files('fuzz-lldp-rx.c'), }, network_fuzz_template + { - 'sources' : files( - 'fuzz-ndisc-rs.c', - 'icmp6-test-util.c', - ), + 'sources' : files('fuzz-ndisc-rs.c'), + 'objects' : ['test-ndisc-ra'], }, ] diff --git a/src/locale/meson.build b/src/locale/meson.build index e9c61f49b3..c417591680 100644 --- a/src/locale/meson.build +++ b/src/locale/meson.build @@ -29,7 +29,7 @@ executables += [ libexec_template + { 'name' : 'systemd-localed', 'dbus' : true, - 'sources' : [systemd_localed_sources, systemd_localed_extract_sources], + 'sources' : systemd_localed_sources + systemd_localed_extract_sources, 'extract' : systemd_localed_extract_sources, 'dependencies' : libxkbcommon_deps, }, diff --git a/src/login/meson.build b/src/login/meson.build index 99096c4c29..8e3212a0f6 100644 --- a/src/login/meson.build +++ b/src/login/meson.build @@ -46,7 +46,7 @@ executables += [ libexec_template + { 'name' : 'systemd-logind', 'dbus' : true, - 'sources' : [systemd_logind_sources, systemd_logind_extract_sources], + 'sources' : systemd_logind_sources + systemd_logind_extract_sources, 'include_directories' : [libexec_template['include_directories'], include_directories('.')], 'extract' : systemd_logind_extract_sources, 'dependencies' : [ diff --git a/src/machine/meson.build b/src/machine/meson.build index 19ab1fa8f7..9370077fdc 100644 --- a/src/machine/meson.build +++ b/src/machine/meson.build @@ -24,7 +24,7 @@ executables += [ libexec_template + { 'name' : 'systemd-machined', 'dbus' : true, - 'sources' : [systemd_machined_sources, systemd_machined_extract_sources], + 'sources' : systemd_machined_sources + systemd_machined_extract_sources, 'extract' : systemd_machined_extract_sources, }, executable_template + { diff --git a/src/network/meson.build b/src/network/meson.build index 990dac2283..97191fb171 100644 --- a/src/network/meson.build +++ b/src/network/meson.build @@ -200,7 +200,7 @@ executables += [ 'name' : 'systemd-networkd', 'dbus' : true, 'conditions' : ['ENABLE_NETWORKD'], - 'sources' : [systemd_networkd_sources, systemd_networkd_extract_sources], + 'sources' : systemd_networkd_sources + systemd_networkd_extract_sources, 'extract' : systemd_networkd_extract_sources, 'include_directories' : network_includes, 'link_with' : [ diff --git a/src/nspawn/meson.build b/src/nspawn/meson.build index b59017c15e..29fec248df 100644 --- a/src/nspawn/meson.build +++ b/src/nspawn/meson.build @@ -8,7 +8,6 @@ nspawn_sources = files( 'nspawn.c', 'nspawn-bind-user.c', 'nspawn-cgroup.c', - 'nspawn-network.c', 'nspawn-register.c', 'nspawn-seccomp.c', 'nspawn-setuid.c', @@ -42,7 +41,7 @@ executables += [ executable_template + { 'name' : 'systemd-nspawn', 'public' : true, - 'sources' : [nspawn_sources, nspawn_extract_sources], + 'sources' : nspawn_sources + nspawn_extract_sources, 'include_directories' : [ executable_template['include_directories'], include_directories('.') diff --git a/src/nsresourced/meson.build b/src/nsresourced/meson.build index 85ebf6a021..805a4788d0 100644 --- a/src/nsresourced/meson.build +++ b/src/nsresourced/meson.build @@ -30,7 +30,7 @@ endif executables += [ libexec_template + { 'name' : 'systemd-nsresourced', - 'sources' : [systemd_nsresourced_sources, systemd_nsresourced_extract_sources], + 'sources' : systemd_nsresourced_sources + systemd_nsresourced_extract_sources, 'include_directories' : [libexec_template['include_directories'], include_directories('.')], 'extract' : systemd_nsresourced_extract_sources, 'dependencies' : threads, diff --git a/src/oom/meson.build b/src/oom/meson.build index 1d0880e3f2..f462169e71 100644 --- a/src/oom/meson.build +++ b/src/oom/meson.build @@ -18,7 +18,7 @@ executables += [ libexec_template + { 'name' : 'systemd-oomd', 'dbus' : true, - 'sources' : [systemd_oomd_sources, systemd_oomd_extract_sources], + 'sources' : systemd_oomd_sources + systemd_oomd_extract_sources, 'extract' : systemd_oomd_extract_sources, 'dependencies' : libatomic, }, diff --git a/src/resolve/meson.build b/src/resolve/meson.build index 57edb6508f..2c20a8299d 100644 --- a/src/resolve/meson.build +++ b/src/resolve/meson.build @@ -114,7 +114,7 @@ executables += [ libexec_template + resolve_common_template + { 'name' : 'systemd-resolved', 'dbus' : true, - 'sources' : [systemd_resolved_sources, systemd_resolved_extract_sources], + 'sources' : systemd_resolved_sources + systemd_resolved_extract_sources, 'include_directories' : [libexec_template['include_directories'], include_directories('.')], 'extract' : systemd_resolved_extract_sources, }, diff --git a/src/shutdown/meson.build b/src/shutdown/meson.build index 5fc896c000..c91253ca8e 100644 --- a/src/shutdown/meson.build +++ b/src/shutdown/meson.build @@ -14,13 +14,13 @@ systemd_shutdown_extract_sources = files( executables += [ libexec_template + { 'name' : 'systemd-shutdown', - 'sources' : [systemd_shutdown_sources, systemd_shutdown_extract_sources], + 'sources' : systemd_shutdown_sources + systemd_shutdown_extract_sources, 'extract' : systemd_shutdown_extract_sources, 'dependencies' : libmount, }, libexec_template + { 'name' : 'systemd-shutdown.standalone', - 'sources' : [systemd_shutdown_sources, systemd_shutdown_extract_sources], + 'sources' : systemd_shutdown_sources + systemd_shutdown_extract_sources, 'c_args' : '-DSTANDALONE', 'link_with' : [ libbasic_static, diff --git a/src/sleep/meson.build b/src/sleep/meson.build index 03fc9f1ab5..f17c778fe2 100644 --- a/src/sleep/meson.build +++ b/src/sleep/meson.build @@ -10,7 +10,7 @@ sleep_extract_sources = files( executables += [ libexec_template + { 'name' : 'systemd-sleep', - 'sources' : [sleep_sources, sleep_extract_sources], + 'sources' : sleep_sources + sleep_extract_sources, 'include_directories' : [libexec_template['include_directories'], include_directories('.')], 'extract' : sleep_extract_sources, }, diff --git a/src/systemctl/meson.build b/src/systemctl/meson.build index bdeda919fd..4cff1f31de 100644 --- a/src/systemctl/meson.build +++ b/src/systemctl/meson.build @@ -4,11 +4,6 @@ systemctl_sources = files( 'systemctl-add-dependency.c', 'systemctl-cancel-job.c', 'systemctl-clean-or-freeze.c', - 'systemctl-compat-halt.c', - 'systemctl-compat-runlevel.c', - 'systemctl-compat-shutdown.c', - 'systemctl-compat-telinit.c', - 'systemctl-daemon-reload.c', 'systemctl-edit.c', 'systemctl-enable.c', 'systemctl-is-active.c', @@ -21,7 +16,7 @@ systemctl_sources = files( 'systemctl-list-unit-files.c', 'systemctl-list-units.c', 'systemctl-log-setting.c', - 'systemctl-logind.c', + 'systemctl-main.c', 'systemctl-mount.c', 'systemctl-preset-all.c', 'systemctl-reset-failed.c', @@ -31,12 +26,20 @@ systemctl_sources = files( 'systemctl-set-property.c', 'systemctl-show.c', 'systemctl-start-special.c', - 'systemctl-start-unit.c', 'systemctl-switch-root.c', - 'systemctl-sysv-compat.c', 'systemctl-trivial-method.c', - 'systemctl-util.c', 'systemctl-whoami.c', +) +systemctl_extract_sources = files( + 'systemctl-compat-halt.c', + 'systemctl-compat-runlevel.c', + 'systemctl-compat-shutdown.c', + 'systemctl-compat-telinit.c', + 'systemctl-daemon-reload.c', + 'systemctl-logind.c', + 'systemctl-start-unit.c', + 'systemctl-sysv-compat.c', + 'systemctl-util.c', 'systemctl.c', ) @@ -51,7 +54,8 @@ executables += [ executable_template + { 'name' : 'systemctl', 'public' : true, - 'sources' : systemctl_sources, + 'sources' : systemctl_sources + systemctl_extract_sources, + 'extract' : systemctl_extract_sources, 'link_with' : systemctl_link_with, 'dependencies' : [ libcap, @@ -64,12 +68,9 @@ executables += [ 'install_tag' : 'systemctl', }, fuzz_template + { - 'sources' : [ - files('fuzz-systemctl-parse-argv.c'), - systemctl_sources, - ], + 'sources' : files('fuzz-systemctl-parse-argv.c'), + 'objects' : ['systemctl'], 'link_with' : systemctl_link_with, - 'c_args' : ['-DFUZZ_SYSTEMCTL_PARSE_ARGV'], }, ] diff --git a/src/systemctl/systemctl-main.c b/src/systemctl/systemctl-main.c new file mode 100644 index 0000000000..48c083e5e5 --- /dev/null +++ b/src/systemctl/systemctl-main.c @@ -0,0 +1,267 @@ +/* SPDX-License-Identifier: LGPL-2.1-or-later */ + +#include +#include +#include + +#include "dissect-image.h" +#include "glyph-util.h" +#include "log.h" +#include "logs-show.h" +#include "loop-util.h" +#include "main-func.h" +#include "mount-util.h" +#include "stat-util.h" +#include "systemctl.h" +#include "systemctl-add-dependency.h" +#include "systemctl-cancel-job.h" +#include "systemctl-clean-or-freeze.h" +#include "systemctl-compat-halt.h" +#include "systemctl-compat-runlevel.h" +#include "systemctl-compat-telinit.h" +#include "systemctl-daemon-reload.h" +#include "systemctl-edit.h" +#include "systemctl-enable.h" +#include "systemctl-is-active.h" +#include "systemctl-is-enabled.h" +#include "systemctl-is-system-running.h" +#include "systemctl-kill.h" +#include "systemctl-list-dependencies.h" +#include "systemctl-list-jobs.h" +#include "systemctl-list-machines.h" +#include "systemctl-list-unit-files.h" +#include "systemctl-list-units.h" +#include "systemctl-log-setting.h" +#include "systemctl-logind.h" +#include "systemctl-mount.h" +#include "systemctl-preset-all.h" +#include "systemctl-reset-failed.h" +#include "systemctl-service-watchdogs.h" +#include "systemctl-set-default.h" +#include "systemctl-set-environment.h" +#include "systemctl-set-property.h" +#include "systemctl-show.h" +#include "systemctl-start-special.h" +#include "systemctl-start-unit.h" +#include "systemctl-switch-root.h" +#include "systemctl-trivial-method.h" +#include "systemctl-util.h" +#include "systemctl-whoami.h" +#include "verbs.h" +#include "virt.h" + +static int systemctl_main(int argc, char *argv[]) { + static const Verb verbs[] = { + { "list-units", VERB_ANY, VERB_ANY, VERB_DEFAULT|VERB_ONLINE_ONLY, verb_list_units }, + { "list-unit-files", VERB_ANY, VERB_ANY, 0, verb_list_unit_files }, + { "list-automounts", VERB_ANY, VERB_ANY, VERB_ONLINE_ONLY, verb_list_automounts }, + { "list-paths", VERB_ANY, VERB_ANY, VERB_ONLINE_ONLY, verb_list_paths }, + { "list-sockets", VERB_ANY, VERB_ANY, VERB_ONLINE_ONLY, verb_list_sockets }, + { "list-timers", VERB_ANY, VERB_ANY, VERB_ONLINE_ONLY, verb_list_timers }, + { "list-jobs", VERB_ANY, VERB_ANY, VERB_ONLINE_ONLY, verb_list_jobs }, + { "list-machines", VERB_ANY, VERB_ANY, VERB_ONLINE_ONLY, verb_list_machines }, + { "clear-jobs", VERB_ANY, 1, VERB_ONLINE_ONLY, verb_trivial_method }, + { "cancel", VERB_ANY, VERB_ANY, VERB_ONLINE_ONLY, verb_cancel }, + { "start", 2, VERB_ANY, VERB_ONLINE_ONLY, verb_start }, + { "stop", 2, VERB_ANY, VERB_ONLINE_ONLY, verb_start }, + { "condstop", 2, VERB_ANY, VERB_ONLINE_ONLY, verb_start }, /* For compatibility with ALTLinux */ + { "reload", 2, VERB_ANY, VERB_ONLINE_ONLY, verb_start }, + { "restart", 2, VERB_ANY, VERB_ONLINE_ONLY, verb_start }, + { "try-restart", 2, VERB_ANY, VERB_ONLINE_ONLY, verb_start }, + { "reload-or-restart", VERB_ANY, VERB_ANY, VERB_ONLINE_ONLY, verb_start }, + { "reload-or-try-restart", 2, VERB_ANY, VERB_ONLINE_ONLY, verb_start }, /* For compatibility with old systemctl <= 228 */ + { "try-reload-or-restart", 2, VERB_ANY, VERB_ONLINE_ONLY, verb_start }, + { "force-reload", 2, VERB_ANY, VERB_ONLINE_ONLY, verb_start }, /* For compatibility with SysV */ + { "condreload", 2, VERB_ANY, VERB_ONLINE_ONLY, verb_start }, /* For compatibility with ALTLinux */ + { "condrestart", 2, VERB_ANY, VERB_ONLINE_ONLY, verb_start }, /* For compatibility with RH */ + { "isolate", 2, 2, VERB_ONLINE_ONLY, verb_start }, + { "kill", 2, VERB_ANY, VERB_ONLINE_ONLY, verb_kill }, + { "clean", 2, VERB_ANY, VERB_ONLINE_ONLY, verb_clean_or_freeze }, + { "freeze", 2, VERB_ANY, VERB_ONLINE_ONLY, verb_clean_or_freeze }, + { "thaw", 2, VERB_ANY, VERB_ONLINE_ONLY, verb_clean_or_freeze }, + { "is-active", 2, VERB_ANY, VERB_ONLINE_ONLY, verb_is_active }, + { "check", 2, VERB_ANY, VERB_ONLINE_ONLY, verb_is_active }, /* deprecated alias of is-active */ + { "is-failed", VERB_ANY, VERB_ANY, VERB_ONLINE_ONLY, verb_is_failed }, + { "show", VERB_ANY, VERB_ANY, VERB_ONLINE_ONLY, verb_show }, + { "cat", 2, VERB_ANY, VERB_ONLINE_ONLY, verb_cat }, + { "status", VERB_ANY, VERB_ANY, VERB_ONLINE_ONLY, verb_show }, + { "help", VERB_ANY, VERB_ANY, VERB_ONLINE_ONLY, verb_show }, + { "daemon-reload", 1, 1, VERB_ONLINE_ONLY, verb_daemon_reload }, + { "daemon-reexec", 1, 1, VERB_ONLINE_ONLY, verb_daemon_reload }, + { "log-level", VERB_ANY, 2, VERB_ONLINE_ONLY, verb_log_setting }, + { "log-target", VERB_ANY, 2, VERB_ONLINE_ONLY, verb_log_setting }, + { "service-log-level", 2, 3, VERB_ONLINE_ONLY, verb_service_log_setting }, + { "service-log-target", 2, 3, VERB_ONLINE_ONLY, verb_service_log_setting }, + { "service-watchdogs", VERB_ANY, 2, VERB_ONLINE_ONLY, verb_service_watchdogs }, + { "show-environment", VERB_ANY, 1, VERB_ONLINE_ONLY, verb_show_environment }, + { "set-environment", 2, VERB_ANY, VERB_ONLINE_ONLY, verb_set_environment }, + { "unset-environment", 2, VERB_ANY, VERB_ONLINE_ONLY, verb_set_environment }, + { "import-environment", VERB_ANY, VERB_ANY, VERB_ONLINE_ONLY, verb_import_environment }, + { "halt", VERB_ANY, 1, VERB_ONLINE_ONLY, verb_start_system_special }, + { "poweroff", VERB_ANY, 1, VERB_ONLINE_ONLY, verb_start_system_special }, + { "reboot", VERB_ANY, 1, VERB_ONLINE_ONLY, verb_start_system_special }, + { "kexec", VERB_ANY, 1, VERB_ONLINE_ONLY, verb_start_system_special }, + { "soft-reboot", VERB_ANY, 1, VERB_ONLINE_ONLY, verb_start_system_special }, + { "sleep", VERB_ANY, 1, VERB_ONLINE_ONLY, verb_start_system_special }, + { "suspend", VERB_ANY, 1, VERB_ONLINE_ONLY, verb_start_system_special }, + { "hibernate", VERB_ANY, 1, VERB_ONLINE_ONLY, verb_start_system_special }, + { "hybrid-sleep", VERB_ANY, 1, VERB_ONLINE_ONLY, verb_start_system_special }, + { "suspend-then-hibernate",VERB_ANY, 1, VERB_ONLINE_ONLY, verb_start_system_special }, + { "default", VERB_ANY, 1, VERB_ONLINE_ONLY, verb_start_special }, + { "rescue", VERB_ANY, 1, VERB_ONLINE_ONLY, verb_start_system_special }, + { "emergency", VERB_ANY, 1, VERB_ONLINE_ONLY, verb_start_system_special }, + { "exit", VERB_ANY, 2, VERB_ONLINE_ONLY, verb_start_special }, + { "reset-failed", VERB_ANY, VERB_ANY, VERB_ONLINE_ONLY, verb_reset_failed }, + { "enable", 2, VERB_ANY, 0, verb_enable }, + { "disable", 2, VERB_ANY, 0, verb_enable }, + { "is-enabled", 2, VERB_ANY, 0, verb_is_enabled }, + { "reenable", 2, VERB_ANY, 0, verb_enable }, + { "preset", 2, VERB_ANY, 0, verb_enable }, + { "preset-all", VERB_ANY, 1, 0, verb_preset_all }, + { "mask", 2, VERB_ANY, 0, verb_enable }, + { "unmask", 2, VERB_ANY, 0, verb_enable }, + { "link", 2, VERB_ANY, 0, verb_enable }, + { "revert", 2, VERB_ANY, 0, verb_enable }, + { "switch-root", VERB_ANY, VERB_ANY, VERB_ONLINE_ONLY, verb_switch_root }, + { "list-dependencies", VERB_ANY, VERB_ANY, VERB_ONLINE_ONLY, verb_list_dependencies }, + { "set-default", 2, 2, 0, verb_set_default }, + { "get-default", VERB_ANY, 1, 0, verb_get_default }, + { "set-property", 3, VERB_ANY, VERB_ONLINE_ONLY, verb_set_property }, + { "is-system-running", VERB_ANY, 1, 0, verb_is_system_running }, + { "add-wants", 3, VERB_ANY, 0, verb_add_dependency }, + { "add-requires", 3, VERB_ANY, 0, verb_add_dependency }, + { "edit", 2, VERB_ANY, VERB_ONLINE_ONLY, verb_edit }, + { "bind", 3, 4, VERB_ONLINE_ONLY, verb_bind }, + { "mount-image", 4, 5, VERB_ONLINE_ONLY, verb_mount_image }, + { "whoami", VERB_ANY, VERB_ANY, VERB_ONLINE_ONLY, verb_whoami }, + {} + }; + + const Verb *verb = verbs_find_verb(argv[optind], verbs); + if (verb && (verb->flags & VERB_ONLINE_ONLY) && arg_root) + return log_error_errno(SYNTHETIC_ERRNO(EINVAL), + "Verb '%s' cannot be used with --root= or --image=.", + argv[optind] ?: verb->verb); + + return dispatch_verb(argc, argv, verbs, NULL); +} + +static int run(int argc, char *argv[]) { + _cleanup_(loop_device_unrefp) LoopDevice *loop_device = NULL; + _cleanup_(umount_and_freep) char *mounted_dir = NULL; + int r; + + setlocale(LC_ALL, ""); + log_setup(); + + r = systemctl_dispatch_parse_argv(argc, argv); + if (r <= 0) + goto finish; + + journal_browse_prepare(); + + if (proc_mounted() == 0) + log_full(arg_no_warn ? LOG_DEBUG : LOG_WARNING, + "%s%s/proc/ is not mounted. This is not a supported mode of operation. Please fix\n" + "your invocation environment to mount /proc/ and /sys/ properly. Proceeding anyway.\n" + "Your mileage may vary.", + optional_glyph(GLYPH_WARNING_SIGN), + optional_glyph(GLYPH_SPACE)); + + if (arg_action != ACTION_SYSTEMCTL && running_in_chroot() > 0) { + if (!arg_quiet) + log_info("Running in chroot, ignoring request."); + r = 0; + goto finish; + } + + /* systemctl_main() will print an error message for the bus connection, but only if it needs to */ + + if (arg_image) { + assert(!arg_root); + + r = mount_image_privately_interactively( + arg_image, + arg_image_policy, + DISSECT_IMAGE_GENERIC_ROOT | + DISSECT_IMAGE_REQUIRE_ROOT | + DISSECT_IMAGE_RELAX_VAR_CHECK | + DISSECT_IMAGE_VALIDATE_OS | + DISSECT_IMAGE_ALLOW_USERSPACE_VERITY, + &mounted_dir, + /* ret_dir_fd= */ NULL, + &loop_device); + if (r < 0) + return r; + + arg_root = strdup(mounted_dir); + if (!arg_root) + return log_oom(); + } + + switch (arg_action) { + + case ACTION_SYSTEMCTL: + r = systemctl_main(argc, argv); + break; + + /* Legacy command aliases set arg_action. They provide some fallbacks, e.g. to tell sysvinit to + * reboot after you have installed systemd binaries. */ + + case ACTION_HALT: + case ACTION_POWEROFF: + case ACTION_REBOOT: + case ACTION_KEXEC: + r = halt_main(); + break; + + case ACTION_RUNLEVEL2: + case ACTION_RUNLEVEL3: + case ACTION_RUNLEVEL4: + case ACTION_RUNLEVEL5: + case ACTION_RESCUE: + r = start_with_fallback(); + break; + + case ACTION_RELOAD: + case ACTION_REEXEC: + r = reload_with_fallback(); + break; + + case ACTION_CANCEL_SHUTDOWN: + r = logind_cancel_shutdown(); + break; + + case ACTION_SHOW_SHUTDOWN: + case ACTION_SYSTEMCTL_SHOW_SHUTDOWN: + r = logind_show_shutdown(); + break; + + case ACTION_RUNLEVEL: + r = runlevel_main(); + break; + + case ACTION_EXIT: + case ACTION_SLEEP: + case ACTION_SUSPEND: + case ACTION_HIBERNATE: + case ACTION_HYBRID_SLEEP: + case ACTION_SUSPEND_THEN_HIBERNATE: + case ACTION_EMERGENCY: + case ACTION_DEFAULT: + /* systemctl verbs with no equivalent in the legacy commands. These cannot appear in + * arg_action. Fall through. */ + + case _ACTION_INVALID: + default: + assert_not_reached(); + } + +finish: + release_busses(); + + /* Note that we return r here, not 0, so that we can implement the LSB-like return codes */ + return r; +} + +DEFINE_MAIN_FUNCTION_WITH_POSITIVE_FAILURE(run); diff --git a/src/systemctl/systemctl.c b/src/systemctl/systemctl.c index d1e3340737..cffaae5c39 100644 --- a/src/systemctl/systemctl.c +++ b/src/systemctl/systemctl.c @@ -28,26 +28,10 @@ #include "stat-util.h" #include "string-table.h" #include "systemctl.h" -#include "systemctl-add-dependency.h" -#include "systemctl-cancel-job.h" -#include "systemctl-clean-or-freeze.h" #include "systemctl-compat-halt.h" #include "systemctl-compat-runlevel.h" #include "systemctl-compat-shutdown.h" #include "systemctl-compat-telinit.h" -#include "systemctl-daemon-reload.h" -#include "systemctl-edit.h" -#include "systemctl-enable.h" -#include "systemctl-is-active.h" -#include "systemctl-is-enabled.h" -#include "systemctl-is-system-running.h" -#include "systemctl-kill.h" -#include "systemctl-list-dependencies.h" -#include "systemctl-list-jobs.h" -#include "systemctl-list-machines.h" -#include "systemctl-list-unit-files.h" -#include "systemctl-list-units.h" -#include "systemctl-log-setting.h" #include "systemctl-logind.h" #include "systemctl-mount.h" #include "systemctl-preset-all.h" @@ -1167,221 +1151,3 @@ int systemctl_dispatch_parse_argv(int argc, char *argv[]) { arg_action = ACTION_SYSTEMCTL; return systemctl_parse_argv(argc, argv); } - -#ifndef FUZZ_SYSTEMCTL_PARSE_ARGV -static int systemctl_main(int argc, char *argv[]) { - static const Verb verbs[] = { - { "list-units", VERB_ANY, VERB_ANY, VERB_DEFAULT|VERB_ONLINE_ONLY, verb_list_units }, - { "list-unit-files", VERB_ANY, VERB_ANY, 0, verb_list_unit_files }, - { "list-automounts", VERB_ANY, VERB_ANY, VERB_ONLINE_ONLY, verb_list_automounts }, - { "list-paths", VERB_ANY, VERB_ANY, VERB_ONLINE_ONLY, verb_list_paths }, - { "list-sockets", VERB_ANY, VERB_ANY, VERB_ONLINE_ONLY, verb_list_sockets }, - { "list-timers", VERB_ANY, VERB_ANY, VERB_ONLINE_ONLY, verb_list_timers }, - { "list-jobs", VERB_ANY, VERB_ANY, VERB_ONLINE_ONLY, verb_list_jobs }, - { "list-machines", VERB_ANY, VERB_ANY, VERB_ONLINE_ONLY, verb_list_machines }, - { "clear-jobs", VERB_ANY, 1, VERB_ONLINE_ONLY, verb_trivial_method }, - { "cancel", VERB_ANY, VERB_ANY, VERB_ONLINE_ONLY, verb_cancel }, - { "start", 2, VERB_ANY, VERB_ONLINE_ONLY, verb_start }, - { "stop", 2, VERB_ANY, VERB_ONLINE_ONLY, verb_start }, - { "condstop", 2, VERB_ANY, VERB_ONLINE_ONLY, verb_start }, /* For compatibility with ALTLinux */ - { "reload", 2, VERB_ANY, VERB_ONLINE_ONLY, verb_start }, - { "restart", 2, VERB_ANY, VERB_ONLINE_ONLY, verb_start }, - { "try-restart", 2, VERB_ANY, VERB_ONLINE_ONLY, verb_start }, - { "reload-or-restart", VERB_ANY, VERB_ANY, VERB_ONLINE_ONLY, verb_start }, - { "reload-or-try-restart", 2, VERB_ANY, VERB_ONLINE_ONLY, verb_start }, /* For compatibility with old systemctl <= 228 */ - { "try-reload-or-restart", 2, VERB_ANY, VERB_ONLINE_ONLY, verb_start }, - { "force-reload", 2, VERB_ANY, VERB_ONLINE_ONLY, verb_start }, /* For compatibility with SysV */ - { "condreload", 2, VERB_ANY, VERB_ONLINE_ONLY, verb_start }, /* For compatibility with ALTLinux */ - { "condrestart", 2, VERB_ANY, VERB_ONLINE_ONLY, verb_start }, /* For compatibility with RH */ - { "isolate", 2, 2, VERB_ONLINE_ONLY, verb_start }, - { "kill", 2, VERB_ANY, VERB_ONLINE_ONLY, verb_kill }, - { "clean", 2, VERB_ANY, VERB_ONLINE_ONLY, verb_clean_or_freeze }, - { "freeze", 2, VERB_ANY, VERB_ONLINE_ONLY, verb_clean_or_freeze }, - { "thaw", 2, VERB_ANY, VERB_ONLINE_ONLY, verb_clean_or_freeze }, - { "is-active", 2, VERB_ANY, VERB_ONLINE_ONLY, verb_is_active }, - { "check", 2, VERB_ANY, VERB_ONLINE_ONLY, verb_is_active }, /* deprecated alias of is-active */ - { "is-failed", VERB_ANY, VERB_ANY, VERB_ONLINE_ONLY, verb_is_failed }, - { "show", VERB_ANY, VERB_ANY, VERB_ONLINE_ONLY, verb_show }, - { "cat", 2, VERB_ANY, VERB_ONLINE_ONLY, verb_cat }, - { "status", VERB_ANY, VERB_ANY, VERB_ONLINE_ONLY, verb_show }, - { "help", VERB_ANY, VERB_ANY, VERB_ONLINE_ONLY, verb_show }, - { "daemon-reload", 1, 1, VERB_ONLINE_ONLY, verb_daemon_reload }, - { "daemon-reexec", 1, 1, VERB_ONLINE_ONLY, verb_daemon_reload }, - { "log-level", VERB_ANY, 2, VERB_ONLINE_ONLY, verb_log_setting }, - { "log-target", VERB_ANY, 2, VERB_ONLINE_ONLY, verb_log_setting }, - { "service-log-level", 2, 3, VERB_ONLINE_ONLY, verb_service_log_setting }, - { "service-log-target", 2, 3, VERB_ONLINE_ONLY, verb_service_log_setting }, - { "service-watchdogs", VERB_ANY, 2, VERB_ONLINE_ONLY, verb_service_watchdogs }, - { "show-environment", VERB_ANY, 1, VERB_ONLINE_ONLY, verb_show_environment }, - { "set-environment", 2, VERB_ANY, VERB_ONLINE_ONLY, verb_set_environment }, - { "unset-environment", 2, VERB_ANY, VERB_ONLINE_ONLY, verb_set_environment }, - { "import-environment", VERB_ANY, VERB_ANY, VERB_ONLINE_ONLY, verb_import_environment }, - { "halt", VERB_ANY, 1, VERB_ONLINE_ONLY, verb_start_system_special }, - { "poweroff", VERB_ANY, 1, VERB_ONLINE_ONLY, verb_start_system_special }, - { "reboot", VERB_ANY, 1, VERB_ONLINE_ONLY, verb_start_system_special }, - { "kexec", VERB_ANY, 1, VERB_ONLINE_ONLY, verb_start_system_special }, - { "soft-reboot", VERB_ANY, 1, VERB_ONLINE_ONLY, verb_start_system_special }, - { "sleep", VERB_ANY, 1, VERB_ONLINE_ONLY, verb_start_system_special }, - { "suspend", VERB_ANY, 1, VERB_ONLINE_ONLY, verb_start_system_special }, - { "hibernate", VERB_ANY, 1, VERB_ONLINE_ONLY, verb_start_system_special }, - { "hybrid-sleep", VERB_ANY, 1, VERB_ONLINE_ONLY, verb_start_system_special }, - { "suspend-then-hibernate",VERB_ANY, 1, VERB_ONLINE_ONLY, verb_start_system_special }, - { "default", VERB_ANY, 1, VERB_ONLINE_ONLY, verb_start_special }, - { "rescue", VERB_ANY, 1, VERB_ONLINE_ONLY, verb_start_system_special }, - { "emergency", VERB_ANY, 1, VERB_ONLINE_ONLY, verb_start_system_special }, - { "exit", VERB_ANY, 2, VERB_ONLINE_ONLY, verb_start_special }, - { "reset-failed", VERB_ANY, VERB_ANY, VERB_ONLINE_ONLY, verb_reset_failed }, - { "enable", 2, VERB_ANY, 0, verb_enable }, - { "disable", 2, VERB_ANY, 0, verb_enable }, - { "is-enabled", 2, VERB_ANY, 0, verb_is_enabled }, - { "reenable", 2, VERB_ANY, 0, verb_enable }, - { "preset", 2, VERB_ANY, 0, verb_enable }, - { "preset-all", VERB_ANY, 1, 0, verb_preset_all }, - { "mask", 2, VERB_ANY, 0, verb_enable }, - { "unmask", 2, VERB_ANY, 0, verb_enable }, - { "link", 2, VERB_ANY, 0, verb_enable }, - { "revert", 2, VERB_ANY, 0, verb_enable }, - { "switch-root", VERB_ANY, VERB_ANY, VERB_ONLINE_ONLY, verb_switch_root }, - { "list-dependencies", VERB_ANY, VERB_ANY, VERB_ONLINE_ONLY, verb_list_dependencies }, - { "set-default", 2, 2, 0, verb_set_default }, - { "get-default", VERB_ANY, 1, 0, verb_get_default }, - { "set-property", 3, VERB_ANY, VERB_ONLINE_ONLY, verb_set_property }, - { "is-system-running", VERB_ANY, 1, 0, verb_is_system_running }, - { "add-wants", 3, VERB_ANY, 0, verb_add_dependency }, - { "add-requires", 3, VERB_ANY, 0, verb_add_dependency }, - { "edit", 2, VERB_ANY, VERB_ONLINE_ONLY, verb_edit }, - { "bind", 3, 4, VERB_ONLINE_ONLY, verb_bind }, - { "mount-image", 4, 5, VERB_ONLINE_ONLY, verb_mount_image }, - { "whoami", VERB_ANY, VERB_ANY, VERB_ONLINE_ONLY, verb_whoami }, - {} - }; - - const Verb *verb = verbs_find_verb(argv[optind], verbs); - if (verb && (verb->flags & VERB_ONLINE_ONLY) && arg_root) - return log_error_errno(SYNTHETIC_ERRNO(EINVAL), - "Verb '%s' cannot be used with --root= or --image=.", - argv[optind] ?: verb->verb); - - return dispatch_verb(argc, argv, verbs, NULL); -} - -static int run(int argc, char *argv[]) { - _cleanup_(loop_device_unrefp) LoopDevice *loop_device = NULL; - _cleanup_(umount_and_freep) char *mounted_dir = NULL; - int r; - - setlocale(LC_ALL, ""); - log_setup(); - - r = systemctl_dispatch_parse_argv(argc, argv); - if (r <= 0) - goto finish; - - journal_browse_prepare(); - - if (proc_mounted() == 0) - log_full(arg_no_warn ? LOG_DEBUG : LOG_WARNING, - "%s%s/proc/ is not mounted. This is not a supported mode of operation. Please fix\n" - "your invocation environment to mount /proc/ and /sys/ properly. Proceeding anyway.\n" - "Your mileage may vary.", - optional_glyph(GLYPH_WARNING_SIGN), - optional_glyph(GLYPH_SPACE)); - - if (arg_action != ACTION_SYSTEMCTL && running_in_chroot() > 0) { - if (!arg_quiet) - log_info("Running in chroot, ignoring request."); - r = 0; - goto finish; - } - - /* systemctl_main() will print an error message for the bus connection, but only if it needs to */ - - if (arg_image) { - assert(!arg_root); - - r = mount_image_privately_interactively( - arg_image, - arg_image_policy, - DISSECT_IMAGE_GENERIC_ROOT | - DISSECT_IMAGE_REQUIRE_ROOT | - DISSECT_IMAGE_RELAX_VAR_CHECK | - DISSECT_IMAGE_VALIDATE_OS | - DISSECT_IMAGE_ALLOW_USERSPACE_VERITY, - &mounted_dir, - /* ret_dir_fd= */ NULL, - &loop_device); - if (r < 0) - return r; - - arg_root = strdup(mounted_dir); - if (!arg_root) - return log_oom(); - } - - switch (arg_action) { - - case ACTION_SYSTEMCTL: - r = systemctl_main(argc, argv); - break; - - /* Legacy command aliases set arg_action. They provide some fallbacks, e.g. to tell sysvinit to - * reboot after you have installed systemd binaries. */ - - case ACTION_HALT: - case ACTION_POWEROFF: - case ACTION_REBOOT: - case ACTION_KEXEC: - r = halt_main(); - break; - - case ACTION_RUNLEVEL2: - case ACTION_RUNLEVEL3: - case ACTION_RUNLEVEL4: - case ACTION_RUNLEVEL5: - case ACTION_RESCUE: - r = start_with_fallback(); - break; - - case ACTION_RELOAD: - case ACTION_REEXEC: - r = reload_with_fallback(); - break; - - case ACTION_CANCEL_SHUTDOWN: - r = logind_cancel_shutdown(); - break; - - case ACTION_SHOW_SHUTDOWN: - case ACTION_SYSTEMCTL_SHOW_SHUTDOWN: - r = logind_show_shutdown(); - break; - - case ACTION_RUNLEVEL: - r = runlevel_main(); - break; - - case ACTION_EXIT: - case ACTION_SLEEP: - case ACTION_SUSPEND: - case ACTION_HIBERNATE: - case ACTION_HYBRID_SLEEP: - case ACTION_SUSPEND_THEN_HIBERNATE: - case ACTION_EMERGENCY: - case ACTION_DEFAULT: - /* systemctl verbs with no equivalent in the legacy commands. These cannot appear in - * arg_action. Fall through. */ - - case _ACTION_INVALID: - default: - assert_not_reached(); - } - -finish: - release_busses(); - - /* Note that we return r here, not 0, so that we can implement the LSB-like return codes */ - return r; -} - -DEFINE_MAIN_FUNCTION_WITH_POSITIVE_FAILURE(run); -#endif diff --git a/src/systemctl/systemctl.h b/src/systemctl/systemctl.h index e282380323..7bdca74bed 100644 --- a/src/systemctl/systemctl.h +++ b/src/systemctl/systemctl.h @@ -84,6 +84,7 @@ extern int arg_signal; extern int arg_kill_value; extern bool arg_kill_value_set; extern char *arg_root; +extern char *arg_image; extern usec_t arg_when; extern bool arg_stdin; extern const char *arg_reboot_argument; diff --git a/src/sysupdate/meson.build b/src/sysupdate/meson.build index baf3e93a8d..3f733c7933 100644 --- a/src/sysupdate/meson.build +++ b/src/sysupdate/meson.build @@ -9,14 +9,14 @@ systemd_sysupdate_sources = files( 'sysupdate-resource.c', 'sysupdate-transfer.c', 'sysupdate-update-set.c', + 'sysupdate.c', +) +systemd_sysupdate_extract_sources = files( 'sysupdate-update-set-flags.c', 'sysupdate-util.c', - 'sysupdate.c', ) systemd_updatectl_sources = files( - 'sysupdate-update-set-flags.c', - 'sysupdate-util.c', 'updatectl.c', ) @@ -25,7 +25,8 @@ executables += [ 'name' : 'systemd-sysupdate', 'public' : true, 'conditions' : ['ENABLE_SYSUPDATE'], - 'sources' : systemd_sysupdate_sources, + 'sources' : systemd_sysupdate_sources + systemd_sysupdate_extract_sources, + 'extract' : systemd_sysupdate_extract_sources, 'link_with' : [ libshared, libshared_fdisk, @@ -48,6 +49,7 @@ executables += [ 'name' : 'updatectl', 'public' : true, 'sources' : systemd_updatectl_sources, + 'objects' : ['systemd-sysupdate'], 'conditions' : ['ENABLE_SYSUPDATED'], }, ] diff --git a/src/test/meson.build b/src/test/meson.build index 24d0dca2ee..0ccc9332cd 100644 --- a/src/test/meson.build +++ b/src/test/meson.build @@ -364,15 +364,14 @@ executables += [ 'test-nss-hosts.c', 'nss-test-util.c', ), + 'extract' : files('nss-test-util.c'), 'dependencies' : libdl, 'conditions' : ['ENABLE_NSS'], 'timeout' : 120, }, test_template + { - 'sources' : files( - 'test-nss-users.c', - 'nss-test-util.c', - ), + 'sources' : files('test-nss-users.c'), + 'objects' : ['test-nss-hosts'], 'dependencies' : libdl, 'conditions' : ['ENABLE_NSS'], }, diff --git a/src/timesync/meson.build b/src/timesync/meson.build index d32e32dcbc..608589e4b8 100644 --- a/src/timesync/meson.build +++ b/src/timesync/meson.build @@ -33,7 +33,7 @@ endif executables += [ libexec_template + { 'name' : 'systemd-timesyncd', - 'sources' : [timesyncd_sources, timesyncd_extract_sources], + 'sources' : timesyncd_sources + timesyncd_extract_sources, 'include_directories' : [libexec_template['include_directories'], include_directories('.')], 'extract' : timesyncd_extract_sources, 'link_with' : timesyncd_link_with, diff --git a/src/tmpfiles/meson.build b/src/tmpfiles/meson.build index e035d5f03d..1016573969 100644 --- a/src/tmpfiles/meson.build +++ b/src/tmpfiles/meson.build @@ -15,14 +15,14 @@ executables += [ executable_template + { 'name' : 'systemd-tmpfiles', 'public' : true, - 'sources' : [systemd_tmpfiles_sources, systemd_tmpfiles_extract_sources], + 'sources' : systemd_tmpfiles_sources + systemd_tmpfiles_extract_sources, 'extract' : systemd_tmpfiles_extract_sources, 'dependencies' : libacl, }, executable_template + { 'name' : 'systemd-tmpfiles.standalone', 'public' : have_standalone_binaries, - 'sources' : [systemd_tmpfiles_sources, systemd_tmpfiles_extract_sources], + 'sources' : systemd_tmpfiles_sources + systemd_tmpfiles_extract_sources, 'c_args' : '-DSTANDALONE', 'link_with' : [ libbasic_static, diff --git a/src/udev/meson.build b/src/udev/meson.build index ba0a6b14ff..ccf630919f 100644 --- a/src/udev/meson.build +++ b/src/udev/meson.build @@ -149,11 +149,9 @@ udev_binaries_dict = [ executable_template + { 'name' : 'udevadm', 'public' : true, - 'sources' : [ - udevadm_sources, - udevadm_extract_sources, - keyboard_keys_from_name_h, - ], + 'sources' : udevadm_sources + + udevadm_extract_sources + + keyboard_keys_from_name_h, 'include_directories' : [ libexec_template['include_directories'], include_directories('.', 'net'), diff --git a/src/vmspawn/meson.build b/src/vmspawn/meson.build index eefe81c870..4ba56b71f1 100644 --- a/src/vmspawn/meson.build +++ b/src/vmspawn/meson.build @@ -19,7 +19,7 @@ executables += [ executable_template + { 'name' : 'systemd-vmspawn', 'public' : true, - 'sources' : [vmspawn_sources, vmspawn_extract_sources], + 'sources' : vmspawn_sources + vmspawn_extract_sources, 'extract' : vmspawn_extract_sources, 'dependencies' : [libblkid] }, diff --git a/src/xdg-autostart-generator/meson.build b/src/xdg-autostart-generator/meson.build index 58620b5dcd..8f51bdcc7d 100644 --- a/src/xdg-autostart-generator/meson.build +++ b/src/xdg-autostart-generator/meson.build @@ -14,10 +14,8 @@ systemd_xdg_autostart_generator_extract_sources = files( executables += [ executable_template + { 'name' : 'systemd-xdg-autostart-generator', - 'sources' : [ - systemd_xdg_autostart_generator_sources, - systemd_xdg_autostart_generator_extract_sources, - ], + 'sources' : systemd_xdg_autostart_generator_sources + + systemd_xdg_autostart_generator_extract_sources, 'extract' : systemd_xdg_autostart_generator_extract_sources, 'install_dir' : usergeneratordir, }, From e4b4a9b6773cf4fa228d87dc473f563f1b7ff6b6 Mon Sep 17 00:00:00 2001 From: Daan De Meyer Date: Mon, 19 May 2025 17:41:18 +0200 Subject: [PATCH 3/8] meson: Make sure fuzz-journal-remote is built in oss-fuzz oss-fuzz builds with --auto-features=disabled, yet we have to make sure all fuzzers are still built when --auto-features=disabled, so let's always build systemd-journal-remote even if it is disabled so that we can use its objects to build fuzz-journal-remote. Instead, when remote=disabled, we make sure we don't installed systemd-journal-remote. --- src/journal-remote/meson.build | 28 ++++++++++++++++++---------- 1 file changed, 18 insertions(+), 10 deletions(-) diff --git a/src/journal-remote/meson.build b/src/journal-remote/meson.build index 04b0f6e881..47515db0a7 100644 --- a/src/journal-remote/meson.build +++ b/src/journal-remote/meson.build @@ -1,9 +1,5 @@ # SPDX-License-Identifier: LGPL-2.1-or-later -if conf.get('ENABLE_REMOTE') != 1 - subdir_done() -endif - systemd_journal_gatewayd_sources = files( 'journal-gatewayd.c', ) @@ -39,7 +35,10 @@ executables += [ libexec_template + { 'name' : 'systemd-journal-gatewayd', 'public' : true, - 'conditions' : ['HAVE_MICROHTTPD'], + 'conditions' : [ + 'ENABLE_REMOTE', + 'HAVE_MICROHTTPD', + ], 'sources' : systemd_journal_gatewayd_sources + systemd_journal_gatewayd_extract_sources, 'extract' : systemd_journal_gatewayd_extract_sources, 'dependencies' : common_deps + [libmicrohttpd], @@ -47,6 +46,10 @@ executables += [ libexec_template + { 'name' : 'systemd-journal-remote', 'public' : true, + # We always build systemd-journal regardless of ENABLE_REMOTE because we have to build + # fuzz-journal-remote even when --auto-features=disabled (see tools/oss-fuzz.sh for why). + # Instead, we make sure we don't install it when the remote feature is disabled. + 'install' : conf.get('ENABLE_REMOTE') == 1, 'sources' : systemd_journal_remote_sources + systemd_journal_remote_extract_sources, 'objects' : conf.get('HAVE_MICROHTTPD') == 1 ? ['systemd-journal-gatewayd'] : [], 'extract' : systemd_journal_remote_extract_sources, @@ -55,7 +58,10 @@ executables += [ libexec_template + { 'name' : 'systemd-journal-upload', 'public' : true, - 'conditions' : ['HAVE_LIBCURL'], + 'conditions' : [ + 'ENABLE_REMOTE', + 'HAVE_LIBCURL', + ], 'sources' : systemd_journal_upload_sources + systemd_journal_upload_extract_sources, 'objects' : ['systemd-journal-remote'], 'extract' : systemd_journal_upload_extract_sources, @@ -63,7 +69,7 @@ executables += [ }, test_template + { 'sources' : files('test-journal-header-util.c'), - 'conditions' : ['HAVE_LIBCURL'], + 'conditions' : ['ENABLE_REMOTE', 'HAVE_LIBCURL'], 'objects' : ['systemd-journal-upload'], }, fuzz_template + { @@ -74,8 +80,10 @@ executables += [ ] in_files = [ - ['journal-upload.conf', conf.get('HAVE_LIBCURL') == 1 and install_sysconfdir_samples], - ['journal-remote.conf', conf.get('HAVE_MICROHTTPD') == 1 and install_sysconfdir_samples]] + ['journal-upload.conf', + conf.get('ENABLE_REMOTE') == 1 and conf.get('HAVE_LIBCURL') == 1 and install_sysconfdir_samples], + ['journal-remote.conf', + conf.get('ENABLE_REMOTE') == 1 and conf.get('HAVE_MICROHTTPD') == 1 and install_sysconfdir_samples]] foreach tuple : in_files file = tuple[0] @@ -88,7 +96,7 @@ foreach tuple : in_files install_dir : pkgconfigfiledir) endforeach -if conf.get('HAVE_MICROHTTPD') == 1 +if conf.get('ENABLE_REMOTE') == 1 and conf.get('HAVE_MICROHTTPD') == 1 install_data('browse.html', install_dir : pkgdatadir / 'gatewayd') From 1fa170b9d2c94d513b42d1749df7a9e94e659563 Mon Sep 17 00:00:00 2001 From: Daan De Meyer Date: Mon, 19 May 2025 17:43:48 +0200 Subject: [PATCH 4/8] oss-fuzz: Add comment on why we build with --auto-features=disabled --- tools/oss-fuzz.sh | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/tools/oss-fuzz.sh b/tools/oss-fuzz.sh index 05f9191fb6..3cd5cec670 100755 --- a/tools/oss-fuzz.sh +++ b/tools/oss-fuzz.sh @@ -32,6 +32,12 @@ meson_args=("-Db_lundef=false") if [ -z "$FUZZING_ENGINE" ]; then meson_args+=("-Dllvm-fuzz=true") else + # The situation with runtime dependencies on oss-fuzz is complicated as the execution environment differs + # from the build environment + # (https://google.github.io/oss-fuzz/further-reading/fuzzer-environment/#runtime-dependencies). Because + # statically linking isn't viable for us for various reasons, we do a build with most features disabled + # to link against as few libraries as possible. The libraries we do end up linking against happen (by + # chance) to be installed in the oss-fuzz execution environment. meson_args+=("-Doss-fuzz=true" "--auto-features=disabled" "-Dnspawn=enabled" "-Dresolve=true") apt-get update From b7400b14ed91fb1b612024808297bef50ae24fc2 Mon Sep 17 00:00:00 2001 From: Daan De Meyer Date: Thu, 15 May 2025 14:52:48 +0200 Subject: [PATCH 5/8] meson: Build fuzz executables by default if fuzz-tests option is enabled fuzz-tests is enabled by default now but we still don't build the fuzz executables by default. Let's change that so that we always make sure these still compile when we make changes. --- meson.build | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/meson.build b/meson.build index 83442da079..aeff1b3629 100644 --- a/meson.build +++ b/meson.build @@ -2196,7 +2196,7 @@ test_additional_kwargs = { } fuzz_template = executable_template + { - 'build_by_default' : fuzzer_build, + 'build_by_default' : want_fuzz_tests, 'install' : false, } From 6196e414a5565535eaee3e486181fb60c65061fe Mon Sep 17 00:00:00 2001 From: Daan De Meyer Date: Thu, 15 May 2025 14:07:59 +0200 Subject: [PATCH 6/8] tree-wide: Ensure source file names are unique Let's ensure all of our source file names are unique without having to take the directory into account. This allows us to create meson targets or unit tests identified by the the name of the source file they operate on without having to include the full path of the source file in the target or test name to avoid conflicts. --- src/boot/boot.c | 2 +- src/boot/edid.c | 2 +- src/boot/{efivars.c => efi-efivars.c} | 2 +- src/boot/{efivars.h => efi-efivars.h} | 0 src/boot/{log.c => efi-log.c} | 2 +- src/boot/{log.h => efi-log.h} | 0 src/boot/export-vars.c | 2 +- src/boot/meson.build | 4 ++-- src/boot/random-seed.c | 2 +- src/boot/secure-boot.c | 2 +- src/boot/shim.c | 2 +- src/boot/smbios.c | 2 +- src/boot/stub.c | 2 +- src/boot/ubsan.c | 2 +- src/boot/util.c | 2 +- src/boot/util.h | 2 +- src/boot/vmm.c | 2 +- src/escape/{escape.c => escape-tool.c} | 0 src/escape/meson.build | 2 +- src/measure/{measure.c => measure-tool.c} | 0 src/measure/meson.build | 2 +- src/network/generator/{main.c => network-generator-main.c} | 0 src/network/meson.build | 6 +++--- src/network/wait-online/{link.c => wait-online-link.c} | 4 ++-- src/network/wait-online/{link.h => wait-online-link.h} | 0 .../wait-online/{manager.c => wait-online-manager.c} | 5 +++-- .../wait-online/{manager.h => wait-online-manager.h} | 0 src/network/wait-online/wait-online.c | 2 +- src/path/meson.build | 2 +- src/path/{path.c => path-tool.c} | 0 src/random-seed/meson.build | 2 +- src/random-seed/{random-seed.c => random-seed-tool.c} | 0 32 files changed, 29 insertions(+), 28 deletions(-) rename src/boot/{efivars.c => efi-efivars.c} (99%) rename src/boot/{efivars.h => efi-efivars.h} (100%) rename src/boot/{log.c => efi-log.c} (99%) rename src/boot/{log.h => efi-log.h} (100%) rename src/escape/{escape.c => escape-tool.c} (100%) rename src/measure/{measure.c => measure-tool.c} (100%) rename src/network/generator/{main.c => network-generator-main.c} (100%) rename src/network/wait-online/{link.c => wait-online-link.c} (99%) rename src/network/wait-online/{link.h => wait-online-link.h} (100%) rename src/network/wait-online/{manager.c => wait-online-manager.c} (99%) rename src/network/wait-online/{manager.h => wait-online-manager.h} (100%) rename src/path/{path.c => path-tool.c} (100%) rename src/random-seed/{random-seed.c => random-seed-tool.c} (100%) diff --git a/src/boot/boot.c b/src/boot/boot.c index c2851e1267..967b9db1dc 100644 --- a/src/boot/boot.c +++ b/src/boot/boot.c @@ -8,8 +8,8 @@ #include "device-path-util.h" #include "devicetree.h" #include "drivers.h" +#include "efi-efivars.h" #include "efi-string-table.h" -#include "efivars.h" #include "efivars-fundamental.h" #include "export-vars.h" #include "graphics.h" diff --git a/src/boot/edid.c b/src/boot/edid.c index 62e338353e..a1a41cc289 100644 --- a/src/boot/edid.c +++ b/src/boot/edid.c @@ -2,7 +2,7 @@ #include "edid.h" #include "edid-fundamental.h" -#include "log.h" +#include "efi-log.h" #include "proto/edid-discovered.h" #include "util.h" diff --git a/src/boot/efivars.c b/src/boot/efi-efivars.c similarity index 99% rename from src/boot/efivars.c rename to src/boot/efi-efivars.c index 2613efa6d7..e05997972b 100644 --- a/src/boot/efivars.c +++ b/src/boot/efi-efivars.c @@ -1,7 +1,7 @@ /* SPDX-License-Identifier: LGPL-2.1-or-later */ +#include "efi-efivars.h" #include "efi-string.h" -#include "efivars.h" #include "ticks.h" #include "util.h" diff --git a/src/boot/efivars.h b/src/boot/efi-efivars.h similarity index 100% rename from src/boot/efivars.h rename to src/boot/efi-efivars.h diff --git a/src/boot/log.c b/src/boot/efi-log.c similarity index 99% rename from src/boot/log.c rename to src/boot/efi-log.c index edad4125c6..1810375c6a 100644 --- a/src/boot/log.c +++ b/src/boot/efi-log.c @@ -1,6 +1,6 @@ /* SPDX-License-Identifier: LGPL-2.1-or-later */ -#include "log.h" +#include "efi-log.h" #include "proto/rng.h" #include "util.h" diff --git a/src/boot/log.h b/src/boot/efi-log.h similarity index 100% rename from src/boot/log.h rename to src/boot/efi-log.h diff --git a/src/boot/export-vars.c b/src/boot/export-vars.c index fb281ad394..25ca62065a 100644 --- a/src/boot/export-vars.c +++ b/src/boot/export-vars.c @@ -1,7 +1,7 @@ /* SPDX-License-Identifier: LGPL-2.1-or-later */ #include "device-path-util.h" -#include "efivars.h" +#include "efi-efivars.h" #include "export-vars.h" #include "part-discovery.h" #include "url-discovery.h" diff --git a/src/boot/meson.build b/src/boot/meson.build index 570ea2079e..48d03b5b80 100644 --- a/src/boot/meson.build +++ b/src/boot/meson.build @@ -298,13 +298,13 @@ libefi_sources = files( 'devicetree.c', 'drivers.c', 'edid.c', + 'efi-efivars.c', 'efi-firmware.c', + 'efi-log.c', 'efi-string.c', - 'efivars.c', 'export-vars.c', 'graphics.c', 'initrd.c', - 'log.c', 'measure.c', 'part-discovery.c', 'pe.c', diff --git a/src/boot/random-seed.c b/src/boot/random-seed.c index 9837a85ccd..a4d7f5ba26 100644 --- a/src/boot/random-seed.c +++ b/src/boot/random-seed.c @@ -1,6 +1,6 @@ /* SPDX-License-Identifier: LGPL-2.1-or-later */ -#include "efivars.h" +#include "efi-efivars.h" #include "memory-util-fundamental.h" #include "proto/rng.h" #include "random-seed.h" diff --git a/src/boot/secure-boot.c b/src/boot/secure-boot.c index f44a6f149b..5781669a4c 100644 --- a/src/boot/secure-boot.c +++ b/src/boot/secure-boot.c @@ -1,8 +1,8 @@ /* SPDX-License-Identifier: LGPL-2.1-or-later */ #include "console.h" +#include "efi-efivars.h" #include "efi-string-table.h" -#include "efivars.h" #include "proto/security-arch.h" #include "secure-boot.h" #include "util.h" diff --git a/src/boot/shim.c b/src/boot/shim.c index 09d87df530..c84e7fe589 100644 --- a/src/boot/shim.c +++ b/src/boot/shim.c @@ -9,7 +9,7 @@ */ #include "device-path-util.h" -#include "efivars.h" +#include "efi-efivars.h" #include "secure-boot.h" #include "shim.h" #include "util.h" diff --git a/src/boot/smbios.c b/src/boot/smbios.c index 0e2b8812ee..e2674f6cd3 100644 --- a/src/boot/smbios.c +++ b/src/boot/smbios.c @@ -1,7 +1,7 @@ /* SPDX-License-Identifier: LGPL-2.1-or-later */ +#include "efi-efivars.h" #include "efi-string.h" -#include "efivars.h" #include "proto/device-path.h" #include "smbios.h" #include "string-util-fundamental.h" diff --git a/src/boot/stub.c b/src/boot/stub.c index 9cc115a1f6..a117d11332 100644 --- a/src/boot/stub.c +++ b/src/boot/stub.c @@ -5,7 +5,7 @@ #include "cpio.h" #include "device-path-util.h" #include "devicetree.h" -#include "efivars.h" +#include "efi-efivars.h" #include "export-vars.h" #include "graphics.h" #include "iovec-util-fundamental.h" diff --git a/src/boot/ubsan.c b/src/boot/ubsan.c index 951204683e..959c78d2bc 100644 --- a/src/boot/ubsan.c +++ b/src/boot/ubsan.c @@ -1,6 +1,6 @@ /* SPDX-License-Identifier: LGPL-2.1-or-later */ -#include "log.h" +#include "efi-log.h" typedef struct { const char *filename; diff --git a/src/boot/util.c b/src/boot/util.c index a218ee2cc1..20db520654 100644 --- a/src/boot/util.c +++ b/src/boot/util.c @@ -1,8 +1,8 @@ /* SPDX-License-Identifier: LGPL-2.1-or-later */ #include "device-path-util.h" +#include "efi-efivars.h" #include "efi-string.h" -#include "efivars.h" #include "memory-util-fundamental.h" #include "proto/device-path.h" #include "proto/simple-text-io.h" diff --git a/src/boot/util.h b/src/boot/util.h index 6b227680b4..4f0fe43149 100644 --- a/src/boot/util.h +++ b/src/boot/util.h @@ -8,7 +8,7 @@ #if SD_BOOT -#include "log.h" +#include "efi-log.h" #include "proto/file-io.h" /* This is provided by the linker. */ diff --git a/src/boot/vmm.c b/src/boot/vmm.c index 29dbd6ffdb..babe581073 100644 --- a/src/boot/vmm.c +++ b/src/boot/vmm.c @@ -8,7 +8,7 @@ #include "device-path-util.h" #include "drivers.h" #include "efi-string.h" -#include "efivars.h" +#include "efi-efivars.h" #include "proto/device-path.h" #include "smbios.h" #include "string-util-fundamental.h" diff --git a/src/escape/escape.c b/src/escape/escape-tool.c similarity index 100% rename from src/escape/escape.c rename to src/escape/escape-tool.c diff --git a/src/escape/meson.build b/src/escape/meson.build index d21b3722cc..94cd3b1fba 100644 --- a/src/escape/meson.build +++ b/src/escape/meson.build @@ -4,6 +4,6 @@ executables += [ executable_template + { 'name' : 'systemd-escape', 'public' : true, - 'sources' : files('escape.c'), + 'sources' : files('escape-tool.c'), }, ] diff --git a/src/measure/measure.c b/src/measure/measure-tool.c similarity index 100% rename from src/measure/measure.c rename to src/measure/measure-tool.c diff --git a/src/measure/meson.build b/src/measure/meson.build index 13a890170c..e4e4f579df 100644 --- a/src/measure/meson.build +++ b/src/measure/meson.build @@ -8,7 +8,7 @@ executables += [ 'HAVE_OPENSSL', 'HAVE_TPM2', ], - 'sources' : files('measure.c'), + 'sources' : files('measure-tool.c'), 'dependencies' : libopenssl, }, ] diff --git a/src/network/generator/main.c b/src/network/generator/network-generator-main.c similarity index 100% rename from src/network/generator/main.c rename to src/network/generator/network-generator-main.c diff --git a/src/network/meson.build b/src/network/meson.build index 97191fb171..70c5a09bb2 100644 --- a/src/network/meson.build +++ b/src/network/meson.build @@ -116,8 +116,8 @@ systemd_networkd_extract_sources = files( systemd_networkd_wait_online_sources = files( 'wait-online/dns-configuration.c', - 'wait-online/link.c', - 'wait-online/manager.c', + 'wait-online/wait-online-link.c', + 'wait-online/wait-online-manager.c', 'wait-online/wait-online.c', ) @@ -229,7 +229,7 @@ executables += [ }, libexec_template + { 'name' : 'systemd-network-generator', - 'sources' : files('generator/network-generator.c', 'generator/main.c'), + 'sources' : files('generator/network-generator.c', 'generator/network-generator-main.c'), 'extract' : files('generator/network-generator.c'), 'link_with' : networkd_link_with, }, diff --git a/src/network/wait-online/link.c b/src/network/wait-online/wait-online-link.c similarity index 99% rename from src/network/wait-online/link.c rename to src/network/wait-online/wait-online-link.c index 7515579edb..f7c2e4fc98 100644 --- a/src/network/wait-online/link.c +++ b/src/network/wait-online/wait-online-link.c @@ -6,10 +6,10 @@ #include "dns-configuration.h" #include "format-ifname.h" #include "hashmap.h" -#include "link.h" -#include "manager.h" #include "string-util.h" #include "strv.h" +#include "wait-online-link.h" +#include "wait-online-manager.h" static Link* link_free(Link *l) { diff --git a/src/network/wait-online/link.h b/src/network/wait-online/wait-online-link.h similarity index 100% rename from src/network/wait-online/link.h rename to src/network/wait-online/wait-online-link.h diff --git a/src/network/wait-online/manager.c b/src/network/wait-online/wait-online-manager.c similarity index 99% rename from src/network/wait-online/manager.c rename to src/network/wait-online/wait-online-manager.c index c4318d3cf5..0ff2c77277 100644 --- a/src/network/wait-online/manager.c +++ b/src/network/wait-online/wait-online-manager.c @@ -11,11 +11,12 @@ #include "alloc-util.h" #include "dns-configuration.h" #include "json-util.h" -#include "link.h" -#include "manager.h" #include "netlink-util.h" +#include "string-util.h" #include "strv.h" #include "time-util.h" +#include "wait-online-link.h" +#include "wait-online-manager.h" static bool link_in_command_line_interfaces(Link *link, Manager *m) { assert(link); diff --git a/src/network/wait-online/manager.h b/src/network/wait-online/wait-online-manager.h similarity index 100% rename from src/network/wait-online/manager.h rename to src/network/wait-online/wait-online-manager.h diff --git a/src/network/wait-online/wait-online.c b/src/network/wait-online/wait-online.c index 58b485bbd1..c693b5335c 100644 --- a/src/network/wait-online/wait-online.c +++ b/src/network/wait-online/wait-online.c @@ -11,12 +11,12 @@ #include "daemon-util.h" #include "log.h" #include "main-func.h" -#include "manager.h" #include "parse-argument.h" #include "pretty-print.h" #include "signal-util.h" #include "socket-util.h" #include "strv.h" +#include "wait-online-manager.h" static bool arg_quiet = false; static usec_t arg_timeout = 120 * USEC_PER_SEC; diff --git a/src/path/meson.build b/src/path/meson.build index 70d3dd0cfd..64c2e1d191 100644 --- a/src/path/meson.build +++ b/src/path/meson.build @@ -4,6 +4,6 @@ executables += [ executable_template + { 'name' : 'systemd-path', 'public' : true, - 'sources' : files('path.c'), + 'sources' : files('path-tool.c'), }, ] diff --git a/src/path/path.c b/src/path/path-tool.c similarity index 100% rename from src/path/path.c rename to src/path/path-tool.c diff --git a/src/random-seed/meson.build b/src/random-seed/meson.build index daa2eefa74..6e8292f8d4 100644 --- a/src/random-seed/meson.build +++ b/src/random-seed/meson.build @@ -4,6 +4,6 @@ executables += [ libexec_template + { 'name' : 'systemd-random-seed', 'conditions' : ['ENABLE_RANDOMSEED'], - 'sources' : files('random-seed.c'), + 'sources' : files('random-seed-tool.c'), }, ] diff --git a/src/random-seed/random-seed.c b/src/random-seed/random-seed-tool.c similarity index 100% rename from src/random-seed/random-seed.c rename to src/random-seed/random-seed-tool.c From d86fead481327cb293464f8a782ff22d036de62e Mon Sep 17 00:00:00 2001 From: Daan De Meyer Date: Thu, 15 May 2025 15:09:27 +0200 Subject: [PATCH 7/8] meson: Rework clang-tidy integration to be done via unit tests Instead of using run-clang-tidy.py with its own scheduling, let's just gather a list of source files ourselves and then use that to add a unit test for each source file that runs clang-tidy on the source file. We also add a bit of logic to run clang-tidy on most header files as well for extra coverage. This uncovered various header files that were not standalone so this commit also includes fixes to make sure the clang-tidy tests are all green. We can also use this in a later commit to run clang-include-cleaner on each source file in the same way. --- .github/workflows/linter.yml | 2 +- meson.build | 50 ++++++++++++++++++----------- src/basic/meson.build | 2 ++ src/basic/rlimit-util.h | 1 + src/basic/uid-range.h | 1 + src/basic/virt.h | 1 + src/boot/meson.build | 5 +++ src/core/meson.build | 2 ++ src/core/show-status.h | 1 + src/fundamental/meson.build | 2 ++ src/journal/journald-stream.h | 12 +++++-- src/journal/journald-sync.h | 8 +++-- src/libsystemd-network/meson.build | 6 ++-- src/libsystemd/meson.build | 2 ++ src/libudev/meson.build | 2 ++ src/login/logind-seat.h | 1 + src/machine/operation.h | 1 + src/shared/meson.build | 1 + src/shared/smack-util.h | 1 + src/shared/utmp-wtmp.h | 1 + src/sysupdate/sysupdate-partition.h | 1 + 21 files changed, 76 insertions(+), 27 deletions(-) diff --git a/.github/workflows/linter.yml b/.github/workflows/linter.yml index b4ab5769ae..5aca56290d 100644 --- a/.github/workflows/linter.yml +++ b/.github/workflows/linter.yml @@ -74,4 +74,4 @@ jobs: run: mkosi sandbox -- env CC=clang CXX=clang++ meson setup build - name: Run clang-tidy - run: mkosi sandbox -- ninja -C build clang-tidy + run: mkosi sandbox -- meson test -C build --suite=clang-tidy --print-errorlogs --no-stdsplit diff --git a/meson.build b/meson.build index aeff1b3629..5dd5f348aa 100644 --- a/meson.build +++ b/meson.build @@ -15,7 +15,7 @@ project('systemd', 'c', add_test_setup( 'default', - exclude_suites : ['integration-tests'], + exclude_suites : ['clang-tidy', 'integration-tests'], is_default : true, ) @@ -2002,6 +2002,7 @@ executables_by_name = {} objects_by_name = {} fuzzer_exes = [] generated_sources = [version_h, vmlinux_h_dependency] +sources = [] # binaries that have --help and are intended for use by humans, # usually, but not always, installed in /bin. @@ -2470,6 +2471,10 @@ foreach dict : executables executables_by_name += { name : exe } + if not name.endswith('.standalone') + sources += dict.get('sources', []) + endif + if dict.has_key('extract') objects_by_name += { name : { @@ -2829,23 +2834,32 @@ endif alias_target('gensources', generated_sources) -run_clang_tidy = find_program('run-clang-tidy', required : false) -if run_clang_tidy.found() - run_target( - 'clang-tidy', - command : [ - run_clang_tidy, - '-use-color', - '-quiet', - '-p', meson.project_build_root(), - # There seems to be a bug in clang-tidy where by even with --quiet some - # messages from clang's own diagnostics engine leak through: - # X warnings generated. - # Until this is fixed upstream, we use -fno-caret-diagnostics to suppress these. - '-extra-arg=-fno-caret-diagnostics', - ], - depends : generated_sources - ) +clang_tidy = find_program('clang-tidy', required : false) +if meson.version().version_compare('>=1.4.0') + foreach source : sources + if fs.name(source).endswith('.h') + continue + endif + + inputs = [source] + + header = source.full_path().replace('.c', '.h') + if fs.exists(header) + inputs += header + endif + + foreach input : inputs + if clang_tidy.found() + test( + 'clang-tidy-@0@'.format(fs.name(input)), + clang_tidy, + args : ['-p', meson.project_build_root(), input], + suite : 'clang-tidy', + depends : generated_sources, + ) + endif + endforeach + endforeach endif check_api_docs_sh = find_program('tools/check-api-docs.sh') diff --git a/src/basic/meson.build b/src/basic/meson.build index 44b90c2e76..df363f6048 100644 --- a/src/basic/meson.build +++ b/src/basic/meson.build @@ -118,6 +118,8 @@ basic_sources = files( 'xattr-util.c', ) +sources += basic_sources + missing_audit_h = files('missing_audit.h') missing_socket_h = files('missing_socket.h') diff --git a/src/basic/rlimit-util.h b/src/basic/rlimit-util.h index ad48e31550..dd1fef4396 100644 --- a/src/basic/rlimit-util.h +++ b/src/basic/rlimit-util.h @@ -2,6 +2,7 @@ #pragma once #include +#include #include "macro.h" diff --git a/src/basic/uid-range.h b/src/basic/uid-range.h index 197085a60b..e1965cf9b7 100644 --- a/src/basic/uid-range.h +++ b/src/basic/uid-range.h @@ -1,6 +1,7 @@ /* SPDX-License-Identifier: LGPL-2.1-or-later */ #pragma once +#include #include #include diff --git a/src/basic/virt.h b/src/basic/virt.h index 8193d4a760..e4fdaca976 100644 --- a/src/basic/virt.h +++ b/src/basic/virt.h @@ -1,6 +1,7 @@ /* SPDX-License-Identifier: LGPL-2.1-or-later */ #pragma once +#include #include #include "errno-list.h" diff --git a/src/boot/meson.build b/src/boot/meson.build index 48d03b5b80..dffd5db88e 100644 --- a/src/boot/meson.build +++ b/src/boot/meson.build @@ -348,6 +348,11 @@ if host_machine.cpu_family() in ['aarch64', 'arm', 'x86_64', 'x86'] systemd_boot_sources += files('bcd.c') endif +sources += libefi_sources +sources += systemd_boot_sources +sources += stub_sources +sources += addon_sources + boot_targets = [] efi_elf_binaries = [] efi_archspecs = [ diff --git a/src/core/meson.build b/src/core/meson.build index 659dc9b7ea..24843ec789 100644 --- a/src/core/meson.build +++ b/src/core/meson.build @@ -78,6 +78,8 @@ if conf.get('BPF_FRAMEWORK') == 1 restrict_ifaces_skel_h] endif +sources += libcore_sources + load_fragment_gperf_gperf = custom_target( 'load-fragment-gperf.gperf', input : 'load-fragment-gperf.gperf.in', diff --git a/src/core/show-status.h b/src/core/show-status.h index a51616f75a..1986985c21 100644 --- a/src/core/show-status.h +++ b/src/core/show-status.h @@ -1,6 +1,7 @@ /* SPDX-License-Identifier: LGPL-2.1-or-later */ #pragma once +#include #include #include diff --git a/src/fundamental/meson.build b/src/fundamental/meson.build index 5536be6e4c..6bc26caad2 100644 --- a/src/fundamental/meson.build +++ b/src/fundamental/meson.build @@ -13,3 +13,5 @@ fundamental_sources = files( 'string-util-fundamental.c', 'uki.c', ) + +sources += fundamental_sources diff --git a/src/journal/journald-stream.h b/src/journal/journald-stream.h index a22b136049..cb55970059 100644 --- a/src/journal/journald-stream.h +++ b/src/journal/journald-stream.h @@ -1,13 +1,19 @@ /* SPDX-License-Identifier: LGPL-2.1-or-later */ #pragma once -typedef struct Manager Manager; -typedef struct StdoutStream StdoutStream; -typedef struct StreamSyncReq StreamSyncReq; +#include + +#include "sd-event.h" +#include "sd-id128.h" #include "fdset.h" #include "list.h" +typedef struct ClientContext ClientContext; +typedef struct Manager Manager; +typedef struct StdoutStream StdoutStream; +typedef struct StreamSyncReq StreamSyncReq; + typedef enum StdoutStreamState { STDOUT_STREAM_IDENTIFIER, STDOUT_STREAM_UNIT_ID, diff --git a/src/journal/journald-sync.h b/src/journal/journald-sync.h index 5f042ece96..4ef4aa4952 100644 --- a/src/journal/journald-sync.h +++ b/src/journal/journald-sync.h @@ -1,14 +1,16 @@ /* SPDX-License-Identifier: LGPL-2.1-or-later */ #pragma once -typedef struct Manager Manager; -typedef struct StreamSyncReq StreamSyncReq; -typedef struct SyncReq SyncReq; +#include "sd-varlink.h" #include "journald-stream.h" #include "list.h" #include "macro.h" +typedef struct Manager Manager; +typedef struct StreamSyncReq StreamSyncReq; +typedef struct SyncReq SyncReq; + /* Encapsulates the synchronization request data we need to keep per STDOUT stream. Primarily a byte counter * to count down. */ struct StreamSyncReq { diff --git a/src/libsystemd-network/meson.build b/src/libsystemd-network/meson.build index a6de329627..6b36c2eb64 100644 --- a/src/libsystemd-network/meson.build +++ b/src/libsystemd-network/meson.build @@ -1,6 +1,6 @@ # SPDX-License-Identifier: LGPL-2.1-or-later -sources = files( +libsystemd_network_sources = files( 'arp-util.c', 'dhcp-network.c', 'dhcp-option.c', @@ -36,9 +36,11 @@ sources = files( 'sd-radv.c', ) +sources += libsystemd_network_sources + libsystemd_network = static_library( 'systemd-network', - sources, + libsystemd_network_sources, include_directories : includes, implicit_include_directories : false, dependencies : userspace, diff --git a/src/libsystemd/meson.build b/src/libsystemd/meson.build index 60b73f4da1..57fc116929 100644 --- a/src/libsystemd/meson.build +++ b/src/libsystemd/meson.build @@ -137,6 +137,8 @@ libsystemd_sources = files( + sd_login_sources + sd_json_sources + sd_varlink_sources \ + sd_path_sources + sd_netlink_sources + sd_network_sources +sources += libsystemd_sources + libsystemd_c_args = ['-fvisibility=default'] libsystemd_static = static_library( diff --git a/src/libudev/meson.build b/src/libudev/meson.build index e5c0c8361b..43959640b9 100644 --- a/src/libudev/meson.build +++ b/src/libudev/meson.build @@ -11,6 +11,8 @@ libudev_sources = files( 'libudev.c', ) +sources += libudev_sources + ############################################################ libudev_includes = [includes, include_directories('.')] diff --git a/src/login/logind-seat.h b/src/login/logind-seat.h index 2dc57686e9..c391363303 100644 --- a/src/login/logind-seat.h +++ b/src/login/logind-seat.h @@ -5,6 +5,7 @@ #include "list.h" #include "memory-util.h" +#include "set.h" #include "string-util.h" #include "time-util.h" diff --git a/src/machine/operation.h b/src/machine/operation.h index 1fd8d42a2e..330ef0bf98 100644 --- a/src/machine/operation.h +++ b/src/machine/operation.h @@ -7,6 +7,7 @@ #include "sd-event.h" #include "sd-varlink.h" +#include "assert-util.h" #include "list.h" typedef struct Machine Machine; diff --git a/src/shared/meson.build b/src/shared/meson.build index d57bd93da1..3f70ddbfd5 100644 --- a/src/shared/meson.build +++ b/src/shared/meson.build @@ -317,6 +317,7 @@ ethtool_link_mode_h = custom_target( generated_sources += ethtool_link_mode_h shared_sources += ethtool_link_mode_h +sources += shared_sources fname = 'ethtool-link-mode.xml' ethtool_link_mode_xml = custom_target( diff --git a/src/shared/smack-util.h b/src/shared/smack-util.h index e380de3dd7..5bd2cea38b 100644 --- a/src/shared/smack-util.h +++ b/src/shared/smack-util.h @@ -7,6 +7,7 @@ Author: Auke Kok ***/ +#include #include #include diff --git a/src/shared/utmp-wtmp.h b/src/shared/utmp-wtmp.h index 2e04fac404..8577d9b013 100644 --- a/src/shared/utmp-wtmp.h +++ b/src/shared/utmp-wtmp.h @@ -4,6 +4,7 @@ #include #include +#include "assert-util.h" #include "time-util.h" #if ENABLE_UTMP diff --git a/src/sysupdate/sysupdate-partition.h b/src/sysupdate/sysupdate-partition.h index 094d8e0ca4..15324013f3 100644 --- a/src/sysupdate/sysupdate-partition.h +++ b/src/sysupdate/sysupdate-partition.h @@ -1,6 +1,7 @@ /* SPDX-License-Identifier: LGPL-2.1-or-later */ #pragma once +#include #include #include From 5fff57362e462cc424ff574df480140b3769601b Mon Sep 17 00:00:00 2001 From: Daan De Meyer Date: Tue, 20 May 2025 10:46:28 +0200 Subject: [PATCH 8/8] meson: Use hyphens everywhere in gperf.c filenames --- src/home/meson.build | 2 +- src/login/meson.build | 2 +- src/resolve/meson.build | 4 ++-- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/home/meson.build b/src/home/meson.build index 10e794bd70..c549adf79d 100644 --- a/src/home/meson.build +++ b/src/home/meson.build @@ -42,7 +42,7 @@ if conf.get('HAVE_LIBFIDO2') == 1 endif homed_gperf_c = custom_target( - 'homed_gperf.c', + 'homed-gperf.c', input : 'homed-gperf.gperf', output : 'homed-gperf.c', command : [gperf, '@INPUT@', '--output-file', '@OUTPUT@']) diff --git a/src/login/meson.build b/src/login/meson.build index 8e3212a0f6..46eb392b6c 100644 --- a/src/login/meson.build +++ b/src/login/meson.build @@ -29,7 +29,7 @@ systemd_logind_extract_sources = files( ) logind_gperf_c = custom_target( - 'logind_gperf.c', + 'logind-gperf.c', input : 'logind-gperf.gperf', output : 'logind-gperf.c', command : [gperf, '@INPUT@', '--output-file', '@OUTPUT@']) diff --git a/src/resolve/meson.build b/src/resolve/meson.build index 2c20a8299d..a814551a9b 100644 --- a/src/resolve/meson.build +++ b/src/resolve/meson.build @@ -79,13 +79,13 @@ dns_type_to_name_h = custom_target( capture : true) resolved_gperf_c = custom_target( - 'resolved_gperf.c', + 'resolved-gperf.c', input : 'resolved-gperf.gperf', output : 'resolved-gperf.c', command : [gperf, '@INPUT@', '--output-file', '@OUTPUT@']) resolved_dnssd_gperf_c = custom_target( - 'resolved_dnssd_gperf.c', + 'resolved-dnssd-gperf.c', input : 'resolved-dnssd-gperf.gperf', output : 'resolved-dnssd-gperf.c', command : [gperf, '@INPUT@', '--output-file', '@OUTPUT@'])