summaryrefslogtreecommitdiff
path: root/lib/activate
diff options
context:
space:
mode:
authorDavid Teigland <teigland@redhat.com>2022-06-14 15:20:21 -0500
committerDavid Teigland <teigland@redhat.com>2022-09-13 15:15:05 -0500
commit264827cb98458f7100456eeebf7fdde8dcbc0ad4 (patch)
tree301eb6cceaad99a2886ed526324756eee43bf2e8 /lib/activate
parent18722dfdf4d3e6f172d0b2af8bbdc4a154ea1dc0 (diff)
downloadlvm2-264827cb98458f7100456eeebf7fdde8dcbc0ad4.tar.gz
lvresize: add new options and defaults for fs handling
The new option "--fs String" for lvresize/lvreduce/lvextend controls the handling of file systems before/after resizing the LV. --resizefs is the same as --fs resize. The new option "--fsmode String" can be used to control mounting and unmounting of the fs during resizing. Possible --fs values: checksize Only applies to reducing size; does nothing for extend. Check the fs size and reduce the LV if the fs is not using the affected space, i.e. the fs does not need to be shrunk. Fail the command without reducing the fs or LV if the fs is using the affected space. resize Resize the fs using the fs-specific resize command. This may include mounting, unmounting, or running fsck. See --fsmode to control mounting behavior, and --nofsck to disable fsck. resize_fsadm Use the old method of calling fsadm to handle the fs (deprecated.) Warning: this option does not prevent lvreduce from destroying file systems that are unmounted (or mounted if prompts are skipped.) ignore Resize the LV without checking for or handling a file system. Warning: using ignore when reducing the LV size may destroy the file system. Possible --fsmode values: manage Mount or unmount the fs as needed to resize the fs, and attempt to restore the original mount state at the end. nochange Do not mount or unmount the fs. If mounting or unmounting is required to resize the fs, then do not resize the fs or the LV and fail the command. offline Unmount the fs if it is mounted, and resize the fs while it is unmounted. If mounting is required to resize the fs, then do not resize the fs or the LV and fail the command. Notes on lvreduce: When no --fs or --resizefs option is specified: . lvextend default behavior is fs ignore. . lvreduce default behavior is fs checksize (includes activating the LV.) With the exception of --fs resize_fsadm|ignore, lvreduce requires the recent libblkid fields FSLASTBLOCK and FSBLOCKSIZE. FSLASTBLOCK*FSBLOCKSIZE is the last byte used by the fs on the LV, which determines if reducing the fs is necessary.
Diffstat (limited to 'lib/activate')
-rw-r--r--lib/activate/dev_manager.c75
-rw-r--r--lib/activate/dev_manager.h2
2 files changed, 77 insertions, 0 deletions
diff --git a/lib/activate/dev_manager.c b/lib/activate/dev_manager.c
index 2bfd275fd..5fec52a2a 100644
--- a/lib/activate/dev_manager.c
+++ b/lib/activate/dev_manager.c
@@ -4028,3 +4028,78 @@ out:
return r;
}
+
+/*
+ * crypt offset is usually the LUKS header size but can be larger.
+ * The LUKS header is usually 2MB for LUKS1 and 16MB for LUKS2.
+ * The offset needs to be subtracted from the LV size to get the
+ * size used to resize the crypt device.
+ */
+int get_crypt_table_offset(dev_t crypt_devt, uint32_t *offset_bytes)
+{
+ struct dm_task *dmt = dm_task_create(DM_DEVICE_TABLE);
+ uint64_t start, length;
+ char *target_type = NULL;
+ void *next = NULL;
+ char *params = NULL;
+ char offset_str[32] = { 0 };
+ int copy_offset = 0;
+ int spaces = 0;
+ int i, i_off = 0;
+
+ if (!dmt)
+ return_0;
+
+ if (!dm_task_set_major_minor(dmt, (int)MAJOR(crypt_devt), (int)MINOR(crypt_devt), 0)) {
+ dm_task_destroy(dmt);
+ return_0;
+ }
+
+ /* Non-blocking status read */
+ if (!dm_task_no_flush(dmt))
+ log_warn("WARNING: Can't set no_flush for dm status.");
+
+ if (!dm_task_run(dmt)) {
+ dm_task_destroy(dmt);
+ return_0;
+ }
+
+ next = dm_get_next_target(dmt, next, &start, &length, &target_type, &params);
+
+ if (!target_type || !params || strcmp(target_type, "crypt")) {
+ dm_task_destroy(dmt);
+ return_0;
+ }
+
+ /*
+ * get offset from params string:
+ * <cipher> <key> <iv_offset> <device> <offset> [<#opt_params> <opt_params>]
+ * <offset> is reported in 512 byte sectors.
+ */
+ for (i = 0; i < strlen(params); i++) {
+ if (params[i] == ' ') {
+ spaces++;
+ if (spaces == 4)
+ copy_offset = 1;
+ if (spaces == 5)
+ break;
+ continue;
+ }
+ if (!copy_offset)
+ continue;
+
+ offset_str[i_off++] = params[i];
+
+ if (i_off == sizeof(offset_str)) {
+ offset_str[0] = '\0';
+ break;
+ }
+ }
+ dm_task_destroy(dmt);
+
+ if (!offset_str[0])
+ return_0;
+
+ *offset_bytes = ((uint32_t)strtoul(offset_str, NULL, 0) * 512);
+ return 1;
+}
diff --git a/lib/activate/dev_manager.h b/lib/activate/dev_manager.h
index 9980e1647..b494e3eaf 100644
--- a/lib/activate/dev_manager.h
+++ b/lib/activate/dev_manager.h
@@ -29,6 +29,8 @@ struct lv_seg_status;
int read_only_lv(const struct logical_volume *lv, const struct lv_activate_opts *laopts, const char *layer);
+int get_crypt_table_offset(dev_t crypt_devt, uint32_t *offset_bytes);
+
/*
* Constructor and destructor.
*/