summaryrefslogtreecommitdiffstats
path: root/src/partition/growfs.c
diff options
context:
space:
mode:
authorLennart Poettering <lennart@poettering.net>2022-07-14 18:09:18 +0200
committerGitHub <noreply@github.com>2022-07-14 18:09:18 +0200
commit0541980587d56d8e14b8d29eedbcfb7be067ac40 (patch)
treefacaee56ff7568655da4ced90c9f852d36253753 /src/partition/growfs.c
parentupdate TODO (diff)
parentgrowfs: don't reopen fds unnecessarily (diff)
downloadsystemd-0541980587d56d8e14b8d29eedbcfb7be067ac40.tar.xz
systemd-0541980587d56d8e14b8d29eedbcfb7be067ac40.zip
Merge pull request #24015 from poettering/growfs-fd-tweaks
growfs fd handling tweaks
Diffstat (limited to 'src/partition/growfs.c')
-rw-r--r--src/partition/growfs.c31
1 files changed, 22 insertions, 9 deletions
diff --git a/src/partition/growfs.c b/src/partition/growfs.c
index d9603d2b6d..3d46efa51c 100644
--- a/src/partition/growfs.c
+++ b/src/partition/growfs.c
@@ -85,16 +85,23 @@ static int resize_crypt_luks_device(dev_t devno, const char *fstype, dev_t main_
}
#endif
-static int maybe_resize_underlying_device(const char *mountpath, dev_t main_devno) {
+static int maybe_resize_underlying_device(
+ int mountfd,
+ const char *mountpath,
+ dev_t main_devno) {
+
_cleanup_free_ char *fstype = NULL, *devpath = NULL;
dev_t devno;
int r;
+ assert(mountfd >= 0);
+ assert(mountpath);
+
#if HAVE_LIBCRYPTSETUP
cryptsetup_enable_logging(NULL);
#endif
- r = get_block_device_harder(mountpath, &devno);
+ r = get_block_device_harder_fd(mountfd, &devno);
if (r < 0)
return log_error_errno(r, "Failed to determine underlying block device of \"%s\": %m",
mountpath);
@@ -198,6 +205,7 @@ static int run(int argc, char *argv[]) {
_cleanup_close_ int mountfd = -1, devfd = -1;
_cleanup_free_ char *devpath = NULL;
uint64_t size, newsize;
+ struct stat st;
dev_t devno;
int r;
@@ -213,7 +221,11 @@ static int run(int argc, char *argv[]) {
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);
+ mountfd = open(arg_target, O_RDONLY|O_CLOEXEC|O_DIRECTORY);
+ if (mountfd < 0)
+ return log_error_errno(errno, "Failed to open \"%s\": %m", arg_target);
+
+ r = get_block_device_fd(mountfd, &devno);
if (r == -EUCLEAN)
return btrfs_log_dev_root(LOG_ERR, r, arg_target);
if (r < 0)
@@ -221,22 +233,23 @@ static int run(int argc, char *argv[]) {
if (devno == 0)
return log_error_errno(SYNTHETIC_ERRNO(ENODEV), "File system \"%s\" not backed by block device.", arg_target);
- r = maybe_resize_underlying_device(arg_target, devno);
+ r = maybe_resize_underlying_device(mountfd, arg_target, devno);
if (r < 0)
return r;
- mountfd = open(arg_target, O_RDONLY|O_CLOEXEC);
- 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)
return log_error_errno(r, "Failed to format device major/minor path: %m");
- devfd = open(devpath, O_RDONLY|O_CLOEXEC);
+ devfd = open(devpath, O_RDONLY|O_CLOEXEC|O_NOCTTY);
if (devfd < 0)
return log_error_errno(errno, "Failed to open \"%s\": %m", devpath);
+ if (fstat(devfd, &st) < 0)
+ return log_error_errno(r, "Failed to stat() device %s: %m", devpath);
+ if (!S_ISBLK(st.st_mode))
+ return log_error_errno(SYNTHETIC_ERRNO(ENOTBLK), "Backing device of file system is not a block device, refusing.");
+
if (ioctl(devfd, BLKGETSIZE64, &size) != 0)
return log_error_errno(errno, "Failed to query size of \"%s\": %m", devpath);