Commit 4ffacdc3 authored by Ryan Jackson's avatar Ryan Jackson

Cleanup, fixes, and stuff to make slicefix a bit more intelligent: try to use

labels or UUIDs instead of device names when we aren't sure what the device
will be called (due to name change from hda -> sda).
parent 310c4cdb
......@@ -80,12 +80,14 @@ frisbee-mfs-install: destdircheck
#@if [ -r $(SRCDIR)/group ]; then \
# $(INSTALL) -m 644 $(SRCDIR)/group $(SYSETCDIR); \
#fi
(cd ../../tools/binoffset; $(MAKE) DESTDIR=$(DESTDIR) client-install)
$(INSTALL) -m 755 $(SRCDIR)/control_interface $(SYSETCDIR)/testbed
$(INSTALL) -m 755 $(SRCDIR)/rc.frisbee $(SYSETCDIR)/testbed
$(INSTALL) -m 755 $(SRCDIR)/rc.ipod $(SYSETCDIR)/testbed
$(INSTALL) -m 755 $(SRCDIR)/slicefix $(SYSETCDIR)/testbed
$(INSTALL) -m 755 $(SRCDIR)/freebsd_to_linux_disk $(SYSETCDIR)/testbed
$(INSTALL) -m 755 $(SRCDIR)/check_disklabel $(SYSETCDIR)/testbed
$(INSTALL) -m 755 $(SRCDIR)/extract_kernel_version $(SYSETCDIR)/testbed
$(INSTALL) -m 755 $(SRCDIR)/get_edd_map $(SYSETCDIR)/testbed
$(INSTALL) -m 755 -s ../tmcc-nossl $(SYSETCDIR)/testbed/tmcc
$(INSTALL) -m 755 -s ../findif $(SYSETCDIR)/testbed
......@@ -214,6 +216,7 @@ script-install: dir-install $(SCRIPTS)
$(INSTALL) -m 755 $(SRCDIR)/slicefix $(BINDIR)/slicefix
$(INSTALL) -m 755 $(SRCDIR)/freebsd_to_linux_disk $(BINDIR)/freebsd_to_linux_disk
$(INSTALL) -m 755 $(SRCDIR)/check_disklabel $(BINDIR)/check_disklabel
$(INSTALL) -m 755 $(SRCDIR)/extract_kernel_version $(BINDIR)/extract-kernel-version
$(INSTALL) -m 755 $(SRCDIR)/get_edd_map $(BINDIR)/testbed
$(INSTALL) -m 755 -s ../findif $(BINDIR)/findif
......
#!/bin/sh
# extracts .config info from a [b]zImage file
# uses: binoffset (new), dd, zcat, strings, grep
# $arg1 is [b]zImage filename
if [ -r /etc/emulab/paths.sh ]; then
. /etc/emulab/paths.sh
else
BINDIR=/etc/testbed
BOOTDIR=/var/emulab/boot
ETCDIR=/etc/emulab
fi
binoffset="$BINDIR/binoffset"
test -e $binoffset || cc -o $binoffset ./scripts/binoffset.c || exit 1
function dump_version {
typeset file="$1"
sed -n -r '/Linux version/p' "$file" | \
tr -d -c ' -~' | sed 's/.*\(Linux version .*\)$/\1\n/'
clean_up
exit 0
}
IKCFG_ST="0x49 0x4b 0x43 0x46 0x47 0x5f 0x53 0x54"
IKCFG_ED="0x49 0x4b 0x43 0x46 0x47 0x5f 0x45 0x44"
function dump_config {
typeset file="$1"
start=`$binoffset $file $IKCFG_ST 2>/dev/null`
[ "$?" != "0" ] && start="-1"
if [ "$start" -eq "-1" ]; then
return
fi
end=`$binoffset $file $IKCFG_ED 2>/dev/null`
let start="$start + 8"
let size="$end - $start"
dd if="$file" ibs=1 skip="$start" count="$size" 2>/dev/null | zcat
clean_up
exit 0
}
usage()
{
echo " usage: extract-ikconfig [b]zImage_filename"
}
clean_up()
{
if [ "$TMPFILE" != "" ]; then
rm -f $TMPFILE
fi
}
if [ $# -lt 1 ]
then
usage
exit 1
fi
TMPFILE=`mktemp -t ikconfig-XXXXXX` || exit 1
image="$1"
# vmlinux: Attempt to dump the configuration from the file directly
dump_config "$image"
GZHDR1="0x1f 0x8b 0x08 0x00"
GZHDR2="0x1f 0x8b 0x08 0x08"
# vmlinux.gz: Check for a compressed images
off=`$binoffset "$image" $GZHDR1 2>/dev/null`
[ "$?" != "0" ] && off="-1"
if [ "$off" -eq "-1" ]; then
off=`$binoffset "$image" $GZHDR2 2>/dev/null`
[ "$?" != "0" ] && off="-1"
fi
if [ "$off" -eq "0" ]; then
zcat <"$image" >"$TMPFILE"
#dump_config "$TMPFILE"
dump_version "$TMPFILE"
elif [ "$off" -ne "-1" ]; then
(dd ibs="$off" skip=1 count=0 && dd bs=512k) <"$image" 2>/dev/null | \
zcat >"$TMPFILE"
#dump_config "$TMPFILE"
dump_version "$TMPFILE"
fi
echo "ERROR: Unable to extract kernel configuration information."
echo " This kernel image may not have the config info."
clean_up
exit 1
......@@ -6,8 +6,8 @@ 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`
local sig=`dd if=$device bs=1 count=4 skip=440 2>/dev/null | od -x | \
sed -n '1s/^[0-9a-f]* *\([0-9a-f]*\) *\([0-9a-f]*\) *$/\1\2/p'`
while [ ${#sig} -lt 8 ]; do
sig="0$sig"
......@@ -72,8 +72,13 @@ find_host_adapter()
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`
number=`ls $pcidev_path/ | sed -n 's/^host\([0-9]*\)/\1/p' | \
sort -n | sed -n ${channel}p`
if [ -z "$number" ]; then
number=`ls $pcidev_path/ | sed -n 's/^ide\([0-9]*\)/\1/p' | \
sort -n | sed -n ${channel}p`
fi
else
return 1
fi
......@@ -81,7 +86,9 @@ find_host_adapter()
echo $number
}
modprobe edd
if ! [ -d $EDD_PATH ]; then
modprobe edd
fi
for bdev in /sys/firmware/edd/int13_dev8*; do
[ `cat $bdev/version` = 0x00 ] && continue
......
This diff is collapsed.
......@@ -27,6 +27,12 @@ else
ETCDIR=/etc/testbed
fi
# See if we can map drive names to BIOS numbers via EDD
if [ -x $BINDIR/get_edd_map ]; then
$BINDIR/get_edd_map > $BOOTDIR/edd_map
fi
# Behave a little different on widearea nodes.
isrem=0
if [ -e $ETCDIR/isrem ]; then
......@@ -324,6 +330,11 @@ if [ $OS = "Linux" ]; then
;;
esac
# Try to map disks to BIOS drive numbers via EDD
# The map is created now before we touch any disks
# since we may need to use the MBR to determine
# which disk is which.
$BINDIR/get_edd_map > $BOOTDIR/edd_map 2>/dev/null
fi
FRISBEE_OPTS="-S $BOSSIP"
......@@ -350,9 +361,9 @@ if [ $PARTITION -ne 0 ]; then
fi
# Enable IPoD
if [ -r $BINDIR/rc.ipod ]; then
. $BINDIR/rc.ipod
fi
#if [ -r $BINDIR/rc.ipod ]; then
# . $BINDIR/rc.ipod
#fi
FRISBEE_OPTS="$FRISBEE_OPTS `get_buffer_sizes`"
......@@ -450,7 +461,7 @@ fi
echo "Adjusting slice-related files"
export SLICEFIX_ACPI=$ACPI
export SLICEFIX_ASF=$ASF
$BINDIR/slicefix $PARTITION $FREEBSD_DISK
#$BINDIR/slicefix $PARTITION $FREEBSD_DISK
echo "Image load complete at `date`"
#
......
#! /bin/sh
ide_disks="a b c d e f g h i j k l end"
pata_controllers=""
sd_to_hd_map() {
# Find all IDE controllers and guess which ones are PATA
for pci_device in /sys/devices/pci*/*; do
[ -f $pci_device/class ] || continue
class=`cat $pci_device/class`
# IDE devices are in class 0x0101
case $class in
0x0101*) ;;
*) continue; ;;
esac
# See if there is a SATA device on the controller. If so,
# the controller isn't PATA. Skip it.
# This falls down if the controller isn't PATA but there
# are no devices attached. We then assume the controller
# is PATA and consume IDE devices unnecessarily. This
# itself is only an issue if there are PATA devices on
# another controller, since they will get the wrong names.
is_pata=1
for disk in `find $pci_device | grep 'block[:/][^/]*$'`; do
disk=${disk##*/}
disk=${disk#block:}
if hdparm -I /dev/$disk | grep -q SATA; then
is_pata=0
break
fi
done
# See what lspci thinks of the controller. If it doesn't
# think it's SATA, assume it's PATA.
#lspci -s ${pci_device##*/} | grep -iq SATA && is_pata=0
[ $is_pata -ne 1 ] && continue
pata_controllers="$pata_controllers `ls -d $pci_device/host*`"
done
# This is really nasty. Sort the host adapters in order
# by adapter number.
pata_controllers=`echo $pata_controllers | tr ' ' '\n' | \
sed 's/^\(.*host\)\(.*\)$/\2 \1\2/' | \
sort -k1 -n | cut -d' ' -f2`
# Try mapping SCSI devices to IDE devices. Note that each controller
# always consumes two devices even if they're not present.
for host in $pata_controllers; do
host_num=${host##*host}
target=$host/target$host_num:0:0/$host_num:0:0:0
if [ -d $target/block ]; then
scsi_disk=`ls -d $target/block/*`
scsi_disk=${scsi_disk##*/}
echo $scsi_disk=hd${ide_disks%% *}
fi
ide_disks=${ide_disks#* }
target=$host/target$host_num:0:1/$host_num:0:1:0
if [ -d $target/block ]; then
scsi_disk=`ls -d $target/block/*`
scsi_disk=${scsi_disk##*/}
echo $scsi_disk=hd${ide_disks%% *}
fi
ide_disks=${ide_disks#* }
[ "$ide_disks" = end ] && break
done
}
sd_to_hd_map > /tmp/ide_disks
# Remap any remaining SCSI devices to account for the ones mapped to IDE
# devices. SCSI disks always proceed in order, with the first being 'a', the
# second being 'b', and so on.
scsi_disks="a b c d e f g h i j k l m n o p"
rm -f /tmp/scsi_disks
for dev in /sys/block/sd*; do
dev=${dev##*/}
if ! grep "^$dev=" /tmp/ide_disks > /dev/null; then
echo $dev=sd${scsi_disks%% *} >> /tmp/scsi_disks
scsi_disks=${scsi_disks#* }
fi
done
cat /tmp/ide_disks /tmp/scsi_disks
rm -f /tmp/ide_disks /tmp/scsi_disks
......@@ -29,6 +29,118 @@ case $# in
exit 1
esac
get_fstab_root_device()
{
local image_root=$1
while read device mount rest; do
[ x$device = x ] && continue
case $device in
\#*) continue ;;
esac
if [ $mount = / ]; then
echo ${device}
break
fi
done < $image_root/etc/fstab
}
get_lilo_boot_device()
{
local image_root=$1
[ -f $image_root/etc/lilo.conf ] || return 1
sed -n 's/^boot=//p' $image_root/etc/lilo.conf
return 0
}
get_grub_boot_device()
{
local image_root=$1
local grub_config=/etc/grub.conf
local grub_device_map=/boot/grub/device.map
local grub_boot_dev
if ! [ -f $grub_config ]; then
grub_config=/boot/grub/menu.lst
if ! [ -f $grub_config ]; then
return 1
fi
fi
if ! [ -f $grub_device_map ]; then
return 1
fi
# Check for Debian-ish grub configs
grub_boot_dev=`sed -n 's/^##* *groot=(\(hd[0-9]*\).*$/(\1)/p' \
$grub_config`
# Check for Fedora-ish grub configs
if [ -z "$grub_boot_dev" ]; then
grub_boot_dev=`sed -n 's/.*groot=(\(hd[0-9]*\)/(\1)/p' \
$grub_config`
fi
[ -z "$grub_boot_dev" ] && return 1
real_grub_boot_dev=`grep "^$grub_boot_dev" $grub_device_map | \
awk '{ print $2 }'`
[ -z "$real_grub_boot_dev" ] && return 1
echo $real_grub_boot_dev
}
image_wants_ide()
{
local image_root=$1
local rc=0;
# rc == 0 means image wants ide
# rc == 1 means image doesn't care
# rc == 2 means unknown
local fstab_root_dev
local grub_boot_dev
local lilo_boot_dev
fstab_root_dev=`get_fstab_root_device $image_root`
grub_boot_dev=`get_grub_boot_device $image_root`
lilo_boot_dev=`get_lilo_boot_device $image_root`
for dev in "$fstab_root_dev" "$grub_boot_dev" "$lilo_boot_dev"; do
case "$fstab_root_dev" in
*=*)
# Probably LABEL= or UUID=
rc=1
;;
/dev/hd*)
rc=0
;;
*)
rc=2
;;
esac
[ $rc -lt 2 ] && return $rc
done
# If we get here, we don't know what the image wants
return $rc
}
map_disk()
{
local disk=$1
local map=$2
sed -n "s/^$disk=//p" $map
}
linux_disk=`$BINDIR/freebsd_to_linux_disk $freebsd_disk $part`
lrootdev=${linux_disk#* }
linux_disk=${linux_disk%% *}
......@@ -417,9 +529,12 @@ dolinux() {
echo "fixing Linux root partition ${disk}${part}"
fstype=ext3
fi
mount -t $fstype $rootdev /mnt || {
echo "$fstype mount of $rootdev failed"
return 1
mount -t $fstype $rootdev /mnt 2> /dev/null || {
fstype=ext2
mount -t $fstype $rootdev /mnt || {
echo "$fstype mount of $rootdev failed"
return 1
}
}
# hardwire the boss node
......@@ -432,13 +547,12 @@ dolinux() {
}
fi
# 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 || {
echo "Failed to update /etc/fstab"
umount $rootdev
return 1
}
$BINDIR/remap_ide_disks > /tmp/disk_map
new_disk=`map_disk $linux_disk /tmp/disk_map`
translated_rootdev=/dev/$new_disk$part
$BINDIR/guess_linux_root_device /mnt $rootdev $translated_rootdev
lilo_commandline=`cat /mnt/var/emulab/boot/runlilo 2> /dev/null`
#
# If there's a GRUB config file, update all root=X kernel params.
......@@ -451,74 +565,40 @@ dolinux() {
gconf=/mnt$fgconf
fi
if [ -r $gconf ]; then
echo " updating $fgconf"
sed -i.orig -e "s;\([br]oot=/dev\)/[hs]d.[0-7];\1/${linux_disk}${part};" $gconf || {
echo "Failed to update $fgconf"
}
#
# Tweak grub's notion of root.
# Note that grub's partition numbering is zero-based.
#
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`
gdisk=''
# 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}
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`
#
# 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".
# It appears that we do NOT have to update Linux's drive mapping.
#
sed -i'' -e "s;root (hd[0-9],[0-9]);root (hd${gdisk},${gpart});" $gconf || {
echo "Failed to update root in $fgconf"
}
fi
#
# If using lilo, update lilo.conf and set indicator to tell Emulab
# to rerun lilo.
#
linux=
lconf=/mnt/etc/lilo.conf
if [ -r $lconf ]; then
echo " updating /etc/lilo.conf"
sed -i.orig -e "s;\([br]oot=/dev\)/[hs]d.[0-7];\1/${linux_disk}${part};" $lconf || {
echo "Failed to update /etc/lilo.conf"
umount $rootdev
return 1
}
# XXX note the hardwired path, cannot use BOOTDIR as it is
# different in frisbee MFS. This also assumes Linux partition
# is one big filesystem.
cp /dev/null /mnt/var/emulab/boot/runlilo
# We fall back to our old guessing method if EDD
# doesn't work.
if [ x$gdisk = x ]; then
gdisk=`echo $os_linux_disk | \
sed -e 's/^.*\(.\)$/\1/;y/abcdefgh/01234567/'`
if [ $FLASHBOOT -eq 1 ]; then
gdisk=`expr $gdisk + 1`
fi
fi
gpart=`expr $part - 1`
#
# 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".
# It appears that we do NOT have to update Linux's drive mapping.
#
sed -i'' -e "s;root (hd[0-9],[0-9]);root (hd${gdisk},${gpart});" $gconf || {
echo "Failed to update root in $fgconf"
}
# grab the default linux kernel to boot
linux=`lilogetkernel $lconf`
fi
if [ -f /mnt/var/lib/random-seed -a -c /dev/urandom ]; then
......@@ -535,10 +615,10 @@ dolinux() {
umount $rootdev
if [ "x${linux}" != x ]; then
if [ "x${lilo_commandline}" != x ]; then
echo -n " "
# setup one time lilo command line, must be done after unmount
$BINDIR/groklilo -c "$linux root=$lrootdev" $part /dev/$disk || {
$BINDIR/groklilo -c "$lilo_commandline" $part /dev/$disk || {
echo "Failed to set LILO command line"
return 1
}
......
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