summaryrefslogtreecommitdiffstats
path: root/perl-install/fs/proc_partitions.pm
blob: 1d40840f5bfbac1052e7d150e04198569bbd9c02 (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
package fs::proc_partitions; # $Id$

use common;


sub read_raw() {
    my (undef, undef, @all) = cat_("/proc/partitions");
    grep {
	$_->{size} != 1 &&	  # skip main extended partition
	$_->{size} != 0x3fffffff; # skip cdroms (otherwise stops cd-audios)
    } map { 
	my %l; 
	@l{qw(major minor size dev)} = split; 
	\%l;
    } @all;
}

sub read {
    my ($hds) = @_;

    my @all = read_raw();
    my ($parts, $disks) = partition { $_->{dev} =~ /\d$/ && $_->{dev} !~ /^(sr|scd)/ } @all;

    my $devfs_like = any { $_->{dev} =~ m|/disc$| } @$disks;

    fs::get_major_minor($hds);

    my %devfs2normal = map {
	my $hd = $_;
	my $disk = find { $_->{major} == $hd->{major} && $_->{minor} == $hd->{minor} } @$disks;
	$disk->{dev} => $_->{device};
    } @$hds;

    my $prev_part;
    foreach my $part (@$parts) {
	my $dev;
	if ($devfs_like) {
	    $dev = -e "/dev/$part->{dev}" ? $part->{dev} : sprintf("0x%x%02x", $part->{major}, $part->{minor});
	    $part->{rootDevice} = $devfs2normal{dirname($part->{dev}) . '/disc'};
	} else {
	    $dev = $part->{dev};
	    if (my $hd = find { $part->{dev} =~ /^\Q$_->{device}\E./ } @$hds) {
		put_in_hash($part, partition_table::hd2minimal_part($hd));
	    }
	}
	undef $prev_part if $prev_part && ($prev_part->{rootDevice} || '') ne ($part->{rootDevice} || '');

	$part->{device} = $dev;
	$part->{size} *= 2;	# from KB to sectors
	$part->{start} = $prev_part ? $prev_part->{start} + $prev_part->{size} : 0;
	require fs::type;
	put_in_hash($part, fs::type::type_subpart_from_magic($part));
	$prev_part = $part;
	delete $part->{dev}; # cleanup
    }
    @$parts;
}

sub compare {
    my ($hd) = @_;

    $hd->{bus} =~ /^dm_/ and log::l("skipping /proc/partititions check for dmraid $hd->{device}"), return;

    my @l1 = partition_table::get_normal_parts($hd);
    my @l2 = grep { $_->{rootDevice} eq $hd->{device} } &read([$hd]);

    #- /proc/partitions includes partition with type "empty" and a non-null size
    #- so add them for comparison
    my ($len1, $len2) = (int(@l1) + $hd->{primary}{nb_special_empty}, int(@l2));

    if ($len1 != $len2 && arch() ne 'ppc') {
	die sprintf(
		    "/proc/partitions does not agree with drakx %d != %d:\n%s\n", $len1, $len2,
		    "/proc/partitions: " . join(", ", map { "$_->{device} ($_->{rootDevice})" } @l2));
    }
    $len2;
}

sub use_ {
    my ($hd) = @_;
    
    partition_table::raw::zero_MBR($hd);
    $hd->{readonly} = 1;
    $hd->{getting_rid_of_readonly_allowed} = 1;
    $hd->{primary} = { normal => [ grep { $_->{rootDevice} eq $hd->{device} } &read([$hd]) ] };
}

1;