## -*-perl-*- # Routines to set up the filesystem hierarchy # This is where we mount the new Linux filesystem $fsmount = "/mnt"; # %fsformat{device} is used to determine file system types # if a device is not listed there, we ask the user for the type %fs_pars = (); %fs_types = (); %fs_sizes = (); %fs_mountpoints = (); # Indicates that the installation filesystem is mounted $fs_mounted = 0; $root_dev = ""; sub fstab_reset { %fs_pars = (); %fs_types = (); %fs_sizes = (); %fs_mountpoints = (); %fsformat = (); $root_dev = ""; } sub mountpoint_sort { $fs_mountpoints{$a} cmp $fs_mountpoints{$b}; } sub init_filesystems { local ( %fsinfolist, $dev, $size ); local ( $p, $r ); if ($fs_mounted) { if (! &rhs_menu("Warning", < The installation filesystems are already mounted. DO NOT make changes to the filesystem mountpoints unless you first unmount the filesystems and erase them. > What do you want to do? > EOM , 70, 3, "Unmount the filesystems", "", "Unmount and erase the filesystems", "", "Forget it -- do not change the filesystems", "")) { return 1; } if ($dialog_result eq "Forget it -- do not change the filesystems") { return 1; } elsif ($dialog_result eq "Unmount the filesystems") { return 0 if (! &unmount_filesystems); } elsif ($dialog_result eq "Unmount and erase the filesystems") { return 0 if (! &unmount_filesystems); return 0 if (! &erase_filesystems); } } ## Find all disk partitions &rhs_infobox ("Filesystems", < Looking for Linux partitions... > EOM , 60); %fsinfolist = (); open(SAVEERR, ">&STDERR"); open(STDERR, ">/dev/null"); open(PROC, "fdisk -l |") || &newdie("Can't call fdisk!"); while () { if (/^(.{10}).{5}(.{31}).*Linux native$/) { $p = $1; $r = $2; $p =~ s/\s$//; $fsinfolist{$p} = "$r"; } } close PROC; open(STDERR, ">&SAVEERR"); if (keys(%fsinfolist) == 0) { &rhs_msgbox ( "Filesystems", < You don\'t appear to have any Linux partitions on your system. You must create at least one before continuing. > EOM , 60); return 0; } ## Select paritions and mount points ## First the special case where there is only one partition if (keys(%fsinfolist) == 1) { ($dev) = keys(%fsinfolist); $fsinfolist{$dev} =~ /^.*(.{9})$/; $size = $1; chop($size); $root_dev = $dev; $fs_pars{$dev} = $dev; $fs_types{$dev} = $fstype; $fs_sizes{$dev} = $size; $fs_mountpoints{$dev} = "/"; return 1; } SELNEWPAR: while(1) { $msg = < Device Type Blocks Location EOM ; foreach $ent (sort mountpoint_sort (keys(%fs_mountpoints))) { $msg .= sprintf(">%-9s %5s%7s %s\n", $ent, $fs_types{$ent}, $fs_sizes{$ent}, $fs_mountpoints{$ent}); } $msg .= ">"; if (! &rhs_menu("Filesystems", $msg, 60, 4, "Add", "Add a new partition", "Remove", "Remove a partition", "Edit", "Change the location of a partition", "Done", "Continue with install")) { %fs_pars = (); %fs_types = (); %fs_sizes = (); %fs_mountpoints = (); return 0; } if ($dialog_result eq "Add") { &fs_add_filesystem(%fsinfolist); } elsif ($dialog_result eq "Remove") { &fs_remove_filesystem; } elsif ($dialog_result eq "Edit") { &fs_edit_filesystem; } elsif ($dialog_result eq "Done") { if (&fs_verify_fstab) { return 1; } } } # while(1) # should never get here } sub fs_verify_fstab { local ( $ent, $oent ); ## Check for duplicate mount points foreach $ent (values (%fs_mountpoints)) { if ($ent eq $oent) { &rhs_msgbox("Error", < The following mount point is used twice! Only one partition can be mounted at any one mount point. > $ent > EOM , 60); return 0; } $oent = $ent; } ## Check for a "/" filesystem $root_dev = ""; foreach $ent (keys (%fs_mountpoints)) { if ($fs_mountpoints{$ent} eq "/") { $root_dev = $ent; last; } } if ( $root_dev eq "" ) { &rhs_msgbox("Error", < You have not specified a root parition! > You must have a single parition mounted at \"/\". > EOM , 60); return 0; } return 1; } sub fs_remove_filesystem { local ( %fstmp, $ent, $dev ); $fstmp = (); foreach $ent (sort mountpoint_sort (keys(%fs_mountpoints))) { $fstmp{$ent} = sprintf("%5s%7s %-12.12s\n", $fs_types{$ent}, $fs_sizes{$ent}, $fs_mountpoints{$ent}); } if (! &rhs_menua("Filesystems", < Which partition do you want to remove? > EOM , 45, %fstmp)) { return 0; } $dev = $dialog_result; delete $fs_pars{$dev}; delete $fs_sizes{$dev}; delete $fs_types{$dev}; delete $fs_mountpoints{$dev}; return 1; } sub fs_edit_filesystem { local ( %fstmp, $ent, $dev ); $fstmp = (); foreach $ent (sort mountpoint_sort (keys(%fs_mountpoints))) { $fstmp{$ent} = sprintf("%5s%7s %-12.12s\n", $fs_types{$ent}, $fs_sizes{$ent}, $fs_mountpoints{$ent}); } if (! &rhs_menua("Filesystems", < Which partition do you want to edit? > EOM , 45, %fstmp)) { return 0; } $dev = $dialog_result; if (! &rhs_inputbox("Filesystems", < Where do you want to mount $dev? > EOM , 70, $fs_mountpoints{$dev})) { return 0; } $fs_mountpoints{$dev} = $dialog_result; return 1; } sub fs_add_filesystem { local ( %fsinfolist ) = @_; local ( %fstmp, $ent, $entb, $dev, $size ); %fstmp = (); ADDNEWPARB: foreach $ent (sort keys (%fsinfolist)) { foreach $entb (sort keys (%fs_pars)) { next ADDNEWPARB if ($ent eq $entb); } $fstmp{$ent} = $fsinfolist{$ent}; } if (! &rhs_menua("Filesystems", < Which partition do you want to add? > > Device Begin Start End Blocks EOM , 54, %fstmp)) { return 0; } $dev = $dialog_result; $fstmp{$dev} =~ /^.*(.{9})$/; $size = $1; chop($size); return &fs_add($dev, $size); } sub fs_add { local ( $dev, $size ) = @_; local ( $mountpoint ); if (! &rhs_inputbox("Filesystems", < Where do you want to mount $dev? > EOM , 70, "")) { return 0; } $mountpoint = $dialog_result; if ($fsformat{$dev}) { $type = $fsformat{$dev}; } else { if (! &rhs_menu("Filesystems", < What type of filesystem is on this partition? > EOM , 50, 3, "ext2", "Second Extended FS", "minix", "Minix FS", "msdos", "MS-DOS FS")) { return 0; } $type = $dialog_result; } $fs_pars{$dev} = $dev; $fs_types{$dev} = $type; $fs_sizes{$dev} = $size; $fs_mountpoints{$dev} = $mountpoint; return 1; } sub mount_filesystems { local ( $ent, $ret ); if ($fs_mounted) { &rhs_msgbox("Notice", < Your Linux filesystem is already mounted. > EOM , 60); return 1; } $ret = 0; foreach $ent (sort mountpoint_sort (keys(%fs_mountpoints))) { if ($fs_mountpoints{$ent} ne "/") { &invoke("mkdir -p $fsmount$fs_mountpoints{$ent}"); } $ret += &invoke("mount -t $fs_types{$ent} $ent $fsmount$fs_mountpoints{$ent}"); } if ($ret) { &rhs_msgbox("Error", < An error occurred while mounting the filesystem. > You need to repeat the Fstab step and reorganize your filesystem. You should then Unmount your filesystem, and Mount it again. > EOM , 60); $fs_mounted = 0; return 0; } else { if (! $express_install) { &rhs_msgbox("Success", < Your Linux filesystem was mounted successfully. > EOM , 60); } $fs_mounted = 1; return 1; } } sub unmount_filesystems { local ( $ent ); if (! $fs_mounted) { if (! &rhs_yesno("Notice", < Your Linux filesystem does not appear to be mounted. > Go ahead and unmount it anyway? > EOM , 60)) { return 1; } } foreach $ent (reverse sort mountpoint_sort (keys(%fs_mountpoints))) { &invoke("umount $ent"); } $fs_mounted = 0; return 1; } sub erase_filesystems { &rhs_msgbox("Notice", < Erasing filesystems is not supported at this time. To get the same effect, unmount, re-format, and remount your filesystem. > EOM , 60); return 0; } sub finish_fstab { local ( $ent ); open(FD, ">$fsmount/etc/fstab"); print FD <