From f4a7117af261562c96a64a8c90c6ef759c9f6215 Mon Sep 17 00:00:00 2001 From: Totoro Date: Thu, 3 Sep 2026 23:40:26 +0800 Subject: [PATCH] network: honor --root= for picked up credentials network-generator writes generated command line configuration below the alternate root passed with --root=, but network.* credentials were copied to fixed host /run paths. Build the credential target directories with arg_root before passing them to pick_up_credentials(). This keeps normal boot behavior unchanged while making credential output land in the requested root. --- .../generator/network-generator-main.c | 32 ++++++++++++------- src/network/generator/network-generator.c | 3 ++ src/network/generator/network-generator.h | 3 ++ .../TEST-74-AUX-UTILS.network-generator.sh | 10 ++++++ 4 files changed, 36 insertions(+), 12 deletions(-) diff --git a/src/network/generator/network-generator-main.c b/src/network/generator/network-generator-main.c index 10b4a4377a..6e7fb8d60a 100644 --- a/src/network/generator/network-generator-main.c +++ b/src/network/generator/network-generator-main.c @@ -24,6 +24,7 @@ #include "verbs.h" #define NETWORK_UNIT_DIRECTORY "/run/systemd/network/" +#define NETWORKD_CONF_DROPIN_DIRECTORY "/run/systemd/networkd.conf.d/" static char *arg_root = NULL; @@ -141,22 +142,21 @@ static int context_save(Context *context) { Link *link; int r; - _cleanup_free_ char *p = path_join(arg_root, NETWORK_UNIT_DIRECTORY); - if (!p) - return log_oom(); + assert(context); + assert(context->network_dir); - r = mkdir_p(p, 0755); + r = mkdir_p(context->network_dir, 0755); if (r < 0) return log_error_errno(r, "Failed to create directory " NETWORK_UNIT_DIRECTORY ": %m"); HASHMAP_FOREACH(network, context->networks_by_name) - RET_GATHER(r, network_save(network, p)); + RET_GATHER(r, network_save(network, context->network_dir)); HASHMAP_FOREACH(netdev, context->netdevs_by_name) - RET_GATHER(r, netdev_save(netdev, p)); + RET_GATHER(r, netdev_save(netdev, context->network_dir)); HASHMAP_FOREACH(link, context->links_by_filename) - RET_GATHER(r, link_save(link, p)); + RET_GATHER(r, link_save(link, context->network_dir)); return r; } @@ -208,6 +208,14 @@ static int run(int argc, char *argv[]) { if (r <= 0) return r; + context.network_dir = path_join(arg_root, NETWORK_UNIT_DIRECTORY); + if (!context.network_dir) + return log_oom(); + + context.networkd_conf_dropin_dir = path_join(arg_root, NETWORKD_CONF_DROPIN_DIRECTORY); + if (!context.networkd_conf_dropin_dir) + return log_oom(); + if (strv_isempty(args)) { r = proc_cmdline_parse(parse_cmdline_item, &context, 0); if (r < 0) @@ -240,11 +248,11 @@ static int run(int argc, char *argv[]) { RET_GATHER(ret, context_save(&context)); - static const PickUpCredential table[] = { - { "network.conf.", "/run/systemd/networkd.conf.d/", ".conf" }, - { "network.link.", NETWORK_UNIT_DIRECTORY, ".link" }, - { "network.netdev.", NETWORK_UNIT_DIRECTORY, ".netdev" }, - { "network.network.", NETWORK_UNIT_DIRECTORY, ".network" }, + const PickUpCredential table[] = { + { "network.conf.", context.networkd_conf_dropin_dir, ".conf" }, + { "network.link.", context.network_dir, ".link" }, + { "network.netdev.", context.network_dir, ".netdev" }, + { "network.network.", context.network_dir, ".network" }, }; RET_GATHER(ret, pick_up_credentials(table, ELEMENTSOF(table))); diff --git a/src/network/generator/network-generator.c b/src/network/generator/network-generator.c index 5e322f41ea..d3f77f4efa 100644 --- a/src/network/generator/network-generator.c +++ b/src/network/generator/network-generator.c @@ -1413,6 +1413,9 @@ void context_clear(Context *context) { if (!context) return; + free(context->network_dir); + free(context->networkd_conf_dropin_dir); + hashmap_free(context->networks_by_name); hashmap_free(context->netdevs_by_name); hashmap_free(context->links_by_filename); diff --git a/src/network/generator/network-generator.h b/src/network/generator/network-generator.h index 95a6379e4b..0c58a6c060 100644 --- a/src/network/generator/network-generator.h +++ b/src/network/generator/network-generator.h @@ -100,6 +100,9 @@ struct Link { }; typedef struct Context { + char *network_dir; + char *networkd_conf_dropin_dir; + Hashmap *networks_by_name; Hashmap *netdevs_by_name; Hashmap *links_by_filename; diff --git a/test/units/TEST-74-AUX-UTILS.network-generator.sh b/test/units/TEST-74-AUX-UTILS.network-generator.sh index 44912b2a0f..73366a29ac 100755 --- a/test/units/TEST-74-AUX-UTILS.network-generator.sh +++ b/test/units/TEST-74-AUX-UTILS.network-generator.sh @@ -4,12 +4,15 @@ set -eux set -o pipefail +ROOT="$(mktemp -d /var/tmp/test-network-generator-root.XXXXXX)" + at_exit() { rm -f /run/credstore/network.conf.50-testme rm -f /run/credstore/network.network.50-testme rm -f /run/systemd/networkd.conf.d/50-testme.conf rm -f /run/systemd/network/50-testme.network rm -f /run/systemd/system/systemd-network-generator.service.d/50-testme.conf + rm -rf "${ROOT:?}" } trap at_exit EXIT @@ -35,3 +38,10 @@ systemctl restart systemd-network-generator diff /run/credstore/network.conf.50-testme /run/systemd/networkd.conf.d/50-testme.conf diff /run/credstore/network.network.50-testme /run/systemd/network/50-testme.network + +CREDENTIALS_DIRECTORY=/run/credstore /usr/lib/systemd/systemd-network-generator --root="$ROOT" + +diff /run/credstore/network.conf.50-testme \ + "$ROOT/run/systemd/networkd.conf.d/50-testme.conf" +diff /run/credstore/network.network.50-testme \ + "$ROOT/run/systemd/network/50-testme.network"