]> git.ipfire.org Git - thirdparty/systemd.git/commitdiff
repart: Allow Subvolumes= and DefaultSubvolume= when running offline 33498/head
authorDaan De Meyer <daan.j.demeyer@gmail.com>
Wed, 26 Jun 2024 18:33:06 +0000 (20:33 +0200)
committerDaan De Meyer <daan.j.demeyer@gmail.com>
Wed, 21 Aug 2024 09:29:47 +0000 (11:29 +0200)
mkfs.btrfs has recently learned new options --subvol and --default-subvol
so let's stop failing when Subvolumes= and DefaultSubvolume= are used offline
and use the new --subvol and --default-subvol options instead to create subvolumes
in the generated root filesystem without root privileges or loop devices.

man/repart.d.xml
src/partition/repart.c

index ecf14e30998eebec157afd31a2c6b41441f9095b..4ad27649335c2b251bcc76f659e622c539829eee 100644 (file)
         <para>Note that this option only takes effect if the target filesystem supports subvolumes, such as
         <literal>btrfs</literal>.</para>
 
-        <para>Note that due to limitations of <literal>mkfs.btrfs</literal>, this option is only supported
-        when running with <option>--offline=no</option>.</para>
+        <para>Note that this option is only supported in combination with <option>--offline=yes</option>
+        since btrfs-progs 6.11 or newer.</para>
 
         <xi:include href="version-info.xml" xpointer="v255"/></listitem>
       </varlistentry>
         <para>Note that this option only takes effect if the target filesystem supports subvolumes, such as
         <literal>btrfs</literal>.</para>
 
-        <para>Note that due to limitations of <literal>mkfs.btrfs</literal>, this option is only supported
-        when running with <option>--offline=no</option>.</para>
+        <para>Note that this option is only supported in combination with <option>--offline=yes</option>
+        since btrfs-progs 6.11 or newer.</para>
 
         <xi:include href="version-info.xml" xpointer="v256"/></listitem>
       </varlistentry>
index 967059dbeab1b783aff01ae55825ce19282e9004..222c0958ef7145ee2ea4c420a292f7b535aba3b5 100644 (file)
@@ -2087,14 +2087,6 @@ static int partition_read_definition(Partition *p, const char *path, const char
                                   "SizeMinBytes=/SizeMaxBytes= cannot be used with Verity=%s.",
                                   verity_mode_to_string(p->verity));
 
-        if (!strv_isempty(p->subvolumes) && arg_offline > 0)
-                return log_syntax(NULL, LOG_ERR, path, 1, SYNTHETIC_ERRNO(EOPNOTSUPP),
-                                  "Subvolumes= cannot be used with --offline=yes.");
-
-        if (p->default_subvolume && arg_offline > 0)
-                return log_syntax(NULL, LOG_ERR, path, 1, SYNTHETIC_ERRNO(EOPNOTSUPP),
-                                  "DefaultSubvolume= cannot be used with --offline=yes.");
-
         if (p->default_subvolume && !path_strv_contains(p->subvolumes, p->default_subvolume))
                 return log_syntax(NULL, LOG_ERR, path, 1, SYNTHETIC_ERRNO(EINVAL),
                                   "DefaultSubvolume= must be one of the paths in Subvolumes=.");
@@ -3840,7 +3832,7 @@ static int prepare_temporary_file(Context *context, PartitionTarget *t, uint64_t
 
 static bool loop_device_error_is_fatal(const Partition *p, int r) {
         assert(p);
-        return arg_offline == 0 || (r != -ENOENT && !ERRNO_IS_PRIVILEGE(r)) || !strv_isempty(p->subvolumes) || p->default_subvolume;
+        return arg_offline == 0 || (r != -ENOENT && !ERRNO_IS_PRIVILEGE(r));
 }
 
 static int partition_target_prepare(
@@ -5156,6 +5148,40 @@ static int partition_populate_filesystem(Context *context, Partition *p, const c
         return 0;
 }
 
+static int finalize_extra_mkfs_options(const Partition *p, const char *root, char ***ret) {
+        int r;
+        _cleanup_strv_free_ char **sv = NULL;
+
+        assert(p);
+        assert(ret);
+
+        r = mkfs_options_from_env("REPART", p->format, &sv);
+        if (r < 0)
+                return log_error_errno(r,
+                                       "Failed to determine mkfs command line options for '%s': %m",
+                                       p->format);
+
+        if (partition_needs_populate(p) && root && streq(p->format, "btrfs")) {
+                STRV_FOREACH(subvol, p->subvolumes) {
+                        if (p->default_subvolume && streq(*subvol, p->default_subvolume))
+                                continue;
+
+                        r = strv_extend_many(&sv, "--subvol", *subvol);
+                        if (r < 0)
+                                return log_oom();
+                }
+
+                if (p->default_subvolume) {
+                        r = strv_extend_many(&sv, "--default-subvol", p->default_subvolume);
+                        if (r < 0)
+                                return log_oom();
+                }
+        }
+
+        *ret = TAKE_PTR(sv);
+        return 0;
+}
+
 static int context_mkfs(Context *context) {
         int r;
 
@@ -5224,11 +5250,9 @@ static int context_mkfs(Context *context) {
                                 return r;
                 }
 
-                r = mkfs_options_from_env("REPART", p->format, &extra_mkfs_options);
+                r = finalize_extra_mkfs_options(p, root, &extra_mkfs_options);
                 if (r < 0)
-                        return log_error_errno(r,
-                                               "Failed to determine mkfs command line options for '%s': %m",
-                                               p->format);
+                        return r;
 
                 r = make_filesystem(partition_target_path(t), p->format, strempty(p->new_label), root,
                                     p->fs_uuid, arg_discard, /* quiet = */ false,
@@ -6785,11 +6809,9 @@ static int context_minimize(Context *context) {
                                 return r;
                 }
 
-                r = mkfs_options_from_env("REPART", p->format, &extra_mkfs_options);
+                r = finalize_extra_mkfs_options(p, root, &extra_mkfs_options);
                 if (r < 0)
-                        return log_error_errno(r,
-                                               "Failed to determine mkfs command line options for '%s': %m",
-                                               p->format);
+                        return r;
 
                 r = make_filesystem(d ? d->node : temp,
                                     p->format,