]> git.ipfire.org Git - thirdparty/systemd.git/commitdiff
mkfs-util: Add root support for ext and btrfs
authorDaan De Meyer <daan.j.demeyer@gmail.com>
Fri, 7 Oct 2022 19:21:46 +0000 (21:21 +0200)
committerDaan De Meyer <daan.j.demeyer@gmail.com>
Tue, 15 Nov 2022 19:07:54 +0000 (20:07 +0100)
For these filesysrems, it's useful to provide the filesystem upfront
so that we don't have to mount it later which requires root privileges.

src/partition/repart.c
src/shared/mkfs-util.c
src/shared/mkfs-util.h

index f4c37087662f664762fc23babd502beeb0c9f030..d0420435761908d45cb8e89b800854dd28b885e3 100644 (file)
@@ -3604,7 +3604,7 @@ static int context_mkfs(Context *context) {
                  * filesystem because it's read-only, so instead we create a temporary root to use as the
                  * source tree when generating the read-only filesystem. */
 
-                if (fstype_is_ro(p->format)) {
+                if (mkfs_supports_root_option(p->format)) {
                         r = partition_populate_directory(p, denylist, &root, &tmp_root);
                         if (r < 0)
                                 return r;
@@ -3625,7 +3625,7 @@ static int context_mkfs(Context *context) {
                                 return log_error_errno(errno, "Failed to unlock LUKS device: %m");
 
                 /* Now, we can populate all the other filesystems that aren't read-only. */
-                if (!fstype_is_ro(p->format)) {
+                if (!mkfs_supports_root_option(p->format)) {
                         r = partition_populate_filesystem(p, fsdev, denylist);
                         if (r < 0) {
                                 encrypted_dev_fd = safe_close(encrypted_dev_fd);
@@ -5144,7 +5144,9 @@ static int context_minimize(Context *context) {
                 if (r < 0)
                         return log_error_errno(r, "Failed to generate temporary file path: %m");
 
-                if (!fstype_is_ro(p->format)) {
+                if (fstype_is_ro(p->format))
+                        fs_uuid = p->fs_uuid;
+                else {
                         fd = open(temp, O_CREAT|O_EXCL|O_CLOEXEC|O_RDWR|O_NOCTTY, 0600);
                         if (fd < 0)
                                 return log_error_errno(errno, "Failed to open temporary file %s: %m", temp);
@@ -5160,12 +5162,12 @@ static int context_minimize(Context *context) {
                         r = sd_id128_randomize(&fs_uuid);
                         if (r < 0)
                                 return r;
-                } else {
+                }
+
+                if (mkfs_supports_root_option(p->format)) {
                         r = partition_populate_directory(p, denylist, &root, &tmp_root);
                         if (r < 0)
                                 return r;
-
-                        fs_uuid = p->fs_uuid;
                 }
 
                 r = make_filesystem(temp, p->format, strempty(p->new_label), root ?: tmp_root, fs_uuid,
@@ -5180,9 +5182,11 @@ static int context_minimize(Context *context) {
                         continue;
                 }
 
-                r = partition_populate_filesystem(p, temp, denylist);
-                if (r < 0)
-                        return r;
+                if (!mkfs_supports_root_option(p->format)) {
+                        r = partition_populate_filesystem(p, temp, denylist);
+                        if (r < 0)
+                                return r;
+                }
 
                 /* Other filesystems need to be provided with a pre-sized loopback file and will adapt to
                  * fully occupy it. Because we gave the filesystem a 1T sparse file, we need to shrink the
@@ -5216,9 +5220,11 @@ static int context_minimize(Context *context) {
                 if (r < 0)
                         return r;
 
-                r = partition_populate_filesystem(p, temp, denylist);
-                if (r < 0)
-                        return r;
+                if (!mkfs_supports_root_option(p->format)) {
+                        r = partition_populate_filesystem(p, temp, denylist);
+                        if (r < 0)
+                                return r;
+                }
 
                 p->copy_blocks_path = TAKE_PTR(temp);
         }
index 0f23a96de2017e8e086d6e13a4e280b36c7e86ae..f7f4a35212fe9653f5534c7c5fe8d9e2c4b779ed 100644 (file)
@@ -33,6 +33,10 @@ int mkfs_exists(const char *fstype) {
         return true;
 }
 
+int mkfs_supports_root_option(const char *fstype) {
+        return fstype_is_ro(fstype) || STR_IN_SET(fstype, "ext2", "ext3", "ext4", "btrfs");
+}
+
 static int mangle_linux_fs_label(const char *s, size_t max_len, char **ret) {
         /* Not more than max_len bytes (12 or 16) */
 
@@ -129,9 +133,9 @@ int make_filesystem(
                                                        "Don't know how to create read-only file system '%s', refusing.",
                                                        fstype);
         } else {
-                if (root)
+                if (root && !mkfs_supports_root_option(fstype))
                         return log_error_errno(SYNTHETIC_ERRNO(EOPNOTSUPP),
-                                               "Populating with source tree is only supported for read-only filesystems");
+                                               "Populating with source tree is not supported for %s", fstype);
                 r = mkfs_exists(fstype);
                 if (r < 0)
                         return log_error_errno(r, "Failed to determine whether mkfs binary for %s exists: %m", fstype);
@@ -171,7 +175,7 @@ int make_filesystem(
                 assert_se(sd_id128_to_uuid_string(uuid, vol_id));
 
         /* When changing this conditional, also adjust the log statement below. */
-        if (streq(fstype, "ext2"))
+        if (streq(fstype, "ext2")) {
                 argv = strv_new(mkfs,
                                 "-q",
                                 "-L", label,
@@ -180,8 +184,16 @@ int make_filesystem(
                                 "-m", "0",
                                 "-E", discard ? "discard,lazy_itable_init=1" : "nodiscard,lazy_itable_init=1",
                                 node);
+                if (!argv)
+                        return log_oom();
+
+                if (root) {
+                        r = strv_extend_strv(&argv, STRV_MAKE("-d", root), false);
+                        if (r < 0)
+                                return log_oom();
+                }
 
-        else if (STR_IN_SET(fstype, "ext3", "ext4"))
+        } else if (STR_IN_SET(fstype, "ext3", "ext4")) {
                 argv = strv_new(mkfs,
                                 "-q",
                                 "-L", label,
@@ -192,7 +204,13 @@ int make_filesystem(
                                 "-E", discard ? "discard,lazy_itable_init=1" : "nodiscard,lazy_itable_init=1",
                                 node);
 
-        else if (streq(fstype, "btrfs")) {
+                if (root) {
+                        r = strv_extend_strv(&argv, STRV_MAKE("-d", root), false);
+                        if (r < 0)
+                                return log_oom();
+                }
+
+        } else if (streq(fstype, "btrfs")) {
                 argv = strv_new(mkfs,
                                 "-q",
                                 "-L", label,
@@ -207,6 +225,12 @@ int make_filesystem(
                                 return log_oom();
                 }
 
+                if (root) {
+                        r = strv_extend_strv(&argv, STRV_MAKE("-r", root), false);
+                        if (r < 0)
+                                return log_oom();
+                }
+
         } else if (streq(fstype, "f2fs")) {
                 argv = strv_new(mkfs,
                                 "-q",
index 3125ef176d6babd4cfbdaac7753a9db79200625b..62061c6647d2684bc48ad4aa23d993e0cdcaf7ca 100644 (file)
@@ -9,4 +9,6 @@
 
 int mkfs_exists(const char *fstype);
 
+int mkfs_supports_root_option(const char *fstype);
+
 int make_filesystem(const char *node, const char *fstype, const char *label, const char *root, sd_id128_t uuid, bool discard);