#34 upgrade to 257.2
Opened 17 days ago by teknoraver. Modified 15 days ago
rpms/ teknoraver/systemd c10s-sig-hyperscale  into  c10s-sig-hyperscale

Rebuilt for the bin-sbin merge (2nd attempt)
Zbigniew Jędrzejewski-Szmek • 19 days ago  
Rebuilt for the bin-sbin merge (2nd attempt)
Zbigniew Jędrzejewski-Szmek • 19 days ago  
Revert use of PrivateTmp=disconnected
Zbigniew Jędrzejewski-Szmek • 21 days ago  
Drop patch numbers
Zbigniew Jędrzejewski-Szmek • 21 days ago  
Version 257.2
Zbigniew Jędrzejewski-Szmek • 23 days ago  
Add bcond for OBS-specific quirks
Luca Boccassi • 23 days ago  
spec: drop trailing whitespace
Luca Boccassi • 23 days ago  
Rename source .abignore file
Zbigniew Jędrzejewski-Szmek • 24 days ago  
@@ -0,0 +1,240 @@ 

+ From 1ef7ac52b34cef84ad5d4103bdaab4a2578bad9e Mon Sep 17 00:00:00 2001

+ From: Ryan Wilson <ryantimwilson@meta4.com>

+ 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 4e51a55bd1..39864d18f7 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 3c042e6c18..6a740b186a 100644

+ --- a/src/network/networkd-link.c

+ +++ b/src/network/networkd-link.c

+ @@ -275,6 +275,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);

+ @@ -2662,7 +2663,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;

+ @@ -2703,6 +2704,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);

+ @@ -2725,6 +2729,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 113217cdb6..229ce976bc 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 6ba198282e..853e0a0ace 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 da917dd897..2e32fbc300 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 883f16d81b..12edb68583 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 b697643a07..fedf9956cf 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 75b61b7d07..881937d456 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.47.1

+ 

@@ -0,0 +1,69 @@ 

+ From 0792bb7a9d25a1ab8a5f208f2f5cea8a362dc1c6 Mon Sep 17 00:00:00 2001

+ From: =?UTF-8?q?Zbigniew=20J=C4=99drzejewski-Szmek?= <zbyszek@in.waw.pl>

+ 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

+ 

@@ -0,0 +1,36 @@ 

+ From 2641ff693f715dd5094c56c59e0e660b9b35c9e2 Mon Sep 17 00:00:00 2001

+ From: Ryan Wilson <ryantimwilson@meta.com>

+ Date: Thu, 5 Dec 2024 08:31:42 -0800

+ Subject: [PATCH] Temporary workaround: PrivateUsers=full implies

+  DelegateNamespaces=yes

+ 

+ ---

+  src/core/exec-invoke.c | 5 ++++-

+  1 file changed, 4 insertions(+), 1 deletion(-)

+ 

+ diff --git a/src/core/exec-invoke.c b/src/core/exec-invoke.c

+ index 8305bb2bcf..8c2a689d6e 100644

+ --- a/src/core/exec-invoke.c

+ +++ b/src/core/exec-invoke.c

+ @@ -4061,6 +4061,9 @@ static bool exec_context_need_unprivileged_private_users(

+          assert(context);

+          assert(params);

+  

+ +        if (context->private_users == PRIVATE_USERS_FULL)

+ +                return true;

+ +

+          /* These options require PrivateUsers= when used in user units, as we need to be in a user namespace

+           * to have permission to enable them when not running as root. If we have effective CAP_SYS_ADMIN

+           * (system manager) then we have privileges and don't need this. */

+ @@ -5015,7 +5018,7 @@ int exec_invoke(

+  

+                  /* The kernel requires /proc/pid/setgroups be set to "deny" prior to writing /proc/pid/gid_map in

+                   * unprivileged user namespaces. */

+ -                r = setup_private_users(pu, saved_uid, saved_gid, uid, gid, /* allow_setgroups= */ false);

+ +                r = setup_private_users(pu, saved_uid, saved_gid, uid, gid, /* allow_setgroups= */ params->runtime_scope != RUNTIME_SCOPE_USER);

+                  /* 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 != PRIVATE_USERS_NO) {

+ -- 

+ 2.43.5

+ 

@@ -0,0 +1,347 @@ 

+ From 9ae68659b0870f3213a8e06011b1dbccdeb86ee6 Mon Sep 17 00:00:00 2001

+ From: Ryan Wilson <ryantimwilson@meta4.com>

+ 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-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 457b1e5926..4e51a55bd1 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 b1dc927af9..6a3a88210c 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 3ec6fe76c1..9828847924 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 ae13eba9ae..fbda880e9c 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 88620aad53..8bda6b1aec 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 51b9f39482..b697643a07 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.47.1

+ 

@@ -0,0 +1,58 @@ 

+ From 799367ff00cd0c85acd0bbea3dcec619e48b5601 Mon Sep 17 00:00:00 2001

+ From: Ryan Wilson <ryantimwilson@meta4.com>

+ Date: Tue, 3 Dec 2024 14:46:54 -0800

+ Subject: [PATCH] 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 43ffbab..b1dc927 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);

+  

+ -- 

+ 2.47.1

+ 

@@ -0,0 +1,43 @@ 

+ From 05188f9029780396097d5355198b8ec818852353 Mon Sep 17 00:00:00 2001

+ From: Ryan Wilson <ryantimwilson@meta.com>

+ Date: Tue, 12 Nov 2024 22:17:53 -0800

+ Subject: [PATCH] pam_systemd: Make pam_systemd 256 backwards compatible to

+  logind 255

+ 

+ ---

+  src/login/pam_systemd.c | 19 +++++++++++++++++++

+  1 file changed, 19 insertions(+)

+ 

+ diff --git a/src/login/pam_systemd.c b/src/login/pam_systemd.c

+ index a711c89b12..7222d5a0df 100644

+ --- a/src/login/pam_systemd.c

+ +++ b/src/login/pam_systemd.c

+ @@ -1124,6 +1124,25 @@ _public_ PAM_EXTERN int pam_sm_open_session(

+  

+                  r = sd_bus_call(bus, m, LOGIN_SLOW_BUS_CALL_TIMEOUT_USEC, &error, &reply);

+          }

+ +        if (r < 0 && sd_bus_error_has_name(&error, SD_BUS_ERROR_INVALID_ARGS)) {

+ +                SessionContext context2 = context;

+ +                context2.class = "";

+ +

+ +                sd_bus_error_free(&error);

+ +                pam_debug_syslog(handle, debug,

+ +                                 "New session classes are not available, retrying after unsetting class.");

+ +

+ +                m = sd_bus_message_unref(m);

+ +                r = create_session_message(bus,

+ +                                           handle,

+ +                                           &context2,

+ +                                           /* avoid_pidfd = */ true,

+ +                                           &m);

+ +                if (r < 0)

+ +                        return pam_bus_log_create_error(handle, r);

+ +

+ +                r = sd_bus_call(bus, m, LOGIN_SLOW_BUS_CALL_TIMEOUT_USEC, &error, &reply);

+ +        }

+          if (r < 0) {

+                  if (sd_bus_error_has_name(&error, BUS_ERROR_SESSION_BUSY)) {

+                          /* We are already in a session, don't do anything */

+ -- 

+ 2.43.5

+ 

file added
+373
@@ -0,0 +1,373 @@ 

+ From 3f14557ce01cc9012991a602851b03f0a4205fc2 Mon Sep 17 00:00:00 2001

+ From: Daan De Meyer <daan.j.demeyer@gmail.com>

+ 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</programlisting>

+      </variablelist>

+    </refsect1>

+  

+ +  <refsect1>

+ +    <title>[BandMultiQueueing] Section Options</title>

+ +    <para>The [BandMultiQueueing] section manages the queueing discipline (qdisc) of Band Multi Queueing (multiq).</para>

+ +

+ +    <variablelist class='network-directives'>

+ +      <xi:include href="tc.xml" xpointer="qdisc-parent" />

+ +      <xi:include href="tc.xml" xpointer="qdisc-handle" />

+ +    </variablelist>

+ +  </refsect1>

+ +

+    <refsect1>

+      <title>[HeavyHitterFilter] Section Options</title>

+      <para>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 <daan.j.demeyer@gmail.com>

+ 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</programlisting>

+      </variablelist>

+    </refsect1>

+  

+ +  <refsect1>

+ +    <title>[ClassfulMultiQueueing] Section Options</title>

+ +    <para>The [ClassfulMultiQueueing] section manages the queueing discipline (qdisc) of Classful Multi Queueing (mq).</para>

+ +

+ +    <variablelist class='network-directives'>

+ +      <xi:include href="tc.xml" xpointer="qdisc-parent" />

+ +      <xi:include href="tc.xml" xpointer="qdisc-handle" />

+ +    </variablelist>

+ +  </refsect1>

+ +

+    <refsect1>

+      <title>[BandMultiQueueing] Section Options</title>

+      <para>The [BandMultiQueueing] section manages the queueing discipline (qdisc) of Band Multi Queueing (multiq).</para>

+ 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')

file added
+574
@@ -0,0 +1,574 @@ 

+ From 10e421f70889a672f984785393051e0471c0aeb2 Mon Sep 17 00:00:00 2001

+ From: Daan De Meyer <daan.j.demeyer@gmail.com>

+ 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 {

+  

+      <!--property PrivateUsers is not documented!-->

+  

+ +    <!--property PrivateUsersEx is not documented!-->

+ +

+      <!--property PrivateMounts is not documented!-->

+  

+      <!--property PrivateIPC is not documented!-->

+ @@ -4516,6 +4520,8 @@ node /org/freedesktop/systemd1/unit/avahi_2ddaemon_2eservice {

+  

+      <variablelist class="dbus-property" generated="True" extra-ref="PrivateUsers"/>

+  

+ +    <variablelist class="dbus-property" generated="True" extra-ref="PrivateUsersEx"/>

+ +

+      <variablelist class="dbus-property" generated="True" extra-ref="PrivateMounts"/>

+  

+      <variablelist class="dbus-property" generated="True" extra-ref="PrivateIPC"/>

+ @@ -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 {

+  

+      <!--property PrivateUsers is not documented!-->

+  

+ +    <!--property PrivateUsersEx is not documented!-->

+ +

+      <!--property PrivateMounts is not documented!-->

+  

+      <!--property PrivateIPC is not documented!-->

+ @@ -6625,6 +6635,8 @@ node /org/freedesktop/systemd1/unit/avahi_2ddaemon_2esocket {

+  

+      <variablelist class="dbus-property" generated="True" extra-ref="PrivateUsers"/>

+  

+ +    <variablelist class="dbus-property" generated="True" extra-ref="PrivateUsersEx"/>

+ +

+      <variablelist class="dbus-property" generated="True" extra-ref="PrivateMounts"/>

+  

+      <variablelist class="dbus-property" generated="True" extra-ref="PrivateIPC"/>

+ @@ -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 {

+  

+      <!--property PrivateUsers is not documented!-->

+  

+ +    <!--property PrivateUsersEx is not documented!-->

+ +

+      <!--property PrivateMounts is not documented!-->

+  

+      <!--property PrivateIPC is not documented!-->

+ @@ -8436,6 +8452,8 @@ node /org/freedesktop/systemd1/unit/home_2emount {

+  

+      <variablelist class="dbus-property" generated="True" extra-ref="PrivateUsers"/>

+  

+ +    <variablelist class="dbus-property" generated="True" extra-ref="PrivateUsersEx"/>

+ +

+      <variablelist class="dbus-property" generated="True" extra-ref="PrivateMounts"/>

+  

+      <variablelist class="dbus-property" generated="True" extra-ref="PrivateIPC"/>

+ @@ -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 {

+  

+      <!--property PrivateUsers is not documented!-->

+  

+ +    <!--property PrivateUsersEx is not documented!-->

+ +

+      <!--property PrivateMounts is not documented!-->

+  

+      <!--property PrivateIPC is not documented!-->

+ @@ -10342,6 +10364,8 @@ node /org/freedesktop/systemd1/unit/dev_2dsda3_2eswap {

+  

+      <variablelist class="dbus-property" generated="True" extra-ref="PrivateUsers"/>

+  

+ +    <variablelist class="dbus-property" generated="True" extra-ref="PrivateUsersEx"/>

+ +

+      <variablelist class="dbus-property" generated="True" extra-ref="PrivateMounts"/>

+  

+      <variablelist class="dbus-property" generated="True" extra-ref="PrivateIPC"/>

+ 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</programlisting>

+        <varlistentry>

+          <term><varname>PrivateUsers=</varname></term>

+  

+ -        <listitem><para>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 <literal>root</literal> user and group as well as

+ -        the unit's own user and group to themselves and everything else to the <literal>nobody</literal> 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 <literal>root</literal> or the unit's own will stay visible

+ -        from within the unit but appear owned by the <literal>nobody</literal> 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 <literal>root</literal> 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 <varname>CapabilityBoundingSet=</varname> will affect only the latter, and there's no way to acquire

+ -        additional capabilities in the host's user namespace. Defaults to off.</para>

+ +        <listitem><para>Takes a boolean argument or one of <literal>self</literal> or

+ +        <literal>identity</literal>. 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

+ +        <literal>self</literal>, a minimal user and group mapping is configured that maps the

+ +        <literal>root</literal> user and group as well as the unit's own user and group to themselves and

+ +        everything else to the <literal>nobody</literal> 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 <literal>root</literal> or the unit's own will stay visible from

+ +        within the unit but appear owned by the <literal>nobody</literal> user and group. </para>

+ +

+ +        <para>If the parameter is <literal>identity</literal>, 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

+ +        <literal>nobody</literal> 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.</para>

+ +

+ +        <para>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 <literal>root</literal> 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

+ +        <varname>CapabilityBoundingSet=</varname> will affect only the latter, and there's no way to acquire

+ +        additional capabilities in the host's user namespace.</para>

+  

+          <para>When this setting is set up by a per-user instance of the service manager, the mapping of the

+          <literal>root</literal> 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"'

file added
+1954
The added file is too large to be shown here, see it at: 34543.patch
file added
+36
@@ -0,0 +1,36 @@ 

+ From 7759cc92c07c86272bdc91c18e66646920bde0f6 Mon Sep 17 00:00:00 2001

+ From: Daan De Meyer <daan.j.demeyer@gmail.com>

+ 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

file added
+255
@@ -0,0 +1,255 @@ 

+ From 0d0ecaab000cf2768a3edf1e73119bf2fce952b0 Mon Sep 17 00:00:00 2001

+ From: Daan De Meyer <daan.j.demeyer@gmail.com>

+ 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 <daan.j.demeyer@gmail.com>

+ 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 <daan.j.demeyer@gmail.com>

+ 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 <daan.j.demeyer@gmail.com>

+ 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 <daan.j.demeyer@gmail.com>

+ 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 <daan.j.demeyer@gmail.com>

+ 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;

file added
+233
@@ -0,0 +1,233 @@ 

+ From da81a108653e2ef19102698dbc0184bd18b084d9 Mon Sep 17 00:00:00 2001

+ From: Mike Yuan <me@yhndnzj.com>

+ 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 <me@yhndnzj.com>

+ 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 <me@yhndnzj.com>

+ 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 <daan.j.demeyer@gmail.com>

+ 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 &

file added
+580
@@ -0,0 +1,580 @@ 

+ From 871ee2f08715f8fae441786db04ba8497822f79a Mon Sep 17 00:00:00 2001

+ From: Daan De Meyer <daan.j.demeyer@gmail.com>

+ 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, &times);

+          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, &times);

+          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=<user>@.host --user to connect to bus of other user)" :

+ -                               r == hint_addr ? "Failed to connect to bus: Operation not permitted (consider using --machine=<user>@.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=<user>@.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=<user>@.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 <daan.j.demeyer@gmail.com>

+ 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 <daan.j.demeyer@gmail.com>

+ 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);

file added
+96
@@ -0,0 +1,96 @@ 

+ From c5698fe9076a8dc3472140c7d67f4524430f80a0 Mon Sep 17 00:00:00 2001

+ From: Daan De Meyer <daan.j.demeyer@gmail.com>

+ 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 <daan.j.demeyer@gmail.com>

+ 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 <daan.j.demeyer@gmail.com>

+ 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=<user>@.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=<user>@.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=<user>@.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=<user>@.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) {

file added
+117
@@ -0,0 +1,117 @@ 

+ From ca0cef28691be7ea22274c2fa7d95a2725da1ba5 Mon Sep 17 00:00:00 2001

+ From: Yu Watanabe <watanabe.yu+github@gmail.com>

+ 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, &not_ready_units) < 0)

+                          continue;

+  

+ 

+ From 388151b72103c10d63bac1e845d6a151619990ae Mon Sep 17 00:00:00 2001

+ From: Yu Watanabe <watanabe.yu+github@gmail.com>

+ 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 <<EOF

+ +event_timeout=1h

+ +EOF

+ +

+ +mkdir -p /run/udev/rules.d/

+ +cat >/run/udev/rules.d/99-testsuite.rules <<EOF

+ +SUBSYSTEM=="net", ACTION=="change", KERNEL=="${IFNAME}", OPTIONS="log_level=debug", RUN+="/usr/bin/sleep 1000"

+ +EOF

+ +

+ +systemctl restart systemd-udevd.service

+ +

+ +ip link add "$IFNAME" type dummy

+ +IFINDEX=$(ip -json link show "$IFNAME" | jq '.[].ifindex')

+ +udevadm wait --timeout 10 "/sys/class/net/${IFNAME}"

+ +# Check if the database file is created.

+ +[[ -e "/run/udev/data/n${IFINDEX}" ]]

+ +

+ +systemd-run \

+ +    -p After="sys-subsystem-net-devices-${IFNAME}.device" \

+ +    -p BindsTo="sys-subsystem-net-devices-${IFNAME}.device" \

+ +    -u testsleep.service \

+ +    sleep 1h

+ +

+ +timeout 10 bash -c 'until systemctl is-active testsleep.service; do sleep .5; done'

+ +

+ +udevadm trigger "/sys/class/net/${IFNAME}"

+ +timeout 30 bash -c "until grep -F 'ID_PROCESSING=1' /run/udev/data/n${IFINDEX}; do sleep .5; done"

+ +

+ +for _ in {1..3}; do

+ +    systemctl daemon-reexec

+ +    systemctl is-active testsleep.service

+ +done

+ +

+ +for _ in {1..3}; do

+ +    systemctl daemon-reload

+ +    systemctl is-active testsleep.service

+ +done

+ +

+ +# Check if the reexec and reload have finished during processing the event.

+ +grep -F 'ID_PROCESSING=1' "/run/udev/data/n${IFINDEX}"

+ +

+ +# cleanup

+ +systemctl stop testsleep.service

+ +rm -f /run/udev/udev.conf.d/timeout.conf

+ +rm -f /run/udev/rules.d/99-testsuite.rules

+ +# Forcibly kills sleep command invoked by the udev rule before restarting,

+ +# otherwise systemctl restart below will takes longer.

+ +killall -KILL sleep

+ +systemctl restart systemd-udevd.service

+ +ip link del "$IFNAME"

+ +

+ +exit 0

@@ -0,0 +1,13 @@ 

+ diff --git a/src/libsystemd/sd-netlink/netlink-internal.h b/src/libsystemd/sd-netlink/netlink-internal.h

+ index 891d3e8413..0fd919407a 100644

+ --- a/src/libsystemd/sd-netlink/netlink-internal.h

+ +++ b/src/libsystemd/sd-netlink/netlink-internal.h

+ @@ -11,7 +11,7 @@

+  #include "prioq.h"

+  #include "time-util.h"

+  

+ -#define NETLINK_DEFAULT_TIMEOUT_USEC ((usec_t) (25 * USEC_PER_SEC))

+ +#define NETLINK_DEFAULT_TIMEOUT_USEC USEC_INFINITY

+  

+  #define NETLINK_RQUEUE_MAX 64*1024

+  

file renamed
file was moved with no change to the file
file modified
+1 -1
@@ -1,1 +1,1 @@ 

- SHA512 (systemd-257.1.tar.gz) = dded7555077f85d0f8106b72cc46604fbe4249452be6b2d55800770b6deb2a3a122697c5a5f23b22dab416e8c050e53fc30d59dfd3bfd7c9fbbdab3162e8ebe5

+ SHA512 (systemd-257.2.tar.gz) = 4f47fcd9a4148101ee7b85cf5908a04ec9e025dc7a5a2e8e61c05439cfd427851b6d356bb96a0dfae55566bbf6d3c93a13251d220840c09296e94f80bd4a5945

file modified
+134 -26
@@ -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)
@@ -39,15 +42,17 @@ 

  %global __meson_auto_features disabled

  %endif

  

- # Override %%autorelease. This is ugly, but rpmautospec doesn't implement

- # autorelease correctly if the macro is conditionalized in the Release field.

- %{?release_override:%global autorelease %{release_override}%{?dist}}

- 

  Name:           systemd

  Url:            https://systemd.io

- # Allow users to specify the version and release when building the rpm by 

+ # 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:257.1}

+ # 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:        %autorelease

  

  %global stable %(c="%version"; [ "$c" = "${c#*.*}" ]; echo $?)
@@ -78,7 +83,7 @@ 

  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
@@ -95,27 +100,51 @@ 

  

  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

- 

  %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}

- 

  # Those are downstream-only patches, but we don't want them in packit builds:

  # https://bugzilla.redhat.com/show_bug.cgi?id=2251843

- Patch0011:      https://github.com/systemd/systemd/pull/30846.patch

+ # Meta specific backports (900-1000)

+ 

+ %if 0%{?facebook}

+ 

+ %if %{without upstream}

+ 

+ # pam_systemd: Make pam_systemd 256 backwards compatible to logind 255

+ Patch0904: 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

  

  %endif

  

+ # bump networkd netlink timeout to infinity

+ Patch0908: 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

+ # or upstreamed

+ %if %{with upstream}

+ 

+ # Temporary workaround: PrivateUsers=full implies DelegateNamespaces=yes

+ Patch1003: 0001-Temporary-workaround-PrivateUsers-full-implies-Deleg.patch

+ 

+ %endif

+ 

+ Patch:          https://github.com/systemd/systemd/pull/30846.patch

+ %endif

+ 

  %ifarch %{ix86} x86_64 aarch64 riscv64

  %global want_bootloader 1

  %endif
@@ -230,6 +259,10 @@ 

  %endif

  %endif

  

+ %if %{with obs}

+ BuildRequires:  pesign-obs-integration

+ %endif

+ 

  Requires(post): coreutils

  Requires(post): grep

  # systemd-machine-id-setup requires libssl
@@ -505,6 +538,7 @@ 

  Unified Kernel Image (UKI).

  

  %if 0%{?want_bootloader}

+ %if %{without obs}

  %package boot-unsigned

  Summary: UEFI boot manager (unsigned version)

  
@@ -525,6 +559,27 @@ 

  

  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
@@ -681,6 +736,25 @@ 

  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}
@@ -689,6 +763,8 @@ 

  %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*
@@ -834,6 +910,15 @@ 

          -Dukify=enabled

  )

  

+ %if 0%{?facebook}

+ CONFIGURE_OPTS+=(

+         -Dntp-servers='1.ntp.vip.facebook.com 2.ntp.vip.facebook.com 3.ntp.vip.facebook.com 4.ntp.vip.facebook.com'

+         -Ddns-servers='10.127.255.51 10.191.255.51 2401:db00:eef0:a53:: 2401:db00:eef0:b53::'

+         -Dsupport-url='https://fb.workplace.com/groups/systemd.and.friends'

+         -Dcontainer-uid-base-min=10485760

+ )

+ %endif

+ 

  %if %{without lto}

  %global _lto_cflags %nil

  %endif
@@ -963,7 +1048,7 @@ 

  # 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}
@@ -978,11 +1063,13 @@ 

  # https://fedoraproject.org/wiki/Changes/IncreaseVmMaxMapCount

  install -Dm0644 -t %{buildroot}%{_prefix}/lib/sysctl.d/ %{SOURCE17}

  

+ %if %{undefined facebook}

  # As requested in https://bugzilla.redhat.com/show_bug.cgi?id=1738828.

  # Test results are that bfq seems to behave better and more consistently on

  # typical hardware. The kernel does not have a configuration option to set the

  # default scheduler, and it currently needs to be set by userspace.

  install -Dm0644 -t %{buildroot}%{_prefix}/lib/udev/rules.d/ %{SOURCE18}

+ %endif

  

  sed -i 's|#!/usr/bin/env python3|#!%{__python3}|' %{buildroot}/usr/lib/systemd/tests/run-unit-tests.py

  
@@ -1038,6 +1125,11 @@ 

  # Split files in build root into rpms

  python3 %{SOURCE2} %buildroot %{!?want_bootloader:--no-bootloader}

  

+ # Stage sd-boot binaries for signing

+ %if %{with obs} && 0%{?want_bootloader}

+ BRP_PESIGN_FILES=/usr/lib/systemd/boot/efi/systemd-boot%{efi_arch}.efi BRP_PESIGN_PACKAGES=systemd-boot /usr/lib/rpm/brp-suse.d/brp-99-pesign

+ %endif

+ 

  %check

  %if %{with tests}

  meson test -C %{_vpath_builddir} -t 6 --print-errorlogs
@@ -1081,17 +1173,21 @@ 

  systemctl --global preset-all &>/dev/null || :

  

  %posttrans

- if [ $1 -ge 2 ]; then

-   [ -w %{_localstatedir} ] && journalctl --update-catalog || :

+ # We can't check for upgrades on c9s as https://github.com/rpm-software-management/rpm/commit/3848c97cb227e7c018781aa7d5e1e46990ce1ffb

+ # is missing so we run this stuff unconditionally on installs and upgrades.

+ [ -w %{_localstatedir} ] && journalctl --update-catalog || :

+ 

+ systemctl daemon-reexec || :

  

-   systemctl daemon-reexec || :

+ systemd-tmpfiles --create &>/dev/null || :

  

-   systemd-tmpfiles --create &>/dev/null || :

- fi

+ restarting_services='systemd-timedated.service systemd-hostnamed.service systemd-journald.service systemd-localed.service systemd-userdbd.service'

  

- %systemd_posttrans_with_restart systemd-timedated.service systemd-hostnamed.service systemd-journald.service systemd-localed.service systemd-userdbd.service

+ %if 0%{?facebook}

+ restarting_services="$restarting_services systemd-logind.service"

+ %endif

  

- # FIXME: systemd-logind.service is excluded (https://github.com/systemd/systemd/pull/17558)

+ %systemd_posttrans_with_restart $restarting_services

  

  # This is the expanded form of %%systemd_user_daemon_reexec. We

  # can't use the macro because we define it ourselves.
@@ -1100,9 +1196,15 @@ 

      /usr/lib/systemd/systemd-update-helper user-reexec || :

  fi

  

+ # Facebook minimum version is 255 so once 255-1.5 is released to Facebook's fleet,

+ # we can rely on the fact all systemd RPMs will use posttrans/postun and RPM state

+ # to ensure only one daemon-reexec. However, non-Facebook Centos RPMs may be older

+ # versions and we can't rely on removing triggerun for versions < 256.

+ %if 0%{?facebook} == 0

  %triggerun -- systemd < 256

  # This is for upgrades from previous versions before systemd restart was moved to %%postun

  systemctl daemon-reexec || :

+ %endif

  

  %triggerpostun -- systemd < 253~rc1-2

  # This is for upgrades from previous versions where systemd-journald-audit.socket
@@ -1126,7 +1228,7 @@ 

      mv %{_localstatedir}/lib/systemd/clock %{_localstatedir}/lib/systemd/timesync/.

  fi

  

- udevadm hwdb --update &>/dev/null

+ systemd-hwdb update &>/dev/null

  

  %systemd_post %udev_services

  
@@ -1187,7 +1289,9 @@ 

  %systemd_preun systemd-networkd.service systemd-networkd-wait-online.service

  

  %posttrans networkd

+ %if %{undefined facebook}

  %systemd_posttrans_with_restart systemd-networkd.service

+ %endif

  

  %post resolved

  [ $1 -eq 1 ] || exit 0
@@ -1292,7 +1396,11 @@ 

  

  %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

file removed
-50
@@ -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 '<no matches>' /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

no initial comment

rebased onto 237a642

17 days ago

1 new commit added

  • upgrade to v257.2
16 days ago

12 new commits added

  • Merge remote-tracking branch 'fedora/rawhide' into c10s-sig-hyperscale
  • Rebuilt for the bin-sbin merge (2nd attempt)
  • Rebuilt for the bin-sbin merge (2nd attempt)
  • Enable signing systemd-boot on OBS builds
  • Revert use of PrivateTmp=disconnected
  • Drop patch numbers
  • remove STI test
  • Version 257.2
  • Add bcond for OBS-specific quirks
  • spec: drop trailing whitespace
  • Replace 'udevadm hwdb' with systemd-hwdb
  • Rename source .abignore file
16 days ago

12 new commits added

  • Merge remote-tracking branch 'fedora/rawhide' into c10s-sig-hyperscale
  • Rebuilt for the bin-sbin merge (2nd attempt)
  • Rebuilt for the bin-sbin merge (2nd attempt)
  • Enable signing systemd-boot on OBS builds
  • Revert use of PrivateTmp=disconnected
  • Drop patch numbers
  • remove STI test
  • Version 257.2
  • Add bcond for OBS-specific quirks
  • spec: drop trailing whitespace
  • Replace 'udevadm hwdb' with systemd-hwdb
  • Rename source .abignore file
15 days ago