mirror of
git://sourceware.org/git/lvm2.git
synced 2025-03-10 16:58:47 +03:00
blkdeactive: Introduce option "forcevg" to forcibly deactivate VG
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>
This commit is contained in:
parent
71a453a25b
commit
37796aa7bf
@ -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
|
||||
|
@ -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)"
|
||||
# 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)"
|
||||
|
||||
# Do deactivate
|
||||
# Single dm device tree deactivation.
|
||||
if test -b "$1"; then
|
||||
$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
|
||||
|
Loading…
x
Reference in New Issue
Block a user