summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDavid Teigland <teigland@redhat.com>2022-09-01 14:12:08 -0500
committerDavid Teigland <teigland@redhat.com>2022-09-02 16:45:36 -0500
commit2e1e61bfd6c8a53e35ba8b9a7953dbc0d2c3e9b8 (patch)
tree45aa73c24630d633768fa6354f1acfaee63d6e1f
parentc2b31ee8d5149d1f008f12be11334289f332bf9f (diff)
downloadlvm2-dev-dct-lvresize-9.tar.gz
lvresize: use script to call fs commandsdev-dct-lvresize-9
Intead of calling each fs command directly, call a helper script that will run those commands.
-rw-r--r--lib/device/filesystem.c274
-rw-r--r--lib/device/filesystem.h15
-rw-r--r--lib/metadata/lv_manip.c72
-rw-r--r--scripts/Makefile.in2
-rwxr-xr-xscripts/lvresize_fs_helper.sh477
-rw-r--r--test/shell/lvresize-fs.sh10
6 files changed, 617 insertions, 233 deletions
diff --git a/lib/device/filesystem.c b/lib/device/filesystem.c
index 4bdb88863..f35486f4a 100644
--- a/lib/device/filesystem.c
+++ b/lib/device/filesystem.c
@@ -263,222 +263,188 @@ int fs_get_info(struct cmd_context *cmd, struct logical_volume *lv,
return ret;
}
-#define FS_CMD_MAX_ARGS 6
+#define FS_CMD_MAX_ARGS 16
-int fs_fsck_command(struct cmd_context *cmd, struct logical_volume *lv, struct fs_info *fsi)
+int crypt_resize_script(struct cmd_context *cmd, struct logical_volume *lv, struct fs_info *fsi,
+ uint64_t newsize_bytes)
{
+ char crypt_path[PATH_MAX];
+ char newsize_bytes_str[16] = { 0 };
const char *argv[FS_CMD_MAX_ARGS + 4];
int args = 0;
int status;
- if (strncmp(fsi->fstype, "ext", 3)) {
- log_error("fsck not supported for %s.", fsi->fstype);
+ if (dm_snprintf(newsize_bytes_str, sizeof(newsize_bytes_str), "%llu", (unsigned long long)newsize_bytes) < 0)
return_0;
- }
- /*
- * ext234: e2fsck -f -p path
- * TODO: replace -p with -y based on yes_ARG, or other?
- */
+ if (dm_snprintf(crypt_path, sizeof(crypt_path), "/dev/dm-%d", (int)MINOR(fsi->crypt_devt)) < 0)
+ return_0;
- argv[0] = E2FSCK_PATH; /* defined by configure */
- argv[++args] = "-f";
- argv[++args] = "-p";
- argv[++args] = fsi->fs_dev_path;
+ argv[0] = "/usr/sbin/lvresize_fs_helper"; /* define in configure? */
+ argv[++args] = "--cryptresize";
+ argv[++args] = "--cryptpath";
+ argv[++args] = crypt_path;
+ argv[++args] = "--newsizebytes";
+ argv[++args] = newsize_bytes_str;
argv[++args] = NULL;
- log_print("Checking file system %s with %s on %s...",
- fsi->fstype, E2FSCK_PATH, display_lvname(lv));
-
if (!exec_cmd(cmd, argv, &status, 1)) {
- log_error("e2fsck failed on %s.", display_lvname(lv));
+ log_error("Failed to resize crypt dev with lvresize_fs_helper.");
return 0;
}
- log_print("Checked file system %s on %s.", fsi->fstype, display_lvname(lv));
return 1;
}
-int fs_reduce_command(struct cmd_context *cmd, struct logical_volume *lv, struct fs_info *fsi,
- uint64_t newsize_bytes)
+/*
+ * The helper script does the following steps for reduce:
+ * devpath = $cryptpath ? $cryptpath : $lvpath
+ * if needs_unmount
+ * umount $mountdir
+ * if needs_fsck
+ * e2fsck -f -p $devpath
+ * if needs_mount
+ * mount $devpath $tmpdir
+ * if $fstype == "ext"
+ * resize2fs $devpath $newsize_kb
+ * if needs_crypt
+ * cryptsetup resize --size $newsize_sectors $cryptpath
+ */
+
+int fs_reduce_script(struct cmd_context *cmd, struct logical_volume *lv, struct fs_info *fsi,
+ uint64_t newsize_bytes, char *fsopt)
{
- char newsize_kb_str[16] = { 0 };
+ char lv_path[PATH_MAX];
+ char crypt_path[PATH_MAX];
+ char newsize_bytes_str[16] = { 0 };
const char *argv[FS_CMD_MAX_ARGS + 4];
int args = 0;
int status;
- if (!strncmp(fsi->fstype, "ext", 3)) {
- if (dm_snprintf(newsize_kb_str, 16, "%lluk", (unsigned long long)(newsize_bytes/1024)) < 0)
- return_0;
-
- /*
- * ext234 shrink: resize2fs path newsize
- */
- argv[0] = RESIZE2FS_PATH; /* defined by configure */
- argv[++args] = fsi->fs_dev_path;
- argv[++args] = newsize_kb_str;
- argv[++args] = NULL;
+ if (dm_snprintf(newsize_bytes_str, sizeof(newsize_bytes_str), "%llu", (unsigned long long)newsize_bytes) < 0)
+ return_0;
- } else {
- log_error("fs reduce not supported for %s.", fsi->fstype);
+ if (dm_snprintf(lv_path, PATH_MAX, "%s%s/%s", lv->vg->cmd->dev_dir, lv->vg->name, lv->name) < 0)
return_0;
- }
- log_print("Reducing file system %s on %s...", fsi->fstype, display_lvname(lv));
+ argv[0] = "/usr/sbin/lvresize_fs_helper"; /* define in configure? */
+ argv[++args] = "--fsreduce";
+ argv[++args] = "--fstype";
+ argv[++args] = fsi->fstype;
+ argv[++args] = "--lvpath";
+ argv[++args] = lv_path;
- if (!exec_cmd(cmd, argv, &status, 1)) {
- log_error("Failed to reduce %s file system on %s.", fsi->fstype, display_lvname(lv));
- return 0;
+ if (newsize_bytes) {
+ argv[++args] = "--newsizebytes";
+ argv[++args] = newsize_bytes_str;
}
-
- log_print("Reduced file system %s to %s (%llu bytes) on %s.",
- fsi->fstype, display_size(cmd, newsize_bytes/512),
- (unsigned long long)newsize_bytes, display_lvname(lv));
- return 1;
-}
-
-int fs_extend_command(struct cmd_context *cmd, struct logical_volume *lv, struct fs_info *fsi)
-{
- const char *argv[FS_CMD_MAX_ARGS + 4];
- int args = 0;
- int status;
-
- if (!strncmp(fsi->fstype, "ext", 3)) {
- /* TODO: include -f if lvm command inclues -f ? */
- argv[0] = RESIZE2FS_PATH; /* defined by configure */
- argv[++args] = fsi->fs_dev_path;
- argv[++args] = NULL;
-
- } else if (!strcmp(fsi->fstype, "xfs")) {
- argv[0] = XFS_GROWFS_PATH; /* defined by configure */
- argv[++args] = fsi->fs_dev_path;
- argv[++args] = NULL;
-
- } else {
- log_error("Extend not supported for %s file system.", fsi->fstype);
- return_0;
+ if (fsi->mounted) {
+ argv[++args] = "--mountdir";
+ argv[++args] = fsi->mount_dir;
}
- log_print("Extending file system %s on %s...", fsi->fstype, display_lvname(lv));
+ if (fsi->needs_unmount)
+ argv[++args] = "--unmount";
+ if (fsi->needs_mount)
+ argv[++args] = "--mount";
+ if (fsi->needs_fsck)
+ argv[++args] = "--fsck";
- if (!exec_cmd(cmd, argv, &status, 1)) {
- log_error("Failed to extend %s file system on %s.", fsi->fstype, display_lvname(lv));
- return 0;
+ if (fsi->needs_crypt) {
+ if (dm_snprintf(crypt_path, sizeof(crypt_path), "/dev/dm-%d", (int)MINOR(fsi->crypt_devt)) < 0)
+ return_0;
+ argv[++args] = "--cryptresize";
+ argv[++args] = "--cryptpath";
+ argv[++args] = crypt_path;
}
- log_print("Extended file system %s on %s.", fsi->fstype, display_lvname(lv));
- return 1;
-}
-
-int fs_mount_command(struct cmd_context *cmd, struct logical_volume *lv, struct fs_info *fsi,
- int reuse_mount_dir)
-{
- char mountdir[PATH_MAX];
- const char *argv[FS_CMD_MAX_ARGS + 4];
- int args = 0;
- int status;
+ /*
+ * --fs resize|resize_remount want the fs to be remounted after
+ * resizing if it was unmounted. (Not often applicable.)
+ */
+ if (fsi->needs_unmount && (!strcmp(fsopt, "resize") || !strcmp(fsopt, "resize_remount")))
+ argv[++args] = "--remount";
- if (reuse_mount_dir) {
- if (!fsi->mount_dir[0]) {
- log_error("Cannot remount fs without previous mount dir.");
- return 0;
- }
- memcpy(mountdir, fsi->mount_dir, PATH_MAX);
- } else {
- if (dm_snprintf(mountdir, sizeof(mountdir), "/tmp/%s_XXXXXX", cmd->name) < 0)
- return_0;
- if (!mkdtemp(mountdir)) {
- log_error("Failed to create temp dir for mount: %s", strerror(errno));
- return 0;
- }
- memcpy(fsi->mount_dir, mountdir, PATH_MAX);
- fsi->temp_mount_dir = 1;
- }
-
- argv[0] = MOUNT_PATH; /* defined by configure */
- argv[++args] = fsi->fs_dev_path;
- argv[++args] = mountdir;
argv[++args] = NULL;
- log_print("Mounting %s.", display_lvname(lv));
-
if (!exec_cmd(cmd, argv, &status, 1)) {
- log_error("Failed to mount file system on %s at %s.", display_lvname(lv), mountdir);
+ log_error("Failed to resize file system with lvresize_fs_helper.");
return 0;
}
- log_print("Mounted %s at %s dir %s.", display_lvname(lv),
- reuse_mount_dir ? "original" : "temporary", mountdir);
return 1;
}
-int fs_unmount_command(struct cmd_context *cmd, struct logical_volume *lv, struct fs_info *fsi)
+/*
+ * The helper script does the following steps for extend:
+ * devpath = $cryptpath ? $cryptpath : $lvpath
+ * if needs_unmount
+ * umount $mountdir
+ * if needs_fsck
+ * e2fsck -f -p $devpath
+ * if needs_crypt
+ * cryptsetup resize $cryptpath
+ * if needs_mount
+ * mount $devpath $tmpdir
+ * if $fstype == "ext"
+ * resize2fs $devpath
+ * if $fstype == "xfs"
+ * xfs_growfs $devpath
+ */
+
+int fs_extend_script(struct cmd_context *cmd, struct logical_volume *lv, struct fs_info *fsi,
+ char *fsopt)
{
+ char lv_path[PATH_MAX];
+ char crypt_path[PATH_MAX];
const char *argv[FS_CMD_MAX_ARGS + 4];
int args = 0;
int status;
- argv[0] = UMOUNT_PATH; /* defined by configure */
- argv[++args] = fsi->fs_dev_path;
- argv[++args] = NULL;
+ if (dm_snprintf(lv_path, PATH_MAX, "%s%s/%s", lv->vg->cmd->dev_dir, lv->vg->name, lv->name) < 0)
+ return_0;
- log_print("Unmounting %s.", display_lvname(lv));
+ argv[0] = "/usr/sbin/lvresize_fs_helper"; /* define in configure? */
+ argv[++args] = "--fsextend";
+ argv[++args] = "--fstype";
+ argv[++args] = fsi->fstype;
+ argv[++args] = "--lvpath";
+ argv[++args] = lv_path;
- if (!exec_cmd(cmd, argv, &status, 1)) {
- log_error("Failed to unmount file system on %s.", display_lvname(lv));
- return 0;
+ if (fsi->mounted) {
+ argv[++args] = "--mountdir";
+ argv[++args] = fsi->mount_dir;
}
- log_print("Unmounted %s.", display_lvname(lv));
+ if (fsi->needs_unmount)
+ argv[++args] = "--unmount";
+ if (fsi->needs_mount)
+ argv[++args] = "--mount";
+ if (fsi->needs_fsck)
+ argv[++args] = "--fsck";
- if (fsi->temp_mount_dir) {
- if (rmdir(fsi->mount_dir) < 0)
- log_print("Error removing temp dir %s", fsi->mount_dir);
- fsi->mount_dir[0] = '\0';
- fsi->temp_mount_dir = 0;
+ if (fsi->needs_crypt) {
+ if (dm_snprintf(crypt_path, sizeof(crypt_path), "/dev/dm-%d", (int)MINOR(fsi->crypt_devt)) < 0)
+ return_0;
+ argv[++args] = "--cryptresize";
+ argv[++args] = "--cryptpath";
+ argv[++args] = crypt_path;
}
- return 1;
-}
-
-int crypt_resize_command(struct cmd_context *cmd, dev_t crypt_devt, uint64_t newsize_bytes)
-{
- char crypt_path[PATH_MAX];
- const char *argv[FS_CMD_MAX_ARGS + 4];
- char size_str[16] = { 0 };
- int args = 0;
- int status;
- if (dm_snprintf(crypt_path, sizeof(crypt_path), "/dev/dm-%d", (int)MINOR(crypt_devt)) < 0)
- return_0;
-
- if (dm_snprintf(size_str, sizeof(size_str), "%llu", (unsigned long long)newsize_bytes/512) < 0)
- return_0;
+ /*
+ * --fs resize|resize_remount want the fs to be remounted after
+ * resizing if it was unmounted. (Not often applicable.)
+ */
+ if (fsi->needs_unmount && (!strcmp(fsopt, "resize") || !strcmp(fsopt, "resize_remount")))
+ argv[++args] = "--remount";
- argv[0] = CRYPTSETUP_PATH; /* defined by configure */
- argv[++args] = "resize";
- if (newsize_bytes) {
- argv[++args] = "--size";
- argv[++args] = size_str;
- }
- argv[++args] = crypt_path;
argv[++args] = NULL;
- log_print("Resizing crypt device %s...", crypt_path);
-
if (!exec_cmd(cmd, argv, &status, 1)) {
- log_error("Failed to cryptsetup resize %s to %s (%llu sectors)",
- crypt_path, display_size(cmd, newsize_bytes/512),
- (unsigned long long)newsize_bytes/512);
+ log_error("Failed to resize file system with lvresize_fs_helper.");
return 0;
}
- if (newsize_bytes)
- log_print("Resized crypt device %s to %s (%llu sectors)",
- crypt_path, display_size(cmd, newsize_bytes/512),
- (unsigned long long)newsize_bytes/512);
- else
- log_print("Resized crypt device %s.", crypt_path);
-
return 1;
}
diff --git a/lib/device/filesystem.h b/lib/device/filesystem.h
index 1e83469cb..0e61456c2 100644
--- a/lib/device/filesystem.h
+++ b/lib/device/filesystem.h
@@ -41,14 +41,11 @@ struct fs_info {
int fs_get_info(struct cmd_context *cmd, struct logical_volume *lv,
struct fs_info *fsi, int include_mount);
-int fs_fsck_command(struct cmd_context *cmd, struct logical_volume *lv, struct fs_info *fsi);
-int fs_reduce_command(struct cmd_context *cmd, struct logical_volume *lv, struct fs_info *fsi,
- uint64_t newsize_bytes);
-int fs_extend_command(struct cmd_context *cmd, struct logical_volume *lv, struct fs_info *fsi);
-int fs_mount_command(struct cmd_context *cmd, struct logical_volume *lv, struct fs_info *fsi,
- int reuse_mount_dir);
-int fs_unmount_command(struct cmd_context *cmd, struct logical_volume *lv, struct fs_info *fsi);
-
-int crypt_resize_command(struct cmd_context *cmd, dev_t crypt_devt, uint64_t newsize_bytes);
+int fs_extend_script(struct cmd_context *cmd, struct logical_volume *lv, struct fs_info *fsi,
+ char *fsopt);
+int fs_reduce_script(struct cmd_context *cmd, struct logical_volume *lv, struct fs_info *fsi,
+ uint64_t newsize_bytes_fs, char *fsopt);
+int crypt_resize_script(struct cmd_context *cmd, struct logical_volume *lv, struct fs_info *fsi,
+ uint64_t newsize_bytes_fs);
#endif
diff --git a/lib/metadata/lv_manip.c b/lib/metadata/lv_manip.c
index 91bc6bd0d..aa4f31c14 100644
--- a/lib/metadata/lv_manip.c
+++ b/lib/metadata/lv_manip.c
@@ -6346,7 +6346,6 @@ static int _fs_reduce(struct cmd_context *cmd, struct logical_volume *lv,
struct fs_info fsinfo2;
uint64_t newsize_bytes_lv;
uint64_t newsize_bytes_fs;
- int mounted = 0, unmounted = 0;
int ret = 0;
memset(&fsinfo, 0, sizeof(fsinfo));
@@ -6391,7 +6390,7 @@ static int _fs_reduce(struct cmd_context *cmd, struct logical_volume *lv,
* the LV size, so that the FS does not see an incorrect device size.
*/
if (!fsinfo.needs_reduce && fsinfo.needs_crypt && !test_mode()) {
- ret = crypt_resize_command(cmd, fsinfo.crypt_devt, newsize_bytes_fs);
+ ret = crypt_resize_script(cmd, lv, &fsinfo, newsize_bytes_fs);
goto out;
}
@@ -6425,31 +6424,9 @@ static int _fs_reduce(struct cmd_context *cmd, struct logical_volume *lv,
*/
unlock_vg(cmd, lv->vg, lv->vg->name);
- if (fsinfo.needs_unmount) {
- if (!fs_unmount_command(cmd, lv, &fsinfo))
- goto_out;
- unmounted = 1;
- }
-
- if (fsinfo.needs_fsck) {
- if (!fs_fsck_command(cmd, lv, &fsinfo))
- goto_out;
- }
-
- if (fsinfo.needs_mount) {
- if (!fs_mount_command(cmd, lv, &fsinfo, 0))
- goto_out;
- mounted = 1;
- }
-
- if (!fs_reduce_command(cmd, lv, &fsinfo, newsize_bytes_fs))
+ if (!fs_reduce_script(cmd, lv, &fsinfo, newsize_bytes_fs, lp->fsopt))
goto_out;
- if (fsinfo.needs_crypt) {
- if (!crypt_resize_command(cmd, fsinfo.crypt_devt, newsize_bytes_fs))
- goto_out;
- }
-
if (!lock_vol(cmd, lv->vg->name, LCK_VG_WRITE, NULL)) {
log_error("Failed to lock VG, cannot reduce LV.");
ret = 0;
@@ -6482,16 +6459,6 @@ static int _fs_reduce(struct cmd_context *cmd, struct logical_volume *lv,
}
ret = 1;
-
- /*
- * put the fs back into the original mounted|unmounted state.
- */
- if (!strcmp(lp->fsopt, "resize_remount") || !strcmp(lp->fsopt, "resize")) {
- if (mounted && !fs_unmount_command(cmd, lv, &fsinfo))
- ret = 0;
- if (unmounted && !fs_mount_command(cmd, lv, &fsinfo, 1))
- ret = 0;
- }
out:
return ret;
}
@@ -6500,7 +6467,6 @@ static int _fs_extend(struct cmd_context *cmd, struct logical_volume *lv,
struct lvresize_params *lp)
{
struct fs_info fsinfo;
- int mounted = 0, unmounted = 0;
int ret = 0;
memset(&fsinfo, 0, sizeof(fsinfo));
@@ -6550,42 +6516,10 @@ static int _fs_extend(struct cmd_context *cmd, struct logical_volume *lv,
*/
unlock_vg(cmd, lv->vg, lv->vg->name);
- if (fsinfo.needs_unmount) {
- if (!fs_unmount_command(cmd, lv, &fsinfo))
- goto_out;
- unmounted = 1;
- }
-
- if (fsinfo.needs_fsck) {
- if (!fs_fsck_command(cmd, lv, &fsinfo))
- goto_out;
- }
-
- if (fsinfo.needs_crypt) {
- if (!crypt_resize_command(cmd, fsinfo.crypt_devt, 0))
- goto_out;
- }
-
- if (fsinfo.needs_mount) {
- if (!fs_mount_command(cmd, lv, &fsinfo, 0))
- goto_out;
- mounted = 1;
- }
-
- if (!fs_extend_command(cmd, lv, &fsinfo))
+ if (!fs_extend_script(cmd, lv, &fsinfo, lp->fsopt))
goto_out;
ret = 1;
-
- /*
- * put the fs back into the original mounted|unmounted state.
- */
- if (!strcmp(lp->fsopt, "resize_remount") || !strcmp(lp->fsopt, "resize")) {
- if (mounted && !fs_unmount_command(cmd, lv, &fsinfo))
- ret = 0;
- if (unmounted && !fs_mount_command(cmd, lv, &fsinfo, 1))
- ret = 0;
- }
out:
return ret;
}
diff --git a/scripts/Makefile.in b/scripts/Makefile.in
index ebcea92f9..607df3c0a 100644
--- a/scripts/Makefile.in
+++ b/scripts/Makefile.in
@@ -21,7 +21,7 @@ ifeq ("@BUILD_DMEVENTD@", "yes")
LDFLAGS += -Wl,-rpath-link,$(top_builddir)/daemons/dmeventd
endif
-LVM_SCRIPTS = lvmdump.sh
+LVM_SCRIPTS = lvmdump.sh lvresize_fs_helper.sh
DM_SCRIPTS =
ifeq ("@FSADM@", "yes")
diff --git a/scripts/lvresize_fs_helper.sh b/scripts/lvresize_fs_helper.sh
new file mode 100755
index 000000000..b0c184182
--- /dev/null
+++ b/scripts/lvresize_fs_helper.sh
@@ -0,0 +1,477 @@
+#!/bin/bash
+#
+# Copyright (C) 2022 Red Hat, Inc. All rights reserved.
+#
+# This file is part of LVM2.
+#
+# This copyrighted material is made available to anyone wishing to use,
+# modify, copy, or redistribute it subject to the terms and conditions
+# of the GNU General Public License v.2.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software Foundation,
+# Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+
+errorexit() {
+ echo "$1" >&2
+ exit 1
+}
+
+logmsg() {
+ echo "$1"
+ logger "${SCRIPTNAME}: $1"
+}
+
+# Set to 1 while the fs is temporarily mounted on $TMPDIR
+TMP_MOUNT_DONE=0
+# Set to 1 if the fs resize command fails
+RESIZEFS_FAILED=0
+
+fsextend() {
+ if [ "$DO_UNMOUNT" -eq 1 ]; then
+ logmsg "unmount ${MOUNTDIR}"
+ umount "$MOUNTDIR"
+ if [ $? -eq 0 ]; then
+ logmsg "unmount done"
+ else
+ logmsg "unmount failed"
+ exit 1
+ fi
+ fi
+
+ if [ "$DO_FSCK" -eq 1 ]; then
+ logmsg "e2fsck ${DEVPATH}"
+ e2fsck -f -p "$DEVPATH"
+ if [ $? -eq 0 ]; then
+ logmsg "e2fsck done"
+ else
+ logmsg "e2fsck failed"
+ exit 1
+ fi
+ fi
+
+ if [ "$DO_CRYPTRESIZE" -eq 1 ]; then
+ logmsg "cryptsetup resize ${DEVPATH}"
+ cryptsetup resize "$DEVPATH"
+ if [ $? -eq 0 ]; then
+ logmsg "cryptsetup done"
+ else
+ logmsg "cryptsetup failed"
+ exit 1
+ fi
+ fi
+
+ if [ "$DO_MOUNT" -eq 1 ]; then
+ logmsg "mount ${DEVPATH} ${TMPDIR}"
+ mount -t "$FSTYPE" "$DEVPATH" "$TMPDIR"
+ if [ $? -eq 0 ]; then
+ logmsg "mount done"
+ TMP_MOUNT_DONE=1
+ else
+ logmsg "mount failed"
+ exit 1
+ fi
+ fi
+
+ if [[ "$FSTYPE" == "ext"* ]]; then
+ logmsg "resize2fs ${DEVPATH}"
+ resize2fs "$DEVPATH"
+ if [ $? -eq 0 ]; then
+ logmsg "resize2fs done"
+ else
+ logmsg "resize2fs failed"
+ RESIZEFS_FAILED=1
+ fi
+ elif [[ "$FSTYPE" == "xfs" ]]; then
+ logmsg "xfs_growfs ${DEVPATH}"
+ xfs_growfs "$DEVPATH"
+ if [ $? -eq 0 ]; then
+ logmsg "xfs_growfs done"
+ else
+ logmsg "xfs_growfs failed"
+ RESIZEFS_FAILED=1
+ fi
+ fi
+
+ # If the fs was temporarily mounted, now unmount it.
+ if [ $TMP_MOUNT_DONE -eq 1 ]; then
+ logmsg "cleanup unmount ${TMPDIR}"
+ umount "$TMPDIR"
+ if [ $? -eq 0 ]; then
+ logmsg "cleanup unmount done"
+ TMP_MOUNT_DONE=0
+ rmdir "$TMPDIR"
+ else
+ logmsg "cleanup unmount failed"
+ exit 1
+ fi
+ fi
+
+ # If the fs was temporarily unmounted, now remount it.
+ # Not considered a command failure if this fails.
+ if [[ $DO_UNMOUNT -eq 1 && $REMOUNT -eq 1 ]]; then
+ logmsg "remount ${DEVPATH} ${MOUNTDIR}"
+ mount -t "$FSTYPE" "$DEVPATH" "$MOUNTDIR"
+ if [ $? -eq 0 ]; then
+ logmsg "remount done"
+ else
+ logmsg "remount failed"
+ fi
+ fi
+
+ if [ $RESIZEFS_FAILED -eq 1 ]; then
+ logmsg "File system extend failed."
+ exit 1
+ fi
+
+ exit 0
+}
+
+fsreduce() {
+ if [ "$DO_UNMOUNT" -eq 1 ]; then
+ logmsg "unmount ${MOUNTDIR}"
+ umount "$MOUNTDIR"
+ if [ $? -eq 0 ]; then
+ logmsg "unmount done"
+ else
+ logmsg "unmount failed"
+ exit 1
+ fi
+ fi
+
+ if [ "$DO_FSCK" -eq 1 ]; then
+ logmsg "e2fsck ${DEVPATH}"
+ e2fsck -f -p "$DEVPATH"
+ if [ $? -eq 0 ]; then
+ logmsg "e2fsck done"
+ else
+ logmsg "e2fsck failed"
+ exit 1
+ fi
+ fi
+
+ if [ "$DO_MOUNT" -eq 1 ]; then
+ logmsg "mount ${DEVPATH} ${TMPDIR}"
+ mount -t "$FSTYPE" "$DEVPATH" "$TMPDIR"
+ if [ $? -eq 0 ]; then
+ logmsg "mount done"
+ TMP_MOUNT_DONE=1
+ else
+ logmsg "mount failed"
+ exit 1
+ fi
+ fi
+
+ if [[ "$FSTYPE" == "ext"* ]]; then
+ NEWSIZEKB=$(($NEWSIZEBYTES/1024))
+ logmsg "resize2fs ${DEVPATH} ${NEWSIZEKB}"
+ resize2fs "$DEVPATH" "$NEWSIZEKB"
+ if [ $? -eq 0 ]; then
+ logmsg "resize2fs done"
+ else
+ logmsg "resize2fs failed"
+ # will exit after cleanup unmount
+ RESIZEFS_FAILED=1
+ fi
+ fi
+
+ # If the fs was temporarily mounted, now unmount it.
+ if [ $TMP_MOUNT_DONE -eq 1 ]; then
+ logmsg "cleanup unmount ${TMPDIR}"
+ umount "$TMPDIR"
+ if [ $? -eq 0 ]; then
+ logmsg "cleanup unmount done"
+ TMP_MOUNT_DONE=0
+ rmdir "$TMPDIR"
+ else
+ logmsg "cleanup unmount failed"
+ exit 1
+ fi
+ fi
+
+ if [ $RESIZEFS_FAILED -eq 1 ]; then
+ logmsg "File system reduce failed."
+ exit 1
+ fi
+
+ if [ "$DO_CRYPTRESIZE" -eq 1 ]; then
+ NEWSIZESECTORS=$(($NEWSIZEBYTES/512))
+ logmsg "cryptsetup resize ${NEWSIZESECTORS} ${DEVPATH}"
+ cryptsetup resize --size "$NEWSIZESECTORS" "$DEVPATH"
+ if [ $? -eq 0 ]; then
+ logmsg "cryptsetup done"
+ else
+ logmsg "cryptsetup failed"
+ exit 1
+ fi
+ fi
+
+ # If the fs was temporarily unmounted, now remount it.
+ # Not considered a command failure if this fails.
+ if [[ $DO_UNMOUNT -eq 1 && $REMOUNT -eq 1 ]]; then
+ logmsg "remount ${DEVPATH} ${MOUNTDIR}"
+ mount -t "$FSTYPE" "$DEVPATH" "$MOUNTDIR"
+ if [ $? -eq 0 ]; then
+ logmsg "remount done"
+ else
+ logmsg "remount failed"
+ fi
+ fi
+
+ exit 0
+}
+
+cryptresize() {
+ NEWSIZESECTORS=$(($NEWSIZEBYTES/512))
+ logmsg "cryptsetup resize ${NEWSIZESECTORS} ${DEVPATH}"
+ cryptresize resize --size "$NEWSIZESECTORS" "$DEVPATH"
+ if [ $? -eq 0 ]; then
+ logmsg "cryptsetup done"
+ else
+ logmsg "cryptsetup failed"
+ exit 1
+ fi
+
+ exit 0
+}
+
+usage() {
+ echo "${SCRIPTNAME}: helper script called by lvresize to resize file systems."
+ echo ""
+ echo "${SCRIPTNAME} --fsextend --fstype name --lvpath path"
+ echo " [ --mountdir path ]"
+ echo " [ --mount ]"
+ echo " [ --unmount ]"
+ echo " [ --remount ]"
+ echo " [ --fsck ]"
+ echo " [ --cryptresize ]"
+ echo " [ --cryptpath path ]"
+ echo ""
+ echo "${SCRIPTNAME} --fsreduce --fstype name --lvpath path"
+ echo " [ --newsizebytes num ]"
+ echo " [ --mountdir path ]"
+ echo " [ --mount ]"
+ echo " [ --unmount ]"
+ echo " [ --remount ]"
+ echo " [ --fsck ]"
+ echo " [ --cryptresize ]"
+ echo " [ --cryptpath path ]"
+ echo ""
+ echo "${SCRIPTNAME} --cryptresize --cryptpath path --newsizebytes num"
+ echo ""
+ echo "Options:"
+ echo " --fsextend"
+ echo " Extend the file system."
+ echo " --fsreduce"
+ echo " Reduce the file system."
+ echo " --fstype name"
+ echo " The type of file system (ext*, xfs)."
+ echo " --lvpath path"
+ echo " The path to the LV being resized."
+ echo " --mountdir path"
+ echo " The file system is currently mounted here."
+ echo " --mount"
+ echo " Mount the file system on a temporary directory before resizing."
+ echo " --unmount"
+ echo " Unmount the file system before resizing."
+ echo " --remount"
+ echo " Remount the file system after resizing if unmounted."
+ echo " --fsck"
+ echo " Run fsck on the file system before resizing (only with ext*)."
+ echo " --newsizebytes num"
+ echo " The new size of the file system."
+ echo " --cryptresize"
+ echo " Resize the crypt device between the LV and file system."
+ echo " --cryptpath path"
+ echo " The path to the crypt device."
+ echo ""
+}
+
+#
+# BEGIN SCRIPT
+#
+PATH="/sbin:/usr/sbin:/bin:/usr/sbin:$PATH"
+SCRIPTNAME=$(basename "$0")
+
+# These are the only commands that this script will run.
+# Each is enabled (1) by the corresponding command options:
+# --fsextend, --fsreduce, --cryptresize, --mount, --unmount, --fsck
+DO_FSEXTEND=0
+DO_FSREDUCE=0
+DO_CRYPTRESIZE=0
+DO_MOUNT=0
+DO_UNMOUNT=0
+DO_FSCK=0
+
+# --remount: attempt to remount the fs if it was originally
+# mounted and the script unmounted it.
+REMOUNT=0
+
+if [ "$UID" != 0 ] && [ "$EUID" != 0 ]; then
+ errorexit "${SCRIPTNAME} must be run as root."
+fi
+
+GETOPT="getopt"
+
+OPTIONS=$("$GETOPT" -o hv -l help,debug,fsextend,fsreduce,cryptresize,mount,unmount,remount,fsck,fstype:,lvpath:,newsizebytes:,mountdir:,cryptpath: -n "${SCRIPTNAME}" -- "$@")
+eval set -- "$OPTIONS"
+
+while true
+do
+ case $1 in
+ --fsextend)
+ DO_FSEXTEND=1
+ shift
+ ;;
+ --fsreduce)
+ DO_FSREDUCE=1
+ shift
+ ;;
+ --cryptresize)
+ DO_CRYPTRESIZE=1
+ shift
+ ;;
+ --mount)
+ DO_MOUNT=1
+ shift
+ ;;
+ --unmount)
+ DO_UNMOUNT=1
+ shift
+ ;;
+ --fsck)
+ DO_FSCK=1
+ shift
+ ;;
+ --remount)
+ REMOUNT=1
+ shift
+ ;;
+ --fstype)
+ FSTYPE=$2;
+ shift; shift
+ ;;
+ --lvpath)
+ LVPATH=$2;
+ shift; shift
+ ;;
+ --newsizebytes)
+ NEWSIZEBYTES=$2;
+ shift; shift
+ ;;
+ --mountdir)
+ MOUNTDIR=$2;
+ shift; shift
+ ;;
+ --cryptpath)
+ CRYPTPATH=$2;
+ shift; shift
+ ;;
+ --debug)
+ DEBUG=1
+ set -x
+ shift
+ ;;
+ -h|--help)
+ usage
+ shift
+ exit 0
+ ;;
+ -v)
+ VERBOSE=1
+ shift
+ ;;
+ --)
+ shift
+ break
+ ;;
+ *)
+ errorexit "Unknown option \"$1\."
+ exit 1
+ ;;
+ esac
+done
+
+#
+# Input arg checking
+#
+
+# There are three top level commands: --fsextend, --fsreduce, --cryptresize.
+if [[ "$DO_FSEXTEND" -eq 0 && "$DO_FSREDUCE" -eq 0 && "$DO_CRYPTRESIZE" -eq 0 ]]; then
+ errorexit "Missing --fsextend|--fsreduce|--cryptresize."
+fi
+
+if [[ "$DO_FSEXTEND" -eq 1 || "$DO_FSREDUCE" -eq 1 ]]; then
+ case "$FSTYPE" in
+ ext[234]) ;;
+ "xfs") ;;
+ *) errorexit "Cannot resize --fstype \"$FSTYPE\"."
+ esac
+
+ if [ -z "$LVPATH" ]; then
+ errorexit "Missing required --lvpath."
+ fi
+fi
+
+if [[ "$DO_CRYPTRESIZE" -eq 1 && -z "$CRYPTPATH" ]]; then
+ errorexit "Missing required --cryptpath for --cryptresize."
+fi
+
+if [ "$DO_CRYPTRESIZE" -eq 1 ]; then
+ DEVPATH=$CRYPTPATH
+else
+ DEVPATH=$LVPATH
+fi
+
+if [ -z "$DEVPATH" ]; then
+ errorexit "Missing path to device."
+fi
+
+if [ ! -e "$DEVPATH" ]; then
+ errorexit "Device does not exist \"$DEVPATH\"."
+fi
+
+if [[ "$DO_UNMOUNT" -eq 1 && -z "$MOUNTDIR" ]]; then
+ errorexit "Missing required --mountdir for --unmount."
+fi
+
+if [[ "$DO_FSREDUCE" -eq 1 && "$FSTYPE" == "xfs" ]]; then
+ errorexit "Cannot reduce xfs."
+fi
+
+if [[ "$DO_FSCK" -eq 1 && "$FSTYPE" == "xfs" ]]; then
+ errorexit "Cannot use --fsck with xfs."
+fi
+
+if [ "$DO_MOUNT" -eq 1 ]; then
+ TMPDIR=$(mktemp --suffix _lvresize_$$ -d -p /tmp)
+ if [ ! -e "$TMPDIR" ]; then
+ errorexit "Failed to create temp dir."
+ fi
+ # In case the script terminates without doing cleanup
+ function finish {
+ if [ "$TMP_MOUNT_DONE" -eq 1 ]; then
+ logmsg "exit unmount ${TMPDIR}"
+ umount "$TMPDIR"
+ rmdir "$TMPDIR"
+ fi
+ }
+ trap finish EXIT
+fi
+
+#
+# Main program function:
+# - the two main functions are fsextend and fsreduce.
+# - one special case function is cryptresize.
+#
+
+echo "Resizing ${FSTYPE} on ${DEVPATH}"
+
+if [ "$DO_FSEXTEND" -eq 1 ]; then
+ fsextend
+elif [ "$DO_FSREDUCE" -eq 1 ]; then
+ fsreduce
+elif [ "$DO_CRYPTRESIZE" -eq 1 ]; then
+ cryptresize
+fi
+
diff --git a/test/shell/lvresize-fs.sh b/test/shell/lvresize-fs.sh
index 41b97008f..53bd532f0 100644
--- a/test/shell/lvresize-fs.sh
+++ b/test/shell/lvresize-fs.sh
@@ -717,6 +717,7 @@ df --output=size "$mount_dir" |tee df1
# fs is 200M, reduced size is 216M, so no fs reduce is needed
lvreduce -L216M $vg/$lv
check lv_field $vg/$lv lv_size "216.00m"
+ls -l $mount_dir/zeros1
df --output=size "$mount_dir" |tee df2
# fs size unchanged
diff df1 df2
@@ -735,6 +736,7 @@ df --output=size "$mount_dir" |tee df1
# fs is 200M, reduced size is 200M, so no fs reduce is needed
lvreduce -L200M $vg/$lv
check lv_field $vg/$lv lv_size "200.00m"
+ls -l $mount_dir/zeros1
df --output=size "$mount_dir" |tee df2
# fs size unchanged
diff df1 df2
@@ -752,6 +754,7 @@ df --output=size "$mount_dir" |tee df1
# lvreduce runs resize2fs to shrink the fs
lvreduce --yes --fs resize -L-200M $vg/$lv
check lv_field $vg/$lv lv_size "256.00m"
+ls -l $mount_dir/zeros1
df --output=size "$mount_dir" |tee df2
# fs size is changed
not diff df1 df2
@@ -773,6 +776,8 @@ df --output=size "$mount_dir" |tee df1
not lvreduce --yes --fs resize -L-200M $vg/$lv
check lv_field $vg/$lv lv_size "456.00m"
mount "$DM_DEV_DIR/$vg/$lv" "$mount_dir"
+ls -l $mount_dir/zeros1
+ls -l $mount_dir/zeros2
df --output=size "$mount_dir" |tee df2
# fs size is unchanged
diff df1 df2
@@ -795,6 +800,7 @@ umount "$mount_dir"
lvreduce -L216M $vg/$lv
check lv_field $vg/$lv lv_size "216.00m"
mount "$DM_DEV_DIR/$vg/$lv" "$mount_dir"
+ls -l $mount_dir/zeros1
df --output=size "$mount_dir" |tee df2
# fs size unchanged
diff df1 df2
@@ -815,6 +821,7 @@ umount "$mount_dir"
lvreduce -L200M $vg/$lv
check lv_field $vg/$lv lv_size "200.00m"
mount "$DM_DEV_DIR/$vg/$lv" "$mount_dir"
+ls -l $mount_dir/zeros1
df --output=size "$mount_dir" |tee df2
# fs size unchanged
diff df1 df2
@@ -834,6 +841,7 @@ umount "$mount_dir"
lvreduce --fs resize -L-200M $vg/$lv
check lv_field $vg/$lv lv_size "256.00m"
mount "$DM_DEV_DIR/$vg/$lv" "$mount_dir"
+ls -l $mount_dir/zeros1
df --output=size "$mount_dir" |tee df2
# fs size is changed
not diff df1 df2
@@ -854,6 +862,7 @@ umount "$mount_dir"
not lvreduce --yes --fs resize -L-200M $vg/$lv
check lv_field $vg/$lv lv_size "456.00m"
mount "$DM_DEV_DIR/$vg/$lv" "$mount_dir"
+ls -l $mount_dir/zeros1
df --output=size "$mount_dir" |tee df2
# fs size is unchanged
diff df1 df2
@@ -949,6 +958,7 @@ df --output=size "$mount_dir" |tee df1
# lvreduce runs resize2fs to shrink the fs
lvreduce --yes --fs resize_fsadm -L-200M $vg/$lv
check lv_field $vg/$lv lv_size "256.00m"
+ls -l $mount_dir/zeros1
df --output=size "$mount_dir" |tee df2
# fs size is changed
not diff df1 df2