summaryrefslogtreecommitdiffstats
path: root/perl-install/partition_table/gpt.pm
blob: 1ac2969465c4e623e57b3d43990415ef4fdbb1d3 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
package partition_table::gpt;

use diagnostics;
use strict;
use vars qw(@ISA);

@ISA = qw(partition_table::raw);

use fs::type;
use partition_table::raw;
use c;

my $nb_primary = 128;

my %_GUID_to_Label = (
  # No OS
  "00000000-0000-0000-0000-000000000000" => "Unused entry",
  "024DEE41-33E7-11D3-9D69-0008C781F39F" => "MBR partition scheme",
  "C12A7328-F81F-11D2-BA4B-00A0C93EC93B" => "EFI System partition",
  "21686148-6449-6E6F-744E-656564454649" => "BIOS Boot partition",
  "D3BFE2DE-3DAF-11DF-BA40-E3A556D89593" => "Intel Fast Flash (iFFS) partition for Rapid Start (iRST)",
  "F4019732-066E-4E12-8273-346C5641494F" => "Sony boot partition",
  "BFBFAFE7-A34F-448A-9A5B-6213EB736C22" => "Lenovo boot partition",
  # Microsoft
  "E3C9E316-0B5C-4DB8-817D-F92DF00215AE" => "Microsoft Reserved Partition (MSR)",
  "EBD0A0A2-B9E5-4433-87C0-68B6B72699C7" => "Microsoft Basic data partition",
  "5808C8AA-7E8F-42E0-85D2-E1E90434CFB3" => "Microsoft Logical Disk Manager (LDM) metadata partition",
  "AF9B60A0-1431-4F62-BC68-3311714A69AD" => "Microsoft Logical Disk Manager data partition",
  "DE94BBA4-06D1-4D40-A16A-BFD50179D6AC" => "Microsoft Windows Recovery Environment",
  "37AFFC90-EF7D-4E96-91C3-2D7AE055B174" => "Microsoft IBM General Parallel File System (GPFS) partition",
  "E75CAF8F-F680-4CEE-AFA3-B001E56EFC2D" => "Microsoft Storage Spaces partition",
  # HP-UX
  "75894C1E-3AEB-11D3-B7C1-7B03A0000000" => "HP-UX Data partition",
  "E2A1E728-32E3-11D6-A682-7B03A0000000" => "HP-UX Service Partition",
  # Linux
  "0FC63DAF-8483-4772-8E79-3D69D8477DE4" => "Linux filesystem data",
  "A19D880F-05FC-4D3B-A006-743F0F84911E" => "Linux RAID partition",
  "0657FD6D-A4AB-43C4-84E5-0933C84B4F4F" => "Linux Swap partition",
  "E6D6D379-F507-44C2-A23C-238F2A3DF928" => "Linux Logical Volume Manager (LVM) partition",
  "933AC7E1-2EB4-4F13-B844-0E14E2AEF915" => "Linux /home partition",
  "3B8F8425-20E0-4F3B-907F-1A25A76F98E8" => "Linux /srv (server data) partition",
  "7FFEC5C9-2D00-49B7-8941-3EA10A5586B7" => "Linux Plain dm-crypt partition",
  "CA7D7CCB-63ED-4C53-861C-1742536059CC" => "Linux LUKS partition",
  "8DA63339-0007-60C0-C436-083AC8230908" => "Linux Reserved",
  # FreeBSD
  "83BD6B9D-7F41-11DC-BE0B-001560B84F0F" => "FreeBSD Boot partition",
  "516E7CB4-6ECF-11D6-8FF8-00022D09712B" => "FreeBSD Data partition",
  "516E7CB5-6ECF-11D6-8FF8-00022D09712B" => "FreeBSD Swap partition",
  "516E7CB6-6ECF-11D6-8FF8-00022D09712B" => "FreeBSD Unix File System (UFS) partition",
  "516E7CB8-6ECF-11D6-8FF8-00022D09712B" => "FreeBSD Vinum volume manager partition",
  "516E7CBA-6ECF-11D6-8FF8-00022D09712B" => "FreeBSD ZFS partition",
  # Mac OSX
  "48465300-0000-11AA-AA11-00306543ECAC" => "Mac OSX Hierarchical File System Plus (HFS+) partition",
  "55465300-0000-11AA-AA11-00306543ECAC" => "Mac OSX Apple UFS",
  "6A898CC3-1DD2-11B2-99A6-080020736631" => "Mac OSX ZFS",
  "52414944-0000-11AA-AA11-00306543ECAC" => "Apple RAID partition",
  "52414944-5F4F-11AA-AA11-00306543ECAC" => "Apple RAID partition, offline",
  "426F6F74-0000-11AA-AA11-00306543ECAC" => "Apple Boot partition",
  "4C616265-6C00-11AA-AA11-00306543ECAC" => "Apple Label",
  "5265636F-7665-11AA-AA11-00306543ECAC" => "Apple TV Recovery partition",
  "53746F72-6167-11AA-AA11-00306543ECAC" => "Apple Core Storage (Lion FileVault) partition",
  # Solaris
  "6A82CB45-1DD2-11B2-99A6-080020736631" => "Solaris Boot partition",
  "6A85CF4D-1DD2-11B2-99A6-080020736631" => "Solaris Root partition",
  "6A87C46F-1DD2-11B2-99A6-080020736631" => "Solaris Swap partition",
  "6A8B642B-1DD2-11B2-99A6-080020736631" => "Solaris Backup partition",
  "6A898CC3-1DD2-11B2-99A6-080020736631" => "Solaris /usr partition",
  "6A8EF2E9-1DD2-11B2-99A6-080020736631" => "Solaris /var partition",
  "6A90BA39-1DD2-11B2-99A6-080020736631" => "Solaris /home partition",
  "6A9283A5-1DD2-11B2-99A6-080020736631" => "Solaris Alternate sector",
  "6A945A3B-1DD2-11B2-99A6-080020736631" => "Solaris Reserved partition",
  "6A9630D1-1DD2-11B2-99A6-080020736631" => "Solaris Reserved partition",
  "6A980767-1DD2-11B2-99A6-080020736631" => "Solaris Reserved partition",
  "6A96237F-1DD2-11B2-99A6-080020736631" => "Solaris Reserved partition",
  "6A8D2AC7-1DD2-11B2-99A6-080020736631" => "Solaris Reserved partition",
  # NetBSD
  "49F48D32-B10E-11DC-B99B-0019D1879648" => "NetBSD Swap partition",
  "49F48D5A-B10E-11DC-B99B-0019D1879648" => "NetBSD FFS partition",
  "49F48D82-B10E-11DC-B99B-0019D1879648" => "NetBSD LFS partition",
  "49F48DAA-B10E-11DC-B99B-0019D1879648" => "NetBSD RAID partition",
  "2DB519C4-B10F-11DC-B99B-0019D1879648" => "NetBSD Concatenated partition",
  "2DB519EC-B10F-11DC-B99B-0019D1879648" => "NetBSD Encrypted partition",
  # ChromeOS
  "FE3A2A5D-4F32-41A7-B725-ACCC3285A309" => "ChromeOS kernel",
  "3CB8E202-3B7E-47DD-8A3C-7FF2A13CFCEC" => "ChromeOS rootfs",
  "2E0A753D-9E48-43B0-8337-B15192CB1B5E" => "ChromeOS future use",
  # Haiku
  "42465331-3BA3-10F1-802A-4861696B7521" => "Haiku BFS",
  # MidnightBSD
  "85D5E45E-237C-11E1-B4B3-E89A8F7FC3A7" => "MidnightBSD Boot partition",
  "85D5E45A-237C-11E1-B4B3-E89A8F7FC3A7" => "MidnightBSD Data partition",
  "85D5E45B-237C-11E1-B4B3-E89A8F7FC3A7" => "MidnightBSD Swap partition",
  "0394EF8B-237E-11E1-B4B3-E89A8F7FC3A7" => "MidnightBSD Unix File System (UFS) partition",
  "85D5E45C-237C-11E1-B4B3-E89A8F7FC3A7" => "MidnightBSD Vinum volume manager partition",
  "85D5E45D-237C-11E1-B4B3-E89A8F7FC3A7" => "MidnightBSD ZFS partition",
  # Ceph
  "BFBFAFE7-A34F-448A-9A5B-6213EB736C22" => "Ceph Journal",
  "45B0969E-9B03-4F30-B4C6-5EC00CEFF106" => "Ceph dm-crypt Encrypted Journal",
  "4FBD7E29-9D25-41B8-AFD0-062C0CEFF05D" => "Ceph OSD",
  "4FBD7E29-9D25-41B8-AFD0-5EC00CEFF05D" => "Ceph dm-crypt OSD",
  "89C57F98-2FE5-4DC0-89C1-F3AD0CEFF2BE" => "Ceph disk in creation",
  "89C57F98-2FE5-4DC0-89C1-5EC00CEFF2BE" => "Ceph dm-crypt disk in creation",
);

sub read_one {
    my ($hd, $_sector) = @_;

    c::get_disk_type($hd->{file}) eq "gpt" or die "$hd->{device} not a GPT disk ($hd->{file})";

    my @pt;
    # FIXME: just use '@pt = map { ... } c::...' if part_numbers are always linear:
    foreach (c::get_disk_partitions($hd->{file})) {
        # fix detecting ESP (special case are they're detected through pt_type):
        if (c::get_partition_flag($hd->{file}, $_->{part_number}, 'ESP')) {
	    $_->{pt_type} = 0xef;
        } elsif (c::get_partition_flag($hd->{file}, $_->{part_number}, 'LVM')) {
	    $_->{pt_type} = 0x8e;
        } elsif (c::get_partition_flag($hd->{file}, $_->{part_number}, 'RAID')) {
	    $_->{pt_type} = 0xfd;
        }
        $part->{fs_type} = 'swap' if $part->{fs_type} eq 'linux-swap(v1)';
        @pt[$_->{part_number}-1] = $_;
    }

    for (my $part_number = 1; $part_number < $nb_primary; $part_number++) {
	next if exists($pt[$part_number-1]);
	$pt[$part_number-1] = { part_number => $part_number };
    }

    \@pt;
}

sub write {
    my ($hd, $_sector, $pt, $_info) = @_;

    my $partitions_killed;

    # Initialize the disk if current partition table is not gpt
    if (c::get_disk_type($hd->{file}) ne "gpt") {
        c::set_disk_type($hd->{file}, "gpt");
        $partitions_killed = 1;
    }

    foreach (@{$hd->{will_tell_kernel}}) {
        my ($action, $part_number, $o_start, $o_size) = @$_;
        my ($part) = grep { $_->{start} == $o_start && $_->{size} == $o_size } @$pt;
        print "($action, $part_number, $o_start, $o_size)\n";
        if ($action eq 'add') {
            local $part->{fs_type} = 'linux-swap(v1)' if isSwap($part->{fs_type});
            local $part->{fs_type} = 'ntfs' if $part->{fs_type} eq 'ntfs-3g';
            c::disk_add_partition($hd->{file}, $o_start, $o_size, $part->{fs_type}) or die "failed to add partition #$part_number on $hd->{file}";
	    my $flag;
	    if (isESP($part)) {
                $flag = 'ESP';
	    } elsif (isRawLVM($part)) {
                $flag = 'LVM';
	    } elsif (isRawRAID($part)) {
                $flag = 'RAID';
	    }
	    if ($flag) {
	        c::set_partition_flag($hd->{file}, $part_number, $flag)
	          or die "failed to set type '$flag' for $part->{file} on $part->{mntpoint}";
	    }
        } elsif ($action eq 'del' && !$partitions_killed) {
            c::disk_del_partition($hd->{file}, $part_number) or die "failed to del partition #$part_number on $hd->{file}";
        }
    }
    common::sync();
    1;
}

sub initialize {
    my ($class, $hd) = @_;
    my @raw;
    for (my $part_number = 0; $part_number < $nb_primary-1; $part_number++) {
        # part_number starts at 1
        $raw[$part_number] = { part_number => $part_number + 1 };
    }
    $hd->{primary} = { raw => \@raw };
    bless $hd, $class;
}

sub can_add { &can_raw_add }
sub adjustStart {}
sub adjustEnd {}

1;
quot;, "ultrastor" => "UltraStor 14F/24F/34F", "wd7000" => "Western Digital wd7000", "a100u2w" => "a100u2w", "atp870u" => "atp870u (Acard/Artop)", "dc395x_trm" => "dc395x_trm", "psi240i" => "psi240i", "qlogicfc" => "qlogicfc", "sim710" => "sim710", "sym53c416" => "sym53c416", "tmscsim" => "tmscsim", "scsi_mod" => "scsi_mod", ), "aic7xxx" => "Adaptec 2740, 2840, 2940", "ncr53c8xx" => "NCR 53C8xx PCI", # "pci2000" => "Perceptive Solutions PCI-2000", # TODO "qlogicisp" => "Qlogic ISP", "sym53c8xx" => "Symbios 53c8xx", "sd_mod" => "sd_mod", "ide-mod" => "ide-mod", "ide-probe" => "ide-probe", "ide-probe-mod" => "ide-probe-mod", }], [ 'disk', { arch() =~ /^sparc/ ? ( "pluto" => "Sun SparcSTORAGE Array SCSI", #- name it "fc4:soc:pluto" ? ) : arch() =~ /alpha/ ? () : ( "DAC960" => "Mylex DAC960", # "dpt" => "Distributed Tech SmartCache/Raid I-IV Controller", # not there anymore? "megaraid" => "AMI MegaRAID", "cpqarray" => "Compaq Smart-2/P RAID Controller", "gdth" => "ICP Disk Array Controller", "ips" => "IBM ServeRAID controller", "eata" => "EATA SCSI PM2x24/PM3224", "eata_pio" => "EATA PIO Adapters", "eata_dma" => "EATA DMA Adapters", "ppa" => "Iomega PPA3 (parallel port Zip)", "imm" => "Iomega Zip (new driver)", ), "ide-disk" => "IDE disk", }], [ 'cdrom', { arch() !~ /^sparc|alpha/ ? ( "sbpcd" => "SoundBlaster/Panasonic", #- "aztcd" => "Aztech CD", #- "gscd" => "Goldstar R420", #- "isp16" => "ISP16/MAD16/Mozart", #- "mcd" => "Mitsumi", #- removed for space #- "mcdx" => "Mitsumi (alternate)", #- "optcd" => "Optics Storage 8000", #- "cm206" => "Phillips CM206/CM260", #- "sjcd" => "Sanyo", "cdu31a" => "Sony CDU-31A", "sonycd535" => "Sony CDU-5xx", ) : (), "isofs" => "iso9660", "ide-cd" => "ide-cd", "sr_mod" => "SCSI CDROM support", "cdrom" => "cdrom", }], [ 'sound', { arch() !~ /^sparc/ ? ( "alsa" => "ALSA sound module, many sound cards", "cmpci" => "C-Media Electronics CMI8338A CMI8338B CMI8738", "es1370" => "Ensoniq ES1370 [AudioPCI]", "es1371" => "Ensoniq ES1371 [AudioPCI-97]", "esssolo1" => "ESS Technology ES1969 Solo-1 Audiodrive", "maestro" => "Maestro", "nm256" => "Neomagic MagicMedia 256AV", "pas16" => "Pro Audio Spectrum/Studio 16", "via82cxxx" => "VIA VT82C686_5", "sonicvibes" => "S3 SonicVibes", ) : (), }], [ 'pcmcia', { arch() !~ /^sparc/ ? ( "ide_cs" => "ide_cs", "fmvj18x_cs" => "fmvj18x_cs", "fdomain_cs" => "fdomain_cs", "netwave_cs" => "netwave_cs", "serial_cs" => "serial_cs", "wavelan_cs" => "wavelan_cs", "pcnet_cs" => "pcnet_cs", "aha152x_cs" => "aha152x_cs", "xirc2ps_cs" => "xirc2ps_cs", "3c574_cs" => "3c574_cs", "qlogic_cs" => "qlogic_cs", "nmclan_cs" => "nmclan_cs", "ibmtr_cs" => "ibmtr_cs", "dummy_cs" => "dummy_cs", "memory_cs" => "memory_cs", "ftl_cs" => "ftl_cs", "smc91c92_cs" => "smc91c92_cs", "3c589_cs" => "3c589_cs", "parport_cs" => "parport_cs", "3c575_cb" => "3c575_cb", "apa1480_cb" => "apa1480_cb", "cb_enabler" => "cb_enabler", "epic_cb" => "epic_cb", "iflash2+_mtd" => "iflash2+_mtd", "iflash2_mtd" => "iflash2_mtd", "memory_cb" => "memory_cb", "serial_cb" => "serial_cb", "sram_mtd" => "sram_mtd", "tulip_cb" => "tulip_cb", ) : (), }], [ 'pcmcia_everywhere', { arch() !~ /^sparc/ ? ( "pcmcia_core" => "PCMCIA core support", "tcic" => "PCMCIA tcic controller", "ds" => "PCMCIA card support", "i82365" => "PCMCIA i82365 controller", ) : (), }], [ 'paride', { arch() !~ /^sparc/ ? ( "aten" => "ATEN EH-100", "bpck" => "Microsolutions backpack", "comm" => "DataStor (older type) commuter adapter", "dstr" => "DataStor EP-2000", "epat" => "Shuttle EPAT", "epia" => "Shuttle EPIA", "fit2" => "Fidelity Intl. (older type)", "fit3" => "Fidelity Intl. TD-3000", "frpw" => "Freecom Power", "friq" => "Freecom IQ (ASIC-2)", "kbic" => "KingByte KBIC-951A and KBIC-971A", "ktti" => "KT Tech. PHd", "on20" => "OnSpec 90c20", "on26" => "OnSpec 90c26", "pd" => "Parallel port IDE disks", "pcd" => "Parallel port CD-ROM", "pf" => "Parallel port ATAPI disk", "paride" => "Main parallel port module", ) : (), }], [ 'raid', { "linear" => "linear", "raid0" => "raid0", "raid1" => "raid1", "raid5" => "raid5", }], [ 'mouse', { arch() !~ /^sparc/ ? ( "busmouse" => "busmouse", "msbusmouse" => "msbusmouse", "serial" => "serial", "qpmouse" => "qpmouse", "atixlmouse" => "atixlmouse", "usb-uhci", "USB (uhci)", "usb-ohci", "USB (ohci)", "usb-ohci-hcd", "USB (ohci-hcd)", ) : (), }], [ 'fs', { "smbfs" => "Windows SMB", "fat" => "fat", "msdos" => "msdos", "romfs" => "romfs", "sysv" => "sysv", "ufs" => "ufs", "umsdos" => "umsdos", "vfat" => "vfat", }], [ 'other', { "st" => "st", "sg" => "sg", "ide-scsi" => "ide-scsi", "loop" => "Loopback device", "lp" => "Parallel Printer", "ide-floppy" => "ide-floppy", "ide-tape" => "ide-tape", "nbd" => "nbd", }], ); my %type_aliases = ( scsi => 'disk', ); my @skip_modules_on_stage1 = arch() =~ /alpha/ ? qw(sb1000) : (); my @drivers_fields = qw(text type); %drivers = (); foreach (@drivers_by_category) { my @l = @$_; my $l = pop @l; foreach (keys %$l) { $drivers{$_} = [ $l->{$_}, @l ]; } } while (my ($k, $v) = each %drivers) { my %l; @l{@drivers_fields} = @$v; $drivers{$k} = \%l; } 1; sub module_of_type($) { my ($type) = @_; my %skip; @skip{@skip_modules_on_stage1} = (); grep { !exists $skip{$_} } grep { $drivers{$_}{type} =~ /^($type)$/ } keys %drivers; } sub text_of_type($) { my ($type) = @_; my $alias = $type_aliases{$type}; map { $_->{text} } grep { $_->{type} eq $type || $_->{type} eq $alias } values %drivers; } sub text2driver($) { my ($text) = @_; foreach (keys %drivers) { $drivers{$_}{text} eq $text and return $_; } die "$text is not a valid module description"; } sub get_alias { my ($alias) = @_; $conf{$alias}{alias}; } sub get_options { my ($name) = @_; $conf{$name}{options}; } sub add_alias($$) { my ($alias, $name) = @_; $name =~ /ignore/ and return; /\Q$alias/ && $conf{$_}{alias} && $conf{$_}{alias} eq $name and return $_ foreach keys %conf; $alias .= $scsi++ || '' if $alias eq 'scsi_hostadapter'; log::l("adding alias $alias to $name"); $conf{$alias}{alias} ||= $name; if ($alias eq "sound" && $name =~ /^snd-card-/) { $conf{$name}{"post-install"} = "modprobe snd-pcm-oss"; } $alias; } sub remove_alias($) { my ($name) = @_; foreach (keys %conf) { $conf{$_}{alias} && $conf{$_}{alias} eq $name or next; delete $conf{$_}{alias}; return 1; } 0; } sub load { my ($name, $type, @options) = @_; if ($::testing) { log::l("i try to install $name module (@options)"); } else { $conf{$name}{loaded} and return; eval { load($_, 'prereq') } foreach @{$deps{$name}}; load_raw([ $name, @options ]); } push @{$loaded{$type}}, $name; if ($type) { add_alias('usb-interface', $name) if $type =~ /SERIAL_USB/i; if ($type eq "scsi" || $type eq $type_aliases{scsi}) { add_alias('scsi_hostadapter', $name); load("sd_mod"); } } $conf{$name}{options} = join " ", @options if @options; } sub load_multi { my $f; $f = sub { map { $f->(@{$deps{$_}}), $_ } @_ }; my %l; my @l = grep { !$conf{$_}{loaded} } grep { my $o = $l{$_}; $l{$_} = 1; !$o } $f->(@_); $::testing and log::l("i would install modules @l"), return; load_raw(map { [ $_ ] } @l); } sub unload($;$) { my ($m, $remove_alias) = @_; if ($::testing) { log::l("rmmod $m"); } else { if (run_program::run("rmmod", $m)) { delete $conf{$m}{loaded}; } } foreach (keys %loaded) { @{$loaded{$_}} = grep { $m ne $_ } @{$loaded{$_}}; } remove_alias($m) if $remove_alias; } sub load_raw { my @l = map { my ($i, @i) = @$_; [ $i, \@i ] } grep { $_->[0] !~ /ignore/ } @_; my $cz = "/lib/modules" . (arch() eq 'sparc64' && "64") . ".cz"; -e $cz or $cz .= "2"; run_program::run("extract_archive", $cz, "/tmp", map { "$_->[0].o" } @l); my @failed = grep { my $m = "/tmp/$_->[0].o"; if (-e $m && run_program::run(["insmod_", "insmod"], "-f", $m, @{$_->[1]})) { unlink $m; $conf{$_->[0]}{loaded} = 1; ''; } else { log::l("missing module $_->[0]") unless -e $m;