diff options
Diffstat (limited to 'lib/device/filesystem.c')
-rw-r--r-- | lib/device/filesystem.c | 292 |
1 files changed, 141 insertions, 151 deletions
diff --git a/lib/device/filesystem.c b/lib/device/filesystem.c index 4bdb88863..3e22e98ec 100644 --- a/lib/device/filesystem.c +++ b/lib/device/filesystem.c @@ -263,221 +263,211 @@ 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_fs) { + char crypt_path[PATH_MAX]; + char newsize_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_str, sizeof(newsize_str), "%llu", (unsigned long long)newsize_bytes_fs) < 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_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 + * + * Note: when a crypt layer is included, newsize_bytes_fs is smaller + * than newsize_bytes_lv because of the crypt header. + */ + +int fs_reduce_script(struct cmd_context *cmd, struct logical_volume *lv, struct fs_info *fsi, + uint64_t newsize_bytes_fs, char *fsopt) { - char newsize_kb_str[16] = { 0 }; + char lv_path[PATH_MAX]; + char crypt_path[PATH_MAX]; + char newsize_str[16] = { 0 }; const char *argv[FS_CMD_MAX_ARGS + 4]; + char *devpath; 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_str, sizeof(newsize_str), "%llu", (unsigned long long)newsize_bytes_fs) < 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_fs) { + argv[++args] = "--newsizebytes"; + argv[++args] = newsize_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)); + devpath = fsi->needs_crypt ? crypt_path : (char *)display_lvname(lv); + + log_print("Reducing file system %s to %s (%llu bytes) on %s...", + fsi->fstype, display_size(cmd, newsize_bytes_fs/512), + (unsigned long long)newsize_bytes_fs, devpath); 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 reduce 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); + log_print("Reduced file system %s on %s.", fsi->fstype, devpath); + 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 + * + * Note: when a crypt layer is included, newsize_bytes_fs is smaller + * than newsize_bytes_lv because of the crypt header. + */ + +int fs_extend_script(struct cmd_context *cmd, struct logical_volume *lv, struct fs_info *fsi, + uint64_t newsize_bytes_fs, char *fsopt) { + char lv_path[PATH_MAX]; + char crypt_path[PATH_MAX]; const char *argv[FS_CMD_MAX_ARGS + 4]; + char *devpath; 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); + devpath = fsi->needs_crypt ? crypt_path : (char *)display_lvname(lv); + + log_print("Extending file system %s to %s (%llu bytes) on %s...", + fsi->fstype, display_size(cmd, newsize_bytes_fs/512), + (unsigned long long)newsize_bytes_fs, devpath); 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 extend 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); + log_print("Extended file system %s on %s.", fsi->fstype, devpath); return 1; } |