Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Bigboot can fail with pvmove error #70

Open
swapdisk opened this issue Jun 24, 2024 · 1 comment
Open

Bigboot can fail with pvmove error #70

swapdisk opened this issue Jun 24, 2024 · 1 comment

Comments

@swapdisk
Copy link
Member

Bug lvmteam/lvm2#148 in the upstream LVM pvmove command may lead to the bigboot.sh script failing in the evict_end_PV function under certain conditions. The evict_end_PV function is only used if there are not a sufficient number of free physical extents at the end of the physical volume that needs to be reduced. In that case, these physical extents need to be moved. The function uses the pvmove command for this, but may encounter the upstream bug if the physical extents to be moved include logical extents for more than one logical volume. "Internal error: Referenced LV pvmove0 not listed" will be observed in the console output if this failure mode is encountered. The /boot partition size will not be increased, the playbook will fail gracefully and the target host will suffer no harm.

As a workaround, it is possible to manually move the required physical extents by running pvmove commands more than once giving physical extent ranges that include logical extents from only one logical volume at a time. These commands can be safely used manually on an impacted host in advance to avoid the error when running the role. Refer to the upstream issue for an example of these commands.

@swapdisk
Copy link
Member Author

swapdisk commented Oct 9, 2024

I've whipped up the little script below. It moves all the free logical extents to the end of a physical volume in a way that works without hitting the pvmove bug. After running this script, the bigboot role can be used without the risk of it failing because of the pvmove bug.

I'm tempted to use this script instead of the bare pvmove command currently executed by the "Evict extents from end of physical volume" task here. Folks, tell me if that's a bad idea or I'll go ahead and do it. If you try this script, kindly comment if it works for you or if you find any issue with it.

Tested on RHEL7, where I'm fairly certain we'll never see the fixed pvmove being released...

#!/bin/bash
#
# pvsqueeze - Squeeze linear extents into free holes
#
# This script iteratively moves linear (allocated to LV) extents to fill in
# free holes found in a PV segment map. The end result is that all free
# extents are at the end of the PV. Use this script in anger as required!
#
# The script outputs the PV segment map before moving anything, then iterates
# stuffing extents in each free hole until there are no more except for the
# last one, and finally outputs the PV segment map again showing the changes.
#

# Usage
if [[ ! $1 =~ ^/dev/ ]]; then
  echo "Usage: $0 PV"
  exit 1
fi

# Set some vars
pvdev=$1
pvsargs='--noheadings --nameprefixes --segments -o pvseg_start,pvseg_size,segtype'

# Show current segment map
echo 'PV segment map before squeeze:'
pvs "$pvdev" --segments -o lvname,pvseg_start,pvseg_size,seg_le_ranges
if [[ $? -ne 0 ]]; then
  echo "$0: Fatal error getting PV info"
  exit 1
fi

# Iterate stuffing PEs in each free hole
while true; do
  # Find first free segment
  LVM2_PVSEG_START=
  eval $(pvs "$pvdev" $pvsargs | grep SEGTYPE=.free. | head -1)
  if [[ -z $LVM2_PVSEG_START ]]; then
    echo "$0: No free segments found"
    exit 1
  fi
  free_start=$LVM2_PVSEG_START
  free_size=$LVM2_PVSEG_SIZE

  # Find the last linear segment
  LVM2_PVSEG_START=
  eval $(pvs "$pvdev" $pvsargs | grep SEGTYPE=.linear. | tail -1)
    if [[ -z $LVM2_PVSEG_START ]]; then
    echo "$0: No linear segments found"
    exit 1
  fi
  move_start=$LVM2_PVSEG_START
  move_size=$LVM2_PVSEG_SIZE

  # We're done when first free is after the last linear
  [[ $free_start -gt $move_start ]] && break

  # Move last linear PEs to the free segment
  from_range="$pvdev:$((move_start+move_size-free_size))-$((move_start+move_size-1))"
  to_range="$pvdev:$((free_start))-$((free_start+free_size))"
  echo "Moving $from_range to $to_range..."
  pvmove --atomic --alloc anywhere "$from_range" "$to_range"
  if [[ $? -ne 0 ]]; then
    echo "$0: Fatal error doing pvmove"
    exit 1
  fi
done

# Show squeezed segment map
echo 'PV segment map after squeeze:'
pvs "$pvdev" --segments -o lvname,pvseg_start,pvseg_size,seg_le_ranges

exit 0

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant