#!/bin/sh -e PATH=/bin:/sbin:/usr/bin:/usr/sbin mp="/tmp/upgrade.$$" image='newimage' cfg='/etc/upgrade.conf' progs='/bin/dd /bin/kill /bin/sh /bin/sleep /libexec/ld-elf.so.1 /sbin/init' roundup() { echo $(( (($1+256)/512+1)*512 )); } load_files() { local bdir f for f do bdir=${f%/*} mkdir -p $mp$bdir cp -p $f $mp$bdir/ done } # # Main # [ -r $cfg ] && . $cfg || { echo $0: cannot read $cfg; exit 1; } export FTP_USER FTP_PASSWORD HTTP_AUTH echo "Verifying $url" size=$(fetch -s "$url") if [ -z "$size" -o "$size" = Unknown ]; then echo Failed >&2 exit 1 fi echo Size: $size bytes size=$(roundup $size) depends=$(ldd -f '%p\n' $progs 2>/dev/null | sort -u) for f in $progs $depends do size=$(( $size + $(roundup `stat -f '%z' $f`) )) done size=$(($size*6/5)) echo Allocating $(($size/1024))K for memory disk if ! md=$(mdconfig -at malloc -o reserve -s ${size}b); then echo Failed to allocate $size bytes >&2 exit 1 fi md=/dev/$md mkdir -p $mp; [ -d $mp ] || exit 1 newfs -O1 -b 4096 -f 512 -m 0 -o space $md >/dev/null mount -o async $md $mp cd $mp mkdir dev etc load_files $progs $depends cp -p /etc/rc.upgrade etc/rc # silence init(8) moaning "login_getclass: unknown class" cp -p /etc/login.conf.db etc bsize=$(geom map list | awk '/Stripesize:/ {print $2; exit}') iseek=''; off=''; skip=0; stage=1 { echo '#!/bin/sh -e' for part in $layout do size=$(sysctl kern.geom.conftxt | awk '$3=="map/'$part'" {print $4}') blocks=$(($size/$bsize)) [ -z "$off" ] && off=$(sysctl kern.geom.conftxt |\ awk -vb=$bsize '$3=="map/'$part'" {printf "%d", $9/b}') printf 'echo STAGE %s: WRITING BLOCKS %s-%s\n' \ $stage $(($skip+$off)) $(($skip+$blocks+$off-1)) printf 'dd if=/%s of=/dev/map/%s ibs=%s obs=%s conv=osync count=%s %s\n' \ "$image" "$part" $bsize $bsize $blocks $iseek skip=$(($skip+$blocks)) iseek="iseek=$skip" stage=$(($stage+1)) done } > bin/flashit chmod +x bin/flashit echo Downloading $url fetch -vo $image $url kenv vfs.root.mountfrom=ufs:$md echo Closing network connections and unmounting flash... reboot -r