From 12c29e5b3a1d9294f2a1c0a4a83335fa23c272b8 Mon Sep 17 00:00:00 2001 From: Daan De Meyer Date: Wed, 18 Sep 2024 16:42:12 +0200 Subject: [PATCH] Revert "repart: Drop unprivileged subvolumes logic for btrfs" 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 | 67 +++++++++++++++++++++++++++++++++++++++------ 1 file changed, 58 insertions(+), 9 deletions(-) diff --git a/src/repart/repart.c b/src/repart/repart.c index e485cd5231d..9515b7539ff 100644 --- a/src/repart/repart.c +++ b/src/repart/repart.c @@ -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; } -- 2.47.3