From 2b82a99fe0d3f2814812b41023030489e1071f5d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Zbigniew=20J=C4=99drzejewski-Szmek?= Date: Thu, 5 Dec 2019 09:22:13 +0100 Subject: growfs: define main function through macro --- src/partition/growfs.c | 84 +++++++++++++++++++------------------------------- 1 file changed, 32 insertions(+), 52 deletions(-) diff --git a/src/partition/growfs.c b/src/partition/growfs.c index 1dbc9a46d6..77bda6ea7f 100644 --- a/src/partition/growfs.c +++ b/src/partition/growfs.c @@ -18,6 +18,7 @@ #include "fd-util.h" #include "format-util.h" #include "log.h" +#include "main-func.h" #include "missing_fs.h" #include "mountpoint-util.h" #include "parse-util.h" @@ -231,7 +232,7 @@ static int parse_argv(int argc, char *argv[]) { return 1; } -int main(int argc, char *argv[]) { +static int run(int argc, char *argv[]) { _cleanup_close_ int mountfd = -1, devfd = -1; _cleanup_free_ char *devpath = NULL; uint64_t size, numblocks; @@ -244,58 +245,40 @@ int main(int argc, char *argv[]) { log_setup_service(); r = parse_argv(argc, argv); - if (r < 0) - return EXIT_FAILURE; - if (r == 0) - return EXIT_SUCCESS; + if (r <= 0) + return r; r = path_is_mount_point(arg_target, NULL, 0); - if (r < 0) { - log_error_errno(r, "Failed to check if \"%s\" is a mount point: %m", arg_target); - return EXIT_FAILURE; - } - if (r == 0) { - log_error_errno(r, "\"%s\" is not a mount point: %m", arg_target); - return EXIT_FAILURE; - } + if (r < 0) + return log_error_errno(r, "Failed to check if \"%s\" is a mount point: %m", arg_target); + if (r == 0) + return log_error_errno(SYNTHETIC_ERRNO(EINVAL), "\"%s\" is not a mount point: %m", arg_target); r = get_block_device(arg_target, &devno); - if (r < 0) { - log_error_errno(r, "Failed to determine block device of \"%s\": %m", arg_target); - return EXIT_FAILURE; - } + if (r < 0) + return log_error_errno(r, "Failed to determine block device of \"%s\": %m", arg_target); r = maybe_resize_slave_device(arg_target, devno); if (r < 0) - return EXIT_FAILURE; + return r; mountfd = open(arg_target, O_RDONLY|O_CLOEXEC); - if (mountfd < 0) { - log_error_errno(errno, "Failed to open \"%s\": %m", arg_target); - return EXIT_FAILURE; - } + if (mountfd < 0) + return log_error_errno(errno, "Failed to open \"%s\": %m", arg_target); r = device_path_make_major_minor(S_IFBLK, devno, &devpath); - if (r < 0) { - log_error_errno(r, "Failed to format device major/minor path: %m"); - return EXIT_FAILURE; - } + if (r < 0) + return log_error_errno(r, "Failed to format device major/minor path: %m"); devfd = open(devpath, O_RDONLY|O_CLOEXEC); - if (devfd < 0) { - log_error_errno(errno, "Failed to open \"%s\": %m", devpath); - return EXIT_FAILURE; - } + if (devfd < 0) + return log_error_errno(errno, "Failed to open \"%s\": %m", devpath); - if (ioctl(devfd, BLKBSZGET, &blocksize) != 0) { - log_error_errno(errno, "Failed to query block size of \"%s\": %m", devpath); - return EXIT_FAILURE; - } + if (ioctl(devfd, BLKBSZGET, &blocksize) != 0) + return log_error_errno(errno, "Failed to query block size of \"%s\": %m", devpath); - if (ioctl(devfd, BLKGETSIZE64, &size) != 0) { - log_error_errno(errno, "Failed to query size of \"%s\": %m", devpath); - return EXIT_FAILURE; - } + if (ioctl(devfd, BLKGETSIZE64, &size) != 0) + return log_error_errno(errno, "Failed to query size of \"%s\": %m", devpath); if (size % blocksize != 0) log_notice("Partition size %"PRIu64" is not a multiple of the blocksize %d," @@ -303,10 +286,8 @@ int main(int argc, char *argv[]) { numblocks = size / blocksize; - if (fstatfs(mountfd, &sfs) < 0) { - log_error_errno(errno, "Failed to stat file system \"%s\": %m", arg_target); - return EXIT_FAILURE; - } + if (fstatfs(mountfd, &sfs) < 0) + return log_error_errno(errno, "Failed to stat file system \"%s\": %m", arg_target); switch(sfs.f_type) { case EXT4_SUPER_MAGIC: @@ -316,15 +297,14 @@ int main(int argc, char *argv[]) { r = resize_btrfs(arg_target, mountfd, devfd, numblocks, blocksize); break; default: - log_error("Don't know how to resize fs %llx on \"%s\"", - (long long unsigned) sfs.f_type, arg_target); - return EXIT_FAILURE; + return log_error_errno(SYNTHETIC_ERRNO(EOPNOTSUPP), + "Don't know how to resize fs %llx on \"%s\"", + (long long unsigned) sfs.f_type, arg_target); } - - if (r < 0) - return EXIT_FAILURE; - - log_info("Successfully resized \"%s\" to %s bytes (%"PRIu64" blocks of %d bytes).", - arg_target, format_bytes(fb, sizeof fb, size), numblocks, blocksize); - return EXIT_SUCCESS; + if (r > 0) + log_info("Successfully resized \"%s\" to %s bytes (%"PRIu64" blocks of %d bytes).", + arg_target, format_bytes(fb, sizeof fb, size), numblocks, blocksize); + return r; } + +DEFINE_MAIN_FUNCTION(run); -- cgit v1.2.1 From d6f1e66076929f071830334800fc380bd4954806 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Zbigniew=20J=C4=99drzejewski-Szmek?= Date: Thu, 5 Dec 2019 10:15:49 +0100 Subject: growfs: port over to resize_fs() --- src/partition/growfs.c | 94 ++++++++++---------------------------------------- src/shared/resize-fs.c | 13 ++++++- src/shared/resize-fs.h | 2 +- 3 files changed, 31 insertions(+), 78 deletions(-) diff --git a/src/partition/growfs.c b/src/partition/growfs.c index 77bda6ea7f..7e2452a5d1 100644 --- a/src/partition/growfs.c +++ b/src/partition/growfs.c @@ -19,57 +19,14 @@ #include "format-util.h" #include "log.h" #include "main-func.h" -#include "missing_fs.h" #include "mountpoint-util.h" #include "parse-util.h" -#include "path-util.h" #include "pretty-print.h" -#include "stat-util.h" -#include "strv.h" -#include "util.h" +#include "resize-fs.h" static const char *arg_target = NULL; static bool arg_dry_run = false; -static int resize_ext4(const char *path, int mountfd, int devfd, uint64_t numblocks, uint64_t blocksize) { - assert((uint64_t) (int) blocksize == blocksize); - - if (arg_dry_run) - return 0; - - if (ioctl(mountfd, EXT4_IOC_RESIZE_FS, &numblocks) != 0) - return log_error_errno(errno, "Failed to resize \"%s\" to %"PRIu64" blocks (ext4): %m", - path, numblocks); - - return 0; -} - -static int resize_btrfs(const char *path, int mountfd, int devfd, uint64_t numblocks, uint64_t blocksize) { - struct btrfs_ioctl_vol_args args = {}; - int r; - - assert((uint64_t) (int) blocksize == blocksize); - - /* https://bugzilla.kernel.org/show_bug.cgi?id=118111 */ - if (numblocks * blocksize < 256*1024*1024) { - log_warning("%s: resizing of btrfs volumes smaller than 256M is not supported", path); - return -EOPNOTSUPP; - } - - r = snprintf(args.name, sizeof(args.name), "%"PRIu64, numblocks * blocksize); - /* The buffer is large enough for any number to fit... */ - assert((size_t) r < sizeof(args.name)); - - if (arg_dry_run) - return 0; - - if (ioctl(mountfd, BTRFS_IOC_RESIZE, &args) != 0) - return log_error_errno(errno, "Failed to resize \"%s\" to %"PRIu64" blocks (btrfs): %m", - path, numblocks); - - return 0; -} - #if HAVE_LIBCRYPTSETUP static int resize_crypt_luks_device(dev_t devno, const char *fstype, dev_t main_devno) { _cleanup_free_ char *devpath = NULL, *main_devpath = NULL; @@ -160,7 +117,7 @@ static int maybe_resize_slave_device(const char *mountpath, dev_t main_devno) { return resize_crypt_luks_device(devno, fstype, main_devno); #endif - log_debug("Don't know how to resize %s of type %s, ignoring", devpath, strnull(fstype)); + log_debug("Don't know how to resize %s of type %s, ignoring.", devpath, strnull(fstype)); return 0; } @@ -235,11 +192,9 @@ static int parse_argv(int argc, char *argv[]) { static int run(int argc, char *argv[]) { _cleanup_close_ int mountfd = -1, devfd = -1; _cleanup_free_ char *devpath = NULL; - uint64_t size, numblocks; + uint64_t size, newsize; char fb[FORMAT_BYTES_MAX]; - struct statfs sfs; dev_t devno; - int blocksize; int r; log_setup_service(); @@ -274,37 +229,24 @@ static int run(int argc, char *argv[]) { if (devfd < 0) return log_error_errno(errno, "Failed to open \"%s\": %m", devpath); - if (ioctl(devfd, BLKBSZGET, &blocksize) != 0) - return log_error_errno(errno, "Failed to query block size of \"%s\": %m", devpath); - if (ioctl(devfd, BLKGETSIZE64, &size) != 0) return log_error_errno(errno, "Failed to query size of \"%s\": %m", devpath); - if (size % blocksize != 0) - log_notice("Partition size %"PRIu64" is not a multiple of the blocksize %d," - " ignoring %"PRIu64" bytes", size, blocksize, size % blocksize); - - numblocks = size / blocksize; - - if (fstatfs(mountfd, &sfs) < 0) - return log_error_errno(errno, "Failed to stat file system \"%s\": %m", arg_target); - - switch(sfs.f_type) { - case EXT4_SUPER_MAGIC: - r = resize_ext4(arg_target, mountfd, devfd, numblocks, blocksize); - break; - case BTRFS_SUPER_MAGIC: - r = resize_btrfs(arg_target, mountfd, devfd, numblocks, blocksize); - break; - default: - return log_error_errno(SYNTHETIC_ERRNO(EOPNOTSUPP), - "Don't know how to resize fs %llx on \"%s\"", - (long long unsigned) sfs.f_type, arg_target); - } - if (r > 0) - log_info("Successfully resized \"%s\" to %s bytes (%"PRIu64" blocks of %d bytes).", - arg_target, format_bytes(fb, sizeof fb, size), numblocks, blocksize); - return r; + log_debug("Resizing \"%s\" to %"PRIu64" bytes...", arg_target, size); + r = resize_fs(mountfd, size, &newsize); + if (r < 0) + return log_error_errno(r, "Failed to resize \"%s\" to %"PRIu64" bytes: %m", + arg_target, size); + if (newsize == size) + log_info("Successfully resized \"%s\" to %s bytes.", + arg_target, + format_bytes(fb, sizeof fb, newsize)); + else + log_info("Successfully resized \"%s\" to %s bytes (%"PRIu64" bytes lost due to blocksize).", + arg_target, + format_bytes(fb, sizeof fb, newsize), + size - newsize); + return 0; } DEFINE_MAIN_FUNCTION(run); diff --git a/src/shared/resize-fs.c b/src/shared/resize-fs.c index 9f33dd77d8..5ed26a6c92 100644 --- a/src/shared/resize-fs.c +++ b/src/shared/resize-fs.c @@ -13,7 +13,7 @@ #include "resize-fs.h" #include "stat-util.h" -int resize_fs(int fd, uint64_t sz) { +int resize_fs(int fd, uint64_t sz, uint64_t *ret_size) { struct statfs sfs; int r; @@ -38,6 +38,9 @@ int resize_fs(int fd, uint64_t sz) { if (ioctl(fd, EXT4_IOC_RESIZE_FS, &u) < 0) return -errno; + if (ret_size) + *ret_size = u * sfs.f_bsize; + } else if (is_fs_type(&sfs, BTRFS_SUPER_MAGIC)) { struct btrfs_ioctl_vol_args args = {}; @@ -49,12 +52,17 @@ int resize_fs(int fd, uint64_t sz) { if (sz < BTRFS_MINIMAL_SIZE) return -ERANGE; + sz -= sz % sfs.f_bsize; + r = snprintf(args.name, sizeof(args.name), "%" PRIu64, sz); assert((size_t) r < sizeof(args.name)); if (ioctl(fd, BTRFS_IOC_RESIZE, &args) < 0) return -errno; + if (ret_size) + *ret_size = sz; + } else if (is_fs_type(&sfs, XFS_SB_MAGIC)) { xfs_fsop_geom_t geo; xfs_growfs_data_t d; @@ -73,6 +81,9 @@ int resize_fs(int fd, uint64_t sz) { if (ioctl(fd, XFS_IOC_FSGROWFSDATA, &d) < 0) return -errno; + if (ret_size) + *ret_size = d.newblocks * geo.blocksize; + } else return -EOPNOTSUPP; diff --git a/src/shared/resize-fs.h b/src/shared/resize-fs.h index b544176528..92b41d318c 100644 --- a/src/shared/resize-fs.h +++ b/src/shared/resize-fs.h @@ -5,7 +5,7 @@ #include "stat-util.h" -int resize_fs(int fd, uint64_t sz); +int resize_fs(int fd, uint64_t sz, uint64_t *ret_size); #define BTRFS_MINIMAL_SIZE (256U*1024U*1024U) #define XFS_MINIMAL_SIZE (14U*1024U*1024U) -- cgit v1.2.1