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
......
#! /bin/sh
imageroot="$1"
real_root_dev="$2"
translated_root_dev="$3"
default_lilo_entry=''
is_label_or_uuid()
{
local mount="$1"
local rc=1 #failure
case $mount in
LABEL=*|label=*) rc=0; ;;
UUID=*|uuid=*) rc=0; ;;
esac
return $rc
}
get_label()
{
local disk="$1"
[ -x /lib/udev/vol_id ] || return 1
label=`/lib/udev/vol_id --label-raw $disk`
[ -n "$label" ] && echo LABEL=$label
}
get_uuid()
{
local disk="$1"
[ -x /lib/udev/vol_id ] || return 1
uuid=`/lib/udev/vol_id --uuid $disk`
[ -n "$uuid" ] && echo UUID=$uuid
}
#extract_kernel_version()
#{
# local kernel="$1"
#
# echo $kernel | sed 's/[^-]*-\([0-9]*\.[0-9]*\.[0-9]*\).*/\1/'
#}
kernel_version_compare()
{
local version1="$1"
local version2="$2"
local rc=0
version1=`echo $version1 | sed 's/^\([0-9]*\.[0-9]*\.[0-9]*\).*$/\1/'`
local version1_major=${version1%%.*}
local version1_minor=${version1#*.}
local version1_maintenance=${version1_minor#*.}
version1_minor=${version1_minor%.*}
version2=`echo $version2 | sed 's/^\([0-9]*\.[0-9]*\.[0-9]*\).*$/\1/'`
local version2_major=${version2%%.*}
local version2_minor=${version2#*.}
local version2_maintenance=${version2_minor#*.}
version2_minor=${version2_minor%.*}
if [ $version1_major -lt $version2_major ]; then
rc=-1
elif [ $version1_major -gt $version2_major ]; then
rc=1
elif [ $version1_minor -lt $version2_minor ]; then
rc=-1
elif [ $version1_minor -gt $version2_minor ]; then
rc=1
elif [ $version1_maintenance -lt $version2_maintenance ]; then
rc=-1
elif [ $version1_maintenance -gt $version2_maintenance ]; then
rc=1
fi
echo $rc
}
extract_default_grub_entry()
{
local imageroot="$1"
local grub_conf="$imageroot/$2"
local default=`sed -n 's/^default[ ]*\([0-9]*\)$/\1/p' $grub_conf`
[ -z "$default" ] && default=0
local current_entry=-1
while read directive rest; do
[ -z "$directive" ] && continue
case $directive in
title)
current_entry=$(( $current_entry + 1 ))
;;
esac
[ $current_entry -lt $default ] && continue
[ $current_entry -gt $default ] && break
case $directive in
kernel)
kernel=${rest%% *}
commandline=${rest#* }
;;
initrd)
initrd="$rest"
;;
esac
done < $grub_conf
}
extract_default_lilo_entry()
{
local imageroot=$1
local lilo_conf="$imageroot/etc/lilo.conf"
# Extract global settings in case the default entry doesn't
# have them specified.
local global_root=`sed -n \
's/^root[ ]*=[ ]*\(.*\)$/\1/p' \
$lilo_conf`
local global_initrd=`sed -n \
's/^initrd[ ]*=[ ]*\(.*\)$/\1/p' \
$lilo_conf`
if [ -z "$global_initrd" ]; then
global_initrd=`sed -n \
's/^ramdisk[ ]*=[ ]*\(.*\)$/\1/p' \
$lilo_conf`
fi
local global_append=`sed -n \
's/^append[ ]*=[ ]*"\(.*\)"$/\1/p' \
$lilo_conf`
local global_readonly=`sed -n 's/^read-only/ro/p' $lilo_conf`
if [ -z "$global_readonly" ]; then
global_readonly=`sed -n 's/^read-write/rw/p' $lilo_conf`
fi
# Get the default label. If there isn't one, use the first
# defined label.
local default=`sed -n 's/^default[ ]*=[ ]*\(.*\)$/\1/p' \
$lilo_conf`
if [ -z "$default" ]; then
default=`sed -n \
's/^[ ]*label[ ]*=[ ]*\(.*\)$/\1/p' \
$lilo_conf | head -n1`
fi
default_lilo_entry="$default"
local current_image=''
local current_initrd=''
local current_append=''
local current_root=''
local current_readonly=''
local found_image=0
while read line; do
line=`echo "$line" | sed 's/[ ]*=[ ]*/=/'`
[ -z "$line" ] && continue
case "$line" in
image=*)
[ $found_image -eq 1 ] && break
current_image=${line#*=}
current_root=''
current_readonly=''
current_initrd=''
current_append=''
;;
label=*|alias=*)
if [ ${line#*=} = $default ]; then
found_image=1
fi
;;
append=*)
current_append=${line#*=}
current_append=${current_append#\"}
current_append=${current_append%\"}
;;
initrd=*|ramdisk=*)
current_initrd=${line#*=}
;;
root=*)
current_root=${line#*=}
;;
read-only)
current_readonly=ro
;;
read-write)
current_readonly=rw
;;
esac
done < $lilo_conf
[ -z "$current_initrd" ] && current_initrd="$global_initrd"
[ -z "$current_append" ] && current_append="$global_append"
[ -z "$current_root" ] && current_root="$global_root"
local found_root=0
local found_readonly=0
for token in $current_append; do
case $token in
root=*)
found_root=1
;;
ro|rw)
found_readonly=1
;;
esac
done
if [ $found_readonly -eq 0 ]; then
current_append="$current_append $current_readonly"
fi
if [ $found_root -eq 0 ]; then
current_append="$current_append root=$current_root"
fi
kernel="$current_image"
commandline="$current_append"
initrd="$current_initrd"
}
get_bootloader_name()
{
local device=$1
# Check for GRUB first because it doesn't write to the first part of the MBR.
# Anything that was there before will still be there, so if LILO was previously
# installed the string 'LILO' will be present as well as 'GRUB'. LILO uses
# the whole MBR, so we don't need to do anything special to detect it properly.
local bootloader=unknown
if dd if=$real_root_dev bs=512 count=1 2> /dev/null| grep GRUB > /dev/null; then
bootloader=GRUB
elif dd if=$real_root_dev bs=512 count=1 2> /dev/null| grep LILO > /dev/null; then
bootloader=LILO
fi
echo $bootloader
}
initrd_handles_label()
{
local initrd="$1"
local decompressed_initrd="/tmp/initrd.$$"
local initrd_dir="/tmp/initrd.dir.$$"
[ -f "$initrd" ] || return 1
mkdir -p "$initrd_dir"
gzip -dc < "$initrd" > "$decompressed_initrd" 2> /dev/null
if [ $? -ne 0 ]; then
cp "$initrd" "$decompressed_initrd"
if [ $? -ne 0 ]; then
exit 1
fi
fi
local mounted=0
mount -o ro,loop -t ext3 "$decompressed_initrd" "$initrd_dir" \
2> /dev/null
if [ $? -ne 0 ]; then
mount -o ro,loop -t ext2 "$decompressed_initrd" "$initrd_dir" \
2> /dev/null
if [ $? -eq 0 ]; then
mounted=1
fi
else
mounted=1
fi
if [ $mounted -eq 0 ]; then
(cd "$initrd_dir" && cpio -idu < "$decompressed_initrd" > \
/dev/null 2>&1)
if [ $? -ne 0 ]; then
exit 1
fi
fi
cd "$initrd_dir"
local supports_label=0
if grep LABEL bin/mount > /dev/null 2>&1 && \
grep UUID bin/mount > /dev/null 2>&1 || \
grep libblkid.so bin/mount > /dev/null 2>&1; then
supports_label=1
elif grep LABEL bin/nash > /dev/null 2>&1 && \
grep UUID bin/nash > /dev/null 2>&1 || \
grep libblkid.so bin/nash > /dev/null 2>&1; then
supports_label=1
elif grep LABEL bin/busybox > /dev/null 2>&1 && \
grep UUID bin/busybox > /dev/null 2>&1; then
supports_label=1
elif [ -x sbin/udevd ] && [ -x lib/udev/vol_id ] && \
grep '[^#]*vol_id' etc/udev/rules.d/* > /dev/null; then
:
supports_label=1
else
supports_label=0
fi
for file in bin/mount bin/busybox bin/nash lib/udev/vol_id \
etc/udev/rules.d/*; do
[ -f "$file" ] || continue
if grep "LABEL=" "$file" > /dev/null; then
supports_label=1
break
fi
done
cd /
[ $mounted -eq 1 ] && umount "$initrd_dir"
rm -rf "$initrd_dir" "$decompressed_initrd"
if [ $supports_label -eq 1 ]; then
return 0
else
return 1
fi
}
system_handles_label()
{
local imageroot="$1"
cd "$imageroot"
local supports_label=0
if grep LABEL bin/mount > /dev/null 2>&1 && \
grep UUID bin/mount > /dev/null 2>&1 || \
grep libblkid.so bin/mount > /dev/null 2>&1; then
supports_label=1
elif [ -x sbin/udevd ] && [ -x lib/udev/vol_id ] && \
grep '[^#]*vol_id' etc/udev/rules.d/* > /dev/null; then
:
supports_label=1
else
supports_label=0
fi
if [ $supports_label -eq 1 ]; then
return 0
else
return 1
fi
}
extract_root_from_commandline()
{
local commandline="$@"
for token in $commandline; do
case $token in
root=*)
echo ${token#root=}
break
;;
esac
done
}
extract_root_from_fstab()
{
local imageroot="$1"
while read device dir rest; do
[ -z "$device" ] && continue
case $device in
\#*)
continue
;;
esac
if [ $dir = / ]; then
echo $device
break
fi
done < $imageroot/etc/fstab
}
rewrite_fstab()
{
local imageroot="$1"
local old_root="$2"
local new_root="$3"
sed -i.orig "s;$old_root;$new_root;g" $imageroot/etc/fstab
}
rewrite_grub_config()
{
local imageroot="$1"
local grub_config="$2"
local old_root="$3"
local new_root="$4"
sed -i.orig "s;$old_root;$new_root;g" "$imageroot/$grub_config"
}
rewrite_lilo_config()
{
local imageroot="$1"
local lilo_conf="$imageroot/etc/lilo.conf"
local old_root="$2"
local new_root="$3"
sed -i.orig '/^[ ]*root=/d' $lilo_conf
sed -i.orig '/append=/s;[ ]*root=[^" ]*;;g' $lilo_conf
sed -i.orig "/append=/s;\"\$; root=$new_root\";g" $lilo_conf
# Set the special flag that says we need to finish fixing LILO after
# boot, and dump the one-time default LILO command-line so that
# slicefix can find out what it is.
echo "$default_lilo_entry root=$new_root" > \
$imageroot/var/emulab/boot/runlilo
}
echo -n "Determining installed bootloader... "
bootloader=`get_bootloader_name $real_root_dev`
echo "$bootloader"
case $bootloader in
unknown)
exit 1
;;
LILO)
if ! [ -f $imageroot/etc/lilo.conf ]; then
echo "Can't find LILO config" 1>&2
exit 1
fi
extract_default_lilo_entry $imageroot
;;
GRUB)
grub_config=''
for file in /etc/grub.conf /boot/grub/{grub.conf,menu.lst}; do
if [ -f "$imageroot/$file" ]; then
grub_config="$file"
break
fi
done
if [ -z "$grub_config" ]; then
echo "Can't find GRUB config" 1>&2
exit 1
fi
extract_default_grub_entry $imageroot $grub_config
;;
esac
echo -n "Finding root device in /etc/fstab... "
system_root=`extract_root_from_fstab $imageroot`
echo "'$system_root'"
echo -n "Finding root device in default $bootloader entry... "
bootloader_root=`extract_root_from_commandline $commandline`
echo "'$bootloader_root'"
initrd_can_use_label=0
echo -n "Checking for label/UUID support in \"$initrd\"... "
if initrd_handles_label "$imageroot/$initrd"; then
initrd_can_use_label=1
echo yes
else
echo no
fi