From 65314bc926c6e3b3b7592b80aef57ee45541e90e Mon Sep 17 00:00:00 2001 From: vxtls <187420201+vxtls@users.noreply.github.com> Date: Fri, 6 Mar 2026 09:27:41 -0500 Subject: [PATCH] fix(network): gate dhcp on get_network state across boots --- rootfs.py | 44 ++++++++++++++++++++++++++++++++---- seed/script-generator.c | 5 +++- steps/helpers.sh | 1 - steps/improve/get_network.sh | 5 +++- steps/improve/update_env.sh | 1 + 5 files changed, 48 insertions(+), 8 deletions(-) diff --git a/rootfs.py b/rootfs.py index e58cf77d..727727dc 100755 --- a/rootfs.py +++ b/rootfs.py @@ -119,6 +119,17 @@ else: if old_env_content is not None: with open(os.path.join(dest_steps, "env"), "wb") as env_file: env_file.write(old_env_content) +env_path = os.path.join(dest_steps, "env") +if os.path.isfile(env_path): + with open(env_path, "r", encoding="utf-8", errors="ignore") as env_file: + env_content = env_file.read() +else: + env_content = "" +if "NETWORK_READY=" not in env_content: + with open(env_path, "a", encoding="utf-8") as env_file: + if env_content and not env_content.endswith("\\n"): + env_file.write("\\n") + env_file.write("NETWORK_READY=False\\n") config_path = os.path.join(dest_steps, "bootstrap.cfg") if build_guix_also: @@ -131,10 +142,29 @@ lines.append("PAYLOAD_REQUIRED=False\\n") with open(config_path, "w", encoding="utf-8") as cfg: cfg.writelines(lines) -# Ensure resumed stage0-image /init has minimal early mounts for runtime. -init_path = os.path.join(mountpoint, "init") +# Ensure resumed stage0-image init scripts have minimal early mounts and +# only restore networking after get_network has run. mount_marker = "# LB_STAGE0_EARLY_MOUNTS" -if os.path.isfile(init_path): +legacy_network_block = ( + 'if [ "${CHROOT}" = False ] && command -v dhcpcd >/dev/null 2>&1; then\\n' + 'dhcpcd --waitip=4 || true\\n' + 'fi\\n' +) +gated_network_block = ( + 'if [ -f /steps/env ]; then\\n' + '. /steps/env\\n' + 'fi\\n' + 'if [ "${CHROOT}" = False ] && [ "${NETWORK_READY}" = True ] && command -v dhcpcd >/dev/null 2>&1; then\\n' + 'dhcpcd --waitip=4 || true\\n' + 'fi\\n' +) +for init_name in os.listdir(mountpoint): + if init_name != "init" and not init_name.startswith("init."): + continue + init_path = os.path.join(mountpoint, init_name) + if not os.path.isfile(init_path): + continue + with open(init_path, "r", encoding="utf-8", errors="ignore") as init_file: init_content = init_file.read() @@ -151,8 +181,12 @@ if os.path.isfile(init_path): + mount_block + init_content[first_newline + 1 :] ) - with open(init_path, "w", encoding="utf-8") as init_file: - init_file.write(init_content) + + if legacy_network_block in init_content and gated_network_block not in init_content: + init_content = init_content.replace(legacy_network_block, gated_network_block) + + with open(init_path, "w", encoding="utf-8") as init_file: + init_file.write(init_content) if build_guix_also: dest_steps_guix = os.path.join(mountpoint, "steps-guix") diff --git a/seed/script-generator.c b/seed/script-generator.c index 9150daf3..9aada6b3 100644 --- a/seed/script-generator.c +++ b/seed/script-generator.c @@ -534,9 +534,12 @@ void output_resume_network_init(FILE *out) { fputs("if [ -f /steps/bootstrap.cfg ]; then\n", out); fputs(". /steps/bootstrap.cfg\n", out); fputs("fi\n", out); + fputs("if [ -f /steps/env ]; then\n", out); + fputs(". /steps/env\n", out); + fputs("fi\n", out); fputs("mount | grep ' on /dev ' >/dev/null 2>&1 || (mkdir -p /dev; mount -t devtmpfs devtmpfs /dev)\n", out); fputs("mount | grep ' on /proc ' >/dev/null 2>&1 || (mkdir -p /proc; mount -t proc proc /proc)\n", out); - fputs("if [ \"${CHROOT}\" = False ] && command -v dhcpcd >/dev/null 2>&1; then\n", out); + fputs("if [ \"${CHROOT}\" = False ] && [ \"${NETWORK_READY}\" = True ] && command -v dhcpcd >/dev/null 2>&1; then\n", out); fputs("dhcpcd --waitip=4 || true\n", out); fputs("fi\n", out); } diff --git a/steps/helpers.sh b/steps/helpers.sh index c4d0bf2c..5df59621 100755 --- a/steps/helpers.sh +++ b/steps/helpers.sh @@ -344,7 +344,6 @@ source_line_action() { # Default get function that downloads source tarballs. default_src_get() { - ensure_network_ready # shellcheck disable=SC2153 cd "${DISTFILES}" # shellcheck disable=SC2162 diff --git a/steps/improve/get_network.sh b/steps/improve/get_network.sh index eb783ea1..45958e3f 100755 --- a/steps/improve/get_network.sh +++ b/steps/improve/get_network.sh @@ -4,7 +4,7 @@ # # SPDX-License-Identifier: GPL-3.0-or-later # -dhcpcd --waitip=4 +ensure_network_ready # Ensure network accessible timeout=120 while ! curl example.com >/dev/null 2>&1; do @@ -16,3 +16,6 @@ while ! curl example.com >/dev/null 2>&1; do false fi done + +sed -i '/^NETWORK_READY=/d' /steps/env +echo 'NETWORK_READY=True' >> /steps/env diff --git a/steps/improve/update_env.sh b/steps/improve/update_env.sh index a0a7e102..d39d44c3 100755 --- a/steps/improve/update_env.sh +++ b/steps/improve/update_env.sh @@ -19,6 +19,7 @@ export SOURCE_DATE_EPOCH=0 export KBUILD_BUILD_TIMESTAMP='@0' export SHELL=/usr/bin/bash DESTDIR=/tmp/destdir +NETWORK_READY=False EOF # The following values are set up in the kaem environment.