mirror of
git://sourceware.org/git/lvm2.git
synced 2025-01-02 01:18:26 +03:00
vdo: fixes
Better identify VDO device with major:minor. Handle different LV name from originally converted origin LV. Improve --dry-run handling.
This commit is contained in:
parent
419c93c873
commit
1ae157a0f6
@ -1,5 +1,9 @@
|
|||||||
Version 2.03.14 -
|
Version 2.03.14 -
|
||||||
==================================
|
==================================
|
||||||
|
Improve lvm_import_vdo script.
|
||||||
|
Support VDO LV with lvcreate -ky.
|
||||||
|
Fix lvconvert for VDO LV bigger then 2T.
|
||||||
|
Create VDO LVs automatically without zeroing.
|
||||||
Rename vdoimport to lvm_import_vdo.
|
Rename vdoimport to lvm_import_vdo.
|
||||||
|
|
||||||
Version 2.03.13 - 11th August 2021
|
Version 2.03.13 - 11th August 2021
|
||||||
|
@ -41,10 +41,15 @@ BLOCKDEV="blockdev"
|
|||||||
READLINK="readlink"
|
READLINK="readlink"
|
||||||
READLINK_E="-e"
|
READLINK_E="-e"
|
||||||
MKDIR="mkdir"
|
MKDIR="mkdir"
|
||||||
|
DMSETUP="dmsetup"
|
||||||
|
|
||||||
TEMPDIR="${TMPDIR:-/tmp}/${TOOL}_${RANDOM}$$"
|
TEMPDIR="${TMPDIR:-/tmp}/${TOOL}_${RANDOM}$$"
|
||||||
DM_DEV_DIR="${DM_DEV_DIR:-/dev}"
|
DM_DEV_DIR="${DM_DEV_DIR:-/dev}"
|
||||||
|
|
||||||
|
DEVICENAME=""
|
||||||
|
DEVMAJOR=0
|
||||||
|
DEVMINOR=0
|
||||||
|
|
||||||
DRY=0
|
DRY=0
|
||||||
VERB=""
|
VERB=""
|
||||||
FORCE=""
|
FORCE=""
|
||||||
@ -147,8 +152,6 @@ get_largest_extent_size_() {
|
|||||||
# dereference device name if it is symbolic link
|
# dereference device name if it is symbolic link
|
||||||
detect_lv_() {
|
detect_lv_() {
|
||||||
local DEVICE=$1
|
local DEVICE=$1
|
||||||
local MAJOR
|
|
||||||
local MINOR
|
|
||||||
local SYSVOLUME
|
local SYSVOLUME
|
||||||
local MAJORMINOR
|
local MAJORMINOR
|
||||||
|
|
||||||
@ -161,17 +164,21 @@ detect_lv_() {
|
|||||||
/dev/dm-[0-9]*)
|
/dev/dm-[0-9]*)
|
||||||
read -r <"/sys/block/${RDEVICE#/dev/}/dm/name" SYSVOLUME 2>&1 && DEVICE="$DM_DEV_DIR/mapper/$SYSVOLUME"
|
read -r <"/sys/block/${RDEVICE#/dev/}/dm/name" SYSVOLUME 2>&1 && DEVICE="$DM_DEV_DIR/mapper/$SYSVOLUME"
|
||||||
read -r <"/sys/block/${RDEVICE#/dev/}/dev" MAJORMINOR 2>&1 || error "Cannot get major:minor for \"$DEVICE\"."
|
read -r <"/sys/block/${RDEVICE#/dev/}/dev" MAJORMINOR 2>&1 || error "Cannot get major:minor for \"$DEVICE\"."
|
||||||
MAJOR=${MAJORMINOR%%:*}
|
DEVMAJOR=${MAJORMINOR%%:*}
|
||||||
MINOR=${MAJORMINOR##*:}
|
DEVMINOR=${MAJORMINOR##*:}
|
||||||
;;
|
;;
|
||||||
*)
|
*)
|
||||||
STAT=$(stat --format "MAJOR=\$((0x%t)) MINOR=\$((0x%T))" "$RDEVICE")
|
STAT=$(stat --format "DEVMAJOR=\$((0x%t)) DEVMINOR=\$((0x%T))" "$RDEVICE")
|
||||||
test -n "$STAT" || error "Cannot get major:minor for \"$DEVICE\"."
|
test -n "$STAT" || error "Cannot get major:minor for \"$DEVICE\"."
|
||||||
eval "$STAT"
|
eval "$STAT"
|
||||||
;;
|
;;
|
||||||
esac
|
esac
|
||||||
|
|
||||||
eval "$(dmsetup info -c -j "$MAJOR" -m "$MINOR" -o uuid,name --noheadings --nameprefixes --separator ' ')"
|
DEV="$("$DMSETUP" info -c -j "$DEVMAJOR" -m "$DEVMINOR" -o uuid,name --noheadings --nameprefixes --separator ' ' 2>/dev/null)"
|
||||||
|
case "$DEV" in
|
||||||
|
Device*) ;; # no devices
|
||||||
|
*) eval "$DEV" ;;
|
||||||
|
esac
|
||||||
}
|
}
|
||||||
|
|
||||||
# parse yaml config files into 'prefix_yaml_part_names=("value")' strings
|
# parse yaml config files into 'prefix_yaml_part_names=("value")' strings
|
||||||
@ -226,20 +233,26 @@ convert2lvm_() {
|
|||||||
local TRVDONAME
|
local TRVDONAME
|
||||||
local EXTENTSZ
|
local EXTENTSZ
|
||||||
local IS_LV=1
|
local IS_LV=1
|
||||||
|
local FOUND=""
|
||||||
|
local MAJOR=0
|
||||||
|
local MINOR=0
|
||||||
|
local DM_VG_NAME
|
||||||
|
local DM_LV_NAME
|
||||||
|
|
||||||
DM_UUID=""
|
DM_UUID=""
|
||||||
detect_lv_ "$DEVICE"
|
detect_lv_ "$DEVICE"
|
||||||
case "$DM_UUID" in
|
case "$DM_UUID" in
|
||||||
LVM-*) eval "$(dmsetup splitname --nameprefixes --noheadings --separator ' ' "$DM_NAME")"
|
LVM-*) eval "$("$DMSETUP" splitname --nameprefixes --noheadings --separator ' ' "$DM_NAME")"
|
||||||
if [ -z "$VGNAME" ] || [ "$VGNAME" = "$LVNAME" ] ; then
|
if [ -z "$VGNAME" ] || [ "$VGNAME" = "$LVNAME" ] ; then
|
||||||
VGNAME=$DM_VG_NAME
|
VGNAME=$DM_VG_NAME
|
||||||
|
LVNAME=$DM_LV_NAME
|
||||||
elif test "$VGNAME" != "$DM_VG_NAME" ; then
|
elif test "$VGNAME" != "$DM_VG_NAME" ; then
|
||||||
error "Volume group name \"$VGNAME\" does not match name \"$DM_VG_NAME\" for device \"$DEVICE\"."
|
error "Volume group name \"$VGNAME\" does not match name \"$DM_VG_NAME\" for device \"$DEVICE\"."
|
||||||
fi
|
fi
|
||||||
;;
|
;;
|
||||||
*) IS_LV=0
|
*) IS_LV=0
|
||||||
# Check $VGNANE does not already exists
|
# Check $VGNANE does not already exists
|
||||||
"$LVM" vgs "$VGNAME" && error "Cannot use already existing volume group name \"$VGNAME\"."
|
"$LVM" vgs "$VGNAME" >/dev/null 2>&1 && error "Cannot use already existing volume group name \"$VGNAME\"."
|
||||||
;;
|
;;
|
||||||
esac
|
esac
|
||||||
|
|
||||||
@ -247,15 +260,37 @@ convert2lvm_() {
|
|||||||
|
|
||||||
"$MKDIR" -p -m 0000 "$TEMPDIR" || error "Failed to create $TEMPDIR."
|
"$MKDIR" -p -m 0000 "$TEMPDIR" || error "Failed to create $TEMPDIR."
|
||||||
|
|
||||||
|
# TODO: might use directly /etc/vdoconf.yml (avoding need of 'vdo' manager)
|
||||||
verbose "Getting YAML VDO configuration."
|
verbose "Getting YAML VDO configuration."
|
||||||
"$VDO" printConfigFile $VDOCONF >"$TEMPDIR/vdoconf.yml"
|
"$VDO" printConfigFile $VDOCONF >"$TEMPDIR/vdoconf.yml"
|
||||||
|
|
||||||
VDONAME=$(awk -v DNAME="$DEVICE" '/.*VDOService$/ {VNAME=substr($1, 0, length($1) - 1)} /[[:space:]]*device:/ { if ($2 ~ DNAME) {print VNAME}}' "$TEMPDIR/vdoconf.yml")
|
# Check list of devices in VDO configure file for their major:minor
|
||||||
|
# and match with given $DEVICE devmajor:devminor
|
||||||
|
for i in $(awk '/.*device:/ {print $2}' "$TEMPDIR/vdoconf.yml") ; do
|
||||||
|
local DEV
|
||||||
|
DEV=$("$READLINK" $READLINK_E "$i") || continue
|
||||||
|
STAT=$(stat --format "MAJOR=\$((0x%t)) MINOR=\$((0x%T))" "$DEV" 2>/dev/null) || continue
|
||||||
|
eval "$STAT"
|
||||||
|
test "$MAJOR" = "$DEVMAJOR" && test "$MINOR" = "$DEVMINOR" && {
|
||||||
|
test -z "$FOUND" || error "VDO configuration contains duplicate entries $FOUND and $i"
|
||||||
|
FOUND=$i
|
||||||
|
}
|
||||||
|
done
|
||||||
|
|
||||||
|
test -n "$FOUND" || error "Can't find matching device in vdo configuration file."
|
||||||
|
verbose "Found matching device $FOUND $MAJOR:$MINOR"
|
||||||
|
|
||||||
|
VDONAME=$(awk -v DNAME="$FOUND" '/.*VDOService$/ {VNAME=substr($1, 0, length($1) - 1)} /[[:space:]]*device:/ { if ($2 ~ DNAME) {print VNAME}}' "$TEMPDIR/vdoconf.yml")
|
||||||
TRVDONAME=$(echo "$VDONAME" | tr '-' '_')
|
TRVDONAME=$(echo "$VDONAME" | tr '-' '_')
|
||||||
|
|
||||||
# When VDO volume is 'active', check it's not mounted/being used
|
# When VDO volume is 'active', check it's not mounted/being used
|
||||||
eval "$(dmsetup info -c -o open "$VDONAME" --noheadings --nameprefixes || true)"
|
DM_OPEN="$("$DMSETUP" info -c -o open "$VDONAME" --noheadings --nameprefixes 2>/dev/null || true)"
|
||||||
test "${DM_OPEN:-0}" -eq 0 || error "Cannot converted VDO volume \"$VDONAME\" which is in use!"
|
case "$DM_OPEN" in
|
||||||
|
Device*) ;; # no devices
|
||||||
|
*) eval "$DM_OPEN"
|
||||||
|
test "${DM_OPEN:-0}" -eq 0 || error "Cannot converted VDO volume \"$VDONAME\" which is in use!"
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
|
||||||
#parse_yaml_ "$TEMPDIR/vdoconf.yml" _
|
#parse_yaml_ "$TEMPDIR/vdoconf.yml" _
|
||||||
eval "$(parse_yaml_ "$TEMPDIR/vdoconf.yml" _ | grep "$TRVDONAME" | sed -e "s/_config_vdos_$TRVDONAME/vdo/g")"
|
eval "$(parse_yaml_ "$TEMPDIR/vdoconf.yml" _ | grep "$TRVDONAME" | sed -e "s/_config_vdos_$TRVDONAME/vdo/g")"
|
||||||
@ -263,8 +298,7 @@ convert2lvm_() {
|
|||||||
vdo_logicalSize=$(get_kb_size_with_unit_ "$vdo_logicalSize")
|
vdo_logicalSize=$(get_kb_size_with_unit_ "$vdo_logicalSize")
|
||||||
vdo_physicalSize=$(get_kb_size_with_unit_ "$vdo_physicalSize")
|
vdo_physicalSize=$(get_kb_size_with_unit_ "$vdo_physicalSize")
|
||||||
|
|
||||||
verbose "Going to convert physical sized VDO device $vdo_physicalSize KiB."
|
verbose "Converted VDO device has logical/physical size $vdo_logicalSize/$vdo_physicalSize KiB."
|
||||||
verbose "With logical volume of size $vdo_logicalSize KiB."
|
|
||||||
|
|
||||||
PARAMS=$(cat <<EOF
|
PARAMS=$(cat <<EOF
|
||||||
allocation {
|
allocation {
|
||||||
@ -313,7 +347,7 @@ EOF
|
|||||||
|
|
||||||
pvfree=$(( pvfree / 1024 - 2048 )) # to KiB
|
pvfree=$(( pvfree / 1024 - 2048 )) # to KiB
|
||||||
else
|
else
|
||||||
pvfree=$("$LVM" lvs -o size --units b --nosuffix --noheadings "$VGNAME/$LVNAME")
|
pvfree=$("$LVM" lvs -o size --units b --nosuffix --noheadings "$DM_VG_NAME/$DM_LV_NAME")
|
||||||
pvfree=$(( pvfree / 1024 )) # to KiB
|
pvfree=$(( pvfree / 1024 )) # to KiB
|
||||||
fi
|
fi
|
||||||
|
|
||||||
@ -334,11 +368,11 @@ EOF
|
|||||||
vg_extent_size=$(( vg_extent_size / 1024 ))
|
vg_extent_size=$(( vg_extent_size / 1024 ))
|
||||||
|
|
||||||
test "$vg_extent_size" -le "$EXTENTSZ" || {
|
test "$vg_extent_size" -le "$EXTENTSZ" || {
|
||||||
error "Please vgchange extent_size to at most $EXTENTSZ KiB or extend and align virtual size on $vg_extent_size KiB."
|
error "Please vgchange extent_size to at most $EXTENTSZ KiB or extend and align virtual size of VDO device on $vg_extent_size KiB."
|
||||||
}
|
}
|
||||||
verbose "Renaming existing LV to be used as _vdata volume for VDO pool LV."
|
verbose "Renaming existing LV to be used as _vdata volume for VDO pool LV."
|
||||||
dry "$LVM" lvrename $YES $VERB "$VGNAME/$LVNAME" "$VGNAME/${LVNAME}_vpool" || {
|
dry "$LVM" lvrename $YES $VERB "$VGNAME/$DM_LV_NAME" "$VGNAME/${LVNAME}_vpool" || {
|
||||||
error "Rename of LV \"$VGNAME/$LVNAME\" failed, while VDO header has been already moved!"
|
error "Rename of LV \"$VGNAME/$DM_LV_NAME\" failed, while VDO header has been already moved!"
|
||||||
}
|
}
|
||||||
fi
|
fi
|
||||||
|
|
||||||
@ -372,5 +406,7 @@ do
|
|||||||
shift
|
shift
|
||||||
done
|
done
|
||||||
|
|
||||||
|
test -n "$DEVICENAME" || error "Device name is not specified. (see: $TOOL --help)"
|
||||||
|
|
||||||
# do conversion
|
# do conversion
|
||||||
convert2lvm_ "$DEVICENAME"
|
convert2lvm_ "$DEVICENAME"
|
||||||
|
@ -61,22 +61,36 @@ lvm_import_vdo --dry-run -y -v --name $lv1 "$DM_DEV_DIR/$vg/$lv1"
|
|||||||
|
|
||||||
lvm_import_vdo -y --name $lv1 "$DM_DEV_DIR/$vg/$lv1"
|
lvm_import_vdo -y --name $lv1 "$DM_DEV_DIR/$vg/$lv1"
|
||||||
|
|
||||||
# ATM needed - since we do not call 'vdo convert' in this case
|
# ensure VDO device is not left in config file
|
||||||
vdo remove $VDOCONF --force --name "$VDONAME" || true
|
vdo remove $VDOCONF --force --name "$VDONAME" 2>/dev/null || true
|
||||||
|
|
||||||
|
lvremove -f $vg
|
||||||
|
|
||||||
|
|
||||||
|
# Test user can specify different VDO LV name (so the original LV is renamed)
|
||||||
|
lvcreate -y -L5G -n $lv1 $vg
|
||||||
|
|
||||||
|
vdo create $VDOCONF --name "$VDONAME" --device="$DM_DEV_DIR/$vg/$lv1" --vdoLogicalSize=10G
|
||||||
|
|
||||||
|
lvm_import_vdo -y --name $vg/$lv2 "$DM_DEV_DIR/$vg/$lv1"
|
||||||
|
|
||||||
|
check lv_exists $vg $lv2
|
||||||
|
check lv_not_exists $vg $lv1
|
||||||
|
|
||||||
vgremove -f $vg
|
vgremove -f $vg
|
||||||
|
|
||||||
|
# ensure VDO device is not left in config file
|
||||||
|
vdo remove $VDOCONF --force --name "$VDONAME" 2>/dev/null || true
|
||||||
|
|
||||||
aux wipefs_a "$dev1"
|
aux wipefs_a "$dev1"
|
||||||
|
|
||||||
# prepare 'unused' $vg2
|
# prepare 'unused' $vg2
|
||||||
vgcreate $vg2 "$dev2"
|
vgcreate $vg2 "$dev2"
|
||||||
|
|
||||||
#
|
#
|
||||||
# Check conversion of VDO volume on non-LV device
|
# Check conversion of VDO volume on non-LV device and with >2T size
|
||||||
#
|
#
|
||||||
vdo create $VDOCONF --name "$VDONAME" --device="$dev1" --vdoLogicalSize=31G
|
vdo create $VDOCONF --name "$VDONAME" --device="$dev1" --vdoLogicalSize=3T
|
||||||
|
|
||||||
mkfs -E nodiscard "$DM_DEV_DIR/mapper/$VDONAME"
|
|
||||||
|
|
||||||
# Fail with an already existing volume group $vg2
|
# Fail with an already existing volume group $vg2
|
||||||
not lvm_import_vdo --dry-run -y -v --name $vg2/$lv1 "$dev1" |& tee err
|
not lvm_import_vdo --dry-run -y -v --name $vg2/$lv1 "$dev1" |& tee err
|
||||||
@ -87,7 +101,7 @@ vdo stop $VDOCONF --name "$VDONAME"
|
|||||||
|
|
||||||
lvm_import_vdo -y -v --name $vg/$lv1 "$dev1"
|
lvm_import_vdo -y -v --name $vg/$lv1 "$dev1"
|
||||||
|
|
||||||
fsck -n "$DM_DEV_DIR/$vg/$lv1"
|
check lv_field $vg/$lv1 size "3.00t"
|
||||||
|
|
||||||
vgremove -f $vg
|
vgremove -f $vg
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user