diff options
author | Zhang Huan <zhanghuan@huayun.com> | 2021-03-02 11:32:54 -0600 |
---|---|---|
committer | David Teigland <teigland@redhat.com> | 2021-03-02 11:32:54 -0600 |
commit | 37796aa7bf81393c2d07ff245dd4c496a00218d6 (patch) | |
tree | bde2bc041c0d0235b7af669d634deda828a8301f | |
parent | 71a453a25bb305425f1f8f5b6b65a5fd9ec08f5f (diff) | |
download | lvm2-37796aa7bf81393c2d07ff245dd4c496a00218d6.tar.gz |
blkdeactive: Introduce option "forcevg" to forcibly deactivate VGdev-dct-lvmlockctl-kill-2
This patch introduces new option "forcevg" for LVM, the main purpose is
to flush in-flight I/O operations and replace the LV's device mapper
table with 'error' target, this is accomplished by using command
"dmsetup wipe_table".
To handle the failure as soon as possible, it will not deactivate
holders and not try to use command "lvchange", thus can speed up
wiping table.
This option is supposed to be used by "lvmlockctl" command to forcibly
deactivate volume group, this can avoid watchdog reset when detect
drive failures.
Signed-off-by: Zhang Huan <zhanghuan@huayun.com>
[Refactored changes and commit log]
Signed-off-by: Leo Yan <leo.yan@linaro.org>
-rw-r--r-- | man/blkdeactivate.8_main | 12 | ||||
-rw-r--r-- | scripts/blkdeactivate.sh.in | 70 |
2 files changed, 73 insertions, 9 deletions
diff --git a/man/blkdeactivate.8_main b/man/blkdeactivate.8_main index 06af52e52..eec663eca 100644 --- a/man/blkdeactivate.8_main +++ b/man/blkdeactivate.8_main @@ -52,6 +52,12 @@ Retry removal several times in case of failure. Deactivate the whole LVM Volume Group when processing a Logical Volume. Deactivating the Volume Group as a whole is quicker than deactivating each Logical Volume separately. +.IP \fIforcevg\fP +Forcibly deactivate the whole LVM Volume Group as soon as possible. +The primary job of this option is to flush the in-flight I/O operation +and then replace the LV's device-mapper table with 'error' target. +This is accomplished by using command "dmsetup wipe_table". +When this option is used, any other options (e.g. "-d retry|force", "-u") will be ignored. .RE .TP .BR -m ", " --mpathoptions \ \fImpath_options\fP @@ -118,6 +124,12 @@ Volume Group at once when processing an LVM Logical Volume. .B blkdeactivate -u -d retry -l wholevg .BR .P +Forcibly deactivate the whole vg. +.BR +# +.B blkdeactivate -l forcevg testvg +.BR +.P Deactivate all supported block devices found in the system. If the deactivation of a device-mapper device fails, retry it and force removal. .BR diff --git a/scripts/blkdeactivate.sh.in b/scripts/blkdeactivate.sh.in index 7c517b87b..db3291ae8 100644 --- a/scripts/blkdeactivate.sh.in +++ b/scripts/blkdeactivate.sh.in @@ -72,6 +72,8 @@ DO_UMOUNT=0 # Deactivate each LV separately by default (not the whole VG). LVM_DO_WHOLE_VG=0 +# Forcily deactivate the whole VG by wiping DM table +LVM_DO_FORCE_VG=0 # Do not retry LV deactivation by default. LVM_CONFIG="activation{retry_deactivation=0}" @@ -137,6 +139,7 @@ usage() { echo " LVM_OPTIONS:" echo " retry retry removal several times in case of failure" echo " wholevg deactivate the whole VG when processing an LV" + echo " forcevg force deactivate (wipe_table) the whole VG" echo " MDRAID_OPTIONS:" echo " wait wait for resync, recovery or reshape to complete first" echo " MPATH_OPTIONS:" @@ -287,6 +290,49 @@ deactivate_lvm () { fi } +is_top_level_lv() { + is_top_level_device && return 0 + skip=1 + while $LSBLK_READ; do + # First line self device + test "$skip" -eq 1 && skip=0 && continue + + # not top device but top lv in this VG, return 0 + test "$devtype" != "lvm" && return 0 + test ${name:0:${#DM_VG_NAME}+1} != $DM_VG_NAME"-" && return 0 + test ${name:0:${#DM_VG_NAME}+2} = $DM_VG_NAME"--" && return 0 + # the same vg, hidden lv + test ${name:0:${#DM_VG_NAME}+1} = $DM_VG_NAME"-" && return 1 + done <<< "$($LSBLK $DEV_DIR/$kname)" +} + +deactivate_vg () { + local VG_NAME; local LV_NAME; + local DM_VG_NAME; local DM_LV_NAME; + local LVS; + local skip_disablequeue=0 + + VG_NAME=$name + DM_VG_NAME=${name/-/--} + test -z "${SKIP_VG_LIST["$DM_VG_NAME"]}" || return 1 + test "$LVM_AVAILABLE" -eq 0 && { + add_device_to_skip_list + return 1 + } + + # Replace DM table with 'error' target. + # The reason for not using command "lvchange" ahead if because it may hang + # for a long time for the failed device. + echo -n " [LVM]: force deactivating Logical Volumes for $VG_NAME... " + "$DMSETUP" info -c -S "uuid=~LVM && vgname=$VG_NAME && lv_layer=\"\"" \ + -o name --noheadings | xargs "$DMSETUP" wipe_table + if [ "$?" = "0" ]; then + echo "wipe table done" + else + echo "wipe table failed" && return 1 + fi +} + deactivate_md () { local xname xname=$(printf "%s" "$name") @@ -361,7 +407,9 @@ deactivate () { # deactivate_holders first to recursively deactivate any existing # # holders it might have before deactivating the device it processes. # ###################################################################### - if test "$devtype" = "lvm"; then + if test "$devtype" = "vg"; then + deactivate_vg + elif test "$devtype" = "lvm"; then deactivate_lvm elif test "$devtype" = "vdo"; then deactivate_vdo @@ -425,14 +473,17 @@ deactivate_all() { ################################## while test $# -ne 0; do - # Unmount all relevant mountpoints first - while $LSBLK_READ; do - device_umount - done <<< "$($LSBLK "$1" | $SORT_MNT)" - - # Do deactivate - # Single dm device tree deactivation. - if test -b "$1"; then + # Force deactivate the whole vg + if test $LVM_DO_FORCE_VG -ne 0; then + $LSBLK_READ <<< "vg $1 $1" + deactivate || return 1 + elif -b "$1"; then + # Single dm device tree deactivation. + # Unmount all relevant mountpoints first + while $LSBLK_READ; do + device_umount + done <<< "$($LSBLK "$1" | $SORT_MNT)" + $LSBLK_READ <<< "$($LSBLK --nodeps "$1")" # check if the device is not on the skip list already @@ -474,6 +525,7 @@ get_lvmopts() { "") ;; "retry") LVM_CONFIG="activation{retry_deactivation=1}" ;; "wholevg") LVM_DO_WHOLE_VG=1 ;; + "forcevg") LVM_DO_FORCE_VG=1 ;; *) echo "$opt: unknown LVM option" esac done |