package fsedit; # $Id$ use diagnostics; use strict; use vars qw(%suggestions); #-###################################################################################### #- misc imports #-###################################################################################### use common; use partition_table; use partition_table::raw; use fs::get; use fs::type; use fs::loopback; use fs::proc_partitions; use detect_devices; use devices; use log; use fs; %suggestions = ( N_("simple") => [ { mntpoint => "/", size => MB(300), fs_type => 'ext3', ratio => 5, maxsize => MB(8000) }, { mntpoint => "swap", size => MB(64), fs_type => 'swap', ratio => 1, maxsize => MB(4000) }, { mntpoint => "/home", size => MB(300), fs_type => 'ext3', ratio => 3 }, ], N_("with /usr") => [ { mntpoint => "/", size => MB(250), fs_type => 'ext3', ratio => 1, maxsize => MB(4000) }, { mntpoint => "swap", size => MB(64), fs_type => 'swap', ratio => 1, maxsize => MB(4000) }, { mntpoint => "/usr", size => MB(300), fs_type => 'ext3', ratio => 4, maxsize => MB(8000) }, { mntpoint => "/home", size => MB(100), fs_type => 'ext3', ratio => 3 }, ], N_("server") => [ { mntpoint => "/", size => MB(150), fs_type => 'ext3', ratio => 1, maxsize => MB(4000) }, { mntpoint => "swap", size => MB(64), fs_type => 'swap', ratio => 2, maxsize => MB(4000) }, { mntpoint => "/usr", size => MB(300), fs_type => 'ext3', ratio => 4, maxsize => MB(8000) }, { mntpoint => "/var", size => MB(200), fs_type => 'ext3', ratio => 3 }, { mntpoint => "/home", size => MB(150), fs_type => 'ext3', ratio => 3 }, { mntpoint => "/tmp", size => MB(150), fs_type => 'ext3', ratio => 2, maxsize => MB(4000) }, ], ); foreach (values %suggestions) { if (arch() =~ /ia64/) { @$_ = ({ mntpoint => "/boot/efi", size => MB(50), pt_type => 0xef, ratio => 1, maxsize => MB(150) }, @$_); } } my @suggestions_mntpoints = ( "/var/ftp", "/var/www", "/boot", '/usr/local', '/opt', arch() =~ /sparc/ ? "/mnt/sunos" : arch() =~ /ppc/ ? "/mnt/macos" : "/mnt/windows", ); #-###################################################################################### #- Functions #-###################################################################################### sub recompute_loopbacks { my ($all_hds) = @_; my @fstab = fs::get::fstab($all_hds); @{$all_hds->{loopbacks}} = map { isPartOfLoopback($_) ? @{$_->{loopback}} : () } @fstab; } sub raids { my ($hds) = @_; my @parts = fs::get::hds_fstab(@$hds); my @l = grep { isRawRAID($_) } @parts or return []; log::l("looking for raids in " . join(' ', map { $_->{device} } @l)); require raid; raid::detect_during_install(@l) if $::isInstall; raid::get_existing(@l); } sub lvms { my ($all_hds) = @_; my @pvs = grep { isRawLVM($_) } fs::get::fstab($all_hds) or return; log::l("looking for vgs in " . join(' ', map { $_->{device} } @pvs)); #- otherwise vgscan will not find them devices::make($_->{device}) foreach @pvs; require lvm; my @lvms; foreach (@pvs) { my $name = lvm::pv_to_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 handle_dmraid { my ($drives, $o_in) = @_; @$drives > 1 or return; devices::make($_->{device}) foreach @$drives; require fs::dmraid; eval { fs::dmraid::init() } or log::l("dmraid::init failed"), return; my @vgs = fs::dmraid::vgs(); log::l(sprintf('dmraid: ' . join(' ', map { "$_->{device} [" . join(' ', @{$_->{disks}}) . "]" } @vgs))); if ($o_in && @vgs && $::isInstall) { @vgs = grep { $o_in->ask_yesorno('', N("BIOS software RAID detected on disks %s. Activate it?", join(' ', @{$_->{disks}})), 1); } @vgs or do { fs::dmraid::call_dmraid('-an'); return; }; } log::l("using dmraid on " . join(' ', map { $_->{device} } @vgs)); my @used_hds = map { my $part = fs::get::device2part($_, $drives) or log::l("handle_dmraid: can't find $_ in known drives"); if_($part, $part); } map { @{$_->{disks}} } @vgs; @$drives = difference2($drives, \@used_hds); push @$drives, @vgs; } sub get_hds { my ($o_flags, $o_in) = @_; my $flags = $o_flags || {}; $flags->{readonly} && ($flags->{clearall} || $flags->{clear}) and die "conflicting flags readonly and clear/clearall"; my @drives = detect_devices::hds(); #- replace drives used in dmraid by the merged name handle_dmraid(\@drives, $o_in) if !$flags->{nodmraid}; foreach my $hd (@drives) { $hd->{file} = devices::make($hd->{device}); $hd->{prefix} ||= $hd->{device}; } @drives = partition_table::raw::get_geometries(@drives); my (@hds, @raw_hds); foreach my $hd (@drives) { $hd->{readonly} = $flags->{readonly}; eval { partition_table::raw::test_for_bad_drives($hd) if !$flags->{no_bad_drives} }; if (my $err = $@) { log::l("test_for_bad_drives returned $err"); if ($err =~ /write error:/) { log::l("setting $hd->{device} readonly"); $hd->{readonly} = 1; } elsif ($err =~ /read error:/) { next; } else { $o_in and $o_in->ask_warn('', $err); next; } } if ($flags->{clearall} || member($hd->{device}, @{$flags->{clear} || []})) { my $lvms = []; #- temporary one, will be re-created later in get_hds() partition_table_initialize($lvms, $hd, $o_in); } else { my $handle_die_and_cdie = sub { if (my $type = fs::type::type_subpart_from_magic($hd)) { #- non partitioned drive? if (exists $hd->{usb_description} && $type->{fs_type}) { #- USB keys put_in_hash($hd, $type); push @raw_hds, $hd; $hd = ''; 1; } else { 0; } } elsif ($hd->{readonly}) { log::l("using /proc/partitions since diskdrake failed :("); fs::proc_partitions::use_($hd); 1; } else { 0; } }; my $handled; eval { catch_cdie { partition_table::read($hd); if (listlength(partition_table::get_normal_parts($hd)) == 0) { $handled = 1 if $handle_die_and_cdie->(); } elsif ($::isInstall) { if (fs::type::is_dmraid($hd)) { if (my $p = find { ! -e "/dev/$_->{device}" } partition_table::get_normal_parts($hd)) { #- dmraid should have created the device, so it means we don't agree die sprintf(q(bad dmraid (missing partition %s), you may try rebooting install with option "nodmraid"), $p->{device}); } } else { fs::proc_partitions::compare($hd) if !detect_devices::is_xbox() && arch() ne 'ppc'; } } } sub { my $err = $@; if ($handle_die_and_cdie->()) { $handled = 1; 0; #- do not continue, transform cdie into die } else { !$o_in || $o_in->ask_okcancel('', formatError($err)); } }; }; if (my $err = $@) { if ($handled) { #- already handled in cdie handler above } elsif ($handle_die_and_cdie->()) { } elsif ($o_in && $o_in->ask_yesorno(N("Error"), N("I can not 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? ", $hd->{device}, formatError($err)))) { partition_table::raw::zero_MBR($hd); } else { #- using it readonly log::l("using /proc/partitions since diskdrake failed :("); fs::proc_partitions::use_($hd); } } $hd or next; member($_->{device}, @{$flags->{clear} || []}) and partition_table::remove($hd, $_) foreach partition_table::get_normal_parts($hd); } my @parts = partition_table::get_normal_parts($hd); # checking the magic of the filesystem, do not rely on pt_type foreach (@parts) { if (my $type = fs::type::type_subpart_from_magic($_)) { $type->{pt_type} = $_->{pt_type}; #- keep {pt_type} put_in_hash($_, $type); } else { $_->{bad_fs_type_magic} = 1; } } if ($hd->{usb_media_type}) { $_->{is_removable} = 1 foreach @parts; } push @hds, $hd; } #- detect raids before LVM allowing LVM on raid my $raids = raids(\@hds); my $all_hds = { %{ fs::get::empty_all_hds() }, hds => \@hds, raw_hds => \@raw_hds, lvms => [], raids => $raids }; $all_hds->{lvms} = [ lvms($all_hds) ]; fs::get_major_minor([ fs::get::fstab($all_hds) ]); $all_hds; } #- are_same_partitions() do not look at the device name since things may have changed sub are_same_partitions { my ($part1, $part2) = @_; foreach ('start', 'size', 'pt_type', 'fs_type', 'rootDevice') { $part1->{$_} eq $part2->{$_} or return 0; } 1; } sub is_one_big_fat_or_NT { my ($hds) = @_; @$hds == 1 or return 0; my @l = fs::get::hds_fstab(@$hds); @l == 1 && isFat_or_NTFS($l[0]) && fs::get::hds_free_space(@$hds) < MB(10); } 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; $free_space{$_->{rootDevice}} += $_->{size} foreach fs::get::holes($all_hds); my @l = my @L = grep { my @possible = $_->{hd} ? $_->{hd} : keys %free_space; my $size = $_->{size}; if (my $dev = find { $free_space{$_} >= $size } @possible) { $free_space{$dev} -= $size; 1; } else { 0 } } @$suggestions; my $free_space = $best->{hd} && $free_space{$best->{hd}} || sum(values %free_space); 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 += fs::get::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}; #- suggestions now use {fs_type}, but still keep compatibility foreach (@$suggestions) { fs::type::set_pt_type($_, $_->{pt_type}) if !exists $_->{fs_type}; } my $has_swap = any { isSwap($_) } fs::get::fstab($all_hds); my @local_suggestions = grep { !$_->{mntpoint} && !$_->{VG_name} || !fs::get::has_mntpoint($_->{mntpoint}, $all_hds) || isSwap($_) && !$has_swap } grep { !$_->{hd} || $_->{hd} eq $part->{rootDevice} } @$suggestions; #- this allows specifying the size using a relative size. #- one should rather use {ratio} instead foreach (@local_suggestions) { if ($_->{percent_size} && $_->{percent_size} =~ /(.+?)%?$/) { $_->{size} = $1 / 100 * fs::get::part2hd($part, $all_hds)->{totalsectors}; log::l("in suggestion, setting size=$_->{size} for percent_size=$_->{percent_size}"); } } my ($best) = grep { !$_->{maxsize} || $part->{size} <= $_->{maxsize} } grep { $_->{size} <= ($part->{maxsize} || $part->{size}) } grep { !$part->{fs_type} || $part->{fs_type} eq $_->{fs_type} || isTrueFS($part) && isTrueFS($_) } @local_suggestions; defined $best or return 0; #- sorry no suggestion :( $part->{mntpoint} = $best->{mntpoint}; fs::type::set_type_subpart($part, $best) if !isTrueFS($best) || !isTrueFS($part); $part->{size} = computeSize($part, $best, $all_hds, \@local_suggestions); foreach ('options', 'lv_name', 'encrypt_key', 'primaryOrExtended', 'device_LABEL', 'prefer_device_LABEL', 'device_UUID', 'prefer_device_UUID', 'prefer_device') { $part->{$_} = $best->{$_} if $best->{$_}; } $best; } sub suggestions_mntpoint { my ($all_hds) = @_; sort grep { !/swap/ && !fs::get::has_mntpoint($_, $all_hds) } (@suggestions_mntpoints, map { $_->{mntpoint} } @{$suggestions{server} || $suggestions{simple}}); } #- you can do this before modifying $part->{mntpoint} #- so $part->{mntpoint} should not be used here, use $mntpoint instead sub check_mntpoint { my ($mntpoint, $part, $all_hds) = @_; $mntpoint eq '' || isSwap($part) || isNonMountable($part) and return 0; $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"); fs::get::mntpoint2part($mntpoint, [ grep { $_ ne $part } fs::get::really_all_fstab($all_hds) ]) and die N("There is already a partition with mount point %s\n", $mntpoint); if ($mntpoint eq "/" && isRAID($part) && !fs::get::has_mntpoint("/boot", $all_hds)) { my $md_part = fs::get::device2part($part->{raid}, $all_hds->{raids}); 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 $md_part->{level} ne '1'; # lilo handles / on RAID1 } #- NB: if the LV doesn't exist, lv_nb_pvs returns 0 die N("You can not use the LVM Logical Volume for mount point %s since it spans physical volumes", $mntpoint) if $mntpoint eq '/boot' && isLVM($part) && lvm::lv_nb_pvs($part) > 1; cdie N("You've selected the LVM Logical Volume as root (/). The bootloader is not able to handle this when the volume spans physical volumes. You should create a /boot partition first") if $mntpoint eq "/" && isLVM($part) && lvm::lv_nb_pvs($part) != 1 && !fs::get::has_mntpoint("/boot", $all_hds); 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 /media)); 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, '/home', fs::type::directories_needed_to_boot()); die N("You can not use an encrypted file system for mount point %s", $mntpoint) if $part->{options} =~ /encrypted/ && member($mntpoint, qw(/ /usr /var /boot)); local $part->{mntpoint} = $mntpoint; fs::loopback::check_circular_mounts($part, $all_hds); } sub add { my ($hd, $part, $all_hds, $options) = @_; isSwap($part) ? ($part->{mntpoint} = 'swap') : $options->{force} || check_mntpoint($part->{mntpoint}, $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) = @_; my @to_add = @$to_add; foreach my $part_ (fs::get::holes($all_hds, 'non_readonly')) { my ($start, $size, $dev) = @$part_{"start", "size", "rootDevice"}; my ($part, $suggested); while ($suggested = suggest_part($part = { start => $start, size => 0, maxsize => $size, rootDevice => $dev }, $all_hds, \@to_add)) { my $hd = fs::get::part2hd($part, $all_hds); add($hd, $part, $all_hds, { primaryOrExtended => $part->{primaryOrExtended} }); $size -= $part->{size} + $part->{start} - $start; $start = $part->{start} + $part->{size}; @to_add = grep { $_ != $suggested } @to_add; } } } sub auto_allocate { my ($all_hds, $o_suggestions) = @_; my $before = listlength(fs::get::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(fs::get::fstab($all_hds))) { # find out why auto_allocate failed if (any { !fs::get::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($_) } fs::get::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 %h = %$md; delete @h{'hd', 'parts'}; # keeping mntpoint, level, chunk-size, fs_type/pt_type $h{disks} = \@raids_; my $part = raid::new($all_hds->{raids}, %h); raid::updateSize($part); push @raids, $part; #- we can build raid over raid } } sub auto_allocate_vgs { my ($all_hds, $suggestions) = @_; my @pvs = grep { isRawLVM($_) } fs::get::fstab($all_hds) or return 0; my @vgs = grep { $_->{VG_name} } @$suggestions or return 0; partition_table::write($_) foreach @{$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 change_type { my ($type, $hd, $part) = @_; $type->{pt_type} != $part->{pt_type} || $type->{fs_type} ne $part->{fs_type} or return; fs::type::check($type->{fs_type}, $hd, $part); $hd->{isDirty} = 1; $part->{mntpoint} = '' if isSwap($part) && $part->{mntpoint} eq "swap"; $part->{mntpoint} = '' if isRawLVM($type) || isRawRAID($type); set_isFormatted($part, 0); fs::type::set_type_subpart($part, $type); fs::mount_options::rationalize($part); 1; } sub partition_table_clear_and_initialize { my ($lvms, $hd, $o_in, $o_type, $b_warn) = @_; $hd->clear_existing; partition_table_initialize($lvms, $hd, $o_in, $o_type, $b_warn); } sub partition_table_initialize { my ($lvms, $hd, $o_in, $b_warn, $o_type) = @_; partition_table::initialize($hd, $o_type); if ($hd->isa('partition_table::lvm')) { if ($b_warn && $o_in) { $o_in->ask_okcancel_('', N("ALL existing partitions and their data will be lost on drive %s", partition_table::description($hd))) or return; } require lvm; lvm::check($o_in ? $o_in->do_pkgs : do_pkgs_standalone->new) if $::isStandalone; lvm::create_singleton_vg($lvms, fs::get::hds_fstab($hd)); } } 1; 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 510 511 512 513 514 515 516 517 518 519 520 521 522 523 524 525 526 527 528 529 530 531 532 533 534 535 536 537 538 539 540 541 542 543 544 545 546 547 548 549 550 551 552 553 554 555 556 557 558 559 560 561 562 563 564 565 566 567 568 569 570 571 572 573 574 575 576 577 578 579 580 581 582 583 584 585 586 587 588 589 590 591 592 593 594 595 596 597 598 599 600 601 602 603 604 605 606 607 608 609 610 611 612 613 614 615 616 617 618 619 620 621 622 623 624 625 626 627 628 629 630 631 632 633 634 635 636 637 638 639 640 641 642 643 644 645 646 647 648 649 650 651 652 653 654 655 656 657 658 659 660 661 662 663 664 665 666 667 668 669 670 671 672 673 674 675 676 677 678 679 680 681 682 683 684 685 686 687 688 689 690 691 692 693 694 695 696 697 698 699 700 701 702 703 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 800 801 802 803 804 805 806 807 808 809 810 811 812 813 814 815 816 817 818 819 820 821 822 823 824 825 826 827 828 829 830 831 832 833 834 835 836 837 838 839 840 841 842 843 844 845 846 847 848 849 850 851 852 853 854 855 856 857 858 859 860 861 862 863 864 865 866 867 868 869 870 871 872 873 874 875 876 877 878 879 880 881 882 883 884 885 886 887 888 889 890 891 892 893 894 895 896 897 898 899 900 901 902 903 904 905 906 907 908 909 910 911 912 913 914 915 916 917 918 919 920 921 922 923 924 925 926 927 928 929 930 931 932 933 934 935 936 937 938 939 940 941 942 943 944 945 946 947 948 949 950 951 952 953 954 955 956 957 958 959 960 961 962 963 964 965 966 967 968 969 970 971 972 973 974 975 976 977 978 979 980 981 982 983 984 985 986 987 988 989 990 991 992 993 994 995 996 997 998 999 1000 1001 1002 1003 1004 1005 1006
package help;
use common;

1;

# IMPORTANT: Don't edit this File - It is automatically generated 
#            from the manuals !!! 
#            Write a mail to <documentation@mandrakesoft.com> if
#            you want it changed.
sub acceptLicense() {
    N("Before continuing, you should carefully read the terms of the license. It
covers the entire Mandrakelinux distribution. If you do agree with all the
terms in it, check the \"%s\" box. If not, clicking on the \"%s\" button
will reboot your computer.", N("Accept"), N("Quit"));
}
sub addUser() {
    N("GNU/Linux is a multi-user system, meaning each user may have their own
preferences, their own files and so on. You can read the ``Starter Guide''
to learn more about multi-user systems. But unlike \"root\", who is the
system administrator, the users you add at this point will not be
authorized to change anything except their own files and their own
configurations, protecting the system from unintentional or malicious
changes that impact on the system as a whole. You will have to create at
least one regular user for yourself -- this is the account which you should
use for routine, day-to-day use. Although it is very easy to log in as
\"root\" to do anything and everything, it may also be very dangerous! A
very simple mistake could mean that your system will not work any more. If
you make a serious mistake as a regular user, the worst that will happen is
that you will lose some information, but not affect the entire system.

The first field asks you for a real name. Of course, this is not mandatory
-- you can actually enter whatever you like. DrakX will use the first word
you typed in this field and copy it to the \"%s\" field, which is the name
this user will enter to log onto the system. If you like, you may override
the default and change the user name. The next step is to enter a password.
From a security point of view, a non-privileged (regular) user password is
not as crucial as the \"root\" password, but that is no reason to neglect
it by making it blank or too simple: after all, your files could be the
ones at risk.

Once you click on \"%s\", you can add other users. Add a user for each one
of your friends: your father or your sister, for example. Click \"%s\" when
you have finished adding users.

Clicking the \"%s\" button allows you to change the default \"shell\" for
that user (bash by default).

When you have finished adding users, you will be asked to choose a user who
can automatically log into the system when the computer boots up. If you
are interested in that feature (and do not care much about local security),
choose the desired user and window manager, then click \"%s\". If you are
not interested in this feature, uncheck the \"%s\" box.", N("User name"), N("Accept user"), N("Next"), N("Advanced"), N("Next"), N("Do you want to use this feature?"));
}
sub ask_mntpoint_s() {
    N("Listed here are the existing Linux partitions detected on your hard drive.
You can keep the choices made by the wizard, since they are good for most
common installations. If you make any changes, you must at least define a
root partition (\"/\"). Do not choose too small a partition or you will not
be able to install enough software. If you want to store your data on a
separate partition, you will also need to create a \"/home\" partition
(only possible if you have more than one Linux partition available).

Each partition is listed as follows: \"Name\", \"Capacity\".

\"Name\" is structured: \"hard drive type\", \"hard drive number\",
\"partition number\" (for example, \"hda1\").

\"Hard drive type\" is \"hd\" if your hard drive is an IDE hard drive and
\"sd\" if it is a SCSI hard drive.

\"Hard drive number\" is always a letter after \"hd\" or \"sd\". For IDE
hard drives:

 * \"a\" means \"master hard drive on the primary IDE controller\";

 * \"b\" means \"slave hard drive on the primary IDE controller\";

 * \"c\" means \"master hard drive on the secondary IDE controller\";

 * \"d\" means \"slave hard drive on the secondary IDE controller\".

With SCSI hard drives, an \"a\" means \"lowest SCSI ID\", a \"b\" means
\"second lowest SCSI ID\", etc.");
}
sub chooseCd() {
    N("The Mandrakelinux installation is distributed on several CD-ROMs. If a
selected package is located on another CD-ROM, DrakX will eject the current
CD and ask you to insert the correct CD as required.");
}
sub choosePackages() {
    N("It is now time to specify which programs you wish to install on your
system. There are thousands of packages available for Mandrakelinux, and
to make it simpler to manage the packages have been placed into groups of
similar applications.

Packages are sorted into groups corresponding to a particular use of your
machine. Mandrakelinux sorts packages groups in four categories. You can
mix and match applications from the various categories, so a
``Workstation'' installation can still have applications from the
``Development'' category installed.

 * \"%s\": if you plan to use your machine as a workstation, select one or
more of the groups that are in the workstation category.

 * \"%s\": if you plan on using your machine for programming, select the
appropriate groups from that category.

 * \"%s\": if your machine is intended to be a server, select which of the
more common services you wish to install on your machine.

 * \"%s\": this is where you will choose your preferred graphical
environment. At least one must be selected if you want to have a graphical
interface available.

Moving the mouse cursor over a group name will display a short explanatory
text about that group. If you unselect all groups when performing a regular
installation (as opposed to an upgrade), a dialog will pop up proposing
different options for a minimal installation:

 * \"%s\": install the minimum number of packages possible to have a
working graphical desktop.

 * \"%s\": installs the base system plus basic utilities and their
documentation. This installation is suitable for setting up a server.

 * \"%s\": will install the absolute minimum number of packages necessary
to get a working Linux system. With this installation you will only have a
command line interface. The total size of this installation is about 65
megabytes.

You can check the \"%s\" box, which is useful if you are familiar with the
packages being offered or if you want to have total control over what will
be installed.

If you started the installation in \"%s\" mode, you can unselect all groups
to avoid installing any new package. This is useful for repairing or
updating an existing system.", N("Workstation"), N("Development"), N("Server"), N("Graphical Environment"), N("With X"), N("With basic documentation"), N("Truly minimal install"), N("Individual package selection"), N("Upgrade"));
}
sub choosePackagesTree() {
    N("If you told the installer that you wanted to individually select packages,
it will present a tree containing all packages classified by groups and
subgroups. While browsing the tree, you can select entire groups,
subgroups, or individual packages.

Whenever you select a package on the tree, a description appears on the
right to let you know the purpose of the package.

!! If a server package has been selected, either because you specifically
chose the individual package or because it was part of a group of packages,
you will be asked to confirm that you really want those servers to be
installed. By default Mandrakelinux will automatically start any installed
services at boot time. Even if they are safe and have no known issues at
the time the distribution was shipped, it is entirely possible that that
security holes were discovered after this version of Mandrakelinux was
finalized. If you do not know what a particular service is supposed to do
or why it is being installed, then click \"%s\". Clicking \"%s\" will
install the listed services and they will be started automatically by
default during boot. !!

The \"%s\" option is used to disable the warning dialog which appears
whenever the installer automatically selects a package to resolve a
dependency issue. Some packages have relationships between each them such
that installation of one package requires that some other program is also
required to be installed. The installer can determine which packages are
required to satisfy a dependency to successfully complete the installation.

The tiny floppy disk icon at the bottom of the list allows you to load a
package list created during a previous installation. This is useful if you
have a number of machines that you wish to configure identically. Clicking
on this icon will ask you to insert a floppy disk previously created at the
end of another installation. See the second tip of last step on how to
create such a floppy.", N("No"), N("Yes"), N("Automatic dependencies"));
}
sub configureNetwork() {
    N("You will now set up your Internet/network connection. If you wish to
connect your computer to the Internet or to a local network, click \"%s\".
Mandrakelinux will attempt to auto-detect network devices and modems. If
this detection fails, uncheck the \"%s\" box. You may also choose not to
configure the network, or to do it later, in which case clicking the \"%s\"
button will take you to the next step.

When configuring your network, the available connections options are:
Normal modem connection, Winmodem connection, ISDN modem, ADSL connection,
cable modem, and finally a simple LAN connection (Ethernet).

We will not detail each configuration option - just make sure that you have
all the parameters, such as IP address, default gateway, DNS servers, etc.
from your Internet Service Provider or system administrator.

About Winmodem Connection. Winmodems are special integrated low-end modems
that require additional software to work compared to Normal modems. Some of
those modems actually work under Mandrakelinux, some others do not. You
can consult the list of supported modems at LinModems.

You can consult the ``Starter Guide'' chapter about Internet connections
for details about the configuration, or simply wait until your system is
installed and use the program described there to configure your connection.", N("Next"), N("Use auto detection"), N("Cancel"));
}
sub configurePrinter() {
    N("\"%s\": clicking on the \"%s\" button will open the printer configuration
wizard. Consult the corresponding chapter of the ``Starter Guide'' for more
information on how to setup a new printer. The interface presented there is
similar to the one used during installation.", N("Printer"), N("Configure"));
}
sub configureServices() {
    N("This dialog is used to choose which services you wish to start at boot
time.

DrakX will list all the services available on the current installation.
Review each one carefully and uncheck those which are not needed at boot
time.

A short explanatory text will be displayed about a service when it is
selected. However, if you are not sure whether a service is useful or not,
it is safer to leave the default behavior.

!! At this stage, be very careful if you intend to use your machine as a
server: you will probably not want to start any services that you do not
need. Please remember that several services can be dangerous if they are
enabled on a server. In general, select only the services you really need.
!!");
}
sub configureTimezoneGMT() {
    N("GNU/Linux manages time in GMT (Greenwich Mean Time) and translates it to
local time according to the time zone you selected. If the clock on your
motherboard is set to local time, you may deactivate this by unselecting
\"%s\", which will let GNU/Linux know that the system clock and the
hardware clock are in the same time zone. This is useful when the machine
also hosts another operating system like Windows.

The \"%s\" option will automatically regulate the clock by connecting to a
remote time server on the Internet. For this feature to work, you must have
a working Internet connection. It is best to choose a time server located
near you. This option actually installs a time server that can be used by
other machines on your local network as well.", N("Hardware clock set to GMT"), N("Automatic time synchronization"));
}
sub configureX_card_list() {
    N("Graphic Card

   The installer will normally automatically detect and configure the
graphic card installed on your machine. If it is not the case, you can
choose from this list the card you actually have installed.

   In the situation where different servers are available for your card,
with or without 3D acceleration, you are asked to choose the server that
best suits your needs.");
}
sub configureX_chooser() {
    N("X (for X Window System) is the heart of the GNU/Linux graphical interface
on which all the graphical environments (KDE, GNOME, AfterStep,
WindowMaker, etc.) bundled with Mandrakelinux rely upon.

You will be presented with a list of different parameters to change to get
an optimal graphical display: Graphic Card

   The installer will normally automatically detect and configure the
graphic card installed on your machine. If it is not the case, you can
choose from this list the card you actually have installed.

   In the situation where different servers are available for your card,
with or without 3D acceleration, you are asked to choose the server that
best suits your needs.



Monitor

   The installer will normally automatically detect and configure the
monitor connected to your machine. If it is incorrect, you can choose from
this list the monitor you actually have connected to your computer.



Resolution

   Here you can choose the resolutions and color depths available for your
hardware. Choose the one that best suits your needs (you will be able to
change that after installation though). A sample of the chosen
configuration is shown in the monitor picture.



Test

   Depending on your hardware, this entry might not appear.

   the system will try to open a graphical screen at the desired
resolution. If you can see the message during the test and answer \"%s\",
then DrakX will proceed to the next step. If you cannot see the message, it
means that some part of the auto-detected configuration was incorrect and
the test will automatically end after 12 seconds, bringing you back to the
menu. Change settings until you get a correct graphical display.



Options

   Here you can choose whether you want to have your machine automatically
switch to a graphical interface at boot. Obviously, you want to check
\"%s\" if your machine is to act as a server, or if you were not successful
in getting the display configured.", N("Yes"), N("No"));
}
sub configureX_monitor() {
    N("Monitor

   The installer will normally automatically detect and configure the
monitor connected to your machine. If it is incorrect, you can choose from
this list the monitor you actually have connected to your computer.");
}
sub configureX_resolution() {
    N("Resolution

   Here you can choose the resolutions and color depths available for your
hardware. Choose the one that best suits your needs (you will be able to
change that after installation though). A sample of the chosen
configuration is shown in the monitor picture.");
}
sub configureX_xfree_and_glx() {
    N("In the situation where different servers are available for your card, with
or without 3D acceleration, you are asked to choose the server that best
suits your needs.");
}
sub configureXxdm() {
    N("Options

   Here you can choose whether you want to have your machine automatically
switch to a graphical interface at boot. Obviously, you want to check
\"%s\" if your machine is to act as a server, or if you were not successful
in getting the display configured.", N("No"));
}
sub doPartitionDisks() {
    N("At this point, you need to decide where you want to install the Mandrake
Linux operating system on your hard drive. If your hard drive is empty or
if an existing operating system is using all the available space you will
have to partition the drive. Basically, partitioning a hard drive consists
of logically dividing it to create the space needed to install your new
Mandrakelinux system.

Because the process of partitioning a hard drive is usually irreversible
and can lead to lost data if there is an existing operating system already
installed on the drive, partitioning can be intimidating and stressful if
you are an inexperienced user. Fortunately, DrakX includes a wizard which
simplifies this process. Before continuing with this step, read through the
rest of this section and above all, take your time.

Depending on your hard drive configuration, several options are available:

 * \"%s\": this option will perform an automatic partitioning of your blank
drive(s). If you use this option there will be no further prompts.

 * \"%s\": the wizard has detected one or more existing Linux partitions on
your hard drive. If you want to use them, choose this option. You will then
be asked to choose the mount points associated with each of the partitions.
The legacy mount points are selected by default, and for the most part it's
a good idea to keep them.

 * \"%s\": if Microsoft Windows is installed on your hard drive and takes
all the space available on it, you will have to create free space for
GNU/Linux. To do so, you can delete your Microsoft Windows partition and
data (see ``Erase entire disk'' solution) or resize your Microsoft Windows
FAT or NTFS partition. Resizing can be performed without the loss of any
data, provided you have previously defragmented the Windows partition.
Backing up your data is strongly recommended.. Using this option is
recommended if you want to use both Mandrakelinux and Microsoft Windows on
the same computer.

   Before choosing this option, please understand that after this
procedure, the size of your Microsoft Windows partition will be smaller
then when you started. You will have less free space under Microsoft
Windows to store your data or to install new software.

 * \"%s\": if you want to delete all data and all partitions present on
your hard drive and replace them with your new Mandrakelinux system,
choose this option. Be careful, because you will not be able to undo your
choice after you confirm.

   !! If you choose this option, all data on your disk will be deleted. !!

 * \"%s\": this will simply erase everything on the drive and begin fresh,
partitioning everything from scratch. All data on your disk will be lost.

   !! If you choose this option, all data on your disk will be lost. !!

 * \"%s\": choose this option if you want to manually partition your hard
drive. Be careful -- it is a powerful but dangerous choice and you can very
easily lose all your data. That's why this option is really only
recommended if you have done something like this before and have some
experience. For more instructions on how to use the DiskDrake utility,
refer to the ``Managing Your Partitions'' section in the ``Starter Guide''.", N("Use free space"), N("Use existing partition"), N("Use the free space on the Windows partition"), N("Erase entire disk"), N("Remove Windows"), N("Custom disk partitioning"));
}
sub exitInstall() {
    N("There you are. Installation is now complete and your GNU/Linux system is
ready to use. Just click \"%s\" to reboot the system. Don't forget to
remove the installation media (CD-ROM or floppy). The first thing you
should see after your computer has finished doing its hardware tests is the
bootloader menu, giving you the choice of which operating system to start.

The \"%s\" button shows two more buttons to:

 * \"%s\": to create an installation floppy disk that will automatically
perform a whole installation without the help of an operator, similar to
the installation you just configured.

   Note that two different options are available after clicking the button:

    * \"%s\". This is a partially automated installation. The partitioning
step is the only interactive procedure.

    * \"%s\". Fully automated installation: the hard disk is completely
rewritten, all data is lost.

   This feature is very handy when installing a number of similar machines.
See the Auto install section on our web site for more information.

 * \"%s\": saves a list of the packages selected in this installation. To
use this selection with another installation, insert the floppy and start
the installation. At the prompt, press the [F1] key and type >>linux
defcfg=\"floppy\" <<.", N("Reboot"), N("Advanced"), N("Generate auto-install floppy"), N("Replay"), N("Automated"), N("Save packages selection"));
}
sub formatPartitions() {
    N("Any partitions that have been newly defined must be formatted for use
(formatting means creating a file system).

At this time, you may wish to reformat some already existing partitions to
erase any data they contain. If you wish to do that, please select those
partitions as well.

Please note that it is not necessary to reformat all pre-existing
partitions. You must reformat the partitions containing the operating
system (such as \"/\", \"/usr\" or \"/var\") but you do not have to
reformat partitions containing data that you wish to keep (typically
\"/home\").

Please be careful when selecting partitions. After formatting, all data on
the selected partitions will be deleted and you will not be able to recover
it.

Click on \"%s\" when you are ready to format the partitions.

Click on \"%s\" if you want to choose another partition for your new
Mandrakelinux operating system installation.

Click on \"%s\" if you wish to select partitions that will be checked for
bad blocks on the disk.", N("Next"), N("Previous"), N("Advanced"));
}
sub installUpdates() {
    N("At the time you are installing Mandrakelinux, it is likely that some
packages will have been updated since the initial release. Bugs may have
been fixed, security issues resolved. To allow you to benefit from these
updates, you are now able to download them from the Internet. Check \"%s\"
if you have a working Internet connection, or \"%s\" if you prefer to
install updated packages later.

Choosing \"%s\" will display a list of places from which updates can be
retrieved. You should choose one near to you. A package-selection tree will
appear: review the selection, and press \"%s\" to retrieve and install the
selected package(s), or \"%s\" to abort.", N("Yes"), N("No"), N("Yes"), N("Install"), N("Cancel"));
}
sub miscellaneous() {
    N("At this point, DrakX will allow you to choose the security level desired
for the machine. As a rule of thumb, the security level should be set
higher if the machine will contain crucial data, or if it will be a machine
directly exposed to the Internet. The trade-off of a higher security level
is generally obtained at the expense of ease of use.

If you do not know what to choose, stay with the default option. You will
be able to change that security level later with tool draksec from the
Mandrake Control Center.

The \"%s\" field can inform the system of the user on this computer who
will be responsible for security. Security messages will be sent to that
address.", N("Security Administrator"));
}
sub partition_with_diskdrake() {
    N("At this point, you need to choose which partition(s) will be used for the
installation of your Mandrakelinux system. If partitions have already been
defined, either from a previous installation of GNU/Linux or by another
partitioning tool, you can use existing partitions. Otherwise, hard drive
partitions must be defined.

To create partitions, you must first select a hard drive. You can select
the disk for partitioning by clicking on ``hda'' for the first IDE drive,
``hdb'' for the second, ``sda'' for the first SCSI drive and so on.

To partition the selected hard drive, you can use these options:

 * \"%s\": this option deletes all partitions on the selected hard drive

 * \"%s\": this option enables you to automatically create ext3 and swap
partitions in the free space of your hard drive

\"%s\": gives access to additional features:

 * \"%s\": saves the partition table to a floppy. Useful for later
partition-table recovery if necessary. It is strongly recommended that you
perform this step.

 * \"%s\": allows you to restore a previously saved partition table from a
floppy disk.

 * \"%s\": if your partition table is damaged, you can try to recover it
using this option. Please be careful and remember that it doesn't always
work.

 * \"%s\": discards all changes and reloads the partition table that was
originally on the hard drive.

 * \"%s\": un-checking this option will force users to manually mount and
unmount removable media such as floppies and CD-ROMs.

 * \"%s\": use this option if you wish to use a wizard to partition your
hard drive. This is recommended if you do not have a good understanding of
partitioning.

 * \"%s\": use this option to cancel your changes.

 * \"%s\": allows additional actions on partitions (type, options, format)
and gives more information about the hard drive.

 * \"%s\": when you are finished partitioning your hard drive, this will
save your changes back to disk.

When defining the size of a partition, you can finely set the partition
size by using the Arrow keys of your keyboard.

Note: you can reach any option using the keyboard. Navigate through the
partitions using [Tab] and the [Up/Down] arrows.

When a partition is selected, you can use:

 * Ctrl-c to create a new partition (when an empty partition is selected)

 * Ctrl-d to delete a partition

 * Ctrl-m to set the mount point

To get information about the different file system types available, please
read the ext2FS chapter from the ``Reference Manual''.

If you are installing on a PPC machine, you will want to create a small HFS
``bootstrap'' partition of at least 1MB which will be used by the yaboot
bootloader. If you opt to make the partition a bit larger, say 50MB, you
may find it a useful place to store a spare kernel and ramdisk images for
emergency boot situations.", N("Clear all"), N("Auto allocate"), N("More"), N("Save partition table"), N("Restore partition table"), N("Rescue partition table"), N("Reload partition table"), N("Removable media auto-mounting"), N("Wizard"), N("Undo"), N("Toggle between normal/expert mode"), N("Done"));
}
sub resizeFATChoose() {
    N("More than one Microsoft partition has been detected on your hard drive.
Please choose the one which you want to resize in order to install your new
Mandrakelinux operating system.

Each partition is listed as follows: \"Linux name\", \"Windows name\"
\"Capacity\".

\"Linux name\" is structured: \"hard drive type\", \"hard drive number\",
\"partition number\" (for example, \"hda1\").

\"Hard drive type\" is \"hd\" if your hard dive is an IDE hard drive and
\"sd\" if it is a SCSI hard drive.

\"Hard drive number\" is always a letter after \"hd\" or \"sd\". With IDE
hard drives:

 * \"a\" means \"master hard drive on the primary IDE controller\";

 * \"b\" means \"slave hard drive on the primary IDE controller\";

 * \"c\" means \"master hard drive on the secondary IDE controller\";

 * \"d\" means \"slave hard drive on the secondary IDE controller\".

With SCSI hard drives, an \"a\" means \"lowest SCSI ID\", a \"b\" means
\"second lowest SCSI ID\", etc.

\"Windows name\" is the letter of your hard drive under Windows (the first
disk or partition is called \"C:\").");
}
sub selectCountry() {
    N("\"%s\": check the current country selection. If you are not in this
country, click on the \"%s\" button and choose another one. If your country
is not in the first list shown, click the \"%s\" button to get the complete
country list.", N("Country / Region"), N("Configure"), N("More"));
}
sub selectInstallClass() {
    N("This step is activated only if an existing GNU/Linux partition has been
found on your machine.

DrakX now needs to know if you want to perform a new install or an upgrade
of an existing Mandrakelinux system:

 * \"%s\": For the most part, this completely wipes out the old system. If
you wish to change how your hard drives are partitioned, or change the file
system, you should use this option. However, depending on your partitioning
scheme, you can prevent some of your existing data from being over-written.

 * \"%s\": this installation class allows you to update the packages
currently installed on your Mandrakelinux system. Your current
partitioning scheme and user data is not altered. Most of other
configuration steps remain available, similar to a standard installation.

Using the ``Upgrade'' option should work fine on Mandrakelinux systems
running version \"8.1\" or later. Performing an Upgrade on versions prior
to Mandrakelinux version \"8.1\" is not recommended.", N("Install"), N("Upgrade"));
}
sub selectKeyboard() {
    N("Depending on the language you chose in section , DrakX will automatically
select a particular type of keyboard configuration. Check that the
selection suits you or choose another keyboard layout.

Also, you may not have a keyboard that corresponds exactly to your
language: for example, if you are an English-speaking Swiss native, you may
have a Swiss keyboard. Or if you speak English and are located in Quebec,
you may find yourself in the same situation where your native language and
country-set keyboard do not match. In either case, this installation step
will allow you to select an appropriate keyboard from a list.

Click on the \"%s\" button to be presented with the complete list of
supported keyboards.