]> git.ipfire.org Git - thirdparty/systemd.git/commitdiff
Revert "repart: Drop unprivileged subvolumes logic for btrfs"
authorDaan De Meyer <daan.j.demeyer@gmail.com>
Wed, 18 Sep 2024 14:42:12 +0000 (16:42 +0200)
committerDaan De Meyer <daan.j.demeyer@gmail.com>
Fri, 13 Dec 2024 14:05:32 +0000 (14:05 +0000)
This adds back support for unprivileged btrfs subvolumes which
can be merged once btrfs-progs 6.12 is out.

This reverts commit 4d9ccdc9aec5728a6bfc66879420b2af25817e03.

src/repart/repart.c

index e485cd5231d5c1e6b33b6854a20f308bc3abd331..9515b7539ff8f2969aa18e14f7b27810e94d642c 100644 (file)
@@ -308,6 +308,19 @@ static SubvolumeFlags subvolume_flags_from_string(const char *s) {
         return flags;
 }
 
+static char* subvolume_flags_to_string(SubvolumeFlags flags) {
+        const char *l[CONST_LOG2U(_SUBVOLUME_FLAGS_MASK + 1) + 1]; /* one string per known flag at most */
+        size_t m = 0;
+
+        if (FLAGS_SET(flags, SUBVOLUME_RO))
+                l[m++] = "ro";
+
+        assert(m < ELEMENTSOF(l));
+        l[m] = NULL;
+
+        return strv_join((char**) l, ",");
+}
+
 typedef struct Subvolume {
         char *path;
         SubvolumeFlags flags;
@@ -2487,14 +2500,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 (!ordered_hashmap_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 && !ordered_hashmap_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=.");
@@ -4342,7 +4347,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)) || !ordered_hashmap_isempty(p->subvolumes) || p->default_subvolume;
+        return arg_offline == 0 || (r != -ENOENT && !ERRNO_IS_PRIVILEGE(r));
 }
 
 static int partition_target_prepare(
@@ -5902,6 +5907,38 @@ static int partition_populate_filesystem(Context *context, Partition *p, const c
         return 0;
 }
 
+static int append_btrfs_subvols(char ***l, OrderedHashmap *subvolumes, const char *default_subvolume) {
+        Subvolume *subvolume;
+        int r;
+
+        assert(l);
+
+        ORDERED_HASHMAP_FOREACH(subvolume, subvolumes) {
+                _cleanup_free_ char *s = NULL, *f = NULL;
+
+                s = strdup(subvolume->path);
+                if (!s)
+                        return log_oom();
+
+                f = subvolume_flags_to_string(subvolume->flags);
+                if (!f)
+                        return log_oom();
+
+                if (streq_ptr(subvolume->path, default_subvolume) &&
+                    !strextend_with_separator(&f, ",", "default"))
+                        return log_oom();
+
+                if (!isempty(f) && !strextend_with_separator(&s, ":", f))
+                        return log_oom();
+
+                r = strv_extend_many(l, "--subvol", s);
+                if (r < 0)
+                        return log_oom();
+        }
+
+        return 0;
+}
+
 static int finalize_extra_mkfs_options(const Partition *p, const char *root, char ***ret) {
         _cleanup_strv_free_ char **sv = NULL;
         int r;
@@ -5915,6 +5952,18 @@ static int finalize_extra_mkfs_options(const Partition *p, const char *root, cha
                                        "Failed to determine mkfs command line options for '%s': %m",
                                        p->format);
 
+        if (partition_needs_populate(p) && root && streq(p->format, "btrfs")) {
+                r = append_btrfs_subvols(&sv, p->subvolumes, p->default_subvolume);
+                if (r < 0)
+                        return r;
+
+                if (p->suppressing) {
+                        r = append_btrfs_subvols(&sv, p->suppressing->subvolumes, NULL);
+                        if (r < 0)
+                                return r;
+                }
+        }
+
         *ret = TAKE_PTR(sv);
         return 0;
 }