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;
"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=.");
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(
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;
"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;
}