]> git.ipfire.org Git - thirdparty/systemd.git/commitdiff
fstab-generator: validate root= and mount.usr= the same way
authorLennart Poettering <lennart@poettering.net>
Mon, 10 Feb 2025 12:12:46 +0000 (13:12 +0100)
committerLennart Poettering <lennart@poettering.net>
Fri, 21 Feb 2025 09:03:32 +0000 (10:03 +0100)
In both cases, let's check for the same special mount sources. We
already covered some of the same, but let's just make it the same
codepaths.

man/systemd-import-generator.xml
src/fstab-generator/fstab-generator.c

index dfadf5db5fc40f4223bb4c6bb6a828661760a642..ba95ebe2c1700b6e0e7b02142ae56a017767f562 100644 (file)
     <example>
       <title>Boot into disk image (tar), with URL derived from UEFI HTTP network booting</title>
 
-      <programlisting>systemd.pull=tar,machine,verify=no,bootorigin:root:image.tar.xz root=bind:/run/machines/root</programlisting>
+      <programlisting>rd.systemd.pull=tar,machine,verify=no,bootorigin:root:image.tar.xz root=bind:/run/machines/root</programlisting>
 
       <para>This is similar to the previous example, but instead of a raw (i.e. block device based) disk
       image the system boots into a tarball that is downloaded from the originating UEFI network
index 475981f36d06e840131df0476006227c8d9dda06..6693333c4b18999529eec88cd8b184ba0709f1c2 100644 (file)
@@ -1058,12 +1058,12 @@ static int parse_fstab(bool prefix_sysroot) {
         return ret;
 }
 
-static int sysroot_is_nfsroot(void) {
+static int mount_source_is_nfsroot(const char *what) {
         union in_addr_union u;
         const char *sep, *a;
         int r;
 
-        assert(arg_root_what);
+        assert(what);
 
         /* From dracut.cmdline(7).
          *
@@ -1076,18 +1076,18 @@ static int sysroot_is_nfsroot(void) {
          * If server-ip is an IPv6 address it has to be put in brackets, e.g. [2001:DB8::1]. NFS options
          * can be appended with the prefix ":" or "," and are separated by ",". */
 
-        if (path_equal(arg_root_what, "/dev/nfs") ||
-            STR_IN_SET(arg_root_what, "dhcp", "dhcp6") ||
-            STARTSWITH_SET(arg_root_what, "nfs:", "nfs4:"))
+        if (path_equal(what, "/dev/nfs") ||
+            STR_IN_SET(what, "dhcp", "dhcp6") ||
+            STARTSWITH_SET(what, "nfs:", "nfs4:"))
                 return true;
 
         /* IPv6 address */
-        if (arg_root_what[0] == '[') {
-                sep = strchr(arg_root_what + 1, ']');
+        if (what[0] == '[') {
+                sep = strchr(what + 1, ']');
                 if (!sep)
                         return -EINVAL;
 
-                a = strndupa_safe(arg_root_what + 1, sep - arg_root_what - 1);
+                a = strndupa_safe(what + 1, sep - what - 1);
 
                 r = in_addr_from_string(AF_INET6, a, &u);
                 if (r < 0)
@@ -1097,64 +1097,76 @@ static int sysroot_is_nfsroot(void) {
         }
 
         /* IPv4 address */
-        sep = strchr(arg_root_what, ':');
+        sep = strchr(what, ':');
         if (sep) {
-                a = strndupa_safe(arg_root_what, sep - arg_root_what);
+                a = strndupa_safe(what, sep - what);
 
                 if (in_addr_from_string(AF_INET, a, &u) >= 0)
                         return true;
         }
 
         /* root directory without address */
-        return path_is_absolute(arg_root_what) && !path_startswith(arg_root_what, "/dev");
+        return path_is_absolute(what) && !path_startswith(what, "/dev");
 }
 
-static int add_sysroot_mount(void) {
-        _cleanup_free_ char *what = NULL;
-        const char *extra_opts = NULL, *fstype = NULL;
-        bool default_rw = true, makefs = false;
-        MountPointFlags flags;
+static bool validate_root_or_usr_mount_source(const char *what, const char *switch_name) {
         int r;
 
-        if (isempty(arg_root_what)) {
-                log_debug("Could not find a root= entry on the kernel command line.");
-                return 0;
+        assert(switch_name);
+
+        if (isempty(what)) {
+                log_debug("No %s switch specified on the kernel command line.", switch_name);
+                return false;
         }
 
-        if (streq(arg_root_what, "gpt-auto")) {
+        if (streq(what, "gpt-auto")) {
                 /* This is handled by gpt-auto-generator */
-                log_debug("Skipping root directory handling, as gpt-auto was requested.");
-                return 0;
-        } else if (streq(arg_root_what, "fstab")) {
-                /* This is handled by parse_fstab */
-                log_debug("Using initrd's fstab for /sysroot/ configuration.");
-                return 0;
+                log_debug("Skipping %s directory handling, as gpt-auto was requested.", switch_name);
+                return false;
+        }
+
+        if (streq(what, "fstab")) {
+                /* This is handled by parse_fstab() */
+                log_debug("Using initrd's fstab for %s configuration.", switch_name);
+                return false;
         }
 
-        r = sysroot_is_nfsroot();
+        r = mount_source_is_nfsroot(what);
         if (r < 0)
-                log_debug_errno(r, "Failed to determine if the root directory is on NFS, assuming not: %m");
+                log_debug_errno(r, "Failed to determine if the %s directory is on NFS, assuming not: %m", switch_name);
         else if (r > 0) {
                 /* This is handled by the kernel or the initrd */
-                log_debug("Skipping root directory handling, as root on NFS was requested.");
-                return 0;
+                log_debug("Skipping %s directory handling, as root on NFS was requested.", switch_name);
+                return false;
         }
 
-        if (startswith(arg_root_what, "cifs://")) {
-                log_debug("Skipping root directory handling, as root on CIFS was requested.");
-                return 0;
+        if (startswith(what, "cifs://")) {
+                log_debug("Skipping %s directory handling, as root on CIFS was requested.", switch_name);
+                return false;
         }
 
-        if (startswith(arg_root_what, "iscsi:")) {
-                log_debug("Skipping root directory handling, as root on iSCSI was requested.");
-                return 0;
+        if (startswith(what, "iscsi:")) {
+                log_debug("Skipping %s directory handling, as root on iSCSI was requested.", switch_name);
+                return false;
         }
 
-        if (startswith(arg_root_what, "live:")) {
-                log_debug("Skipping root directory handling, as root on live image was requested.");
-                return 0;
+        if (startswith(what, "live:")) {
+                log_debug("Skipping %s directory handling, as root on live image was requested.", switch_name);
+                return false;
         }
 
+        return true;
+}
+
+static int add_sysroot_mount(void) {
+        _cleanup_free_ char *what = NULL;
+        const char *extra_opts = NULL, *fstype = NULL;
+        bool default_rw = true, makefs = false;
+        MountPointFlags flags;
+
+        if (!validate_root_or_usr_mount_source(arg_root_what, "root="))
+                return 0;
+
         const char *bind = startswith(arg_root_what, "bind:");
         if (bind) {
                 if (!path_is_valid(bind) || !path_is_absolute(bind)) {
@@ -1248,28 +1260,8 @@ static int add_sysroot_usr_mount(void) {
                         return log_oom();
         }
 
-        if (isempty(arg_usr_what)) {
-                log_debug("Could not find a mount.usr= entry on the kernel command line.");
+        if (!validate_root_or_usr_mount_source(arg_usr_what, "mount.usr="))
                 return 0;
-        }
-
-        if (streq(arg_usr_what, "gpt-auto")) {
-                /* This is handled by the gpt-auto generator */
-                log_debug("Skipping /usr/ directory handling, as gpt-auto was requested.");
-                return 1; /* systemd-gpt-auto-generator will generate a unit for this, hence report that a
-                           * unit file is being created for the host /usr/ mount. */
-        } else if (streq(arg_usr_what, "fstab")) {
-                /* This is handled by parse_fstab */
-                log_debug("Using initrd's fstab for /sysroot/usr/ configuration.");
-                return 1; /* parse_fstab will generate a unit for this, hence report that a
-                           * unit file is being created for the host /usr/ mount. */
-        }
-
-        if (path_equal(arg_usr_what, "/dev/nfs")) {
-                /* This is handled by the initrd (if at all supported, that is) */
-                log_debug("Skipping /usr/ directory handling, as /dev/nfs was requested.");
-                return 1; /* As above, report that NFS code will create the unit */
-        }
 
         const char *bind = startswith(arg_usr_what, "bind:");
         if (bind) {