agama/live/live-root/usr/lib/dracut/modules.d/99hcn/ARCHITECTURE.md
2026-08-17 09:43:49 +01:00

33 KiB

HCN Dracut Module Architecture

This document provides the technical design and architecture for the 99hcn dracut module, explaining how it integrates with systemd, NetworkManager, and the Agama installer to provide automatic HCN network configuration during boot.

Table of Contents

  1. Overview
  2. Key Architecture Principles
  3. Boot-Time Integration & Component Diagram
  4. Sequential Boot Process
  5. HCN-Specific Boot Parameters
  6. Parameter Transformation Flow
  7. Profile Generation and Adaptation
  8. Two-Stage Persistence Architecture
  9. Future Considerations

Overview

The 99hcn dracut module provides automatic network configuration for IBM PowerVM Hybrid Cloud Network (HCN) during the initramfs phase of boot. It integrates with systemd and NetworkManager to discover HCN devices, create bonded interfaces, and generate NetworkManager connection profiles that persist to the installed system for runtime management by hcnmgr.

Core Responsibilities:

  1. Parse HCN-specific kernel parameters (rd.hcn.ip, rd.hcn.route)
  2. Reserve the network configuration for HCN by writing an ip=hcn marker to /etc/cmdline.d/
  3. Discover HCN device pairs via /proc/device-tree properties
  4. Transform HCN parameters into bond-targeted standard dracut parameters
  5. Generate NetworkManager connection profiles via nm-initrd-generator
  6. Adapt profiles for hcnmgr daemon compatibility
  7. Persist profiles across initramfs and into the installed system

Key Architecture Principles

  1. Systemd Conditional Activation: The hcn-init-initrd.service uses systemd ConditionKernelCommandLine directives to activate only when:

    • rd.hcn=1 is present, OR
    • rd.hcn.ip is present, OR
    • rd.hcn.route is present
    • AND rd.hcn=0 is NOT present (explicit disable)
  2. Two-Stage Persistence:

    • Stage 1 (HCN module): Generates and fixes up connections in /run/hcn/system-connections/, then copies them to /etc/NetworkManager/system-connections/ for initramfs persistence.
    • Stage 2 (Agama module): Before pivoting to the installed system, save-agama-conf.sh copies connections from /etc/NetworkManager/system-connections/ (with origin=nm-initrd-generator) to the target system's /etc/NetworkManager/system-connections/.
  3. Isolated Profile Generation: Uses a custom output directory (/run/hcn/system-connections/) instead of the standard /run/NetworkManager/system-connections/ to prevent conflicts during profile generation and adaptation.

  4. No Cmdline Pollution: Transformed parameters are passed directly to nm-initrd-generator as command-line arguments, never written to /etc/cmdline.d/, preventing other dracut modules from reading them and regenerating incompatible profiles.

  5. Early Claim of the Network: The hcn-cmdline.sh hook writes a single ip=hcn marker to /etc/cmdline.d/20-hcn.conf while the command line is being parsed. It announces that HCN takes care of the network so that neither NetworkManager nor the other Agama modules configure the bond ports on their own. This requires NetworkManager with ip=hcn support (jsc#PED-14534). The marker is internal: it is written by the module, never by the user, and it does not enable HCN by itself (hcn-init-initrd.service only reacts to rd.hcn*).

  6. Timing-Aware Orchestration: Two-phase execution (cmdline hook + systemd service) handles the fact that HCN devices may not be available when kernel command line parsing runs. The hook only reserves the network, the actual configuration happens in the service once udev has discovered the devices.

Boot-Time Integration & Component Diagram

The following diagram details the control and configuration flow from the initial kernel/logging and early cmdline phase down to NetworkManager activation. It showcases how the execution path adapts dynamically to both standard and HCN boots, highlighting differences between Tumbleweed (NetworkManager >= 1.54) and SLES 16.1 (NetworkManager < 1.54).

                                HARDWARE / HYPERVISOR (PowerVM)
+-------------------------------------------------------------------------------------------------+
|                                                                                                 |
|   +---------------------------------------+           +-------------------------------------+   |
|   |          PCI SR-IOV Ethernet          |           |            Virtual NIC (vnic)       |   |
|   |  - Property: ibm,hcn-id = <hcn-id>    |           |   - Property: ibm,hcn-id = <hcn-id> |   |
|   |  - Property: ibm,hcn-mode = "primary" |           |   - Property: ibm,hcn-mode = "backup"|  |
|   |  - local-mac-address = <MAC_A>        |           |   - local-mac-address = <MAC_B>     |   |
|   +-------------------+-------------------+           +------------------+------------------+   |
+-----------------------|--------------------------------------------------|----------------------+
                        |                                                  |
                        v                                                  v
             /proc/device-tree/pci*/ethernet*                    /proc/device-tree/vdevice/vnic*
                        |                                                  |
===================================================================================================
                                           INITRD PHASE
===================================================================================================
                                                |
                                                v
+-------------------------------------------------------------------------------------------------+
|  1. EARLY CMDLINE & LOGGING PHASE (`dracut-cmdline.service`)                                    |
|     - Runs the HCN cmdline hook: `/lib/dracut/hooks/cmdline/20-hcn-cmdline.sh`                  |
|       * If HCN is requested (rd.hcn=1, rd.hcn.ip or rd.hcn.route) AND the device tree           |
|         contains `ibm,hcn-id` devices: writes `ip=hcn` to `/etc/cmdline.d/20-hcn.conf`.            |
|       * Otherwise: no-op, the boot continues as a standard one.                                 |
|     - Runs the other Agama cmdline hooks (priority 99: agama-dud, live-self-update,             |
|       initrd-nmtui). They add `ip=dhcp` only when no `ip=` is set, so the marker above          |
|       keeps them away from the HCN bond ports.                                                  |
|     - Runs early cmdline hook: `/lib/dracut/hooks/cmdline/99-nm-config.sh`                      |
|                                                                                                 |
|     SLES 16.1 (NM < 1.54):                                                                      |
|     - `nm-config.sh` executes `nm_generate_connections` normally. With `ip=hcn` it              |
|       generates nothing, not even the `rd.neednet=1` default connection.                        |
|                                                                                                 |
|     Tumbleweed (NM >= 1.54):                                                                    |
|     - No generation in cmdline hook (delegated to systemd service).                             |
+-------------------------------------------------------------------------------------------------+
                                                |
                                                v
+-------------------------------------------------------------------------------------------------+
|  1.5 NETWORK GENERATION SERVICE PHASE (Tumbleweed Only)                                         |
|     Runs `NetworkManager-config-initrd.service` (Before `systemd-udevd.service`):               |
|     - RUNS standard `nm-initrd-generator` normally, reading the dracut command line             |
|       (`getcmdline`, see the dracut drop-in) and therefore seeing the `ip=hcn` marker.          |
|     - With `ip=hcn` it generates nothing and leaves the network to the HCN module.              |
+-------------------------------------------------------------------------------------------------+
                                                |
                                                v
+-------------------------------------------------------------------------------------------------+
|  2. KERNEL & UDEV DISCOVERY (`systemd-udev-trigger.service`)                                    |
|     - Drivers bind to physical/virtual devices.                                                 |
|     - Interfaces appear in sysfs: e.g. /sys/class/net/enP32775p1s0 and /sys/class/net/env6      |
+-----------------------------------------------+-------------------------------------------------+
                                                |
                                                v
+-----------------------------------------------+-------------------------------------------------+
|  3. HCN BOND CONFIGURATION SERVICE PHASE                                                        |
|     `hcn-init-initrd.service` (Runs `/usr/bin/parse-hcn` after udev discovery):                |
|     - Activates when any of: rd.hcn=1, rd.hcn.ip, or rd.hcn.route is present                    |
|     - If none are present: Exits early (no-op).                                                 |
|     - If HCN is enabled:                                                                        |
|       * Discovers HCN devices from /proc/device-tree (PCI SR-IOV and VNIC adapters)            |
|       * Compiles bond mapping: `bond333e80f5 -> [enP32775p1s0, env6]` with modes and MACs      |
|       * Reads `rd.hcn.ip` and `rd.hcn.route` params and transforms them to bond-targeted        |
|         `bond=`, `ip=`, and `rd.route=` options.                                                |
|       * Calls `nm-initrd-generator` DIRECTLY with `-c /run/hcn/system-connections` (does NOT   |
|         write to `/etc/cmdline.d/` to prevent future regeneration).                             |
|       * Performs interface profile fixups for hcnmgr compatibility in `/run/hcn/system-         |
|         connections/` (bond naming, controller references, UUIDs, etc.).                        |
|       * Copies adapted profiles to `/etc/NetworkManager/system-connections/` for persistence.   |
+-----------------------------------------------+-------------------------------------------------+
                                                |
                                                v
+-----------------------------------------------+-------------------------------------------------+
|  4. NETWORK MANAGER ACTIVATION                                                                  |
|     - Brings up connection profiles (either standard or bond).                                  |
|                                                                                                 |
|     A. Tumbleweed (NM >= 1.54): `NetworkManager-initrd.service`                                 |
|     B. SLES 16.1 (NM < 1.54): `nm-initrd.service`                                               |
+-------------------------------------------------------------------------------------------------+

Sequential Boot Process

  1. Kernel Initialization & Initramfs Mount: The kernel mounts the initramfs. Systemd starts as PID 1 (/usr/lib/systemd/systemd).

  2. Early Cmdline & Discovery Phase (dracut-cmdline.service):

    • dracut-cmdline processes all command line hooks in priority order.
    • 20-hcn-cmdline.sh (this module) writes ip=hcn to /etc/cmdline.d/20-hcn.conf when HCN is requested and HCN devices exist in /proc/device-tree. Nothing else is written: the transformation of rd.hcn.* still happens much later, in hcn-init-initrd.service.
    • The priority 99 hooks of the other Agama modules (99agama-dud, 99live-self-update, 99initrd-nmtui) run afterwards and skip their ip=dhcp fallback because an ip= is already present.
    • Standard NetworkManager connection generation proceeds normally:
      • SLES 16.1 (NetworkManager < 1.54): 99-nm-config.sh calls nm_generate_connections to generate standard connection profiles.
      • Tumbleweed (NetworkManager >= 1.54): 99-nm-config.sh does not call nm_generate_connections (which is delegated to a systemd service).

2.5. Network Generation Service Phase (Tumbleweed with NetworkManager >= 1.54 Only):

  • NetworkManager-config-initrd.service runs (ordered After=dracut-cmdline.service and Before=systemd-udevd.service / systemd-udev-trigger.service).
  • It runs standard nm-initrd-generator normally to generate connection profiles based on kernel arguments. The dracut drop-in (NetworkManager-config-initrd-dracut.conf, from the 35network-manager module) makes it use getcmdline instead of cat /proc/cmdline, so the ip=hcn marker written above is taken into account.
  • On an HCN boot the generator therefore produces no profiles at all, in particular not the default DHCP connection it would otherwise fabricate for rd.neednet=1. That default would activate the bond ports individually and break the bond (bsc#1272445).
  1. Udev Device Discovery:

    • systemd-udevd.service starts and triggers hardware udev events via systemd-udev-trigger.service.
    • Network interfaces (physical/virtual) are discovered and matching kernel drivers are loaded.
    • Network device nodes (e.g. enP32775p1s0, env6) are created under /sys/class/net/.
  2. Network Generator Orchestration:

    • hcn-init-initrd.service starts (ordered After=systemd-udev-trigger.service and Before=dracut-initqueue.service nm-initrd.service NetworkManager-initrd.service). It activates when any of these kernel command line parameters are present: rd.hcn=1, rd.hcn.ip, or rd.hcn.route.
      • If none of these parameters are present: Service does not start (systemd conditions prevent execution).
      • If any HCN parameter is present:
        • /usr/bin/parse-hcn performs discovery in /proc/device-tree to pair adapters sharing an ibm,hcn-id.
        • For each device, it waits up to 3 minutes for the interface to appear after potential migration events. The unit sets TimeoutStartSec=300 for that, the default start timeout is shorter than the wait.
        • It reads the HCN-specific kernel command line options rd.hcn.ip and rd.hcn.route and translates them to target the planned bond interface (e.g. bond333e80f5).
        • It carries over the remaining device independent network options of the real command line (nameserver=, rd.peerdns=, rd.net.dhcp.*), which the generator run of step 2.5 produced nothing for.
        • It calls the standard nm-initrd-generator directly with transformed parameters as command-line arguments and custom output directories -c /run/hcn/system-connections and -r /run/hcn/conf.d.
        • It adapts the generated NetworkManager profiles for compatibility with hcnmgr daemon (bond naming, controller references, UUIDs).
        • The adapted profiles are copied to /etc/NetworkManager/system-connections/ for persistence across reboots.
  3. Network Interface Activation (NetworkManager):

    • The appropriate activation service starts:
      • Tumbleweed (NetworkManager >= 1.54): NetworkManager-initrd.service starts.
      • SLES 16.1 (NetworkManager < 1.54): nm-initrd.service starts.
    • It reads from /etc/NetworkManager/system-connections/ (HCN connections) and /run/NetworkManager/system-connections/ (standard connections).
    • HCN Active Path: Creates the bond interface, binds the port interfaces, and applies IP and routing configurations. Connection profiles are structured for hcnmgr compatibility.
    • HCN Inactive / Fallback Path: Configures and starts standard independent interfaces according to standard ip= and rd.route= parameters.
  4. Agama Module Integration (Before Pivot):

    • Before pivoting to the installed system, the 99agama-cmdline module's save-agama-conf.sh script executes.
    • If inst.copy_network is enabled (default) and custom network configuration is detected:
      • Copies runtime connections from /run/NetworkManager/system-connections/ with origin=nm-initrd-generator to the installed system.
      • Copies persistent HCN connections from /etc/NetworkManager/system-connections/ with origin=nm-initrd-generator to the installed system.
      • This ensures HCN bond configurations persist into the installed system for hcnmgr daemon to manage.

HCN-Specific Boot Parameters

Why Not Transform Standard ip= Options?

The HCN dracut module introduces dedicated boot parameters rd.hcn.ip and rd.hcn.route instead of transforming standard ip= and rd.route= kernel command line options. This design decision addresses several critical architectural concerns:

  1. Kernel Command Line Immutability:

    • /proc/cmdline is read-only and cannot be modified at runtime
    • We cannot append or transform parameters into /proc/cmdline after the kernel starts
    • Even if we could modify it, other dracut modules have already cached its contents during early boot
  2. Two-Phase Configuration Process:

    • Phase 1 (Boot-time): The parse-hcn.sh script transforms rd.hcn.ip and rd.hcn.route parameters into a combination of bond=, ip=, and rd.route= options with the appropriate bond interface name (e.g., bond333e80f5).
    • Phase 2 (Profile Adaptation): The generated NetworkManager connection profiles must be adapted to ensure compatibility with the hcnmgr daemon, which manages bond interfaces dynamically during the installed system's lifecycle (e.g., during Live Partition Migration).
  3. Module Regeneration Risk: If another dracut module or NetworkManager tool regenerates network configuration after the initial HCN setup, using standard ip= parameters would cause those tools to generate incompatible connection profiles that would lack proper bond configuration and break HCN functionality.

  4. Compatibility with hcnmgr: The hcnmgr daemon expects specific bond naming conventions and connection structure:

    • Bond interfaces follow the bondXXXXXXXX naming pattern (where XXXXXXXX is derived from the HCN ID)
    • Connection profiles include proper controller/port relationships with correct naming
    • UUIDs and connection metadata are structured for hcnmgr runtime management
    • Bond options (mode, fail_over_mac, miimon, primary) are set according to HCN requirements

Parameter Syntax

  • rd.hcn.ip=<value>: Specifies IP configuration for the HCN bond interface. The syntax mirrors the standard ip= parameter but omits the interface name (since the bond name is derived from the HCN ID).

    Format: rd.hcn.ip=<client-IP>::<gateway>:<netmask>:::<method>

    Example: rd.hcn.ip=192.168.1.10::192.168.1.1:255.255.255.0:::none

  • rd.hcn.route=<value>: Specifies routing configuration for the HCN bond interface. The syntax mirrors the standard rd.route= parameter but omits the interface name.

    Format: rd.hcn.route=<network>/<prefix>:<gateway>

    Example: rd.hcn.route=192.168.1.0/24:192.168.1.1

  • rd.hcn=1: Explicitly enables HCN configuration. Note: This parameter is optional and redundant when rd.hcn.ip or rd.hcn.route is present.

Important: The interface name is intentionally omitted from both rd.hcn.ip and rd.hcn.route parameters because:

  • The bond interface name is automatically derived from the HCN ID discovered in /proc/device-tree
  • This ensures the bond name always matches hcnmgr expectations
  • Prevents user error in specifying incorrect bond names

Parameter Transformation Flow

Complete Boot Command Line Example

User provides (on kernel command line or in Grub configuration):

rd.hcn.ip=192.168.1.10::192.168.1.1:255.255.255.0:::none rd.hcn.route=192.168.1.0/24:192.168.1.1

This configuration:

  • Configures the HCN bond with static IP 192.168.1.10, gateway 192.168.1.1, and netmask 255.255.255.0
  • Adds a route to the 192.168.1.0/24 network via 192.168.1.1
  • Note: Interface name is intentionally omitted from rd.hcn.ip and rd.hcn.route

The parse-hcn.sh script transforms this into (example for HCN ID 333e80f5):

Passed directly as arguments to nm-initrd-generator:

nm-initrd-generator -- \
  bond=bond333e80f5:enP32775p1s0,env6:mode=active-backup,fail_over_mac=2,miimon=100,primary=enP32775p1s0 \
  ip=192.168.1.10::192.168.1.1:255.255.255.0::bond333e80f5:none \
  rd.route=192.168.1.0/24:192.168.1.1:bond333e80f5

Where:

  • bond333e80f5 is derived from HCN ID 333e80f5 discovered in /proc/device-tree
  • enP32775p1s0 is the primary SR-IOV interface (discovered via ibm,hcn-mode = "primary")
  • env6 is the backup virtual NIC interface (discovered via ibm,hcn-mode = "backup")
  • Both interfaces share the same ibm,hcn-id = 333e80f5 property
  • Bond options are hardcoded for HCN requirements:
    • mode=active-backup: Only one port is active at a time
    • fail_over_mac=2: Follow the selection of the active port
    • miimon=100: Monitor link status every 100ms
    • primary=enP32775p1s0: Prefer the SR-IOV interface as primary

Carrying over the rest of the network command line

The command line above is built from scratch, so it is also the only network command line nm-initrd-generator gets to see for HCN. The generator run NetworkManager performs on its own with the real command line is not a substitute: the ip=hcn marker keeps that run from producing any connection, so every per-connection setting it parses there is dropped.

carry_over_cmdline() therefore appends the network options that name no device, copied verbatim:

Group Options Handling
Device independent nameserver, rd.peerdns, rd.net.timeout.dhcp, rd.net.dhcp.retry, rd.net.dhcp.vendor-class, rd.net.dhcp.dscp Copied verbatim

Two constraints of the dracut library shape how the function is written:

  • It appends to NEW_ARGS instead of printing the options. Under systemd (DRACUT_SYSTEMD=1, which hcn-init-initrd.service sets like every other dracut service) info() writes to stdout, so the output of a function that logs cannot be captured with a command substitution. The same applies to get_dev_hcn(), which hands its result over in HCN_MAPPING.
  • Only options taking a value can be carried over this way, because getargs() prints nothing for an option given as a bare flag. All the options above do take one, rd.peerdns is used as rd.peerdns=0. A boolean option would need getargbool().

Known gaps, all of them deliberate:

  • rd.net.dhcp.client-id, bootdev, rd.ethtool, and the vlan= / bridge= / team= stacked devices name a device. The user names a bond port, so the reference would have to be rewritten to its bond first. On top of that, nm-initrd-generator creates a full connection for every device it sees named in any of these, and the copy step below would then persist that stray connection to /etc/NetworkManager/system-connections. The stacked devices additionally need a way to be addressed from rd.hcn.ip, which the current syntax does not offer.
  • rd.net.dns, rd.net.dns-backend, rd.net.dns-resolve-mode and rd.net.timeout.carrier produce a global configuration file rather than a connection. They do not depend on the bonds having been resolved and NetworkManager's own run already wrote them to /run/NetworkManager/conf.d. That is also why --run-config-dir points at /run/hcn/conf.d: the generator unconditionally writes 15-carrier-timeout.conf, so with the default directory the HCN run would overwrite NetworkManager's copy of it and reset a rd.net.timeout.carrier supplied by the user.

The host name field of rd.hcn.ip needs no carry-over: the generator writes it to its --initrd-data-dir (/run/NetworkManager/initrd, which it creates itself) while parsing the ip= argument built from rd.hcn.ip. nm-run.sh, the initqueue/settled hook of 35network-manager, then applies it to /proc/sys/kernel/hostname. The ordering holds because hcn-init-initrd.service runs Before=dracut-initqueue.service.

These transformed parameters are:

  1. Passed directly to nm-initrd-generator as command-line arguments (NOT written to /etc/cmdline.d/)
  2. Output directed to isolated directories: -c /run/hcn/system-connections and -r /run/hcn/conf.d
  3. Used by nm-initrd-generator to create initial NetworkManager connection profiles
  4. Adapted by fixup_nm_connections() to ensure hcnmgr daemon compatibility
  5. Copied to /etc/NetworkManager/system-connections/ for persistence across reboots
  6. Activated by NetworkManager which reads from /etc/NetworkManager/system-connections/

Three-Layer Protection Strategy

The HCN module employs a comprehensive protection strategy to ensure hcnmgr-compatible profiles survive across boot stages and prevent regeneration by other modules:

  1. Layer 1 - Prevent Regeneration Trigger:

    • Only the HCN module understands rd.hcn.* parameters
    • Transformed parameters are never written to /etc/cmdline.d/
    • Passed directly to nm-initrd-generator as command-line arguments only
    • Other modules have no transformed parameters to misinterpret
    • The only thing written to /etc/cmdline.d/ is the ip=hcn marker, which makes both NetworkManager and the other Agama modules keep their hands off the network instead of falling back to DHCP on the bond ports
  2. Layer 2 - Isolated Generation:

    • Uses custom output directory: -c /run/hcn/system-connections
    • Prevents conflicts with standard /run/NetworkManager/system-connections/
    • Allows safe adaptation before making profiles visible to NetworkManager
  3. Layer 3 - Persistent Storage:

    • Copies adapted profiles to /etc/NetworkManager/system-connections/
    • Survives reboots (unlike /run which is tmpfs)
    • Protects against other modules that might rm /run/NetworkManager/system-connections/*
    • NetworkManager reads persistent profiles, ensuring HCN configuration survives

Key Insight: The dedicated parameters (rd.hcn.ip, rd.hcn.route) aren't just about syntax—they're about protecting the two-phase transformation workflow through isolated generation, persistent storage, and preventing regeneration triggers.

Profile Generation and Adaptation

High-Level Profile Structure

Generated NetworkManager profiles require modifications for hcnmgr compatibility:

Bond Profile Adaptations:

  • Rename from bond-bond<hcn-id>.nmconnection to bond<hcn-id>.nmconnection
  • Update connection ID to match filename
  • Generate deterministic UUID based on bond name
  • Ensure origin=nm-initrd-generator marker for persistence

Port Profile Adaptations:

  • Update controller references to match new bond profile name
  • Maintain proper controller/port relationships
  • Preserve MAC address bindings

Bond Configuration Structure

The bond interface is created with the following NetworkManager profile structure:

[connection]
id=bond333e80f5
uuid=<deterministic-uuid>
type=bond
interface-name=bond333e80f5
origin=nm-initrd-generator

[bond]
mode=active-backup
fail_over_mac=2
miimon=100
primary=enP32775p1s0

[ipv4]
method=manual
address1=192.168.1.10/24,192.168.1.1
route1=192.168.1.0/24,192.168.1.1

Port profiles reference this bond:

[connection]
id=bond333e80f5-enP32775p1s0
uuid=<generated-uuid>
type=ethernet
interface-name=enP32775p1s0
controller=bond333e80f5
port-type=bond
origin=nm-initrd-generator

[ethernet]
mac-address=<discovered-mac>

Two-Stage Persistence Architecture

Stage 1: Initramfs Persistence (HCN Module)

Location: /etc/NetworkManager/system-connections/

Purpose: Make profiles available to NetworkManager during initramfs and protect against module regeneration

Flow:

  1. parse-hcn.sh generates profiles in /run/hcn/system-connections/
  2. Profiles are adapted for hcnmgr compatibility (fixup process)
  3. Adapted profiles are copied to /etc/NetworkManager/system-connections/
  4. NetworkManager reads from /etc/NetworkManager/system-connections/ and activates the bond

Protection mechanisms:

  • /etc persists across dracut module execution (unlike /run which modules may clear)
  • Other dracut modules don't know about /run/hcn/system-connections/ (isolated generation)
  • No transformed parameters in /etc/cmdline.d/ prevents other modules from regenerating
  • The ip=hcn marker in /etc/cmdline.d/ prevents them from generating anything of their own

Stage 2: Installed System Persistence (Agama Module)

Location: Target system's /etc/NetworkManager/system-connections/

Purpose: Make HCN profiles available in the installed system for hcnmgr daemon

Flow:

  1. Agama's save-agama-conf.sh runs before system pivot
  2. Scans /etc/NetworkManager/system-connections/ for profiles with origin=nm-initrd-generator
  3. Copies matching profiles to installed system's /etc/NetworkManager/system-connections/
  4. After boot into installed system, hcnmgr daemon manages the bond profiles

Integration points:

  • inst.copy_network kernel parameter enables copying (default: enabled)
  • /run/agama/custom_dracut_network marker file indicates custom network configuration
  • Agama copies profiles with proper permissions and SELinux contexts

Future Considerations

Potential Enhancements

  1. IPv6 Support:

    • IPv6 static addressing should work (same parameter format)
    • IPv6 autoconfiguration needs testing: rd.hcn.ip=auto6
    • Multiple IPv6 addresses per bond
  2. Configurable Bond Options:

    • Currently hardcoded: mode=active-backup fail_over_mac=2 miimon=100
    • Could expose via rd.hcn.bond_options=...
    • Requires validation against hcnmgr expectations
  3. DNS Configuration:

    • The ip= format supports nameservers (8th and 9th field)
    • Example: rd.hcn.ip=192.168.1.10::192.168.1.1:255.255.255.0:::none:8.8.8.8
    • A plain nameserver= is carried over as well, see Carrying over the rest of the network command line
    • Needs testing and documentation
  4. VLAN Support:

    • HCN bonds may carry VLAN-tagged traffic
    • Requires additional parameter: rd.hcn.vlan=<vlan-id>
    • Profile generation for VLAN interfaces on top of bond
    • Rewriting a plain vlan=<name>:<port> to the bond is the easy half. The hard half is addressing the VLAN interface from rd.hcn.ip, which currently only understands ports, MACs and bond names, so vlan=, bridge= and team= are not carried over
  5. Configurable Timeout:

    • Current 180-second timeout may be insufficient on slow hardware or during complex LPM
    • Consider: rd.hcn.timeout=300

Known Limitations

  1. Timing Sensitivity:

    • 180-second timeout may be insufficient in rare cases
    • No retry mechanism for transient device-tree reading errors
  2. Error Reporting:

    • Failures may be silent if systemd journal is not checked
    • Consider using dracut-emergency for fatal errors
    • Could add visual indicators (Plymouth messages)
  3. Profile Compatibility:

    • Assumes hcnmgr naming conventions remain stable
    • Breaking changes in hcnmgr may require profile fixup updates
    • No version detection or compatibility checking
  4. Single-Bond Assumption in Simple Cases:

    • When no MAC address is specified, first discovered HCN ID is used
    • May be unexpected on multi-bond systems
  5. NetworkManager with ip=hcn Support Required:

    • The module relies on nm-initrd-generator understanding ip=hcn (jsc#PED-14534)
    • Older versions treat hcn as an unknown method and generate their own wired DHCP connection, which activates the bond ports individually and breaks the bond
    • There is no fallback: the marker is written whenever HCN devices are present

Maintenance Considerations

  • Dracut API Stability: Module relies on dracut hook conventions (cmdline phase, systemd service ordering)
  • NetworkManager Compatibility: Profile format changes between NetworkManager versions may require fixup updates
  • hcnmgr Evolution: Monitor hcnmgr for changes to profile format expectations, bond naming, or UUID structure
  • Kernel Parameter Namespace: rd.hcn.* namespace should be coordinated with upstream dracut to avoid conflicts

References