Commit deee6ffd authored by Ryan Jackson's avatar Ryan Jackson

Added new scripts for doing magic analysis of the image, kernel, and initrd.

Moved the code for linux slicefix to a separate script.  This is currently linux-dependent.
parent 3fc749f8
......@@ -87,7 +87,10 @@ frisbee-mfs-install: destdircheck
$(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)/linux_slicefix $(SYSETCDIR)/testbed
$(INSTALL) -m 755 $(SRCDIR)/extract_kernel_info $(SYSETCDIR)/testbed
$(INSTALL) -m 755 $(SRCDIR)/extract_initrd_info $(SYSETCDIR)/testbed
$(INSTALL) -m 755 $(SRCDIR)/extract_image_info $(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
......
#! /bin/sh
imageroot="$1"
real_root_dev="$2"
translated_root_dev="$3"
initrd=''
kernel=''
commandline=''
grub_config=''
default_lilo_entry=''
get_label()
{
local dev="$1"
local label=''
if [ -x /lib/udev/vol_id ]; then
label=`/lib/udev/vol_id --label-raw $dev`
elif [ -x /sbin/blkid ]; then
label=`/sbin/blkid | \
sed -n "s;^$dev"': *.*LABEL="\([^"]*\)".*;\1;p'`
else
return 1
fi
echo $label
}
get_uuid()
{
local dev="$1"
local uuid=''
if [ -x /lib/udev/vol_id ]; then
uuid=`/lib/udev/vol_id --uuid-raw $dev`
elif [ -x /sbin/blkid ]; then
uuid=`/sbin/blkid | \
sed -n "s;^$dev"': *.*UUID="\([^"]*\)".*;\1;p'`
else
return 1
fi
echo $uuid
}
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
}
get_swap_partitions()
{
local device="$1"
/sbin/fdisk -l "$device" | grep 'Linux swap' | cut -d' ' -f1
}
swapon_handles_label()
{
local imageroot="$1"
cd "$imageroot"
local supports_label=0
if grep libblkid.so bin/swapon > /dev/null 2>&1 \
grep LABEL bin/swapon > /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
fi
if [ $supports_label -eq 1 ]; then
swapon_can_use_label=yes
fi
}
mount_handles_uuid()
{
local imageroot="$1"
cd "$imageroot"
local supports_uuid=0
if grep libblkid.so sbin/mount > /dev/null 2>&1 && \
grep UUID sbin/mount > /dev/null 2>&1; then
supports_uuid=1
fi
if [ $supports_uuid -eq 1 ]; then
mount_can_use_uuid=yes
fi
}
swapon_handles_uuid()
{
local imageroot="$1"
cd "$imageroot"
local supports_uuid=0
if grep libblkid.so sbin/swapon > /dev/null 2>&1 && \
grep UUID sbin/swapon > /dev/null 2>&1; then
supports_uuid=1
fi
if [ $supports_uuid -eq 1 ]; then
swapon_can_use_uuid=yes
fi
}
mount_handles_label()
{
local imageroot="$1"
cd "$imageroot"
local supports_label=0
if grep libblkid.so bin/mount > /dev/null 2>&1 \
grep LABEL 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
fi
if [ $supports_label -eq 1 ]; then
mount_can_use_label=yes
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
}
bootloader=`get_bootloader_name $real_root_dev`
case $bootloader in
unknown)
echo "unknown bootloader on $real_root_dev" 1>&2
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
echo "default_lilo_entry=$default_lilo_entry"
;;
GRUB)
grub_config=''
for file in /boot/grub/grub.conf /etc/grub.conf /boot/grub/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
echo "grub_config=\"$grub_config\""
extract_default_grub_entry $imageroot $grub_config
;;
esac
fstab_root=`extract_root_from_fstab $imageroot`
bootloader_root=`extract_root_from_commandline $commandline`
echo "bootloader=\"$bootloader\""
echo "kernel=\"$kernel\""
echo "initrd=\"$initrd\""
echo "fstab_root=\"$fstab_root\""
echo "bootloader_root=\"$bootloader_root\""
echo "root_label=\"`get_label $real_root_dev`\""
echo "root_uuid=\"`get_uuid $real_root_dev`\""
mount_can_use_label=no
mount_can_use_uuid=no
swapon_can_use_label=no
swapon_can_use_uuid=no
mount_handles_label $imageroot && mount_can_use_label=yes
mount_handles_uuid $imageroot && mount_can_use_uuid=yes
swapon_handles_label $imageroot && swapon_can_use_label=yes
swapon_handles_uuid $imageroot && swapon_can_use_uuid=yes
echo "mount_handles_label=$mount_can_use_label"
echo "mount_handles_uuid=$mount_can_use_uuid"
echo "swapon_handles_label=$swapon_can_use_label"
echo "swapon_handles_uuid=$swapon_can_use_uuid"
exit 0
#! /bin/sh
initrd="$1"
check_initrd()
{
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"
if [ -x sbin/udevd ] && [ -x lib/udev/vol_id ]; then
if grep '[^#]*ID_FS_UUID' etc/udev/rules.d/* > /dev/null; then
initrd_handles_uuid=yes
fi
if grep '[^#]*ID_FS_LABEL' etc/udev/rules.d/* > /dev/null; then
initrd_handles_label=yes
fi
elif [ -x bin/busybox ]; then
if grep LABEL bin/mount > /dev/null; then
initrd_handles_label=yes
fi
if grep UUID bin/mount > /dev/null; then
initrd_handles_uuid=yes
fi
elif [ -x bin/nash ]; then
if grep libblkid.so bin/nash > /dev/null; then
initrd_handles_label=yes
initrd_handles_uuid=yes
else
if grep LABEL bin/nash > /dev/null; then
initrd_handles_label=yes
fi
# Older versions of nash support mounting by
# UUID, but the mkrootdev function doesn't
# support resolving to an actual device by UUID.
# Checking just for 'UUID' in these binaries
# will yield a false positive, so check for the
# nash function that doesn the work instead.
if grep nashDmGetUUID bin/nash > /dev/null; then
initrd_handles_uuid=yes
fi
fi
elif [ -x bin/mount ]; then
if grep libblkid.so bin/mount > /dev/null; then
initrd_handles_label=yes
initrd_handles_uuid=yes
else
if grep LABEL bin/mount > /dev/null; then
initrd_handles_label=yes
fi
if grep UUID bin/mount > /dev/null; then
initrd_handles_uuid=yes
fi
fi
fi
cd /
[ $mounted -eq 1 ] && umount "$initrd_dir"
rm -rf "$initrd_dir" "$decompressed_initrd"
}
initrd_handles_label=no
initrd_handles_uuid=no
check_initrd "$initrd"
echo "initrd_handles_label=$initrd_handles_label"
echo "initrd_handles_uuid=$initrd_handles_uuid"
exit 0
#!/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
clean_up()
{
if [ "$TMPFILE" != "" ]; then
rm -f $TMPFILE
fi
}
check_ide_disk() {
local file="$1"
grep 'ide[-_]disk' "$file" > /dev/null
if [ $? -eq 0 ]; then
echo "kernel_supports_ide=yes"
else
echo "kernel_supports_ide=no"
fi
}
dump_version() {
local file="$1"
local version=`sed -n -r '/Linux version/p' "$file" | \
tr -d -c ' -~' | cut -d' ' -f3`
echo "kernel_version=$version"
}
IKCFG_ST="0x49 0x4b 0x43 0x46 0x47 0x5f 0x53 0x54"
IKCFG_ED="0x49 0x4b 0x43 0x46 0x47 0x5f 0x45 0x44"
dump_config() {
local 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"
}
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"
check_ide_disk "$TMPFILE"
clean_up
exit 0
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"
check_ide_disk "$TMPFILE"
clean_up
exit 0
fi
echo "ERROR: Unable to extract kernel configuration information."
echo " This kernel image may not have the config info."
clean_up
exit 1
......@@ -14,19 +14,37 @@ 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()
{
if [ "$TMPFILE" != "" ]; then
rm -f $TMPFILE
fi
}
clean_up
exit 0
check_ide_disk() {
local file="$1"
grep 'ide[-_]disk' "$file" > /dev/null
if [ $? -eq 0 ]; then
echo "ide-disk: yes"
else
echo "ide-disk: no"
fi
}
dump_version() {
local file="$1"
local version=`sed -n -r '/Linux version/p' "$file" | \
tr -d -c ' -~' | cut -d' ' -f3`
echo "version: $version"
}
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"
dump_config() {
local file="$1"
start=`$binoffset $file $IKCFG_ST 2>/dev/null`
[ "$?" != "0" ] && start="-1"
......@@ -50,13 +68,6 @@ usage()
echo " usage: extract-ikconfig [b]zImage_filename"
}
clean_up()
{
if [ "$TMPFILE" != "" ]; then
rm -f $TMPFILE
fi
}
if [ $# -lt 1 ]
then
usage
......@@ -84,11 +95,17 @@ if [ "$off" -eq "0" ]; then
zcat <"$image" >"$TMPFILE"
#dump_config "$TMPFILE"
dump_version "$TMPFILE"
check_ide_disk "$TMPFILE"
clean_up
exit 0
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"
check_ide_disk "$TMPFILE"
clean_up
exit 0
fi
echo "ERROR: Unable to extract kernel configuration information."
......
......@@ -4,6 +4,8 @@ imageroot="$1"
real_root_dev="$2"
translated_root_dev="$3"
initrd=''
default_lilo_entry=''
is_label_or_uuid()
......@@ -11,7 +13,10 @@ is_label_or_uuid()
local mount="$1"
local rc=1 #failure
# Reject labels that contain slashes, since some initramfs
# images don't support vol_id's FS_LABEL_ENC key-value pair.
case $mount in
LABEL=*/*|label=*/*) rc=1; ;;
LABEL=*|label=*) rc=0; ;;
UUID=*|uuid=*) rc=0; ;;
esac
......@@ -21,14 +26,14 @@ is_label_or_uuid()
get_label()
{
local disk="$1"
local dev="$1"
local label=''
if [ -x /lib/udev/vol_id ]; then
label=`/lib/udev/vol_id --label-raw $disk`
label=`/lib/udev/vol_id --label-raw $dev`
elif [ -x /sbin/blkid ]; then
label=`/sbin/blkid | \
sed -n "s;^$disk"': *.*LABEL="\([^"]*\)".*;\1;p'`
sed -n "s;^$dev"': *.*LABEL="\([^"]*\)".*;\1;p'`
else
return 1
fi
......@@ -38,14 +43,14 @@ get_label()
get_uuid()
{
local disk="$1"
local dev="$1"
local uuid=''
if [ -x /lib/udev/vol_id ]; then
uuid=`/lib/udev/vol_id --uuid-raw $disk`
uuid=`/lib/udev/vol_id --uuid-raw $dev`
elif [ -x /sbin/blkid ]; then
uuid=`/sbin/blkid | \
sed -n "s;^$disk"': *.*UUID="\([^"]*\)".*;\1;p'`
sed -n "s;^$dev"': *.*UUID="\([^"]*\)".*;\1;p'`
else
return 1
fi
......@@ -256,6 +261,13 @@ get_bootloader_name()
echo $bootloader
}
get_swap_partitions()