]> Zhao Yanbai Git Server - minix.git/commitdiff
Bootloader reinstall mode for setup.
authorEvgeniy Ivanov <lolkaantimat@gmail.com>
Tue, 14 Feb 2012 19:17:58 +0000 (23:17 +0400)
committerBen Gras <ben@minix3.org>
Thu, 15 Mar 2012 18:06:23 +0000 (19:06 +0100)
commands/setup/setup.sh

index 23c4e66269addc35d3af9bc8be0b674afd6e5ee0..24b7a50d4e513e65b42a95c21a1d5f688605d84a 100644 (file)
@@ -74,6 +74,34 @@ warn()
   echo -e "\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b ! $1"
 }
 
+check_mbr()
+{
+       # check for potential problems with old mbr.
+       disk=`echo -n "/dev/$primary" | sed 's/p[0-3]//'`
+       minix_primaries=`echo -n "" | fdisk "$disk" | grep "MINIX" | wc -l`
+       if [ "$minix_primaries" -gt 1 ]
+       then
+               # old mbr + bootxx will not work with several partitions of
+               # the same type.
+               dd if=/usr/mdec/mbr of=temp_mbr_netbsd bs=1 count=440 2>/dev/null
+               dd if="$disk" bs=1 count=440 2>/dev/null | cmp - temp_mbr_netbsd >/dev/null
+               if [ "$?" -ne 0 ]
+               then
+                       echo ""
+                       echo "Warning: you have MBR which doesn't support multiple MINIX 3 partitions!"
+                       echo "You will be able to boot from the first one only!"
+                       echo -n "Do you want to install new MBR into $disk? [Y] "
+                       read ok
+                       if [ "$ok" = Y -o "$ok" = y -o "$ok" = "" ]
+                       then
+                               installboot_nbsd -m "$disk" /usr/mdec/mbr >/dev/null
+                       fi
+               fi
+               rm temp_mbr_netbsd
+       fi
+
+}
+
 # No options.
 while getopts '' opt; do usage; done
 shift `expr $OPTIND - 1`
@@ -323,13 +351,15 @@ echo " --- Step 4: Reinstall choice ------------------------------------------"
                echo "You have selected an existing MINIX 3 partition."
                echo "Type F for full installation (to overwrite entire partition)"
                echo "Type R for a reinstallation (existing /home will not be affected)"
+               echo "Type B to reinstall/upgrade bootloader (no data affected)"
                echo ""
-               echo -n "(F)ull or (R)einstall? [R] "
+               echo -n "(F)ull, (R)einstall or (B)ootloader install? [R] "
                read conf
                case "$conf" in
                "")     confirm="ok"; auto="r"; ;;
                [Rr]*)  confirm="ok"; auto="r"; ;;
                [Ff]*)  confirm="ok"; auto="" ;;
+               [Bb]*)  confirm="ok"; bootreinstall="ok" ;;
                esac
 
        else    echo ""
@@ -340,6 +370,184 @@ echo " --- Step 4: Reinstall choice ------------------------------------------"
 
 done
 
+if [ "$bootreinstall" = "ok" ]
+then
+       echo ""
+       echo " --- Step 5: Reinstall bootloader ----------------------------------"
+       echo ""
+
+       echo "WARNING: This procedure uses your current /usr to store your /."
+       echo "Once the procedure starts, it has to finish"
+       echo "to restore your / partition. Please make sure it is not interrupted."
+       echo ""
+
+       echo -n "It's recommended to run fsck before you continue, run? [Y/n] "
+       read ok
+       if [ "$ok" = "y" -o "$ok" = "Y" -o "$ok" = "" ]
+       then
+               fsck.mfs -a "/dev/$root" >/dev/null
+               fsck.mfs -a "/dev/$usr" >/dev/null
+       fi
+
+       # If there is no ELF stuff and not enough space after repartitioning,
+       # user will fall into trouble. So at first copy new stuff.
+       mount "/dev/$root" /mnt >/dev/null || exit
+
+       # grep, stat, etc in chroot
+       mount "/dev/$usr" /mnt/usr >/dev/null || exit
+
+       cp -pf /bin/update_bootcfg /mnt/bin/ && \
+               cp -pf /etc/boot.cfg.default /mnt/etc/ && \
+               cp -pf /boot_monitor /mnt/ || exit
+
+       if [ ! -d /mnt/boot/minix_default -o ! -r /mnt/boot/minix_default/kernel ]
+       then
+               if [ -r /mnt/boot.cfg ]
+               then
+                       echo ""
+                       echo "There is no /boot/minix_default/, but /boot.cfg exists."
+                       echo -n "Do you want to copy minix_default from CD? [Y/n] "
+               else
+                       echo ""
+                       echo -n "There is no /boot/minix_default/, do you want to copy it from CD? [Y/n] "
+               fi
+               read ok
+               if [ "$ok" = "y" -o "$ok" = "Y" -o "$ok" = "" ]
+               then
+                       if [ -e /mnt/boot/minix_default ]
+                       then
+                               echo "Old /boot/minix_default moved to /boot/minix_default_old"
+                               mv /mnt/boot/minix_default /mnt/boot/minix_default_old
+                       fi
+
+                       cp -rfp /boot/minix_default /mnt/boot/ || exit
+               fi
+       fi
+
+       echo " * Updating /boot.cfg"
+
+       chroot /mnt update_bootcfg
+
+       umount /mnt/usr && umount /mnt || exit
+
+       # Check if enough space for new boot
+       let bootspace=`devsize /dev/$primary`-`devsize /dev/$root`-`devsize /dev/$home`-`devsize /dev/$usr` >/dev/null
+       if [ $bootspace -lt $BOOTXXSECTS ]
+       then
+               echo ""
+               echo "Root partition size will be reduced by up to 16Kb to fit new bootloader."
+               echo "This is not a problem."
+
+               free_space=`df /dev/$root | awk '{print $3}' | tail -n 1`
+               # round 16 => 20
+               if [ "$free_space" -le 20 ]
+               then
+                       echo ""
+                       echo "Not enough space on /dev/$root, you need at least 20Kb to use new bootloader!"
+                       exit 1
+               fi
+
+               ROOTSECTS=`expr \`devsize /dev/$root\` - $BOOTXXSECTS + $bootspace`
+
+               free_space=`df /dev/$usr | awk '{print $3}' | tail -n 1`
+               required_space=`df /dev/$root | awk '{print $4}' | tail -n 1`
+
+               if [ "$required_space" -gt "$free_space" ]
+               then
+                       echo ""
+                       echo "You don't have enough free space on /dev/$usr to backup /dev/$root!"
+                       echo "${free_space}Kb available, ${required_space} required."
+                       exit 1
+               fi
+
+               mkdir /mnt/root && mkdir /mnt/usr || exit
+
+               echo "Re-mounting your current / and /usr"
+
+               mount "/dev/$root" /mnt/root || exit
+               mount "/dev/$usr" /mnt/usr || exit
+
+               mkdir /mnt/usr/tmp/root_backup || exit
+
+               echo " * Copying / contents"
+
+               cp -rfp /mnt/root/* /mnt/usr/tmp/root_backup
+               if [ $? -ne 0 ]
+               then
+                       echo ""
+                       echo "Failed to backup root partition, aborting!"
+                       rm -rf /mnt/usr/tmp/root_backup
+                       # umount shouldn't fail here, but if it will, next
+                       # "rm -rf" will serve for user's pleasure.
+                       umount /mnt/root >/dev/null || exit
+                       umount /mnt/usr >/dev/null || exit
+                       rm -rf /mnt/root /mnt/usr
+                       exit 1
+               fi
+
+               echo " * Copying done"
+
+               umount /mnt/root 
+               umount /mnt/usr 
+
+               add_subpart=""
+               minix_subparts=`echo -n "" | fdisk /dev/$primary | grep "MINIX" | wc -l`
+               if [ "$minix_subparts" -gt 3 ]
+               then
+                       echo ""
+                       echo "You have additional subpartition except /, /usr and /home."
+                       echo "Partition type will be set to MINIX (81), you can change it later using part."
+                       echo -n "Do you want to continue? [Y/n] "
+                       read ok
+                       [ "$ok" = "n" -o "$ok" = "N" ] && exit
+                       add_subpart="81:exist"
+               fi
+
+               echo " * Repartitioning"
+
+               partition /dev/$primary $BOOTXXSECTS 81:${ROOTSECTS}* 81:exist 81:exist $add_subpart || exit
+
+               echo " * mkfs on new /"
+
+               mkfs.mfs "/dev/$root" || exit
+
+               if [ $? -ne 0 ]
+               then
+                       echo "Failed to repartition /dev/$primary"
+                       rmdir /mnt/root
+                       rmdir /mnt/usr
+                       exit 1
+               fi
+
+               mount "/dev/$usr" /mnt/usr || exit
+               mount "/dev/$root" /mnt/root || exit
+
+               echo " * Filling new / filesystem"
+
+               mv /mnt/usr/tmp/root_backup/* /mnt/root/ || exit
+               if [ $? -ne 0 ]
+               then
+                       echo "Failed to copy old root data! It is in /tmp/root_backup/"
+               fi
+
+               rmdir /mnt/usr/tmp/root_backup/
+
+               umount /mnt/root
+               umount /mnt/usr
+       fi
+
+       check_mbr
+       installboot_nbsd -f /dev/$primary /usr/mdec/bootxx_minixfs3 >/dev/null || exit 1
+
+       if [ $? -ne 0 ]
+       then
+               echo "Warning: failed to remove /tmp/root_backup!"
+       fi
+
+       echo "New boot installed successfully! You can reboot now."
+       exit
+fi
+
 rmdir $TMPMP
 
 nohome="0"
@@ -456,29 +664,7 @@ blocksizebytes="`expr $blocksize '*' 1024`"
 
 bootsectors=$BOOTXXSECTS
 
-       # check for potential problems with old mbr.
-       # space for bootxx has been checked earlier.
-       minix_primaries=`echo -n "" | fdisk /dev/$primary | grep "MINIX" | wc -l`
-       if [ "$minix_primaries" -gt 1 ]
-       then
-               # old mbr + bootxx will not work with several partitions of
-               # the same type.
-               disk=`echo -n "/dev/$primary" | sed 's/p[0-3]//'`
-               dd if=/usr/mdec/mbr of=temp_mbr_netbsd bs=1 count=440 2>/dev/null
-               dd if="$disk" bs=1 count=440 | cmp - temp_mbr_netbsd >/dev/null
-               if [ "$?" -ne 0 ]
-               then
-                       echo "Warning: you have MBR which doesn't support multiple MINIX 3 partitions!"
-                       echo "You will be able to boot from the first one only!"
-                       echo -n "Do you want to install new MBR into $disk? [Y] "
-                       read ok
-                       if [ "$ok" = Y -o "$ok" = y -o "$ok" = "" ]
-                       then
-                               installboot_nbsd -m "$disk" /usr/mdec/mbr >/dev/null
-                       fi
-               fi
-               rm temp_mbr_netbsd
-       fi
+check_mbr
 
 echo "
 You have selected to (re)install MINIX 3 in the partition /dev/$primary.