aboutsummaryrefslogtreecommitdiffstats
path: root/el/setupBootloaderAddEntry.html
blob: 79dace9a108f85cdbd04104846494eda850e409d (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
<html>
   <head>
      <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
   
      <title>&#928;&#961;&#959;&#963;&#952;&#942;&#954;&#951; &#942; &#949;&#960;&#949;&#958;&#949;&#961;&#947;&#945;&#963;&#943;&#945; &#956;&#953;&#945;&#962; &#954;&#945;&#964;&#945;&#967;&#974;&#961;&#951;&#963;&#951;&#962; &#963;&#964;&#959; &#956;&#949;&#957;&#959;&#973; &#917;&#954;&#954;&#943;&#957;&#951;&#963;&#951;&#962;</title>
      <meta name="generator" content="DocBook XSL Stylesheets V1.75.2">
      <link rel="home" href="index.html" title="&#917;&#947;&#954;&#945;&#964;&#940;&#963;&#964;&#945;&#963;&#951; &#956;&#949; &#964;&#959; DrakX">
      <link rel="up" href="index.html" title="&#917;&#947;&#954;&#945;&#964;&#940;&#963;&#964;&#945;&#963;&#951; &#956;&#949; &#964;&#959; DrakX">
      <link rel="prev" href="setupBootloader.html" title="&#922;&#973;&#961;&#953;&#949;&#962; &#949;&#960;&#953;&#955;&#959;&#947;&#941;&#962; &#964;&#959;&#965; &#960;&#961;&#959;&#947;&#961;&#940;&#956;&#956;&#945;&#964;&#959;&#962; &#949;&#954;&#954;&#943;&#957;&#951;&#963;&#951;&#962;">
      <link rel="next" href="misc-params.html" title="&#931;&#973;&#957;&#959;&#968;&#951; &#964;&#969;&#957; &#948;&#953;&#940;&#966;&#959;&#961;&#969;&#957; &#960;&#945;&#961;&#945;&#956;&#941;&#964;&#961;&#969;&#957;"><style xmlns="http://www.w3.org/TR/xhtml1/transitional" type="text/css">
         <!--
      body { font-family: sans-serif; font-size: 13px }
      table { font-family: sans-serif; font-size: 13px }
    --></style></head>
   <body bgcolor="white" text="black" link="#0000FF" vlink="#840084" alink="#0000FF">
      <div lang="el" class="section" title="&#928;&#961;&#959;&#963;&#952;&#942;&#954;&#951; &#942; &#949;&#960;&#949;&#958;&#949;&#961;&#947;&#945;&#963;&#943;&#945; &#956;&#953;&#945;&#962; &#954;&#945;&#964;&#945;&#967;&#974;&#961;&#951;&#963;&#951;&#962; &#963;&#964;&#959; &#956;&#949;&#957;&#959;&#973; &#917;&#954;&#954;&#943;&#957;&#951;&#963;&#951;&#962;">
         <div class="titlepage">
            <div>
               <div>
                  <h2 class="title"><a name="setupBootloaderAddEntry"></a>&#928;&#961;&#959;&#963;&#952;&#942;&#954;&#951; &#942; &#949;&#960;&#949;&#958;&#949;&#961;&#947;&#945;&#963;&#943;&#945; &#956;&#953;&#945;&#962; &#954;&#945;&#964;&#945;&#967;&#974;&#961;&#951;&#963;&#951;&#962; &#963;&#964;&#959; &#956;&#949;&#957;&#959;&#973; &#917;&#954;&#954;&#943;&#957;&#951;&#963;&#951;&#962;
                  </h2>
               </div>
            </div>
         </div>
           
         
           
         
           
         <p>&#924;&#960;&#959;&#961;&#949;&#943;&#964;&#949; &#957;&#945; &#960;&#961;&#959;&#963;&#952;&#941;&#963;&#949;&#964;&#949; &#956;&#953;&#945; &#954;&#945;&#964;&#945;&#967;&#974;&#961;&#951;&#963;&#951; &#942; &#957;&#945; &#949;&#960;&#949;&#958;&#949;&#961;&#947;&#945;&#963;&#964;&#949;&#943;&#964;&#949; &#945;&#965;&#964;&#942; &#960;&#959;&#965;
            &#949;&#960;&#953;&#955;&#941;&#958;&#945;&#964;&#949;, &#960;&#945;&#964;&#974;&#957;&#964;&#945;&#962; &#963;&#964;&#959; &#963;&#967;&#949;&#964;&#953;&#954;&#972; &#954;&#959;&#965;&#956;&#960;&#943; &#963;&#964;&#951; <span class="emphasis"><em>&#916;&#953;&#945;&#956;&#972;&#961;&#966;&#969;&#963;&#951; &#964;&#959;&#965;
                  &#960;&#961;&#959;&#947;&#961;&#940;&#956;&#956;&#945;&#964;&#959;&#962; &#949;&#954;&#954;&#943;&#957;&#951;&#963;&#951;&#962;</em></span> &#954;&#945;&#953; &#957;&#945; &#949;&#960;&#949;&#958;&#949;&#961;&#947;&#945;&#963;&#964;&#949;&#943;&#964;&#949; &#964;&#945; &#960;&#949;&#948;&#943;&#945; &#963;&#964;&#959;&#957;
            &#945;&#957;&#945;&#948;&#965;&#972;&#956;&#949;&#957;&#959; &#948;&#953;&#940;&#955;&#959;&#947;&#959;.
         </p>
         
           
         <div class="note" title="&#931;&#951;&#956;&#949;&#943;&#969;&#963;&#951;" style="margin-left: 0.5in; margin-right: 0.5in;">
            <table border="0" summary="Note">
               <tr>
                  <td rowspan="2" align="center" valign="top" width="25"><img alt="[&#931;&#951;&#956;&#949;&#943;&#969;&#963;&#951;]" src="note.png"></td>
                  <th align="left"></th>
               </tr>
               <tr>
                  <td align="left" valign="top">
                         
                     <p>&#913;&#957; &#941;&#967;&#949;&#964;&#949; &#949;&#960;&#953;&#955;&#941;&#958;&#949;&#953; <code class="code">Grub 2</code> &#969;&#962; &#960;&#961;&#972;&#947;&#961;&#945;&#956;&#956;&#945; &#949;&#954;&#954;&#943;&#957;&#951;&#963;&#951;&#962;, &#942; Grub2-efi
                        &#947;&#953;&#945; &#963;&#965;&#963;&#964;&#942;&#956;&#945;&#964;&#945; UEFI, &#948;&#949;&#957; &#956;&#960;&#959;&#961;&#949;&#943;&#964;&#949; &#957;&#945; &#967;&#961;&#951;&#963;&#953;&#956;&#959;&#960;&#959;&#953;&#942;&#963;&#949;&#964;&#949; &#945;&#965;&#964;&#972; &#964;&#959; &#949;&#961;&#947;&#945;&#955;&#949;&#943;&#959; &#947;&#953;&#945; &#964;&#951;&#957;
                        &#949;&#960;&#949;&#958;&#949;&#961;&#947;&#945;&#963;&#943;&#945; &#964;&#969;&#957; &#954;&#945;&#964;&#945;&#967;&#969;&#961;&#942;&#963;&#949;&#969;&#957; &#963;&#949; &#945;&#965;&#964;&#972; &#964;&#959; &#963;&#964;&#940;&#948;&#953;&#959;, &#960;&#945;&#964;&#942;&#963;&#964;&#949; &laquo;&#917;&#960;&#972;&#956;&#949;&#957;&#959;&raquo;. &#920;&#945;
                        &#967;&#961;&#949;&#953;&#945;&#963;&#964;&#949;&#943;&#964;&#949; &#957;&#945; &#949;&#960;&#949;&#958;&#949;&#961;&#947;&#945;&#963;&#964;&#949;&#943;&#964;&#949; &#967;&#949;&#953;&#961;&#959;&#954;&#943;&#957;&#951;&#964;&#945; &#964;&#959;
                        <code class="code">/boot/grub2/custom.cfg</code> &#942; &#967;&#961;&#951;&#963;&#953;&#956;&#959;&#960;&#959;&#953;&#942;&#963;&#964;&#949; &#964;&#959;
                        <code class="code">grub-customizer</code>.
                     </p>
                       
                  </td>
               </tr>
            </table>
         </div>
         
           
         
           
         <p>&#924;&#949;&#961;&#953;&#954;&#940; &#960;&#961;&#940;&#947;&#956;&#945;&#964;&#945; &#960;&#959;&#965; &#956;&#960;&#959;&#961;&#959;&#973;&#957; &#957;&#945; &#947;&#943;&#957;&#959;&#965;&#957; &#967;&#969;&#961;&#943;&#962; &#954;&#943;&#957;&#948;&#965;&#957;&#959;, &#949;&#943;&#957;&#945;&#953; &#951; &#945;&#955;&#955;&#945;&#947;&#942; &#964;&#951;&#962;
            &#949;&#964;&#953;&#954;&#941;&#964;&#945;&#962; &#956;&#953;&#945;&#962; &#954;&#945;&#964;&#945;&#967;&#974;&#961;&#951;&#963;&#951;&#962; &#954;&#945;&#953; &#951; &#949;&#960;&#953;&#955;&#959;&#947;&#942; &#956;&#953;&#945;&#962; &#954;&#945;&#964;&#945;&#967;&#974;&#961;&#951;&#963;&#951;&#962; &#969;&#962; &#964;&#951;&#957;
            &#960;&#961;&#959;&#954;&#945;&#952;&#959;&#961;&#953;&#963;&#956;&#941;&#957;&#951;.
         </p>
         
           
         <p>&#924;&#960;&#959;&#961;&#949;&#943;&#964;&#949; &#957;&#945; &#960;&#961;&#959;&#963;&#952;&#941;&#963;&#949;&#964;&#949; &#964;&#959;&#957; &#963;&#969;&#963;&#964;&#972; &#945;&#961;&#953;&#952;&#956;&#972; &#941;&#954;&#948;&#959;&#963;&#951;&#962; &#956;&#953;&#945;&#962; &#954;&#945;&#964;&#945;&#967;&#974;&#961;&#951;&#963;&#951;&#962;, &#942; &#957;&#945; &#964;&#951;&#957;
            &#956;&#949;&#964;&#959;&#957;&#959;&#956;&#940;&#963;&#949;&#964;&#949; &#960;&#955;&#942;&#961;&#969;&#962;.
         </p>
         
           
         <p>&#919; &#960;&#961;&#959;&#954;&#945;&#952;&#959;&#961;&#953;&#963;&#956;&#941;&#957;&#951; &#954;&#945;&#964;&#945;&#967;&#974;&#961;&#951;&#963;&#951; &#949;&#943;&#957;&#945;&#953; &#945;&#965;&#964;&#942; &#963;&#964;&#951;&#957; &#959;&#960;&#959;&#943;&#945; &#958;&#949;&#954;&#953;&#957;&#940; &#959; &#965;&#960;&#959;&#955;&#959;&#947;&#953;&#963;&#964;&#942;&#962; &#945;&#957;
            &#948;&#949;&#957; &#949;&#960;&#953;&#955;&#941;&#958;&#949;&#964;&#949; &#954;&#940;&#960;&#959;&#953;&#945; &#940;&#955;&#955;&#951; &#954;&#945;&#964;&#945;&#967;&#974;&#961;&#951;&#963;&#951; &#963;&#964;&#951;&#957; &#949;&#954;&#954;&#943;&#957;&#951;&#963;&#951;.
         </p>
         
           
         <div class="warning" title="&#928;&#961;&#959;&#949;&#953;&#948;&#959;&#960;&#959;&#943;&#951;&#963;&#951;" style="margin-left: 0.5in; margin-right: 0.5in;">
            <table border="0" summary="Warning">
               <tr>
                  <td rowspan="2" align="center" valign="top" width="25"><img alt="[&#928;&#961;&#959;&#949;&#953;&#948;&#959;&#960;&#959;&#943;&#951;&#963;&#951;]" src="warning.png"></td>
                  <th align="left"></th>
               </tr>
               <tr>
                  <td align="left" valign="top">
                         
                     <p>&#919; &#949;&#960;&#949;&#958;&#949;&#961;&#947;&#945;&#963;&#943;&#945; &#940;&#955;&#955;&#969;&#957; &#960;&#949;&#948;&#943;&#969;&#957; &#956;&#960;&#959;&#961;&#949;&#943; &#957;&#945; &#941;&#967;&#949;&#953; &#969;&#962; &#945;&#960;&#959;&#964;&#941;&#955;&#949;&#963;&#956;&#945; &#964;&#951;&#957; &#945;&#948;&#965;&#957;&#945;&#956;&#943;&#945;
                        &#949;&#954;&#954;&#943;&#957;&#951;&#963;&#951;&#962; &#964;&#959;&#965; &#963;&#965;&#963;&#964;&#942;&#956;&#945;&#964;&#972;&#962; &#963;&#945;&#962;. &#928;&#945;&#961;&#945;&#954;&#945;&#955;&#974; &#956;&#951;&#957; &#954;&#940;&#957;&#949;&#964;&#949; &#945;&#960;&#955;&#940; &#948;&#959;&#954;&#953;&#956;&#941;&#962; &#945;&#957; &#948;&#949;&#957;
                        &#947;&#957;&#969;&#961;&#943;&#950;&#949;&#964;&#949; &#964;&#953; &#945;&#954;&#961;&#953;&#946;&#974;&#962; &#954;&#940;&#957;&#949;&#964;&#949;.
                     </p>
                       
                  </td>
               </tr>
            </table>
         </div>
         
      </div>
   </body>
</html>
#n704'>704 705 706 707 708 709 710 711 712 713 714 715 716 717 718 719 720 721 722 723 724 725 726 727 728 729 730 731 732 733 734 735 736 737 738 739 740 741 742 743 744 745 746 747 748 749 750 751 752 753 754 755 756 757 758 759 760 761 762 763 764 765 766 767 768 769 770 771 772 773 774 775 776 777 778 779 780 781 782 783 784 785 786 787 788 789 790 791 792 793 794 795 796 797 798 799
package fsedit; # $Id$

use diagnostics;
use strict;
use vars qw(%suggestions);

#-######################################################################################
#- misc imports
#-######################################################################################
use common;
use partition_table qw(:types);
use partition_table::raw;
use detect_devices;
use fsedit;
use devices;
use loopback;
use log;
use fs;

%suggestions = (
  N_("simple") => [
    { mntpoint => "/",     size => 300 << 11, type =>0x483, ratio => 5, maxsize => 5500 << 11 },
    { mntpoint => "swap",  size =>  64 << 11, type => 0x82, ratio => 1, maxsize =>  250 << 11 },
    { mntpoint => "/home", size => 300 << 11, type =>0x483, ratio => 3 },
  ], N_("with /usr") => [
    { mntpoint => "/",     size => 150 << 11, type =>0x483, ratio => 1, maxsize => 1000 << 11 },
    { mntpoint => "swap",  size =>  64 << 11, type => 0x82, ratio => 1, maxsize =>  250 << 11 },
    { mntpoint => "/usr",  size => 300 << 11, type =>0x483, ratio => 4, maxsize => 4000 << 11 },
    { mntpoint => "/home", size => 100 << 11, type =>0x483, ratio => 3 },
  ], N_("server") => [
    { mntpoint => "/",     size => 150 << 11, type =>0x483, ratio => 1, maxsize =>  250 << 11 },
    { mntpoint => "swap",  size =>  64 << 11, type => 0x82, ratio => 2, maxsize =>  400 << 11 },
    { mntpoint => "/usr",  size => 300 << 11, type =>0x483, ratio => 4, maxsize => 4000 << 11 },
    { mntpoint => "/var",  size => 150 << 11, type =>0x483, ratio => 3 },
    { mntpoint => "/home", size => 150 << 11, type =>0x483, ratio => 3 },
    { mntpoint => "/tmp",  size => 150 << 11, type =>0x483, ratio => 2, maxsize =>  500 << 11 },
  ],
);
foreach (values %suggestions) {
    if (arch() =~ /ia64/) {
	@$_ = ({ mntpoint => "/boot/efi", size => 50 << 11, type => 0xb, ratio => 1, maxsize => 150 << 11 }, @$_);
    }
}

my @suggestions_mntpoints = (
    "/var/ftp", "/var/www", "/boot",
    arch() =~ /sparc/ ? "/mnt/sunos" : arch() =~ /ppc/ ? "/mnt/macos" : "/mnt/windows",
    #- RedHat also has /usr/local and /opt
);

my @partitions_signatures = (
    [ 0x8e, 0, "HM\1\0" ],
    [ 0x83, 0x438, "\x53\xEF" ],
    [ 0x183, 0x10034, "ReIsErFs" ],
    [ 0x183, 0x10034, "ReIsEr2Fs" ],
    [ 0x283, 0, 'XFSB', 0x200, 'XAGF', 0x400, 'XAGI' ],
    [ 0x383, 0x8000, 'JFS1' ],
    [ 0x82, 4086, "SWAP-SPACE" ],
    [ 0x82, 4086, "SWAPSPACE2" ],
    [ 0x7,  0x1FE, "\x55\xAA", 0x3, "NTFS" ],
    [ 0xc,  0x1FE, "\x55\xAA", 0x52, "FAT32" ],
arch() !~ /^sparc/ ? (
    [ 0x6,  0x1FE, "\x55\xAA", 0x36, "FAT" ],
) : (),
);

sub typeOfPart { 
    my $dev = devices::make($_[0]);
    my $t = typeFromMagic($dev, @partitions_signatures);
    if ($t == 0x83) {
	#- there is no magic to differentiate ext3 and ext2. Using libext2fs
	#- to check if it has a journal
	$t = 0x483 if c::is_ext3($dev);
    }
    $t;
}

#-######################################################################################
#- Functions
#-######################################################################################
sub empty_all_hds {
    { hds => [], lvms => [], raids => [], loopbacks => [], raw_hds => [], nfss => [], smbs => [], davs => [], special => [] };
}
sub recompute_loopbacks {
    my ($all_hds) = @_;
    my @fstab = get_all_fstab($all_hds);
    @{$all_hds->{loopbacks}} = map { isPartOfLoopback($_) ? @{$_->{loopback}} : () } @fstab;
}

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

    my @parts = get_fstab(@$hds);
    {
	my @l = grep { isRawRAID($_) } @parts or return [];
	detect_devices::raidAutoStart(@l);
    }

    fs::get_major_minor(@parts);
    my %devname2part = map { $_->{dev} => { %$_, device => $_->{dev} } } read_proc_partitions_raw();

    my @raids;
    my @mdstat = cat_("/proc/mdstat");
    for (my $i = 0; $i < @mdstat; $i++) {

	my ($nb, $level, $mdparts) = 
	  #- line format is:
	  #- md%d : {in}?active{ (read-only)}? {linear|raid1|raid4|raid5}{ DEVNAME[%d]{(F)}?}*
	  $mdstat[$i] =~ /^md(.).* ([^ \[\]]+) (\S+\[\d+\].*)/ or next;

	$level =~ s/raid//; #- { linear | raid0 | raid1 | raid5 } -> { linear | 0 | 1 | 5 }

	my $chunks = $mdstat[$i+1] =~ /(\S+) chunks/ ? $1 : "64k";

	my @raw_mdparts = map { /([^\[]+)/ } split ' ', $mdparts;
	my @mdparts = 
	  map { 
	      my $mdpart = $devname2part{$_} || { device => $_ };
	      if (my ($part) = grep { is_same_hd($mdpart, $_) } @parts) {
		  $part->{raid} = $nb;
		  delete $part->{mntpoint};
		  $part;
	      } else {
		  #- forget it when not found? that way it won't break much... beurk.
		  ();
	      }
	  } @raw_mdparts;

	my $type = typeOfPart("md$nb");
	log::l("RAID: found md$nb (raid $level) chunks $chunks ", if_($type, "type $type "), "with parts ", join(", ", @raw_mdparts));
	$raids[$nb] = { 'chunk-size' => $chunks, type => $type || 0x83, disks => \@mdparts,
			device => "md$nb", notFormatted => !$type, level => $level };
    }
    require raid;
    raid::update(@raids);
    \@raids;
}

sub lvms {
    my ($all_hds) = @_;
    my @pvs = grep { isRawLVM($_) } get_all_fstab($all_hds) or return;

    #- otherwise vgscan won't find them
    devices::make($_->{device}) foreach @pvs; 
    require lvm;

    my @lvms;
    foreach (@pvs) {
	my $name = lvm::get_vg($_) or next;
	my ($lvm) = grep { $_->{VG_name} eq $name } @lvms;
	if (!$lvm) {
	    $lvm = bless { disks => [], VG_name => $name }, 'lvm';
	    lvm::update_size($lvm);
	    lvm::get_lvs($lvm);
	    push @lvms, $lvm;
	}
	$_->{lvm} = $name;
	push @{$lvm->{disks}}, $_;
    }
    @lvms;
}

sub hds {
    my ($flags, $ask_before_blanking) = @_;
    $flags ||= {};
    $flags->{readonly} && ($flags->{clearall} || $flags->{clear}) and die "conflicting flags readonly and clear/clearall";

    my @drives = detect_devices::hds();

    my (@hds);
    foreach my $hd (@drives) {
	$hd->{file} = devices::make($hd->{device});
	$hd->{prefix} ||= $hd->{device};
	$hd->{readonly} = $flags->{readonly};

	my $h = partition_table::raw::get_geometry($hd->{file}) or log::l("An error occurred while getting the geometry of block device $hd->{file}: $!"), next;
	add2hash_($hd, $h);

	eval { partition_table::raw::test_for_bad_drives($hd) if $::isInstall };
	if (my $err = $@) {
	    if ($err =~ /write error:/) { 
		$hd->{readonly} = 1;
	    } else {
		cdie $err if $err !~ /read error:/;
		next;
	    }
	}

	if ($flags->{clearall} || member($hd->{device}, @{$flags->{clear} || []})) {
	    partition_table::raw::zero_MBR_and_dirty($hd);
	} else {
	    eval { 
		partition_table::read($hd); 
		compare_with_proc_partitions($hd) if $::isInstall;
	    };
	    if (my $err = $@) {
		if ($hd->{readonly}) {
		    use_proc_partitions($hd);
		} elsif ($ask_before_blanking && $ask_before_blanking->($hd->{device}, $err)) {
		    partition_table::raw::zero_MBR($hd);
		} else {
		    #- using it readonly
		    use_proc_partitions($hd);
		}
	    }
	    member($_->{device}, @{$flags->{clear} || []}) and partition_table::remove($hd, $_)
	      foreach partition_table::get_normal_parts($hd);
	}

	# special case for Various type
	$_->{type} = typeOfPart($_->{device}) || 0x100 foreach grep { $_->{type} == 0x100 } partition_table::get_normal_parts($hd);

	#- special case for type overloading (eg: reiserfs is 0x183)
	foreach (grep { isExt2($_) } partition_table::get_normal_parts($hd)) {
	    my $type = typeOfPart($_->{device});
	    $_->{type} = $type if $type > 0x100 || $type && $hd->isa('partition_table::gpt');
	}
	push @hds, $hd;
    }

    #- detect raids before LVM allowing LVM on raid
    my $raids = raids(\@hds);
    my $all_hds = { %{ empty_all_hds() }, hds => \@hds, lvms => [], raids => $raids };

    $all_hds->{lvms} = [ lvms($all_hds) ];

    fs::get_major_minor(get_all_fstab($all_hds));

    $all_hds;
}

sub get_hds {
    #- $in is optional
    my ($flags, $in) = @_;

    if ($in) {
	catch_cdie { hds($flags, sub {
	    my ($dev, $err) = @_;
            $in->ask_yesorno(N("Error"), 
N("I can't read the partition table of device %s, it's too corrupted for me :(
I can try to go on, erasing over bad partitions (ALL DATA will be lost!).
The other solution is to not allow DrakX to modify the partition table.
(the error is %s)

Do you agree to loose all the partitions?
", $dev, formatError($err)));
        }) } sub { $in->ask_okcancel('', formatError($@)) };
    } else {
	catch_cdie { hds($flags) } sub { 1 }
    }
}

sub read_proc_partitions_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_proc_partitions {
    my ($hds) = @_;

    my @all = read_proc_partitions_raw();
    my @parts = grep { $_->{dev} =~ /\d$/ } @all;
    my @disks = grep { $_->{dev} !~ /\d$/ } @all;

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

    my %devfs2normal = map {
	my (undef, $major, $minor) = devices::entry($_->{device});
	my ($disk) = grep { $_->{major} == $major && $_->{minor} == $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};
	    foreach my $hd (@$hds) {
		$part->{rootDevice} = $hd->{device} if $part->{dev} =~ /^$hd->{device}./;
	    }
	}
	$part->{device} = $dev;
	$part->{size} *= 2;	# from KB to sectors
	$part->{type} = typeOfPart($dev); 
	$part->{start} = $prev_part ? $prev_part->{start} + $prev_part->{size} : 0;
	$prev_part = $part;
	delete $part->{dev}; # cleanup
    }
    @parts;
}

sub all_hds {
    my ($all_hds) = @_;
    (@{$all_hds->{hds}}, @{$all_hds->{lvms}});
}
sub part2hd {
    my ($part, $all_hds) = @_;
    my ($hd) = grep { $part->{rootDevice} eq ($_->{device} || $_->{VG_name}) } all_hds($all_hds);
    $hd;
}

sub is_same_hd {
    my ($hd1, $hd2) = @_;
    if ($hd1->{major} && $hd2->{major}) {
	$hd1->{major} == $hd2->{major} && $hd1->{minor} == $hd2->{minor};
    } elsif (my ($s1) = $hd1->{device} =~ m|https?://(.+?)/*$|) {
	my ($s2) = $hd2->{device} =~ m|https?://(.+?)/*$|;
	$s1 eq $s2;
    } else {
	$hd1->{device} eq $hd2->{device};
    }
}

sub is_same_part {
    my ($part1, $part2) = @_;
    foreach ('start', 'size', 'type', 'rootDevice') {
	$part1->{$_} eq $part2->{$_} or return;
    }
    1;
}

#- get all normal partition including special ones as found on sparc.
sub get_fstab {
    map { partition_table::get_normal_parts($_) } @_;
}

#- get normal partition that should be visible for working on.
sub get_visible_fstab {
    grep { $_ && !partition_table::isWholedisk($_) && !partition_table::isHiddenMacPart($_) }
      map { partition_table::get_normal_parts($_) } @_;
}

sub get_fstab_and_holes {
    map {
	if (isLVM($_)) {
	    my @parts = partition_table::get_normal_parts($_);
	    my $free = $_->{totalsectors} - sum map { $_->{size} } @parts;
	    my $free_part = { start => 0, size => $free, type => 0, rootDevice => $_->{VG_name} };
	    @parts, if_($free >= $_->cylinder_size, $free_part);
	} else {
	    partition_table::get_normal_parts_and_holes($_);
	}
    } @_;
}
sub get_holes {
    grep { $_->{type} == 0 } get_fstab_and_holes(@_);
}

sub get_all_fstab {
    my ($all_hds) = @_;
    my @parts = map { partition_table::get_normal_parts($_) } all_hds($all_hds);
    my @raids = grep { $_ } @{$all_hds->{raids}};
    @parts, @raids, @{$all_hds->{loopbacks}};
}
sub get_really_all_fstab {
    my ($all_hds) = @_;
    my @parts = map { partition_table::get_normal_parts($_) } all_hds($all_hds);
    my @raids = grep { $_ } @{$all_hds->{raids}};
    @parts, @raids, @{$all_hds->{loopbacks}}, @{$all_hds->{raw_hds}}, @{$all_hds->{nfss}}, @{$all_hds->{smbs}}, @{$all_hds->{davs}};
}
sub get_all_fstab_and_holes {
    my ($all_hds) = @_;
    my @raids = grep { $_ } @{$all_hds->{raids}};
    get_fstab_and_holes(all_hds($all_hds)), @raids, @{$all_hds->{loopbacks}};
}
sub get_all_holes {
    my ($all_hds) = @_;
    grep { $_->{type} == 0 } get_all_fstab_and_holes($all_hds);
}

sub all_free_space {
    my ($all_hds) = @_;
    sum map { $_->{size} } get_all_holes($all_hds);
}
sub free_space {
    sum map { $_->{size} } get_holes(@_);
}

sub is_one_big_fat {
    my ($hds) = @_;
    @$hds == 1 or return;

    my @l = get_fstab(@$hds);
    @l == 1 && isFat($l[0]) && free_space(@$hds) < 10 << 11;
}

sub file2part {
    my ($fstab, $file, $keep_simple_symlinks) = @_;    
    my $part;

    $file = $keep_simple_symlinks ? common::expand_symlinks_but_simple("$::prefix$file") : expand_symlinks("$::prefix$file");
    unless ($file =~ s/^$::prefix//) {
	my ($part) = grep { loopback::carryRootLoopback($_) } @$fstab or die;
	log::l("found $part->{mntpoint}");
	$file =~ s|/initrd/loopfs|$part->{mntpoint}|;
    }
    foreach (@$fstab) {
	my $m = $_->{mntpoint};
	$part = $_ if 
	  $file =~ /^\Q$m/ && 
	    (!$part || length $part->{mntpoint} < length $m);
    }
    $part or die "file2part: not found $file";