]> git.ipfire.org Git - thirdparty/systemd.git/commitdiff
dissect-image: optionally, grow file systems on mount
authorLennart Poettering <lennart@poettering.net>
Wed, 21 Apr 2021 14:37:09 +0000 (16:37 +0200)
committerLennart Poettering <lennart@poettering.net>
Fri, 23 Apr 2021 15:56:23 +0000 (17:56 +0200)
The new GPT partition flag the previous commits added is now honoured on
mount.

src/shared/dissect-image.c
src/shared/dissect-image.h

index 37c27d41604f6ad86f2d1ccfa8e514cbf559d676..183d5f426d7b3798dd19df0c7409dd04dfacffaa 100644 (file)
@@ -46,6 +46,7 @@
 #include "path-util.h"
 #include "process-util.h"
 #include "raw-clone.h"
+#include "resize-fs.h"
 #include "signal-util.h"
 #include "stat-util.h"
 #include "stdio-util.h"
@@ -1438,6 +1439,43 @@ static int run_fsck(const char *node, const char *fstype) {
         return 0;
 }
 
+static int fs_grow(const char *node_path, const char *mount_path) {
+        _cleanup_close_ int mount_fd = -1, node_fd = -1;
+        char fb[FORMAT_BYTES_MAX];
+        uint64_t size, newsize;
+        int r;
+
+        node_fd = open(node_path, O_RDONLY|O_CLOEXEC|O_NONBLOCK|O_NOCTTY);
+        if (node_fd < 0)
+                return log_debug_errno(errno, "Failed to open node device %s: %m", node_path);
+
+        if (ioctl(node_fd, BLKGETSIZE64, &size) != 0)
+                return log_debug_errno(errno, "Failed to get block device size of %s: %m", node_path);
+
+        mount_fd = open(mount_path, O_RDONLY|O_DIRECTORY|O_CLOEXEC);
+        if (mount_fd < 0)
+                return log_debug_errno(errno, "Failed to open mountd file system %s: %m", mount_path);
+
+        log_debug("Resizing \"%s\" to %"PRIu64" bytes...", mount_path, size);
+        r = resize_fs(mount_fd, size, &newsize);
+        if (r < 0)
+                return log_debug_errno(r, "Failed to resize \"%s\" to %"PRIu64" bytes: %m", mount_path, size);
+
+        if (newsize == size)
+                log_debug("Successfully resized \"%s\" to %s bytes.",
+                          mount_path,
+                          format_bytes(fb, sizeof fb, newsize));
+        else {
+                assert(newsize < size);
+                log_debug("Successfully resized \"%s\" to %s bytes (%"PRIu64" bytes lost due to blocksize).",
+                          mount_path,
+                          format_bytes(fb, sizeof fb, newsize),
+                          size - newsize);
+        }
+
+        return 0;
+}
+
 static int mount_partition(
                 DissectedPartition *m,
                 const char *where,
@@ -1546,6 +1584,9 @@ static int mount_partition(
         if (r < 0)
                 return r;
 
+        if (rw && m->growfs && FLAGS_SET(flags, DISSECT_IMAGE_GROWFS))
+                (void) fs_grow(node, p);
+
         return 1;
 }
 
index 822380323ab661c9cb2b48a43ade8975e7e80117..b2f5c5dc96b16f29aa04a6d0f9976694d0ddd92e 100644 (file)
@@ -111,6 +111,7 @@ typedef enum DissectImageFlags {
         DISSECT_IMAGE_MOUNT_READ_ONLY     = 1 << 17, /* Make mounts read-only */
         DISSECT_IMAGE_READ_ONLY           = DISSECT_IMAGE_DEVICE_READ_ONLY |
                                             DISSECT_IMAGE_MOUNT_READ_ONLY,
+        DISSECT_IMAGE_GROWFS              = 1 << 18, /* Grow file systems in partitions marked for that to the size of the partitions after mount */
 } DissectImageFlags;
 
 struct DissectedImage {