[Pancutan-commits] r57 - in pancutan: defs tests/lib/Pancutan/Test
tincho-guest at alioth.debian.org
tincho-guest at alioth.debian.org
Mon Aug 13 13:47:50 UTC 2007
Author: tincho-guest
Date: 2007-08-13 13:47:50 +0000 (Mon, 13 Aug 2007)
New Revision: 57
Modified:
pancutan/defs/Booting.yaml
pancutan/tests/lib/Pancutan/Test/Booting.pm
pancutan/tests/lib/Pancutan/Test/Files.pm
Log:
Finish APM partitions, added MBR, SUN & BSD detection
Modified: pancutan/defs/Booting.yaml
===================================================================
--- pancutan/defs/Booting.yaml 2007-08-13 07:15:06 UTC (rev 56)
+++ pancutan/defs/Booting.yaml 2007-08-13 13:47:50 UTC (rev 57)
@@ -11,10 +11,21 @@
type: first_cd
non_decoupled_sub: detect_apm_partition
desc: Searches for an Apple Partition Map type partition table
+ depends: scan_files
detect_mbr_partition:
type: first_cd
non_decoupled_sub: detect_mbr_partition
desc: Searches for an Master Boot Record type partition table
+ depends: scan_files
+ detect_bsd_partition:
+ type: first_cd
+ non_decoupled_sub: detect_bsd_partition
+ desc: Searches for an BSD Disklabel type partition table
+ detect_sparc_partition:
+ type: first_cd
+ non_decoupled_sub: detect_sparc_partition
+ desc: Searches for an Sparc Disklabel type partition table
+ depends: scan_files
# desc: Scans the image for boot loaders (isolinux, yaboot, etc)
errors:
invalid-eltorito:
@@ -23,3 +34,18 @@
unknown-boot:
type: warn
desc: The bootable image cannot be mapped to a file
+ invalid-apm:
+ type: error
+ desc: APM partition table found, but it's invalid or contains errors
+ apm-without-hfs:
+ type: warn
+ desc: The APM partition table doesn't have any HFS partition on it
+ invalid-mbr:
+ type: error
+ desc: MBR partition table found, but it's invalid or contains errors
+ invalid-sunlabel:
+ type: error
+ desc: Sun Disklabel partition table found, but it's invalid or contains errors
+ missing-boot-element:
+ type: error
+ desc: Some part of the boot process is missing
Modified: pancutan/tests/lib/Pancutan/Test/Booting.pm
===================================================================
--- pancutan/tests/lib/Pancutan/Test/Booting.pm 2007-08-13 07:15:06 UTC (rev 56)
+++ pancutan/tests/lib/Pancutan/Test/Booting.pm 2007-08-13 13:47:50 UTC (rev 57)
@@ -12,13 +12,126 @@
use HTML::Entities;
use HTML::PullParser;
+my %mbrtypes = ( # Taken from fdisk
+ 0x00 => "Empty",
+ 0x01 => "FAT12",
+ 0x02 => "XENIX root",
+ 0x03 => "XENIX usr",
+ 0x04 => "Small FAT16",
+ 0x05 => "Extended",
+ 0x06 => "FAT16",
+ 0x07 => "HPFS/NTFS",
+ 0x08 => "AIX",
+ 0x09 => "AIX bootable",
+ 0x0a => "OS/2 boot mgr",
+ 0x0b => "FAT32",
+ 0x0c => "FAT32 LBA",
+ 0x0e => "FAT16 LBA",
+ 0x0f => "Extended LBA",
+ 0x10 => "OPUS",
+ 0x11 => "Hidden FAT12",
+ 0x12 => "Compaq diag",
+ 0x14 => "Hidd Sm FAT16",
+ 0x16 => "Hidd FAT16",
+ 0x17 => "Hidd HPFS/NTFS",
+ 0x18 => "AST SmartSleep",
+ 0x1b => "Hidd FAT32",
+ 0x1c => "Hidd FAT32 LBA",
+ 0x1e => "Hidd FAT16 LBA",
+ 0x24 => "NEC DOS",
+ 0x39 => "Plan 9",
+ 0x3c => "PMagic recovery",
+ 0x40 => "Venix 80286",
+ 0x41 => "PPC PReP Boot",
+ 0x42 => "SFS",
+ 0x4d => "QNX4.x",
+ 0x4e => "QNX4.x 2nd part",
+ 0x4f => "QNX4.x 3rd part",
+ 0x50 => "OnTrack DM",
+ 0x51 => "OnTrackDM6 Aux1",
+ 0x52 => "CP/M",
+ 0x53 => "OnTrackDM6 Aux3",
+ 0x54 => "OnTrack DM6",
+ 0x55 => "EZ Drive",
+ 0x56 => "Golden Bow",
+ 0x5c => "Priam Edisk",
+ 0x61 => "SpeedStor",
+ 0x63 => "GNU HURD/SysV",
+ 0x64 => "Netware 286",
+ 0x65 => "Netware 386",
+ 0x70 => "DiskSec MltBoot",
+ 0x75 => "PC/IX",
+ 0x80 => "Minix <1.4a",
+ 0x81 => "Minix >1.4b",
+ 0x82 => "Linux swap",
+ 0x83 => "Linux",
+ 0x84 => "OS/2 hidden C:",
+ 0x85 => "Linux extended",
+ 0x86 => "NTFS volume set",
+ 0x87 => "NTFS volume set",
+ 0x88 => "Linux plaintext",
+ 0x8e => "Linux LVM",
+ 0x93 => "Amoeba",
+ 0x94 => "Amoeba BBT",
+ 0x96 => "CHRP ISO9660",
+ 0x9f => "BSD/OS",
+ 0xa0 => "Thinkpad hib",
+ 0xa5 => "FreeBSD",
+ 0xa6 => "OpenBSD",
+ 0xa7 => "NeXTSTEP",
+ 0xa8 => "Darwin UFS",
+ 0xa9 => "NetBSD",
+ 0xab => "Darwin boot",
+ 0xb7 => "BSDI fs",
+ 0xb8 => "BSDI swap",
+ 0xbb => "Boot Wizard Hid",
+ 0xbe => "Solaris boot",
+ 0xbf => "Solaris",
+ 0xc1 => "DRDOS/2 FAT12",
+ 0xc4 => "DRDOS/2 smFAT16",
+ 0xc6 => "DRDOS/2 FAT16",
+ 0xc7 => "Syrinx",
+ 0xda => "Non-FS data",
+ 0xdb => "CP/M / CTOS",
+ 0xde => "Dell Utility",
+ 0xdf => "BootIt",
+ 0xe1 => "DOS access",
+ 0xe3 => "DOS R/O",
+ 0xe4 => "SpeedStor",
+ 0xeb => "BeOS fs",
+ 0xee => "EFI GPT",
+ 0xef => "EFI FAT",
+ 0xf0 => "Lnx/PA-RISC bt",
+ 0xf1 => "SpeedStor",
+ 0xf2 => "DOS secondary",
+ 0xf4 => "SpeedStor",
+ 0xfd => "Lnx RAID auto",
+ 0xfe => "LANstep",
+ 0xff => "XENIX BBT"
+);
+my %suntypes = ( # Taken from fdisk
+ 0x00 => "Unassigned partition",
+ 0x01 => "Boot partition",
+ 0x02 => "Root filesystem",
+ 0x03 => "Swap partition",
+ 0x04 => "/usr filesystem",
+ 0x05 => "Full-disk slice",
+ 0x06 => "Stand partition",
+ 0x07 => "/var filesystem",
+ 0x08 => "/home filesystem",
+ 0x09 => "Alt sector partition",
+ 0x0a => "Cachefs partition",
+ 0x0b => "SMI reserved data",
+ 0x82 => "Linux SWAP",
+ 0x83 => "Linux filesystem",
+ 0x8e => "Linux LVM",
+ 0xfd => "LInux RAID"
+);
+
sub read_eltorito {
my ($meta, $ncd, $scratch) = @_;
my $file = $meta->{set}[$ncd]{file};
my @res;
- my %lsnidx = map {
- $scratch->{files}{$_}{LSN} => $_
- } keys %{$scratch->{files}};
my $iso = Device::Cdio::ISO9660::IFS->new(
-source => $file) or die "Error opening ISO file: $!";
my $boot = $iso->seek_read(17,1);
@@ -104,7 +217,7 @@
my @emucodes = qw(noemu 1.2disk 1.44disk 2.88disk hdd);
$emul = $emucodes[$emul];
}
- my $bfile = $lsnidx{$lba};
+ my $bfile = $scratch->{lsnidx}{$lba};
if($bfile) {
push @{$meta->{set}[$ncd]{boot}{images}}, {
file => $bfile,
@@ -121,6 +234,11 @@
"LBA: $lba, emulation: $emudesc, boot file: $bfile, ",
"platform: $platform, id: $idstr");
next unless($bootable);
+ if($emul eq "noemu") {
+ push(@{$meta->{set}[$ncd]{boot}{files}}, [ pc => $bfile ]);
+ } else {
+ push(@{$meta->{set}[$ncd]{boot}{files}}, [ pcimg => $bfile ]);
+ }
}
$iso->close();
return @res;
@@ -135,6 +253,8 @@
close($fh);
return ();
}
+ $meta->{set}[$ncd]{boot}{apm} = 1;
+ my @res;
my $bs = unpack("n", substr($buf, 2, 2)); # block size
my $nr = unpack("N", substr($buf, $bs + 4, 4)); # nr of partitions
info("APM partition table detected: $nr partitions, block size: $bs");
@@ -142,8 +262,8 @@
my @partitions;
foreach(1..$nr) {
if(substr($buf, $bs * $_, 2) ne "PM") {
- warnn("Invalid signature in APM partition $_: ",
- substr($buf, $bs * $_, 2));
+ push(@res, "invalid-apm", "Invalid signature in APM partition $_: "
+ . substr($buf, $bs * $_, 2));
next;
}
my $start = unpack("N", substr($buf, $_ * $bs + 8, 4));
@@ -153,7 +273,8 @@
info("APM partition $_: type: $type, name: $name, start: $start, ",
"size: $len");
if($_ != 1 and $start < $partitions[-1]{start}) {
- warnn("APM partitions order doesn't match physical ordering");
+ push(@res, "invalid-apm",
+ "APM partitions order doesn't match physical ordering");
}
push @partitions, {
start => $start,
@@ -164,41 +285,197 @@
}
@partitions = sort({ $a->{start} <=> $b->{start} } @partitions);
if($partitions[0]{type} ne "Apple_partition_map") {
- warnn("Invalid APM partition: first partition is type \"",
- $partitions[0]{type}, "\"");
+ push(@res, "invalid-apm",
+ "First partition is type \"$partitions[0]{type}\"");
}
if($partitions[0]{start} != 1) {
- warnn("Invalid APM partition: first partition starts in block ",
+ push(@res, "invalid-apm", "First partition starts in block " .
$partitions[0]{start});
}
foreach(1..$#partitions) {
my $start = $partitions[$_]{start};
my $suppst = $partitions[$_-1]{start} + $partitions[$_-1]{len};
if($start < $suppst) {
- warnn("Invalid APM partition $_ overlaps with previous partition");
+ push(@res, "invalid-apm",
+ "Partition $_ overlaps with previous partition");
} elsif($start != $suppst) {
- warnn("APM partition $nr is not contiguous");
+ debug("note -- APM partition $nr is not contiguous");
}
- next unless($partitions[$_]{type} eq "Apple_HFS");
- execute(hfsbootfiles => $file, $start);
}
+ @partitions = grep({$_->{type} eq "Apple_HFS"} @partitions);
+ unless(@partitions) {
+ push(@res, "apm-without-hfs", "");
+ }
+ my @bootfiles;
+ foreach(@partitions) {
+ my($st, @files) = execute(hfsbootfiles => $file, $_->{start});
+ die "Error executing hfsbootfiles: $st\n" if($st);
+ push @bootfiles, @files;
+ }
+ foreach(@bootfiles) {
+ chomp;
+ s/^[^:]*://;
+ s/:/\//g;
+ if($scratch->{files}{$_}) {
+ info("Mac bootfile: $_");
+ push(@{$meta->{set}[$ncd]{boot}{files}}, [ mac => $_ ]);
+ } else {
+ push(@res, "unknown-boot", "Cannot find $_");
+ }
+ }
close($fh);
- ();
+ return @res;
}
sub detect_mbr_partition {
my ($meta, $ncd, $scratch) = @_;
+ my $file = $meta->{set}[$ncd]{file};
my $fh;
- my $file = $meta->{set}[$ncd]{file};
sysopen($fh, $file, O_RDONLY) or die "Error opening ISO file: $!";
- my $buf = _myread($fh, 0, 1024);
- if(substr($buf, 510, 2) eq "\x55\xaa") {
+ my $buf = _myread($fh, 0, 512);
+ unless(substr($buf, 510, 2) eq "\x55\xaa") {
close($fh);
return ();
}
info("MBR partition detected");
+ my @res;
+ foreach(0..3) {
+ my $active = ord(substr($buf, 0x1be + 16 * $_, 1));
+ my $type = ord(substr($buf, 0x1be + 16 * $_ + 4, 1));
+ next unless($type);
+ if($active != 0 and $active != 0x80) {
+ push(@res, "invalid-mbr", "Active flag has invalid value $active");
+ }
+ $active = ($active != 0);
+ my $pdesc;
+ if(!exists $mbrtypes{$type}) {
+ push(@res, "invalid-mbr", "Invalid partition type $type");
+ $pdesc = "unknown";
+ } else {
+ $pdesc = $mbrtypes{$type};
+ }
+ my $start = unpack("V", substr($buf, 0x1be + 16 * $_ + 8, 4));
+ my $size = unpack("V", substr($buf, 0x1be + 16 * $_ + 12, 4));
+ if($start % 4) {
+ push(@res, "invalid-mbr", "Partition " . ($_ + 1) .
+ " points to an out of bounds block");
+ }
+ $start /= 4;
+ $size *= 512;
+ info("MBR partition: ", $_ + 1, ", type $pdesc, ",
+ "start LBA: $start, size: $size");
+ if($type == 0x96) { # CHRP
+ if($start > 0) {
+ push(@res, "invalid-mbr", "Partition type \"$pdesc\" " .
+ "should point to the beginning of the ISO image");
+ } elsif(! $scratch->{files}{"ppc/bootinfo.txt"}) {
+ push(@res, "invalid-mbr", "Partition type is \"$pdesc\", " .
+ "but a CHRP boot definition cannot be found");
+ } else {
+ push(@{$meta->{set}[$ncd]{boot}{files}},
+ [ chrp => "ppc/bootinfo.txt" ]);
+ info("CHRP boot file: ppc/bootinfo.txt");
+ }
+ next;
+ } elsif($start == 0) {
+ push(@res, "invalid-mbr", "Partition type \"$pdesc\" points to ",
+ "beggining of ISO image, but I don't know how to handle it");
+ } elsif(not exists($scratch->{lsnidx}{$start})) {
+ push(@res, "unknown-boot", "Partition " . ($_ + 1) .
+ " points to block $start");
+ next;
+ }
+ my $bfile = $scratch->{lsnidx}{$start};
+ if($type == 0x41) { # PReP
+ push(@{$meta->{set}[$ncd]{boot}{files}},
+ [ prep => $bfile ]);
+ info("PReP boot file: $bfile");
+ } else {
+ push(@res, "invalid-mbr", "Partition type \"$pdesc\" points to ",
+ "$bfile, but I don't know how to handle it");
+ push(@{$meta->{set}[$ncd]{boot}{files}},
+ [ unknown => $bfile ]);
+ }
+ }
close($fh);
- ();
+ return @res;
}
+sub detect_bsd_partition {
+ my ($meta, $ncd, $scratch) = @_;
+ my $file = $meta->{set}[$ncd]{file};
+ my($fh, $buf, @res);
+ sysopen($fh, $file, O_RDONLY) or die "Error opening ISO file: $!";
+ $buf = _myread($fh, 0, 512);
+ unless(unpack("V", substr($buf, 0, 4)) == 0x82564557) {
+ $buf = _myread($fh, 512, 512);
+ }
+ unless(unpack("V", substr($buf, 0, 4)) == 0x82564557) {
+ close($fh);
+ return ();
+ }
+ info("BSD disklabel detected");
+ close($fh);
+ return(@res);
+}
+sub detect_sparc_partition {
+ my ($meta, $ncd, $scratch) = @_;
+ my $file = $meta->{set}[$ncd]{file};
+ my($fh, $buf, @res);
+ sysopen($fh, $file, O_RDONLY) or die "Error opening ISO file: $!";
+ $buf = _myread($fh, 0, 512);
+ unless(unpack("n", substr($buf, 508, 2)) == 0xdabe) {
+ close($fh);
+ return ();
+ }
+ info("Sparc disklabel detected");
+ my $label = unpack("Z*", substr($buf, 0, 128));
+ my $volname = unpack("Z*", substr($buf, 132, 8));
+ my $nr = unpack("n", substr($buf, 140, 2));
+ my $sane = unpack("N", substr($buf, 188, 4));
+ my $cylsize = (unpack("n", substr($buf, 436, 2)) *
+ unpack("n", substr($buf, 438, 2)));
+ my $chksum = 0;
+ $chksum ^= $_ foreach(unpack("n*", $buf));
+ if($chksum) {
+ push(@res, "invalid-sunlabel", "Invalid checksum: $chksum");
+ }
+ if($sane != 0x600DDEEE) {
+ push(@res, "invalid-sunlabel", "Vtoc not sane: $sane");
+ }
+ my %bootstarts;
+ foreach(0..($nr - 1)) {
+ my $tag = unpack("n", substr($buf, 142 + $_ * 4, 2));
+ my $lag = unpack("n", substr($buf, 144 + $_ * 4, 2));
+ my $start = unpack("N", substr($buf, 444 + $_ * 8, 4));
+ my $size = unpack("N", substr($buf, 448 + $_ * 8, 4));
+ next unless($tag);
+ $bootstarts{$start} = 1; # eliminate duplicates, we only care about
+ # start location
+ }
+ my @bootstarts = keys(%bootstarts);
+ unless(@bootstarts) {
+ push(@res, "invalid-sunlabel", "Cannot find any valid partition");
+ }
+ foreach(@bootstarts) {
+ # This is not very clear, just in case, we try all slices
+ my $bfile = _myread($fh, $_ * $cylsize, 15 * 512);
+ if(index($bfile, "/boot/second.b") >= 0) {
+ # geez, nothing better to look for
+ info("Detected SILO bootloader");
+ if(! $scratch->{files}{"boot/second.b"}) {
+ push(@res, "missing-boot-element",
+ "Missing SILO second stage loader");
+ } elsif(! $scratch->{files}{"boot/silo.conf"}) {
+ push(@res, "missing-boot-element",
+ "Missing SILO configuration file");
+ } else {
+ push(@{$meta->{set}[$ncd]{boot}{files}},
+ [ silo => "/boot/silo.conf" ]);
+ }
+ }
+ }
+ close($fh);
+ return(@res);
+}
sub _myread {
my($fh, $pos, $bytes) = @_;
my $buf;
Modified: pancutan/tests/lib/Pancutan/Test/Files.pm
===================================================================
--- pancutan/tests/lib/Pancutan/Test/Files.pm 2007-08-13 07:15:06 UTC (rev 56)
+++ pancutan/tests/lib/Pancutan/Test/Files.pm 2007-08-13 13:47:50 UTC (rev 57)
@@ -31,10 +31,12 @@
}
sub scan_files_master {
my($global, $ncd, $scratch, $files, $lsns) = @_;
- my %hash = map { $files->[$_] => { LSN => $lsns->[$_] } } 0..$#{$files};
- debug(scalar keys %hash, " files found");
- $scratch->{files} = \%hash;
+ foreach(0..$#{$files}) {
+ $scratch->{files}{$files->[$_]} = { LSN => $lsns->[$_] };
+ $scratch->{lsnidx}{$lsns->[$_]} = $files->[$_];
+ }
$scratch->{filelist} = [ @$files ];
+ debug(scalar @$files, " files found");
return ();
}
sub scan_files {
More information about the Pancutan-commits
mailing list