Commit d01ec626 authored by Ryan Jackson's avatar Ryan Jackson

Now that both the initramfs and the dongle have perl installed, convert some of

the nastier shell scripts I wrote to somewhat cleaner perl.
parent fe78b402
#! /bin/sh
disk=$1
part=$2
if [ -z "$disk" ] || [ -z "$part" ]; then
echo "Usage: ${0##*/} disk partition"
if [ -z "$disk" ]; then
echo "Usage: ${0##*/} disk"
exit 1
fi
......@@ -12,27 +11,26 @@ dunit=`echo $disk | sed -e 's/..\([0-7]\)/\1/'`
case $disk in
# IDE
ad[0-3])
#dtype="hd"
old_dtype="hd"
dtype="sd"
d=`echo $dunit | sed -e 'y/0123/048c/'`
lrootdev="3${d}${part}"
;;
# SATA
ad[4-7])
old_dtype="sd"
dtype="sd"
dunit=`expr $dunit - 4`
lrootdev="8${dunit}${part}"
;;
# SCSI
da[0-7])
dtype="sd"
lrootdev="8${dunit}${part}"
old_dtype="sd"
;;
# Megaraid
amrd[0-7])
dunit=`echo $disk | sed -e 's/amrd\([0-7]\)/\1/'`
dtype="sd"
lrootdev="8${dunit}${part}"
old_dtype="sd"
;;
*)
echo "${0##*/}: linux: unknown disk $disk" 1>&2
......@@ -41,5 +39,6 @@ case $disk in
esac
dunit=`echo $dunit | sed -e 'y/01234567/abcdefgh/'`;
ldisk=$dtype$dunit
old_ldisk=$old_dtype$dunit
echo $ldisk $lrootdev
echo $ldisk $old_ldisk
#! /usr/bin/perl
use Data::Dumper;
use constant EDD_PREFIX => '/sys/firmware/edd';
use strict;
my %mbr_sig_map;
my %disk_size;
my %edd_data;
my %blockdev_found;
sub read_file
{
my ($filename) = @_;
my $output;
open FILE, $filename || return undef;
while (<FILE>) {
$output .= $_;
}
close FILE;
chomp $output;
return $output;
}
sub read_mbr
{
my ($device) = @_;
my $output;
open FILE, $device or die "Couldn't open $device: $!\n";
read FILE, $output, 512;
close FILE;
return $output;
}
sub read_disk_mbr_signatures
{
for my $disk (glob "/sys/block/[hs]d[a-z]") {
my $size;
open SIZE, "$disk/size";
($size) = <SIZE>;
close SIZE;
chomp $size;
$disk =~ s/^.*\///;
$disk_size{$disk} = $size;
my $sig = substr read_mbr("/dev/$disk"), 440, 4;
$mbr_sig_map{$disk} = unpack 'V', $sig;
}
}
sub read_edd_data
{
for my $dir (glob EDD_PREFIX . "/*") {
my ($bus, $busid, $channel);
my ($interface, $device, $lun);
my $junk;
my $disk_hash = {};
my $data = read_file("$dir/host_bus");
if (defined $data) {
my ($bus, $busid, $junk1, $channel) = split(/\s+/, $data);
$$disk_hash{'bus'} = $bus;
$$disk_hash{'busid'} = $busid;
$$disk_hash{'channel'} = $channel;
}
my $data = read_file("$dir/interface");
if (defined $data) {
my ($interface, $junk, $device, $junk, $lun) = split /\s+/, $data;
$lun = 0 unless defined $lun;
$$disk_hash{'interface'} = $interface;
$$disk_hash{'device'} = $device;
$$disk_hash{'lun'} = $lun;
}
if (-l "$dir/pci_dev") {
$$disk_hash{'pci_dev'} = "$dir/pci_dev";
}
my $sectors = read_file("$dir/sectors");
if (defined $sectors) {
$$disk_hash{'sectors'} = $sectors;
}
my $sig = read_file("$dir/mbr_signature");
if (defined $sig) {
$$disk_hash{'mbr_signature'} = hex $sig;
}
$dir =~ s/.*int13_dev//;
$edd_data{$dir} = $disk_hash;
}
}
sub resolve_edd_pcidev
{
my ($bios_device) = @_;
my $pci_dev_file = ${$edd_data{$bios_device}}{'pci_dev'};
my $channel = ${$edd_data{$bios_device}}{'channel'};
my $device = ${$edd_data{$bios_device}}{'device'};
my $lun = ${$edd_data{$bios_device}}{'lun'};
return undef unless ($pci_dev_file);
my @host_adapters = sort glob "$pci_dev_file/host*";
if (@host_adapters < $channel) {
return undef;
}
$host_adapters[$channel] =~ /\d+$/;
my $host_num = $&;
my $path;
my $dev_path = $host_adapters[$channel] .
"/target$host_num:0:$device";
my $lun_path = "$dev_path/$host_num:0:$device:$lun";
if (! -e $lun_path) {
$path = "$dev_path/$host_num:0:$device:0";
}
else {
$path = $lun_path;
}
my $blockdev;
if ( -d "$path/block") {
($blockdev) = glob "$path/block/*";
}
elsif ($blockdev = glob "$path/block:*") {
$blockdev =~ s/.*block://;
}
else {
return undef;
}
$blockdev =~ s/.*\///;
${$edd_data{$bios_device}}{'blockdev'} = $blockdev;
$blockdev_found{$blockdev} = 1;
}
sub resolve_edd_mbrsig
{
my ($bios_device) = @_;
my $mbr_signature = ${$edd_data{$bios_device}}{'mbr_signature'};
my $blockdev = ${$edd_data{$bios_device}}{'blockdev'};
my $sectors = ${$edd_data{$bios_device}}{'sectors'};
return if defined $blockdev;
return undef unless defined ($mbr_signature);
my $last_match;
for my $blockdev (keys %disk_size) {
next if ($blockdev_found{$blockdev});
next if ($sectors != $disk_size{$blockdev});
if ($mbr_signature == $mbr_sig_map{$blockdev}) {
if (not defined $last_match) {
$last_match = $blockdev;
}
else {
return undef;
}
}
}
if ($last_match) {
${$edd_data{$bios_device}}{'blockdev'} = $last_match;
}
}
sub main
{
`modprobe edd`;
read_edd_data();
read_disk_mbr_signatures();
for my $device (keys %edd_data) {
resolve_edd_pcidev($device);
}
for my $device (keys %edd_data) {
resolve_edd_mbrsig($device);
}
for my $device (keys %edd_data) {
my $blockdev = ${$edd_data{$device}}{'blockdev'};
if ($blockdev) {
print "$blockdev=$device\n";
}
}
}
main(@ARGV);
......@@ -142,9 +142,10 @@ case $# in
2)
part=$1
disk=$2
old_disk=$3
;;
*)
echo "Usage: $0 partition [disk]"
echo "Usage: $0 partition [disk] [old_disk]"
exit 1
esac
......@@ -160,9 +161,7 @@ mount -t $fstype $real_root_dev /mnt 2> /dev/null || {
}
}
$BINDIR/remap_ide_disks > /tmp/disk_map
new_disk=`map_disk $disk /tmp/disk_map`
translated_root_dev=/dev/$new_disk$part
translated_root_dev=/dev/$old_disk$part
# XXX Ugly, disgusting compatibility hack follows
......
This diff is collapsed.
......@@ -31,8 +31,8 @@ else
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
if [ -x $BINDIR/get_edd_map.pl ]; then
$BINDIR/get_edd_map.pl > $BOOTDIR/edd_map
fi
......
......@@ -29,8 +29,8 @@ case $# in
exit 1
esac
linux_disk=`$BINDIR/freebsd_to_linux_disk $freebsd_disk $part`
lrootdev=${linux_disk#* }
linux_disk=`$BINDIR/freebsd_to_linux_disk $freebsd_disk`
old_linux_disk=${linux_disk#* }
linux_disk=${linux_disk%% *}
if [ $OS = Linux ]; then
......@@ -412,7 +412,7 @@ lilogetkernel() {
dolinux() {
$BINDIR/linux_slicefix $part $linux_disk
$BINDIR/linux_slicefix.pl /dev/$linux_disk$part /dev/$old_linux_disk$part
return $?
}
......
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