summaryrefslogtreecommitdiffstats
path: root/perl-install/mouse.pm
Commit message (Collapse)AuthorAgeFilesLines
* detection defaults on automatic choicesPascal Rigaux2004-02-171-2/+3
|
* fix mouse detect() on kernel 2.4Pascal Rigaux2004-02-171-1/+3
|
* more cleanupPascal Rigaux2004-02-121-8/+9
|
* new 'Universal|Any PS/2 & USB mice' mouse name usable with kernel 2.6Pascal Rigaux2004-02-121-14/+23
|
* rename mouseconfig() with detect_serial() which is what it really does!Pascal Rigaux2004-02-121-2/+2
|
* create probe_wacom_devices() and cleanupPascal Rigaux2004-02-121-13/+14
|
* cleanupPascal Rigaux2004-02-121-1/+1
|
* cleanupPascal Rigaux2004-02-121-8/+10
|
* remove deprecated commentPascal Rigaux2004-02-121-2/+1
|
* always use fast_mouse_probe (probing serial is now mostly deprecated, and itPascal Rigaux2004-02-121-10/+2
| | | | | is *re-done* by drakconnect, so no need to do it soon)
* cleanup wacom detectionPascal Rigaux2004-02-121-6/+3
|
* move Xtest() and setMouseLive() out of c/stuff to xf86misc::mainPascal Rigaux2004-02-081-1/+4
| | | | | | so that we can use them (esp. setMouseLive) in standalone without making drakxtools-newt require xfree libs
* - add change_mouse_live()Pascal Rigaux2004-02-061-1/+18
| | | | | - use /dev/mouse in XF86Config to allow changing protocol in standalone
* use protocol "ExplorerPS/2" instead of "auto" for kernel 2.6Pascal Rigaux2004-02-041-1/+1
| | | | | | (not statisfying since people booting with kernel 2.4 will not get a working mouse, but at least we can test if this really works nicely for 2.6)
* write_conf() doesn't need $prefix anymorePascal Rigaux2004-01-051-1/+1
|
* add new mouse "PS/2|Automatic" and use it by default,Pascal Rigaux2003-11-251-3/+4
| | | | | | so that "PS/2|Generic PS2 Wheel Mouse" use protocol IMPS/2 which is needed when we force mouse change live ("auto" doesn't work in that case)
* - use "auto" for ps/2Pascal Rigaux2003-11-201-2/+2
| | | | | - allow using same config for ps/2 and imps/2
* perl checker should have told us?Guillaume Cottenceau2003-11-191-1/+1
|
* use fast_mouse_probe first in mandrake movePascal Rigaux2003-10-231-2/+2
|
* cleanupPascal Rigaux2003-09-291-1/+0
|
* fixed the fix of fpons trick...Francois Pons2003-09-101-1/+1
|
* fixed the fpons trick (which was false moreover)Francois Pons2003-09-101-1/+1
|
* added load_modules to load mouse module according to configuration.Francois Pons2003-09-101-0/+15
|
* write "MOVE YOUR WHEEL!" only for ps2 micePascal Rigaux2003-09-091-1/+1
|
* - much cleanup in test_mouse()Pascal Rigaux2003-09-031-36/+47
| | | | | - new images for mouse test (thanks to Jerome Villette)
* added emulate wheel support (a bit hacky though) (bug 3976)Francois Pons2003-08-201-1/+9
|
* full pci probe does not freeze anymore, removing code work-arounding the freezePascal Rigaux2003-08-191-13/+0
|
* switch from gtk2-perl to gtk2-perl-xsThierry Vignaud2003-07-091-3/+2
|
* perl_checker adaptations + fixesPascal Rigaux2003-04-241-4/+4
|
* new perl_checker compliancePascal Rigaux2003-04-171-6/+6
|
* prevent warning when using diagnostics pragma (easier debugging)Thierry Vignaud2003-03-051-1/+1
|
* Mouse button emulation. Clarify L-Command, add Enter. (Ben Reser)Stew Benedict2003-02-131-1/+2
|
* (detect): cleanup the value returned when only a wacom is foundPascal Rigaux2003-01-311-5/+1
|
* fix missing pointer_ungrab so that after testing mouse duringGuillaume Cottenceau2003-01-271-1/+3
| | | | | install we can move the mouse pointer everywhere
* remove blinks in mouse testGuillaume Cottenceau2003-01-241-4/+7
|
* - don't setMouseLive when the protocol hasn't changedPascal Rigaux2003-01-241-6/+7
| | | | | | - don't say "MOVE YOUR WHEEL" when there is no wheel and the protocol hasn't changed (nb: no wheel + IMPS/2 can now happen for usb mice)
* - switch "<= 3 buttons usb mice" from X protocol PS/2 to IMPS/2 (it worksPascal Rigaux2003-01-241-4/+4
| | | | | | | | | nicely, and redhat do so) - default usb mice to USB|Wheel instead of USB|Generic, since most (all?) usb mice have a wheel (i tested on 1 button mac mouse, it works nicely with ZAxisMapping and IMPS/2)
* fix absence of scroll up and scroll down in mouse testGuillaume Cottenceau2003-01-211-13/+12
|
* fix gtk+-2 portThierry Vignaud2003-01-201-3/+3
|
* image in CVS is 3b+, not 3bpGuillaume Cottenceau2002-12-201-2/+2
|
* really drop update_type_namePascal Rigaux2002-12-161-16/+0
|
* remove unused variables or rename them with an underscore (eg: $o becomes $_o)Pascal Rigaux2002-12-041-5/+5
|
* gtk2Guillaume Cottenceau2002-12-031-87/+57
|
* use output_with_perm()Pascal Rigaux2002-12-021-4/+2
|
* perl_checker adaptationsPascal Rigaux2002-11-271-7/+9
|
* incorporate 8.2 HP fixes back in cooker.Francois Pons2002-11-221-1/+7
|
* perldoc: explain basic usage of mouse.pm, regardingThierry Vignaud2002-11-191-0/+38
| | | | | | problems that show up in early interaction between harddrake::data and mouse
* add/remove spaces to make perl_checker happyPascal Rigaux2002-11-131-8/+8
|
* add or remove spaces where need to please perl_checkerPascal Rigaux2002-11-111-1/+1
|
* replace "_" with "N" and "__" with "N_"Pascal Rigaux2002-11-061-37/+37
| | | | | | | | | | | | | | | | | | | rationale: - currently, we use _("xxx") as a shorthand for gettext("xxx"). It also used to call xgettext with --keyword=_ - alas, function &_ is global and not by package (notice esp. that _ is not exported in common.pm) - this lead to big ugly pb with packages defining their own &_, overriding common.pm's &_ - a fix is to set @::textdomains to add a new domain (the default being "libDrakX") but relying on the global "_" is still dangerous!
>=> "swap", size => 64 << 11, type => 0x82, ratio => 1, maxsize => 500 << 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 => 800 << 11 }, { mntpoint => "swap", size => 64 << 11, type => 0x82, ratio => 2, maxsize => 800 << 11 }, { mntpoint => "/usr", size => 300 << 11, type =>0x483, ratio => 4, maxsize => 4000 << 11 }, { mntpoint => "/var", size => 200 << 11, type =>0x483, ratio => 3 }, { mntpoint => "/home", size => 150 << 11, type =>0x483, ratio => 3 }, { mntpoint => "/tmp", size => 150 << 11, type =>0x483, ratio => 2, maxsize => 1000 << 11 }, ], ); foreach (values %suggestions) { if (arch() =~ /ia64/) { @$_ = ({ mntpoint => "/boot/efi", size => 50 << 11, type => 0xef, 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" ], [ 0x107, 0x1FE, "\x55\xAA", 0x3, "NTFS" ], [ 0xc, 0x1FE, "\x55\xAA", 0x52, "FAT32" ], if_(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 @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(\d+).* ([^ \[\]]+) (\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 $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, raw_mdparts => \@raw_mdparts, device => "md$nb", notFormatted => !$type, level => $level }; } my %devname2part = map { $_->{dev} => { %$_, device => $_->{dev} } } devices::read_proc_partitions_raw(); each_index { my $raw_mdparts = delete $_->{raw_mdparts}; my @mdparts = map { my $mdpart = $devname2part{$_} || { device => $_ }; if (my $part = find { is_same_hd($mdpart, $_) } @parts, @raids) { $part->{raid} = $::i; $part->{type} = 0xfd; delete $part->{mntpoint}; $part; } else { #- forget it when not found? that way it won't break much... beurk. (); } } @$raw_mdparts; $_->{disks} = \@mdparts; } @raids; 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 = find { $_->{VG_name} eq $name } @lvms; if (!$lvm) { $lvm = new lvm($name); lvm::update_size($lvm); lvm::get_lvs($lvm); push @lvms, $lvm; } $_->{lvm} = $name; push @{$lvm->{disks}}, $_; } @lvms; } sub hds { my ($flags, $o_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, @raw_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 (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}) { log::l("using /proc/partitions since diskdrake failed :("); use_proc_partitions($hd); } elsif (exists $hd->{usb_description} && ($hd->{type} ||= typeOfPart($hd->{device}))) { push @raw_hds, $hd; next; } elsif ($o_ask_before_blanking && $o_ask_before_blanking->($hd->{device}, $err)) { partition_table::raw::zero_MBR($hd); } else { #- using it readonly log::l("using /proc/partitions since diskdrake failed :("); 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($_) || $_->{type} == 0x7 || $_->{type} == 0x17 } partition_table::get_normal_parts($hd)) { my $wanted_type = $_->{type} == 0x17 ? 0x7 : $_->{type}; my $type = typeOfPart($_->{device}); $_->{type} = $type if ($type & 0xff) == $wanted_type || $type && $hd->isa('partition_table::gpt'); } foreach (partition_table::get_normal_parts($hd)) { my $label = member(type2fs($_), qw(ext2 ext3)) ? c::get_ext2_label(devices::make($_->{device})) : ''; $_->{device_LABEL} = $label if $label; } push @hds, $hd; } #- detect raids before LVM allowing LVM on raid my $raids = raids(\@hds); my $all_hds = { %{ empty_all_hds() }, hds => \@hds, raw_hds => \@raw_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, $o_in) = @_; if ($o_in) { catch_cdie { hds($flags, sub { my ($dev, $err) = @_; $o_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 lose all the partitions? ", $dev, formatError($err))); }) } sub { $o_in->ask_okcancel('', formatError($@)) }; } else { catch_cdie { hds($flags) } sub { 1 } } } sub read_proc_partitions { my ($hds) = @_; my @all = devices::read_proc_partitions_raw(); my ($parts, $disks) = partition { $_->{dev} =~ /\d$/ && $_->{dev} !~ /^(sr|scd)/ } @all; my $devfs_like = any { $_->{dev} =~ m|/disc$| } @$disks; my %devfs2normal = map { my (undef, $major, $minor) = devices::entry($_->{device}); my $disk = find { $_->{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}; if (my $hd = find { $part->{dev} =~ /^$_->{device}./ } @$hds) { $part->{rootDevice} = $hd->{device}; } } undef $prev_part if $prev_part && ($prev_part->{rootDevice} || '') ne ($part->{rootDevice} || ''); $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 = find { $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->{devfs_device} && $hd2->{devfs_device} && $hd1->{devfs_device} eq $hd2->{devfs_device} || $hd1->{device_LABEL} && $hd2->{device_LABEL} && $hd1->{device_LABEL} eq $hd2->{device_LABEL} || $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_or_NT { my ($hds) = @_; @$hds == 1 or return; my @l = get_fstab(@$hds); @l == 1 && isFat_or_NTFS($l[0]) && free_space(@$hds) < 10 << 11; } sub file2part { my ($fstab, $file, $b_keep_simple_symlinks) = @_; my $part; $file = $b_keep_simple_symlinks ? common::expand_symlinks_but_simple("$::prefix$file") : expand_symlinks("$::prefix$file"); unless ($file =~ s/^$::prefix//) { my $part = find { 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"; $file =~ s|$part->{mntpoint}/?|/|; ($part, $file); } sub computeSize { my ($part, $best, $all_hds, $suggestions) = @_; my $max = $part->{maxsize} || $part->{size}; return min($max, $best->{size}) unless $best->{ratio}; my $free_space = all_free_space($all_hds); my @l = my @L = grep { if ($free_space >= $_->{size}) { $free_space -= $_->{size}; 1; } else { 0 } } @$suggestions; my $cylinder_size_maxsize_adjusted; my $tot_ratios = 0; while (1) { my $old_free_space = $free_space; my $old_tot_ratios = $tot_ratios; $tot_ratios = sum(map { $_->{ratio} } @l); last if $tot_ratios == $old_tot_ratios; @l = grep { if ($_->{ratio} && $_->{maxsize} && $tot_ratios && $_->{size} + $_->{ratio} / $tot_ratios * $old_free_space >= $_->{maxsize}) { return min($max, $best->{maxsize}) if $best->{mntpoint} eq $_->{mntpoint}; $free_space -= $_->{maxsize} - $_->{size}; if (!$cylinder_size_maxsize_adjusted++) { eval { $free_space += part2hd($part, $all_hds)->cylinder_size - 1 }; } 0; } else { $_->{ratio}; } } @l; } my $size = int min($max, $best->{size} + $free_space * ($tot_ratios && $best->{ratio} / $tot_ratios)); #- verify other entry can fill the hole (any { $_->{size} < $max - $size } @L) ? $size : $max; } sub suggest_part { my ($part, $all_hds, $o_suggestions) = @_; my $suggestions = $o_suggestions || $suggestions{server} || $suggestions{simple}; my $has_swap = any { isSwap($_) } get_all_fstab($all_hds); my @local_suggestions = grep { !has_mntpoint($_->{mntpoint}, $all_hds) || isSwap($_) && !$has_swap } grep { !$_->{hd} || $_->{hd} eq $part->{rootDevice} } @$suggestions; my ($best) = grep { !$_->{maxsize} || $part->{size} <= $_->{maxsize} } grep { $_->{size} <= ($part->{maxsize} || $part->{size}) } grep { !$part->{type} || $part->{type} == $_->{type} || isTrueFS($part) && isTrueFS($_) } @local_suggestions; defined $best or return; #- sorry no suggestion :( $part->{mntpoint} = $best->{mntpoint}; $part->{type} = $best->{type} if !(isTrueFS($best) && isTrueFS($part)); $part->{size} = computeSize($part, $best, $all_hds, \@local_suggestions); foreach ('options', 'lv_name', 'encrypt_key') { $part->{$_} = $best->{$_} if $best->{$_}; } 1; } sub suggestions_mntpoint { my ($all_hds) = @_; sort grep { !/swap/ && !has_mntpoint($_, $all_hds) } (@suggestions_mntpoints, map { $_->{mntpoint} } @{$suggestions{server} || $suggestions{simple}}); } sub mntpoint2part { my ($mntpoint, $fstab) = @_; find { $mntpoint eq $_->{mntpoint} } @$fstab; } sub has_mntpoint { my ($mntpoint, $all_hds) = @_; mntpoint2part($mntpoint, [ get_really_all_fstab($all_hds) ]); } sub get_root_ { my ($fstab, $o_boot) = @_; $o_boot && mntpoint2part("/boot", $fstab) || mntpoint2part("/", $fstab); } sub get_root { &get_root_ || {} } #- do this before modifying $part->{type} sub check_type { my ($type, $_hd, $part) = @_; isThisFs("jfs", { type => $type }) && $part->{size} < 16 << 11 and die N("You can't use JFS for partitions smaller than 16MB"); isThisFs("reiserfs", { type => $type }) && $part->{size} < 32 << 11 and die N("You can't use ReiserFS for partitions smaller than 32MB"); } sub package_needed_for_partition_type { my ($part) = @_; my %l = ( reiserfs => 'reiserfsprogs', xfs => 'xfsprogs', jfs => 'jfsprogs', ); $l{type2fs($part)}; } #- you can do this before modifying $part->{mntpoint} #- so $part->{mntpoint} should not be used here, use $mntpoint instead sub check_mntpoint { my ($mntpoint, $hd, $part, $all_hds) = @_; $mntpoint eq '' || isSwap($part) || isNonMountable($part) and return; $mntpoint =~ m|^/| or die N("Mount points must begin with a leading /"); $mntpoint =~ m|[\x7f-\xff]| and cdie N("Mount points should contain only alphanumerical characters"); mntpoint2part($mntpoint, [ grep { $_ ne $part } get_really_all_fstab($all_hds) ]) and die N("There is already a partition with mount point %s\n", $mntpoint); cdie N("You've selected a software RAID partition as root (/). No bootloader is able to handle this without a /boot partition. Please be sure to add a /boot partition") if $mntpoint eq "/" && isRAID($part) && !has_mntpoint("/boot", $all_hds); die N("You can't use a LVM Logical Volume for mount point %s", $mntpoint) if $mntpoint eq '/boot' && isLVM($hd); cdie N("You've selected a LVM Logical Volume as root (/). The bootloader is not able to handle this without a /boot partition. Please be sure to add a /boot partition") if $mntpoint eq "/" && isLVM($part) && !has_mntpoint("/boot", $all_hds); cdie N("You may not be able to install lilo (since lilo doesn't handle a LV on multiple PVs)") if 0; # arch() =~ /i.86/ && $mntpoint eq '/' && isLVM($hd) && @{$hd->{disks} || []} > 1; cdie N("This directory should remain within the root filesystem") if member($mntpoint, qw(/root)); die N("This directory should remain within the root filesystem") if member($mntpoint, qw(/bin /dev /etc /lib /sbin /mnt)); die N("You need a true filesystem (ext2/ext3, reiserfs, xfs, or jfs) for this mount point\n") if !isTrueLocalFS($part) && $mntpoint eq '/'; die N("You need a true filesystem (ext2/ext3, reiserfs, xfs, or jfs) for this mount point\n") if !isTrueFS($part) && member($mntpoint, qw(/home /tmp /usr /var)); die N("You can't use an encrypted file system for mount point %s", $mntpoint) if $part->{options} =~ /encrypted/ && member($mntpoint, qw(/ /usr /var /boot)); local $part->{mntpoint} = $mntpoint; loopback::check_circular_mounts($hd, $part, $all_hds); } sub add { my ($hd, $part, $all_hds, $options) = @_; isSwap($part) ? ($part->{mntpoint} = 'swap') : $options->{force} || check_mntpoint($part->{mntpoint}, $hd, $part, $all_hds); delete $part->{maxsize}; if (isLVM($hd)) { lvm::lv_create($hd, $part); } else { partition_table::add($hd, $part, $options->{primaryOrExtended}); } } sub allocatePartitions { my ($all_hds, $to_add) = @_; foreach my $part_ (get_all_holes($all_hds)) { my ($start, $size, $dev) = @$part_{"start", "size", "rootDevice"}; my $part; while (suggest_part($part = { start => $start, size => 0, maxsize => $size, rootDevice => $dev }, $all_hds, $to_add)) { my $hd = part2hd($part, $all_hds); add($hd, $part, $all_hds, {}); $size -= $part->{size} + $part->{start} - $start; $start = $part->{start} + $part->{size}; } } } sub auto_allocate { my ($all_hds, $o_suggestions) = @_; my $before = listlength(get_all_fstab($all_hds)); my $suggestions = $o_suggestions || $suggestions{simple}; allocatePartitions($all_hds, $suggestions); if ($o_suggestions) { auto_allocate_raids($all_hds, $suggestions); if (auto_allocate_vgs($all_hds, $suggestions)) { #- allocatePartitions needs to be called twice, once for allocating PVs, once for allocating LVs my @vgs = map { $_->{VG_name} } @{$all_hds->{lvms}}; my @suggested_lvs = grep { member($_->{hd}, @vgs) } @$suggestions; allocatePartitions($all_hds, \@suggested_lvs); } } partition_table::assign_device_numbers($_) foreach @{$all_hds->{hds}}; if ($before == listlength(get_all_fstab($all_hds))) { # find out why auto_allocate failed if (any { !has_mntpoint($_->{mntpoint}, $all_hds) } @$suggestions) { die N("Not enough free space for auto-allocating"); } else { die N("Nothing to do"); } } } sub auto_allocate_raids { my ($all_hds, $suggestions) = @_; my @raids = grep { isRawRAID($_) } get_all_fstab($all_hds) or return; require raid; my @mds = grep { $_->{hd} =~ /md/ } @$suggestions; foreach my $md (@mds) { my @raids_ = grep { !$md->{parts} || $md->{parts} =~ /\Q$_->{mntpoint}/ } @raids; @raids = difference2(\@raids, \@raids_); my $nb = raid::new($all_hds->{raids}, @raids_); my $part = $all_hds->{raids}[$nb]; my %h = %$md; delete @h{'hd', 'parts'}; put_in_hash($part, \%h); # mntpoint, level, chunk-size, type raid::updateSize($part); } } sub auto_allocate_vgs { my ($all_hds, $suggestions) = @_; my @pvs = grep { isRawLVM($_) } get_all_fstab($all_hds) or return; my @vgs = grep { $_->{VG_name} } @$suggestions or return; partition_table::write(@{$all_hds->{hds}}); require lvm; foreach my $vg (@vgs) { my $lvm = new lvm($vg->{VG_name}); push @{$all_hds->{lvms}}, $lvm; my @pvs_ = grep { !$vg->{parts} || $vg->{parts} =~ /\Q$_->{mntpoint}/ } @pvs; @pvs = difference2(\@pvs, \@pvs_); foreach my $part (@pvs_) { raid::make($all_hds->{raids}, $part) if isRAID($part); $part->{lvm} = $lvm->{VG_name}; delete $part->{mntpoint}; lvm::vg_add($part); push @{$lvm->{disks}}, $part; } lvm::update_size($lvm); } 1; } sub undo_prepare { my ($all_hds) = @_; require Data::Dumper; $Data::Dumper::Purity = 1; foreach (@{$all_hds->{hds}}) { my @h = @$_{@partition_table::fields2save}; push @{$_->{undo}}, Data::Dumper->Dump([\@h], ['$h']); } } sub undo { my ($all_hds) = @_; foreach (@{$all_hds->{hds}}) { my $code = pop @{$_->{undo}} or next; my $h; eval $code; @$_{@partition_table::fields2save} = @$h; if ($_->{hasBeenDirty}) { partition_table::will_tell_kernel($_, 'force_reboot'); #- next action needing write_partitions will force it. We can't do it now since more undo may occur, and we must not needReboot now } } } sub move { my ($hd, $part, $hd2, $sector2) = @_; die 'TODO'; # doesn't work for the moment my $part1 = { %$part }; my $part2 = { %$part }; $part2->{start} = $sector2; $part2->{size} += $hd2->cylinder_size - 1; partition_table::remove($hd, $part); { local ($part2->{notFormatted}, $part2->{isFormatted}); #- do not allow partition::add to change this partition_table::add($hd2, $part2); } return if $part2->{notFormatted} && !$part2->{isFormatted} || $::testing; local (*F, *G); sysopen F, $hd->{file}, 0 or die ''; sysopen G, $hd2->{file}, 2 or die N("Error opening %s for writing: %s", $hd2->{file}, $!); my $base = $part1->{start}; my $base2 = $part2->{start}; my $step = 10; if ($hd eq $hd2) { $base == $base2 and return; $step = min($step, abs($base2 - $base)); if ($base < $base2) { $base += $part1->{size} - $step; $base2 += $part1->{size} - $step; $step = -$step; } } my $f = sub { $base < 0 and $base2 += -$base, $base = 0; $base2 < 0 and $base += -$base2, $base2 = 0; c::lseek_sector(fileno(F), $base, 0) or die "seeking to sector $base failed on drive $hd->{device}"; c::lseek_sector(fileno(G), $base2, 0) or die "seeking to sector $base2 failed on drive $hd2->{device}"; my $buf; sysread F, $buf, $SECTORSIZE * abs($_[0]) or die ''; syswrite G, $buf; }; for (my $i = 0; $i < $part1->{size} / abs($step); $i++, $base += $step, $base2 += $step) { print "$base $base2\n"; &$f($step); } if (my $v = ($part1->{size} % abs($step)) * sign($step)) { $base += $v; $base2 += $v; &$f($v); } } sub change_type { my ($type, $hd, $part) = @_; $type != $part->{type} or return; check_type($type, $hd, $part); $hd->{isDirty} = 1; $part->{mntpoint} = '' if isSwap($part) && $part->{mntpoint} eq "swap"; $part->{mntpoint} = '' if isRawLVM({ type => $type }) || isRawRAID({ type => $type }); $part->{type} = $type; $part->{notFormatted} = 1; $part->{isFormatted} = 0; } sub rescuept($) { my ($hd) = @_; my ($ext, @hd); my $dev = devices::make($hd->{device}); open(my $F, "rescuept $dev|"); local $_; while (<$F>) { my ($st, $si, $id) = /start=\s*(\d+),\s*size=\s*(\d+),\s*Id=\s*(\d+)/ or next; my $part = { start => $st, size => $si, type => hex($id) }; if (isExtended($part)) { $ext = $part; } else { push @hd, $part; } } close $F or die "rescuept failed"; partition_table::raw::zero_MBR($hd); foreach (@hd) { my $b = partition_table::verifyInside($_, $ext); if ($b) { $_->{start}--; $_->{size}++; } local $_->{notFormatted}; partition_table::add($hd, $_, ($b ? 'Extended' : 'Primary'), 1); } } sub compare_with_proc_partitions { my ($hd) = @_; my @l1 = partition_table::get_normal_parts($hd); my @l2 = grep { $_->{rootDevice} eq $hd->{device} } read_proc_partitions([$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 doesn't agree with drakx %d != %d:\n%s\n", $len1, $len2, "/proc/partitions: " . join(", ", map { "$_->{device} ($_->{rootDevice})" } @l2)); } $len2; } sub use_proc_partitions { 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_proc_partitions([$hd]) ] }; } 1;