diff --git a/.abignore b/.abignore deleted file mode 100644 index 6a33b88..0000000 --- a/.abignore +++ /dev/null @@ -1,3 +0,0 @@ -[suppress_file] -# Those shared objects are private to systemd -file_name_regexp=libsystemd-(shared|core)-.*.so diff --git a/.editorconfig b/.editorconfig new file mode 100644 index 0000000..1b58baf --- /dev/null +++ b/.editorconfig @@ -0,0 +1,11 @@ +root = true + +[*] +charset = utf-8 +indent_size = 4 +indent_style = space +insert_final_newline = true +trim_trailing_whitespace = true + +[*.{yml,yaml}] +indent_size = 2 diff --git a/.fmf/version b/.fmf/version new file mode 100644 index 0000000..d00491f --- /dev/null +++ b/.fmf/version @@ -0,0 +1 @@ +1 diff --git a/.gitignore b/.gitignore index 6cf7897..ca73e11 100644 --- a/.gitignore +++ b/.gitignore @@ -7,3 +7,7 @@ /systemd-*.tar.xz /systemd-*.tar.gz /*.rpm +/mkosi.output/ +/mkosi.cache/ +/mkosi.builddir/ +/mkosi.local.conf diff --git a/0001-Revert-network-lldp-do-not-save-LLDP-neighbors-under.patch b/0001-Revert-network-lldp-do-not-save-LLDP-neighbors-under.patch deleted file mode 100644 index 1fdbd67..0000000 --- a/0001-Revert-network-lldp-do-not-save-LLDP-neighbors-under.patch +++ /dev/null @@ -1,240 +0,0 @@ -From d8798eb733d5680047128ec1f74c82f347c321ed Mon Sep 17 00:00:00 2001 -From: Ryan Wilson -Date: Wed, 4 Dec 2024 16:53:40 -0800 -Subject: [PATCH] Revert "network/lldp: do not save LLDP neighbors under - /run/systemd" - -This reverts commit 5a0f6adbb2e39914897f404ac97fecebcc2c385a. ---- - src/libsystemd-network/lldp-neighbor.c | 11 ++++ - src/network/networkd-link.c | 7 ++- - src/network/networkd-link.h | 1 + - src/network/networkd-lldp-rx.c | 69 ++++++++++++++++++++++++++ - src/network/networkd-lldp-rx.h | 1 + - src/network/networkd-state-file.c | 2 + - src/network/networkd.c | 3 +- - src/systemd/sd-lldp-rx.h | 1 + - tmpfiles.d/systemd-network.conf | 1 + - 9 files changed, 94 insertions(+), 2 deletions(-) - -diff --git a/src/libsystemd-network/lldp-neighbor.c b/src/libsystemd-network/lldp-neighbor.c -index 02af2954ae..3d381294e6 100644 ---- a/src/libsystemd-network/lldp-neighbor.c -+++ b/src/libsystemd-network/lldp-neighbor.c -@@ -376,6 +376,17 @@ int sd_lldp_neighbor_get_destination_address(sd_lldp_neighbor *n, struct ether_a - return 0; - } - -+int sd_lldp_neighbor_get_raw(sd_lldp_neighbor *n, const void **ret, size_t *size) { -+ assert_return(n, -EINVAL); -+ assert_return(ret, -EINVAL); -+ assert_return(size, -EINVAL); -+ -+ *ret = LLDP_NEIGHBOR_RAW(n); -+ *size = n->raw_size; -+ -+ return 0; -+} -+ - int sd_lldp_neighbor_get_chassis_id(sd_lldp_neighbor *n, uint8_t *type, const void **ret, size_t *size) { - assert_return(n, -EINVAL); - assert_return(type, -EINVAL); -diff --git a/src/network/networkd-link.c b/src/network/networkd-link.c -index 9ce75361fd..0436233ac9 100644 ---- a/src/network/networkd-link.c -+++ b/src/network/networkd-link.c -@@ -273,6 +273,7 @@ static Link *link_free(Link *link) { - free(link->driver); - - unlink_and_free(link->lease_file); -+ unlink_and_free(link->lldp_file); - unlink_and_free(link->state_file); - - sd_device_unref(link->dev); -@@ -2645,7 +2646,7 @@ static Link *link_drop_or_unref(Link *link) { - DEFINE_TRIVIAL_CLEANUP_FUNC(Link*, link_drop_or_unref); - - static int link_new(Manager *manager, sd_netlink_message *message, Link **ret) { -- _cleanup_free_ char *ifname = NULL, *kind = NULL, *state_file = NULL, *lease_file = NULL; -+ _cleanup_free_ char *ifname = NULL, *kind = NULL, *state_file = NULL, *lease_file = NULL, *lldp_file = NULL; - _cleanup_(link_drop_or_unrefp) Link *link = NULL; - unsigned short iftype; - int r, ifindex; -@@ -2686,6 +2687,9 @@ static int link_new(Manager *manager, sd_netlink_message *message, Link **ret) { - - if (asprintf(&lease_file, "/run/systemd/netif/leases/%d", ifindex) < 0) - return log_oom_debug(); -+ -+ if (asprintf(&lldp_file, "/run/systemd/netif/lldp/%d", ifindex) < 0) -+ return log_oom_debug(); - } - - link = new(Link, 1); -@@ -2708,6 +2712,7 @@ static int link_new(Manager *manager, sd_netlink_message *message, Link **ret) { - - .state_file = TAKE_PTR(state_file), - .lease_file = TAKE_PTR(lease_file), -+ .lldp_file = TAKE_PTR(lldp_file), - - .n_dns = UINT_MAX, - .dns_default_route = -1, -diff --git a/src/network/networkd-link.h b/src/network/networkd-link.h -index b1b2fe42db..d590d071bd 100644 ---- a/src/network/networkd-link.h -+++ b/src/network/networkd-link.h -@@ -184,6 +184,7 @@ typedef struct Link { - - /* This is about LLDP reception */ - sd_lldp_rx *lldp_rx; -+ char *lldp_file; - - /* This is about LLDP transmission */ - sd_lldp_tx *lldp_tx; -diff --git a/src/network/networkd-lldp-rx.c b/src/network/networkd-lldp-rx.c -index f74485488e..c45d3e32d7 100644 ---- a/src/network/networkd-lldp-rx.c -+++ b/src/network/networkd-lldp-rx.c -@@ -52,6 +52,8 @@ static void lldp_rx_handler(sd_lldp_rx *lldp_rx, sd_lldp_rx_event_t event, sd_ll - Link *link = ASSERT_PTR(userdata); - int r; - -+ (void) link_lldp_save(link); -+ - if (link->lldp_tx && event == SD_LLDP_RX_EVENT_ADDED) { - /* If we received information about a new neighbor, restart the LLDP "fast" logic */ - -@@ -102,3 +104,70 @@ int link_lldp_rx_configure(Link *link) { - - return 0; - } -+ -+int link_lldp_save(Link *link) { -+ _cleanup_(unlink_and_freep) char *temp_path = NULL; -+ _cleanup_fclose_ FILE *f = NULL; -+ sd_lldp_neighbor **l = NULL; -+ int n = 0, r, i; -+ -+ assert(link); -+ -+ if (isempty(link->lldp_file)) -+ return 0; /* Do not update state file when running in test mode. */ -+ -+ if (!link->lldp_rx) { -+ (void) unlink(link->lldp_file); -+ return 0; -+ } -+ -+ r = sd_lldp_rx_get_neighbors(link->lldp_rx, &l); -+ if (r < 0) -+ return r; -+ if (r == 0) { -+ (void) unlink(link->lldp_file); -+ return 0; -+ } -+ -+ n = r; -+ -+ r = fopen_temporary(link->lldp_file, &f, &temp_path); -+ if (r < 0) -+ goto finish; -+ -+ (void) fchmod(fileno(f), 0644); -+ -+ for (i = 0; i < n; i++) { -+ const void *p; -+ le64_t u; -+ size_t sz; -+ -+ r = sd_lldp_neighbor_get_raw(l[i], &p, &sz); -+ if (r < 0) -+ goto finish; -+ -+ u = htole64(sz); -+ fwrite(&u, 1, sizeof(u), f); -+ fwrite(p, 1, sz, f); -+ } -+ -+ r = fflush_and_check(f); -+ if (r < 0) -+ goto finish; -+ -+ r = conservative_rename(temp_path, link->lldp_file); -+ if (r < 0) -+ goto finish; -+ -+finish: -+ if (r < 0) -+ log_link_error_errno(link, r, "Failed to save LLDP data to %s: %m", link->lldp_file); -+ -+ if (l) { -+ for (i = 0; i < n; i++) -+ sd_lldp_neighbor_unref(l[i]); -+ free(l); -+ } -+ -+ return r; -+} -diff --git a/src/network/networkd-lldp-rx.h b/src/network/networkd-lldp-rx.h -index 75c9f8ca86..22f6602bd0 100644 ---- a/src/network/networkd-lldp-rx.h -+++ b/src/network/networkd-lldp-rx.h -@@ -14,6 +14,7 @@ typedef enum LLDPMode { - } LLDPMode; - - int link_lldp_rx_configure(Link *link); -+int link_lldp_save(Link *link); - - const char* lldp_mode_to_string(LLDPMode m) _const_; - LLDPMode lldp_mode_from_string(const char *s) _pure_; -diff --git a/src/network/networkd-state-file.c b/src/network/networkd-state-file.c -index fbe4fee17d..bc08a84c74 100644 ---- a/src/network/networkd-state-file.c -+++ b/src/network/networkd-state-file.c -@@ -584,6 +584,8 @@ static int link_save(Link *link) { - if (link->state == LINK_STATE_LINGER) - return 0; - -+ link_lldp_save(link); -+ - admin_state = link_state_to_string(link->state); - assert(admin_state); - -diff --git a/src/network/networkd.c b/src/network/networkd.c -index 69a28647c8..3384c7c3ea 100644 ---- a/src/network/networkd.c -+++ b/src/network/networkd.c -@@ -72,7 +72,8 @@ static int run(int argc, char *argv[]) { - * to support old kernels not supporting AmbientCapabilities=. */ - FOREACH_STRING(p, - "/run/systemd/netif/links/", -- "/run/systemd/netif/leases/") { -+ "/run/systemd/netif/leases/", -+ "/run/systemd/netif/lldp/") { - r = mkdir_safe_label(p, 0755, UID_INVALID, GID_INVALID, MKDIR_WARN_MODE); - if (r < 0) - log_warning_errno(r, "Could not create directory '%s': %m", p); -diff --git a/src/systemd/sd-lldp-rx.h b/src/systemd/sd-lldp-rx.h -index 154e37e2d8..a876e41b25 100644 ---- a/src/systemd/sd-lldp-rx.h -+++ b/src/systemd/sd-lldp-rx.h -@@ -75,6 +75,7 @@ sd_lldp_neighbor *sd_lldp_neighbor_unref(sd_lldp_neighbor *n); - int sd_lldp_neighbor_get_source_address(sd_lldp_neighbor *n, struct ether_addr* address); - int sd_lldp_neighbor_get_destination_address(sd_lldp_neighbor *n, struct ether_addr* address); - int sd_lldp_neighbor_get_timestamp(sd_lldp_neighbor *n, clockid_t clock, uint64_t *ret); -+int sd_lldp_neighbor_get_raw(sd_lldp_neighbor *n, const void **ret, size_t *size); - - /* High-level, direct, parsed out field access. These fields exist at most once, hence may be queried directly. */ - int sd_lldp_neighbor_get_chassis_id(sd_lldp_neighbor *n, uint8_t *type, const void **ret, size_t *size); -diff --git a/tmpfiles.d/systemd-network.conf b/tmpfiles.d/systemd-network.conf -index 323beca59c..107317a03c 100644 ---- a/tmpfiles.d/systemd-network.conf -+++ b/tmpfiles.d/systemd-network.conf -@@ -10,4 +10,5 @@ - d /run/systemd/netif 0755 systemd-network systemd-network - - d /run/systemd/netif/links 0755 systemd-network systemd-network - - d /run/systemd/netif/leases 0755 systemd-network systemd-network - -+d /run/systemd/netif/lldp 0755 systemd-network systemd-network - - d /var/lib/systemd/network 0755 systemd-network systemd-network - --- -2.43.5 - diff --git a/0001-Revert-units-use-PrivateTmp-disconnected-instead-of-.patch b/0001-Revert-units-use-PrivateTmp-disconnected-instead-of-.patch new file mode 100644 index 0000000..eca67f0 --- /dev/null +++ b/0001-Revert-units-use-PrivateTmp-disconnected-instead-of-.patch @@ -0,0 +1,69 @@ +From 0792bb7a9d25a1ab8a5f208f2f5cea8a362dc1c6 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Zbigniew=20J=C4=99drzejewski-Szmek?= +Date: Fri, 10 Jan 2025 17:00:08 +0100 +Subject: [PATCH] Revert "units: use PrivateTmp=disconnected instead of 'yes' + if DefaultDependencies=no" + +This reverts commit 1f6e1928488d461d19fd1e4b4d645b0ea5ea8bf5. +--- + units/systemd-coredump@.service.in | 2 +- + units/systemd-oomd.service.in | 2 +- + units/systemd-resolved.service.in | 2 +- + units/systemd-timesyncd.service.in | 2 +- + 4 files changed, 4 insertions(+), 4 deletions(-) + +diff --git a/units/systemd-coredump@.service.in b/units/systemd-coredump@.service.in +index c74dc7a5a1..fa3206d07b 100644 +--- a/units/systemd-coredump@.service.in ++++ b/units/systemd-coredump@.service.in +@@ -26,7 +26,7 @@ NoNewPrivileges=yes + OOMScoreAdjust=500 + PrivateDevices=yes + PrivateNetwork=yes +-PrivateTmp=disconnected ++PrivateTmp=yes + ProtectControlGroups=yes + ProtectHome=read-only + ProtectHostname=yes +diff --git a/units/systemd-oomd.service.in b/units/systemd-oomd.service.in +index 670d5e6140..82bd6245f8 100644 +--- a/units/systemd-oomd.service.in ++++ b/units/systemd-oomd.service.in +@@ -37,7 +37,7 @@ MemoryLow=64M + NoNewPrivileges=yes + OOMScoreAdjust=-900 + PrivateDevices=yes +-PrivateTmp=disconnected ++PrivateTmp=yes + ProtectClock=yes + ProtectHome=yes + ProtectHostname=yes +diff --git a/units/systemd-resolved.service.in b/units/systemd-resolved.service.in +index e181b2528a..4aa0788ac4 100644 +--- a/units/systemd-resolved.service.in ++++ b/units/systemd-resolved.service.in +@@ -29,7 +29,7 @@ LockPersonality=yes + MemoryDenyWriteExecute=yes + NoNewPrivileges=yes + PrivateDevices=yes +-PrivateTmp=disconnected ++PrivateTmp=yes + ProtectClock=yes + ProtectControlGroups=yes + ProtectHome=yes +diff --git a/units/systemd-timesyncd.service.in b/units/systemd-timesyncd.service.in +index 835d6327e7..cf233fbffd 100644 +--- a/units/systemd-timesyncd.service.in ++++ b/units/systemd-timesyncd.service.in +@@ -31,7 +31,7 @@ LockPersonality=yes + MemoryDenyWriteExecute=yes + NoNewPrivileges=yes + PrivateDevices=yes +-PrivateTmp=disconnected ++PrivateTmp=yes + ProtectProc=invisible + ProtectControlGroups=yes + ProtectHome=yes +-- +2.47.1 + diff --git a/0001-networkctl-Make-lldp-status-backwards-compatible-wit.patch b/0001-networkctl-Make-lldp-status-backwards-compatible-wit.patch deleted file mode 100644 index dc78857..0000000 --- a/0001-networkctl-Make-lldp-status-backwards-compatible-wit.patch +++ /dev/null @@ -1,328 +0,0 @@ -From 11d47b91b0fd35aaf2db486783d80bdca7229d82 Mon Sep 17 00:00:00 2001 -From: Ryan Wilson -Date: Wed, 4 Dec 2024 16:15:30 -0800 -Subject: [PATCH] networkctl: Make lldp/status backwards compatible with 255 - over dbus - ---- - src/libsystemd-network/lldp-neighbor.c | 22 +++ - src/network/networkctl.c | 208 ++++++++++++++++++++++++- - src/systemd/sd-lldp-rx.h | 1 + - 3 files changed, 224 insertions(+), 7 deletions(-) - -diff --git a/src/libsystemd-network/lldp-neighbor.c b/src/libsystemd-network/lldp-neighbor.c -index a4384ac2e1..02af2954ae 100644 ---- a/src/libsystemd-network/lldp-neighbor.c -+++ b/src/libsystemd-network/lldp-neighbor.c -@@ -629,6 +629,28 @@ int sd_lldp_neighbor_get_enabled_capabilities(sd_lldp_neighbor *n, uint16_t *ret - return 0; - } - -+int sd_lldp_neighbor_from_raw(sd_lldp_neighbor **ret, const void *raw, size_t raw_size) { -+ _cleanup_(sd_lldp_neighbor_unrefp) sd_lldp_neighbor *n = NULL; -+ int r; -+ -+ assert_return(ret, -EINVAL); -+ assert_return(raw || raw_size <= 0, -EINVAL); -+ -+ n = lldp_neighbor_new(raw_size); -+ if (!n) -+ return -ENOMEM; -+ -+ memcpy_safe(LLDP_NEIGHBOR_RAW(n), raw, raw_size); -+ -+ r = lldp_neighbor_parse(n); -+ if (r < 0) -+ return r; -+ -+ *ret = TAKE_PTR(n); -+ -+ return r; -+} -+ - int sd_lldp_neighbor_tlv_rewind(sd_lldp_neighbor *n) { - assert_return(n, -EINVAL); - -diff --git a/src/network/networkctl.c b/src/network/networkctl.c -index a447c39a64..e31018e813 100644 ---- a/src/network/networkctl.c -+++ b/src/network/networkctl.c -@@ -16,6 +16,7 @@ - #include "sd-device.h" - #include "sd-dhcp-client.h" - #include "sd-hwdb.h" -+#include "sd-lldp-rx.h" - #include "sd-netlink.h" - #include "sd-network.h" - -@@ -173,7 +174,7 @@ int acquire_bus(sd_bus **ret) { - if (networkd_is_running()) { - r = varlink_connect_networkd(/* ret_varlink = */ NULL); - if (r < 0) -- return r; -+ log_warning("Varlink connection failed, fallback to D-Bus."); - } else - log_warning("systemd-networkd is not running, output might be incomplete."); - -@@ -1410,6 +1411,99 @@ static int dump_lldp_neighbors(Varlink *vl, Table *table, int ifindex) { - return dump_list(table, "Connected To", buf); - } - -+static int open_lldp_neighbors_legacy(int ifindex, FILE **ret) { -+ _cleanup_fclose_ FILE *f = NULL; -+ char p[STRLEN("/run/systemd/netif/lldp/") + DECIMAL_STR_MAX(int)]; -+ -+ assert(ifindex >= 0); -+ assert(ret); -+ -+ xsprintf(p, "/run/systemd/netif/lldp/%i", ifindex); -+ -+ f = fopen(p, "re"); -+ if (!f) -+ return -errno; -+ -+ *ret = TAKE_PTR(f); -+ return 0; -+} -+ -+static int next_lldp_neighbor_legacy(FILE *f, sd_lldp_neighbor **ret) { -+ _cleanup_free_ void *raw = NULL; -+ size_t l; -+ le64_t u; -+ int r; -+ -+ assert(f); -+ assert(ret); -+ -+ l = fread(&u, 1, sizeof(u), f); -+ if (l == 0 && feof(f)) -+ return 0; -+ if (l != sizeof(u)) -+ return -EBADMSG; -+ -+ /* each LLDP packet is at most MTU size, but let's allow up to 4KiB just in case */ -+ if (le64toh(u) >= 4096) -+ return -EBADMSG; -+ -+ raw = new(uint8_t, le64toh(u)); -+ if (!raw) -+ return -ENOMEM; -+ -+ if (fread(raw, 1, le64toh(u), f) != le64toh(u)) -+ return -EBADMSG; -+ -+ r = sd_lldp_neighbor_from_raw(ret, raw, le64toh(u)); -+ if (r < 0) -+ return r; -+ -+ return 1; -+} -+ -+static int dump_lldp_neighbors_legacy(Table *table, const char *prefix, int ifindex) { -+ _cleanup_strv_free_ char **buf = NULL; -+ _cleanup_fclose_ FILE *f = NULL; -+ int r; -+ -+ assert(table); -+ assert(prefix); -+ assert(ifindex > 0); -+ -+ r = open_lldp_neighbors_legacy(ifindex, &f); -+ if (r == -ENOENT) -+ return 0; -+ if (r < 0) -+ return r; -+ -+ for (;;) { -+ const char *system_name = NULL, *port_id = NULL, *port_description = NULL; -+ _cleanup_(sd_lldp_neighbor_unrefp) sd_lldp_neighbor *n = NULL; -+ -+ r = next_lldp_neighbor_legacy(f, &n); -+ if (r < 0) -+ return r; -+ if (r == 0) -+ break; -+ -+ (void) sd_lldp_neighbor_get_system_name(n, &system_name); -+ (void) sd_lldp_neighbor_get_port_id_as_string(n, &port_id); -+ (void) sd_lldp_neighbor_get_port_description(n, &port_description); -+ -+ r = strv_extendf(&buf, "%s on port %s%s%s%s", -+ strna(system_name), -+ strna(port_id), -+ isempty(port_description) ? "" : " (", -+ strempty(port_description), -+ isempty(port_description) ? "" : ")"); -+ if (r < 0) -+ return log_oom(); -+ } -+ -+ return dump_list(table, prefix, buf); -+} -+ -+ - static int dump_dhcp_leases(Table *table, const char *prefix, sd_bus *bus, const LinkInfo *link) { - _cleanup_strv_free_ char **buf = NULL; - _cleanup_(sd_bus_message_unrefp) sd_bus_message *reply = NULL; -@@ -1696,7 +1790,6 @@ static int link_status_one( - - assert(bus); - assert(rtnl); -- assert(vl); - assert(info); - - (void) sd_network_link_get_operational_state(info->ifindex, &operational_state); -@@ -2315,7 +2408,7 @@ static int link_status_one( - return table_log_add_error(r); - } - -- r = dump_lldp_neighbors(vl, table, info->ifindex); -+ r = vl ? dump_lldp_neighbors(vl, table, info->ifindex) : dump_lldp_neighbors_legacy(table, "Connected To", info->ifindex); - if (r < 0) - return r; - -@@ -2449,8 +2542,10 @@ static int link_status(int argc, char *argv[], void *userdata) { - log_debug_errno(r, "Failed to open hardware database: %m"); - - r = varlink_connect_networkd(&vl); -- if (r < 0) -- return r; -+ if (r < 0) { -+ log_warning("Varlink connection failed, fallback to D-Bus."); -+ vl = NULL; -+ } - - if (arg_all) - c = acquire_link_info(bus, rtnl, NULL, &links); -@@ -2584,6 +2679,103 @@ static int dump_lldp_neighbors_json(JsonVariant *reply, char * const *patterns) - return json_variant_dump(v, arg_json_format_flags, NULL, NULL); - } - -+static int link_lldp_status_legacy(int argc, char *argv[], void *userdata) { -+ _cleanup_(sd_netlink_unrefp) sd_netlink *rtnl = NULL; -+ _cleanup_(link_info_array_freep) LinkInfo *links = NULL; -+ _cleanup_(table_unrefp) Table *table = NULL; -+ int r, c, m = 0; -+ uint16_t all = 0; -+ TableCell *cell; -+ -+ r = sd_netlink_open(&rtnl); -+ if (r < 0) -+ return log_error_errno(r, "Failed to connect to netlink: %m"); -+ -+ c = acquire_link_info(NULL, rtnl, argc > 1 ? argv + 1 : NULL, &links); -+ if (c < 0) -+ return c; -+ -+ pager_open(arg_pager_flags); -+ -+ table = table_new("link", -+ "chassis-id", -+ "system-name", -+ "caps", -+ "port-id", -+ "port-description"); -+ if (!table) -+ return log_oom(); -+ -+ if (arg_full) -+ table_set_width(table, 0); -+ -+ table_set_header(table, arg_legend); -+ -+ assert_se(cell = table_get_cell(table, 0, 3)); -+ table_set_minimum_width(table, cell, 11); -+ table_set_ersatz_string(table, TABLE_ERSATZ_DASH); -+ -+ FOREACH_ARRAY(link, links, c) { -+ _cleanup_fclose_ FILE *f = NULL; -+ -+ r = open_lldp_neighbors_legacy(link->ifindex, &f); -+ if (r == -ENOENT) -+ continue; -+ if (r < 0) { -+ log_warning_errno(r, "Failed to open LLDP data for %i, ignoring: %m", link->ifindex); -+ continue; -+ } -+ -+ for (;;) { -+ const char *chassis_id = NULL, *port_id = NULL, *system_name = NULL, *port_description = NULL; -+ _cleanup_(sd_lldp_neighbor_unrefp) sd_lldp_neighbor *n = NULL; -+ _cleanup_free_ char *capabilities = NULL; -+ uint16_t cc; -+ -+ r = next_lldp_neighbor_legacy(f, &n); -+ if (r < 0) { -+ log_warning_errno(r, "Failed to read neighbor data: %m"); -+ break; -+ } -+ if (r == 0) -+ break; -+ -+ (void) sd_lldp_neighbor_get_chassis_id_as_string(n, &chassis_id); -+ (void) sd_lldp_neighbor_get_port_id_as_string(n, &port_id); -+ (void) sd_lldp_neighbor_get_system_name(n, &system_name); -+ (void) sd_lldp_neighbor_get_port_description(n, &port_description); -+ -+ if (sd_lldp_neighbor_get_enabled_capabilities(n, &cc) >= 0) { -+ capabilities = lldp_capabilities_to_string(cc); -+ all |= cc; -+ } -+ -+ r = table_add_many(table, -+ TABLE_STRING, link->name, -+ TABLE_STRING, chassis_id, -+ TABLE_STRING, system_name, -+ TABLE_STRING, capabilities, -+ TABLE_STRING, port_id, -+ TABLE_STRING, port_description); -+ if (r < 0) -+ return table_log_add_error(r); -+ -+ m++; -+ } -+ } -+ -+ r = table_print(table, NULL); -+ if (r < 0) -+ return table_log_print_error(r); -+ -+ if (arg_legend) { -+ lldp_capabilities_legend(all); -+ printf("\n%i neighbors listed.\n", m); -+ } -+ -+ return 0; -+} -+ - static int link_lldp_status(int argc, char *argv[], void *userdata) { - _cleanup_(varlink_flush_close_unrefp) Varlink *vl = NULL; - _cleanup_(table_unrefp) Table *table = NULL; -@@ -2594,8 +2786,10 @@ static int link_lldp_status(int argc, char *argv[], void *userdata) { - int r; - - r = varlink_connect_networkd(&vl); -- if (r < 0) -- return r; -+ if (r < 0) { -+ log_warning("Varlink connection failed, fallback to D-Bus."); -+ return link_lldp_status_legacy(argc, argv, userdata); -+ } - - r = varlink_call_and_log(vl, "io.systemd.Network.GetLLDPNeighbors", NULL, &reply); - if (r < 0) -diff --git a/src/systemd/sd-lldp-rx.h b/src/systemd/sd-lldp-rx.h -index a7e1a9f376..154e37e2d8 100644 ---- a/src/systemd/sd-lldp-rx.h -+++ b/src/systemd/sd-lldp-rx.h -@@ -88,6 +88,7 @@ int sd_lldp_neighbor_get_port_description(sd_lldp_neighbor *n, const char **ret) - int sd_lldp_neighbor_get_mud_url(sd_lldp_neighbor *n, const char **ret); - int sd_lldp_neighbor_get_system_capabilities(sd_lldp_neighbor *n, uint16_t *ret); - int sd_lldp_neighbor_get_enabled_capabilities(sd_lldp_neighbor *n, uint16_t *ret); -+int sd_lldp_neighbor_from_raw(sd_lldp_neighbor **ret, const void *raw, size_t raw_size); - - /* Low-level, iterative TLV access. This is for everything else, it iteratively goes through all available TLVs - * (including the ones covered with the calls above), and allows multiple TLVs for the same fields. */ --- -2.43.5 - diff --git a/0001-networkctl-Make-networkctl-lldp-output-backwards-com.patch b/0001-networkctl-Make-networkctl-lldp-output-backwards-com.patch deleted file mode 100644 index f284573..0000000 --- a/0001-networkctl-Make-networkctl-lldp-output-backwards-com.patch +++ /dev/null @@ -1,58 +0,0 @@ -From 7d236cbb2ceea8881e57d9f2e2af091088c4f178 Mon Sep 17 00:00:00 2001 -From: Ryan Wilson -Date: Tue, 3 Dec 2024 14:46:54 -0800 -Subject: [PATCH] networkctl: Make networkctl lldp output backwards compatible - with 255 - ---- - src/network/networkctl.c | 16 +++++++--------- - 1 file changed, 7 insertions(+), 9 deletions(-) - -diff --git a/src/network/networkctl.c b/src/network/networkctl.c -index a447c39a64..8b15ba1fdf 100644 ---- a/src/network/networkctl.c -+++ b/src/network/networkctl.c -@@ -2608,12 +2608,11 @@ static int link_lldp_status(int argc, char *argv[], void *userdata) { - - table = table_new("index", - "link", -- "system-name", -- "system-description", - "chassis-id", -+ "system-name", -+ "caps", - "port-id", -- "port-description", -- "caps"); -+ "port-description"); - if (!table) - return log_oom(); - -@@ -2626,7 +2625,7 @@ static int link_lldp_status(int argc, char *argv[], void *userdata) { - table_hide_column_from_display(table, (size_t) 0); - - /* Make the capabilities not truncated */ -- assert_se(cell = table_get_cell(table, 0, 7)); -+ assert_se(cell = table_get_cell(table, 0, 4)); - table_set_minimum_width(table, cell, 11); - - JsonVariant *i; -@@ -2655,12 +2654,11 @@ static int link_lldp_status(int argc, char *argv[], void *userdata) { - r = table_add_many(table, - TABLE_INT, info.ifindex, - TABLE_STRING, info.ifname, -- TABLE_STRING, neighbor_info.system_name, -- TABLE_STRING, neighbor_info.system_description, - TABLE_STRING, neighbor_info.chassis_id, -+ TABLE_STRING, neighbor_info.system_name, -+ TABLE_STRING, cap_str, - TABLE_STRING, neighbor_info.port_id, -- TABLE_STRING, neighbor_info.port_description, -- TABLE_STRING, cap_str); -+ TABLE_STRING, neighbor_info.port_description); - if (r < 0) - return table_log_add_error(r); - --- -2.43.5 - diff --git a/0001-tmpfiles-make-purge-hard-to-mis-use.patch b/0001-tmpfiles-make-purge-hard-to-mis-use.patch deleted file mode 100644 index 033b575..0000000 --- a/0001-tmpfiles-make-purge-hard-to-mis-use.patch +++ /dev/null @@ -1,88 +0,0 @@ -From 1e788a7fb535a37a8268aa7dc5130f670eb72a6b Mon Sep 17 00:00:00 2001 -From: Daan De Meyer -Date: Tue, 23 Jul 2024 13:14:05 +0200 -Subject: [PATCH] tmpfiles: make --purge hard to (mis-)use - -Follow-up for https://github.com/systemd/systemd/pull/33383. ---- - src/tmpfiles/tmpfiles.c | 17 +++++++++++++++++ - test/units/TEST-22-TMPFILES.18.sh | 4 ++-- - 2 files changed, 19 insertions(+), 2 deletions(-) - -diff --git a/src/tmpfiles/tmpfiles.c b/src/tmpfiles/tmpfiles.c -index 8cc8c1ccd6..14048545db 100644 ---- a/src/tmpfiles/tmpfiles.c -+++ b/src/tmpfiles/tmpfiles.c -@@ -4197,6 +4197,7 @@ static int parse_argv(int argc, char *argv[]) { - ARG_IMAGE_POLICY, - ARG_REPLACE, - ARG_DRY_RUN, -+ ARG_DESTROY_DATA, - ARG_NO_PAGER, - }; - -@@ -4220,10 +4221,18 @@ static int parse_argv(int argc, char *argv[]) { - { "replace", required_argument, NULL, ARG_REPLACE }, - { "dry-run", no_argument, NULL, ARG_DRY_RUN }, - { "no-pager", no_argument, NULL, ARG_NO_PAGER }, -+ -+ /* This is not documented on purpose. -+ * If you think --purge should be allowed without jumping through hoops, -+ * consider opening a bug report with the description of the use case. -+ */ -+ { "destroy-data", no_argument, NULL, ARG_DESTROY_DATA }, -+ - {} - }; - - int c, r; -+ bool destroy_data = false; - - assert(argc >= 0); - assert(argv); -@@ -4330,6 +4339,10 @@ static int parse_argv(int argc, char *argv[]) { - arg_dry_run = true; - break; - -+ case ARG_DESTROY_DATA: -+ destroy_data = true; -+ break; -+ - case ARG_NO_PAGER: - arg_pager_flags |= PAGER_DISABLE; - break; -@@ -4349,6 +4362,10 @@ static int parse_argv(int argc, char *argv[]) { - return log_error_errno(SYNTHETIC_ERRNO(EINVAL), - "Refusing --purge without specification of a configuration file."); - -+ if (FLAGS_SET(arg_operation, OPERATION_PURGE) && !arg_dry_run && !destroy_data) -+ return log_error_errno(SYNTHETIC_ERRNO(EINVAL), -+ "Refusing --purge without --destroy-data."); -+ - if (arg_replace && arg_cat_flags != CAT_CONFIG_OFF) - return log_error_errno(SYNTHETIC_ERRNO(EINVAL), - "Option --replace= is not supported with --cat-config/--tldr."); -diff --git a/test/units/TEST-22-TMPFILES.18.sh b/test/units/TEST-22-TMPFILES.18.sh -index 5d24197c81..de23bbb95f 100755 ---- a/test/units/TEST-22-TMPFILES.18.sh -+++ b/test/units/TEST-22-TMPFILES.18.sh -@@ -21,7 +21,7 @@ systemd-tmpfiles --purge --dry-run - <<<"$c" - test -f /tmp/somedir/somefile - grep -q baz /tmp/somedir/somefile - --systemd-tmpfiles --purge - <<<"$c" -+systemd-tmpfiles --purge --destroy-data - <<<"$c" - test ! -f /tmp/somedir/somefile - test ! -d /tmp/somedir/ - -@@ -29,6 +29,6 @@ systemd-tmpfiles --create --purge --dry-run - <<<"$c" - test ! -f /tmp/somedir/somefile - test ! -d /tmp/somedir/ - --systemd-tmpfiles --create --purge - <<<"$c" -+systemd-tmpfiles --create --destroy-data --purge - <<<"$c" - test -f /tmp/somedir/somefile - grep -q baz /tmp/somedir/somefile --- -2.45.2 - diff --git a/0001-update-utmp-do-not-give-up-if-the-first-attempt-at-c.patch b/0001-update-utmp-do-not-give-up-if-the-first-attempt-at-c.patch new file mode 100644 index 0000000..76c2be1 --- /dev/null +++ b/0001-update-utmp-do-not-give-up-if-the-first-attempt-at-c.patch @@ -0,0 +1,75 @@ +From 8ed12b37afea9ccc36789aad2cef0d60eb6c5073 Mon Sep 17 00:00:00 2001 +From: Yu Watanabe +Date: Wed, 18 Dec 2024 22:27:29 +0900 +Subject: [PATCH 1/2] update-utmp: do not give up if the first attempt at + connecting bus failed +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +Otherwise, the program exits with failure if the first attempt in run() failed: +``` +Dec 18 20:27:37 systemd-update-utmp[254]: Bus n/a: changing state UNSET → OPENING +Dec 18 20:27:37 systemd-update-utmp[254]: sd-bus: starting bus by connecting to /run/systemd/private... +Dec 18 20:27:37 systemd-update-utmp[254]: Bus n/a: changing state OPENING → CLOSED +Dec 18 20:27:37 systemd-update-utmp[254]: Failed to get D-Bus connection: Connection refused +``` + +(cherry picked from commit 85d040dabd2cc67c89b7ed6157429b8f6f2240f4) +--- + src/update-utmp/update-utmp.c | 15 ++++++++++----- + 1 file changed, 10 insertions(+), 5 deletions(-) + +diff --git a/src/update-utmp/update-utmp.c b/src/update-utmp/update-utmp.c +index e40843cf35..a10e6d478a 100644 +--- a/src/update-utmp/update-utmp.c ++++ b/src/update-utmp/update-utmp.c +@@ -53,6 +53,12 @@ static int get_startup_monotonic_time(Context *c, usec_t *ret) { + assert(c); + assert(ret); + ++ if (!c->bus) { ++ r = bus_connect_system_systemd(&c->bus); ++ if (r < 0) ++ return log_warning_errno(r, "Failed to get D-Bus connection, ignoring: %m"); ++ } ++ + r = bus_get_property_trivial( + c->bus, + bus_systemd_mgr, +@@ -94,10 +100,13 @@ static int get_current_runlevel(Context *c) { + UINT64_C(100) * USEC_PER_MSEC + + random_u64_range(UINT64_C(1900) * USEC_PER_MSEC * n_attempts / MAX_ATTEMPTS); + (void) usleep_safe(usec); ++ } + ++ if (!c->bus) { + r = bus_connect_system_systemd(&c->bus); + if (r == -ECONNREFUSED && n_attempts < 64) { +- log_debug_errno(r, "Failed to reconnect to system bus, retrying after a slight delay: %m"); ++ log_debug_errno(r, "Failed to %s to system bus, retrying after a slight delay: %m", ++ n_attempts <= 1 ? "connect" : "reconnect"); + continue; + } + if (r < 0) +@@ -251,7 +260,6 @@ static int run(int argc, char *argv[]) { + .audit_fd = -EBADF, + #endif + }; +- int r; + + log_setup(); + +@@ -264,9 +272,6 @@ static int run(int argc, char *argv[]) { + log_full_errno(IN_SET(errno, EAFNOSUPPORT, EPROTONOSUPPORT) ? LOG_DEBUG : LOG_WARNING, + errno, "Failed to connect to audit log, ignoring: %m"); + #endif +- r = bus_connect_system_systemd(&c.bus); +- if (r < 0) +- return log_error_errno(r, "Failed to get D-Bus connection: %m"); + + return dispatch_verb(argc, argv, verbs, &c); + } +-- +2.47.1 + diff --git a/0002-sysusers-emit-audit-events-for-user-and-group-creati.patch b/0002-sysusers-emit-audit-events-for-user-and-group-creati.patch new file mode 100644 index 0000000..d442f5a --- /dev/null +++ b/0002-sysusers-emit-audit-events-for-user-and-group-creati.patch @@ -0,0 +1,287 @@ +From 398049208b4aae5f2a9f0d4914dee6ab6e101118 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Zbigniew=20J=C4=99drzejewski-Szmek?= +Date: Fri, 10 Jan 2025 15:35:13 +0100 +Subject: [PATCH 2/2] sysusers: emit audit events for user and group creation + +Background: Fedora/RHEL are switching to sysusers.d metadata for creation of +users and groups for system users defined by packages +(https://fedoraproject.org/wiki/Changes/RPMSuportForSystemdSysusers). +Packages carry sysusers files. During package installation, rpm calls an +program to execute on this config. This program may either be +/usr/lib/rpm/sysusers.sh which calls useradd/groupadd, or +/usr/bin/systemd-sysusers. To match the functionality provided by +useradd/groupadd from the shadow-utils project, systemd-sysusers must emit +audit events so that it provides a drop-in replacement. + +systemd-sysuers will emit audit events AUDIT_ADD_USER/AUDIT_ADD_GROUP when +adding users and groups. The operation "names" are copied from shadow-utils in +Fedora (which has a patch to change them from the upstream version), so the +format of the events that is generated on success should be identical. + +The helper code is shared between sysusers and utmp-wtmp. I changed the +audit_fd variable to be unconditional. This way we can avoid ugly iffdefery +every time the variable would be used. The cost is that 4 bytes of unused +storage might be present. This is negligible, and the compiler might even be +able to optimize that away if it inlines things. +--- + src/basic/audit-util.h | 33 +++++++++++++++++++++ + src/sysusers/meson.build | 2 ++ + src/sysusers/sysusers.c | 56 +++++++++++++++++++++++++++++++++++ + src/update-utmp/update-utmp.c | 23 ++------------ + 4 files changed, 94 insertions(+), 20 deletions(-) + +diff --git a/src/basic/audit-util.h b/src/basic/audit-util.h +index 9a74e4f102..d8ecf14f69 100644 +--- a/src/basic/audit-util.h ++++ b/src/basic/audit-util.h +@@ -1,10 +1,16 @@ + /* SPDX-License-Identifier: LGPL-2.1-or-later */ + #pragma once + ++#if HAVE_AUDIT ++# include ++#endif ++ + #include + #include + #include + ++#include "errno-util.h" ++#include "log.h" + #include "pidref.h" + + #define AUDIT_SESSION_INVALID UINT32_MAX +@@ -17,3 +23,30 @@ bool use_audit(void); + static inline bool audit_session_is_valid(uint32_t id) { + return id > 0 && id != AUDIT_SESSION_INVALID; + } ++ ++/* The wrappers for audit_open() and audit_close() are inline functions so that we don't get a spurious ++ * linkage to libaudit in libbasic, but we also don't need to create a separate source file for two very ++ * short functions. */ ++ ++static inline int close_audit_fd(int fd) { ++#if HAVE_AUDIT ++ if (fd >= 0) ++ audit_close(fd); ++#else ++ assert(fd < 0); ++#endif ++ return -EBADF; ++} ++ ++static inline int open_audit_fd_or_warn(void) { ++ int fd = -EBADF; ++ ++#if HAVE_AUDIT ++ /* If the kernel lacks netlink or audit support, don't worry about it. */ ++ fd = audit_open(); ++ if (fd < 0) ++ return log_full_errno(ERRNO_IS_NOT_SUPPORTED(errno) ? LOG_DEBUG : LOG_WARNING, ++ errno, "Failed to connect to audit log, ignoring: %m"); ++#endif ++ return fd; ++} +diff --git a/src/sysusers/meson.build b/src/sysusers/meson.build +index 123ff41d3f..c968f55110 100644 +--- a/src/sysusers/meson.build ++++ b/src/sysusers/meson.build +@@ -9,6 +9,7 @@ executables += [ + 'name' : 'systemd-sysusers', + 'public' : true, + 'sources' : files('sysusers.c'), ++ 'dependencies' : libaudit, + }, + executable_template + { + 'name' : 'systemd-sysusers.standalone', +@@ -20,6 +21,7 @@ executables += [ + libshared_static, + libsystemd_static, + ], ++ 'dependencies' : libaudit, + 'build_by_default' : have_standalone_binaries, + 'install' : have_standalone_binaries, + }, +diff --git a/src/sysusers/sysusers.c b/src/sysusers/sysusers.c +index 44253483db..84eb9fc0c3 100644 +--- a/src/sysusers/sysusers.c ++++ b/src/sysusers/sysusers.c +@@ -3,6 +3,7 @@ + #include + + #include "alloc-util.h" ++#include "audit-util.h" + #include "build.h" + #include "chase.h" + #include "conf-files.h" +@@ -106,6 +107,8 @@ STATIC_DESTRUCTOR_REGISTER(arg_image, freep); + STATIC_DESTRUCTOR_REGISTER(arg_image_policy, image_policy_freep); + + typedef struct Context { ++ int audit_fd; ++ + OrderedHashmap *users, *groups; + OrderedHashmap *todo_uids, *todo_gids; + OrderedHashmap *members; +@@ -126,6 +129,8 @@ typedef struct Context { + static void context_done(Context *c) { + assert(c); + ++ c->audit_fd = close_audit_fd(c->audit_fd); ++ + ordered_hashmap_free(c->groups); + ordered_hashmap_free(c->users); + ordered_hashmap_free(c->members); +@@ -163,6 +168,48 @@ static void maybe_emit_login_defs_warning(Context *c) { + c->login_defs_need_warning = false; + } + ++static void log_audit_accounts(Context *c, ItemType what) { ++#if HAVE_AUDIT ++ assert(c); ++ assert(IN_SET(what, ADD_USER, ADD_GROUP)); ++ ++ if (arg_dry_run || c->audit_fd < 0) ++ return; ++ ++ Item *i; ++ int type = what == ADD_USER ? AUDIT_ADD_USER : AUDIT_ADD_GROUP; ++ const char *op = what == ADD_USER ? "adding-user" : "adding-group"; ++ ++ /* Notes: ++ * ++ * The op must not contain whitespace. The format with a dash matches what Fedora shadow-utils uses. ++ * ++ * We send id == -1, even though we know the number, in particular on success. This is because if we ++ * send the id, the generated audit message will not contain the name. The name seems more useful ++ * than the number, hence send just the name: ++ * ++ * type=ADD_USER msg=audit(01/10/2025 16:02:00.639:3854) : ++ * pid=3846380 uid=root auid=zbyszek ses=2 msg='op=adding-user id=unknown(952) exe=systemd-sysusers ... res=success' ++ * vs. ++ * type=ADD_USER msg=audit(01/10/2025 16:03:15.457:3908) : ++ * pid=3846607 uid=root auid=zbyszek ses=2 msg='op=adding-user acct=foo5 exe=systemd-sysusers ... res=success' ++ */ ++ ++ ORDERED_HASHMAP_FOREACH(i, what == ADD_USER ? c->todo_uids : c->todo_gids) ++ audit_log_acct_message( ++ c->audit_fd, ++ type, ++ program_invocation_short_name, ++ op, ++ i->name, ++ /* id= */ (unsigned) -1, ++ /* host= */ NULL, ++ /* addr= */ NULL, ++ /* tty= */ NULL, ++ /* success= */ 1); ++#endif ++} ++ + static int load_user_database(Context *c) { + _cleanup_fclose_ FILE *f = NULL; + const char *passwd_path; +@@ -971,6 +1018,8 @@ static int write_files(Context *c) { + group_tmp, group_path); + group_tmp = mfree(group_tmp); + } ++ /* OK, we have written the group entries successfully */ ++ log_audit_accounts(c, ADD_GROUP); + if (gshadow) { + r = rename_and_apply_smack_floor_label(gshadow_tmp, gshadow_path); + if (r < 0) +@@ -988,6 +1037,8 @@ static int write_files(Context *c) { + + passwd_tmp = mfree(passwd_tmp); + } ++ /* OK, we have written the user entries successfully */ ++ log_audit_accounts(c, ADD_USER); + if (shadow) { + r = rename_and_apply_smack_floor_label(shadow_tmp, shadow_path); + if (r < 0) +@@ -2232,6 +2283,7 @@ static int run(int argc, char *argv[]) { + #endif + _cleanup_close_ int lock = -EBADF; + _cleanup_(context_done) Context c = { ++ .audit_fd = -EBADF, + .search_uid = UID_INVALID, + }; + +@@ -2281,6 +2333,10 @@ static int run(int argc, char *argv[]) { + assert(!arg_image); + #endif + ++ /* Prepare to emit audit events, but only if we're operating on the host system. */ ++ if (!arg_root) ++ c.audit_fd = open_audit_fd_or_warn(); ++ + /* If command line arguments are specified along with --replace, read all configuration files and + * insert the positional arguments at the specified place. Otherwise, if command line arguments are + * specified, execute just them, and finally, without --replace= or any positional arguments, just +diff --git a/src/update-utmp/update-utmp.c b/src/update-utmp/update-utmp.c +index a10e6d478a..6df9414063 100644 +--- a/src/update-utmp/update-utmp.c ++++ b/src/update-utmp/update-utmp.c +@@ -5,12 +5,9 @@ + #include + #include + +-#if HAVE_AUDIT +-#include +-#endif +- + #include "sd-bus.h" + ++#include "audit-util.h" + #include "alloc-util.h" + #include "bus-error.h" + #include "bus-locator.h" +@@ -30,20 +27,14 @@ + + typedef struct Context { + sd_bus *bus; +-#if HAVE_AUDIT + int audit_fd; +-#endif + } Context; + + static void context_clear(Context *c) { + assert(c); + + c->bus = sd_bus_flush_close_unref(c->bus); +-#if HAVE_AUDIT +- if (c->audit_fd >= 0) +- audit_close(c->audit_fd); +- c->audit_fd = -EBADF; +-#endif ++ c->audit_fd = close_audit_fd(c->audit_fd); + } + + static int get_startup_monotonic_time(Context *c, usec_t *ret) { +@@ -256,22 +247,14 @@ static int run(int argc, char *argv[]) { + }; + + _cleanup_(context_clear) Context c = { +-#if HAVE_AUDIT + .audit_fd = -EBADF, +-#endif + }; + + log_setup(); + + umask(0022); + +-#if HAVE_AUDIT +- /* If the kernel lacks netlink or audit support, don't worry about it. */ +- c.audit_fd = audit_open(); +- if (c.audit_fd < 0) +- log_full_errno(IN_SET(errno, EAFNOSUPPORT, EPROTONOSUPPORT) ? LOG_DEBUG : LOG_WARNING, +- errno, "Failed to connect to audit log, ignoring: %m"); +-#endif ++ c.audit_fd = open_audit_fd_or_warn(); + + return dispatch_verb(argc, argv, verbs, &c); + } +-- +2.47.1 + diff --git a/33738.patch b/33738.patch deleted file mode 100644 index 58ab604..0000000 --- a/33738.patch +++ /dev/null @@ -1,37 +0,0 @@ -From 69c5d6bea7cc2168a2a483d232aa9a77202173f0 Mon Sep 17 00:00:00 2001 -From: Hans de Goede -Date: Tue, 16 Jul 2024 17:46:09 +0200 -Subject: [PATCH] rules: Add uaccess tag to /dev/udmabuf - -In some cases userspace may need to create dmabuffers from userspace -on such example is the software ISP part of libcamera which needs to -allocate dma-buffers for the output of the software ISP. - -At first the plan was to allow console users access to /dev/dma_heap/*, -this was discussed with various kernel folks here: -https://lore.kernel.org/all/bb372250-e8b8-4458-bc99-dd8365b06991@redhat.com/ - -Giving console users access to the dma_heap's was deemed a bad idea -because memory allocated this way is not accounted in cgroup limits. - -Giving access to /dev/udmabuf OTOH was deemed acceptable so that -is what this patch adds. - -Resolves: #32662 ---- - rules.d/70-uaccess.rules.in | 2 ++ - 1 file changed, 2 insertions(+) - -diff --git a/rules.d/70-uaccess.rules.in b/rules.d/70-uaccess.rules.in -index b82ce04a39d38..e683bb1114461 100644 ---- a/rules.d/70-uaccess.rules.in -+++ b/rules.d/70-uaccess.rules.in -@@ -34,6 +34,8 @@ SUBSYSTEM=="sound", TAG+="uaccess", \ - SUBSYSTEM=="video4linux", TAG+="uaccess" - SUBSYSTEM=="dvb", TAG+="uaccess" - SUBSYSTEM=="media", TAG+="uaccess" -+# libcamera software ISP used with some cams requires udmabuf access -+KERNEL=="udmabuf", TAG+="uaccess" - - # industrial cameras, some webcams, camcorders, set-top boxes, TV sets, audio devices, and more - SUBSYSTEM=="firewire", TEST=="units", ENV{IEEE1394_UNIT_FUNCTION_MIDI}=="1", TAG+="uaccess" diff --git a/34251.patch b/34251.patch deleted file mode 100644 index 30dc0f9..0000000 --- a/34251.patch +++ /dev/null @@ -1,373 +0,0 @@ -From 3f14557ce01cc9012991a602851b03f0a4205fc2 Mon Sep 17 00:00:00 2001 -From: Daan De Meyer -Date: Wed, 4 Sep 2024 12:19:49 +0200 -Subject: [PATCH 1/2] network: Add support for multiq qdisc - ---- - man/systemd.network.xml | 10 ++++++++++ - src/network/meson.build | 1 + - src/network/networkd-network-gperf.gperf | 2 ++ - src/network/networkd-network.c | 1 + - src/network/tc/multiq.c | 19 +++++++++++++++++++ - src/network/tc/multiq.h | 11 +++++++++++ - src/network/tc/qdisc.c | 1 + - src/network/tc/qdisc.h | 2 ++ - .../test-network/conf/25-qdisc-multiq.network | 12 ++++++++++++ - test/test-network/systemd-networkd-tests.py | 10 ++++++++++ - 10 files changed, 69 insertions(+) - create mode 100644 src/network/tc/multiq.c - create mode 100644 src/network/tc/multiq.h - create mode 100644 test/test-network/conf/25-qdisc-multiq.network - -diff --git a/man/systemd.network.xml b/man/systemd.network.xml -index 734a4f7c0b21b..cc6a31484f20c 100644 ---- a/man/systemd.network.xml -+++ b/man/systemd.network.xml -@@ -6064,6 +6064,16 @@ ServerAddress=192.168.0.1/24 - - - -+ -+ [BandMultiQueueing] Section Options -+ The [BandMultiQueueing] section manages the queueing discipline (qdisc) of Band Multi Queueing (multiq). -+ -+ -+ -+ -+ -+ -+ - - [HeavyHitterFilter] Section Options - The [HeavyHitterFilter] section manages the queueing discipline (qdisc) of Heavy Hitter Filter -diff --git a/src/network/meson.build b/src/network/meson.build -index 275542daa27f5..3edcd48c83e63 100644 ---- a/src/network/meson.build -+++ b/src/network/meson.build -@@ -93,6 +93,7 @@ sources = files( - 'tc/gred.c', - 'tc/hhf.c', - 'tc/htb.c', -+ 'tc/multiq.c', - 'tc/netem.c', - 'tc/pie.c', - 'tc/qdisc.c', -diff --git a/src/network/networkd-network-gperf.gperf b/src/network/networkd-network-gperf.gperf -index 0957eeef6ed8b..95fe0275a9be4 100644 ---- a/src/network/networkd-network-gperf.gperf -+++ b/src/network/networkd-network-gperf.gperf -@@ -552,6 +552,8 @@ HierarchyTokenBucketClass.Rate, config_parse_hierarchy_token_bucket - HierarchyTokenBucketClass.CeilRate, config_parse_hierarchy_token_bucket_class_rate, TCLASS_KIND_HTB, 0 - HierarchyTokenBucketClass.BufferBytes, config_parse_hierarchy_token_bucket_class_size, TCLASS_KIND_HTB, 0 - HierarchyTokenBucketClass.CeilBufferBytes, config_parse_hierarchy_token_bucket_class_size, TCLASS_KIND_HTB, 0 -+BandMultiQueueing.Parent, config_parse_qdisc_parent, QDISC_KIND_MULTIQ, 0 -+BandMultiQueueing.Handle, config_parse_qdisc_handle, QDISC_KIND_MULTIQ, 0 - NetworkEmulator.Parent, config_parse_qdisc_parent, QDISC_KIND_NETEM, 0 - NetworkEmulator.Handle, config_parse_qdisc_handle, QDISC_KIND_NETEM, 0 - NetworkEmulator.DelaySec, config_parse_network_emulator_delay, QDISC_KIND_NETEM, 0 -diff --git a/src/network/networkd-network.c b/src/network/networkd-network.c -index ecd54a3829d49..2c2f8ad939064 100644 ---- a/src/network/networkd-network.c -+++ b/src/network/networkd-network.c -@@ -551,6 +551,7 @@ int network_load_one(Manager *manager, OrderedHashmap **networks, const char *fi - "HeavyHitterFilter\0" - "HierarchyTokenBucket\0" - "HierarchyTokenBucketClass\0" -+ "BandMultiQueueing\0" - "NetworkEmulator\0" - "PFIFO\0" - "PFIFOFast\0" -diff --git a/src/network/tc/multiq.c b/src/network/tc/multiq.c -new file mode 100644 -index 0000000000000..c70d8c59061e3 ---- /dev/null -+++ b/src/network/tc/multiq.c -@@ -0,0 +1,19 @@ -+/* SPDX-License-Identifier: LGPL-2.1-or-later */ -+ -+#include "multiq.h" -+ -+static int multi_queueing_fill_message(Link *link, QDisc *qdisc, sd_netlink_message *req) { -+ struct tc_multiq_qopt opt = {}; -+ -+ assert(req); -+ -+ /* It looks weird, but the multiq qdisc initialization wants to receive a tc_multiq_qopt attr even -+ * though it doesn't do anything with it. */ -+ return sd_netlink_message_append_data(req, TCA_OPTIONS, &opt, sizeof(opt)); -+} -+ -+const QDiscVTable multiq_vtable = { -+ .object_size = sizeof(BandMultiQueueing), -+ .tca_kind = "multiq", -+ .fill_message = multi_queueing_fill_message, -+}; -diff --git a/src/network/tc/multiq.h b/src/network/tc/multiq.h -new file mode 100644 -index 0000000000000..e53ed57c716ab ---- /dev/null -+++ b/src/network/tc/multiq.h -@@ -0,0 +1,11 @@ -+/* SPDX-License-Identifier: LGPL-2.1-or-later */ -+#pragma once -+ -+#include "qdisc.h" -+ -+typedef struct BandMultiQueueing { -+ QDisc meta; -+} BandMultiQueueing; -+ -+DEFINE_QDISC_CAST(MULTIQ, BandMultiQueueing); -+extern const QDiscVTable multiq_vtable; -diff --git a/src/network/tc/qdisc.c b/src/network/tc/qdisc.c -index 0f89d844f585a..5e8f97a785100 100644 ---- a/src/network/tc/qdisc.c -+++ b/src/network/tc/qdisc.c -@@ -30,6 +30,7 @@ const QDiscVTable * const qdisc_vtable[_QDISC_KIND_MAX] = { - [QDISC_KIND_GRED] = &gred_vtable, - [QDISC_KIND_HHF] = &hhf_vtable, - [QDISC_KIND_HTB] = &htb_vtable, -+ [QDISC_KIND_MULTIQ] = &multiq_vtable, - [QDISC_KIND_NETEM] = &netem_vtable, - [QDISC_KIND_PIE] = &pie_vtable, - [QDISC_KIND_QFQ] = &qfq_vtable, -diff --git a/src/network/tc/qdisc.h b/src/network/tc/qdisc.h -index 50a8f4ead1951..83853dcaa742c 100644 ---- a/src/network/tc/qdisc.h -+++ b/src/network/tc/qdisc.h -@@ -21,6 +21,7 @@ typedef enum QDiscKind { - QDISC_KIND_GRED, - QDISC_KIND_HHF, - QDISC_KIND_HTB, -+ QDISC_KIND_MULTIQ, - QDISC_KIND_NETEM, - QDISC_KIND_PFIFO, - QDISC_KIND_PFIFO_FAST, -@@ -106,6 +107,7 @@ CONFIG_PARSER_PROTOTYPE(config_parse_qdisc_handle); - #include "gred.h" - #include "hhf.h" - #include "htb.h" -+#include "multiq.h" - #include "pie.h" - #include "qfq.h" - #include "netem.h" -diff --git a/test/test-network/conf/25-qdisc-multiq.network b/test/test-network/conf/25-qdisc-multiq.network -new file mode 100644 -index 0000000000000..a805c77124d0c ---- /dev/null -+++ b/test/test-network/conf/25-qdisc-multiq.network -@@ -0,0 +1,12 @@ -+# SPDX-License-Identifier: LGPL-2.1-or-later -+[Match] -+Name=testtun99 -+Name=testtap99 -+ -+[Network] -+LinkLocalAddressing=yes -+IPv6AcceptRA=no -+ -+[BandMultiQueueing] -+Parent=root -+Handle=0002 -diff --git a/test/test-network/systemd-networkd-tests.py b/test/test-network/systemd-networkd-tests.py -index 1b61038d09e08..a2b4eb40b239d 100755 ---- a/test/test-network/systemd-networkd-tests.py -+++ b/test/test-network/systemd-networkd-tests.py -@@ -4648,6 +4648,16 @@ def test_qdisc_ingress(self): - print(output) - self.assertRegex(output, 'qdisc ingress') - -+ @expectedFailureIfModuleIsNotAvailable('sch_multiq') -+ def test_qdisc_multiq(self): -+ copy_network_unit('25-tun.netdev', '25-tap.netdev', '25-qdisc-multiq.network') -+ start_networkd() -+ self.wait_online('testtun99:degraded', 'testtap99:degraded') -+ -+ output = check_output('tc qdisc show dev testtun99') -+ print(output) -+ self.assertIn('qdisc multiq 2: root', output) -+ - @expectedFailureIfModuleIsNotAvailable('sch_netem') - def test_qdisc_netem(self): - copy_network_unit('25-qdisc-netem.network', '12-dummy.netdev', - -From 2b9ced9072a280a2cb0c2c7783a288788a3a6771 Mon Sep 17 00:00:00 2001 -From: Daan De Meyer -Date: Wed, 4 Sep 2024 13:32:32 +0200 -Subject: [PATCH 2/2] network: Add support for mq qdisc - ---- - man/systemd.network.xml | 10 ++++++++++ - src/network/meson.build | 1 + - src/network/networkd-network-gperf.gperf | 2 ++ - src/network/networkd-network.c | 1 + - src/network/tc/mq.c | 8 ++++++++ - src/network/tc/mq.h | 11 +++++++++++ - src/network/tc/qdisc.c | 1 + - src/network/tc/qdisc.h | 2 ++ - test/test-network/conf/25-qdisc-mq.network | 12 ++++++++++++ - test/test-network/systemd-networkd-tests.py | 9 +++++++++ - 10 files changed, 57 insertions(+) - create mode 100644 src/network/tc/mq.c - create mode 100644 src/network/tc/mq.h - create mode 100644 test/test-network/conf/25-qdisc-mq.network - -diff --git a/man/systemd.network.xml b/man/systemd.network.xml -index cc6a31484f20c..89484c449f31d 100644 ---- a/man/systemd.network.xml -+++ b/man/systemd.network.xml -@@ -6064,6 +6064,16 @@ ServerAddress=192.168.0.1/24 - - - -+ -+ [ClassfulMultiQueueing] Section Options -+ The [ClassfulMultiQueueing] section manages the queueing discipline (qdisc) of Classful Multi Queueing (mq). -+ -+ -+ -+ -+ -+ -+ - - [BandMultiQueueing] Section Options - The [BandMultiQueueing] section manages the queueing discipline (qdisc) of Band Multi Queueing (multiq). -diff --git a/src/network/meson.build b/src/network/meson.build -index 3edcd48c83e63..54cf694aeb47e 100644 ---- a/src/network/meson.build -+++ b/src/network/meson.build -@@ -93,6 +93,7 @@ sources = files( - 'tc/gred.c', - 'tc/hhf.c', - 'tc/htb.c', -+ 'tc/mq.c', - 'tc/multiq.c', - 'tc/netem.c', - 'tc/pie.c', -diff --git a/src/network/networkd-network-gperf.gperf b/src/network/networkd-network-gperf.gperf -index 95fe0275a9be4..a84de4ca7fca9 100644 ---- a/src/network/networkd-network-gperf.gperf -+++ b/src/network/networkd-network-gperf.gperf -@@ -552,6 +552,8 @@ HierarchyTokenBucketClass.Rate, config_parse_hierarchy_token_bucket - HierarchyTokenBucketClass.CeilRate, config_parse_hierarchy_token_bucket_class_rate, TCLASS_KIND_HTB, 0 - HierarchyTokenBucketClass.BufferBytes, config_parse_hierarchy_token_bucket_class_size, TCLASS_KIND_HTB, 0 - HierarchyTokenBucketClass.CeilBufferBytes, config_parse_hierarchy_token_bucket_class_size, TCLASS_KIND_HTB, 0 -+ClassfulMultiQueueing.Parent, config_parse_qdisc_parent, QDISC_KIND_MQ, 0 -+ClassfulMultiQueueing.Handle, config_parse_qdisc_handle, QDISC_KIND_MQ, 0 - BandMultiQueueing.Parent, config_parse_qdisc_parent, QDISC_KIND_MULTIQ, 0 - BandMultiQueueing.Handle, config_parse_qdisc_handle, QDISC_KIND_MULTIQ, 0 - NetworkEmulator.Parent, config_parse_qdisc_parent, QDISC_KIND_NETEM, 0 -diff --git a/src/network/networkd-network.c b/src/network/networkd-network.c -index 2c2f8ad939064..8ccf215a71e84 100644 ---- a/src/network/networkd-network.c -+++ b/src/network/networkd-network.c -@@ -551,6 +551,7 @@ int network_load_one(Manager *manager, OrderedHashmap **networks, const char *fi - "HeavyHitterFilter\0" - "HierarchyTokenBucket\0" - "HierarchyTokenBucketClass\0" -+ "ClassfulMultiQueueing\0" - "BandMultiQueueing\0" - "NetworkEmulator\0" - "PFIFO\0" -diff --git a/src/network/tc/mq.c b/src/network/tc/mq.c -new file mode 100644 -index 0000000000000..1435ed1fda0fa ---- /dev/null -+++ b/src/network/tc/mq.c -@@ -0,0 +1,8 @@ -+/* SPDX-License-Identifier: LGPL-2.1-or-later */ -+ -+#include "mq.h" -+ -+const QDiscVTable mq_vtable = { -+ .object_size = sizeof(ClassfulMultiQueueing), -+ .tca_kind = "mq", -+}; -diff --git a/src/network/tc/mq.h b/src/network/tc/mq.h -new file mode 100644 -index 0000000000000..88f0049670cf1 ---- /dev/null -+++ b/src/network/tc/mq.h -@@ -0,0 +1,11 @@ -+/* SPDX-License-Identifier: LGPL-2.1-or-later */ -+#pragma once -+ -+#include "qdisc.h" -+ -+typedef struct ClassfulMultiQueueing { -+ QDisc meta; -+} ClassfulMultiQueueing; -+ -+DEFINE_QDISC_CAST(MQ, ClassfulMultiQueueing); -+extern const QDiscVTable mq_vtable; -diff --git a/src/network/tc/qdisc.c b/src/network/tc/qdisc.c -index 5e8f97a785100..3bcc3930662f4 100644 ---- a/src/network/tc/qdisc.c -+++ b/src/network/tc/qdisc.c -@@ -30,6 +30,7 @@ const QDiscVTable * const qdisc_vtable[_QDISC_KIND_MAX] = { - [QDISC_KIND_GRED] = &gred_vtable, - [QDISC_KIND_HHF] = &hhf_vtable, - [QDISC_KIND_HTB] = &htb_vtable, -+ [QDISC_KIND_MQ] = &mq_vtable, - [QDISC_KIND_MULTIQ] = &multiq_vtable, - [QDISC_KIND_NETEM] = &netem_vtable, - [QDISC_KIND_PIE] = &pie_vtable, -diff --git a/src/network/tc/qdisc.h b/src/network/tc/qdisc.h -index 83853dcaa742c..80b95c2aab4fc 100644 ---- a/src/network/tc/qdisc.h -+++ b/src/network/tc/qdisc.h -@@ -21,6 +21,7 @@ typedef enum QDiscKind { - QDISC_KIND_GRED, - QDISC_KIND_HHF, - QDISC_KIND_HTB, -+ QDISC_KIND_MQ, - QDISC_KIND_MULTIQ, - QDISC_KIND_NETEM, - QDISC_KIND_PFIFO, -@@ -107,6 +108,7 @@ CONFIG_PARSER_PROTOTYPE(config_parse_qdisc_handle); - #include "gred.h" - #include "hhf.h" - #include "htb.h" -+#include "mq.h" - #include "multiq.h" - #include "pie.h" - #include "qfq.h" -diff --git a/test/test-network/conf/25-qdisc-mq.network b/test/test-network/conf/25-qdisc-mq.network -new file mode 100644 -index 0000000000000..32366d05dabed ---- /dev/null -+++ b/test/test-network/conf/25-qdisc-mq.network -@@ -0,0 +1,12 @@ -+# SPDX-License-Identifier: LGPL-2.1-or-later -+[Match] -+Name=testtun99 -+Name=testtap99 -+ -+[Network] -+LinkLocalAddressing=yes -+IPv6AcceptRA=no -+ -+[ClassfulMultiQueueing] -+Parent=root -+Handle=0002 -diff --git a/test/test-network/systemd-networkd-tests.py b/test/test-network/systemd-networkd-tests.py -index a2b4eb40b239d..3989fc04014d1 100755 ---- a/test/test-network/systemd-networkd-tests.py -+++ b/test/test-network/systemd-networkd-tests.py -@@ -4648,6 +4648,15 @@ def test_qdisc_ingress(self): - print(output) - self.assertRegex(output, 'qdisc ingress') - -+ def test_qdisc_mq(self): -+ copy_network_unit('25-tun.netdev', '25-tap.netdev', '25-qdisc-mq.network') -+ start_networkd() -+ self.wait_online('testtun99:degraded', 'testtap99:degraded') -+ -+ output = check_output('tc qdisc show dev testtun99') -+ print(output) -+ self.assertIn('qdisc mq 2: root', output) -+ - @expectedFailureIfModuleIsNotAvailable('sch_multiq') - def test_qdisc_multiq(self): - copy_network_unit('25-tun.netdev', '25-tap.netdev', '25-qdisc-multiq.network') diff --git a/34400.patch b/34400.patch deleted file mode 100644 index 944f3f0..0000000 --- a/34400.patch +++ /dev/null @@ -1,574 +0,0 @@ -From 10e421f70889a672f984785393051e0471c0aeb2 Mon Sep 17 00:00:00 2001 -From: Daan De Meyer -Date: Mon, 9 Sep 2024 12:25:28 +0200 -Subject: [PATCH] core: Add support for PrivateUsers=identity - -This configures an indentity mapping similar to -systemd-nspawn --private-users=identity. - -(cherry picked from commit fa693fdc7e17618958c505af4b2f39ecd1c3363e) ---- - man/org.freedesktop.systemd1.xml | 24 ++++++++++ - man/systemd.exec.xml | 35 ++++++++++----- - src/core/dbus-execute.c | 57 ++++++++++++++++++++++-- - src/core/exec-invoke.c | 56 +++++++++++++++-------- - src/core/execute-serialize.c | 9 ++-- - src/core/execute.c | 2 +- - src/core/execute.h | 2 +- - src/core/load-fragment-gperf.gperf.in | 2 +- - src/core/load-fragment.c | 1 + - src/core/load-fragment.h | 1 + - src/core/namespace.c | 8 ++++ - src/core/namespace.h | 11 +++++ - src/shared/bus-unit-util.c | 1 + - test/units/TEST-07-PID1.private-users.sh | 12 +++++ - 14 files changed, 179 insertions(+), 42 deletions(-) - create mode 100755 test/units/TEST-07-PID1.private-users.sh - -diff --git a/man/org.freedesktop.systemd1.xml b/man/org.freedesktop.systemd1.xml -index b0b45097e30a3..ce0757cf9cfa2 100644 ---- a/man/org.freedesktop.systemd1.xml -+++ b/man/org.freedesktop.systemd1.xml -@@ -3221,6 +3221,8 @@ node /org/freedesktop/systemd1/unit/avahi_2ddaemon_2eservice { - @org.freedesktop.DBus.Property.EmitsChangedSignal("const") - readonly b PrivateUsers = ...; - @org.freedesktop.DBus.Property.EmitsChangedSignal("const") -+ readonly s PrivateUsersEx = '...'; -+ @org.freedesktop.DBus.Property.EmitsChangedSignal("const") - readonly b PrivateMounts = ...; - @org.freedesktop.DBus.Property.EmitsChangedSignal("const") - readonly b PrivateIPC = ...; -@@ -3832,6 +3834,8 @@ node /org/freedesktop/systemd1/unit/avahi_2ddaemon_2eservice { - - - -+ -+ - - - -@@ -4516,6 +4520,8 @@ node /org/freedesktop/systemd1/unit/avahi_2ddaemon_2eservice { - - - -+ -+ - - - -@@ -5338,6 +5344,8 @@ node /org/freedesktop/systemd1/unit/avahi_2ddaemon_2esocket { - @org.freedesktop.DBus.Property.EmitsChangedSignal("const") - readonly b PrivateUsers = ...; - @org.freedesktop.DBus.Property.EmitsChangedSignal("const") -+ readonly s PrivateUsersEx = '...'; -+ @org.freedesktop.DBus.Property.EmitsChangedSignal("const") - readonly b PrivateMounts = ...; - @org.freedesktop.DBus.Property.EmitsChangedSignal("const") - readonly b PrivateIPC = ...; -@@ -5961,6 +5969,8 @@ node /org/freedesktop/systemd1/unit/avahi_2ddaemon_2esocket { - - - -+ -+ - - - -@@ -6625,6 +6635,8 @@ node /org/freedesktop/systemd1/unit/avahi_2ddaemon_2esocket { - - - -+ -+ - - - -@@ -7311,6 +7323,8 @@ node /org/freedesktop/systemd1/unit/home_2emount { - @org.freedesktop.DBus.Property.EmitsChangedSignal("const") - readonly b PrivateUsers = ...; - @org.freedesktop.DBus.Property.EmitsChangedSignal("const") -+ readonly s PrivateUsersEx = '...'; -+ @org.freedesktop.DBus.Property.EmitsChangedSignal("const") - readonly b PrivateMounts = ...; - @org.freedesktop.DBus.Property.EmitsChangedSignal("const") - readonly b PrivateIPC = ...; -@@ -7860,6 +7874,8 @@ node /org/freedesktop/systemd1/unit/home_2emount { - - - -+ -+ - - - -@@ -8436,6 +8452,8 @@ node /org/freedesktop/systemd1/unit/home_2emount { - - - -+ -+ - - - -@@ -9245,6 +9263,8 @@ node /org/freedesktop/systemd1/unit/dev_2dsda3_2eswap { - @org.freedesktop.DBus.Property.EmitsChangedSignal("const") - readonly b PrivateUsers = ...; - @org.freedesktop.DBus.Property.EmitsChangedSignal("const") -+ readonly s PrivateUsersEx = '...'; -+ @org.freedesktop.DBus.Property.EmitsChangedSignal("const") - readonly b PrivateMounts = ...; - @org.freedesktop.DBus.Property.EmitsChangedSignal("const") - readonly b PrivateIPC = ...; -@@ -9780,6 +9800,8 @@ node /org/freedesktop/systemd1/unit/dev_2dsda3_2eswap { - - - -+ -+ - - - -@@ -10342,6 +10364,8 @@ node /org/freedesktop/systemd1/unit/dev_2dsda3_2eswap { - - - -+ -+ - - - -diff --git a/man/systemd.exec.xml b/man/systemd.exec.xml -index 21527f756d669..3cdb7ff70a09b 100644 ---- a/man/systemd.exec.xml -+++ b/man/systemd.exec.xml -@@ -1941,18 +1941,29 @@ BindReadOnlyPaths=/var/lib/systemd - - PrivateUsers= - -- Takes a boolean argument. If true, sets up a new user namespace for the executed processes and -- configures a minimal user and group mapping, that maps the root user and group as well as -- the unit's own user and group to themselves and everything else to the nobody user and -- group. This is useful to securely detach the user and group databases used by the unit from the rest of the -- system, and thus to create an effective sandbox environment. All files, directories, processes, IPC objects and -- other resources owned by users/groups not equaling root or the unit's own will stay visible -- from within the unit but appear owned by the nobody user and group. If this mode is enabled, -- all unit processes are run without privileges in the host user namespace (regardless if the unit's own -- user/group is root or not). Specifically this means that the process will have zero process -- capabilities on the host's user namespace, but full capabilities within the service's user namespace. Settings -- such as CapabilityBoundingSet= will affect only the latter, and there's no way to acquire -- additional capabilities in the host's user namespace. Defaults to off. -+ Takes a boolean argument or one of self or -+ identity. Defaults to off. If enabled, sets up a new user namespace for the -+ executed processes and configures a user and group mapping. If set to a true value or -+ self, a minimal user and group mapping is configured that maps the -+ root user and group as well as the unit's own user and group to themselves and -+ everything else to the nobody user and group. This is useful to securely detach -+ the user and group databases used by the unit from the rest of the system, and thus to create an -+ effective sandbox environment. All files, directories, processes, IPC objects and other resources -+ owned by users/groups not equaling root or the unit's own will stay visible from -+ within the unit but appear owned by the nobody user and group. -+ -+ If the parameter is identity, user namespacing is set up with an identity -+ mapping for the first 65536 UIDs/GIDs. Any UIDs/GIDs above 65536 will be mapped to the -+ nobody user and group, respectively. While this does not provide UID/GID isolation, -+ since all UIDs/GIDs are chosen identically it does provide process capability isolation, and hence is -+ often a good choice if proper user namespacing with distinct UID maps is not appropriate. -+ -+ If this mode is enabled, all unit processes are run without privileges in the host user -+ namespace (regardless if the unit's own user/group is root or not). Specifically -+ this means that the process will have zero process capabilities on the host's user namespace, but -+ full capabilities within the service's user namespace. Settings such as -+ CapabilityBoundingSet= will affect only the latter, and there's no way to acquire -+ additional capabilities in the host's user namespace. - - When this setting is set up by a per-user instance of the service manager, the mapping of the - root user and group to itself is omitted (unless the user manager is root). -diff --git a/src/core/dbus-execute.c b/src/core/dbus-execute.c -index b0d9402e53ca7..1aeba38df60a6 100644 ---- a/src/core/dbus-execute.c -+++ b/src/core/dbus-execute.c -@@ -58,6 +58,7 @@ static BUS_DEFINE_PROPERTY_GET(property_get_mount_apivfs, "b", ExecContext, exec - static BUS_DEFINE_PROPERTY_GET2(property_get_ioprio_class, "i", ExecContext, exec_context_get_effective_ioprio, ioprio_prio_class); - static BUS_DEFINE_PROPERTY_GET2(property_get_ioprio_priority, "i", ExecContext, exec_context_get_effective_ioprio, ioprio_prio_data); - static BUS_DEFINE_PROPERTY_GET_GLOBAL(property_get_empty_string, "s", NULL); -+static BUS_DEFINE_PROPERTY_GET_REF(property_get_private_users_ex, "s", PrivateUsers, private_users_to_string); - static BUS_DEFINE_PROPERTY_GET_REF(property_get_syslog_level, "i", int, LOG_PRI); - static BUS_DEFINE_PROPERTY_GET_REF(property_get_syslog_facility, "i", int, LOG_FAC); - static BUS_DEFINE_PROPERTY_GET(property_get_cpu_affinity_from_numa, "b", ExecContext, exec_context_get_cpu_affinity_from_numa); -@@ -943,6 +944,21 @@ static int property_get_image_policy( - return sd_bus_message_append(reply, "s", s); - } - -+static int property_get_private_users( -+ sd_bus *bus, -+ const char *path, -+ const char *interface, -+ const char *property, -+ sd_bus_message *reply, -+ void *userdata, -+ sd_bus_error *error) { -+ -+ PrivateUsers *p = ASSERT_PTR(userdata); -+ int b = *p != PRIVATE_USERS_OFF; -+ -+ return sd_bus_message_append_basic(reply, 'b', &b); -+} -+ - const sd_bus_vtable bus_exec_vtable[] = { - SD_BUS_VTABLE_START(0), - SD_BUS_PROPERTY("Environment", "as", NULL, offsetof(ExecContext, environment), SD_BUS_VTABLE_PROPERTY_CONST), -@@ -1063,7 +1079,8 @@ const sd_bus_vtable bus_exec_vtable[] = { - SD_BUS_PROPERTY("ProtectKernelLogs", "b", bus_property_get_bool, offsetof(ExecContext, protect_kernel_logs), SD_BUS_VTABLE_PROPERTY_CONST), - SD_BUS_PROPERTY("ProtectControlGroups", "b", bus_property_get_bool, offsetof(ExecContext, protect_control_groups), SD_BUS_VTABLE_PROPERTY_CONST), - SD_BUS_PROPERTY("PrivateNetwork", "b", bus_property_get_bool, offsetof(ExecContext, private_network), SD_BUS_VTABLE_PROPERTY_CONST), -- SD_BUS_PROPERTY("PrivateUsers", "b", bus_property_get_bool, offsetof(ExecContext, private_users), SD_BUS_VTABLE_PROPERTY_CONST), -+ SD_BUS_PROPERTY("PrivateUsers", "b", property_get_private_users, offsetof(ExecContext, private_users), SD_BUS_VTABLE_PROPERTY_CONST), -+ SD_BUS_PROPERTY("PrivateUsersEx", "s", property_get_private_users_ex, offsetof(ExecContext, private_users), SD_BUS_VTABLE_PROPERTY_CONST), - SD_BUS_PROPERTY("PrivateMounts", "b", bus_property_get_tristate, offsetof(ExecContext, private_mounts), SD_BUS_VTABLE_PROPERTY_CONST), - SD_BUS_PROPERTY("PrivateIPC", "b", bus_property_get_bool, offsetof(ExecContext, private_ipc), SD_BUS_VTABLE_PROPERTY_CONST), - SD_BUS_PROPERTY("ProtectHome", "s", property_get_protect_home, offsetof(ExecContext, protect_home), SD_BUS_VTABLE_PROPERTY_CONST), -@@ -1738,6 +1755,41 @@ int bus_exec_context_set_transient_property( - if (streq(name, "PrivateTmp")) - return bus_set_transient_bool(u, name, &c->private_tmp, message, flags, error); - -+ if (streq(name, "PrivateUsers")) { -+ int v; -+ -+ r = sd_bus_message_read(message, "b", &v); -+ if (r < 0) -+ return r; -+ -+ if (!UNIT_WRITE_FLAGS_NOOP(flags)) { -+ c->private_users = v ? PRIVATE_USERS_SELF : PRIVATE_USERS_OFF; -+ (void) unit_write_settingf(u, flags, name, "%s=%s", name, yes_no(v)); -+ } -+ -+ return 1; -+ -+ } else if (streq(name, "PrivateUsersEx")) { -+ const char *s; -+ PrivateUsers t; -+ -+ r = sd_bus_message_read(message, "s", &s); -+ if (r < 0) -+ return r; -+ -+ t = private_users_from_string(s); -+ if (t < 0) -+ return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Invalid %s setting: %s", name, s); -+ -+ if (!UNIT_WRITE_FLAGS_NOOP(flags)) { -+ c->private_users = t; -+ (void) unit_write_settingf(u, flags, name, "PrivateUsers=%s", -+ private_users_to_string(c->private_users)); -+ } -+ -+ return 1; -+ } -+ - if (streq(name, "PrivateDevices")) - return bus_set_transient_bool(u, name, &c->private_devices, message, flags, error); - -@@ -1753,9 +1805,6 @@ int bus_exec_context_set_transient_property( - if (streq(name, "PrivateIPC")) - return bus_set_transient_bool(u, name, &c->private_ipc, message, flags, error); - -- if (streq(name, "PrivateUsers")) -- return bus_set_transient_bool(u, name, &c->private_users, message, flags, error); -- - if (streq(name, "NoNewPrivileges")) - return bus_set_transient_bool(u, name, &c->no_new_privileges, message, flags, error); - -diff --git a/src/core/exec-invoke.c b/src/core/exec-invoke.c -index 5850a595f0475..1f4a9923df7e0 100644 ---- a/src/core/exec-invoke.c -+++ b/src/core/exec-invoke.c -@@ -2080,7 +2080,7 @@ static int build_pass_environment(const ExecContext *c, char ***ret) { - return 0; - } - --static int setup_private_users(uid_t ouid, gid_t ogid, uid_t uid, gid_t gid) { -+static int setup_private_users(PrivateUsers private_users, uid_t ouid, gid_t ogid, uid_t uid, gid_t gid) { - _cleanup_free_ char *uid_map = NULL, *gid_map = NULL; - _cleanup_close_pair_ int errno_pipe[2] = EBADF_PAIR; - _cleanup_close_ int unshare_ready_fd = -EBADF; -@@ -2099,33 +2099,48 @@ static int setup_private_users(uid_t ouid, gid_t ogid, uid_t uid, gid_t gid) { - * For unprivileged users (i.e. without capabilities), the root to root mapping is excluded. As such, it - * does not need CAP_SETUID to write the single line mapping to itself. */ - -+ if (private_users == PRIVATE_USERS_OFF) -+ return 0; -+ -+ if (private_users == PRIVATE_USERS_IDENTITY) { -+ uid_map = strdup("0 0 65536\n"); -+ if (!uid_map) -+ return -ENOMEM; - /* Can only set up multiple mappings with CAP_SETUID. */ -- if (have_effective_cap(CAP_SETUID) > 0 && uid != ouid && uid_is_valid(uid)) -+ } else if (have_effective_cap(CAP_SETUID) > 0 && uid != ouid && uid_is_valid(uid)) { - r = asprintf(&uid_map, - UID_FMT " " UID_FMT " 1\n" /* Map $OUID → $OUID */ - UID_FMT " " UID_FMT " 1\n", /* Map $UID → $UID */ - ouid, ouid, uid, uid); -- else -+ if (r < 0) -+ return -ENOMEM; -+ } else { - r = asprintf(&uid_map, - UID_FMT " " UID_FMT " 1\n", /* Map $OUID → $OUID */ - ouid, ouid); -+ if (r < 0) -+ return -ENOMEM; -+ } - -- if (r < 0) -- return -ENOMEM; -- -+ if (private_users == PRIVATE_USERS_IDENTITY) { -+ gid_map = strdup("0 0 65536\n"); -+ if (!gid_map) -+ return -ENOMEM; - /* Can only set up multiple mappings with CAP_SETGID. */ -- if (have_effective_cap(CAP_SETGID) > 0 && gid != ogid && gid_is_valid(gid)) -+ } else if (have_effective_cap(CAP_SETGID) > 0 && gid != ogid && gid_is_valid(gid)) { - r = asprintf(&gid_map, - GID_FMT " " GID_FMT " 1\n" /* Map $OGID → $OGID */ - GID_FMT " " GID_FMT " 1\n", /* Map $GID → $GID */ - ogid, ogid, gid, gid); -- else -+ if (r < 0) -+ return -ENOMEM; -+ } else { - r = asprintf(&gid_map, - GID_FMT " " GID_FMT " 1\n", /* Map $OGID -> $OGID */ - ogid, ogid); -- -- if (r < 0) -- return -ENOMEM; -+ if (r < 0) -+ return -ENOMEM; -+ } - - /* Create a communication channel so that the parent can tell the child when it finished creating the user - * namespace. */ -@@ -2236,7 +2251,7 @@ static int setup_private_users(uid_t ouid, gid_t ogid, uid_t uid, gid_t gid) { - if (r != EXIT_SUCCESS) /* If something strange happened with the child, let's consider this fatal, too */ - return -EIO; - -- return 0; -+ return 1; - } - - static int create_many_symlinks(const char *root, const char *source, char **symlinks) { -@@ -3865,7 +3880,7 @@ static bool exec_context_need_unprivileged_private_users( - if (params->runtime_scope != RUNTIME_SCOPE_USER) - return false; - -- return context->private_users || -+ return context->private_users != PRIVATE_USERS_OFF || - context->private_tmp || - context->private_devices || - context->private_network || -@@ -4720,18 +4735,23 @@ int exec_invoke( - /* If we're unprivileged, set up the user namespace first to enable use of the other namespaces. - * Users with CAP_SYS_ADMIN can set up user namespaces last because they will be able to - * set up all of the other namespaces (i.e. network, mount, UTS) without a user namespace. */ -+ PrivateUsers pu = context->private_users; -+ if (pu == PRIVATE_USERS_OFF) -+ pu = PRIVATE_USERS_SELF; - -- r = setup_private_users(saved_uid, saved_gid, uid, gid); -+ r = setup_private_users(pu, saved_uid, saved_gid, uid, gid); - /* If it was requested explicitly and we can't set it up, fail early. Otherwise, continue and let - * the actual requested operations fail (or silently continue). */ -- if (r < 0 && context->private_users) { -+ if (r < 0 && context->private_users != PRIVATE_USERS_OFF) { - *exit_status = EXIT_USER; - return log_exec_error_errno(context, params, r, "Failed to set up user namespacing for unprivileged user: %m"); - } - if (r < 0) - log_exec_info_errno(context, params, r, "Failed to set up user namespacing for unprivileged user, ignoring: %m"); -- else -+ else { -+ assert(r > 0); - userns_set_up = true; -+ } - } - - if (exec_needs_network_namespace(context) && runtime && runtime->shared && runtime->shared->netns_storage_socket[0] >= 0) { -@@ -4844,8 +4864,8 @@ int exec_invoke( - * case of mount namespaces being less privileged when the mount point list is copied from a - * different user namespace). */ - -- if (needs_sandboxing && context->private_users && !userns_set_up) { -- r = setup_private_users(saved_uid, saved_gid, uid, gid); -+ if (needs_sandboxing && !userns_set_up) { -+ r = setup_private_users(context->private_users, saved_uid, saved_gid, uid, gid); - if (r < 0) { - *exit_status = EXIT_USER; - return log_exec_error_errno(context, params, r, "Failed to set up user namespacing: %m"); -diff --git a/src/core/execute-serialize.c b/src/core/execute-serialize.c -index 41b31e9ae3f21..867a74419da98 100644 ---- a/src/core/execute-serialize.c -+++ b/src/core/execute-serialize.c -@@ -1880,7 +1880,7 @@ static int exec_context_serialize(const ExecContext *c, FILE *f) { - if (r < 0) - return r; - -- r = serialize_bool_elide(f, "exec-context-private-users", c->private_users); -+ r = serialize_item(f, "exec-context-private-users", private_users_to_string(c->private_users)); - if (r < 0) - return r; - -@@ -2772,10 +2772,9 @@ static int exec_context_deserialize(ExecContext *c, FILE *f) { - return r; - c->private_network = r; - } else if ((val = startswith(l, "exec-context-private-users="))) { -- r = parse_boolean(val); -- if (r < 0) -- return r; -- c->private_users = r; -+ c->private_users = private_users_from_string(val); -+ if (c->private_users < 0) -+ return -EINVAL; - } else if ((val = startswith(l, "exec-context-private-ipc="))) { - r = parse_boolean(val); - if (r < 0) -diff --git a/src/core/execute.c b/src/core/execute.c -index f74665fcd7b9a..c2241803b763a 100644 ---- a/src/core/execute.c -+++ b/src/core/execute.c -@@ -973,7 +973,7 @@ void exec_context_dump(const ExecContext *c, FILE* f, const char *prefix) { - prefix, yes_no(c->protect_clock), - prefix, yes_no(c->protect_control_groups), - prefix, yes_no(c->private_network), -- prefix, yes_no(c->private_users), -+ prefix, private_users_to_string(c->private_users), - prefix, protect_home_to_string(c->protect_home), - prefix, protect_system_to_string(c->protect_system), - prefix, yes_no(exec_context_get_effective_mount_apivfs(c)), -diff --git a/src/core/execute.h b/src/core/execute.h -index 107ae2524387c..603feac0d6027 100644 ---- a/src/core/execute.h -+++ b/src/core/execute.h -@@ -317,7 +317,7 @@ struct ExecContext { - bool private_tmp; - bool private_network; - bool private_devices; -- bool private_users; -+ PrivateUsers private_users; - bool private_ipc; - bool protect_kernel_tunables; - bool protect_kernel_modules; -diff --git a/src/core/load-fragment-gperf.gperf.in b/src/core/load-fragment-gperf.gperf.in -index df219d86dfeaa..213b36ec05eee 100644 ---- a/src/core/load-fragment-gperf.gperf.in -+++ b/src/core/load-fragment-gperf.gperf.in -@@ -130,7 +130,7 @@ - {{type}}.IPCNamespacePath, config_parse_unit_path_printf, 0, offsetof({{type}}, exec_context.ipc_namespace_path) - {{type}}.LogNamespace, config_parse_log_namespace, 0, offsetof({{type}}, exec_context) - {{type}}.PrivateNetwork, config_parse_bool, 0, offsetof({{type}}, exec_context.private_network) --{{type}}.PrivateUsers, config_parse_bool, 0, offsetof({{type}}, exec_context.private_users) -+{{type}}.PrivateUsers, config_parse_private_users, 0, offsetof({{type}}, exec_context.private_users) - {{type}}.PrivateMounts, config_parse_tristate, 0, offsetof({{type}}, exec_context.private_mounts) - {{type}}.PrivateIPC, config_parse_bool, 0, offsetof({{type}}, exec_context.private_ipc) - {{type}}.ProtectSystem, config_parse_protect_system, 0, offsetof({{type}}, exec_context.protect_system) -diff --git a/src/core/load-fragment.c b/src/core/load-fragment.c -index a1a116a439774..23b5a66742da7 100644 ---- a/src/core/load-fragment.c -+++ b/src/core/load-fragment.c -@@ -132,6 +132,7 @@ DEFINE_CONFIG_PARSE_ENUM(config_parse_collect_mode, collect_mode, CollectMode, " - DEFINE_CONFIG_PARSE_ENUM(config_parse_device_policy, cgroup_device_policy, CGroupDevicePolicy, "Failed to parse device policy"); - DEFINE_CONFIG_PARSE_ENUM(config_parse_exec_keyring_mode, exec_keyring_mode, ExecKeyringMode, "Failed to parse keyring mode"); - DEFINE_CONFIG_PARSE_ENUM(config_parse_protect_proc, protect_proc, ProtectProc, "Failed to parse /proc/ protection mode"); -+DEFINE_CONFIG_PARSE_ENUM(config_parse_private_users, private_users, PrivateUsers, "Failed to parse private users mode"); - DEFINE_CONFIG_PARSE_ENUM(config_parse_proc_subset, proc_subset, ProcSubset, "Failed to parse /proc/ subset mode"); - DEFINE_CONFIG_PARSE_ENUM(config_parse_exec_utmp_mode, exec_utmp_mode, ExecUtmpMode, "Failed to parse utmp mode"); - DEFINE_CONFIG_PARSE_ENUM(config_parse_job_mode, job_mode, JobMode, "Failed to parse job mode"); -diff --git a/src/core/load-fragment.h b/src/core/load-fragment.h -index 005b91510608f..b6741c9207ab0 100644 ---- a/src/core/load-fragment.h -+++ b/src/core/load-fragment.h -@@ -113,6 +113,7 @@ CONFIG_PARSER_PROTOTYPE(config_parse_import_credential); - CONFIG_PARSER_PROTOTYPE(config_parse_set_status); - CONFIG_PARSER_PROTOTYPE(config_parse_namespace_path_strv); - CONFIG_PARSER_PROTOTYPE(config_parse_temporary_filesystems); -+CONFIG_PARSER_PROTOTYPE(config_parse_private_users); - CONFIG_PARSER_PROTOTYPE(config_parse_cpu_quota); - CONFIG_PARSER_PROTOTYPE(config_parse_allowed_cpuset); - CONFIG_PARSER_PROTOTYPE(config_parse_protect_home); -diff --git a/src/core/namespace.c b/src/core/namespace.c -index b92bb012eee31..052a4452c12b7 100644 ---- a/src/core/namespace.c -+++ b/src/core/namespace.c -@@ -3080,3 +3080,11 @@ static const char* const proc_subset_table[_PROC_SUBSET_MAX] = { - }; - - DEFINE_STRING_TABLE_LOOKUP(proc_subset, ProcSubset); -+ -+static const char* const private_users_table[_PRIVATE_USERS_MAX] = { -+ [PRIVATE_USERS_OFF] = "off", -+ [PRIVATE_USERS_SELF] = "self", -+ [PRIVATE_USERS_IDENTITY] = "identity", -+}; -+ -+DEFINE_STRING_TABLE_LOOKUP_WITH_BOOLEAN(private_users, PrivateUsers, PRIVATE_USERS_SELF); -diff --git a/src/core/namespace.h b/src/core/namespace.h -index 921716bf3ec93..d10d7f440ad8b 100644 ---- a/src/core/namespace.h -+++ b/src/core/namespace.h -@@ -53,6 +53,14 @@ typedef enum ProcSubset { - _PROC_SUBSET_INVALID = -EINVAL, - } ProcSubset; - -+typedef enum PrivateUsers { -+ PRIVATE_USERS_OFF, -+ PRIVATE_USERS_SELF, -+ PRIVATE_USERS_IDENTITY, -+ _PRIVATE_USERS_MAX, -+ _PRIVATE_USERS_INVALID = -EINVAL, -+} PrivateUsers; -+ - struct BindMount { - char *source; - char *destination; -@@ -184,6 +192,9 @@ ProtectProc protect_proc_from_string(const char *s) _pure_; - const char* proc_subset_to_string(ProcSubset i) _const_; - ProcSubset proc_subset_from_string(const char *s) _pure_; - -+const char* private_users_to_string(PrivateUsers i) _const_; -+PrivateUsers private_users_from_string(const char *s) _pure_; -+ - void bind_mount_free_many(BindMount *b, size_t n); - int bind_mount_add(BindMount **b, size_t *n, const BindMount *item); - -diff --git a/src/shared/bus-unit-util.c b/src/shared/bus-unit-util.c -index da83422524fa4..ff24ac5dd40dc 100644 ---- a/src/shared/bus-unit-util.c -+++ b/src/shared/bus-unit-util.c -@@ -1037,6 +1037,7 @@ static int bus_append_execute_property(sd_bus_message *m, const char *field, con - "SyslogIdentifier", - "ProtectSystem", - "ProtectHome", -+ "PrivateUsersEx", - "SELinuxContext", - "RootImage", - "RootVerity", -diff --git a/test/units/TEST-07-PID1.private-users.sh b/test/units/TEST-07-PID1.private-users.sh -new file mode 100755 -index 0000000000000..2475b5d365d59 ---- /dev/null -+++ b/test/units/TEST-07-PID1.private-users.sh -@@ -0,0 +1,12 @@ -+#!/usr/bin/env bash -+# SPDX-License-Identifier: LGPL-2.1-or-later -+# shellcheck disable=SC2016 -+set -eux -+set -o pipefail -+ -+systemd-run -p PrivateUsers=yes --wait bash -c 'test "$(cat /proc/self/uid_map)" == " 0 0 1"' -+systemd-run -p PrivateUsers=yes --wait bash -c 'test "$(cat /proc/self/gid_map)" == " 0 0 1"' -+systemd-run -p PrivateUsersEx=self --wait bash -c 'test "$(cat /proc/self/uid_map)" == " 0 0 1"' -+systemd-run -p PrivateUsersEx=self --wait bash -c 'test "$(cat /proc/self/gid_map)" == " 0 0 1"' -+systemd-run -p PrivateUsersEx=identity --wait bash -c 'test "$(cat /proc/self/uid_map)" == " 0 0 65536"' -+systemd-run -p PrivateUsersEx=identity --wait bash -c 'test "$(cat /proc/self/gid_map)" == " 0 0 65536"' diff --git a/34543.patch b/34543.patch deleted file mode 100644 index 591bb03..0000000 --- a/34543.patch +++ /dev/null @@ -1,1954 +0,0 @@ -From f5d23169d737f6c6fe123dbaeae053227c744457 Mon Sep 17 00:00:00 2001 -From: Yu Watanabe -Date: Mon, 2 Sep 2024 11:41:57 +0900 -Subject: [PATCH 01/10] network/qdisc: introduce qdisc_ref() and qdisc_unref() - -No functional change, just refactoring and preparation for later change. - -(cherry picked from commit 9b294afa2dbdb05695925ded55a8f1bfa70bb087) ---- - src/network/networkd-network.c | 2 +- - src/network/tc/cake.c | 20 +++---- - src/network/tc/codel.c | 6 +- - src/network/tc/ets.c | 6 +- - src/network/tc/fifo.c | 4 +- - src/network/tc/fq-codel.c | 8 +-- - src/network/tc/fq-pie.c | 2 +- - src/network/tc/fq.c | 10 ++-- - src/network/tc/gred.c | 4 +- - src/network/tc/hhf.c | 2 +- - src/network/tc/htb.c | 4 +- - src/network/tc/netem.c | 6 +- - src/network/tc/pie.c | 2 +- - src/network/tc/qdisc.c | 103 +++++++++++++++++++++++---------- - src/network/tc/qdisc.h | 7 ++- - src/network/tc/sfb.c | 2 +- - src/network/tc/sfq.c | 2 +- - src/network/tc/tbf.c | 6 +- - src/network/tc/teql.c | 2 +- - 19 files changed, 122 insertions(+), 76 deletions(-) - -diff --git a/src/network/networkd-network.c b/src/network/networkd-network.c -index 8232db06c934c..155e9568e2a27 100644 ---- a/src/network/networkd-network.c -+++ b/src/network/networkd-network.c -@@ -799,7 +799,7 @@ static Network *network_free(Network *network) { - hashmap_free_with_destructor(network->rules_by_section, routing_policy_rule_free); - hashmap_free_with_destructor(network->dhcp_static_leases_by_section, dhcp_static_lease_free); - ordered_hashmap_free_with_destructor(network->sr_iov_by_section, sr_iov_free); -- hashmap_free_with_destructor(network->qdiscs_by_section, qdisc_free); -+ hashmap_free(network->qdiscs_by_section); - hashmap_free_with_destructor(network->tclasses_by_section, tclass_free); - - return mfree(network); -diff --git a/src/network/tc/cake.c b/src/network/tc/cake.c -index c495fafda4cc8..704e527b46a1f 100644 ---- a/src/network/tc/cake.c -+++ b/src/network/tc/cake.c -@@ -150,7 +150,7 @@ int config_parse_cake_bandwidth( - void *data, - void *userdata) { - -- _cleanup_(qdisc_free_or_set_invalidp) QDisc *qdisc = NULL; -+ _cleanup_(qdisc_unref_or_set_invalidp) QDisc *qdisc = NULL; - CommonApplicationsKeptEnhanced *c; - Network *network = ASSERT_PTR(data); - uint64_t k; -@@ -204,7 +204,7 @@ int config_parse_cake_overhead( - void *data, - void *userdata) { - -- _cleanup_(qdisc_free_or_set_invalidp) QDisc *qdisc = NULL; -+ _cleanup_(qdisc_unref_or_set_invalidp) QDisc *qdisc = NULL; - CommonApplicationsKeptEnhanced *c; - Network *network = ASSERT_PTR(data); - int32_t v; -@@ -263,7 +263,7 @@ int config_parse_cake_mpu( - void *data, - void *userdata) { - -- _cleanup_(qdisc_free_or_set_invalidp) QDisc *qdisc = NULL; -+ _cleanup_(qdisc_unref_or_set_invalidp) QDisc *qdisc = NULL; - CommonApplicationsKeptEnhanced *c; - Network *network = ASSERT_PTR(data); - uint32_t v; -@@ -321,7 +321,7 @@ int config_parse_cake_tristate( - void *data, - void *userdata) { - -- _cleanup_(qdisc_free_or_set_invalidp) QDisc *qdisc = NULL; -+ _cleanup_(qdisc_unref_or_set_invalidp) QDisc *qdisc = NULL; - CommonApplicationsKeptEnhanced *c; - Network *network = ASSERT_PTR(data); - int *dest, r; -@@ -386,7 +386,7 @@ int config_parse_cake_compensation_mode( - void *data, - void *userdata) { - -- _cleanup_(qdisc_free_or_set_invalidp) QDisc *qdisc = NULL; -+ _cleanup_(qdisc_unref_or_set_invalidp) QDisc *qdisc = NULL; - CommonApplicationsKeptEnhanced *c; - Network *network = ASSERT_PTR(data); - CakeCompensationMode mode; -@@ -451,7 +451,7 @@ int config_parse_cake_flow_isolation_mode( - void *data, - void *userdata) { - -- _cleanup_(qdisc_free_or_set_invalidp) QDisc *qdisc = NULL; -+ _cleanup_(qdisc_unref_or_set_invalidp) QDisc *qdisc = NULL; - CommonApplicationsKeptEnhanced *c; - Network *network = ASSERT_PTR(data); - CakeFlowIsolationMode mode; -@@ -513,7 +513,7 @@ int config_parse_cake_priority_queueing_preset( - void *data, - void *userdata) { - -- _cleanup_(qdisc_free_or_set_invalidp) QDisc *qdisc = NULL; -+ _cleanup_(qdisc_unref_or_set_invalidp) QDisc *qdisc = NULL; - CommonApplicationsKeptEnhanced *c; - CakePriorityQueueingPreset preset; - Network *network = ASSERT_PTR(data); -@@ -565,7 +565,7 @@ int config_parse_cake_fwmark( - void *data, - void *userdata) { - -- _cleanup_(qdisc_free_or_set_invalidp) QDisc *qdisc = NULL; -+ _cleanup_(qdisc_unref_or_set_invalidp) QDisc *qdisc = NULL; - CommonApplicationsKeptEnhanced *c; - Network *network = ASSERT_PTR(data); - uint32_t fwmark; -@@ -623,7 +623,7 @@ int config_parse_cake_rtt( - void *data, - void *userdata) { - -- _cleanup_(qdisc_free_or_set_invalidp) QDisc *qdisc = NULL; -+ _cleanup_(qdisc_unref_or_set_invalidp) QDisc *qdisc = NULL; - CommonApplicationsKeptEnhanced *c; - Network *network = ASSERT_PTR(data); - usec_t t; -@@ -689,7 +689,7 @@ int config_parse_cake_ack_filter( - void *data, - void *userdata) { - -- _cleanup_(qdisc_free_or_set_invalidp) QDisc *qdisc = NULL; -+ _cleanup_(qdisc_unref_or_set_invalidp) QDisc *qdisc = NULL; - CommonApplicationsKeptEnhanced *c; - CakeAckFilter ack_filter; - Network *network = ASSERT_PTR(data); -diff --git a/src/network/tc/codel.c b/src/network/tc/codel.c -index e21252394c03e..53ccf66e419e6 100644 ---- a/src/network/tc/codel.c -+++ b/src/network/tc/codel.c -@@ -86,7 +86,7 @@ int config_parse_controlled_delay_u32( - void *data, - void *userdata) { - -- _cleanup_(qdisc_free_or_set_invalidp) QDisc *qdisc = NULL; -+ _cleanup_(qdisc_unref_or_set_invalidp) QDisc *qdisc = NULL; - ControlledDelay *cd; - Network *network = ASSERT_PTR(data); - int r; -@@ -138,7 +138,7 @@ int config_parse_controlled_delay_usec( - void *data, - void *userdata) { - -- _cleanup_(qdisc_free_or_set_invalidp) QDisc *qdisc = NULL; -+ _cleanup_(qdisc_unref_or_set_invalidp) QDisc *qdisc = NULL; - ControlledDelay *cd; - Network *network = ASSERT_PTR(data); - usec_t *p; -@@ -203,7 +203,7 @@ int config_parse_controlled_delay_bool( - void *data, - void *userdata) { - -- _cleanup_(qdisc_free_or_set_invalidp) QDisc *qdisc = NULL; -+ _cleanup_(qdisc_unref_or_set_invalidp) QDisc *qdisc = NULL; - ControlledDelay *cd; - Network *network = ASSERT_PTR(data); - int r; -diff --git a/src/network/tc/ets.c b/src/network/tc/ets.c -index 730b0a10c3cfb..4af750834cb30 100644 ---- a/src/network/tc/ets.c -+++ b/src/network/tc/ets.c -@@ -88,7 +88,7 @@ int config_parse_ets_u8( - void *data, - void *userdata) { - -- _cleanup_(qdisc_free_or_set_invalidp) QDisc *qdisc = NULL; -+ _cleanup_(qdisc_unref_or_set_invalidp) QDisc *qdisc = NULL; - EnhancedTransmissionSelection *ets; - Network *network = ASSERT_PTR(data); - uint8_t v, *p; -@@ -154,7 +154,7 @@ int config_parse_ets_quanta( - void *data, - void *userdata) { - -- _cleanup_(qdisc_free_or_set_invalidp) QDisc *qdisc = NULL; -+ _cleanup_(qdisc_unref_or_set_invalidp) QDisc *qdisc = NULL; - EnhancedTransmissionSelection *ets; - Network *network = ASSERT_PTR(data); - int r; -@@ -237,7 +237,7 @@ int config_parse_ets_prio( - void *data, - void *userdata) { - -- _cleanup_(qdisc_free_or_set_invalidp) QDisc *qdisc = NULL; -+ _cleanup_(qdisc_unref_or_set_invalidp) QDisc *qdisc = NULL; - EnhancedTransmissionSelection *ets; - Network *network = ASSERT_PTR(data); - int r; -diff --git a/src/network/tc/fifo.c b/src/network/tc/fifo.c -index 940fa0062f001..9638be8ff9caa 100644 ---- a/src/network/tc/fifo.c -+++ b/src/network/tc/fifo.c -@@ -52,7 +52,7 @@ int config_parse_pfifo_size( - void *data, - void *userdata) { - -- _cleanup_(qdisc_free_or_set_invalidp) QDisc *qdisc = NULL; -+ _cleanup_(qdisc_unref_or_set_invalidp) QDisc *qdisc = NULL; - Network *network = ASSERT_PTR(data); - FirstInFirstOut *fifo; - int r; -@@ -112,7 +112,7 @@ int config_parse_bfifo_size( - void *data, - void *userdata) { - -- _cleanup_(qdisc_free_or_set_invalidp) QDisc *qdisc = NULL; -+ _cleanup_(qdisc_unref_or_set_invalidp) QDisc *qdisc = NULL; - Network *network = ASSERT_PTR(data); - FirstInFirstOut *fifo; - uint64_t u; -diff --git a/src/network/tc/fq-codel.c b/src/network/tc/fq-codel.c -index 124faf73e72a4..9255cde4650d9 100644 ---- a/src/network/tc/fq-codel.c -+++ b/src/network/tc/fq-codel.c -@@ -106,7 +106,7 @@ int config_parse_fair_queueing_controlled_delay_u32( - void *data, - void *userdata) { - -- _cleanup_(qdisc_free_or_set_invalidp) QDisc *qdisc = NULL; -+ _cleanup_(qdisc_unref_or_set_invalidp) QDisc *qdisc = NULL; - FairQueueingControlledDelay *fqcd; - Network *network = ASSERT_PTR(data); - uint32_t *p; -@@ -166,7 +166,7 @@ int config_parse_fair_queueing_controlled_delay_usec( - void *data, - void *userdata) { - -- _cleanup_(qdisc_free_or_set_invalidp) QDisc *qdisc = NULL; -+ _cleanup_(qdisc_unref_or_set_invalidp) QDisc *qdisc = NULL; - FairQueueingControlledDelay *fqcd; - Network *network = ASSERT_PTR(data); - usec_t *p; -@@ -231,7 +231,7 @@ int config_parse_fair_queueing_controlled_delay_bool( - void *data, - void *userdata) { - -- _cleanup_(qdisc_free_or_set_invalidp) QDisc *qdisc = NULL; -+ _cleanup_(qdisc_unref_or_set_invalidp) QDisc *qdisc = NULL; - FairQueueingControlledDelay *fqcd; - Network *network = ASSERT_PTR(data); - int r; -@@ -276,7 +276,7 @@ int config_parse_fair_queueing_controlled_delay_size( - void *data, - void *userdata) { - -- _cleanup_(qdisc_free_or_set_invalidp) QDisc *qdisc = NULL; -+ _cleanup_(qdisc_unref_or_set_invalidp) QDisc *qdisc = NULL; - FairQueueingControlledDelay *fqcd; - Network *network = ASSERT_PTR(data); - uint64_t sz; -diff --git a/src/network/tc/fq-pie.c b/src/network/tc/fq-pie.c -index c8b2e7b7ee908..8f4f7c431c441 100644 ---- a/src/network/tc/fq-pie.c -+++ b/src/network/tc/fq-pie.c -@@ -49,7 +49,7 @@ int config_parse_fq_pie_packet_limit( - void *data, - void *userdata) { - -- _cleanup_(qdisc_free_or_set_invalidp) QDisc *qdisc = NULL; -+ _cleanup_(qdisc_unref_or_set_invalidp) QDisc *qdisc = NULL; - FlowQueuePIE *fq_pie; - Network *network = ASSERT_PTR(data); - uint32_t val; -diff --git a/src/network/tc/fq.c b/src/network/tc/fq.c -index 74785c980ae4b..ea55e5cb0a122 100644 ---- a/src/network/tc/fq.c -+++ b/src/network/tc/fq.c -@@ -115,7 +115,7 @@ int config_parse_fair_queueing_u32( - void *data, - void *userdata) { - -- _cleanup_(qdisc_free_or_set_invalidp) QDisc *qdisc = NULL; -+ _cleanup_(qdisc_unref_or_set_invalidp) QDisc *qdisc = NULL; - FairQueueing *fq; - Network *network = ASSERT_PTR(data); - uint32_t *p; -@@ -179,7 +179,7 @@ int config_parse_fair_queueing_size( - void *data, - void *userdata) { - -- _cleanup_(qdisc_free_or_set_invalidp) QDisc *qdisc = NULL; -+ _cleanup_(qdisc_unref_or_set_invalidp) QDisc *qdisc = NULL; - FairQueueing *fq; - Network *network = ASSERT_PTR(data); - uint64_t sz; -@@ -247,7 +247,7 @@ int config_parse_fair_queueing_bool( - void *data, - void *userdata) { - -- _cleanup_(qdisc_free_or_set_invalidp) QDisc *qdisc = NULL; -+ _cleanup_(qdisc_unref_or_set_invalidp) QDisc *qdisc = NULL; - FairQueueing *fq; - Network *network = ASSERT_PTR(data); - int r; -@@ -293,7 +293,7 @@ int config_parse_fair_queueing_usec( - void *data, - void *userdata) { - -- _cleanup_(qdisc_free_or_set_invalidp) QDisc *qdisc = NULL; -+ _cleanup_(qdisc_unref_or_set_invalidp) QDisc *qdisc = NULL; - FairQueueing *fq; - Network *network = ASSERT_PTR(data); - usec_t sec; -@@ -353,7 +353,7 @@ int config_parse_fair_queueing_max_rate( - void *data, - void *userdata) { - -- _cleanup_(qdisc_free_or_set_invalidp) QDisc *qdisc = NULL; -+ _cleanup_(qdisc_unref_or_set_invalidp) QDisc *qdisc = NULL; - FairQueueing *fq; - Network *network = ASSERT_PTR(data); - uint64_t sz; -diff --git a/src/network/tc/gred.c b/src/network/tc/gred.c -index 2efb02c345f04..198905a1521ff 100644 ---- a/src/network/tc/gred.c -+++ b/src/network/tc/gred.c -@@ -77,7 +77,7 @@ int config_parse_generic_random_early_detection_u32( - void *data, - void *userdata) { - -- _cleanup_(qdisc_free_or_set_invalidp) QDisc *qdisc = NULL; -+ _cleanup_(qdisc_unref_or_set_invalidp) QDisc *qdisc = NULL; - GenericRandomEarlyDetection *gred; - Network *network = ASSERT_PTR(data); - uint32_t *p; -@@ -143,7 +143,7 @@ int config_parse_generic_random_early_detection_bool( - void *data, - void *userdata) { - -- _cleanup_(qdisc_free_or_set_invalidp) QDisc *qdisc = NULL; -+ _cleanup_(qdisc_unref_or_set_invalidp) QDisc *qdisc = NULL; - GenericRandomEarlyDetection *gred; - Network *network = ASSERT_PTR(data); - int r; -diff --git a/src/network/tc/hhf.c b/src/network/tc/hhf.c -index d44522f98cc92..9ddb7ef9063d5 100644 ---- a/src/network/tc/hhf.c -+++ b/src/network/tc/hhf.c -@@ -49,7 +49,7 @@ int config_parse_heavy_hitter_filter_packet_limit( - void *data, - void *userdata) { - -- _cleanup_(qdisc_free_or_set_invalidp) QDisc *qdisc = NULL; -+ _cleanup_(qdisc_unref_or_set_invalidp) QDisc *qdisc = NULL; - HeavyHitterFilter *hhf; - Network *network = ASSERT_PTR(data); - int r; -diff --git a/src/network/tc/htb.c b/src/network/tc/htb.c -index eb2c8cfff4cd1..8f1faa1dc5d45 100644 ---- a/src/network/tc/htb.c -+++ b/src/network/tc/htb.c -@@ -57,7 +57,7 @@ int config_parse_hierarchy_token_bucket_default_class( - void *data, - void *userdata) { - -- _cleanup_(qdisc_free_or_set_invalidp) QDisc *qdisc = NULL; -+ _cleanup_(qdisc_unref_or_set_invalidp) QDisc *qdisc = NULL; - HierarchyTokenBucket *htb; - Network *network = ASSERT_PTR(data); - int r; -@@ -109,7 +109,7 @@ int config_parse_hierarchy_token_bucket_u32( - void *data, - void *userdata) { - -- _cleanup_(qdisc_free_or_set_invalidp) QDisc *qdisc = NULL; -+ _cleanup_(qdisc_unref_or_set_invalidp) QDisc *qdisc = NULL; - HierarchyTokenBucket *htb; - Network *network = ASSERT_PTR(data); - int r; -diff --git a/src/network/tc/netem.c b/src/network/tc/netem.c -index 6a63221c3ac30..51039de1f4e7b 100644 ---- a/src/network/tc/netem.c -+++ b/src/network/tc/netem.c -@@ -60,7 +60,7 @@ int config_parse_network_emulator_delay( - void *data, - void *userdata) { - -- _cleanup_(qdisc_free_or_set_invalidp) QDisc *qdisc = NULL; -+ _cleanup_(qdisc_unref_or_set_invalidp) QDisc *qdisc = NULL; - Network *network = ASSERT_PTR(data); - NetworkEmulator *ne; - usec_t u; -@@ -121,7 +121,7 @@ int config_parse_network_emulator_rate( - void *data, - void *userdata) { - -- _cleanup_(qdisc_free_or_set_invalidp) QDisc *qdisc = NULL; -+ _cleanup_(qdisc_unref_or_set_invalidp) QDisc *qdisc = NULL; - Network *network = ASSERT_PTR(data); - NetworkEmulator *ne; - uint32_t rate; -@@ -181,7 +181,7 @@ int config_parse_network_emulator_packet_limit( - void *data, - void *userdata) { - -- _cleanup_(qdisc_free_or_set_invalidp) QDisc *qdisc = NULL; -+ _cleanup_(qdisc_unref_or_set_invalidp) QDisc *qdisc = NULL; - Network *network = ASSERT_PTR(data); - NetworkEmulator *ne; - int r; -diff --git a/src/network/tc/pie.c b/src/network/tc/pie.c -index c9b171baf11d7..c482f19787abc 100644 ---- a/src/network/tc/pie.c -+++ b/src/network/tc/pie.c -@@ -49,7 +49,7 @@ int config_parse_pie_packet_limit( - void *data, - void *userdata) { - -- _cleanup_(qdisc_free_or_set_invalidp) QDisc *qdisc = NULL; -+ _cleanup_(qdisc_unref_or_set_invalidp) QDisc *qdisc = NULL; - ProportionalIntegralControllerEnhanced *pie; - Network *network = ASSERT_PTR(data); - int r; -diff --git a/src/network/tc/qdisc.c b/src/network/tc/qdisc.c -index 38dee2c00157f..d372481d6280b 100644 ---- a/src/network/tc/qdisc.c -+++ b/src/network/tc/qdisc.c -@@ -42,8 +42,54 @@ const QDiscVTable * const qdisc_vtable[_QDISC_KIND_MAX] = { - [QDISC_KIND_TEQL] = &teql_vtable, - }; - -+static QDisc* qdisc_detach_impl(QDisc *qdisc) { -+ assert(qdisc); -+ assert(!qdisc->link || !qdisc->network); -+ -+ if (qdisc->network) { -+ assert(qdisc->section); -+ hashmap_remove(qdisc->network->qdiscs_by_section, qdisc->section); -+ -+ qdisc->network = NULL; -+ return qdisc; -+ } -+ -+ if (qdisc->link) { -+ set_remove(qdisc->link->qdiscs, qdisc); -+ -+ qdisc->link = NULL; -+ return qdisc; -+ } -+ -+ return NULL; -+} -+ -+static void qdisc_detach(QDisc *qdisc) { -+ assert(qdisc); -+ -+ qdisc_unref(qdisc_detach_impl(qdisc)); -+} -+ -+static void qdisc_hash_func(const QDisc *qdisc, struct siphash *state); -+static int qdisc_compare_func(const QDisc *a, const QDisc *b); -+ -+DEFINE_PRIVATE_HASH_OPS_WITH_KEY_DESTRUCTOR( -+ qdisc_hash_ops, -+ QDisc, -+ qdisc_hash_func, -+ qdisc_compare_func, -+ qdisc_detach); -+ -+DEFINE_PRIVATE_HASH_OPS_WITH_VALUE_DESTRUCTOR( -+ qdisc_section_hash_ops, -+ ConfigSection, -+ config_section_hash_func, -+ config_section_compare_func, -+ QDisc, -+ qdisc_detach); -+ - static int qdisc_new(QDiscKind kind, QDisc **ret) { -- _cleanup_(qdisc_freep) QDisc *qdisc = NULL; -+ _cleanup_(qdisc_unrefp) QDisc *qdisc = NULL; - int r; - - if (kind == _QDISC_KIND_INVALID) { -@@ -52,6 +98,7 @@ static int qdisc_new(QDiscKind kind, QDisc **ret) { - return -ENOMEM; - - *qdisc = (QDisc) { -+ .n_ref = 1, - .parent = TC_H_ROOT, - .kind = kind, - }; -@@ -61,6 +108,7 @@ static int qdisc_new(QDiscKind kind, QDisc **ret) { - if (!qdisc) - return -ENOMEM; - -+ qdisc->n_ref = 1; - qdisc->parent = TC_H_ROOT; - qdisc->kind = kind; - -@@ -78,7 +126,7 @@ static int qdisc_new(QDiscKind kind, QDisc **ret) { - - int qdisc_new_static(QDiscKind kind, Network *network, const char *filename, unsigned section_line, QDisc **ret) { - _cleanup_(config_section_freep) ConfigSection *n = NULL; -- _cleanup_(qdisc_freep) QDisc *qdisc = NULL; -+ _cleanup_(qdisc_unrefp) QDisc *qdisc = NULL; - QDisc *existing; - int r; - -@@ -113,14 +161,14 @@ int qdisc_new_static(QDiscKind kind, Network *network, const char *filename, uns - qdisc->parent = existing->parent; - qdisc->tca_kind = TAKE_PTR(existing->tca_kind); - -- qdisc_free(existing); -+ qdisc_detach(existing); - } - - qdisc->network = network; - qdisc->section = TAKE_PTR(n); - qdisc->source = NETWORK_CONFIG_SOURCE_STATIC; - -- r = hashmap_ensure_put(&network->qdiscs_by_section, &config_section_hash_ops, qdisc->section, qdisc); -+ r = hashmap_ensure_put(&network->qdiscs_by_section, &qdisc_section_hash_ops, qdisc->section, qdisc); - if (r < 0) - return r; - -@@ -128,22 +176,20 @@ int qdisc_new_static(QDiscKind kind, Network *network, const char *filename, uns - return 0; - } - --QDisc* qdisc_free(QDisc *qdisc) { -+static QDisc* qdisc_free(QDisc *qdisc) { - if (!qdisc) - return NULL; - -- if (qdisc->network && qdisc->section) -- hashmap_remove(qdisc->network->qdiscs_by_section, qdisc->section); -+ qdisc_detach_impl(qdisc); - - config_section_free(qdisc->section); - -- if (qdisc->link) -- set_remove(qdisc->link->qdiscs, qdisc); -- - free(qdisc->tca_kind); - return mfree(qdisc); - } - -+DEFINE_TRIVIAL_REF_UNREF_FUNC(QDisc, qdisc, qdisc_free); -+ - static const char *qdisc_get_tca_kind(const QDisc *qdisc) { - assert(qdisc); - -@@ -177,13 +223,6 @@ static int qdisc_compare_func(const QDisc *a, const QDisc *b) { - return strcmp_ptr(qdisc_get_tca_kind(a), qdisc_get_tca_kind(b)); - } - --DEFINE_PRIVATE_HASH_OPS_WITH_KEY_DESTRUCTOR( -- qdisc_hash_ops, -- QDisc, -- qdisc_hash_func, -- qdisc_compare_func, -- qdisc_free); -- - static int qdisc_get(Link *link, const QDisc *in, QDisc **ret) { - QDisc *existing; - -@@ -199,11 +238,13 @@ static int qdisc_get(Link *link, const QDisc *in, QDisc **ret) { - return 0; - } - --static int qdisc_add(Link *link, QDisc *qdisc) { -+static int qdisc_attach(Link *link, QDisc *qdisc) { - int r; - - assert(link); - assert(qdisc); -+ assert(!qdisc->link); -+ assert(!qdisc->network); - - r = set_ensure_put(&link->qdiscs, &qdisc_hash_ops, qdisc); - if (r < 0) -@@ -212,11 +253,12 @@ static int qdisc_add(Link *link, QDisc *qdisc) { - return -EEXIST; - - qdisc->link = link; -+ qdisc_ref(qdisc); - return 0; - } - - static int qdisc_dup(const QDisc *src, QDisc **ret) { -- _cleanup_(qdisc_freep) QDisc *dst = NULL; -+ _cleanup_(qdisc_unrefp) QDisc *dst = NULL; - - assert(src); - assert(ret); -@@ -228,7 +270,8 @@ static int qdisc_dup(const QDisc *src, QDisc **ret) { - if (!dst) - return -ENOMEM; - -- /* clear all pointers */ -+ /* clear the reference counter and all pointers */ -+ dst->n_ref = 1; - dst->network = NULL; - dst->section = NULL; - dst->link = NULL; -@@ -319,7 +362,7 @@ void link_qdisc_drop_marked(Link *link) { - - if (qdisc->state == 0) { - log_qdisc_debug(qdisc, link, "Forgetting"); -- qdisc_free(qdisc); -+ qdisc_detach(qdisc); - } else - log_qdisc_debug(qdisc, link, "Removed"); - } -@@ -443,17 +486,17 @@ int link_request_qdisc(Link *link, QDisc *qdisc) { - assert(qdisc); - - if (qdisc_get(link, qdisc, &existing) < 0) { -- _cleanup_(qdisc_freep) QDisc *tmp = NULL; -+ _cleanup_(qdisc_unrefp) QDisc *tmp = NULL; - - r = qdisc_dup(qdisc, &tmp); - if (r < 0) - return log_oom(); - -- r = qdisc_add(link, tmp); -+ r = qdisc_attach(link, tmp); - if (r < 0) - return log_link_warning_errno(link, r, "Failed to store QDisc: %m"); - -- existing = TAKE_PTR(tmp); -+ existing = tmp; - } else - existing->source = qdisc->source; - -@@ -476,7 +519,7 @@ int link_request_qdisc(Link *link, QDisc *qdisc) { - } - - int manager_rtnl_process_qdisc(sd_netlink *rtnl, sd_netlink_message *message, Manager *m) { -- _cleanup_(qdisc_freep) QDisc *tmp = NULL; -+ _cleanup_(qdisc_unrefp) QDisc *tmp = NULL; - QDisc *qdisc = NULL; - Link *link; - uint16_t type; -@@ -551,13 +594,13 @@ int manager_rtnl_process_qdisc(sd_netlink *rtnl, sd_netlink_message *message, Ma - qdisc_enter_configured(tmp); - log_qdisc_debug(tmp, link, "Received new"); - -- r = qdisc_add(link, tmp); -+ r = qdisc_attach(link, tmp); - if (r < 0) { - log_link_warning_errno(link, r, "Failed to remember QDisc, ignoring: %m"); - return 0; - } - -- qdisc = TAKE_PTR(tmp); -+ qdisc = tmp; - } - - if (!m->enumerating) { -@@ -628,7 +671,7 @@ void network_drop_invalid_qdisc(Network *network) { - - HASHMAP_FOREACH(qdisc, network->qdiscs_by_section) - if (qdisc_section_verify(qdisc, &has_root, &has_clsact) < 0) -- qdisc_free(qdisc); -+ qdisc_detach(qdisc); - } - - int config_parse_qdisc_parent( -@@ -643,7 +686,7 @@ int config_parse_qdisc_parent( - void *data, - void *userdata) { - -- _cleanup_(qdisc_free_or_set_invalidp) QDisc *qdisc = NULL; -+ _cleanup_(qdisc_unref_or_set_invalidp) QDisc *qdisc = NULL; - Network *network = ASSERT_PTR(data); - int r; - -@@ -702,7 +745,7 @@ int config_parse_qdisc_handle( - void *data, - void *userdata) { - -- _cleanup_(qdisc_free_or_set_invalidp) QDisc *qdisc = NULL; -+ _cleanup_(qdisc_unref_or_set_invalidp) QDisc *qdisc = NULL; - Network *network = ASSERT_PTR(data); - uint16_t n; - int r; -diff --git a/src/network/tc/qdisc.h b/src/network/tc/qdisc.h -index cbba1bef71199..3989ad7651531 100644 ---- a/src/network/tc/qdisc.h -+++ b/src/network/tc/qdisc.h -@@ -42,6 +42,8 @@ typedef struct QDisc { - NetworkConfigSource source; - NetworkConfigState state; - -+ unsigned n_ref; -+ - uint32_t handle; - uint32_t parent; - -@@ -74,7 +76,8 @@ extern const QDiscVTable * const qdisc_vtable[_QDISC_KIND_MAX]; - - DEFINE_NETWORK_CONFIG_STATE_FUNCTIONS(QDisc, qdisc); - --QDisc* qdisc_free(QDisc *qdisc); -+QDisc* qdisc_ref(QDisc *qdisc); -+QDisc* qdisc_unref(QDisc *qdisc); - int qdisc_new_static(QDiscKind kind, Network *network, const char *filename, unsigned section_line, QDisc **ret); - - void qdisc_mark_recursive(QDisc *qdisc); -@@ -89,7 +92,7 @@ void network_drop_invalid_qdisc(Network *network); - - int manager_rtnl_process_qdisc(sd_netlink *rtnl, sd_netlink_message *message, Manager *m); - --DEFINE_SECTION_CLEANUP_FUNCTIONS(QDisc, qdisc_free); -+DEFINE_SECTION_CLEANUP_FUNCTIONS(QDisc, qdisc_unref); - - CONFIG_PARSER_PROTOTYPE(config_parse_qdisc_parent); - CONFIG_PARSER_PROTOTYPE(config_parse_qdisc_handle); -diff --git a/src/network/tc/sfb.c b/src/network/tc/sfb.c -index 861c5fe2a0c0b..07fac6700f693 100644 ---- a/src/network/tc/sfb.c -+++ b/src/network/tc/sfb.c -@@ -60,7 +60,7 @@ int config_parse_stochastic_fair_blue_u32( - void *data, - void *userdata) { - -- _cleanup_(qdisc_free_or_set_invalidp) QDisc *qdisc = NULL; -+ _cleanup_(qdisc_unref_or_set_invalidp) QDisc *qdisc = NULL; - StochasticFairBlue *sfb; - Network *network = ASSERT_PTR(data); - int r; -diff --git a/src/network/tc/sfq.c b/src/network/tc/sfq.c -index 92dbae1166a66..78778653439cb 100644 ---- a/src/network/tc/sfq.c -+++ b/src/network/tc/sfq.c -@@ -44,7 +44,7 @@ int config_parse_stochastic_fairness_queueing_perturb_period( - void *data, - void *userdata) { - -- _cleanup_(qdisc_free_or_set_invalidp) QDisc *qdisc = NULL; -+ _cleanup_(qdisc_unref_or_set_invalidp) QDisc *qdisc = NULL; - StochasticFairnessQueueing *sfq; - Network *network = ASSERT_PTR(data); - int r; -diff --git a/src/network/tc/tbf.c b/src/network/tc/tbf.c -index 647fc8cb1eb8a..3e7a3098dab3f 100644 ---- a/src/network/tc/tbf.c -+++ b/src/network/tc/tbf.c -@@ -122,7 +122,7 @@ int config_parse_token_bucket_filter_size( - void *data, - void *userdata) { - -- _cleanup_(qdisc_free_or_set_invalidp) QDisc *qdisc = NULL; -+ _cleanup_(qdisc_unref_or_set_invalidp) QDisc *qdisc = NULL; - Network *network = ASSERT_PTR(data); - TokenBucketFilter *tbf; - uint64_t k; -@@ -195,7 +195,7 @@ int config_parse_token_bucket_filter_rate( - void *data, - void *userdata) { - -- _cleanup_(qdisc_free_or_set_invalidp) QDisc *qdisc = NULL; -+ _cleanup_(qdisc_unref_or_set_invalidp) QDisc *qdisc = NULL; - Network *network = ASSERT_PTR(data); - TokenBucketFilter *tbf; - uint64_t k, *p; -@@ -256,7 +256,7 @@ int config_parse_token_bucket_filter_latency( - void *data, - void *userdata) { - -- _cleanup_(qdisc_free_or_set_invalidp) QDisc *qdisc = NULL; -+ _cleanup_(qdisc_unref_or_set_invalidp) QDisc *qdisc = NULL; - Network *network = ASSERT_PTR(data); - TokenBucketFilter *tbf; - usec_t u; -diff --git a/src/network/tc/teql.c b/src/network/tc/teql.c -index dcb149dbe2a5b..f4fa331f523c2 100644 ---- a/src/network/tc/teql.c -+++ b/src/network/tc/teql.c -@@ -50,7 +50,7 @@ int config_parse_trivial_link_equalizer_id( - void *data, - void *userdata) { - -- _cleanup_(qdisc_free_or_set_invalidp) QDisc *qdisc = NULL; -+ _cleanup_(qdisc_unref_or_set_invalidp) QDisc *qdisc = NULL; - TrivialLinkEqualizer *teql; - Network *network = ASSERT_PTR(data); - unsigned id; - -From 51800c582a03cfb58de19020b4fd81cf6754c17f Mon Sep 17 00:00:00 2001 -From: Yu Watanabe -Date: Mon, 2 Sep 2024 11:59:51 +0900 -Subject: [PATCH 02/10] network/tclass: introduce tclass_ref() and - tclass_unref() - -No functional change, just refactoring and preparation for later change. - -(cherry picked from commit 541d0ed20a4e8572536d3f5268e6ffa84c9faa04) ---- - src/network/networkd-network.c | 2 +- - src/network/tc/drr.c | 2 +- - src/network/tc/htb.c | 6 +- - src/network/tc/qfq.c | 4 +- - src/network/tc/tclass.c | 101 +++++++++++++++++++++++---------- - src/network/tc/tclass.h | 7 ++- - 6 files changed, 84 insertions(+), 38 deletions(-) - -diff --git a/src/network/networkd-network.c b/src/network/networkd-network.c -index 155e9568e2a27..d4161a608dae3 100644 ---- a/src/network/networkd-network.c -+++ b/src/network/networkd-network.c -@@ -800,7 +800,7 @@ static Network *network_free(Network *network) { - hashmap_free_with_destructor(network->dhcp_static_leases_by_section, dhcp_static_lease_free); - ordered_hashmap_free_with_destructor(network->sr_iov_by_section, sr_iov_free); - hashmap_free(network->qdiscs_by_section); -- hashmap_free_with_destructor(network->tclasses_by_section, tclass_free); -+ hashmap_free(network->tclasses_by_section); - - return mfree(network); - } -diff --git a/src/network/tc/drr.c b/src/network/tc/drr.c -index 373911bc70f31..5d754101de2af 100644 ---- a/src/network/tc/drr.c -+++ b/src/network/tc/drr.c -@@ -54,7 +54,7 @@ int config_parse_drr_size( - void *data, - void *userdata) { - -- _cleanup_(tclass_free_or_set_invalidp) TClass *tclass = NULL; -+ _cleanup_(tclass_unref_or_set_invalidp) TClass *tclass = NULL; - DeficitRoundRobinSchedulerClass *drr; - Network *network = ASSERT_PTR(data); - uint64_t u; -diff --git a/src/network/tc/htb.c b/src/network/tc/htb.c -index 8f1faa1dc5d45..39f436a804d2a 100644 ---- a/src/network/tc/htb.c -+++ b/src/network/tc/htb.c -@@ -251,7 +251,7 @@ int config_parse_hierarchy_token_bucket_class_u32( - void *data, - void *userdata) { - -- _cleanup_(tclass_free_or_set_invalidp) TClass *tclass = NULL; -+ _cleanup_(tclass_unref_or_set_invalidp) TClass *tclass = NULL; - HierarchyTokenBucketClass *htb; - Network *network = ASSERT_PTR(data); - uint32_t v; -@@ -304,7 +304,7 @@ int config_parse_hierarchy_token_bucket_class_size( - void *data, - void *userdata) { - -- _cleanup_(tclass_free_or_set_invalidp) TClass *tclass = NULL; -+ _cleanup_(tclass_unref_or_set_invalidp) TClass *tclass = NULL; - HierarchyTokenBucketClass *htb; - Network *network = ASSERT_PTR(data); - uint64_t v; -@@ -387,7 +387,7 @@ int config_parse_hierarchy_token_bucket_class_rate( - void *data, - void *userdata) { - -- _cleanup_(tclass_free_or_set_invalidp) TClass *tclass = NULL; -+ _cleanup_(tclass_unref_or_set_invalidp) TClass *tclass = NULL; - HierarchyTokenBucketClass *htb; - Network *network = ASSERT_PTR(data); - uint64_t *v; -diff --git a/src/network/tc/qfq.c b/src/network/tc/qfq.c -index 7702e6ff6e733..0da53a89e432e 100644 ---- a/src/network/tc/qfq.c -+++ b/src/network/tc/qfq.c -@@ -62,7 +62,7 @@ int config_parse_quick_fair_queueing_weight( - void *data, - void *userdata) { - -- _cleanup_(tclass_free_or_set_invalidp) TClass *tclass = NULL; -+ _cleanup_(tclass_unref_or_set_invalidp) TClass *tclass = NULL; - QuickFairQueueingClass *qfq; - Network *network = ASSERT_PTR(data); - uint32_t v; -@@ -122,7 +122,7 @@ int config_parse_quick_fair_queueing_max_packet( - void *data, - void *userdata) { - -- _cleanup_(tclass_free_or_set_invalidp) TClass *tclass = NULL; -+ _cleanup_(tclass_unref_or_set_invalidp) TClass *tclass = NULL; - QuickFairQueueingClass *qfq; - Network *network = ASSERT_PTR(data); - uint64_t v; -diff --git a/src/network/tc/tclass.c b/src/network/tc/tclass.c -index fcbe8cbcf46bd..168d93e1c521f 100644 ---- a/src/network/tc/tclass.c -+++ b/src/network/tc/tclass.c -@@ -24,8 +24,54 @@ const TClassVTable * const tclass_vtable[_TCLASS_KIND_MAX] = { - [TCLASS_KIND_QFQ] = &qfq_tclass_vtable, - }; - -+static TClass* tclass_detach_impl(TClass *tclass) { -+ assert(tclass); -+ assert(!tclass->link || !tclass->network); -+ -+ if (tclass->network) { -+ assert(tclass->section); -+ hashmap_remove(tclass->network->tclasses_by_section, tclass->section); -+ -+ tclass->network = NULL; -+ return tclass; -+ } -+ -+ if (tclass->link) { -+ set_remove(tclass->link->tclasses, tclass); -+ -+ tclass->link = NULL; -+ return tclass; -+ } -+ -+ return NULL; -+} -+ -+static void tclass_detach(TClass *tclass) { -+ assert(tclass); -+ -+ tclass_unref(tclass_detach_impl(tclass)); -+} -+ -+static void tclass_hash_func(const TClass *tclass, struct siphash *state); -+static int tclass_compare_func(const TClass *a, const TClass *b); -+ -+DEFINE_PRIVATE_HASH_OPS_WITH_KEY_DESTRUCTOR( -+ tclass_hash_ops, -+ TClass, -+ tclass_hash_func, -+ tclass_compare_func, -+ tclass_detach); -+ -+DEFINE_PRIVATE_HASH_OPS_WITH_VALUE_DESTRUCTOR( -+ tclass_section_hash_ops, -+ ConfigSection, -+ config_section_hash_func, -+ config_section_compare_func, -+ TClass, -+ tclass_detach); -+ - static int tclass_new(TClassKind kind, TClass **ret) { -- _cleanup_(tclass_freep) TClass *tclass = NULL; -+ _cleanup_(tclass_unrefp) TClass *tclass = NULL; - int r; - - if (kind == _TCLASS_KIND_INVALID) { -@@ -34,6 +80,7 @@ static int tclass_new(TClassKind kind, TClass **ret) { - return -ENOMEM; - - *tclass = (TClass) { -+ .n_ref = 1, - .parent = TC_H_ROOT, - .kind = kind, - }; -@@ -43,6 +90,7 @@ static int tclass_new(TClassKind kind, TClass **ret) { - if (!tclass) - return -ENOMEM; - -+ tclass->n_ref = 1; - tclass->parent = TC_H_ROOT; - tclass->kind = kind; - -@@ -60,7 +108,7 @@ static int tclass_new(TClassKind kind, TClass **ret) { - - int tclass_new_static(TClassKind kind, Network *network, const char *filename, unsigned section_line, TClass **ret) { - _cleanup_(config_section_freep) ConfigSection *n = NULL; -- _cleanup_(tclass_freep) TClass *tclass = NULL; -+ _cleanup_(tclass_unrefp) TClass *tclass = NULL; - TClass *existing; - int r; - -@@ -90,7 +138,7 @@ int tclass_new_static(TClassKind kind, Network *network, const char *filename, u - tclass->section = TAKE_PTR(n); - tclass->source = NETWORK_CONFIG_SOURCE_STATIC; - -- r = hashmap_ensure_put(&network->tclasses_by_section, &config_section_hash_ops, tclass->section, tclass); -+ r = hashmap_ensure_put(&network->tclasses_by_section, &tclass_section_hash_ops, tclass->section, tclass); - if (r < 0) - return r; - -@@ -98,22 +146,20 @@ int tclass_new_static(TClassKind kind, Network *network, const char *filename, u - return 0; - } - --TClass* tclass_free(TClass *tclass) { -+static TClass* tclass_free(TClass *tclass) { - if (!tclass) - return NULL; - -- if (tclass->network && tclass->section) -- hashmap_remove(tclass->network->tclasses_by_section, tclass->section); -+ tclass_detach_impl(tclass); - - config_section_free(tclass->section); - -- if (tclass->link) -- set_remove(tclass->link->tclasses, tclass); -- - free(tclass->tca_kind); - return mfree(tclass); - } - -+DEFINE_TRIVIAL_REF_UNREF_FUNC(TClass, tclass, tclass_free); -+ - static const char *tclass_get_tca_kind(const TClass *tclass) { - assert(tclass); - -@@ -147,13 +193,6 @@ static int tclass_compare_func(const TClass *a, const TClass *b) { - return strcmp_ptr(tclass_get_tca_kind(a), tclass_get_tca_kind(b)); - } - --DEFINE_PRIVATE_HASH_OPS_WITH_KEY_DESTRUCTOR( -- tclass_hash_ops, -- TClass, -- tclass_hash_func, -- tclass_compare_func, -- tclass_free); -- - static int tclass_get(Link *link, const TClass *in, TClass **ret) { - TClass *existing; - -@@ -169,11 +208,13 @@ static int tclass_get(Link *link, const TClass *in, TClass **ret) { - return 0; - } - --static int tclass_add(Link *link, TClass *tclass) { -+static int tclass_attach(Link *link, TClass *tclass) { - int r; - - assert(link); - assert(tclass); -+ assert(!tclass->link); -+ assert(!tclass->network); - - r = set_ensure_put(&link->tclasses, &tclass_hash_ops, tclass); - if (r < 0) -@@ -182,11 +223,12 @@ static int tclass_add(Link *link, TClass *tclass) { - return -EEXIST; - - tclass->link = link; -+ tclass_ref(tclass); - return 0; - } - - static int tclass_dup(const TClass *src, TClass **ret) { -- _cleanup_(tclass_freep) TClass *dst = NULL; -+ _cleanup_(tclass_unrefp) TClass *dst = NULL; - - assert(src); - assert(ret); -@@ -198,7 +240,8 @@ static int tclass_dup(const TClass *src, TClass **ret) { - if (!dst) - return -ENOMEM; - -- /* clear all pointers */ -+ /* clear the reference counter and all pointers */ -+ dst->n_ref = 1; - dst->network = NULL; - dst->section = NULL; - dst->link = NULL; -@@ -286,7 +329,7 @@ void link_tclass_drop_marked(Link *link) { - - if (tclass->state == 0) { - log_tclass_debug(tclass, link, "Forgetting"); -- tclass_free(tclass); -+ tclass_detach(tclass); - } else - log_tclass_debug(tclass, link, "Removed"); - } -@@ -393,17 +436,17 @@ int link_request_tclass(Link *link, TClass *tclass) { - assert(tclass); - - if (tclass_get(link, tclass, &existing) < 0) { -- _cleanup_(tclass_freep) TClass *tmp = NULL; -+ _cleanup_(tclass_unrefp) TClass *tmp = NULL; - - r = tclass_dup(tclass, &tmp); - if (r < 0) - return log_oom(); - -- r = tclass_add(link, tmp); -+ r = tclass_attach(link, tmp); - if (r < 0) - return log_link_warning_errno(link, r, "Failed to store TClass: %m"); - -- existing = TAKE_PTR(tmp); -+ existing = tmp; - } else - existing->source = tclass->source; - -@@ -426,7 +469,7 @@ int link_request_tclass(Link *link, TClass *tclass) { - } - - int manager_rtnl_process_tclass(sd_netlink *rtnl, sd_netlink_message *message, Manager *m) { -- _cleanup_(tclass_freep) TClass *tmp = NULL; -+ _cleanup_(tclass_unrefp) TClass *tmp = NULL; - TClass *tclass = NULL; - Link *link; - uint16_t type; -@@ -501,13 +544,13 @@ int manager_rtnl_process_tclass(sd_netlink *rtnl, sd_netlink_message *message, M - tclass_enter_configured(tmp); - log_tclass_debug(tmp, link, "Received new"); - -- r = tclass_add(link, tmp); -+ r = tclass_attach(link, tmp); - if (r < 0) { - log_link_warning_errno(link, r, "Failed to remember TClass, ignoring: %m"); - return 0; - } - -- tclass = TAKE_PTR(tmp); -+ tclass = tmp; - } - - break; -@@ -566,7 +609,7 @@ void network_drop_invalid_tclass(Network *network) { - - HASHMAP_FOREACH(tclass, network->tclasses_by_section) - if (tclass_section_verify(tclass) < 0) -- tclass_free(tclass); -+ tclass_detach(tclass); - } - - int config_parse_tclass_parent( -@@ -581,7 +624,7 @@ int config_parse_tclass_parent( - void *data, - void *userdata) { - -- _cleanup_(tclass_free_or_set_invalidp) TClass *tclass = NULL; -+ _cleanup_(tclass_unref_or_set_invalidp) TClass *tclass = NULL; - Network *network = ASSERT_PTR(data); - int r; - -@@ -627,7 +670,7 @@ int config_parse_tclass_classid( - void *data, - void *userdata) { - -- _cleanup_(tclass_free_or_set_invalidp) TClass *tclass = NULL; -+ _cleanup_(tclass_unref_or_set_invalidp) TClass *tclass = NULL; - Network *network = ASSERT_PTR(data); - int r; - -diff --git a/src/network/tc/tclass.h b/src/network/tc/tclass.h -index 85df57d42c21e..44f71814501dc 100644 ---- a/src/network/tc/tclass.h -+++ b/src/network/tc/tclass.h -@@ -24,6 +24,8 @@ typedef struct TClass { - NetworkConfigSource source; - NetworkConfigState state; - -+ unsigned n_ref; -+ - uint32_t classid; - uint32_t parent; - -@@ -55,7 +57,8 @@ extern const TClassVTable * const tclass_vtable[_TCLASS_KIND_MAX]; - - DEFINE_NETWORK_CONFIG_STATE_FUNCTIONS(TClass, tclass); - --TClass* tclass_free(TClass *tclass); -+TClass* tclass_ref(TClass *tclass); -+TClass* tclass_unref(TClass *tclass); - int tclass_new_static(TClassKind kind, Network *network, const char *filename, unsigned section_line, TClass **ret); - - void tclass_mark_recursive(TClass *tclass); -@@ -71,7 +74,7 @@ void network_drop_invalid_tclass(Network *network); - int manager_rtnl_process_tclass(sd_netlink *rtnl, sd_netlink_message *message, Manager *m); - int link_enumerate_tclass(Link *link, uint32_t parent); - --DEFINE_SECTION_CLEANUP_FUNCTIONS(TClass, tclass_free); -+DEFINE_SECTION_CLEANUP_FUNCTIONS(TClass, tclass_unref); - - CONFIG_PARSER_PROTOTYPE(config_parse_tclass_parent); - CONFIG_PARSER_PROTOTYPE(config_parse_tclass_classid); - -From 7594bd35d1756a5ce938763a26450c5ba0c99df5 Mon Sep 17 00:00:00 2001 -From: Yu Watanabe -Date: Mon, 2 Sep 2024 13:03:09 +0900 -Subject: [PATCH 03/10] network/neighbor: skip requesting neighbor if it is - already requested - -(cherry picked from commit 4bdc3d85aee073cb7d22b53bde13fd878333b12c) ---- - src/network/networkd-neighbor.c | 3 +++ - 1 file changed, 3 insertions(+) - -diff --git a/src/network/networkd-neighbor.c b/src/network/networkd-neighbor.c -index 6b81950f96c63..3377bb056e589 100644 ---- a/src/network/networkd-neighbor.c -+++ b/src/network/networkd-neighbor.c -@@ -343,6 +343,9 @@ static int link_request_neighbor(Link *link, const Neighbor *neighbor) { - return 0; - } - -+ if (neighbor_get_request(link, neighbor, NULL) >= 0) -+ return 0; /* already requested, skipping. */ -+ - r = neighbor_dup(neighbor, &tmp); - if (r < 0) - return r; - -From b7ca4295dd22d7998ecbe87ef5883c106b1e7182 Mon Sep 17 00:00:00 2001 -From: Yu Watanabe -Date: Mon, 2 Sep 2024 12:55:59 +0900 -Subject: [PATCH 04/10] network/qdisc: skip requesting qdisc if it is already - requested - -(cherry picked from commit 998973e313a680a3434c2dd23384e86ff01726f3) ---- - src/network/tc/qdisc.c | 27 +++++++++++++++++++++++++++ - 1 file changed, 27 insertions(+) - -diff --git a/src/network/tc/qdisc.c b/src/network/tc/qdisc.c -index d372481d6280b..1475b4aced4de 100644 ---- a/src/network/tc/qdisc.c -+++ b/src/network/tc/qdisc.c -@@ -238,6 +238,30 @@ static int qdisc_get(Link *link, const QDisc *in, QDisc **ret) { - return 0; - } - -+static int qdisc_get_request(Link *link, const QDisc *qdisc, Request **ret) { -+ Request *req; -+ -+ assert(link); -+ assert(link->manager); -+ assert(qdisc); -+ -+ req = ordered_set_get( -+ link->manager->request_queue, -+ &(Request) { -+ .link = link, -+ .type = REQUEST_TYPE_TC_QDISC, -+ .userdata = (void*) qdisc, -+ .hash_func = (hash_func_t) qdisc_hash_func, -+ .compare_func = (compare_func_t) qdisc_compare_func, -+ }); -+ if (!req) -+ return -ENOENT; -+ -+ if (ret) -+ *ret = req; -+ return 0; -+} -+ - static int qdisc_attach(Link *link, QDisc *qdisc) { - int r; - -@@ -485,6 +509,9 @@ int link_request_qdisc(Link *link, QDisc *qdisc) { - assert(link); - assert(qdisc); - -+ if (qdisc_get_request(link, qdisc, NULL) >= 0) -+ return 0; /* already requested, skipping. */ -+ - if (qdisc_get(link, qdisc, &existing) < 0) { - _cleanup_(qdisc_unrefp) QDisc *tmp = NULL; - - -From e51b9362c36f787e231e41e485dbdf0cebf94ded Mon Sep 17 00:00:00 2001 -From: Yu Watanabe -Date: Mon, 2 Sep 2024 13:06:54 +0900 -Subject: [PATCH 05/10] network/tclass: skip requesting tclass if it is already - requested - -(cherry picked from commit e3f91033aea354c28011e841b7043549a1a5226b) ---- - src/network/tc/tclass.c | 27 +++++++++++++++++++++++++++ - 1 file changed, 27 insertions(+) - -diff --git a/src/network/tc/tclass.c b/src/network/tc/tclass.c -index 168d93e1c521f..926ec69adf0fe 100644 ---- a/src/network/tc/tclass.c -+++ b/src/network/tc/tclass.c -@@ -208,6 +208,30 @@ static int tclass_get(Link *link, const TClass *in, TClass **ret) { - return 0; - } - -+static int tclass_get_request(Link *link, const TClass *tclass, Request **ret) { -+ Request *req; -+ -+ assert(link); -+ assert(link->manager); -+ assert(tclass); -+ -+ req = ordered_set_get( -+ link->manager->request_queue, -+ &(Request) { -+ .link = link, -+ .type = REQUEST_TYPE_TC_CLASS, -+ .userdata = (void*) tclass, -+ .hash_func = (hash_func_t) tclass_hash_func, -+ .compare_func = (compare_func_t) tclass_compare_func, -+ }); -+ if (!req) -+ return -ENOENT; -+ -+ if (ret) -+ *ret = req; -+ return 0; -+} -+ - static int tclass_attach(Link *link, TClass *tclass) { - int r; - -@@ -435,6 +459,9 @@ int link_request_tclass(Link *link, TClass *tclass) { - assert(link); - assert(tclass); - -+ if (tclass_get_request(link, tclass, NULL) >= 0) -+ return 0; /* already requested, skipping. */ -+ - if (tclass_get(link, tclass, &existing) < 0) { - _cleanup_(tclass_unrefp) TClass *tmp = NULL; - - -From 36e35ff4583b0f4b609a82e1a7178c3c810da4f9 Mon Sep 17 00:00:00 2001 -From: Yu Watanabe -Date: Mon, 2 Sep 2024 13:20:59 +0900 -Subject: [PATCH 06/10] network/qdisc: make qdisc_drop() static - -This also drops unused constant return value. - -(cherry picked from commit 4a31c768a9f4e1ff957880a5c4f52d36d768e4a4) ---- - src/network/tc/qdisc.c | 4 +--- - src/network/tc/qdisc.h | 1 - - 2 files changed, 1 insertion(+), 4 deletions(-) - -diff --git a/src/network/tc/qdisc.c b/src/network/tc/qdisc.c -index 1475b4aced4de..851f624c45954 100644 ---- a/src/network/tc/qdisc.c -+++ b/src/network/tc/qdisc.c -@@ -392,7 +392,7 @@ void link_qdisc_drop_marked(Link *link) { - } - } - --QDisc* qdisc_drop(QDisc *qdisc) { -+static void qdisc_drop(QDisc *qdisc) { - assert(qdisc); - assert(qdisc->link); - -@@ -401,8 +401,6 @@ QDisc* qdisc_drop(QDisc *qdisc) { - /* link_qdisc_drop_marked() may invalidate qdisc, so run link_tclass_drop_marked() first. */ - link_tclass_drop_marked(qdisc->link); - link_qdisc_drop_marked(qdisc->link); -- -- return NULL; - } - - static int qdisc_handler(sd_netlink *rtnl, sd_netlink_message *m, Request *req, Link *link, QDisc *qdisc) { -diff --git a/src/network/tc/qdisc.h b/src/network/tc/qdisc.h -index 3989ad7651531..75351fb8ada1f 100644 ---- a/src/network/tc/qdisc.h -+++ b/src/network/tc/qdisc.h -@@ -81,7 +81,6 @@ QDisc* qdisc_unref(QDisc *qdisc); - int qdisc_new_static(QDiscKind kind, Network *network, const char *filename, unsigned section_line, QDisc **ret); - - void qdisc_mark_recursive(QDisc *qdisc); --QDisc* qdisc_drop(QDisc *qdisc); - void link_qdisc_drop_marked(Link *link); - - int link_find_qdisc(Link *link, uint32_t handle, const char *kind, QDisc **qdisc); - -From 29aa394b2b267d993ae7ea713396315b0fe239ff Mon Sep 17 00:00:00 2001 -From: Yu Watanabe -Date: Mon, 2 Sep 2024 13:22:41 +0900 -Subject: [PATCH 07/10] network/tclass: make tclass_drop() static - -This also drops unused constant return value. - -(cherry picked from commit 3d7f26d9f2d2e1129dfd64f786ae04d75d546a61) ---- - src/network/tc/tclass.c | 6 ++---- - src/network/tc/tclass.h | 1 - - 2 files changed, 2 insertions(+), 5 deletions(-) - -diff --git a/src/network/tc/tclass.c b/src/network/tc/tclass.c -index 926ec69adf0fe..3c74f95992ce2 100644 ---- a/src/network/tc/tclass.c -+++ b/src/network/tc/tclass.c -@@ -359,7 +359,7 @@ void link_tclass_drop_marked(Link *link) { - } - } - --TClass* tclass_drop(TClass *tclass) { -+static void tclass_drop(TClass *tclass) { - assert(tclass); - - tclass_mark_recursive(tclass); -@@ -367,8 +367,6 @@ TClass* tclass_drop(TClass *tclass) { - /* link_tclass_drop_marked() may invalidate tclass, so run link_qdisc_drop_marked() first. */ - link_qdisc_drop_marked(tclass->link); - link_tclass_drop_marked(tclass->link); -- -- return NULL; - } - - static int tclass_handler(sd_netlink *rtnl, sd_netlink_message *m, Request *req, Link *link, TClass *tclass) { -@@ -584,7 +582,7 @@ int manager_rtnl_process_tclass(sd_netlink *rtnl, sd_netlink_message *message, M - - case RTM_DELTCLASS: - if (tclass) -- (void) tclass_drop(tclass); -+ tclass_drop(tclass); - else - log_tclass_debug(tmp, link, "Kernel removed unknown"); - -diff --git a/src/network/tc/tclass.h b/src/network/tc/tclass.h -index 44f71814501dc..ce51b2499ecc8 100644 ---- a/src/network/tc/tclass.h -+++ b/src/network/tc/tclass.h -@@ -62,7 +62,6 @@ TClass* tclass_unref(TClass *tclass); - int tclass_new_static(TClassKind kind, Network *network, const char *filename, unsigned section_line, TClass **ret); - - void tclass_mark_recursive(TClass *tclass); --TClass* tclass_drop(TClass *tclass); - void link_tclass_drop_marked(Link *link); - - int link_find_tclass(Link *link, uint32_t classid, TClass **ret); - -From 02d55715180e4d2002fe2e1f14f2945e48674a22 Mon Sep 17 00:00:00 2001 -From: Yu Watanabe -Date: Mon, 2 Sep 2024 12:27:04 +0900 -Subject: [PATCH 08/10] network/qdisc: do not save qdisc to Link before it is - configured - -Otherwise, if the same kind of qdisc is already assigned, parameters -configured in .network file will not be used. So, let's first copy the -qdisc and put it on Request, then on success generate a new copy based -on the netlink notification and store it to Link. - -This is the same as 0a0c2672dbd22dc85d660e5baa7e1bef701beb88, -65f5f581568448d6098358b704cae10a656d09f0, and friends, but for qdisc. - -Preparation for fixing #31226. - -(cherry picked from commit 0a35458f5eff59225aaa53734e6194f3e548ba03) ---- - src/network/tc/qdisc.c | 115 ++++++++++++++++++++++------------------- - src/network/tc/qdisc.h | 2 +- - src/network/tc/tc.c | 2 +- - 3 files changed, 65 insertions(+), 54 deletions(-) - -diff --git a/src/network/tc/qdisc.c b/src/network/tc/qdisc.c -index 851f624c45954..0f89d844f585a 100644 ---- a/src/network/tc/qdisc.c -+++ b/src/network/tc/qdisc.c -@@ -378,11 +378,15 @@ void link_qdisc_drop_marked(Link *link) { - assert(link); - - SET_FOREACH(qdisc, link->qdiscs) { -+ Request *req; -+ - if (!qdisc_is_marked(qdisc)) - continue; - - qdisc_unmark(qdisc); - qdisc_enter_removed(qdisc); -+ if (qdisc_get_request(link, qdisc, &req) >= 0) -+ qdisc_enter_removed(req->userdata); - - if (qdisc->state == 0) { - log_qdisc_debug(qdisc, link, "Forgetting"); -@@ -483,6 +487,7 @@ static bool qdisc_is_ready_to_configure(QDisc *qdisc, Link *link) { - } - - static int qdisc_process_request(Request *req, Link *link, QDisc *qdisc) { -+ QDisc *existing; - int r; - - assert(req); -@@ -497,54 +502,56 @@ static int qdisc_process_request(Request *req, Link *link, QDisc *qdisc) { - return log_link_warning_errno(link, r, "Failed to configure QDisc: %m"); - - qdisc_enter_configuring(qdisc); -+ if (qdisc_get(link, qdisc, &existing) >= 0) -+ qdisc_enter_configuring(existing); -+ - return 1; - } - --int link_request_qdisc(Link *link, QDisc *qdisc) { -- QDisc *existing; -+int link_request_qdisc(Link *link, const QDisc *qdisc) { -+ _cleanup_(qdisc_unrefp) QDisc *tmp = NULL; -+ QDisc *existing = NULL; - int r; - - assert(link); - assert(qdisc); -+ assert(qdisc->source != NETWORK_CONFIG_SOURCE_FOREIGN); - - if (qdisc_get_request(link, qdisc, NULL) >= 0) - return 0; /* already requested, skipping. */ - -- if (qdisc_get(link, qdisc, &existing) < 0) { -- _cleanup_(qdisc_unrefp) QDisc *tmp = NULL; -- -- r = qdisc_dup(qdisc, &tmp); -- if (r < 0) -- return log_oom(); -- -- r = qdisc_attach(link, tmp); -- if (r < 0) -- return log_link_warning_errno(link, r, "Failed to store QDisc: %m"); -+ r = qdisc_dup(qdisc, &tmp); -+ if (r < 0) -+ return r; - -- existing = tmp; -- } else -- existing->source = qdisc->source; -+ if (qdisc_get(link, qdisc, &existing) >= 0) -+ /* Copy state for logging below. */ -+ tmp->state = existing->state; - -- log_qdisc_debug(existing, link, "Requesting"); -+ log_qdisc_debug(tmp, link, "Requesting"); - r = link_queue_request_safe(link, REQUEST_TYPE_TC_QDISC, -- existing, NULL, -+ tmp, -+ qdisc_unref, - qdisc_hash_func, - qdisc_compare_func, - qdisc_process_request, - &link->tc_messages, - qdisc_handler, - NULL); -- if (r < 0) -- return log_link_warning_errno(link, r, "Failed to request QDisc: %m"); -- if (r == 0) -- return 0; -+ if (r <= 0) -+ return r; - -- qdisc_enter_requesting(existing); -+ qdisc_enter_requesting(tmp); -+ if (existing) -+ qdisc_enter_requesting(existing); -+ -+ TAKE_PTR(tmp); - return 1; - } - - int manager_rtnl_process_qdisc(sd_netlink *rtnl, sd_netlink_message *message, Manager *m) { - _cleanup_(qdisc_unrefp) QDisc *tmp = NULL; -+ Request *req = NULL; - QDisc *qdisc = NULL; - Link *link; - uint16_t type; -@@ -609,45 +616,49 @@ int manager_rtnl_process_qdisc(sd_netlink *rtnl, sd_netlink_message *message, Ma - } - - (void) qdisc_get(link, tmp, &qdisc); -+ (void) qdisc_get_request(link, tmp, &req); - -- switch (type) { -- case RTM_NEWQDISC: -- if (qdisc) { -- qdisc_enter_configured(qdisc); -- log_qdisc_debug(qdisc, link, "Received remembered"); -- } else { -- qdisc_enter_configured(tmp); -- log_qdisc_debug(tmp, link, "Received new"); -+ if (type == RTM_DELQDISC) { -+ if (qdisc) -+ qdisc_drop(qdisc); -+ else -+ log_qdisc_debug(tmp, link, "Kernel removed unknown"); - -- r = qdisc_attach(link, tmp); -- if (r < 0) { -- log_link_warning_errno(link, r, "Failed to remember QDisc, ignoring: %m"); -- return 0; -- } -+ return 0; -+ } - -- qdisc = tmp; -+ bool is_new = false; -+ if (!qdisc) { -+ /* If we did not know the qdisc, then save it. */ -+ r = qdisc_attach(link, tmp); -+ if (r < 0) { -+ log_link_warning_errno(link, r, "Failed to remember QDisc, ignoring: %m"); -+ return 0; - } - -- if (!m->enumerating) { -- /* Some kind of QDisc (e.g. tbf) also create an implicit class under the qdisc, but -- * the kernel may not notify about the class. Hence, we need to enumerate classes. */ -- r = link_enumerate_tclass(link, qdisc->handle); -- if (r < 0) -- log_link_warning_errno(link, r, "Failed to enumerate TClass, ignoring: %m"); -- } -+ qdisc = tmp; -+ is_new = true; -+ } - -- break; -+ /* Also update information that cannot be obtained through netlink notification. */ -+ if (req && req->waiting_reply) { -+ QDisc *q = ASSERT_PTR(req->userdata); - -- case RTM_DELQDISC: -- if (qdisc) -- qdisc_drop(qdisc); -- else -- log_qdisc_debug(tmp, link, "Kernel removed unknown"); -+ qdisc->source = q->source; -+ } - -- break; -+ qdisc_enter_configured(qdisc); -+ if (req) -+ qdisc_enter_configured(req->userdata); - -- default: -- assert_not_reached(); -+ log_qdisc_debug(qdisc, link, is_new ? "Remembering" : "Received remembered"); -+ -+ if (!m->enumerating) { -+ /* Some kind of QDisc (e.g. tbf) also create an implicit class under the qdisc, but -+ * the kernel may not notify about the class. Hence, we need to enumerate classes. */ -+ r = link_enumerate_tclass(link, qdisc->handle); -+ if (r < 0) -+ log_link_warning_errno(link, r, "Failed to enumerate TClass, ignoring: %m"); - } - - return 1; -diff --git a/src/network/tc/qdisc.h b/src/network/tc/qdisc.h -index 75351fb8ada1f..50a8f4ead1951 100644 ---- a/src/network/tc/qdisc.h -+++ b/src/network/tc/qdisc.h -@@ -85,7 +85,7 @@ void link_qdisc_drop_marked(Link *link); - - int link_find_qdisc(Link *link, uint32_t handle, const char *kind, QDisc **qdisc); - --int link_request_qdisc(Link *link, QDisc *qdisc); -+int link_request_qdisc(Link *link, const QDisc *qdisc); - - void network_drop_invalid_qdisc(Network *network); - -diff --git a/src/network/tc/tc.c b/src/network/tc/tc.c -index 8a1c5b3a3b3a1..37e30441e163f 100644 ---- a/src/network/tc/tc.c -+++ b/src/network/tc/tc.c -@@ -20,7 +20,7 @@ int link_request_traffic_control(Link *link) { - HASHMAP_FOREACH(qdisc, link->network->qdiscs_by_section) { - r = link_request_qdisc(link, qdisc); - if (r < 0) -- return r; -+ return log_link_warning_errno(link, r, "Failed to request QDisc: %m"); - } - - HASHMAP_FOREACH(tclass, link->network->tclasses_by_section) { - -From ae6eaa526e47e520da69ad98b74bde43e7fe914f Mon Sep 17 00:00:00 2001 -From: Yu Watanabe -Date: Mon, 2 Sep 2024 13:15:49 +0900 -Subject: [PATCH 09/10] network/tclass: do not save tclass to Link before it is - configured - -Otherwise, if the same kind of tclass is already assigned, parameters -configured in .network file will not be used. So, let's first copy the -tclass and put it on Request, then on success generate a new copy based -on the netlink notification and store it to Link. - -This is the same as 0a0c2672dbd22dc85d660e5baa7e1bef701beb88, -65f5f581568448d6098358b704cae10a656d09f0, and friends, but for tclass. - -(cherry picked from commit 304e2419c79778bf8811fbb5ec672a8c1197dbb3) ---- - src/network/tc/tc.c | 2 +- - src/network/tc/tclass.c | 102 ++++++++++++++++++++++------------------ - src/network/tc/tclass.h | 2 +- - 3 files changed, 58 insertions(+), 48 deletions(-) - -diff --git a/src/network/tc/tc.c b/src/network/tc/tc.c -index 37e30441e163f..4679e86ac9789 100644 ---- a/src/network/tc/tc.c -+++ b/src/network/tc/tc.c -@@ -26,7 +26,7 @@ int link_request_traffic_control(Link *link) { - HASHMAP_FOREACH(tclass, link->network->tclasses_by_section) { - r = link_request_tclass(link, tclass); - if (r < 0) -- return r; -+ return log_link_warning_errno(link, r, "Failed to request TClass: %m"); - } - - if (link->tc_messages == 0) { -diff --git a/src/network/tc/tclass.c b/src/network/tc/tclass.c -index 3c74f95992ce2..684f917c50562 100644 ---- a/src/network/tc/tclass.c -+++ b/src/network/tc/tclass.c -@@ -345,11 +345,15 @@ void link_tclass_drop_marked(Link *link) { - assert(link); - - SET_FOREACH(tclass, link->tclasses) { -+ Request *req; -+ - if (!tclass_is_marked(tclass)) - continue; - - tclass_unmark(tclass); - tclass_enter_removed(tclass); -+ if (tclass_get_request(link, tclass, &req) >= 0) -+ tclass_enter_removed(req->userdata); - - if (tclass->state == 0) { - log_tclass_debug(tclass, link, "Forgetting"); -@@ -433,6 +437,7 @@ static bool tclass_is_ready_to_configure(TClass *tclass, Link *link) { - } - - static int tclass_process_request(Request *req, Link *link, TClass *tclass) { -+ TClass *existing; - int r; - - assert(req); -@@ -447,54 +452,56 @@ static int tclass_process_request(Request *req, Link *link, TClass *tclass) { - return log_link_warning_errno(link, r, "Failed to configure TClass: %m"); - - tclass_enter_configuring(tclass); -+ if (tclass_get(link, tclass, &existing) >= 0) -+ tclass_enter_configuring(existing); -+ - return 1; - } - --int link_request_tclass(Link *link, TClass *tclass) { -- TClass *existing; -+int link_request_tclass(Link *link, const TClass *tclass) { -+ _cleanup_(tclass_unrefp) TClass *tmp = NULL; -+ TClass *existing = NULL; - int r; - - assert(link); - assert(tclass); -+ assert(tclass->source != NETWORK_CONFIG_SOURCE_FOREIGN); - - if (tclass_get_request(link, tclass, NULL) >= 0) - return 0; /* already requested, skipping. */ - -- if (tclass_get(link, tclass, &existing) < 0) { -- _cleanup_(tclass_unrefp) TClass *tmp = NULL; -- -- r = tclass_dup(tclass, &tmp); -- if (r < 0) -- return log_oom(); -- -- r = tclass_attach(link, tmp); -- if (r < 0) -- return log_link_warning_errno(link, r, "Failed to store TClass: %m"); -+ r = tclass_dup(tclass, &tmp); -+ if (r < 0) -+ return r; - -- existing = tmp; -- } else -- existing->source = tclass->source; -+ if (tclass_get(link, tclass, &existing) >= 0) -+ /* Copy state for logging below. */ -+ tmp->state = existing->state; - -- log_tclass_debug(existing, link, "Requesting"); -+ log_tclass_debug(tmp, link, "Requesting"); - r = link_queue_request_safe(link, REQUEST_TYPE_TC_CLASS, -- existing, NULL, -+ tmp, -+ tclass_unref, - tclass_hash_func, - tclass_compare_func, - tclass_process_request, - &link->tc_messages, - tclass_handler, - NULL); -- if (r < 0) -- return log_link_warning_errno(link, r, "Failed to request TClass: %m"); -- if (r == 0) -- return 0; -+ if (r <= 0) -+ return r; - -- tclass_enter_requesting(existing); -+ tclass_enter_requesting(tmp); -+ if (existing) -+ tclass_enter_requesting(existing); -+ -+ TAKE_PTR(tmp); - return 1; - } - - int manager_rtnl_process_tclass(sd_netlink *rtnl, sd_netlink_message *message, Manager *m) { - _cleanup_(tclass_unrefp) TClass *tmp = NULL; -+ Request *req = NULL; - TClass *tclass = NULL; - Link *link; - uint16_t type; -@@ -559,39 +566,42 @@ int manager_rtnl_process_tclass(sd_netlink *rtnl, sd_netlink_message *message, M - } - - (void) tclass_get(link, tmp, &tclass); -+ (void) tclass_get_request(link, tmp, &req); - -- switch (type) { -- case RTM_NEWTCLASS: -- if (tclass) { -- tclass_enter_configured(tclass); -- log_tclass_debug(tclass, link, "Received remembered"); -- } else { -- tclass_enter_configured(tmp); -- log_tclass_debug(tmp, link, "Received new"); -- -- r = tclass_attach(link, tmp); -- if (r < 0) { -- log_link_warning_errno(link, r, "Failed to remember TClass, ignoring: %m"); -- return 0; -- } -- -- tclass = tmp; -- } -- -- break; -- -- case RTM_DELTCLASS: -+ if (type == RTM_DELTCLASS) { - if (tclass) - tclass_drop(tclass); - else - log_tclass_debug(tmp, link, "Kernel removed unknown"); - -- break; -+ return 0; -+ } - -- default: -- assert_not_reached(); -+ bool is_new = false; -+ if (!tclass) { -+ /* If we did not know the tclass, then save it. */ -+ r = tclass_attach(link, tmp); -+ if (r < 0) { -+ log_link_warning_errno(link, r, "Failed to remember TClass, ignoring: %m"); -+ return 0; -+ } -+ -+ tclass = tmp; -+ is_new = true; - } - -+ /* Also update information that cannot be obtained through netlink notification. */ -+ if (req && req->waiting_reply) { -+ TClass *t = ASSERT_PTR(req->userdata); -+ -+ tclass->source = t->source; -+ } -+ -+ tclass_enter_configured(tclass); -+ if (req) -+ tclass_enter_configured(req->userdata); -+ -+ log_tclass_debug(tclass, link, is_new ? "Remembering" : "Received remembered"); - return 1; - } - -diff --git a/src/network/tc/tclass.h b/src/network/tc/tclass.h -index ce51b2499ecc8..31374d6da8dcc 100644 ---- a/src/network/tc/tclass.h -+++ b/src/network/tc/tclass.h -@@ -66,7 +66,7 @@ void link_tclass_drop_marked(Link *link); - - int link_find_tclass(Link *link, uint32_t classid, TClass **ret); - --int link_request_tclass(Link *link, TClass *tclass); -+int link_request_tclass(Link *link, const TClass *tclass); - - void network_drop_invalid_tclass(Network *network); - - -From 91823bc0cdb41df6e8b66e58ae5cecee2f83b4d4 Mon Sep 17 00:00:00 2001 -From: Daan De Meyer -Date: Thu, 1 Aug 2024 14:38:05 +0200 -Subject: [PATCH 10/10] networkd: Replace existing objects instead of doing - nothing if they exist - -Currently, if for example a traffic control object already exist, networkd -will silently do nothing, even if the settings in the network file for the -traffic control object have changed. Let's instead replace the object if it -already exists so that new settings from the network file are applied as -expected. - -Fixes #31226 - -(cherry picked from commit 21d9eeb5e6177544b32a5e25c355373573a3ccee) ---- - src/libsystemd/sd-netlink/netlink-message-rtnl.c | 6 +++--- - test/test-network/systemd-networkd-tests.py | 11 +++++++++++ - 2 files changed, 14 insertions(+), 3 deletions(-) - -diff --git a/src/libsystemd/sd-netlink/netlink-message-rtnl.c b/src/libsystemd/sd-netlink/netlink-message-rtnl.c -index fb11c7e02bb28..9184c43fecced 100644 ---- a/src/libsystemd/sd-netlink/netlink-message-rtnl.c -+++ b/src/libsystemd/sd-netlink/netlink-message-rtnl.c -@@ -892,7 +892,7 @@ int sd_rtnl_message_new_addrlabel( - return r; - - if (nlmsg_type == RTM_NEWADDRLABEL) -- (*ret)->hdr->nlmsg_flags |= NLM_F_CREATE | NLM_F_EXCL; -+ (*ret)->hdr->nlmsg_flags |= NLM_F_CREATE | NLM_F_REPLACE; - - addrlabel = NLMSG_DATA((*ret)->hdr); - -@@ -1143,7 +1143,7 @@ int sd_rtnl_message_new_traffic_control( - return r; - - if (IN_SET(nlmsg_type, RTM_NEWQDISC, RTM_NEWTCLASS)) -- (*ret)->hdr->nlmsg_flags |= NLM_F_CREATE | NLM_F_EXCL; -+ (*ret)->hdr->nlmsg_flags |= NLM_F_CREATE | NLM_F_REPLACE; - - tcm = NLMSG_DATA((*ret)->hdr); - tcm->tcm_ifindex = ifindex; -@@ -1212,7 +1212,7 @@ int sd_rtnl_message_new_mdb( - return r; - - if (nlmsg_type == RTM_NEWMDB) -- (*ret)->hdr->nlmsg_flags |= NLM_F_CREATE | NLM_F_EXCL; -+ (*ret)->hdr->nlmsg_flags |= NLM_F_CREATE | NLM_F_REPLACE; - - bpm = NLMSG_DATA((*ret)->hdr); - bpm->family = AF_BRIDGE; -diff --git a/test/test-network/systemd-networkd-tests.py b/test/test-network/systemd-networkd-tests.py -index ba8e65ee90bfc..83a98c2902104 100755 ---- a/test/test-network/systemd-networkd-tests.py -+++ b/test/test-network/systemd-networkd-tests.py -@@ -4424,6 +4424,17 @@ def test_qdisc_cake(self): - self.assertIn('rtt 1s', output) - self.assertIn('ack-filter-aggressive', output) - -+ # Test for replacing existing qdisc. See #31226. -+ with open(os.path.join(network_unit_dir, '25-qdisc-cake.network'), mode='a', encoding='utf-8') as f: -+ f.write('Bandwidth=250M\n') -+ -+ networkctl_reload() -+ self.wait_online('dummy98:routable') -+ -+ output = check_output('tc qdisc show dev dummy98') -+ print(output) -+ self.assertIn('bandwidth 250Mbit', output) -+ - @expectedFailureIfModuleIsNotAvailable('sch_codel') - def test_qdisc_codel(self): - copy_network_unit('25-qdisc-codel.network', '12-dummy.netdev') diff --git a/34621.patch b/34621.patch deleted file mode 100644 index e6fe21f..0000000 --- a/34621.patch +++ /dev/null @@ -1,36 +0,0 @@ -From 7759cc92c07c86272bdc91c18e66646920bde0f6 Mon Sep 17 00:00:00 2001 -From: Daan De Meyer -Date: Thu, 3 Oct 2024 10:46:27 +0200 -Subject: [PATCH] nsresourced: Fix declaration of bpf_rdonly_cast() - -Fixes compilation error - -""" -[780/3171] /usr/bin/clang -std=gnu11 -Wno-compare-distinct-pointer-types -fno-stack-protector -O2 -target bpf -g -c -D__aarch64__ -I. -isystem /usr/include/ -idirafter /usr/include ../src/nsresourced/bpf/userns_restrict/userns-restrict.bpf.c -o src/nsresourced/bpf/userns_restrict/userns-restrict.bpf.unstripped.o -I/usr/src/kernels/6.11.1-0.hs1.hs+fb.el9.aarch64 -FAILED: src/nsresourced/bpf/userns_restrict/userns-restrict.bpf.unstripped.o -/usr/bin/clang -std=gnu11 -Wno-compare-distinct-pointer-types -fno-stack-protector -O2 -target bpf -g -c -D__aarch64__ -I. -isystem /usr/include/ -idirafter /usr/include ../src/nsresourced/bpf/userns_restrict/userns-restrict.bpf.c -o src/nsresourced/bpf/userns_restrict/userns-restrict.bpf.unstripped.o -I/usr/src/kernels/6.11.1-0.hs1.hs+fb.el9.aarch64 -../src/nsresourced/bpf/userns_restrict/userns-restrict.bpf.c:27:7: error: conflicting types for 'bpf_rdonly_cast' - 27 | void *bpf_rdonly_cast(void *, __u32) __ksym; - | ^ -/usr/src/kernels/6.11.1-0.hs1.hs+fb.el9.aarch64/vmlinux.h:143063:14: note: previous declaration is here - 143063 | extern void *bpf_rdonly_cast(const void *obj__ign, u32 btf_id__k) __weak __ksym; - | ^ -1 error generated. -""" ---- - src/nsresourced/bpf/userns_restrict/userns-restrict.bpf.c | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - -diff --git a/src/nsresourced/bpf/userns_restrict/userns-restrict.bpf.c b/src/nsresourced/bpf/userns_restrict/userns-restrict.bpf.c -index 126422bb69cc1..0ff41a138bee9 100644 ---- a/src/nsresourced/bpf/userns_restrict/userns-restrict.bpf.c -+++ b/src/nsresourced/bpf/userns_restrict/userns-restrict.bpf.c -@@ -24,7 +24,7 @@ - /* bpf_rdonly_cast() was introduced in libbpf commit 688879f together with - * the definition of a bpf_core_cast macro. So use that one to avoid - * defining a prototype for bpf_rdonly_cast */ --void *bpf_rdonly_cast(void *, __u32) __ksym; -+void* bpf_rdonly_cast(const void *, __u32) __ksym; - #endif - - /* BPF module that implements an allowlist of mounts (identified by mount ID) for user namespaces (identified diff --git a/34686.patch b/34686.patch deleted file mode 100644 index 21c46f4..0000000 --- a/34686.patch +++ /dev/null @@ -1,255 +0,0 @@ -From 0d0ecaab000cf2768a3edf1e73119bf2fce952b0 Mon Sep 17 00:00:00 2001 -From: Daan De Meyer -Date: Wed, 9 Oct 2024 14:49:07 +0200 -Subject: [PATCH 1/6] mkosi: Fix up ownership of testuser home directory on - first boot - -When building unprivileged, the testuser home directory ends up -owned by root:root because mkosi can't chown directories to other -owners when running unprivileged. So let's fix up the testuser -ownership on first boot with tmpfiles instead. ---- - mkosi.extra/usr/lib/tmpfiles.d/testuser.conf | 3 +++ - 1 file changed, 3 insertions(+) - create mode 100644 mkosi.extra/usr/lib/tmpfiles.d/testuser.conf - -diff --git a/mkosi.extra/usr/lib/tmpfiles.d/testuser.conf b/mkosi.extra/usr/lib/tmpfiles.d/testuser.conf -new file mode 100644 -index 0000000000000..7113177f4deba ---- /dev/null -+++ b/mkosi.extra/usr/lib/tmpfiles.d/testuser.conf -@@ -0,0 +1,3 @@ -+# SPDX-License-Identifier: LGPL-2.1-or-later -+ -+z! /home/testuser 700 testuser testuser - -From ec9fd0d4f5f77404fbfabde9e7a9d01aaa1356ff Mon Sep 17 00:00:00 2001 -From: Daan De Meyer -Date: Wed, 9 Oct 2024 16:37:06 +0200 -Subject: [PATCH 2/6] update-utmp: Make reconnect logic more robust - -We might also fail to connect to the private manager bus itself if -the daemon-reexec is still ongoing, so let's handle that as well by -retrying on ECONNREFUSED. ---- - src/update-utmp/update-utmp.c | 45 +++++++++++++++++++---------------- - 1 file changed, 25 insertions(+), 20 deletions(-) - -diff --git a/src/update-utmp/update-utmp.c b/src/update-utmp/update-utmp.c -index c376676e8d0a5..7a8a53f7e8ec5 100644 ---- a/src/update-utmp/update-utmp.c -+++ b/src/update-utmp/update-utmp.c -@@ -82,6 +82,25 @@ static int get_current_runlevel(Context *c) { - assert(c); - - for (unsigned n_attempts = 0;;) { -+ if (n_attempts++ > 0) { -+ /* systemd might have dropped off momentarily, let's not make this an error, -+ * and wait some random time. Let's pick a random time in the range 0ms…250ms, -+ * linearly scaled by the number of failed attempts. */ -+ c->bus = sd_bus_flush_close_unref(c->bus); -+ -+ usec_t usec = random_u64_range(UINT64_C(10) * USEC_PER_MSEC + -+ UINT64_C(240) * USEC_PER_MSEC * n_attempts/64); -+ (void) usleep_safe(usec); -+ -+ r = bus_connect_system_systemd(&c->bus); -+ if (r == -ECONNREFUSED && n_attempts < 64) { -+ log_debug_errno(r, "Failed to reconnect to system bus, retrying after a slight delay: %m"); -+ continue; -+ } -+ if (r < 0) -+ return log_error_errno(r, "Failed to reconnect to system bus: %m"); -+ } -+ - FOREACH_ELEMENT(e, table) { - _cleanup_(sd_bus_error_free) sd_bus_error error = SD_BUS_ERROR_NULL; - _cleanup_free_ char *state = NULL, *path = NULL; -@@ -102,18 +121,10 @@ static int get_current_runlevel(Context *c) { - sd_bus_error_has_names(&error, - SD_BUS_ERROR_NO_REPLY, - SD_BUS_ERROR_DISCONNECTED)) && -- ++n_attempts < 64) { -- -- /* systemd might have dropped off momentarily, let's not make this an error, -- * and wait some random time. Let's pick a random time in the range 0ms…250ms, -- * linearly scaled by the number of failed attempts. */ -- -- usec_t usec = random_u64_range(UINT64_C(10) * USEC_PER_MSEC + -- UINT64_C(240) * USEC_PER_MSEC * n_attempts/64); -- log_debug_errno(r, "Failed to get state of %s, retrying after %s: %s", -- e->special, FORMAT_TIMESPAN(usec, USEC_PER_MSEC), bus_error_message(&error, r)); -- (void) usleep_safe(usec); -- goto reconnect; -+ n_attempts < 64) { -+ log_debug_errno(r, "Failed to get state of %s, retrying after a slight delay: %s", -+ e->special, bus_error_message(&error, r)); -+ break; - } - if (r < 0) - return log_warning_errno(r, "Failed to get state of %s: %s", e->special, bus_error_message(&error, r)); -@@ -121,14 +132,8 @@ static int get_current_runlevel(Context *c) { - if (STR_IN_SET(state, "active", "reloading")) - return e->runlevel; - } -- -- return 0; -- --reconnect: -- c->bus = sd_bus_flush_close_unref(c->bus); -- r = bus_connect_system_systemd(&c->bus); -- if (r < 0) -- return log_error_errno(r, "Failed to reconnect to system bus: %m"); -+ if (r >= 0) -+ return 0; - } - } - - -From a339495b1d67f69f49ffffdd96002164a28f1c93 Mon Sep 17 00:00:00 2001 -From: Daan De Meyer -Date: Wed, 9 Oct 2024 11:44:34 +0200 -Subject: [PATCH 3/6] bus-util: Drop fallback to system/user bus if manager bus - doesn't work - -We have various callsites that explicitly need the manager bus and -won't work with the system bus, like daemon-reexec and friends which -can't properly wait until the operation has finished unless using the -manager bus. - -If we silently fall back to the system bus for these operations, we -can end up with rather hard to debug issues so let's remove the fallback -as it was added back in 2013 in a6aa89122d2fa5e811a72200773068c13bfffea2 -without a clear explanation of why it was needed (I expect as a fallback -if kdbus wasn't available but that's not a thing anymore these days). ---- - src/shared/bus-util.c | 6 +++--- - 1 file changed, 3 insertions(+), 3 deletions(-) - -diff --git a/src/shared/bus-util.c b/src/shared/bus-util.c -index f4c4eed70702a..44ed617da8dfb 100644 ---- a/src/shared/bus-util.c -+++ b/src/shared/bus-util.c -@@ -245,7 +245,7 @@ int bus_connect_system_systemd(sd_bus **ret_bus) { - - r = sd_bus_start(bus); - if (r < 0) -- return sd_bus_default_system(ret_bus); -+ return r; - - r = bus_check_peercred(bus); - if (r < 0) -@@ -265,7 +265,7 @@ int bus_connect_user_systemd(sd_bus **ret_bus) { - - e = secure_getenv("XDG_RUNTIME_DIR"); - if (!e) -- return sd_bus_default_user(ret_bus); -+ return -ENXIO; - - ee = bus_address_escape(e); - if (!ee) -@@ -281,7 +281,7 @@ int bus_connect_user_systemd(sd_bus **ret_bus) { - - r = sd_bus_start(bus); - if (r < 0) -- return sd_bus_default_user(ret_bus); -+ return r; - - r = bus_check_peercred(bus); - if (r < 0) - -From a178ffdfcd9d25886a6e563a0fbd9929852e85c4 Mon Sep 17 00:00:00 2001 -From: Daan De Meyer -Date: Wed, 9 Oct 2024 12:10:44 +0200 -Subject: [PATCH 4/6] bus-util: Move geteuid() check out of - bus_connect_system_systemd() - -Let's move this check to bus_connect_transport_systemd() so that -bus_connect_system_systemd() will only ever connect to the manager -private manager bus instance and fail otherwise. ---- - src/shared/bus-util.c | 13 ++++++------- - 1 file changed, 6 insertions(+), 7 deletions(-) - -diff --git a/src/shared/bus-util.c b/src/shared/bus-util.c -index 44ed617da8dfb..a196ba47f647c 100644 ---- a/src/shared/bus-util.c -+++ b/src/shared/bus-util.c -@@ -229,12 +229,6 @@ int bus_connect_system_systemd(sd_bus **ret_bus) { - - assert(ret_bus); - -- if (geteuid() != 0) -- return sd_bus_default_system(ret_bus); -- -- /* If we are root then let's talk directly to the system -- * instance, instead of going via the bus */ -- - r = sd_bus_new(&bus); - if (r < 0) - return r; -@@ -521,8 +515,13 @@ int bus_connect_transport_systemd( - /* Print a friendly message when the local system is actually not running systemd as PID 1. */ - return log_error_errno(SYNTHETIC_ERRNO(EHOSTDOWN), - "System has not been booted with systemd as init system (PID 1). Can't operate."); -- return bus_connect_system_systemd(ret_bus); - -+ if (geteuid() == 0) -+ /* If we are root then let's talk directly to the system -+ * instance, instead of going via the bus. */ -+ return bus_connect_system_systemd(ret_bus); -+ -+ return sd_bus_default_system(ret_bus); - default: - assert_not_reached(); - } - -From b066b683539675bc51a71259f1e0f42cef5379ad Mon Sep 17 00:00:00 2001 -From: Daan De Meyer -Date: Thu, 10 Oct 2024 15:54:37 +0200 -Subject: [PATCH 5/6] stdio-bridge: Use bus_log_connect_error() - ---- - src/stdio-bridge/stdio-bridge.c | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - -diff --git a/src/stdio-bridge/stdio-bridge.c b/src/stdio-bridge/stdio-bridge.c -index d3629f5fb0dc5..7b774860c8eb1 100644 ---- a/src/stdio-bridge/stdio-bridge.c -+++ b/src/stdio-bridge/stdio-bridge.c -@@ -142,7 +142,7 @@ static int run(int argc, char *argv[]) { - - r = sd_bus_start(a); - if (r < 0) -- return log_error_errno(r, "Failed to start bus client: %m"); -+ return bus_log_connect_error(r, arg_transport, arg_runtime_scope); - - r = sd_bus_get_bus_id(a, &server_id); - if (r < 0) - -From d94e85c2279ac255a9c964046723684ca99b7f00 Mon Sep 17 00:00:00 2001 -From: Daan De Meyer -Date: Thu, 10 Oct 2024 15:54:57 +0200 -Subject: [PATCH 6/6] stdio-bridge: Use customized log message for forwarding - bus - -Let's more clearly indicate that we failed to set up the server -which forwards messages from the remote client to the local bus -instead of logging a generic bus client message. ---- - src/stdio-bridge/stdio-bridge.c | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - -diff --git a/src/stdio-bridge/stdio-bridge.c b/src/stdio-bridge/stdio-bridge.c -index 7b774860c8eb1..22570511cbabb 100644 ---- a/src/stdio-bridge/stdio-bridge.c -+++ b/src/stdio-bridge/stdio-bridge.c -@@ -170,7 +170,7 @@ static int run(int argc, char *argv[]) { - - r = sd_bus_start(b); - if (r < 0) -- return log_error_errno(r, "Failed to start bus client: %m"); -+ return log_error_errno(r, "Failed to start bus forwarding server: %m"); - - for (;;) { - _cleanup_(sd_bus_message_unrefp) sd_bus_message *m = NULL; diff --git a/34707.patch b/34707.patch deleted file mode 100644 index 5d8e278..0000000 --- a/34707.patch +++ /dev/null @@ -1,233 +0,0 @@ -From da81a108653e2ef19102698dbc0184bd18b084d9 Mon Sep 17 00:00:00 2001 -From: Mike Yuan -Date: Thu, 10 Oct 2024 21:16:05 +0200 -Subject: [PATCH 1/4] core/manager: still send out STATUS=Ready for user - manager - -This effectively reverts 37d15cd132f3a8a0bf42fb252c1604e804171ff2. - -The offending commit wrongly assumed that the second READY=1 -notification is for system scope only, but it also serves the purpose -of flushing out previous STATUS= containing user unit job status. ---- - src/core/manager.c | 14 +++++++------- - 1 file changed, 7 insertions(+), 7 deletions(-) - -diff --git a/src/core/manager.c b/src/core/manager.c -index 2789f0e3d0c9c..456ad46135b72 100644 ---- a/src/core/manager.c -+++ b/src/core/manager.c -@@ -3885,7 +3885,7 @@ static void manager_notify_finished(Manager *m) { - log_taint_string(m); - } - --static void manager_send_ready_user_scope(Manager *m) { -+static void manager_send_ready_on_basic_target(Manager *m) { - int r; - - assert(m); -@@ -3904,18 +3904,18 @@ static void manager_send_ready_user_scope(Manager *m) { - m->status_ready = false; - } - --static void manager_send_ready_system_scope(Manager *m) { -+static void manager_send_ready_on_idle(Manager *m) { - int r; - - assert(m); - -- if (!MANAGER_IS_SYSTEM(m)) -- return; -- - /* Skip the notification if nothing changed. */ - if (m->ready_sent && m->status_ready) - return; - -+ /* Note that for user managers, we might have already sent READY=1 in manager_send_ready_user_scope(). -+ * But we still need to flush STATUS=. The second READY=1 will be treated as a noop so it doesn't -+ * hurt to send it twice. */ - r = sd_notify(/* unset_environment= */ false, - "READY=1\n" - "STATUS=Ready."); -@@ -3940,7 +3940,7 @@ static void manager_check_basic_target(Manager *m) { - return; - - /* For user managers, send out READY=1 as soon as we reach basic.target */ -- manager_send_ready_user_scope(m); -+ manager_send_ready_on_basic_target(m); - - /* Log the taint string as soon as we reach basic.target */ - log_taint_string(m); -@@ -3971,7 +3971,7 @@ void manager_check_finished(Manager *m) { - if (hashmap_buckets(m->jobs) > hashmap_size(m->units) / 10) - m->jobs = hashmap_free(m->jobs); - -- manager_send_ready_system_scope(m); -+ manager_send_ready_on_idle(m); - - /* Notify Type=idle units that we are done now */ - manager_close_idle_pipe(m); - -From 155098a702c4f6de6b1dca534661492625773fed Mon Sep 17 00:00:00 2001 -From: Mike Yuan -Date: Thu, 10 Oct 2024 21:06:35 +0200 -Subject: [PATCH 2/4] core/manager-serialize: drop serialization for - Manager.ready_sent - -This field indicates whether READY=1 has been sent to -the service manager/supervisor. Whenever we reload/reexec/soft-reboot, -manager_send_reloading() always resets it to false first, -so that READY=1 is sent after reloading finishes. Hence -we utterly get "false" at all times. Kill it. ---- - src/core/manager-serialize.c | 12 +----------- - 1 file changed, 1 insertion(+), 11 deletions(-) - -diff --git a/src/core/manager-serialize.c b/src/core/manager-serialize.c -index 62dfce93a0a85..3f624619dfd19 100644 ---- a/src/core/manager-serialize.c -+++ b/src/core/manager-serialize.c -@@ -92,7 +92,6 @@ int manager_serialize( - (void) serialize_item_format(f, "current-job-id", "%" PRIu32, m->current_job_id); - (void) serialize_item_format(f, "n-installed-jobs", "%u", m->n_installed_jobs); - (void) serialize_item_format(f, "n-failed-jobs", "%u", m->n_failed_jobs); -- (void) serialize_bool(f, "ready-sent", m->ready_sent); - (void) serialize_bool(f, "taint-logged", m->taint_logged); - (void) serialize_bool(f, "service-watchdogs", m->service_watchdogs); - -@@ -356,15 +355,6 @@ int manager_deserialize(Manager *m, FILE *f, FDSet *fds) { - else - m->n_failed_jobs += n; - -- } else if ((val = startswith(l, "ready-sent="))) { -- int b; -- -- b = parse_boolean(val); -- if (b < 0) -- log_notice("Failed to parse ready-sent flag '%s', ignoring.", val); -- else -- m->ready_sent = m->ready_sent || b; -- - } else if ((val = startswith(l, "taint-logged="))) { - int b; - -@@ -558,7 +548,7 @@ int manager_deserialize(Manager *m, FILE *f, FDSet *fds) { - - if (q < _MANAGER_TIMESTAMP_MAX) /* found it */ - (void) deserialize_dual_timestamp(val, m->timestamps + q); -- else if (!STARTSWITH_SET(l, "kdbus-fd=", "honor-device-enumeration=")) /* ignore deprecated values */ -+ else if (!STARTSWITH_SET(l, "kdbus-fd=", "honor-device-enumeration=", "ready-sent=")) /* ignore deprecated values */ - log_notice("Unknown serialization item '%s', ignoring.", l); - } - } - -From a375e145190482e8a2f0971bffb332e31211622f Mon Sep 17 00:00:00 2001 -From: Mike Yuan -Date: Thu, 10 Oct 2024 21:32:17 +0200 -Subject: [PATCH 3/4] units/{user,capsule}@.service: issue daemon-reexec when - notify-reloading - -Closes #28367 (but not really in the exact form, see below) - -We have the problem of restarting all user manager instances -after upgrade. Current approaches involve systemctl kill -with SIGRTMIN+25, which is async and feels rather ugly [1][2]; -or systemctl --machine=user@ --user, which requires entering -each user session. Neither is particularly elegant. -Instead, let's just signal daemon-reexec when user@.service -is reloaded from system manager. Our long goal of dropping -daemon-reload in favor of reexec (see TODO) is unlikely to happen -due to user dbus restrictions, but here the synchronization -is done via READY=1. - -[1] https://gitlab.archlinux.org/archlinux/packaging/packages/systemd/-/blob/main/systemd.install?ref_type=heads#L37 -[2] https://salsa.debian.org/systemd-team/systemd/-/blob/debian/master/debian/systemd.postinst#L24 - -#28367 would not really work for us now I come to think about it, -because all processes will be reparented to pid1 as soon as -original user manager process exits. This alternative approach -seems good enough for our use case. ---- - units/capsule@.service.in | 4 ++++ - units/user@.service.in | 4 ++++ - 2 files changed, 8 insertions(+) - -diff --git a/units/capsule@.service.in b/units/capsule@.service.in -index f2bb9e3a45a83..a64298786e490 100644 ---- a/units/capsule@.service.in -+++ b/units/capsule@.service.in -@@ -23,6 +23,10 @@ StateDirectory=capsules/%i - RuntimeDirectory=capsules/%i - LogExtraFields=CAPSULE=%i - Slice=capsule.slice -+# Reexecute the manager on service reload, instead of reloading. -+# This provides a synchronous method for restarting all user manager -+# instances after upgrade. -+ReloadSignal=RTMIN+25 - KillMode=mixed - Delegate=pids memory cpu - DelegateSubgroup=init.scope -diff --git a/units/user@.service.in b/units/user@.service.in -index 5695465747217..381ab2a0db54e 100644 ---- a/units/user@.service.in -+++ b/units/user@.service.in -@@ -20,6 +20,10 @@ PAMName=systemd-user - Type=notify-reload - ExecStart={{LIBEXECDIR}}/systemd --user - Slice=user-%i.slice -+# Reexecute the manager on service reload, instead of reloading. -+# This provides a synchronous method for restarting all user manager -+# instances after upgrade. -+ReloadSignal=RTMIN+25 - KillMode=mixed - Delegate=pids memory cpu - DelegateSubgroup=init.scope - -From 2d0af8bc354f4a1429cebedfb387af72c88720a0 Mon Sep 17 00:00:00 2001 -From: Daan De Meyer -Date: Thu, 10 Oct 2024 22:37:39 +0200 -Subject: [PATCH 4/4] rpm/systemd-update-helper: Use systemctl reload to - reexec/reload user managers - -Let's always use systemctl reload to reexec and reload user managers -now that it always implies a reexec. This moves all the job management -logic to pid 1 instead of bash and reduces the complexity of the logic -as we remove systemd-run, pam and systemd-stdio-bridge from the equation. ---- - src/rpm/systemd-update-helper.in | 20 ++++---------------- - 1 file changed, 4 insertions(+), 16 deletions(-) - -diff --git a/src/rpm/systemd-update-helper.in b/src/rpm/systemd-update-helper.in -index c81e16c3d3ffb..8af914935261a 100755 ---- a/src/rpm/systemd-update-helper.in -+++ b/src/rpm/systemd-update-helper.in -@@ -107,25 +107,13 @@ case "$command" in - - [ -d /run/systemd/system ] || exit 0 - -- users=$(systemctl list-units 'user@*' --legend=no | sed -n -r 's/.*user@([0-9]+).service.*/\1/p') -- -- if [[ "$command" =~ reexec ]]; then -- for user in $users; do -- SYSTEMD_BUS_TIMEOUT={{UPDATE_HELPER_USER_TIMEOUT_SEC}}s \ -- systemctl --user -M "$user@" daemon-reexec & -- done -- wait -- fi -- -- if [[ "$command" =~ reload ]]; then -- for user in $users; do -- SYSTEMD_BUS_TIMEOUT={{UPDATE_HELPER_USER_TIMEOUT_SEC}}s \ -- systemctl --user -M "$user@" daemon-reload & -- done -- wait -+ if [[ "$command" =~ reexec|reload ]]; then -+ SYSTEMD_BUS_TIMEOUT={{UPDATE_HELPER_USER_TIMEOUT_SEC}}s systemctl reload "user@*.service" - fi - - if [[ "$command" =~ restart ]]; then -+ users=$(systemctl list-units 'user@*' --legend=no | sed -n -r 's/.*user@([0-9]+).service.*/\1/p') -+ - for user in $users; do - SYSTEMD_BUS_TIMEOUT={{UPDATE_HELPER_USER_TIMEOUT_SEC}}s \ - systemctl --user -M "$user@" reload-or-restart --marked & diff --git a/34728.patch b/34728.patch deleted file mode 100644 index 158fee3..0000000 --- a/34728.patch +++ /dev/null @@ -1,580 +0,0 @@ -From 871ee2f08715f8fae441786db04ba8497822f79a Mon Sep 17 00:00:00 2001 -From: Daan De Meyer -Date: Tue, 8 Oct 2024 16:22:58 +0200 -Subject: [PATCH 1/3] bus-util: Log more information when connecting to a bus - socket fails - -Let's log about which bus we're trying to connect to and what transport -we're using to do it. - -(cherry picked from commit d8a77d55e6ad7f251ae0eb6758af6bba111095df) ---- - src/analyze/analyze-blame.c | 2 +- - src/analyze/analyze-critical-chain.c | 2 +- - src/analyze/analyze-dot.c | 2 +- - src/analyze/analyze-dump.c | 2 +- - src/analyze/analyze-fdstore.c | 2 +- - src/analyze/analyze-log-control.c | 2 +- - src/analyze/analyze-malloc.c | 2 +- - src/analyze/analyze-plot.c | 2 +- - src/analyze/analyze-security.c | 2 +- - src/analyze/analyze-service-watchdogs.c | 2 +- - src/analyze/analyze-time.c | 2 +- - src/busctl/busctl.c | 2 +- - src/cgls/cgls.c | 9 ++++----- - src/firstboot/firstboot.c | 4 ++-- - src/home/homectl.c | 2 +- - src/hostname/hostnamectl.c | 2 +- - src/import/importctl.c | 2 +- - src/locale/localectl.c | 2 +- - src/login/inhibit.c | 2 +- - src/login/loginctl.c | 2 +- - src/machine/machinectl.c | 2 +- - src/mount/mount-tool.c | 2 +- - src/portable/portablectl.c | 2 +- - src/run/run.c | 2 +- - src/shared/bus-util.c | 18 ++++++++++++++---- - src/shared/bus-util.h | 4 +++- - src/shared/cgroup-show.c | 2 +- - src/systemctl/systemctl-util.c | 2 +- - src/timedate/timedatectl.c | 2 +- - 29 files changed, 48 insertions(+), 37 deletions(-) - -diff --git a/src/analyze/analyze-blame.c b/src/analyze/analyze-blame.c -index 81e5c590b9cc2..4d78ed405d7d4 100644 ---- a/src/analyze/analyze-blame.c -+++ b/src/analyze/analyze-blame.c -@@ -14,7 +14,7 @@ int verb_blame(int argc, char *argv[], void *userdata) { - - r = acquire_bus(&bus, NULL); - if (r < 0) -- return bus_log_connect_error(r, arg_transport); -+ return bus_log_connect_error(r, arg_transport, arg_runtime_scope); - - n = acquire_time_data(bus, /* require_finished = */ false, ×); - if (n <= 0) -diff --git a/src/analyze/analyze-critical-chain.c b/src/analyze/analyze-critical-chain.c -index 7d78de3d388d1..03c014d4023e6 100644 ---- a/src/analyze/analyze-critical-chain.c -+++ b/src/analyze/analyze-critical-chain.c -@@ -200,7 +200,7 @@ int verb_critical_chain(int argc, char *argv[], void *userdata) { - - r = acquire_bus(&bus, NULL); - if (r < 0) -- return bus_log_connect_error(r, arg_transport); -+ return bus_log_connect_error(r, arg_transport, arg_runtime_scope); - - n = acquire_time_data(bus, /* require_finished = */ true, ×); - if (n <= 0) -diff --git a/src/analyze/analyze-dot.c b/src/analyze/analyze-dot.c -index 9e92d59bceeee..b93bf4a9a5bb0 100644 ---- a/src/analyze/analyze-dot.c -+++ b/src/analyze/analyze-dot.c -@@ -149,7 +149,7 @@ int verb_dot(int argc, char *argv[], void *userdata) { - - r = acquire_bus(&bus, NULL); - if (r < 0) -- return bus_log_connect_error(r, arg_transport); -+ return bus_log_connect_error(r, arg_transport, arg_runtime_scope); - - r = expand_patterns(bus, strv_skip(argv, 1), &expanded_patterns); - if (r < 0) -diff --git a/src/analyze/analyze-dump.c b/src/analyze/analyze-dump.c -index 2642582903b09..4ee547ed4c969 100644 ---- a/src/analyze/analyze-dump.c -+++ b/src/analyze/analyze-dump.c -@@ -123,7 +123,7 @@ int verb_dump(int argc, char *argv[], void *userdata) { - - r = acquire_bus(&bus, NULL); - if (r < 0) -- return bus_log_connect_error(r, arg_transport); -+ return bus_log_connect_error(r, arg_transport, arg_runtime_scope); - - pager_open(arg_pager_flags); - -diff --git a/src/analyze/analyze-fdstore.c b/src/analyze/analyze-fdstore.c -index 8ada6d4e73e1f..1f4adb7089ab0 100644 ---- a/src/analyze/analyze-fdstore.c -+++ b/src/analyze/analyze-fdstore.c -@@ -98,7 +98,7 @@ int verb_fdstore(int argc, char *argv[], void *userdata) { - - r = acquire_bus(&bus, NULL); - if (r < 0) -- return bus_log_connect_error(r, arg_transport); -+ return bus_log_connect_error(r, arg_transport, arg_runtime_scope); - - STRV_FOREACH(arg, strv_skip(argv, 1)) { - r = dump_fdstore(bus, *arg); -diff --git a/src/analyze/analyze-log-control.c b/src/analyze/analyze-log-control.c -index cead0e833f5da..854cf6cb806c2 100644 ---- a/src/analyze/analyze-log-control.c -+++ b/src/analyze/analyze-log-control.c -@@ -12,7 +12,7 @@ int verb_log_control(int argc, char *argv[], void *userdata) { - - r = acquire_bus(&bus, NULL); - if (r < 0) -- return bus_log_connect_error(r, arg_transport); -+ return bus_log_connect_error(r, arg_transport, arg_runtime_scope); - - r = verb_log_control_common(bus, "org.freedesktop.systemd1", argv[0], argc == 2 ? argv[1] : NULL); - if (r < 0) -diff --git a/src/analyze/analyze-malloc.c b/src/analyze/analyze-malloc.c -index 5e6ff5bb9627c..514526d14256a 100644 ---- a/src/analyze/analyze-malloc.c -+++ b/src/analyze/analyze-malloc.c -@@ -43,7 +43,7 @@ int verb_malloc(int argc, char *argv[], void *userdata) { - - r = acquire_bus(&bus, NULL); - if (r < 0) -- return bus_log_connect_error(r, arg_transport); -+ return bus_log_connect_error(r, arg_transport, arg_runtime_scope); - - r = sd_bus_can_send(bus, SD_BUS_TYPE_UNIX_FD); - if (r < 0) -diff --git a/src/analyze/analyze-plot.c b/src/analyze/analyze-plot.c -index e271296b6875b..ce67c092c37cd 100644 ---- a/src/analyze/analyze-plot.c -+++ b/src/analyze/analyze-plot.c -@@ -468,7 +468,7 @@ int verb_plot(int argc, char *argv[], void *userdata) { - - r = acquire_bus(&bus, &use_full_bus); - if (r < 0) -- return bus_log_connect_error(r, arg_transport); -+ return bus_log_connect_error(r, arg_transport, arg_runtime_scope); - - n = acquire_boot_times(bus, /* require_finished = */ true, &boot); - if (n < 0) -diff --git a/src/analyze/analyze-security.c b/src/analyze/analyze-security.c -index 3d7b647a6f361..d3ba975107297 100644 ---- a/src/analyze/analyze-security.c -+++ b/src/analyze/analyze-security.c -@@ -2904,7 +2904,7 @@ int verb_security(int argc, char *argv[], void *userdata) { - if (!arg_offline) { - r = acquire_bus(&bus, NULL); - if (r < 0) -- return bus_log_connect_error(r, arg_transport); -+ return bus_log_connect_error(r, arg_transport, arg_runtime_scope); - } - - pager_open(arg_pager_flags); -diff --git a/src/analyze/analyze-service-watchdogs.c b/src/analyze/analyze-service-watchdogs.c -index 6535eb1a894f7..b1fad4328caa5 100644 ---- a/src/analyze/analyze-service-watchdogs.c -+++ b/src/analyze/analyze-service-watchdogs.c -@@ -16,7 +16,7 @@ int verb_service_watchdogs(int argc, char *argv[], void *userdata) { - - r = acquire_bus(&bus, NULL); - if (r < 0) -- return bus_log_connect_error(r, arg_transport); -+ return bus_log_connect_error(r, arg_transport, arg_runtime_scope); - - if (argc == 1) { - /* get ServiceWatchdogs */ -diff --git a/src/analyze/analyze-time.c b/src/analyze/analyze-time.c -index c233b1f08558e..8135112dec42b 100644 ---- a/src/analyze/analyze-time.c -+++ b/src/analyze/analyze-time.c -@@ -11,7 +11,7 @@ int verb_time(int argc, char *argv[], void *userdata) { - - r = acquire_bus(&bus, NULL); - if (r < 0) -- return bus_log_connect_error(r, arg_transport); -+ return bus_log_connect_error(r, arg_transport, arg_runtime_scope); - - r = pretty_boot_time(bus, &buf); - if (r < 0) -diff --git a/src/busctl/busctl.c b/src/busctl/busctl.c -index 8db9076997232..bbd36c1dc42bc 100644 ---- a/src/busctl/busctl.c -+++ b/src/busctl/busctl.c -@@ -152,7 +152,7 @@ static int acquire_bus(bool set_monitor, sd_bus **ret) { - - r = sd_bus_start(bus); - if (r < 0) -- return bus_log_connect_error(r, arg_transport); -+ return bus_log_connect_error(r, arg_transport, arg_runtime_scope); - - *ret = TAKE_PTR(bus); - -diff --git a/src/cgls/cgls.c b/src/cgls/cgls.c -index 70fa260246929..1dcd316cdb379 100644 ---- a/src/cgls/cgls.c -+++ b/src/cgls/cgls.c -@@ -221,13 +221,12 @@ static int run(int argc, char *argv[]) { - return log_error_errno(r, "Failed to mangle unit name: %m"); - - if (!bus) { -+ RuntimeScope scope = arg_show_unit == SHOW_UNIT_USER ? RUNTIME_SCOPE_USER : RUNTIME_SCOPE_SYSTEM; -+ - /* Connect to the bus only if necessary */ -- r = bus_connect_transport_systemd( -- BUS_TRANSPORT_LOCAL, NULL, -- arg_show_unit == SHOW_UNIT_USER ? RUNTIME_SCOPE_USER : RUNTIME_SCOPE_SYSTEM, -- &bus); -+ r = bus_connect_transport_systemd(BUS_TRANSPORT_LOCAL, NULL, scope, &bus); - if (r < 0) -- return bus_log_connect_error(r, BUS_TRANSPORT_LOCAL); -+ return bus_log_connect_error(r, BUS_TRANSPORT_LOCAL, scope); - } - - q = show_cgroup_get_unit_path_and_warn(bus, unit_name, &cgroup); -diff --git a/src/firstboot/firstboot.c b/src/firstboot/firstboot.c -index 0dbdfc663871f..3b732b38609ab 100644 ---- a/src/firstboot/firstboot.c -+++ b/src/firstboot/firstboot.c -@@ -1616,7 +1616,7 @@ static int reload_system_manager(sd_bus **bus) { - if (!*bus) { - r = bus_connect_transport_systemd(BUS_TRANSPORT_LOCAL, NULL, RUNTIME_SCOPE_SYSTEM, bus); - if (r < 0) -- return bus_log_connect_error(r, BUS_TRANSPORT_LOCAL); -+ return bus_log_connect_error(r, BUS_TRANSPORT_LOCAL, RUNTIME_SCOPE_SYSTEM); - } - - r = bus_service_manager_reload(*bus); -@@ -1639,7 +1639,7 @@ static int reload_vconsole(sd_bus **bus) { - if (!*bus) { - r = bus_connect_transport_systemd(BUS_TRANSPORT_LOCAL, NULL, RUNTIME_SCOPE_SYSTEM, bus); - if (r < 0) -- return bus_log_connect_error(r, BUS_TRANSPORT_LOCAL); -+ return bus_log_connect_error(r, BUS_TRANSPORT_LOCAL, RUNTIME_SCOPE_SYSTEM); - } - - r = bus_wait_for_jobs_new(*bus, &w); -diff --git a/src/home/homectl.c b/src/home/homectl.c -index 346daa1195ccd..36e3bf729948f 100644 ---- a/src/home/homectl.c -+++ b/src/home/homectl.c -@@ -134,7 +134,7 @@ static int acquire_bus(sd_bus **bus) { - - r = bus_connect_transport(arg_transport, arg_host, RUNTIME_SCOPE_SYSTEM, bus); - if (r < 0) -- return bus_log_connect_error(r, arg_transport); -+ return bus_log_connect_error(r, arg_transport, RUNTIME_SCOPE_SYSTEM); - - (void) sd_bus_set_allow_interactive_authorization(*bus, arg_ask_password); - -diff --git a/src/hostname/hostnamectl.c b/src/hostname/hostnamectl.c -index d1c4d476f66b9..ead0cc4da6e82 100644 ---- a/src/hostname/hostnamectl.c -+++ b/src/hostname/hostnamectl.c -@@ -813,7 +813,7 @@ static int run(int argc, char *argv[]) { - - r = bus_connect_transport(arg_transport, arg_host, RUNTIME_SCOPE_SYSTEM, &bus); - if (r < 0) -- return bus_log_connect_error(r, arg_transport); -+ return bus_log_connect_error(r, arg_transport, RUNTIME_SCOPE_SYSTEM); - - return hostnamectl_main(bus, argc, argv); - } -diff --git a/src/import/importctl.c b/src/import/importctl.c -index f939d80815dca..da9e5b62d23d6 100644 ---- a/src/import/importctl.c -+++ b/src/import/importctl.c -@@ -1235,7 +1235,7 @@ static int run(int argc, char *argv[]) { - - r = bus_connect_transport(arg_transport, arg_host, RUNTIME_SCOPE_SYSTEM, &bus); - if (r < 0) -- return bus_log_connect_error(r, arg_transport); -+ return bus_log_connect_error(r, arg_transport, RUNTIME_SCOPE_SYSTEM); - - (void) sd_bus_set_allow_interactive_authorization(bus, arg_ask_password); - -diff --git a/src/locale/localectl.c b/src/locale/localectl.c -index 32354027f1755..2fb4657fe24fb 100644 ---- a/src/locale/localectl.c -+++ b/src/locale/localectl.c -@@ -527,7 +527,7 @@ static int run(int argc, char *argv[]) { - - r = bus_connect_transport(arg_transport, arg_host, RUNTIME_SCOPE_SYSTEM, &bus); - if (r < 0) -- return bus_log_connect_error(r, arg_transport); -+ return bus_log_connect_error(r, arg_transport, RUNTIME_SCOPE_SYSTEM); - - return localectl_main(bus, argc, argv); - } -diff --git a/src/login/inhibit.c b/src/login/inhibit.c -index 4682830d198a8..e060c614004b1 100644 ---- a/src/login/inhibit.c -+++ b/src/login/inhibit.c -@@ -265,7 +265,7 @@ static int run(int argc, char *argv[]) { - - r = sd_bus_default_system(&bus); - if (r < 0) -- return bus_log_connect_error(r, BUS_TRANSPORT_LOCAL); -+ return bus_log_connect_error(r, BUS_TRANSPORT_LOCAL, RUNTIME_SCOPE_SYSTEM); - - if (arg_action == ACTION_LIST) - return print_inhibitors(bus); -diff --git a/src/login/loginctl.c b/src/login/loginctl.c -index cf3bff437a0bc..e950bfc985ff5 100644 ---- a/src/login/loginctl.c -+++ b/src/login/loginctl.c -@@ -1727,7 +1727,7 @@ static int run(int argc, char *argv[]) { - - r = bus_connect_transport(arg_transport, arg_host, RUNTIME_SCOPE_SYSTEM, &bus); - if (r < 0) -- return bus_log_connect_error(r, arg_transport); -+ return bus_log_connect_error(r, arg_transport, RUNTIME_SCOPE_SYSTEM); - - (void) sd_bus_set_allow_interactive_authorization(bus, arg_ask_password); - -diff --git a/src/machine/machinectl.c b/src/machine/machinectl.c -index 1b63e6d203786..b9105f298b6b1 100644 ---- a/src/machine/machinectl.c -+++ b/src/machine/machinectl.c -@@ -2446,7 +2446,7 @@ static int run(int argc, char *argv[]) { - - r = bus_connect_transport(arg_transport, arg_host, RUNTIME_SCOPE_SYSTEM, &bus); - if (r < 0) -- return bus_log_connect_error(r, arg_transport); -+ return bus_log_connect_error(r, arg_transport, RUNTIME_SCOPE_SYSTEM); - - (void) sd_bus_set_allow_interactive_authorization(bus, arg_ask_password); - -diff --git a/src/mount/mount-tool.c b/src/mount/mount-tool.c -index fcebdcaf18c9b..b991bed714896 100644 ---- a/src/mount/mount-tool.c -+++ b/src/mount/mount-tool.c -@@ -1503,7 +1503,7 @@ static int run(int argc, char* argv[]) { - - r = bus_connect_transport_systemd(arg_transport, arg_host, arg_runtime_scope, &bus); - if (r < 0) -- return bus_log_connect_error(r, arg_transport); -+ return bus_log_connect_error(r, arg_transport, arg_runtime_scope); - - if (arg_action == ACTION_UMOUNT) - return action_umount(bus, argc, argv); -diff --git a/src/portable/portablectl.c b/src/portable/portablectl.c -index 57b930d6cba41..2681cf4dd2070 100644 ---- a/src/portable/portablectl.c -+++ b/src/portable/portablectl.c -@@ -229,7 +229,7 @@ static int acquire_bus(sd_bus **bus) { - - r = bus_connect_transport(arg_transport, arg_host, RUNTIME_SCOPE_SYSTEM, bus); - if (r < 0) -- return bus_log_connect_error(r, arg_transport); -+ return bus_log_connect_error(r, arg_transport, RUNTIME_SCOPE_SYSTEM); - - (void) sd_bus_set_allow_interactive_authorization(*bus, arg_ask_password); - -diff --git a/src/run/run.c b/src/run/run.c -index ba7bb2148a15f..3a7102e32923b 100644 ---- a/src/run/run.c -+++ b/src/run/run.c -@@ -2405,7 +2405,7 @@ static int run(int argc, char* argv[]) { - else - r = bus_connect_transport_systemd(arg_transport, arg_host, arg_runtime_scope, &bus); - if (r < 0) -- return bus_log_connect_error(r, arg_transport); -+ return bus_log_connect_error(r, arg_transport, arg_runtime_scope); - - if (arg_scope) - return start_transient_scope(bus); -diff --git a/src/shared/bus-util.c b/src/shared/bus-util.c -index 30f9602b1edbc..f347ea604ec25 100644 ---- a/src/shared/bus-util.c -+++ b/src/shared/bus-util.c -@@ -28,6 +28,7 @@ - #include "path-util.h" - #include "socket-util.h" - #include "stdio-util.h" -+#include "string-table.h" - #include "uid-classification.h" - - static int name_owner_change_callback(sd_bus_message *m, void *userdata, sd_bus_error *ret_error) { -@@ -49,14 +50,14 @@ int bus_log_address_error(int r, BusTransport transport) { - "Failed to set bus address: %m"); - } - --int bus_log_connect_error(int r, BusTransport transport) { -+int bus_log_connect_error(int r, BusTransport transport, RuntimeScope scope) { - bool hint_vars = transport == BUS_TRANSPORT_LOCAL && r == -ENOMEDIUM, - hint_addr = transport == BUS_TRANSPORT_LOCAL && ERRNO_IS_PRIVILEGE(r); - - return log_error_errno(r, -- r == hint_vars ? "Failed to connect to bus: $DBUS_SESSION_BUS_ADDRESS and $XDG_RUNTIME_DIR not defined (consider using --machine=@.host --user to connect to bus of other user)" : -- r == hint_addr ? "Failed to connect to bus: Operation not permitted (consider using --machine=@.host --user to connect to bus of other user)" : -- "Failed to connect to bus: %m"); -+ r == hint_vars ? "Failed to connect to %s scope bus via %s transport: $DBUS_SESSION_BUS_ADDRESS and $XDG_RUNTIME_DIR not defined (consider using --machine=@.host --user to connect to bus of other user)" : -+ r == hint_addr ? "Failed to connect to %s scope bus via %s transport: Operation not permitted (consider using --machine=@.host --user to connect to bus of other user)" : -+ "Failed to connect to %s scope bus via %s transport: %m", runtime_scope_to_string(scope), bus_transport_to_string(transport)); - } - - int bus_async_unregister_and_exit(sd_event *e, sd_bus *bus, const char *name) { -@@ -926,3 +927,12 @@ int bus_message_read_id128(sd_bus_message *m, sd_id128_t *ret) { - return -EINVAL; - } - } -+ -+static const char* const bus_transport_table[] = { -+ [BUS_TRANSPORT_LOCAL] = "local", -+ [BUS_TRANSPORT_REMOTE] = "remote", -+ [BUS_TRANSPORT_MACHINE] = "machine", -+ [BUS_TRANSPORT_CAPSULE] = "capsule", -+}; -+ -+DEFINE_STRING_TABLE_LOOKUP_TO_STRING(bus_transport, BusTransport); -diff --git a/src/shared/bus-util.h b/src/shared/bus-util.h -index 9c6f01d8eb846..fbccb24314fe4 100644 ---- a/src/shared/bus-util.h -+++ b/src/shared/bus-util.h -@@ -48,7 +48,7 @@ int bus_connect_transport(BusTransport transport, const char *host, RuntimeScope - int bus_connect_transport_systemd(BusTransport transport, const char *host, RuntimeScope runtime_scope, sd_bus **bus); - - int bus_log_address_error(int r, BusTransport transport); --int bus_log_connect_error(int r, BusTransport transport); -+int bus_log_connect_error(int r, BusTransport transport, RuntimeScope scope); - - #define bus_log_parse_error(r) \ - log_error_errno(r, "Failed to parse bus message: %m") -@@ -84,3 +84,5 @@ int bus_creds_get_pidref(sd_bus_creds *c, PidRef *ret); - int bus_query_sender_pidref(sd_bus_message *m, PidRef *ret); - - int bus_message_read_id128(sd_bus_message *m, sd_id128_t *ret); -+ -+const char* bus_transport_to_string(BusTransport transport) _const_; -diff --git a/src/shared/cgroup-show.c b/src/shared/cgroup-show.c -index 87177316da8f9..96826ac7d8e87 100644 ---- a/src/shared/cgroup-show.c -+++ b/src/shared/cgroup-show.c -@@ -433,7 +433,7 @@ int show_cgroup_get_path_and_warn( - - r = bus_connect_transport_systemd(BUS_TRANSPORT_LOCAL, NULL, RUNTIME_SCOPE_SYSTEM, &bus); - if (r < 0) -- return bus_log_connect_error(r, BUS_TRANSPORT_LOCAL); -+ return bus_log_connect_error(r, BUS_TRANSPORT_LOCAL, RUNTIME_SCOPE_SYSTEM); - - r = show_cgroup_get_unit_path_and_warn(bus, unit, &root); - if (r < 0) -diff --git a/src/systemctl/systemctl-util.c b/src/systemctl/systemctl-util.c -index 38e1f23740ed6..18c8823e3fe70 100644 ---- a/src/systemctl/systemctl-util.c -+++ b/src/systemctl/systemctl-util.c -@@ -54,7 +54,7 @@ int acquire_bus(BusFocus focus, sd_bus **ret) { - else - r = bus_connect_transport(arg_transport, arg_host, arg_runtime_scope, &buses[focus]); - if (r < 0) -- return bus_log_connect_error(r, arg_transport); -+ return bus_log_connect_error(r, arg_transport, arg_runtime_scope); - - (void) sd_bus_set_allow_interactive_authorization(buses[focus], arg_ask_password); - } -diff --git a/src/timedate/timedatectl.c b/src/timedate/timedatectl.c -index 46ec6b31bc46a..db9f3b22b9b5e 100644 ---- a/src/timedate/timedatectl.c -+++ b/src/timedate/timedatectl.c -@@ -1031,7 +1031,7 @@ static int run(int argc, char *argv[]) { - - r = bus_connect_transport(arg_transport, arg_host, RUNTIME_SCOPE_SYSTEM, &bus); - if (r < 0) -- return bus_log_connect_error(r, arg_transport); -+ return bus_log_connect_error(r, arg_transport, RUNTIME_SCOPE_SYSTEM); - - return timedatectl_main(bus, argc, argv); - } - -From 31e38b55b2e4bb1aa42fe106ea14df8e82758303 Mon Sep 17 00:00:00 2001 -From: Daan De Meyer -Date: Tue, 8 Oct 2024 16:25:52 +0200 -Subject: [PATCH 2/3] core: Bump log level of reexecute request to notice - -A daemon-reload is important enough to deserve logging at notice -level. - -(cherry picked from commit 4ee41be82507348fbbc9d3ab28aae6330eb51663) ---- - src/core/dbus-manager.c | 8 ++++---- - 1 file changed, 4 insertions(+), 4 deletions(-) - -diff --git a/src/core/dbus-manager.c b/src/core/dbus-manager.c -index 7da35a803c62c..2412bd1aab742 100644 ---- a/src/core/dbus-manager.c -+++ b/src/core/dbus-manager.c -@@ -1571,10 +1571,10 @@ static void log_caller(sd_bus_message *message, Manager *manager, const char *me - (void) sd_bus_creds_get_comm(creds, &comm); - caller = manager_get_unit_by_pid(manager, pid); - -- log_info("%s requested from client PID " PID_FMT "%s%s%s%s%s%s...", -- method, pid, -- comm ? " ('" : "", strempty(comm), comm ? "')" : "", -- caller ? " (unit " : "", caller ? caller->id : "", caller ? ")" : ""); -+ log_notice("%s requested from client PID " PID_FMT "%s%s%s%s%s%s...", -+ method, pid, -+ comm ? " ('" : "", strempty(comm), comm ? "')" : "", -+ caller ? " (unit " : "", caller ? caller->id : "", caller ? ")" : ""); - } - - static int method_reload(sd_bus_message *message, void *userdata, sd_bus_error *error) { - -From 814be7116dda14074749253d94b83387ceff0ff1 Mon Sep 17 00:00:00 2001 -From: Daan De Meyer -Date: Tue, 8 Oct 2024 16:28:25 +0200 -Subject: [PATCH 3/3] core: Log in more scenarios about which process initiated - an operation - -Exit/Reboot/Poweroff and similar operations are invasive enough that -logging about who initiated them is very useful to debug issues. - -(cherry picked from commit acb0f501f4291efce82bcf89d4ad92b6a895f4fa) ---- - src/core/dbus-manager.c | 12 ++++++++++++ - 1 file changed, 12 insertions(+) - -diff --git a/src/core/dbus-manager.c b/src/core/dbus-manager.c -index 2412bd1aab742..0c1260f2d9cbe 100644 ---- a/src/core/dbus-manager.c -+++ b/src/core/dbus-manager.c -@@ -1671,6 +1671,8 @@ static int method_exit(sd_bus_message *message, void *userdata, sd_bus_error *er - if (r < 0) - return r; - -+ log_caller(message, m, "Exit"); -+ - /* Exit() (in contrast to SetExitCode()) is actually allowed even if - * we are running on the host. It will fall back on reboot() in - * systemd-shutdown if it cannot do the exit() because it isn't a -@@ -1695,6 +1697,8 @@ static int method_reboot(sd_bus_message *message, void *userdata, sd_bus_error * - return sd_bus_error_setf(error, SD_BUS_ERROR_NOT_SUPPORTED, - "Reboot is only supported for system managers."); - -+ log_caller(message, m, "Reboot"); -+ - m->objective = MANAGER_REBOOT; - - return sd_bus_reply_method_return(message, NULL); -@@ -1737,6 +1741,8 @@ static int method_soft_reboot(sd_bus_message *message, void *userdata, sd_bus_er - return -ENOMEM; - } - -+ log_caller(message, m, "Soft reboot"); -+ - free_and_replace(m->switch_root, rt); - m->objective = MANAGER_SOFT_REBOOT; - -@@ -1757,6 +1763,8 @@ static int method_poweroff(sd_bus_message *message, void *userdata, sd_bus_error - return sd_bus_error_setf(error, SD_BUS_ERROR_NOT_SUPPORTED, - "Powering off is only supported for system managers."); - -+ log_caller(message, m, "Poweroff"); -+ - m->objective = MANAGER_POWEROFF; - - return sd_bus_reply_method_return(message, NULL); -@@ -1776,6 +1784,8 @@ static int method_halt(sd_bus_message *message, void *userdata, sd_bus_error *er - return sd_bus_error_setf(error, SD_BUS_ERROR_NOT_SUPPORTED, - "Halt is only supported for system managers."); - -+ log_caller(message, m, "Halt"); -+ - m->objective = MANAGER_HALT; - - return sd_bus_reply_method_return(message, NULL); -@@ -1795,6 +1805,8 @@ static int method_kexec(sd_bus_message *message, void *userdata, sd_bus_error *e - return sd_bus_error_setf(error, SD_BUS_ERROR_NOT_SUPPORTED, - "KExec is only supported for system managers."); - -+ log_caller(message, m, "Kexec"); -+ - m->objective = MANAGER_KEXEC; - - return sd_bus_reply_method_return(message, NULL); diff --git a/34851.patch b/34851.patch deleted file mode 100644 index e923768..0000000 --- a/34851.patch +++ /dev/null @@ -1,96 +0,0 @@ -From c5698fe9076a8dc3472140c7d67f4524430f80a0 Mon Sep 17 00:00:00 2001 -From: Daan De Meyer -Date: Tue, 22 Oct 2024 10:59:27 +0200 -Subject: [PATCH 1/3] bus-util: Return ENOMEDIUM if XDG_RUNTIME_DIR is unset - -bus_log_connect_error() checks for ENOMEDIUM, not ENXIO. ---- - src/shared/bus-util.c | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - -diff --git a/src/shared/bus-util.c b/src/shared/bus-util.c -index 6ea046ee6d435..57c60dcb67d33 100644 ---- a/src/shared/bus-util.c -+++ b/src/shared/bus-util.c -@@ -259,7 +259,7 @@ int bus_connect_user_systemd(sd_bus **ret_bus) { - - e = secure_getenv("XDG_RUNTIME_DIR"); - if (!e) -- return -ENXIO; -+ return -ENOMEDIUM; - - ee = bus_address_escape(e); - if (!ee) - -From d0316b7a0d356ba12325ce5a00b0cbe0bc359461 Mon Sep 17 00:00:00 2001 -From: Daan De Meyer -Date: Tue, 22 Oct 2024 11:12:17 +0200 -Subject: [PATCH 2/3] bus-util: Special case when DBUS_SESSION_BUS_ADDRESS is - set and XDG_RUNTIME_DIR isn't - -We noticed some failures because we have code that connects to user -managers by setting DBUS_SESSION_BUS_ADDRESS without setting XDG_RUNTIME_DIR. -If that's the case, connect to the user session bus instead of the -private manager bus as we can't connect to the latter if XDG_RUNTIME_DIR -is not set. ---- - src/shared/bus-util.c | 12 +++++++++++- - 1 file changed, 11 insertions(+), 1 deletion(-) - -diff --git a/src/shared/bus-util.c b/src/shared/bus-util.c -index 57c60dcb67d33..fa4f879b7bac3 100644 ---- a/src/shared/bus-util.c -+++ b/src/shared/bus-util.c -@@ -496,6 +496,8 @@ int bus_connect_transport_systemd( - RuntimeScope runtime_scope, - sd_bus **ret_bus) { - -+ int r; -+ - assert(transport >= 0); - assert(transport < _BUS_TRANSPORT_MAX); - assert(ret_bus); -@@ -508,7 +510,15 @@ int bus_connect_transport_systemd( - switch (runtime_scope) { - - case RUNTIME_SCOPE_USER: -- return bus_connect_user_systemd(ret_bus); -+ r = bus_connect_user_systemd(ret_bus); -+ /* We used to always fall back to the user session bus if we couldn't connect to the -+ * private manager bus. To keep compat with existing code that was setting -+ * DBUS_SESSION_BUS_ADDRESS without setting XDG_RUNTIME_DIR, connect to the user -+ * session bus if DBUS_SESSION_BUS_ADDRESS is set and XDG_RUNTIME_DIR isn't. */ -+ if (r == -ENOMEDIUM && secure_getenv("DBUS_SESSION_BUS_ADDRESS")) -+ r = sd_bus_default_user(ret_bus); -+ -+ return r; - - case RUNTIME_SCOPE_SYSTEM: - if (sd_booted() <= 0) - -From d64a5b30f10a07001c4124f5c4127452fc3cac99 Mon Sep 17 00:00:00 2001 -From: Daan De Meyer -Date: Tue, 22 Oct 2024 12:32:02 +0200 -Subject: [PATCH 3/3] bus-util: Fix bus_log_connect_error() - ---- - src/shared/bus-util.c | 6 +++--- - 1 file changed, 3 insertions(+), 3 deletions(-) - -diff --git a/src/shared/bus-util.c b/src/shared/bus-util.c -index fa4f879b7bac3..ce94597955aa3 100644 ---- a/src/shared/bus-util.c -+++ b/src/shared/bus-util.c -@@ -56,9 +56,9 @@ int bus_log_connect_error(int r, BusTransport transport, RuntimeScope scope) { - hint_addr = transport == BUS_TRANSPORT_LOCAL && ERRNO_IS_PRIVILEGE(r); - - return log_error_errno(r, -- r == hint_vars ? "Failed to connect to %s scope bus via %s transport: $DBUS_SESSION_BUS_ADDRESS and $XDG_RUNTIME_DIR not defined (consider using --machine=@.host --user to connect to bus of other user)" : -- r == hint_addr ? "Failed to connect to %s scope bus via %s transport: Operation not permitted (consider using --machine=@.host --user to connect to bus of other user)" : -- "Failed to connect to %s scope bus via %s transport: %m", runtime_scope_to_string(scope), bus_transport_to_string(transport)); -+ hint_vars ? "Failed to connect to %s scope bus via %s transport: $DBUS_SESSION_BUS_ADDRESS and $XDG_RUNTIME_DIR not defined (consider using --machine=@.host --user to connect to bus of other user)" : -+ hint_addr ? "Failed to connect to %s scope bus via %s transport: Operation not permitted (consider using --machine=@.host --user to connect to bus of other user)" : -+ "Failed to connect to %s scope bus via %s transport: %m", runtime_scope_to_string(scope), bus_transport_to_string(transport)); - } - - int bus_async_unregister_and_exit(sd_event *e, sd_bus *bus, const char *name) { diff --git a/35332.patch b/35332.patch deleted file mode 100644 index 731a645..0000000 --- a/35332.patch +++ /dev/null @@ -1,117 +0,0 @@ -From ca0cef28691be7ea22274c2fa7d95a2725da1ba5 Mon Sep 17 00:00:00 2001 -From: Yu Watanabe -Date: Sun, 24 Nov 2024 13:19:27 +0900 -Subject: [PATCH 1/2] core/device: ignore ID_PROCESSING udev property on - enumerate - -This partially reverts the commit 405be62f05d76f1845f347737b5972158c79dd3e -"tree-wide: refuse enumerated device with ID_PROCESSING=1". - -Otherwise, when systemd-udev-trigger.service is started just before -daemon-reexec, which can be easily happen on update, then udev database -files for many devices may have ID_PROCESSING=1 property, thus devices may -not enumerated on daemon-reexec. That causes many units especially mount -units deactivated after daemon-reexec. - -Fixes #35329. ---- - src/core/device.c | 3 --- - 1 file changed, 3 deletions(-) - -diff --git a/src/core/device.c b/src/core/device.c -index 03a730f6240c1..a8921e91c344e 100644 ---- a/src/core/device.c -+++ b/src/core/device.c -@@ -1048,9 +1048,6 @@ static void device_enumerate(Manager *m) { - _cleanup_set_free_ Set *ready_units = NULL, *not_ready_units = NULL; - Device *d; - -- if (device_is_processed(dev) <= 0) -- continue; -- - if (device_setup_units(m, dev, &ready_units, ¬_ready_units) < 0) - continue; - - -From 388151b72103c10d63bac1e845d6a151619990ae Mon Sep 17 00:00:00 2001 -From: Yu Watanabe -Date: Sun, 24 Nov 2024 13:57:37 +0900 -Subject: [PATCH 2/2] test: add reproducer for issue #35329 - -Without the previous commit, the test case will fail. ---- - .../TEST-17-UDEV.device_is_processing.sh | 65 +++++++++++++++++++ - 1 file changed, 65 insertions(+) - create mode 100755 test/units/TEST-17-UDEV.device_is_processing.sh - -diff --git a/test/units/TEST-17-UDEV.device_is_processing.sh b/test/units/TEST-17-UDEV.device_is_processing.sh -new file mode 100755 -index 0000000000000..9b39b43238e44 ---- /dev/null -+++ b/test/units/TEST-17-UDEV.device_is_processing.sh -@@ -0,0 +1,65 @@ -+#!/usr/bin/env bash -+# SPDX-License-Identifier: LGPL-2.1-or-later -+set -ex -+set -o pipefail -+ -+# This is a reproducer of issue #35329, -+# which is a regression caused by 405be62f05d76f1845f347737b5972158c79dd3e. -+ -+IFNAME=udevtestnetif -+ -+udevadm settle -+ -+mkdir -p /run/udev/udev.conf.d/ -+cat >/run/udev/udev.conf.d/timeout.conf </run/udev/rules.d/99-testsuite.rules < +Date: Wed, 8 Jan 2025 10:25:05 +0100 +Subject: [PATCH 01/22] fmf: Don't fail if we can't put selinux in permissive + mode + +The tests might be running unprivileged or in an environment without +selinux so let's not fail if we can't put it in permissive mode. + +(cherry picked from commit 0250db0139b159cb9e6c1a87ad91ffdd03e80236) +--- + test/fmf/integration-tests/test.sh | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +diff --git a/test/fmf/integration-tests/test.sh b/test/fmf/integration-tests/test.sh +index 4984fb119b571..fe139567bdf06 100755 +--- a/test/fmf/integration-tests/test.sh ++++ b/test/fmf/integration-tests/test.sh +@@ -4,8 +4,8 @@ + set -eux + set -o pipefail + +-# Switch SELinux to permissive, since the tests don't set proper contexts +-setenforce 0 ++# Switch SELinux to permissive if possible, since the tests don't set proper contexts ++setenforce 0 || true + + # Allow running the integration tests downstream in dist-git with something like + # the following snippet which makes the dist-git sources available in $TMT_SOURCE_DIR: + +From 006ff34ef7d27aa10fd7343dacd1663f25561799 Mon Sep 17 00:00:00 2001 +From: Daan De Meyer +Date: Wed, 8 Jan 2025 10:25:50 +0100 +Subject: [PATCH 02/22] fmf: Fix dist-git example + +All that's needed is dist-git-source: true so remove the other settings +that aren't required. + +(cherry picked from commit 0a85b3757968a2750286119760244e017c990263) +--- + test/fmf/integration-tests/test.sh | 3 --- + 1 file changed, 3 deletions(-) + +diff --git a/test/fmf/integration-tests/test.sh b/test/fmf/integration-tests/test.sh +index fe139567bdf06..73771d4237207 100755 +--- a/test/fmf/integration-tests/test.sh ++++ b/test/fmf/integration-tests/test.sh +@@ -13,9 +13,6 @@ setenforce 0 || true + # summary: systemd Fedora test suite + # discover: + # how: fmf +-# url: https://github.com/systemd/systemd +-# ref: main +-# path: test/fmf + # dist-git-source: true + # dist-git-install-builddeps: false + # prepare: + +From fc5028ef24af77c9bf0965bb9e3518cdc1041797 Mon Sep 17 00:00:00 2001 +From: Daan De Meyer +Date: Wed, 8 Jan 2025 10:38:21 +0100 +Subject: [PATCH 03/22] fmf: Fix glob + +Globs inside quotes aren't expanded and we need the glob to be more +specific to avoid matching multiple entries inside the tmt source +directory. + +(cherry picked from commit fc1b08dee2ccf706580fa448e66831d1e853d054) +--- + test/fmf/integration-tests/test.sh | 5 ++++- + 1 file changed, 4 insertions(+), 1 deletion(-) + +diff --git a/test/fmf/integration-tests/test.sh b/test/fmf/integration-tests/test.sh +index 73771d4237207..0a1595fa97268 100755 +--- a/test/fmf/integration-tests/test.sh ++++ b/test/fmf/integration-tests/test.sh +@@ -23,8 +23,11 @@ setenforce 0 || true + # execute: + # how: tmt + ++shopt -s extglob ++ + if [[ -n "${TMT_SOURCE_DIR:-}" ]]; then +- pushd "$TMT_SOURCE_DIR/*/" ++ # Match either directories ending with branch names (e.g. systemd-fmf) or releases (e.g systemd-257.1). ++ pushd "$TMT_SOURCE_DIR"/systemd-+([0-9a-z.~])/ + elif [[ -n "${PACKIT_TARGET_URL:-}" ]]; then + # Prepare systemd source tree + git clone "$PACKIT_TARGET_URL" systemd --branch "$PACKIT_TARGET_BRANCH" + +From bff09b9634e0160bd33302eec1c25438cdba2af5 Mon Sep 17 00:00:00 2001 +From: Daan De Meyer +Date: Wed, 8 Jan 2025 12:12:15 +0100 +Subject: [PATCH 04/22] fmf: Only mess with /etc/yum.repos.d when running + within testing farm + +If running tmt locally to debug the test script, make sure we don't +mess with /etc/yum.repos.d. + +(cherry picked from commit 8e3347f3bd3d9a01b8f39b0858eab74084ecf20a) +--- + test/fmf/integration-tests/test.sh | 18 ++++++++++++------ + 1 file changed, 12 insertions(+), 6 deletions(-) + +diff --git a/test/fmf/integration-tests/test.sh b/test/fmf/integration-tests/test.sh +index 0a1595fa97268..347cd219a458a 100755 +--- a/test/fmf/integration-tests/test.sh ++++ b/test/fmf/integration-tests/test.sh +@@ -63,6 +63,11 @@ Release=${VERSION_ID:-rawhide} + [Build] + ToolsTreeDistribution=$ID + ToolsTreeRelease=${VERSION_ID:-rawhide} ++EOF ++ ++if [[ -n "${TESTING_FARM_REQUEST_ID:-}" ]]; then ++ tee --append mkosi.local.conf <> /etc/yum.repos.d/copr_build* ++ # Ensure packages built for this test have highest priority ++ echo -e "\npriority=1" >> /etc/yum.repos.d/copr_build* + +-# Disable mkosi's own repository logic +-touch /etc/yum.repos.d/mkosi.repo ++ # Disable mkosi's own repository logic ++ touch /etc/yum.repos.d/mkosi.repo ++fi + + # TODO: drop once BTRFS regression is fixed in kernel 6.13 + sed -i "s/Format=btrfs/Format=ext4/" mkosi.repart/10-root.conf + +From d0b9af0f2bb5f8891eb4def4ec201bf527fe2096 Mon Sep 17 00:00:00 2001 +From: Daan De Meyer +Date: Wed, 8 Jan 2025 16:41:46 +0100 +Subject: [PATCH 05/22] fmf: Dump CPU and memory information + +(cherry picked from commit 44368f84d7ddbec7a50648a65c27cb6a31090a29) +--- + test/fmf/integration-tests/test.sh | 4 ++++ + 1 file changed, 4 insertions(+) + +diff --git a/test/fmf/integration-tests/test.sh b/test/fmf/integration-tests/test.sh +index 347cd219a458a..4545090c3c1ab 100755 +--- a/test/fmf/integration-tests/test.sh ++++ b/test/fmf/integration-tests/test.sh +@@ -7,6 +7,10 @@ set -o pipefail + # Switch SELinux to permissive if possible, since the tests don't set proper contexts + setenforce 0 || true + ++echo "CPU and Memory information:" ++lscpu ++lsmem ++ + # Allow running the integration tests downstream in dist-git with something like + # the following snippet which makes the dist-git sources available in $TMT_SOURCE_DIR: + # + +From c8cd705e5ed0a1f1fe642772a7605b36f30215a1 Mon Sep 17 00:00:00 2001 +From: Daan De Meyer +Date: Wed, 8 Jan 2025 13:31:11 +0100 +Subject: [PATCH 06/22] TEST-06-SELINUX: Add knob to allow checking for AVCs + +When running the integration tests downstream, it's useful to be +able to test that a new systemd version doesn't introduce any AVC +denials, so let's add a knob to make that possible. + +(cherry picked from commit de19520ec979902fd457515d1a795210fdaedf93) +--- + test/README.testsuite | 10 ++++++++++ + test/fmf/integration-tests/test.sh | 7 +++++++ + test/units/TEST-06-SELINUX.sh | 4 ++++ + 3 files changed, 21 insertions(+) + +diff --git a/test/README.testsuite b/test/README.testsuite +index da2d17a6dba7c..6b367aa6738fa 100644 +--- a/test/README.testsuite ++++ b/test/README.testsuite +@@ -151,6 +151,16 @@ that make use of `run_testcases`. + + `TEST_SKIP_TESTCASE=testcase`: takes a space separated list of testcases to skip. + ++### SELinux AVCs ++ ++To have `TEST-06-SELINUX` check for SELinux denials, write the following to ++mkosi.local.conf: ++ ++```conf ++[Runtime] ++KernelCommandLineExtra=systemd.setenv=TEST_SELINUX_CHECK_AVCS=1 ++``` ++ + ## Ubuntu CI + + New PRs submitted to the project are run through regression tests, and one set +diff --git a/test/fmf/integration-tests/test.sh b/test/fmf/integration-tests/test.sh +index 4545090c3c1ab..fccfa15c72821 100755 +--- a/test/fmf/integration-tests/test.sh ++++ b/test/fmf/integration-tests/test.sh +@@ -69,6 +69,13 @@ ToolsTreeDistribution=$ID + ToolsTreeRelease=${VERSION_ID:-rawhide} + EOF + ++if [[ -n "${TEST_SELINUX_CHECK_AVCS:-}" ]]; then ++ tee --append mkosi.local.conf < +Date: Wed, 8 Jan 2025 16:03:06 +0100 +Subject: [PATCH 07/22] fmf: Force SELinux relabel when running within testing + farm + +We expect to run as root within testing farm and to have permissions +to do selinux relabelling so let's enable it explicitly. + +(cherry picked from commit e1c883bf32f3922bfc977701062e353c0a0a4ac5) +--- + test/fmf/integration-tests/test.sh | 3 +++ + 1 file changed, 3 insertions(+) + +diff --git a/test/fmf/integration-tests/test.sh b/test/fmf/integration-tests/test.sh +index fccfa15c72821..8cea79cf30274 100755 +--- a/test/fmf/integration-tests/test.sh ++++ b/test/fmf/integration-tests/test.sh +@@ -78,6 +78,9 @@ fi + + if [[ -n "${TESTING_FARM_REQUEST_ID:-}" ]]; then + tee --append mkosi.local.conf < +Date: Thu, 9 Jan 2025 11:27:51 +0100 +Subject: [PATCH 08/22] test: Drop set -x from integration-test-setup.sh + +(cherry picked from commit 90538ede55ac9d40dc513f64f052c687672cae89) +--- + test/integration-test-setup.sh | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/test/integration-test-setup.sh b/test/integration-test-setup.sh +index d7c384a97cf48..c67f938acf26f 100755 +--- a/test/integration-test-setup.sh ++++ b/test/integration-test-setup.sh +@@ -1,6 +1,6 @@ + #!/usr/bin/env bash + # SPDX-License-Identifier: LGPL-2.1-or-later +-set -eux ++set -eu + set -o pipefail + + case "$1" in + +From 9f6617a1a086ecbdd4abb29d4a5b4eada05eb9c4 Mon Sep 17 00:00:00 2001 +From: Daan De Meyer +Date: Thu, 9 Jan 2025 11:28:15 +0100 +Subject: [PATCH 09/22] test: Only plug in integration-test-setup.sh in + interactive mode + +If we're not running interactively, there's no point in the features +from integration-test-setup.sh which are intended for interactive +development and debugging so lets skip adding it in that case. + +(cherry picked from commit 794d456cf402a35290d6562c21f0ff846511026c) +--- + test/integration-test-wrapper.py | 9 +++++++++ + test/test.service.in | 2 -- + 2 files changed, 9 insertions(+), 2 deletions(-) + +diff --git a/test/integration-test-wrapper.py b/test/integration-test-wrapper.py +index ef6df8840f50d..5fa0325b889e5 100755 +--- a/test/integration-test-wrapper.py ++++ b/test/integration-test-wrapper.py +@@ -459,6 +459,15 @@ def main() -> None: + """ + ) + ++ if sys.stderr.isatty(): ++ dropin += textwrap.dedent( ++ """ ++ [Service] ++ ExecStartPre=/usr/lib/systemd/tests/testdata/integration-test-setup.sh setup ++ ExecStopPost=/usr/lib/systemd/tests/testdata/integration-test-setup.sh finalize ++ """ ++ ) ++ + cmd = [ + args.mkosi, + '--directory', os.fspath(args.meson_source_dir), +diff --git a/test/test.service.in b/test/test.service.in +index 6400be0700288..75f703698f687 100644 +--- a/test/test.service.in ++++ b/test/test.service.in +@@ -7,9 +7,7 @@ Before=getty-pre.target + + [Service] + ExecStartPre=rm -f /failed /testok +-ExecStartPre=/usr/lib/systemd/tests/testdata/integration-test-setup.sh setup + ExecStart=@command@ +-ExecStopPost=/usr/lib/systemd/tests/testdata/integration-test-setup.sh finalize + Type=oneshot + MemoryAccounting=@memory-accounting@ + StateDirectory=%N + +From 2aa2a0c9d166fd7a77c027852255bf248fe63aa0 Mon Sep 17 00:00:00 2001 +From: Daan De Meyer +Date: Tue, 7 Jan 2025 15:01:02 +0100 +Subject: [PATCH 10/22] mkosi: Re-enable TEST-21-DFUZZER when running with + sanitizers + +Similar to how CentOS CI did it previously, let's only run +TEST-21-DFUZZER when built with sanitizers for maximum effect. + +(cherry picked from commit 103e92810a4bd3f01d2a49d85ef9575d60a8d244) +--- + .github/workflows/mkosi.yml | 8 ++++++++ + test/TEST-21-DFUZZER/meson.build | 1 - + 2 files changed, 8 insertions(+), 1 deletion(-) + +diff --git a/.github/workflows/mkosi.yml b/.github/workflows/mkosi.yml +index a043022ce05a1..592ed41051458 100644 +--- a/.github/workflows/mkosi.yml ++++ b/.github/workflows/mkosi.yml +@@ -61,6 +61,7 @@ jobs: + cflags: "-O2 -D_FORTIFY_SOURCE=3" + relabel: no + vm: 1 ++ skip: TEST-21-DFUZZER + - distro: debian + release: testing + sanitizers: "" +@@ -68,6 +69,7 @@ jobs: + cflags: "-Og" + relabel: no + vm: 0 ++ skip: TEST-21-DFUZZER + - distro: ubuntu + release: noble + sanitizers: "" +@@ -75,6 +77,7 @@ jobs: + cflags: "-Og" + relabel: no + vm: 0 ++ skip: TEST-21-DFUZZER + - distro: fedora + release: "41" + sanitizers: "" +@@ -82,6 +85,7 @@ jobs: + cflags: "-Og" + relabel: yes + vm: 0 ++ skip: TEST-21-DFUZZER + - distro: fedora + release: rawhide + sanitizers: address,undefined +@@ -96,6 +100,7 @@ jobs: + cflags: "-Og" + relabel: no + vm: 0 ++ skip: TEST-21-DFUZZER + - distro: centos + release: "9" + sanitizers: "" +@@ -103,6 +108,7 @@ jobs: + cflags: "-Og" + relabel: yes + vm: 0 ++ skip: TEST-21-DFUZZER + - distro: centos + release: "10" + sanitizers: "" +@@ -110,6 +116,7 @@ jobs: + cflags: "-Og" + relabel: yes + vm: 0 ++ skip: TEST-21-DFUZZER + + steps: + - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 +@@ -195,6 +202,7 @@ jobs: + mkosi sandbox \ + env \ + TEST_PREFER_QEMU=${{ matrix.vm }} \ ++ TEST_SKIP=${{ matrix.skip }} \ + meson test \ + -C build \ + --no-rebuild \ +diff --git a/test/TEST-21-DFUZZER/meson.build b/test/TEST-21-DFUZZER/meson.build +index f57be63380222..932f0c5f0e407 100644 +--- a/test/TEST-21-DFUZZER/meson.build ++++ b/test/TEST-21-DFUZZER/meson.build +@@ -6,6 +6,5 @@ integration_tests += [ + 'timeout' : 3600, + 'priority' : 50, + 'vm' : true, +- 'enabled' : false, + }, + ] + +From 0d6306c37144494e8b029a5f73aec40372587203 Mon Sep 17 00:00:00 2001 +From: Daan De Meyer +Date: Thu, 9 Jan 2025 15:13:18 +0100 +Subject: [PATCH 11/22] fmf: Move meson logs and failed test journals to test + artifacts dir + +(cherry picked from commit 0e444c948e7d8ddbdec83116b68af7d876e2d2f6) +--- + test/fmf/integration-tests/test.sh | 7 ++++++- + 1 file changed, 6 insertions(+), 1 deletion(-) + +diff --git a/test/fmf/integration-tests/test.sh b/test/fmf/integration-tests/test.sh +index 8cea79cf30274..762016f2a5c1c 100755 +--- a/test/fmf/integration-tests/test.sh ++++ b/test/fmf/integration-tests/test.sh +@@ -125,6 +125,11 @@ mkosi -f sandbox \ + --suite integration-tests \ + --print-errorlogs \ + --no-stdsplit \ +- --num-processes "$(($(nproc) - 1))" ++ --num-processes "$(($(nproc) - 1))" && EC=0 || EC=$? ++ ++find build/meson-logs -type f -exec mv {} "$TMT_TEST_DATA" \; ++find build/test/journal -type f -exec mv {} "$TMT_TEST_DATA" \; + + popd ++ ++exit "$EC" + +From 80d2d53b0d8573b69597a37f6ced38df97ad2746 Mon Sep 17 00:00:00 2001 +From: Daan De Meyer +Date: Thu, 9 Jan 2025 15:24:51 +0100 +Subject: [PATCH 12/22] fmf: Log clock source + +(cherry picked from commit 6e761c5a93278fc719a66f7c984af9608b836991) +--- + test/fmf/integration-tests/test.sh | 2 ++ + 1 file changed, 2 insertions(+) + +diff --git a/test/fmf/integration-tests/test.sh b/test/fmf/integration-tests/test.sh +index 762016f2a5c1c..d1e43b1d7dbc9 100755 +--- a/test/fmf/integration-tests/test.sh ++++ b/test/fmf/integration-tests/test.sh +@@ -11,6 +11,8 @@ echo "CPU and Memory information:" + lscpu + lsmem + ++echo "Clock source: $(cat /sys/devices/system/clocksource/clocksource0/current_clocksource)" ++ + # Allow running the integration tests downstream in dist-git with something like + # the following snippet which makes the dist-git sources available in $TMT_SOURCE_DIR: + # + +From 0584ff62f23838d2a85d48ce22a56aeb61e6f3e7 Mon Sep 17 00:00:00 2001 +From: Daan De Meyer +Date: Thu, 9 Jan 2025 16:24:22 +0100 +Subject: [PATCH 13/22] tree-wide: Fix python formatting + +The new release of ruff formats a few more things which causes linter +failures in CI so let's fix those formatting nits. + +(cherry picked from commit 96403d5121d93dd47dbe9dab5b90ff973e664ac3) +--- + src/ukify/ukify.py | 6 +++--- + test/integration-test-wrapper.py | 6 +++--- + 2 files changed, 6 insertions(+), 6 deletions(-) + +diff --git a/src/ukify/ukify.py b/src/ukify/ukify.py +index 3f36aa7af6b08..be4e30eb8e36e 100755 +--- a/src/ukify/ukify.py ++++ b/src/ukify/ukify.py +@@ -763,7 +763,7 @@ def call_systemd_measure(uki: UKI, opts: UkifyConfig, profile_start: int = 0) -> + cmd = [ + measure_tool, + 'calculate', +- *(f"--{s.name.removeprefix('.')}={s.content}" for s in to_measure.values()), ++ *(f'--{s.name.removeprefix(".")}={s.content}' for s in to_measure.values()), + *(f'--bank={bank}' for bank in banks), + # For measurement, the keys are not relevant, so we can lump all the phase paths + # into one call to systemd-measure calculate. +@@ -786,7 +786,7 @@ def call_systemd_measure(uki: UKI, opts: UkifyConfig, profile_start: int = 0) -> + cmd = [ + measure_tool, + 'sign', +- *(f"--{s.name.removeprefix('.')}={s.content}" for s in to_measure.values()), ++ *(f'--{s.name.removeprefix(".")}={s.content}' for s in to_measure.values()), + *(f'--bank={bank}' for bank in banks), + ] + +@@ -1284,7 +1284,7 @@ def make_uki(opts: UkifyConfig) -> None: + os.umask(umask := os.umask(0)) + os.chmod(opts.output, 0o777 & ~umask) + +- print(f"Wrote {'signed' if sign_args_present else 'unsigned'} {opts.output}") ++ print(f'Wrote {"signed" if sign_args_present else "unsigned"} {opts.output}') + + + @contextlib.contextmanager +diff --git a/test/integration-test-wrapper.py b/test/integration-test-wrapper.py +index 5fa0325b889e5..d9d92fcba3b0e 100755 +--- a/test/integration-test-wrapper.py ++++ b/test/integration-test-wrapper.py +@@ -429,7 +429,7 @@ def main() -> None: + dropin += textwrap.dedent( + f""" + [Service] +- Environment=TEST_MATCH_SUBTEST={os.environ["TEST_MATCH_SUBTEST"]} ++ Environment=TEST_MATCH_SUBTEST={os.environ['TEST_MATCH_SUBTEST']} + """ + ) + +@@ -437,7 +437,7 @@ def main() -> None: + dropin += textwrap.dedent( + f""" + [Service] +- Environment=TEST_MATCH_TESTCASE={os.environ["TEST_MATCH_TESTCASE"]} ++ Environment=TEST_MATCH_TESTCASE={os.environ['TEST_MATCH_TESTCASE']} + """ + ) + +@@ -568,7 +568,7 @@ def main() -> None: + + ops += [f'journalctl --file {journal_file} --no-hostname -o short-monotonic -u {args.unit} -p info'] + +- print("Test failed, relevant logs can be viewed with: \n\n" f"{(' && '.join(ops))}\n", file=sys.stderr) ++ print(f'Test failed, relevant logs can be viewed with: \n\n{(" && ".join(ops))}\n', file=sys.stderr) + + # 0 also means we failed so translate that to a non-zero exit code to mark the test as failed. + exit(result.returncode or 1) + +From eb15a87fb0ba3d37b58e0b74f6c796f6d632c273 Mon Sep 17 00:00:00 2001 +From: Daan De Meyer +Date: Fri, 10 Jan 2025 14:27:33 +0100 +Subject: [PATCH 14/22] test: Add option to save in progress test journals to + /tmp + +The journal isn't the best at being fast, especially when writing +to disk and not to memory, which can cause integration tests to +grind to a halt on beefy systems due to all the systemd-journal-remote +instances not being able to write journal entries to disk fast enough. + +Let's introduce an option to allow writing in progress test journals +to use /tmp which can be used on beefy systems with lots of memory to +speed things up. + +(cherry picked from commit e49fdecd161b3d391e55311652fda3220d851fa1) +--- + test/README.testsuite | 4 ++++ + test/integration-test-wrapper.py | 12 +++++++++++- + 2 files changed, 15 insertions(+), 1 deletion(-) + +diff --git a/test/README.testsuite b/test/README.testsuite +index 6b367aa6738fa..e33c08f33a20e 100644 +--- a/test/README.testsuite ++++ b/test/README.testsuite +@@ -151,6 +151,10 @@ that make use of `run_testcases`. + + `TEST_SKIP_TESTCASE=testcase`: takes a space separated list of testcases to skip. + ++`TEST_JOURNAL_USE_TMP=1`: Write test journal to `/tmp` while the test is in ++progress and only move the journal to its final location in the build directory ++(`$BUILD_DIR/test/journal`) when the test is finished. ++ + ### SELinux AVCs + + To have `TEST-06-SELINUX` check for SELinux denials, write the following to +diff --git a/test/integration-test-wrapper.py b/test/integration-test-wrapper.py +index d9d92fcba3b0e..1c28cf3776e80 100755 +--- a/test/integration-test-wrapper.py ++++ b/test/integration-test-wrapper.py +@@ -10,6 +10,7 @@ + import os + import re + import shlex ++import shutil + import subprocess + import sys + import tempfile +@@ -441,7 +442,11 @@ def main() -> None: + """ + ) + +- journal_file = (args.meson_build_dir / (f'test/journal/{name}.journal')).absolute() ++ if os.getenv('TEST_JOURNAL_USE_TMP', '0') == '1': ++ journal_file = Path(f'/tmp/systemd-integration-tests/journal/{name.journal}') ++ else: ++ journal_file = (args.meson_build_dir / f'test/journal/{name}.journal').absolute() ++ + journal_file.unlink(missing_ok=True) + + if not sys.stderr.isatty(): +@@ -551,6 +556,11 @@ def main() -> None: + ): + journal_file.unlink(missing_ok=True) + ++ if os.getenv('TEST_JOURNAL_USE_TMP', '0') == '1': ++ dst = args.meson_build_dir / f'test/journal/{name}.journal' ++ dst.parent.mkdir(parents=True, exist_ok=True) ++ shutil.move(journal_file, dst) ++ + if shell or (result.returncode in (args.exit_code, 77) and not coredumps and not sanitizer): + exit(0 if shell or result.returncode == args.exit_code else 77) + + +From ce86b8086e92c84e33385fb48467384abe74ca6d Mon Sep 17 00:00:00 2001 +From: Daan De Meyer +Date: Fri, 10 Jan 2025 14:29:58 +0100 +Subject: [PATCH 15/22] test: Don't register machines with machined unless + we're in interactive mode + +(cherry picked from commit 84b30442d257102a9a39122f9a537fa48fb0bfda) +--- + test/integration-test-wrapper.py | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/test/integration-test-wrapper.py b/test/integration-test-wrapper.py +index 1c28cf3776e80..94904cfbc4c05 100755 +--- a/test/integration-test-wrapper.py ++++ b/test/integration-test-wrapper.py +@@ -516,7 +516,7 @@ def main() -> None: + ] + ), + '--credential', f"journal.storage={'persistent' if sys.stderr.isatty() else args.storage}", +- *(['--runtime-build-sources=no'] if not sys.stderr.isatty() else []), ++ *(['--runtime-build-sources=no', '--register=no'] if not sys.stderr.isatty() else []), + 'vm' if args.vm or os.getuid() != 0 or os.getenv('TEST_PREFER_QEMU', '0') == '1' else 'boot', + ] # fmt: skip + + +From 504eee6eb099c80b48d8bf7e82ca9e0d6549e076 Mon Sep 17 00:00:00 2001 +From: Daan De Meyer +Date: Fri, 10 Jan 2025 14:51:24 +0100 +Subject: [PATCH 16/22] test: Move StateDirectory= directive into dropin + +The integration-test-setup calls require StateDirectory= but some +tests override the test unit used which then won't have StateDirectory= +so let's move StateDirectory= into the dropin as well to avoid this +issue. + +(cherry picked from commit 1f17ec0ed419627a686ee6e719ac7f55cf082ada) +--- + test/integration-test-wrapper.py | 1 + + test/test.service.in | 1 - + 2 files changed, 1 insertion(+), 1 deletion(-) + +diff --git a/test/integration-test-wrapper.py b/test/integration-test-wrapper.py +index 94904cfbc4c05..610c34c903425 100755 +--- a/test/integration-test-wrapper.py ++++ b/test/integration-test-wrapper.py +@@ -470,6 +470,7 @@ def main() -> None: + [Service] + ExecStartPre=/usr/lib/systemd/tests/testdata/integration-test-setup.sh setup + ExecStopPost=/usr/lib/systemd/tests/testdata/integration-test-setup.sh finalize ++ StateDirectory=%N + """ + ) + +diff --git a/test/test.service.in b/test/test.service.in +index 75f703698f687..790c513da4338 100644 +--- a/test/test.service.in ++++ b/test/test.service.in +@@ -10,4 +10,3 @@ ExecStartPre=rm -f /failed /testok + ExecStart=@command@ + Type=oneshot + MemoryAccounting=@memory-accounting@ +-StateDirectory=%N + +From 4fc1059282f5e39b3385fe175d377de96461f68b Mon Sep 17 00:00:00 2001 +From: Daan De Meyer +Date: Fri, 10 Jan 2025 15:26:37 +0100 +Subject: [PATCH 17/22] fmf: Bump inotify limits to avoid systemd-nspawn + failures + +(cherry picked from commit c32a8cdaa0f03ae29e9edade1213cc2001b28000) +--- + test/fmf/integration-tests/test.sh | 4 ++++ + 1 file changed, 4 insertions(+) + +diff --git a/test/fmf/integration-tests/test.sh b/test/fmf/integration-tests/test.sh +index d1e43b1d7dbc9..34bf1abfa8943 100755 +--- a/test/fmf/integration-tests/test.sh ++++ b/test/fmf/integration-tests/test.sh +@@ -13,6 +13,10 @@ lsmem + + echo "Clock source: $(cat /sys/devices/system/clocksource/clocksource0/current_clocksource)" + ++# Bump inotify limits so nspawn containers don't run out of inotify file descriptors. ++sysctl fs.inotify.max_user_watches=65536 ++sysctl fs.inotify.max_user_instances=1024 ++ + # Allow running the integration tests downstream in dist-git with something like + # the following snippet which makes the dist-git sources available in $TMT_SOURCE_DIR: + # + +From 7f3639f9a0ead8ea70f2d975de4271bb7d8ab05b Mon Sep 17 00:00:00 2001 +From: Daan De Meyer +Date: Fri, 10 Jan 2025 15:26:54 +0100 +Subject: [PATCH 18/22] fmf: Use different heuristic on beefy systems + +If we save journals in /tmp, we can run a larger number of tests in +parallel so let's make use of the larger number of CPUs if the tests +run on a beefy machine. + +(cherry picked from commit 53546c71fe0a1b30ee296df84bb8c3577f5675a4) +--- + test/fmf/integration-tests/test.sh | 10 +++++++++- + 1 file changed, 9 insertions(+), 1 deletion(-) + +diff --git a/test/fmf/integration-tests/test.sh b/test/fmf/integration-tests/test.sh +index 34bf1abfa8943..06a98bfd7a0be 100755 +--- a/test/fmf/integration-tests/test.sh ++++ b/test/fmf/integration-tests/test.sh +@@ -116,6 +116,14 @@ if [[ ! -e /dev/kvm ]]; then + export TEST_NO_QEMU=1 + fi + ++NPROC="$(nproc)" ++if [[ "$NPROC" -ge 10 ]]; then ++ export TEST_JOURNAL_USE_TMP=1 ++ NPROC="$((NPROC / 3))" ++else ++ NPROC="$((NPROC - 1))" ++fi ++ + # Create missing mountpoint for mkosi sandbox. + mkdir -p /etc/pacman.d/gnupg + +@@ -131,7 +139,7 @@ mkosi -f sandbox \ + --suite integration-tests \ + --print-errorlogs \ + --no-stdsplit \ +- --num-processes "$(($(nproc) - 1))" && EC=0 || EC=$? ++ --num-processes "$NPROC" && EC=0 || EC=$? + + find build/meson-logs -type f -exec mv {} "$TMT_TEST_DATA" \; + find build/test/journal -type f -exec mv {} "$TMT_TEST_DATA" \; + +From 3661dcc1cbf43dca2a9a77c3dffe50cbe1a7ea18 Mon Sep 17 00:00:00 2001 +From: Daan De Meyer +Date: Fri, 10 Jan 2025 15:29:28 +0100 +Subject: [PATCH 19/22] fmf: Skip TEST-21-DFUZZER + +Similar to Github Actions, since we don't build with sanitizers in +the packit job, let's skip TEST-21-DFUZZER. + +(cherry picked from commit e0c2fd6a3345d26afdf4159406c38cd9101d2e0d) +--- + test/fmf/integration-tests/test.sh | 4 ++++ + 1 file changed, 4 insertions(+) + +diff --git a/test/fmf/integration-tests/test.sh b/test/fmf/integration-tests/test.sh +index 06a98bfd7a0be..f82961f9599d0 100755 +--- a/test/fmf/integration-tests/test.sh ++++ b/test/fmf/integration-tests/test.sh +@@ -124,6 +124,10 @@ else + NPROC="$((NPROC - 1))" + fi + ++# This test is only really useful if we're building with sanitizers and takes a long time, so let's skip it ++# for now. ++export TEST_SKIP="TEST-21-DFUZZER" ++ + # Create missing mountpoint for mkosi sandbox. + mkdir -p /etc/pacman.d/gnupg + + +From 25c8ee9dc089b593940cefefb2dba7660768a7a8 Mon Sep 17 00:00:00 2001 +From: Daan De Meyer +Date: Mon, 13 Jan 2025 10:33:20 +0100 +Subject: [PATCH 20/22] test: Fix bug in integration test wrapper + +(cherry picked from commit 79ac78e3680a425d86c7a90e6846c630c9583b48) +--- + test/integration-test-wrapper.py | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/test/integration-test-wrapper.py b/test/integration-test-wrapper.py +index 610c34c903425..5321faef57818 100755 +--- a/test/integration-test-wrapper.py ++++ b/test/integration-test-wrapper.py +@@ -443,7 +443,7 @@ def main() -> None: + ) + + if os.getenv('TEST_JOURNAL_USE_TMP', '0') == '1': +- journal_file = Path(f'/tmp/systemd-integration-tests/journal/{name.journal}') ++ journal_file = Path(f'/tmp/systemd-integration-tests/journal/{name}.journal') + else: + journal_file = (args.meson_build_dir / f'test/journal/{name}.journal').absolute() + + +From 051ad7661f7cf29b6cbf99c70a6a504f777bc240 Mon Sep 17 00:00:00 2001 +From: Daan De Meyer +Date: Tue, 14 Jan 2025 09:52:40 +0100 +Subject: [PATCH 21/22] test: Only move journal file if we didn't just unlink + it + +(cherry picked from commit 1d77ac19cfa1c9b194d7e9805430ab6fd38ba97e) +--- + test/integration-test-wrapper.py | 3 +-- + 1 file changed, 1 insertion(+), 2 deletions(-) + +diff --git a/test/integration-test-wrapper.py b/test/integration-test-wrapper.py +index 5321faef57818..a7bf5ea6060d4 100755 +--- a/test/integration-test-wrapper.py ++++ b/test/integration-test-wrapper.py +@@ -556,8 +556,7 @@ def main() -> None: + and not sanitizer + ): + journal_file.unlink(missing_ok=True) +- +- if os.getenv('TEST_JOURNAL_USE_TMP', '0') == '1': ++ elif os.getenv('TEST_JOURNAL_USE_TMP', '0') == '1': + dst = args.meson_build_dir / f'test/journal/{name}.journal' + dst.parent.mkdir(parents=True, exist_ok=True) + shutil.move(journal_file, dst) + +From 6cd2c87e4ef1379520c98316ac5d6bcf21ef1bd1 Mon Sep 17 00:00:00 2001 +From: Daan De Meyer +Date: Tue, 14 Jan 2025 11:41:17 +0100 +Subject: [PATCH 22/22] fmf: Only move logs if corresponding directory exists + +Otherwise find fails with an error. + +(cherry picked from commit 3c2fa8e0501f9f39b3b7ca0506a7d548a39af928) +--- + test/fmf/integration-tests/test.sh | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +diff --git a/test/fmf/integration-tests/test.sh b/test/fmf/integration-tests/test.sh +index f82961f9599d0..aff79340f79fe 100755 +--- a/test/fmf/integration-tests/test.sh ++++ b/test/fmf/integration-tests/test.sh +@@ -145,8 +145,8 @@ mkosi -f sandbox \ + --no-stdsplit \ + --num-processes "$NPROC" && EC=0 || EC=$? + +-find build/meson-logs -type f -exec mv {} "$TMT_TEST_DATA" \; +-find build/test/journal -type f -exec mv {} "$TMT_TEST_DATA" \; ++[[ -d build/meson-logs ]] && find build/meson-logs -type f -exec mv {} "$TMT_TEST_DATA" \; ++[[ -d build/test/journal ]] && find build/test/journal -type f -exec mv {} "$TMT_TEST_DATA" \; + + popd + diff --git a/36050.patch b/36050.patch new file mode 100644 index 0000000..67ccd58 --- /dev/null +++ b/36050.patch @@ -0,0 +1,638 @@ +From 020c48ffda361eb4962a11b888aca1ba75284ba6 Mon Sep 17 00:00:00 2001 +From: Ryan Wilson +Date: Tue, 3 Dec 2024 14:46:54 -0800 +Subject: [PATCH 1/3] networkctl: Make networkctl lldp output backwards + compatible with 255 + +--- + src/network/networkctl-lldp.c | 16 +++++++--------- + 1 file changed, 7 insertions(+), 9 deletions(-) + +diff --git a/src/network/networkctl-lldp.c b/src/network/networkctl-lldp.c +index 43ffbabb9fcbb..b1dc927af9767 100644 +--- a/src/network/networkctl-lldp.c ++++ b/src/network/networkctl-lldp.c +@@ -238,12 +238,11 @@ int link_lldp_status(int argc, char *argv[], void *userdata) { + + table = table_new("index", + "link", +- "system-name", +- "system-description", + "chassis-id", ++ "system-name", ++ "caps", + "port-id", +- "port-description", +- "caps"); ++ "port-description"); + if (!table) + return log_oom(); + +@@ -256,7 +255,7 @@ int link_lldp_status(int argc, char *argv[], void *userdata) { + table_hide_column_from_display(table, (size_t) 0); + + /* Make the capabilities not truncated */ +- assert_se(cell = table_get_cell(table, 0, 7)); ++ assert_se(cell = table_get_cell(table, 0, 4)); + table_set_minimum_width(table, cell, 11); + + sd_json_variant *i; +@@ -285,12 +284,11 @@ int link_lldp_status(int argc, char *argv[], void *userdata) { + r = table_add_many(table, + TABLE_INT, info.ifindex, + TABLE_STRING, info.ifname, +- TABLE_STRING, neighbor_info.system_name, +- TABLE_STRING, neighbor_info.system_description, + TABLE_STRING, neighbor_info.chassis_id, ++ TABLE_STRING, neighbor_info.system_name, ++ TABLE_STRING, cap_str, + TABLE_STRING, neighbor_info.port_id, +- TABLE_STRING, neighbor_info.port_description, +- TABLE_STRING, cap_str); ++ TABLE_STRING, neighbor_info.port_description); + if (r < 0) + return table_log_add_error(r); + + +From b99fb7eb9882f261fa250d9d5c76a83cbf1e41c6 Mon Sep 17 00:00:00 2001 +From: Ryan Wilson +Date: Wed, 4 Dec 2024 16:15:30 -0800 +Subject: [PATCH 2/3] networkctl: Make lldp/status backwards compatible with + 255 over dbus + +--- + src/libsystemd-network/lldp-neighbor.c | 22 +++ + src/network/networkctl-lldp.c | 198 ++++++++++++++++++++++++- + src/network/networkctl-lldp.h | 1 + + src/network/networkctl-status-link.c | 9 +- + src/network/networkctl-util.c | 2 +- + src/systemd/sd-lldp-rx.h | 1 + + 6 files changed, 226 insertions(+), 7 deletions(-) + +diff --git a/src/libsystemd-network/lldp-neighbor.c b/src/libsystemd-network/lldp-neighbor.c +index 457b1e5926b0c..4e51a55bd1f64 100644 +--- a/src/libsystemd-network/lldp-neighbor.c ++++ b/src/libsystemd-network/lldp-neighbor.c +@@ -630,6 +630,28 @@ int sd_lldp_neighbor_get_enabled_capabilities(sd_lldp_neighbor *n, uint16_t *ret + return 0; + } + ++int sd_lldp_neighbor_from_raw(sd_lldp_neighbor **ret, const void *raw, size_t raw_size) { ++ _cleanup_(sd_lldp_neighbor_unrefp) sd_lldp_neighbor *n = NULL; ++ int r; ++ ++ assert_return(ret, -EINVAL); ++ assert_return(raw || raw_size <= 0, -EINVAL); ++ ++ n = lldp_neighbor_new(raw_size); ++ if (!n) ++ return -ENOMEM; ++ ++ memcpy_safe(LLDP_NEIGHBOR_RAW(n), raw, raw_size); ++ ++ r = lldp_neighbor_parse(n); ++ if (r < 0) ++ return r; ++ ++ *ret = TAKE_PTR(n); ++ ++ return r; ++} ++ + int sd_lldp_neighbor_tlv_rewind(sd_lldp_neighbor *n) { + assert_return(n, -EINVAL); + +diff --git a/src/network/networkctl-lldp.c b/src/network/networkctl-lldp.c +index b1dc927af9767..6a3a88210c8e2 100644 +--- a/src/network/networkctl-lldp.c ++++ b/src/network/networkctl-lldp.c +@@ -1,11 +1,15 @@ + /* SPDX-License-Identifier: LGPL-2.1-or-later */ + + #include "alloc-util.h" ++#include "fd-util.h" + #include "json-util.h" + #include "networkctl.h" + #include "networkctl-dump-util.h" ++#include "networkctl-link-info.h" + #include "networkctl-lldp.h" + #include "networkctl-util.h" ++#include "sd-lldp-rx.h" ++#include "sparse-endian.h" + #include "stdio-util.h" + #include "strv.h" + #include "terminal-util.h" +@@ -214,6 +218,194 @@ static int dump_lldp_neighbors_json(sd_json_variant *reply, char * const *patter + return sd_json_variant_dump(v, arg_json_format_flags, NULL, NULL); + } + ++static int open_lldp_neighbors_legacy(int ifindex, FILE **ret) { ++ _cleanup_fclose_ FILE *f = NULL; ++ char p[STRLEN("/run/systemd/netif/lldp/") + DECIMAL_STR_MAX(int)]; ++ ++ assert(ifindex >= 0); ++ assert(ret); ++ ++ xsprintf(p, "/run/systemd/netif/lldp/%i", ifindex); ++ ++ f = fopen(p, "re"); ++ if (!f) ++ return -errno; ++ ++ *ret = TAKE_PTR(f); ++ return 0; ++} ++ ++static int next_lldp_neighbor_legacy(FILE *f, sd_lldp_neighbor **ret) { ++ _cleanup_free_ void *raw = NULL; ++ size_t l; ++ le64_t u; ++ int r; ++ ++ assert(f); ++ assert(ret); ++ ++ l = fread(&u, 1, sizeof(u), f); ++ if (l == 0 && feof(f)) ++ return 0; ++ if (l != sizeof(u)) ++ return -EBADMSG; ++ ++ /* each LLDP packet is at most MTU size, but let's allow up to 4KiB just in case */ ++ if (le64toh(u) >= 4096) ++ return -EBADMSG; ++ ++ raw = new(uint8_t, le64toh(u)); ++ if (!raw) ++ return -ENOMEM; ++ ++ if (fread(raw, 1, le64toh(u), f) != le64toh(u)) ++ return -EBADMSG; ++ ++ r = sd_lldp_neighbor_from_raw(ret, raw, le64toh(u)); ++ if (r < 0) ++ return r; ++ ++ return 1; ++} ++ ++int dump_lldp_neighbors_legacy(Table *table, const char *prefix, int ifindex) { ++ _cleanup_strv_free_ char **buf = NULL; ++ _cleanup_fclose_ FILE *f = NULL; ++ int r; ++ ++ assert(table); ++ assert(prefix); ++ assert(ifindex > 0); ++ ++ r = open_lldp_neighbors_legacy(ifindex, &f); ++ if (r == -ENOENT) ++ return 0; ++ if (r < 0) ++ return r; ++ ++ for (;;) { ++ const char *system_name = NULL, *port_id = NULL, *port_description = NULL; ++ _cleanup_(sd_lldp_neighbor_unrefp) sd_lldp_neighbor *n = NULL; ++ ++ r = next_lldp_neighbor_legacy(f, &n); ++ if (r < 0) ++ return r; ++ if (r == 0) ++ break; ++ ++ (void) sd_lldp_neighbor_get_system_name(n, &system_name); ++ (void) sd_lldp_neighbor_get_port_id_as_string(n, &port_id); ++ (void) sd_lldp_neighbor_get_port_description(n, &port_description); ++ ++ r = strv_extendf(&buf, "%s on port %s%s%s%s", ++ strna(system_name), ++ strna(port_id), ++ isempty(port_description) ? "" : " (", ++ strempty(port_description), ++ isempty(port_description) ? "" : ")"); ++ if (r < 0) ++ return log_oom(); ++ } ++ ++ return dump_list(table, prefix, buf); ++} ++static int link_lldp_status_legacy(int argc, char *argv[], void *userdata) { ++ _cleanup_(sd_netlink_unrefp) sd_netlink *rtnl = NULL; ++ _cleanup_(link_info_array_freep) LinkInfo *links = NULL; ++ _cleanup_(table_unrefp) Table *table = NULL; ++ int r, c, m = 0; ++ uint16_t all = 0; ++ TableCell *cell; ++ ++ r = sd_netlink_open(&rtnl); ++ if (r < 0) ++ return log_error_errno(r, "Failed to connect to netlink: %m"); ++ ++ c = acquire_link_info(NULL, rtnl, argc > 1 ? argv + 1 : NULL, &links); ++ if (c < 0) ++ return c; ++ ++ pager_open(arg_pager_flags); ++ ++ table = table_new("link", ++ "chassis-id", ++ "system-name", ++ "caps", ++ "port-id", ++ "port-description"); ++ if (!table) ++ return log_oom(); ++ ++ if (arg_full) ++ table_set_width(table, 0); ++ ++ table_set_header(table, arg_legend); ++ ++ assert_se(cell = table_get_cell(table, 0, 3)); ++ table_set_minimum_width(table, cell, 11); ++ table_set_ersatz_string(table, TABLE_ERSATZ_DASH); ++ ++ FOREACH_ARRAY(link, links, c) { ++ _cleanup_fclose_ FILE *f = NULL; ++ ++ r = open_lldp_neighbors_legacy(link->ifindex, &f); ++ if (r == -ENOENT) ++ continue; ++ if (r < 0) { ++ log_warning_errno(r, "Failed to open LLDP data for %i, ignoring: %m", link->ifindex); ++ continue; ++ } ++ ++ for (;;) { ++ const char *chassis_id = NULL, *port_id = NULL, *system_name = NULL, *port_description = NULL; ++ _cleanup_(sd_lldp_neighbor_unrefp) sd_lldp_neighbor *n = NULL; ++ _cleanup_free_ char *capabilities = NULL; ++ uint16_t cc; ++ ++ r = next_lldp_neighbor_legacy(f, &n); ++ if (r < 0) { ++ log_warning_errno(r, "Failed to read neighbor data: %m"); ++ break; ++ } ++ if (r == 0) ++ break; ++ ++ (void) sd_lldp_neighbor_get_chassis_id_as_string(n, &chassis_id); ++ (void) sd_lldp_neighbor_get_port_id_as_string(n, &port_id); ++ (void) sd_lldp_neighbor_get_system_name(n, &system_name); ++ (void) sd_lldp_neighbor_get_port_description(n, &port_description); ++ ++ if (sd_lldp_neighbor_get_enabled_capabilities(n, &cc) >= 0) { ++ capabilities = lldp_capabilities_to_string(cc); ++ all |= cc; ++ } ++ ++ r = table_add_many(table, ++ TABLE_STRING, link->name, ++ TABLE_STRING, chassis_id, ++ TABLE_STRING, system_name, ++ TABLE_STRING, capabilities, ++ TABLE_STRING, port_id, ++ TABLE_STRING, port_description); ++ if (r < 0) ++ return table_log_add_error(r); ++ ++ m++; ++ } ++ } ++ ++ r = table_print(table, NULL); ++ if (r < 0) ++ return table_log_print_error(r); ++ ++ if (arg_legend) { ++ lldp_capabilities_legend(all); ++ printf("\n%i neighbors listed.\n", m); ++ } ++ ++ return 0; ++} ++ + int link_lldp_status(int argc, char *argv[], void *userdata) { + _cleanup_(sd_varlink_flush_close_unrefp) sd_varlink *vl = NULL; + _cleanup_(table_unrefp) Table *table = NULL; +@@ -224,8 +416,10 @@ int link_lldp_status(int argc, char *argv[], void *userdata) { + int r; + + r = varlink_connect_networkd(&vl); +- if (r < 0) +- return r; ++ if (r < 0) { ++ log_warning("Varlink connection failed, fallback to D-Bus."); ++ return link_lldp_status_legacy(argc, argv, userdata); ++ } + + r = varlink_call_and_log(vl, "io.systemd.Network.GetLLDPNeighbors", NULL, &reply); + if (r < 0) +diff --git a/src/network/networkctl-lldp.h b/src/network/networkctl-lldp.h +index 3ec6fe76c1184..98288479241b3 100644 +--- a/src/network/networkctl-lldp.h ++++ b/src/network/networkctl-lldp.h +@@ -7,3 +7,4 @@ + + int dump_lldp_neighbors(sd_varlink *vl, Table *table, int ifindex); + int link_lldp_status(int argc, char *argv[], void *userdata); ++int dump_lldp_neighbors_legacy(Table *table, const char *prefix, int ifindex); +diff --git a/src/network/networkctl-status-link.c b/src/network/networkctl-status-link.c +index ae13eba9ae076..fbda880e9c9b2 100644 +--- a/src/network/networkctl-status-link.c ++++ b/src/network/networkctl-status-link.c +@@ -267,7 +267,6 @@ static int link_status_one( + + assert(bus); + assert(rtnl); +- assert(vl); + assert(info); + + (void) sd_network_link_get_operational_state(info->ifindex, &operational_state); +@@ -904,7 +903,7 @@ static int link_status_one( + return table_log_add_error(r); + } + +- r = dump_lldp_neighbors(vl, table, info->ifindex); ++ r = vl ? dump_lldp_neighbors(vl, table, info->ifindex) : dump_lldp_neighbors_legacy(table, "Connected To", info->ifindex); + if (r < 0) + return r; + +@@ -955,8 +954,10 @@ int link_status(int argc, char *argv[], void *userdata) { + log_debug_errno(r, "Failed to open hardware database: %m"); + + r = varlink_connect_networkd(&vl); +- if (r < 0) +- return r; ++ if (r < 0) { ++ log_warning("Varlink connection failed, fallback to D-Bus."); ++ vl = NULL; ++ } + + if (arg_all) + c = acquire_link_info(bus, rtnl, NULL, &links); +diff --git a/src/network/networkctl-util.c b/src/network/networkctl-util.c +index 88620aad536a0..8bda6b1aec98f 100644 +--- a/src/network/networkctl-util.c ++++ b/src/network/networkctl-util.c +@@ -90,7 +90,7 @@ int acquire_bus(sd_bus **ret) { + if (networkd_is_running()) { + r = varlink_connect_networkd(/* ret_varlink = */ NULL); + if (r < 0) +- return r; ++ log_warning("Varlink connection failed, fallback to D-Bus."); + } else + log_warning("systemd-networkd is not running, output might be incomplete."); + +diff --git a/src/systemd/sd-lldp-rx.h b/src/systemd/sd-lldp-rx.h +index 51b9f39482001..b697643a0721c 100644 +--- a/src/systemd/sd-lldp-rx.h ++++ b/src/systemd/sd-lldp-rx.h +@@ -88,6 +88,7 @@ int sd_lldp_neighbor_get_port_description(sd_lldp_neighbor *n, const char **ret) + int sd_lldp_neighbor_get_mud_url(sd_lldp_neighbor *n, const char **ret); + int sd_lldp_neighbor_get_system_capabilities(sd_lldp_neighbor *n, uint16_t *ret); + int sd_lldp_neighbor_get_enabled_capabilities(sd_lldp_neighbor *n, uint16_t *ret); ++int sd_lldp_neighbor_from_raw(sd_lldp_neighbor **ret, const void *raw, size_t raw_size); + + /* Low-level, iterative TLV access. This is for everything else, it iteratively goes through all available TLVs + * (including the ones covered with the calls above), and allows multiple TLVs for the same fields. */ + +From ce39b00868dee5aa80c700185649f41026b88d76 Mon Sep 17 00:00:00 2001 +From: Ryan Wilson +Date: Wed, 4 Dec 2024 16:53:40 -0800 +Subject: [PATCH 3/3] Revert "network/lldp: do not save LLDP neighbors under + /run/systemd" + +This reverts commit 5a0f6adbb2e39914897f404ac97fecebcc2c385a. +--- + src/libsystemd-network/lldp-neighbor.c | 11 ++++ + src/network/networkd-link.c | 7 ++- + src/network/networkd-link.h | 1 + + src/network/networkd-lldp-rx.c | 69 ++++++++++++++++++++++++++ + src/network/networkd-lldp-rx.h | 1 + + src/network/networkd-state-file.c | 2 + + src/network/networkd.c | 3 +- + src/systemd/sd-lldp-rx.h | 1 + + tmpfiles.d/systemd-network.conf | 1 + + 9 files changed, 94 insertions(+), 2 deletions(-) + +diff --git a/src/libsystemd-network/lldp-neighbor.c b/src/libsystemd-network/lldp-neighbor.c +index 4e51a55bd1f64..39864d18f7919 100644 +--- a/src/libsystemd-network/lldp-neighbor.c ++++ b/src/libsystemd-network/lldp-neighbor.c +@@ -377,6 +377,17 @@ int sd_lldp_neighbor_get_destination_address(sd_lldp_neighbor *n, struct ether_a + return 0; + } + ++int sd_lldp_neighbor_get_raw(sd_lldp_neighbor *n, const void **ret, size_t *size) { ++ assert_return(n, -EINVAL); ++ assert_return(ret, -EINVAL); ++ assert_return(size, -EINVAL); ++ ++ *ret = LLDP_NEIGHBOR_RAW(n); ++ *size = n->raw_size; ++ ++ return 0; ++} ++ + int sd_lldp_neighbor_get_chassis_id(sd_lldp_neighbor *n, uint8_t *type, const void **ret, size_t *size) { + assert_return(n, -EINVAL); + assert_return(type, -EINVAL); +diff --git a/src/network/networkd-link.c b/src/network/networkd-link.c +index 3f816d7fa25c4..d0b37bd65d074 100644 +--- a/src/network/networkd-link.c ++++ b/src/network/networkd-link.c +@@ -276,6 +276,7 @@ static Link *link_free(Link *link) { + free(link->driver); + + unlink_and_free(link->lease_file); ++ unlink_and_free(link->lldp_file); + unlink_and_free(link->state_file); + + sd_device_unref(link->dev); +@@ -2663,7 +2664,7 @@ static Link *link_drop_or_unref(Link *link) { + DEFINE_TRIVIAL_CLEANUP_FUNC(Link*, link_drop_or_unref); + + static int link_new(Manager *manager, sd_netlink_message *message, Link **ret) { +- _cleanup_free_ char *ifname = NULL, *kind = NULL, *state_file = NULL, *lease_file = NULL; ++ _cleanup_free_ char *ifname = NULL, *kind = NULL, *state_file = NULL, *lease_file = NULL, *lldp_file = NULL; + _cleanup_(link_drop_or_unrefp) Link *link = NULL; + unsigned short iftype; + int r, ifindex; +@@ -2704,6 +2705,9 @@ static int link_new(Manager *manager, sd_netlink_message *message, Link **ret) { + + if (asprintf(&lease_file, "/run/systemd/netif/leases/%d", ifindex) < 0) + return log_oom_debug(); ++ ++ if (asprintf(&lldp_file, "/run/systemd/netif/lldp/%d", ifindex) < 0) ++ return log_oom_debug(); + } + + link = new(Link, 1); +@@ -2726,6 +2730,7 @@ static int link_new(Manager *manager, sd_netlink_message *message, Link **ret) { + + .state_file = TAKE_PTR(state_file), + .lease_file = TAKE_PTR(lease_file), ++ .lldp_file = TAKE_PTR(lldp_file), + + .n_dns = UINT_MAX, + .dns_default_route = -1, +diff --git a/src/network/networkd-link.h b/src/network/networkd-link.h +index 113217cdb6ad8..229ce976bc2b8 100644 +--- a/src/network/networkd-link.h ++++ b/src/network/networkd-link.h +@@ -194,6 +194,7 @@ typedef struct Link { + + /* This is about LLDP reception */ + sd_lldp_rx *lldp_rx; ++ char *lldp_file; + + /* This is about LLDP transmission */ + sd_lldp_tx *lldp_tx; +diff --git a/src/network/networkd-lldp-rx.c b/src/network/networkd-lldp-rx.c +index 6ba198282e7a1..853e0a0aceb67 100644 +--- a/src/network/networkd-lldp-rx.c ++++ b/src/network/networkd-lldp-rx.c +@@ -52,6 +52,8 @@ static void lldp_rx_handler(sd_lldp_rx *lldp_rx, sd_lldp_rx_event_t event, sd_ll + Link *link = ASSERT_PTR(userdata); + int r; + ++ (void) link_lldp_save(link); ++ + if (link->lldp_tx && event == SD_LLDP_RX_EVENT_ADDED) { + /* If we received information about a new neighbor, restart the LLDP "fast" logic */ + +@@ -102,3 +104,70 @@ int link_lldp_rx_configure(Link *link) { + + return 0; + } ++ ++int link_lldp_save(Link *link) { ++ _cleanup_(unlink_and_freep) char *temp_path = NULL; ++ _cleanup_fclose_ FILE *f = NULL; ++ sd_lldp_neighbor **l = NULL; ++ int n = 0, r, i; ++ ++ assert(link); ++ ++ if (isempty(link->lldp_file)) ++ return 0; /* Do not update state file when running in test mode. */ ++ ++ if (!link->lldp_rx) { ++ (void) unlink(link->lldp_file); ++ return 0; ++ } ++ ++ r = sd_lldp_rx_get_neighbors(link->lldp_rx, &l); ++ if (r < 0) ++ return r; ++ if (r == 0) { ++ (void) unlink(link->lldp_file); ++ return 0; ++ } ++ ++ n = r; ++ ++ r = fopen_temporary(link->lldp_file, &f, &temp_path); ++ if (r < 0) ++ goto finish; ++ ++ (void) fchmod(fileno(f), 0644); ++ ++ for (i = 0; i < n; i++) { ++ const void *p; ++ le64_t u; ++ size_t sz; ++ ++ r = sd_lldp_neighbor_get_raw(l[i], &p, &sz); ++ if (r < 0) ++ goto finish; ++ ++ u = htole64(sz); ++ fwrite(&u, 1, sizeof(u), f); ++ fwrite(p, 1, sz, f); ++ } ++ ++ r = fflush_and_check(f); ++ if (r < 0) ++ goto finish; ++ ++ r = conservative_rename(temp_path, link->lldp_file); ++ if (r < 0) ++ goto finish; ++ ++finish: ++ if (r < 0) ++ log_link_error_errno(link, r, "Failed to save LLDP data to %s: %m", link->lldp_file); ++ ++ if (l) { ++ for (i = 0; i < n; i++) ++ sd_lldp_neighbor_unref(l[i]); ++ free(l); ++ } ++ ++ return r; ++} +diff --git a/src/network/networkd-lldp-rx.h b/src/network/networkd-lldp-rx.h +index 75c9f8ca8602f..22f6602bd0ffd 100644 +--- a/src/network/networkd-lldp-rx.h ++++ b/src/network/networkd-lldp-rx.h +@@ -14,6 +14,7 @@ typedef enum LLDPMode { + } LLDPMode; + + int link_lldp_rx_configure(Link *link); ++int link_lldp_save(Link *link); + + const char* lldp_mode_to_string(LLDPMode m) _const_; + LLDPMode lldp_mode_from_string(const char *s) _pure_; +diff --git a/src/network/networkd-state-file.c b/src/network/networkd-state-file.c +index da917dd897241..2e32fbc300c10 100644 +--- a/src/network/networkd-state-file.c ++++ b/src/network/networkd-state-file.c +@@ -714,6 +714,8 @@ static int link_save(Link *link) { + if (link->state == LINK_STATE_LINGER) + return 0; + ++ link_lldp_save(link); ++ + admin_state = ASSERT_PTR(link_state_to_string(link->state)); + oper_state = ASSERT_PTR(link_operstate_to_string(link->operstate)); + carrier_state = ASSERT_PTR(link_carrier_state_to_string(link->carrier_state)); +diff --git a/src/network/networkd.c b/src/network/networkd.c +index 883f16d81b257..12edb685839c9 100644 +--- a/src/network/networkd.c ++++ b/src/network/networkd.c +@@ -75,7 +75,8 @@ static int run(int argc, char *argv[]) { + * to support old kernels not supporting AmbientCapabilities=. */ + FOREACH_STRING(p, + "/run/systemd/netif/links/", +- "/run/systemd/netif/leases/") { ++ "/run/systemd/netif/leases/", ++ "/run/systemd/netif/lldp/") { + r = mkdir_safe_label(p, 0755, UID_INVALID, GID_INVALID, MKDIR_WARN_MODE); + if (r < 0) + log_warning_errno(r, "Could not create directory '%s': %m", p); +diff --git a/src/systemd/sd-lldp-rx.h b/src/systemd/sd-lldp-rx.h +index b697643a0721c..fedf9956cf8da 100644 +--- a/src/systemd/sd-lldp-rx.h ++++ b/src/systemd/sd-lldp-rx.h +@@ -75,6 +75,7 @@ sd_lldp_neighbor *sd_lldp_neighbor_unref(sd_lldp_neighbor *n); + int sd_lldp_neighbor_get_source_address(sd_lldp_neighbor *n, struct ether_addr* address); + int sd_lldp_neighbor_get_destination_address(sd_lldp_neighbor *n, struct ether_addr* address); + int sd_lldp_neighbor_get_timestamp(sd_lldp_neighbor *n, clockid_t clock, uint64_t *ret); ++int sd_lldp_neighbor_get_raw(sd_lldp_neighbor *n, const void **ret, size_t *size); + + /* High-level, direct, parsed out field access. These fields exist at most once, hence may be queried directly. */ + int sd_lldp_neighbor_get_chassis_id(sd_lldp_neighbor *n, uint8_t *type, const void **ret, size_t *size); +diff --git a/tmpfiles.d/systemd-network.conf b/tmpfiles.d/systemd-network.conf +index 75b61b7d07279..881937d456004 100644 +--- a/tmpfiles.d/systemd-network.conf ++++ b/tmpfiles.d/systemd-network.conf +@@ -10,4 +10,5 @@ + d$ /run/systemd/netif 0755 systemd-network systemd-network - + d$ /run/systemd/netif/links 0755 systemd-network systemd-network - + d$ /run/systemd/netif/leases 0755 systemd-network systemd-network - ++d$ /run/systemd/netif/lldp 0755 systemd-network systemd-network - + d$ /var/lib/systemd/network 0755 systemd-network systemd-network - diff --git a/changelog b/changelog index fb6584d..216ab62 100644 --- a/changelog +++ b/changelog @@ -1,3 +1,156 @@ +* Sun Jan 12 2025 Zbigniew Jędrzejewski-Szmek - 257.2-6 +- Rebuilt for the bin-sbin merge (2nd attempt) + +* Fri Jan 10 2025 Zbigniew Jędrzejewski-Szmek - 257.2-4 +- Revert use of PrivateTmp=disconnected (rhbz#2334015, + https://github.com/coreos/fedora-coreos-tracker/issues/1857) + +* Wed Jan 08 2025 Zbigniew Jędrzejewski-Szmek - 257.2-1 +- Version 257.2 +- Fixes for assertion crashes and memory access issues in pid1 and systemd- + machined, and other fixes for systemd-repart, systemd-resolved, systemd- + stdio-bridge, systemctl, journalctl, sd-device, hibernation, and the + hardware database. + +* Tue Jan 07 2025 Yu Watanabe - 257.1-7 +- Replace 'udevadm hwdb' with systemd-hwdb + +* Tue Jan 07 2025 Zbigniew Jędrzejewski-Szmek - 257.1-6 +- Rename source .abignore file + +* Fri Dec 20 2024 Daan De Meyer - 257.1-2 +- Re-enable upstream behaviour of systemd-tmpfiles --purge + +* Fri Dec 20 2024 Zbigniew Jędrzejewski-Szmek - 257.1-1 +- Version 257.1 +- A bunch of post-release fixes, incl. for systemd-resolved, tpm2 support, + systemd-networkd, systemd-logind, journalct. +- Should fix rhbz#2325780. + +* Sun Dec 15 2024 Yu Watanabe - 257-3 +- Add patch for test-time-util + +* Sun Dec 15 2024 Yu Watanabe - 257-2 +- sysusers: support new ! line flag for creating fully locked accounts + +* Tue Dec 10 2024 Zbigniew Jędrzejewski-Szmek - 257-1 +- Version 257 +- A bunch of small fixes in various components: systemd itself, systemd- + cryptenroll, sd-varlink, sd-boot, documentation, tests +- Includes an update of the hardware database + +* Thu Dec 05 2024 Zbigniew Jędrzejewski-Szmek - 257~rc3-5 +- Enable slow tests during build + +* Tue Dec 03 2024 Zbigniew Jędrzejewski-Szmek - 257~rc3-3 +- Recommend qemu-kvm-core instead of qemu-kvm (rhbz#2329979) + +* Fri Nov 29 2024 Yu Watanabe - 257~rc3-2 +- Update tmpfiles --destroy-data patch + +* Wed Nov 27 2024 Zbigniew Jędrzejewski-Szmek - 257~rc3-1 +- Version 257~rc3 +- A bunch of small fixes here and there: virtualization detection, udev, + systemd-networked, pid1. +- Includes a hardware database update. + +* Tue Nov 26 2024 Zbigniew Jędrzejewski-Szmek - 257~rc2-4 +- Make systemd-network-generator co-owned by -udev and -networkd + (rhbz#2328723) + +* Tue Nov 19 2024 Zbigniew Jędrzejewski-Szmek - 257~rc2-3 +- Pull in qemu from systemd-container + +* Fri Nov 15 2024 Zbigniew Jędrzejewski-Szmek - 257~rc2-2 +- Change sysusers u! lines to u because we don't have support in rpm + +* Fri Nov 15 2024 Zbigniew Jędrzejewski-Szmek - 257~rc2-1 +- Version 257~rc2 +- Changes in systemd-measure, systemd-networkd, documentation, systemd- + sysupdated, systemd-sbsign, systemd-boot, systemd-stub, systemd-nspawn, + run0, ukify +- Hardware database update + +* Fri Nov 15 2024 Zbigniew Jędrzejewski-Szmek - 257~rc1-3 +- Disable freezing of user sessions (rhbz#2321268) + +* Thu Nov 07 2024 Zbigniew Jędrzejewski-Szmek - 257~rc1-1 +- Version 257~rc1 + +* Thu Nov 07 2024 Daan De Meyer - 256.7-7 +- Use %%posttrans instead of %%postun to restart services + +* Thu Nov 07 2024 Yaakov Selkowitz - 256.7-6 +- Disable OpenSSL v3 ENGINE on RHEL + +* Tue Nov 05 2024 Daan De Meyer - 256.7-4 +- Backport user manager reexec changes + +* Tue Nov 05 2024 David Tardon - 256.7-3 +- Use %%systemd_preun in systemd-resolved + +* Thu Oct 24 2024 Yu Watanabe - 256.7-2 +- test_sysusers_defined: support new ! line flag for creating fully locked + accounts + +* Fri Oct 11 2024 Zbigniew Jędrzejewski-Szmek - 256.7-1 +- Version 256.7 +- Various small fixes in many components +- Documentation updates + +* Tue Sep 24 2024 Zbigniew Jędrzejewski-Szmek - 256.6-3 +- Move yum/dnf protection removal config file under /usr + +* Thu Sep 12 2024 Matteo Croce - 256.6-1 +- Version 256.6 + +* Thu Aug 29 2024 Daan De Meyer - 256.5-6 +- Always build ukify package + +* Wed Aug 28 2024 Daan De Meyer - 256.5-5 +- Do not use patch to modify systemd-user pam config file + +* Tue Aug 27 2024 Daan De Meyer - 256.5-3 +- Only make python3-pillow Recommends on Fedora + +* Sat Aug 24 2024 Davide Cavalca - 256.5-2 +- Do not require grubby on CentOS Stream 9 + +* Tue Aug 20 2024 Zbigniew Jędrzejewski-Szmek - 256.5-1 +- Version 256.5 +- Includes the patches for the kernel change with kernel threads in leaf + cgroups (https://github.com/systemd/systemd/pull/33885) +- Various smaller fixes + +* Tue Aug 20 2024 Zbigniew Jędrzejewski-Szmek - 256.4-4 +- Disable integration of userdb in sshd + +* Mon Jul 29 2024 Daan De Meyer - 256.4-3 +- Backport patch to only read /proc/cmdline when not in container + +* Mon Jul 29 2024 Daan De Meyer - 256.4-2 +- Backport upstream patch to try more initrd variants in + 90-loaderentry.install + +* Thu Jul 25 2024 Zbigniew Jędrzejewski-Szmek - 256.4-1 +- Version 256.4 +- Hardware db update +- Minor fixes for systemd-udevd and varlink protocol + +* Tue Jul 23 2024 Daan De Meyer - 256.3-3 +- Update tmpfiles --destroy-data patch + +* Tue Jul 23 2024 Zbigniew Jędrzejewski-Szmek - 256.3-1 +- Version 256.3 +- A bunch of fixes for systemd (pid1) +- Various upgrades related to running tests in mkosi + +* Sat Jul 20 2024 Daan De Meyer - 256.2-17 +- Simplify BFQ scheduler enablement + +* Sat Jul 20 2024 Fedora Release Engineering - 256.2-16 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_41_Mass_Rebuild + * Wed Jul 17 2024 Zbigniew Jędrzejewski-Szmek - 256.2-9 - Backport udma buffer access patch (rhbz#2298422) diff --git a/libabigail.abignore b/libabigail.abignore new file mode 100644 index 0000000..6a33b88 --- /dev/null +++ b/libabigail.abignore @@ -0,0 +1,3 @@ +[suppress_file] +# Those shared objects are private to systemd +file_name_regexp=libsystemd-(shared|core)-.*.so diff --git a/plans/upstream.fmf b/plans/upstream.fmf new file mode 100644 index 0000000..fd348ad --- /dev/null +++ b/plans/upstream.fmf @@ -0,0 +1,16 @@ +summary: systemd upstream test suite +discover: + how: fmf + dist-git-source: true + dist-git-install-builddeps: false +prepare: + - name: systemd + how: install + exclude: + - systemd-standalone-.* +execute: + how: tmt +provision: + hardware: + virtualization: + is-supported: true diff --git a/sources b/sources index db248bb..b8843e6 100644 --- a/sources +++ b/sources @@ -1 +1 @@ -SHA512 (systemd-256.7.tar.gz) = 2ff3805a7d97780a716b23ddeea3722a85aba6326ecee527e53e9d35510a0ffa5ec0bf0cdbf8f3409bb9c6832406916f63eb7e8305db5f67c284e5590c642422 +SHA512 (systemd-257.2.tar.gz) = 4f47fcd9a4148101ee7b85cf5908a04ec9e025dc7a5a2e8e61c05439cfd427851b6d356bb96a0dfae55566bbf6d3c93a13251d220840c09296e94f80bd4a5945 diff --git a/split-files.py b/split-files.py index 51400fd..b08c2bd 100644 --- a/split-files.py +++ b/split-files.py @@ -154,6 +154,9 @@ for file in files(buildroot): and os.path.exists(f'./{n}.example')): o = outputs['networkd-defaults'] + # Files that are "consumed" by systemd-networkd go into the -networkd + # subpackage. As a special case, network-generator is co-owned also by + # the -udev subpackage because systemd-udevd reads .link files. elif re.search(r'''/usr/lib/systemd/network/.*\.network| networkd| networkctl| @@ -164,6 +167,8 @@ for file in files(buildroot): systemd\.netdev ''', n, re.X): o = outputs['networkd'] + elif 'network-generator' in n: + o = (outputs['networkd'], outputs['udev']) elif '.so.' in n: o = outputs['libs'] @@ -255,7 +260,10 @@ for file in files(buildroot): suffix = '*' if '/man/' in n else '' - print(f'{prefix}{n}{suffix}', file=o) + if not isinstance(o, tuple): + o = (o,) + for file in o: + print(f'{prefix}{n}{suffix}', file=file) if [print(f'ERROR: no file names were written to {o.name}') for name, o in outputs.items() diff --git a/systemd.spec b/systemd.spec index 3033ea4..7c45317 100644 --- a/systemd.spec +++ b/systemd.spec @@ -32,6 +32,9 @@ # Build from git main %bcond upstream 0 +# Build with OBS-specific quirks +%bcond obs 0 + # When bootstrap, libcryptsetup is disabled # but auto-features causes many options to be turned on # that depend on libcryptsetup (e.g. libcryptsetup-plugins, homed) @@ -43,8 +46,14 @@ Name: systemd Url: https://systemd.io # Allow users to specify the version and release when building the rpm by # setting the %%version_override and %%release_override macros. -Version: %{?version_override}%{!?version_override:256.7} -Release: %{?release_override}%{!?release_override:1.13}%{?dist} +# But don't do that on OBS, otherwise the version subst fails, and will be +# like 257-123-gabcd257.1 instead of 257-123-gabcd +%if %{without obs} +Version: %{?version_override}%{!?version_override:257.2} +%else +Version: %{?version_override}%{!?version_override:%(cat meson.version)} +%endif +Release: %{?release_override}%{!?release_override:1.1}%{?dist} %global stable %(c="%version"; [ "$c" = "${c#*.*}" ]; echo $?) @@ -74,7 +83,7 @@ Source9: systemd-journal-gatewayd.xml Source10: 20-yama-ptrace.conf Source11: systemd-udev-trigger-no-reload.conf # https://fedoraproject.org/wiki/How_to_filter_libabigail_reports -Source13: .abignore +Source13: libabigail.abignore Source14: 10-oomd-defaults.conf Source15: 10-oomd-per-slice-defaults.conf @@ -91,50 +100,32 @@ Source25: 98-default-mac-none.link Source26: systemd-user -%if 0 -GIT_DIR=../../src/systemd/.git git format-patch-ab --no-signature -M -N v235..v235-stable -i=1; for j in 00*patch; do printf "Patch%04d: %s\n" $i $j; i=$((i+1));done|xclip -GIT_DIR=../../src/systemd/.git git diffab -M v233..master@{2017-06-15} -- hwdb/[67]* hwdb/parse_hwdb.py >hwdb.patch -%endif - -# Backports of patches from upstream (0000–0499) -# -# Any patches which are "in preparation" upstream should be listed here, rather -# than in the next section. Packit CI will drop any patches in this range before -# applying upstream pull requests. - %if 0%{?fedora} < 40 && 0%{?rhel} < 10 # Work-around for dracut issue: run generators directly when we are in initrd # https://bugzilla.redhat.com/show_bug.cgi?id=2164404 # Drop when dracut-060 is available. -Patch0010: https://github.com/systemd/systemd/pull/26494.patch +Patch: https://github.com/systemd/systemd/pull/26494.patch %endif %if %{without upstream} +# Temporarily drop use of PrivateTmp=disconnected. This is causing failures +# in various places: +# https://bugzilla.redhat.com/show_bug.cgi?id=2334015 +# https://github.com/coreos/fedora-coreos-tracker/issues/1857 +Patch: 0001-Revert-units-use-PrivateTmp-disconnected-instead-of-.patch -# Requested in https://bugzilla.redhat.com/show_bug.cgi?id=2298422 -Patch0011: https://github.com/systemd/systemd/pull/33738.patch - -# Various logging improvements -Patch0013: https://github.com/systemd/systemd/pull/34728.patch - -# Make sure bus_connect_transport_systemd() actually connects to the private manager bus -Patch0014: https://github.com/systemd/systemd/pull/34686.patch - -# Simplify user manager upgrades -Patch0015: https://github.com/systemd/systemd/pull/34707.patch - -# core/device: ignore ID_PROCESSING udev property on enumerate -Patch0016: https://github.com/systemd/systemd/pull/35332.patch - -# Soft-disable tmpfiles --purge until a good use case comes up. -Patch0492: 0001-tmpfiles-make-purge-hard-to-mis-use.patch - -%endif +# Backport of sysusers audit support for +# https://fedoraproject.org/wiki/Changes/RPMSuportForSystemdSysusers. +Patch: 0001-update-utmp-do-not-give-up-if-the-first-attempt-at-c.patch +Patch: 0002-sysusers-emit-audit-events-for-user-and-group-creati.patch # Those are downstream-only patches, but we don't want them in packit builds: # https://bugzilla.redhat.com/show_bug.cgi?id=2251843 -Patch0491: https://github.com/systemd/systemd/pull/30846.patch +Patch: https://github.com/systemd/systemd/pull/30846.patch + +# Backport various fmf fixes to allow running the integration tests in Fedora CI. +Patch: https://github.com/systemd/systemd/pull/35938.patch +%endif # Meta specific backports (900-1000) @@ -142,34 +133,16 @@ Patch0491: https://github.com/systemd/systemd/pull/30846.patch %if %{without upstream} -# network: Make qdisc reconfigurable -Patch0900: https://github.com/systemd/systemd/pull/34543.patch - -# network: Add support for multiq qdisc -Patch0901: https://github.com/systemd/systemd/pull/34251.patch - -# core: Add support for PrivateUsers=identity -Patch0902: https://github.com/systemd/systemd/pull/34400.patch - -# bus-util: Return ENOMEDIUM if XDG_RUNTIME_DIR is unset -Patch0903: https://github.com/systemd/systemd/pull/34851.patch - # pam_systemd: Make pam_systemd 256 backwards compatible to logind 255 -Patch0904: 0001-pam_systemd-Make-pam_systemd-256-backwards-compatibl.patch +Patch: 0001-pam_systemd-Make-pam_systemd-256-backwards-compatibl.patch -# networkctl: Make networkctl lldp output backwards compatible with 255 -Patch0905: 0001-networkctl-Make-networkctl-lldp-output-backwards-com.patch - -# networkctl: Make lldp/status backwards compatible with 255 over dbus -Patch0906: 0001-networkctl-Make-lldp-status-backwards-compatible-wit.patch - -# Revert "network/lldp: do not save LLDP neighbors under /run/systemd" -Patch0907: 0001-Revert-network-lldp-do-not-save-LLDP-neighbors-under.patch +# Revert breaking changes to unstable systemd-networkd lldp interface +Patch: https://github.com/systemd/systemd/pull/36050.patch %endif # bump networkd netlink timeout to infinity -Patch0908: FB_only_bump_netlink_timeout_to_infinity.patch +Patch: FB_only_bump_netlink_timeout_to_infinity.patch # Meta specific patches for builds from git main (1001-1100) # TODO: These should be removed once they are either merged into git main @@ -177,10 +150,9 @@ Patch0908: FB_only_bump_netlink_timeout_to_infinity.patch %if %{with upstream} # Temporary workaround: PrivateUsers=full implies DelegateNamespaces=yes -Patch1003: 0001-Temporary-workaround-PrivateUsers-full-implies-Deleg.patch +Patch: 0001-Temporary-workaround-PrivateUsers-full-implies-Deleg.patch %endif - %endif %ifarch %{ix86} x86_64 aarch64 riscv64 @@ -228,7 +200,7 @@ BuildRequires: libcurl-devel BuildRequires: kmod-devel BuildRequires: elfutils-devel BuildRequires: openssl-devel -%if 0%{?fedora} >= 41 || 0%{?rhel} >= 11 +%if 0%{?fedora} >= 41 BuildRequires: openssl-devel-engine %endif %if %{with gnutls} @@ -264,7 +236,6 @@ BuildRequires: python3dist(lxml) BuildRequires: python3dist(pefile) %if 0%{?fedora} BuildRequires: python3dist(pillow) -BuildRequires: python3dist(pytest-flakes) %endif BuildRequires: python3dist(pytest) %if 0%{?want_bootloader} @@ -298,6 +269,10 @@ BuildRequires: xen-devel %endif %endif +%if %{with obs} +BuildRequires: pesign-obs-integration +%endif + Requires(post): coreutils Requires(post): grep # systemd-machine-id-setup requires libssl @@ -573,6 +548,7 @@ with a command line, and possibly PCR measurements and other metadata, into a Unified Kernel Image (UKI). %if 0%{?want_bootloader} +%if %{without obs} %package boot-unsigned Summary: UEFI boot manager (unsigned version) @@ -593,6 +569,27 @@ line. systemd-boot supports systems with UEFI firmware only. This package contains the unsigned version. Install systemd-boot instead to get the version that works with Secure Boot. +%else +%package boot +Summary: UEFI boot manager (signed version) + +Provides: systemd-boot-signed-%{efi_arch} = %version-%release +Provides: systemd-boot = %version-%release +Provides: systemd-boot%{_isa} = %version-%release +# A provides with just the version, no release or dist, used to build systemd-boot +Provides: version(systemd-boot-signed) = %version +Provides: version(systemd-boot-signed)%{_isa} = %version + +# self-obsoletes to install both packages after split of systemd-boot +Obsoletes: systemd-udev < 252.2^ + +%description boot +systemd-boot (short: sd-boot) is a simple UEFI boot manager. It provides a +graphical menu to select the entry to boot and an editor for the kernel command +line. systemd-boot supports systems with UEFI firmware only. + +This package contains the signed version. +%endif %endif %package container @@ -602,7 +599,13 @@ Requires: %{name}%{_isa} = %{version}-%{release} Requires(post): systemd%{_isa} = %{version}-%{release} Requires(preun): systemd%{_isa} = %{version}-%{release} Requires(postun): systemd%{_isa} = %{version}-%{release} -# obsolete parent package so that dnf will install new subpackage on upgrade (#1260394) +# For systemd-vmspawn which uses qemu: +Recommends: qemu-kvm-core +%if 0%{?fedora} +Recommends: qemu-device-display-virtio-gpu +Recommends: qemu-device-display-virtio-vga +%endif +# Obsolete parent package so that dnf will install new subpackage on upgrade (#1260394) Obsoletes: %{name} < 229-5 # Bias the system towards libcurl-minimal if nothing pulls in full libcurl (#1997040) Suggests: libcurl-minimal @@ -743,25 +746,6 @@ library or other libraries from systemd-libs. This package conflicts with the main systemd package and is meant for use in exitrds. %prep -%if 0%{?facebook} && %{with upstream} -# For systemd-cd (https://gitlab.com/CentOS/Hyperscale/releng/systemd-releng) builds, -# we want to allow certain patches to accelerate internal projects. - -# Call autosetup but disable patch management, we'll do that with autopatch below -%if %{defined branch} -%autosetup -N -n %{name}-%{branch} -%elif %{defined commit} -%autosetup -N -n %{name}-%{commit} -%else -%autosetup -N -n %{name}-%{version_no_tilde} -%endif - -# Now only install only patches in the specific Meta-only range -%autopatch -m 1001 -M 1100 -p1 - -%else - -# Use standard autosetup with automatic patch management %if %{defined branch} %autosetup -n %{name}-%{branch} -p1 %elif %{defined commit} @@ -770,7 +754,9 @@ main systemd package and is meant for use in exitrds. %autosetup -n %{name}-%{version_no_tilde} -p1 %endif -%endif +# Disable user lockdown until rpm implements it natively. +# https://github.com/rpm-software-management/rpm/issues/3450 +sed -r -i 's/^u!/u/' sysusers.d/*.conf* %build %global ntpvendor %(source /etc/os-release; echo ${ID}) @@ -799,7 +785,8 @@ VMLINUX_H_PATH=$(%python3 -c '%find_vmlinux_h') %endif CONFIGURE_OPTS=( - -Dmode=%[%{with upstream}?"developer":"release"] + -Dmode=release + -Dslow-tests=true -Dsysvinit-path=/etc/rc.d/init.d -Drc-local=/etc/rc.d/rc.local -Dntp-servers='0.%{ntpvendor}.pool.ntp.org 1.%{ntpvendor}.pool.ntp.org 2.%{ntpvendor}.pool.ntp.org 3.%{ntpvendor}.pool.ntp.org' @@ -910,6 +897,11 @@ CONFIGURE_OPTS=( # considering that that support is untested, let's not do this now. -Dbootloader=%[%{?want_bootloader}?"enabled":"disabled"] -Dukify=enabled +%if 0%{?want_bootloader} && %{with obs} + -Dsbat-distro-url=https://github.com/systemd/systemd + -Dsbat-distro=upstream + -Dsbat-distro-summary='Upstream build from git' +%endif ) %if 0%{?facebook} @@ -1050,7 +1042,7 @@ install -Dm0644 -t %{buildroot}%{_pkgdocdir}/ %{SOURCE10} # https://bugzilla.redhat.com/show_bug.cgi?id=1378974 install -Dm0644 -t %{buildroot}%{system_unit_dir}/systemd-udev-trigger.service.d/ %{SOURCE11} -install -Dm0644 -t %{buildroot}%{_prefix}/lib/systemd/ %{SOURCE13} +install -Dm0644 %{SOURCE13} %{buildroot}%{_prefix}/lib/systemd/.abignore # systemd-oomd default configuration install -Dm0644 -t %{buildroot}%{_prefix}/lib/systemd/oomd.conf.d/ %{SOURCE14} @@ -1098,9 +1090,13 @@ mv -v %{buildroot}/usr/sbin/* %{buildroot}%{_bindir}/ %endif %if 0%{?fedora} >= 41 +%if %{without upstream} # This requires https://pagure.io/setup/pull-request/50 # and https://src.fedoraproject.org/rpms/setup/pull-request/10. +# We skip this on upstream builds so that new users and groups +# can be added without breaking the build. %{python3} %{SOURCE4} /usr/lib/sysusers.d/20-setup-{users,groups}.conf %{buildroot}/usr/lib/sysusers.d/basic.conf +%endif rm %{buildroot}/usr/lib/sysusers.d/basic.conf %endif @@ -1113,11 +1109,25 @@ mv %{buildroot}/usr/lib/tmpfiles.d/20-systemd-userdb.conf{,.example} install -m 0644 -t %{buildroot}%{_prefix}/lib/pam.d/ %{SOURCE26} +# Disable freezing of user sessions while we're working out the details. +mkdir -p %{buildroot}/usr/lib/systemd/system/service.d/ +cat >>%{buildroot}/usr/lib/systemd/system/service.d/50-keep-warm.conf </dev/null +systemd-hwdb update &>/dev/null %systemd_post %udev_services @@ -1296,10 +1308,8 @@ fi %systemd_post systemd-resolved.service %preun resolved +%systemd_preun systemd-resolved.service if [ $1 -eq 0 ] ; then - systemctl disable --quiet \ - systemd-resolved.service \ - >/dev/null || : if [ -L /etc/resolv.conf ] && \ realpath /etc/resolv.conf | grep ^/run/systemd/resolve/; then rm -f /etc/resolv.conf # no longer useful @@ -1386,7 +1396,11 @@ fi %files ukify -f .file-list-ukify %if 0%{?want_bootloader} +%if %{without obs} %files boot-unsigned -f .file-list-boot +%else +%files boot -f .file-list-boot +%endif %endif %files container -f .file-list-container diff --git a/sysusers.generate-pre.sh b/sysusers.generate-pre.sh index 4a87d53..944abff 100755 --- a/sysusers.generate-pre.sh +++ b/sysusers.generate-pre.sh @@ -69,7 +69,7 @@ parse() { [ -z "$line" ] && continue eval "arr=( $line )" case "${arr[0]}" in - ('u') + ('u'|'u!') if [[ "${arr[2]}" == *":"* ]]; then user "${arr[1]}" "${arr[2]%:*}" "${arr[3]}" "${arr[2]#*:}" "${arr[4]}" "${arr[5]}" else diff --git a/sysusers.prov b/sysusers.prov index f12e929..7b3d704 100755 --- a/sysusers.prov +++ b/sysusers.prov @@ -42,7 +42,7 @@ parse() { [ -z "$line" ] && continue set -- $line case "$1" in - ('u') + ('u'|'u!') process_u "$2" "$3" ;; ('g') diff --git a/test_sysusers_defined.py b/test_sysusers_defined.py index 2754578..6f04f15 100755 --- a/test_sysusers_defined.py +++ b/test_sysusers_defined.py @@ -11,7 +11,7 @@ def parse_sysusers_file(filename): continue words = line.split() match words[0]: - case 'u': + case 'u'|'u!': users.add(words[1]) case 'g': groups.add(words[1]) diff --git a/tests/tests-reboot.yml b/tests/tests-reboot.yml deleted file mode 100644 index 94ea8a5..0000000 --- a/tests/tests-reboot.yml +++ /dev/null @@ -1,50 +0,0 @@ ---- -- hosts: localhost - vars: - - artifacts: "{{ lookup('env', 'TEST_ARTIFACTS')|default('./artifacts', true) }}" - tags: - - classic - tasks: - # switch SELinux to permissive mode - - name: Get default kernel - command: "grubby --default-kernel" - register: default_kernel - - debug: msg="{{ default_kernel.stdout }}" - - name: Set permissive mode - command: "grubby --args=enforcing=0 --update-kernel {{ default_kernel.stdout }}" - - - name: reboot - block: - - name: restart host - shell: sleep 2 && shutdown -r now "Ansible updates triggered" - async: 1 - poll: 0 - ignore_errors: true - - - name: wait for host to come back - wait_for_connection: - delay: 10 - timeout: 300 - - - name: Re-create /tmp/artifacts - command: mkdir /tmp/artifacts - - - name: Gather SELinux denials since boot - shell: | - result=pass - dmesg | grep -i -e type=1300 -e type=1400 > /tmp/avc.log && result=fail - ausearch -m avc -m selinux_err -m user_avc -ts boot &>> /tmp/avc.log - grep -q '' /tmp/avc.log || result=fail - echo -e "\nresults:\n- test: reboot and collect AVC\n result: $result\n logs:\n - avc.log\n\n" > /tmp/results.yml - ( [ $result = "pass" ] && echo PASS test-reboot || echo FAIL test-reboot ) > /tmp/test.log - - always: - - name: Pull out the artifacts - fetch: - dest: "{{ artifacts }}/" - src: "{{ item }}" - flat: yes - with_items: - - /tmp/test.log - - /tmp/avc.log - - /tmp/results.yml