How to migrate RHEL7 'Booting from Local Disk' to 'Boot from SAN' ?

Latest response

Environment:

  • RHEL 7.1 with 2 partitions: boot and LVM
  • Destination disk smaller than source disk
  • Destination disk use thin provisioning

Note:
This procedure assumes that the destination disk use thin provisioning
Therefore the data are copied at filesystem level using tar command
It also permits to change root filesystem type (ex from ext4 to xfs)

Procedure:

  • Install and configure device-mapper-multipath

  • Create and map only one LUN from the SAN. If other LUNs are attached, please unmap them during the time of the procedure and reattached them afterward.

  • Reboot the machine in rescue mode on RHEL7 media (DVD or PXE), add 'multipath' kernel option

  • Anaconda propose to mount Linux installation. Use "Skip" option.

  • Enable SSH access

  mv /etc/ssh/sshd_config.anaconda /etc/ssh/sshd_config
  sshd-keygen
  /usr/sbin/sshd
  • Connect to the machine through SSH

  • Use lsblk / multipath -l to detect source and destination volumes

  • In this example, /dev/sda is the source disk and /dev/mapper/mpatha is the destination disk

  • Create partitions on destination disk

  parted /dev/mapper/mpatha -s -a optimal mklabel msdos 
  parted /dev/mapper/mpatha -s -a optimal mkpart primary 1 512
  parted /dev/mapper/mpatha -s -a optimal mkpart primary 512 100%
  parted /dev/mapper/mpatha set 1 boot on
  parted /dev/mapper/mpatha set 2 lvm on
  • Create /boot filesystem (XFS)
  mkfs.xfs /dev/mapper/mpatha1
  mkdir /mnt/source /mnt/clone
  mount /dev/sda1 /mnt/source
  mount /dev/mapper/mpatha1 /mnt/clone
  • Clone /boot
  tar -C /mnt/source -czf - . | tar -xzf - -C /mnt/clone
  umount /mnt/source /mnt/clone
  • Ensure all LVs to replicate are 'ACTIVE'
  lvscan
  • Enable additional LVs if needed, ex:
  lvchange -ay /dev/VolGroup00/datalv
  • Create root volume group on target partition
  vgcreate clone_VolGroup00 /dev/mapper/mpatha2
  • Recreate all LVs with minimal size to store existing data, ex with 5GB LVs:
  for lv in $( lvs VolGroup00 -o name --noheadings ); do 
    lvcreate -y -L5G -n clone_$lv clone_VolGroup00; 
  done
  • Create cloned filesystems
  for lv in $( lvs VolGroup00 -o name --noheadings | grep -v swap); do  
    # use same FS than source 
    FS=$(blkid /dev/VolGroup00/$lv | awk -F'"' '{print $(NF-1)}')
    # OR change to a new FS (uncomment to force)
    #FS=xfs
    # create and mount destination FS
    mkfs.$FS /dev/clone_VolGroup00/clone_$lv
    mkdir /mnt/clone/$lv
    mount /dev/clone_VolGroup00/clone_$lv /mnt/clone/$lv
  done
  • Mount source filesystems
  for lv in $( lvs VolGroup00 -o name --noheadings | grep -v swap); do  
    mkdir /mnt/source/$lv
    mount /dev/VolGroup00/$lv /mnt/source/$lv
  done
  • Check and adapt cloned filesystem size. Use 'df -h' to check.
    For each LV, check the used size on the source and adapt the destination size. Ex:
  df -h /mnt/source/varlv/ /mnt/clone/varlv/
Filesystem                                Size  Used Avail Use% Mounted on
/dev/mapper/VolGroup00-varlv               99G  9.8G   85G  11% /mnt/source/varlv
/dev/mapper/clone_VolGroup00-clone_varlv  5.0G   33M  5.0G   1% /mnt/clone/varlv

Source data use 9.8GB, resize destination LV from 5GB to 20GB

  lvresize -r -L 20G /dev/mapper/clone_VolGroup00-clone_varlv
  • Clone all LVs
  for lv in $( lvs VolGroup00 -o name --noheadings | grep -v swap); do  
    echo "cloning $lv..."
    # copy data using tar - unmount if ok
    tar -C /mnt/source/$lv -czf - . | tar -xzf - -C /mnt/clone/$lv && \
    umount /mnt/source/$lv /mnt/clone/$lv
  done

Note:
Following message may appear during copy, ignore them:
tar: ./spool/postfix/public/pickup: socket ignored

  • Disable source VG
  vgchange -an VolGroup00
  • Set lvm filter to accept only cloned disk
  echo 'devices { global_filter = [ "a|/dev/mapper/mpatha|", "r|.*|" ] }' >> /etc/lvm/lvm.conf  
  • Rename vg/lv to original names
  vgrename clone_VolGroup00 VolGroup00
  for lv in $( lvs VolGroup00 -o name --noheadings ); do
    lvrename VolGroup00 $lv ${lv/clone_/}
  done  
  • Run Anaconda menu and chose to mount Linux installation (do not use read-only)
  anaconda
  • When dropped into the shell:
  chroot /mnt/sysimage
  • Create swap
lvresize -L 8G /dev/VolGroup00/swaplv
mkswap /dev/VolGroup00/swaplv
swapon -a
  • Update fstab on clone
  UUID=$( blkid -o value -s UUID /dev/mapper/mpatha1 )
  sed -i "s:UUID=.*/boot:UUID=$UUID /boot:" /etc/fstab
  • If filesystem type has changed, update /etc/fstab accordingly.
    Ex if migrating from ext4 to XFS, replace:
/dev/mapper/VolGroup00-LogVol00 /       ext4    defaults        1       2

With

/dev/mapper/VolGroup00-LogVol00 /       xfs     defaults        1       2
  • Install grub
  grub2-install /dev/mapper/mpatha
  cp /boot/grub2/grub.cfg /boot/grub2/grub.cfg.ori
  grub2-mkconfig -o /boot/grub2/grub.cfg
  • Update /boot/grub2/device.map, ex:
    Replace
(hd0)      /dev/sda

With:

(hd0)      /dev/mapper/mpatha
  • if friendly_names is disabled, create an alias to identify the correct disk, ex:
  echo "
multipaths {  
  multipath {
    wwid     36005076300810a1f6000000000000185
    alias    mpatha
  }
}" >> /etc/multipath.conf
  • Check if lvm filter is used and update it accordingly, ex:
  egrep "^[ \t]*global_filter[ \t]*=|^[ \t]*filter[ \t]*=" /etc/lvm/lvm.conf
  filter = ["a|^/dev/sda|", "r/.*/"]
  # replace with:  
  filter = ["a|^/dev/mapper/mpatha|", "r/.*/"]
  • Re-generate initramfs with multipath module
  cp /boot/initramfs-$(uname -r).img   /boot/initramfs-$(uname -r).img.ori
  dracut --add multipath -fv
  • Reboot and disable local disk in the bios (or remove them physically)

  • Reattached additional LUNs if any

  • Configure HBA bios to boot on the correct LUN and reboot.

Responses