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

Allow full migration of /dev/disk/by-id/devices #1450

Merged
merged 17 commits into from
Sep 1, 2017
Merged
Show file tree
Hide file tree
Changes from 14 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
95 changes: 61 additions & 34 deletions usr/share/rear/finalize/GNU/Linux/260_rename_diskbyid.sh
Original file line number Diff line number Diff line change
Expand Up @@ -2,37 +2,33 @@
#
# We call sed once for each substituation
# it would be better to build one sed script and use this later
# (like verify/GNU/Linux/21_migrate_recovery_configuration.sh
# and finalize/GNU/Linux/150_migrate_disk_devices_layout.sh)
# (like finalize/GNU/Linux/250_migrate_disk_devices_layout.sh)
#
# OLD_ID_FILE contains entries like these (last 2 lines are multipath targets)
# cciss-3600508b100104c3953573830524b0004 cciss/c0d0
# cciss-3600508b100104c3953573830524b0004-part1 cciss/c0d0p1
# cciss-3600508b100104c3953573830524b0004-part2 cciss/c0d0p2
# cciss-3600508b100104c3953573830524b0004-part3 cciss/c0d0p3
# cciss-3600508b100104c3953573830524b0004-part5 cciss/c0d0p5
# scsi-1HITACHI_770122800061 dm-1
# scsi-1HITACHI_770122800062 dm-0
# dm-name-rootvg-lv_swap /dev/mapper/rootvg-lv_swap
# dm-name-rootvg-lvroot /dev/mapper/rootvg-lvroot
# dm-uuid-LVM-AkjnD2jS2SCCZKbxkZeaByuZLNdHc6qCYp35NGzNbhMaL3YZYtRxuPoerlAkOcj3 /dev/mapper/rootvg-lvroot
# dm-uuid-LVM-AkjnD2jS2SCCZKbxkZeaByuZLNdHc6qCeXNhvq6sxq6LQh4aksjr1WUANFuCKooc /dev/mapper/rootvg-lv_swap
# scsi-0QEMU_QEMU_CD-ROM_drive-scsi0-0-0-0 /dev/sr0
# virtio-a1bd20bf-f66d-442c-8 /dev/vda
# virtio-a1bd20bf-f66d-442c-8-part1 /dev/vda1
# virtio-a1bd20bf-f66d-442c-8-part2 /dev/vda2
# virtio-a1bd20bf-f66d-442c-8-part3 /dev/vda3
#
# Those devices have already been adjusted in
# verify/GNU/Linux/21_migrate_recovery_configuration.sh
# cciss-3600508b100104c3953573830524b0004 /dev/cciss/c0d0
# cciss-3600508b100104c3953573830524b0004-part1 /dev/cciss/c0d0p1

FILES="/etc/fstab /boot/grub/menu.lst /boot/grub2/grub.cfg /boot/grub/device.map /boot/efi/*/*/grub.cfg /etc/lvm/lvm.conf"
FILES="/etc/fstab /boot/grub/menu.lst /boot/grub2/grub.cfg /boot/grub/device.map /boot/efi/*/*/grub.cfg /etc/lvm/lvm.conf /etc/lilo.conf /etc/yaboot.conf /etc/default/grub_installdevice"

OLD_ID_FILE=${VAR_DIR}/recovery/diskbyid_mappings
NEW_ID_FILE=$TMP_DIR/diskbyid_mappings
OLD_ID_FILE="${VAR_DIR}/recovery/diskbyid_mappings"
NEW_ID_FILE="$TMP_DIR/diskbyid_mappings"

[ ! -s "$OLD_ID_FILE" ] && return 0
[ -z "$FILES" ] && return 0

# udevinfo is deprecated by udevadm (SLES 10 still uses udevinfo)
UdevSymlinkName=""
type -p udevinfo >/dev/null && UdevSymlinkName="udevinfo -r / -q symlink -n"
type -p udevadm >/dev/null && UdevSymlinkName="udevadm info --root --query=symlink --name"
[[ -z "$UdevSymlinkName" ]] && {
LogPrint "Could not find udevinfo nor udevadm (skip 160_rename_diskbyid.sh)"
return
}
# Apply device mapping to replace device in case of migration.
# apply-mappings() function defined in lib/layout-function.sh
apply-mappings $OLD_ID_FILE

# replace the device names with the real devices

Expand All @@ -44,7 +40,9 @@ while read ID DEV_NAME; do
# we delete DEV_NAME to make sure it won't get used
DEV_NAME=""
else
SYMLINKS=$($UdevSymlinkName $DEV_NAME)
# get symlinks defined by udev from a device
# UdevSymlinkName() defined in lib/layout-function.sh
SYMLINKS=$(UdevSymlinkName $DEV_NAME)
set -- $SYMLINKS
while [ $# -gt 0 ]; do
if [[ $1 =~ /dev/disk/by-id ]]; then
Expand All @@ -57,37 +55,66 @@ while read ID DEV_NAME; do
done
fi
echo $ID $DEV_NAME $ID_NEW
done < $OLD_ID_FILE > $NEW_ID_FILE
done < "$OLD_ID_FILE" > "$NEW_ID_FILE"

sed_change_monitor="$TMP_DIR/by-id_change"

for file in $FILES; do
realfile=$TARGET_FS_ROOT/$file
[ ! -f $realfile ] && continue # if file is not there continue with next one
realfile="$TARGET_FS_ROOT/$file"
[ ! -f "$realfile" ] && continue # if file is not there continue with next one
# keep backup
cp $realfile ${realfile}.rearbak
cp "$realfile" "${realfile}.rearbak"
# we should consider creating a sed script within a string
# and then call sed once (as done other times)
while read ID DEV_NAME ID_NEW; do
# initialize a sed_change variable to monitor if sed change a file
sed_change=0

if [ -n "$ID_NEW" ]; then

# If ID and ID_NEW are the same, no need to change, go the next device.
[[ "$ID" == "$ID_NEW" ]] && continue

# great, we found a new device
ID_FULL=/dev/disk/by-id/$ID
ID_NEW_FULL=/dev/disk/by-id/$ID_NEW
sed -i "s#$ID_FULL\([^-a-zA-Z0-9]\)#$ID_NEW_FULL\1#g" \
$realfile

# Using w flag to store changes made by sed in a output file $sed_change_monitor
# if no change is made, $sed_change_monitor will stay empty.
sed -i "s#$ID_FULL\([^-a-zA-Z0-9]\)#$ID_NEW_FULL\1#w $sed_change_monitor" \
"$realfile"
# ^^^^^^^^^^^^^^^
# This is to make sure we get the full ID (and not
# a substring) because we ask sed for a char other then
# those contained in IDs.
# This does not work with IDs at line end: substitute also those:
sed -i "s#$ID_FULL\$#$ID_NEW_FULL#g" $realfile

# Check if sed made chage on the current file.
# (when size of $sed_change_monitor is not null)
test -s "$sed_change_monitor" && sed_change=1

sed -i "s#$ID_FULL\$#$ID_NEW_FULL#w $sed_change_monitor" $realfile
test -s "$sed_change_monitor" && sed_change=1
else
# lets try with the DEV_NAME as fallback
[ -z "$DEV_NAME" ] && continue
# not even DEV_NAME exists, we can't do anything
ID_FULL=/dev/disk/by-id/$ID
sed -i "s#$ID_FULL\([^-a-zA-Z0-9]\)#/dev/$DEV_NAME\1#g" \
$realfile
sed -i "s#$ID_FULL\$#/dev/$DEV_NAME#g" $realfile
ID_FULL=$ID
sed -i "s#$ID_FULL\([^-a-zA-Z0-9]\)#/dev/$DEV_NAME\1#w $sed_change_monitor" \
"$realfile"
test -s "$sed_change_monitor" && sed_change=1

sed -i "s#$ID_FULL\$#/dev/$DEV_NAME#w $sed_change_monitor" "$realfile"
test -s "$sed_change_monitor" && sed_change=1
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why do you need to check this file after every call of sed? Isn't it enough to check it once at the end of the while loop before printing out the change info?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this file will be written by sed if changes are made into $realfile.
But it is overwritten (no append).
So if on the last sed didn't make any change, the file $sed_change_monitor will be empty even if a previous sed made a change.

fi

# Checking if sed change something in a file (by using w sed flag)
# LogPrint only when a change was made.
if test $sed_change -eq 1 ; then
LogPrint "Patching $file: Replacing [$ID_FULL] by [$ID_NEW_FULL]"
rm "$sed_change_monitor"
fi

done < $NEW_ID_FILE
done

Expand Down
43 changes: 29 additions & 14 deletions usr/share/rear/layout/save/GNU/Linux/150_save_diskbyid_mappings.sh
Original file line number Diff line number Diff line change
@@ -1,20 +1,35 @@
# Remember the mappings if any for disk-by-id

# be careful udevinfo is old, now we have udevadm
# udevinfo -r -q name -n /dev/disk/by-id/scsi-360060e8015268c000001268c000065c0-part4
# udevadm info --query=name --name /dev/disk/by-id/dm-name-vg_fedora-lv_root
UdevQueryName=""
type -p udevinfo >/dev/null && UdevQueryName="udevinfo -r -q name -n"
type -p udevadm >/dev/null && UdevQueryName="udevadm info --query=name --name"
[[ -z "$UdevQueryName" ]] && {
LogPrint "Could not find udevinfo nor udevadm (skip diskbyid_mappings)"
return
}

ls /dev/disk/by-id | while read ID;
do
ID_NEW=$($UdevQueryName /dev/disk/by-id/$ID)
echo $ID $ID_NEW
done >$VAR_DIR/recovery/diskbyid_mappings
# create diskbyid_mappings file:
# we need to keep absolute PATH for device in order to be able to easily use apply_mappings() function.
# and apply disk mapping during migration.
#
# example: scsi-360060e8015268c000001268c000065c0-part4 /dev/sda4
# wwn-0x600507680c82004cf8000000000000d8 /dev/mapper/maptha

# get real device name from a symlink defined by udev
# UdevQueryName() defined in lib/layout-function.sh
ID_NEW=$(UdevQueryName /dev/disk/by-id/$ID)
if [[ $ID_NEW =~ ^dm- ]]; then
# If dm- device is a multipath, get its /dev/mapper/name instead of /dev/dm-X
# as /dev/dm-X are not persistent across reboot and not used in disk mapping file.

# get symlinks defined by udev from a device
# UdevSymlinkName() defined in lib/layout-function.sh
SYMLINKS=$(UdevSymlinkName /dev/$ID_NEW)
set -- $SYMLINKS
while [ $# -gt 0 ]; do
if [[ $1 =~ /dev/mapper/ ]]; then
ID_NEW=${1#/dev/}
break
else
shift
fi
done
fi
echo $ID /dev/$ID_NEW
done >$VAR_DIR/recovery/diskbyid_mappings

[[ -f $VAR_DIR/recovery/diskbyid_mappings ]] && Log "Saved diskbyid_mappings"