#!/bin/sh version=0.1 ############################################################################## # This is a script to install a second system on a wrap-board. A second # # system is an easy way for remote updates and desaster recovery. But as you # # might know, living is at you own risk, so is using this script. It plays # # around with the boot loader (grub), and there is always a risk to loose # # your working system - so dont blame me if you have to show up personally # # at your router installation. # # Requirements: you need to have the grub-package installed, there is a # # packaged version available at the place where you found this script or # # you can compile one yourself using the OpenWrt Software Development Kit. # # Additionally, you need to have the script sync_spare_partition_config # # installed. So the configuration of your new system will be synchronized # # with the current one to give you access after rebooting in the new # # system. # # License: the code is licensed by Rene Ejury in 2007 under the GPL # ############################################################################## dir="/tmp/" # watch out not missing the last "/" kernel_file="openwrt-x86-2.6-ext2.image.kernel" fs_file="openwrt-x86-2.6-ext2.fs" fecho() { spaces=$((73-${#1})) spacestr="" while [ $((spaces--)) -gt 0 ]; do spacestr=$spacestr" "; done echo "| $1$spacestr |" } fline() { echo "+---------------------------------------------------------------------------+" } fline fecho "install_new_system version $version" fline fecho "ATTENTION: Please read the output of the script before rebooting the" fecho " router carefully. Errors might occure." fline; echo cd $dir fline fecho "checking if the new kernel and filesystem images are in $dir" # check if new images are in memory and are the right size if [ -e $fs_file ]; then fecho "found new filesystem image at $dir$fs_file" else echo "ERROR: $dir$fs_file missing" fline; exit 1 fi if [ -e $kernel_file ]; then fecho "found new kernel image at $dir$kernel_file" else echo "ERROR: $dir$kernel_file missing" fline; exit 1 fi fline; echo fline fecho "testing md5-checksums" # check if new images are in memory and are the right size if ! [ -e $fs_file".md5" ]; then fecho "md5sum: $(md5sum $fs_file)" echo "Continue? " read REPLY if [ "$REPLY" != "y" ] && [ "$REPLY" != "Y" ]; then echo "aborted." fline; exit 1 fi fi if ! [ -e $kernel_file".md5" ]; then fecho "md5sum: $(md5sum $kernel_file)" echo "Continue? " read REPLY if [ "$REPLY" != "y" ] && [ "$REPLY" != "Y" ]; then echo "aborted." fline; exit 1 fi fi fline; echo fline fecho "determine the working system partitions..." # first check on which partitions we are working work_system=$(ls -al /dev/root 2>/dev/null | awk 'BEGIN{FS="hda"}{print $2}') if [ "$work_system" != "2" ] && [ "$work_system" != "4" ]; then fecho "ERROR: your working system seems to be partition /dev/hda$work_system" fecho " this script is not made for your system, expecting root partition" fecho " as partition /dev/hda2 or /dev/hda4" fline; exit 1 fi fecho "ok, current working partition is /dev/hda$work_system" fline; echo if [ "$work_system" == "2" ]; then cur_kernel_part="1"; kernel_part="3"; fs_part="4"; new_grub_default="2" else cur_kernel_part="3"; kernel_part="1"; fs_part="2"; new_grub_default="0" fi fline fecho "checking if spare Partitions existing and big enough..." kernel_part_size_blocks=$(awk '/hda'"$kernel_part"'/ {print $3}' /proc/partitions) 2>/dev/null [ $? != 0 ] && { "ERROR: second partition for kernel not found."; exit 1; } kernel_part_size_bytes=$(((($kernel_part_size_blocks*2)+1)*512)) kernel_file_size_bytes=$(ls -al $kernel_file | awk '{print $5}') if [ $kernel_part_size_bytes -lt $kernel_file_size_bytes ]; then echo "ERROR: second kernel partition has size of $kernel_part_size_bytes bytes," echo " min. requiered size is $kernel_file_size_bytes bytes." echo " please adapt your partition table. I won't do this for you." exit 1; fi fecho "partition /dev/hda$kernel_part (size: $kernel_part_size_bytes bytes) ..." fecho " -> big enough for kernel (size: $kernel_file_size_bytes bytes)" fs_part_size_blocks=$(awk '/hda'"$fs_part"'/ {print $3}' /proc/partitions) 2>/dev/null [ $? != 0 ] && { "ERROR: second partition for filesystem not found."; exit 1; } fs_part_size_bytes=$(((($fs_part_size_blocks*2)+1)*512)) fs_file_size_bytes=$(ls -al $fs_file | awk '{print $5}') if [ $fs_part_size_bytes -lt $fs_file_size_bytes ]; then echo "ERROR: second filesystem partition has size of $fs_part_size_bytes bytes," echo " min. requiered size is $fs_file_size_bytes bytes." echo " please adapt your partition table. I won't do this for you." exit 1; fi fecho "partition /dev/hda$fs_part (size: $fs_part_size_bytes bytes) ..." fecho " -> big enough for filesystem (size: $fs_file_size_bytes bytes)" fecho "ok, partition-table is looing ok." fline; echo fline fecho "*** start to write the new system on partition /dev/hda$fs_part ***" dd if=$fs_file of=/dev/hda$fs_part bs=512k [ $? != 0 ] && { "ERROR: system partition dump failed"; exit 1; } fecho "done." #rm $dir$fs_file fline; echo fline fecho "*** start to write the new kernel on partition /dev/hda$kernel_part ***" dd if=$kernel_file of=/dev/hda$kernel_part bs=512k [ $? != 0 ] && { "ERROR: kernel partition dump failed"; exit 1; } fecho "done." #rm $dir$kernel_file fline; echo fline; fecho "*** checking new system on partition /dev/hda$fs_part ***" e2fsck /dev/hda$fs_part [ $? != 0 ] && { "ERROR: system partition broken"; exit 1; } fecho "done."; fline; echo fline; fecho "*** checking new kernel on partition /dev/hda$kernel_part ***" e2fsck /dev/hda$kernel_part [ $? != 0 ] && { "ERROR: kernel partition broken"; exit 1; } fecho "done."; fline; echo # replace menu.lst (use new one as a base) fline fecho "*** Adapting boot menu to use new system ***" mkdir -p /tmp/boot_old mount /dev/hda$cur_kernel_part /tmp/boot_old mkdir -p /tmp/boot_new mount /dev/hda$kernel_part /tmp/boot_new awk '{if ($0 ~ "default") print "default '"$new_grub_default"'"; else {gsub("OpenWrt","OpenWrt-1"); if (/kernel/ && !/nodma/) print $0" ide=nodma"; else print}}' /tmp/boot_new/boot/grub/menu.lst >/tmp/menu.lst echo >>/tmp/menu.lst awk '{if (/title/) start=1; if (start == 1) {gsub("OpenWrt","OpenWrt-2"); gsub("hda2","hda4"); gsub("hd0,0","hd0,2"); if (/kernel/ && !/nodma/) print $0" ide=nodma"; else print}}' /tmp/boot_new/boot/grub/menu.lst >>/tmp/menu.lst cp /tmp/menu.lst /tmp/boot_new/boot/grub/menu.lst mv /tmp/menu.lst /tmp/boot_old/boot/grub/menu.lst umount /tmp/boot_old umount /tmp/boot_new fecho "done." fline; echo fline fecho "*** Starting grub and writing new boot loader... ***" grub --batch --no-curses --no-floppy <