Commit ba667908 authored by Ryan Jackson's avatar Ryan Jackson

Added get_edd_map script which uses Linux's EDD probing to determine

which disk corresponds to which BIOS drive number.  Uses disk MBR
signature and disk size in case EDD v3 info isn't available.

Also fixed slicefix to try mounting FreeBSD filesystems as ufstype=44bsd
first, then ufstype=ufs2 if that fails.
parent 11d43f1e
#! /bin/sh
EDD_PATH=/sys/firmware/edd
get_mbr_signature()
{
local device=$1
local sig=`dd if=$device bs=1 count=4 skip=440 2>/dev/null | \
od -t x4 | head -n1 | cut -d' ' -f2`
while [ ${#sig} -lt 8 ]; do
sig="0$sig"
done
if [ -n "$sig" ]; then
echo "0x$sig"
else
return 1
fi
}
get_host_bus()
{
local device=$1
local bus
local busid
local channel
if [ -f $EDD_PATH/int13_dev$device/host_bus ]; then
bus=`cat $EDD_PATH/int13_dev$device/host_bus | sed 's/ */ /g'`
channel=`echo $bus | sed 's/.*channel: *\(.*\)$/\1/'`
busid=`echo $bus | cut -d' ' -f 2`
bus=${bus%% *}
else
return 1
fi
echo "$bus $busid $channel"
}
get_interface()
{
local device=$1
local interface
local device
local lun
if [ -f $EDD_PATH/int13_dev$device/host_bus ]; then
interface=`cat $EDD_PATH/int13_dev$device/interface | \
sed 's/ */ /g'`
lun=`echo $interface | sed -n 's/.*lun: *\(.*\)$/\1/p'`
[ -z "$lun" ] && lun=0
device=`echo $interface | sed -n 's/.*id: *\([0-9]*\) .*$/\1/p'`
if [ -z "$device" ]; then
device=`echo $interface | \
sed -n 's/.*device: *\([0-9]*\) .*$/\1/p'`
fi
interface=${interface%% *}
else
return 1
fi
echo "$interface $device $lun"
}
find_host_adapter()
{
local device=$1
local channel=$2
local pcidev_path=$EDD_PATH/int13_dev$device/pci_dev
if [ -L $pcidev_path ]; then
channel=`expr $channel + 1`
number=`ls $pcidev_path | sed -n -r 's/^(host|ide)([0-9]*)/\2/p' | \
sort -n | sed -n ${channel}p`
else
return 1
fi
echo $number
}
modprobe edd
for bdev in /sys/firmware/edd/int13_dev8*; do
[ `cat $bdev/version` = 0x00 ] && continue
bdev=${bdev##*_dev}
bus_info=`get_host_bus $bdev`
bus=`echo $bus_info | cut -d' ' -f 1`
busid=`echo $bus_info | cut -d' ' -f 2`
channel=`echo $bus_info | cut -d' ' -f 3`
interface_info=`get_interface $bdev`
interface=`echo $interface_info | cut -d' ' -f 1`
device=`echo $interface_info | cut -d' ' -f 2`
lun=`echo $interface_info | cut -d' ' -f 3`
host_adapter=`find_host_adapter $bdev $channel`
path=$EDD_PATH/int13_dev$bdev/pci_dev/host$host_adapter
if [ -e $path ]; then
device_path=$path/target${host_adapter}:0:$device
lun_path=$device_path/${host_adapter}:0:$device:$lun
else
path=$EDD_PATH/int13_dev$bdev/pci_dev/ide$host_adapter
device_path=$path/$host_adapter.$device
lun_path=$device_path
fi
if [ ! -e $lun_path ]; then
# Some versions of the kernel read the wrong offset
# in the EDD structure to find the LUN. Assume LUN 0
# if that is the case here.
path=$device_path/${host_adapter}:0:$device:0
else
path=$lun_path
fi
if [ -e $path/block ]; then
kdev=`ls $path/block`
elif [ -e $path/block:* ]; then
kdev=`ls -d $path/block:*`
fi
### FIXME should also try IDE layer
kdev=${kdev##*/}
kdev=${kdev##*:}
if [ -n "$kdev" ]; then
echo $kdev=$bdev
eval map_bdev_$bdev=$kdev
eval map_kdev_$kdev=$bdev
else
if [ -z "$unmapped_bios_devices" ]; then
unmapped_bios_devices=$bdev
else
unmapped_bios_devices="$unmapped_bios_devices $bdev"
fi
fi
done
for kdev in /sys/block/[hs]d[a-z]; do
kdev=${kdev##*/}
if eval "[ -n \"\${map_kdev_$kdev}\" ]"; then
continue
fi
if [ -z "$unmapped_kernel_devices" ]; then
unmapped_kernel_devices="$kdev"
else
unmapped_kernel_devices="$unmapped_kernel_devices $kdev"
fi
done
# Hmmm, we couldn't figure out the device using EDD 3.0. Try based on size
# and MBR signature
new_unmapped_bdevs=''
for bdev in $unmapped_bios_devices; do
sectors=`cat $EDD_PATH/int13_dev$bdev/sectors`
mbr_signature=`cat $EDD_PATH/int13_dev$bdev/mbr_signature`
match=''
nomatch=''
for kdev in $unmapped_kernel_devices; do
kdev_sectors=`cat /sys/block/$kdev/size`
kdev_mbr_signature=`get_mbr_signature /dev/$kdev`
if [ $sectors -eq $kdev_sectors ] && \
[ "$mbr_signature" = $kdev_mbr_signature ]; then
match="$match $kdev"
else
nomatch="$nomatch $kdev"
fi
done
match=${match# }
nomatch=${nomatch# }
if [ `echo $match | wc -w` -ne 1 ]; then
new_unmapped_bdevs="$new_unmapped_bdevs $bdev"
unmapped_kernel_devices="$match $nomatch"
else
unmapped_kernel_devices="$nomatch"
echo $match=$bdev
#eval map_kdev_$match="$bdev"
#eval map_bdev_$bdev="$match"
fi
done
unmapped_bios_devices="$new_unmapped_bdevs"
#echo "### Found the following mappings ###"
#set | grep map_
#echo "bios_devices: $unmapped_bios_devices"
#echo "kernel_devices: $unmapped_kernel_devices"
exit 0
...@@ -63,8 +63,9 @@ install_mbr() ...@@ -63,8 +63,9 @@ install_mbr()
fi fi
if [ "$OS" = Linux ]; then if [ "$OS" = Linux ]; then
size=`echo -e 'u\np\nq' | fdisk $disk | \ size=`echo -e 'u\np\nq' | fdisk $disk 2> /dev/null| \
sed -n "s#^${disk}1 *. *[0-9]* *\([0-9]*\).*\\$#\1#p"` sed -n "s#^${disk}1 *. *[0-9]* *[0-9]* *\([0-9]*\).*\\$#\1#p"`
size=`expr $size '*' 2`
elif [ "$OS" = FreeBSD ]; then elif [ "$OS" = FreeBSD ]; then
size=`fdisk -s ${disk##*/} 2>/dev/null | \ size=`fdisk -s ${disk##*/} 2>/dev/null | \
sed -n -e 's/^ *1: *[0-9][0-9]* *\([0-9][0-9]*\).*$/\1/p'` sed -n -e 's/^ *1: *[0-9][0-9]* *\([0-9][0-9]*\).*$/\1/p'`
...@@ -104,7 +105,7 @@ install_mbr() ...@@ -104,7 +105,7 @@ install_mbr()
# to disk, so we'll just use that. # to disk, so we'll just use that.
if [ $OS = Linux ]; then if [ $OS = Linux ]; then
echo "Re-reading partition table ..." echo "Re-reading partition table ..."
echo w | fdisk $disk > /dev/null echo w | fdisk $disk > /dev/null 2>&1
fi fi
} }
...@@ -125,7 +126,7 @@ zap_superblocks() ...@@ -125,7 +126,7 @@ zap_superblocks()
local offsets='' local offsets=''
if [ $OS = Linux ]; then if [ $OS = Linux ]; then
offsets=`echo -e 'u\np\nq' | fdisk $disk | \ offsets=`echo -e 'u\np\nq' | fdisk $disk 2> /dev/null | \
sed -n "s#^${disk}[0-9]* *. *[0-9]* *\([0-9]*\).*\\$#\1#p"` sed -n "s#^${disk}[0-9]* *. *[0-9]* *\([0-9]*\).*\\$#\1#p"`
elif [ $OS = FreeBSD ]; then elif [ $OS = FreeBSD ]; then
offsets=`fdisk -s ${disk##*/} 2>/dev/null | \ offsets=`fdisk -s ${disk##*/} 2>/dev/null | \
...@@ -273,24 +274,9 @@ write_image() ...@@ -273,24 +274,9 @@ write_image()
return $rc return $rc
} }
find_disks() {
local disks
if [ $OS = "FreeBSD" ]; then
for d in `dmesg | sed -n 's/^\([a-z]*[0-9][0-9]*\): [0-9][0-9]*MB/\1/p'`; do
case $d in
ad*|da*|ar*|aacd*) disks="$disks $d"
esac
done
elif [ $OS = "Linux" ]; then
disks=`ls /sys/block/[hs]d* | sed 's;.*/\([^/]*\)$;\1;'`
fi
echo $disks
}
$BINDIR/tmcc state RELOADSETUP $BINDIR/tmcc state RELOADSETUP
echo "Trying to get loadinfo data... "
time=30 time=30
while [ $time -gt 0 ]; do while [ $time -gt 0 ]; do
sleep 1 sleep 1
...@@ -304,9 +290,10 @@ if [ $time -eq 0 ]; then ...@@ -304,9 +290,10 @@ if [ $time -eq 0 ]; then
exit 2 exit 2
fi fi
echo "Got loadinfo data"
BOSSINFO=`$BINDIR/tmcc bossinfo` BOSSINFO=`$BINDIR/tmcc bossinfo`
BOSSIP=${BOSSINFO##* } BOSSIP=${BOSSINFO##* }
STATUS=`$BINDIR/tmcc status`
# For testing purposes. # For testing purposes.
#BOSSINFO='boss.emulab.net 155.101.128.70' #BOSSINFO='boss.emulab.net 155.101.128.70'
...@@ -324,6 +311,7 @@ ACPI=`get_value "$LOADINFO" ACPI` ...@@ -324,6 +311,7 @@ ACPI=`get_value "$LOADINFO" ACPI`
ASF=`get_value "$LOADINFO" ASF` ASF=`get_value "$LOADINFO" ASF`
MBR=`get_value "$LOADINFO" MBRVERS` MBR=`get_value "$LOADINFO" MBRVERS`
FREEBSD_DISK=$DISK
# Convert from the FreeBSD device names to Linux device names # Convert from the FreeBSD device names to Linux device names
# if necessary. # if necessary.
if [ $OS = "Linux" ]; then if [ $OS = "Linux" ]; then
...@@ -331,7 +319,6 @@ if [ $OS = "Linux" ]; then ...@@ -331,7 +319,6 @@ if [ $OS = "Linux" ]; then
[hs]d[a-z]) [hs]d[a-z])
;; ;;
*) *)
OLD_DISK=$DISK
DISK=`$BINDIR/freebsd_to_linux_disk $DISK 0` DISK=`$BINDIR/freebsd_to_linux_disk $DISK 0`
DISK=${DISK%% *} DISK=${DISK%% *}
;; ;;
...@@ -423,18 +410,6 @@ if [ $is_remote -eq 0 -a $PARTITION -eq 0 -a $ZFILL -eq 0 ]; then ...@@ -423,18 +410,6 @@ if [ $is_remote -eq 0 -a $PARTITION -eq 0 -a $ZFILL -eq 0 ]; then
zap_superblocks /dev/$DISK zap_superblocks /dev/$DISK
fi fi
case $STATUS in
*ALLOCATED=emulab-ops/reloading*)
disks=`find_disks`
for d in $disks; do
[ $d = $DISK ] && continue
mount | grep "^/dev/$d" > /dev/null && continue
zap_superblocks $d
dd if=/dev/zero of=/dev/$disk bs=512 count=1
done
;;
esac
install_mbr /dev/$DISK $MBR install_mbr /dev/$DISK $MBR
echo "Resizing final disk partition" echo "Resizing final disk partition"
...@@ -475,7 +450,7 @@ fi ...@@ -475,7 +450,7 @@ fi
echo "Adjusting slice-related files" echo "Adjusting slice-related files"
export SLICEFIX_ACPI=$ACPI export SLICEFIX_ACPI=$ACPI
export SLICEFIX_ASF=$ASF export SLICEFIX_ASF=$ASF
$BINDIR/slicefix $PARTITION $DISK $BINDIR/slicefix $PARTITION $FREEBSD_DISK
echo "Image load complete at `date`" echo "Image load complete at `date`"
# #
......
...@@ -144,9 +144,15 @@ dofreebsd() { ...@@ -144,9 +144,15 @@ dofreebsd() {
fsopts="ro,ufstype=44bsd" fsopts="ro,ufstype=44bsd"
fi fi
# Try mounting the filesystem as UFSv1 first,
# tnen try UFSv2 if that doesn't work.
mount -t $fstype -o $fsopts $rootdev /mnt || { mount -t $fstype -o $fsopts $rootdev /mnt || {
echo "RO-mount of $rootdev failed" fsopts=ro,ufstype=ufs2
return 1 mount -t $fstype -o $fsopts $rootdev /mnt || {
echo "RO-mount of $rootdev failed"
return 1
}
} }
# #
...@@ -427,6 +433,7 @@ dolinux() { ...@@ -427,6 +433,7 @@ dolinux() {
fi fi
# change the swap devices in fstab # change the swap devices in fstab
echo linux_disk=$linux_disk
sed -i.orig -e "s;^/dev/[hs]d.\([0-7]\);/dev/${linux_disk}\1;" /mnt/etc/fstab || { sed -i.orig -e "s;^/dev/[hs]d.\([0-7]\);/dev/${linux_disk}\1;" /mnt/etc/fstab || {
echo "Failed to update /etc/fstab" echo "Failed to update /etc/fstab"
umount $rootdev umount $rootdev
...@@ -453,16 +460,39 @@ dolinux() { ...@@ -453,16 +460,39 @@ dolinux() {
# Tweak grub's notion of root. # Tweak grub's notion of root.
# Note that grub's partition numbering is zero-based. # Note that grub's partition numbering is zero-based.
# #
gdisk=`echo $linux_disk | sed -e 's/^.*\(.\)$/\1/;y/abcdefgh/01234567/'` gdisk=''
if [ $OS = "Linux" ]; then
# Use EDD to figure out the BIOS drive number
#
# HACK: we only look for BIOS drives 0x8[0-9] so we
# don't have to convert to/from hex and do math. The
# The EDD code in the kernel currently only supports
# 0x80-0x85 anyway.
gdisk=`sed -n "s/^$linux_disk=\(8[0-9]\)/\1/p" \
$BOOTDIR/edd_map`
if [ -n "$gdisk" ]; then
echo " EDD says $linux_disk is BIOS drive 0x$gdisk"
gdisk=${gdisk#8}
fi
# We fall back to our old guessing method if EDD
# doesn't work.
fi
if [ x$gdisk = x ]; then
gdisk=`echo $linux_disk | \
sed -e 's/^.*\(.\)$/\1/;y/abcdefgh/01234567/'`
if [ $FLASHBOOT -eq 1 ]; then
gdisk=`expr $gdisk + 1`
fi
fi
gpart=`expr $part - 1` gpart=`expr $part - 1`
# #
# If we booted from a flash device we also have to further tweak # If we booted from a flash device we also have to further tweak
# grub's notion of root disk since the flash device will be "hd0". # grub's notion of root disk since the flash device will be "hd0".
# It appears that we do NOT have to update Linux's drive mapping. # It appears that we do NOT have to update Linux's drive mapping.
# #
if [ $FLASHBOOT -eq 1 ]; then
gdisk=`expr $gdisk + 1`
fi
sed -i'' -e "s;root (hd[0-9],[0-9]);root (hd${gdisk},${gpart});" $gconf || { sed -i'' -e "s;root (hd[0-9],[0-9]);root (hd${gdisk},${gpart});" $gconf || {
echo "Failed to update root in $fgconf" echo "Failed to update root in $fgconf"
} }
...@@ -518,10 +548,11 @@ dolinux() { ...@@ -518,10 +548,11 @@ dolinux() {
} }
fixone() { fixone() {
echo "*** ${disk}s${part}:"
if [ $OS = FreeBSD ]; then if [ $OS = FreeBSD ]; then
echo "*** ${disk}s${part}:"
ptype=`fdisk -${part} ${disk} | grep sysid | sed 's/^sysid \([0-9][0-9]*\).*/\1/'` ptype=`fdisk -${part} ${disk} | grep sysid | sed 's/^sysid \([0-9][0-9]*\).*/\1/'`
elif [ $OS = Linux ]; then elif [ $OS = Linux ]; then
echo "*** ${disk}${part}:"
ptype=`fdisk -l /dev/$disk | awk /${disk}${part}/'{sub(/\*/,""); print "0x"$5}'` ptype=`fdisk -l /dev/$disk | awk /${disk}${part}/'{sub(/\*/,""); print "0x"$5}'`
fi fi
ptype=${ptype:-0} ptype=${ptype:-0}
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment