summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLennart Poettering <lennart@poettering.net>2021-04-21 16:37:09 +0200
committerLennart Poettering <lennart@poettering.net>2021-04-23 17:56:23 +0200
commit81939d9d5e31ad6c133fd0ca1bf4851c821b366f (patch)
treef0ae82631e6299108f1983e987b91091db0b78fc
parentdissect: show growfs flag in systemd-dissect table output (diff)
downloadsystemd-81939d9d5e31ad6c133fd0ca1bf4851c821b366f.tar.xz
systemd-81939d9d5e31ad6c133fd0ca1bf4851c821b366f.zip
dissect-image: optionally, grow file systems on mount
The new GPT partition flag the previous commits added is now honoured on mount.
-rw-r--r--src/shared/dissect-image.c41
-rw-r--r--src/shared/dissect-image.h1
2 files changed, 42 insertions, 0 deletions
diff --git a/src/shared/dissect-image.c b/src/shared/dissect-image.c
index 37c27d4160..183d5f426d 100644
--- a/src/shared/dissect-image.c
+++ b/src/shared/dissect-image.c
@@ -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;
}
diff --git a/src/shared/dissect-image.h b/src/shared/dissect-image.h
index 822380323a..b2f5c5dc96 100644
--- a/src/shared/dissect-image.h
+++ b/src/shared/dissect-image.h
@@ -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 {