Date: Wed, 10 Feb 2016 00:28:15 +0700 From: Eugene Grosbein <eugen@grosbein.net> To: "freebsd-mips@freebsd.org" <freebsd-mips@freebsd.org> Subject: Success story: using reroot to upgrade MIPS online Message-ID: <56BA21AF.50207@grosbein.net>
next in thread | raw e-mail | index | archive | help
Hi! Latest Quarterly Status Report https://www.freebsd.org/news/status/report-2015-10-2015-12.html noted that "Root remount (reroot)" project is finished. I've tried to utilize it to safely upgrade my MIPS32 TP-Link TL-WDR3600 running FreeBSD with new image online, e.g. without console cable, and happy to report that it works flawlessly. I've wrote simple script to perform upgrade. Here is a transcript of such online upgrade session over telnet connection: # upgrade Verifying ftp://eugen@192.168.0.66//home/tftpboot/tl-wdr3600.factory.bin Size: 7919104 bytes Allocating 13443K for memory disk Downloading ftp://eugen@192.168.0.66//home/tftpboot/tl-wdr3600.factory.bin looking up 192.168.0.66 connecting to 192.168.0.66:21 setting passive mode opening data connection initiating transfer remote size / mtime: 7919104 / 1455037602 newimage 100% of 7733 kB 4925 kBps 00m02s vfs.root.mountfrom="ufs:/dev/md2" Closing network connections and unmounting flash... # Connection closed by foreign host. If one has console cable connected (not required), here is what is written there: Feb 10 00:07:56 tl-wdr3600 reroot: rerooted by user Stopping inetd. Shutting down local packages:. Stopping cron. Stopping sshd. Writing entropy file:. Writing early boot entropy file:/etc/rc.shutdown: WARNING: write failed (read-only fs?) Terminated . Trying to mount root from ufs:/dev/md2 []... warning: no time-of-day clock registered, system time will not be set accurately REPROGRAMMING FLASH DO NOT REBOOT OR POWER OFF THE DEVICE STAGE 1: WRITING BLOCKS 2-20 19+0 records in 19+0 records out 1245184 bytes transferred in 12.476816 secs (99800 bytes/sec) STAGE 2: WRITING BLOCKS 21-125 101+1 records in 102+0 records out 6684672 bytWaiting (max 60 seconds) for system process `vnlru' to stop...done Waiting (max 60 seconds) for system process `bufdaemon' to stop...done Waiting (max 60 seconds) for system process `syncer' to stop... Syncing disks, vnodes remaining...0 0 0 0 0 0 0 0 0 done All buffers synced. Uptime: 3m3s Rebooting... Then the device performs full reboot starting with U-Boot loader running new kernel. This first version works with some assumptions: 1. There is enough RAM free to download new image at once plus 20% of its size. For example, it takes 11MB free RAM using 7.6MB new image for a device having 8MB flash. 2. Flash storage is partitioned with one or more partitions using GEOM_MAP feature and GEOM_MAP correctly reports native flash block size as "stripesize", that is true for my device: # geom map list Geom name: flash/spi0 Providers: 1. Name: map/u-boot Mediasize: 131072 (128K) Sectorsize: 512 Stripesize: 65536 [skip] Flash block size is 65536 bytes in this case. 3. New image is accessible with FTP or HTTP(S) methods. Currently running image has stock fetch(1) binary and kernel support for tmpfs(5) (required by reroot feature) and md(4) (memory disk) support with mdconfig(8) binary to keep UFS file system on memory disk that survives rerooting stage (no user tmpfs can survive it currently). 4. FTP/HTTP(S) server is capable to report image size without downloading so "fetch -s" works. URL of image and login credentials are kept in the text file /etc/upgrade.conf" using a format suitable for fetch(1), just like this: url="ftp://username@hostname/path/to/tl-wdr3600.factory.bin" FTP_PASSWORD='secret words' Or, for HTTP: url="http://hostname/path/to/tl-wdr3600.factory.bin" HTTP_AUTH='basic:realm:username:password' hostname may be IP address or FQDN, if running system has working DNS resolver. Refer to fetch(3) manual page for syntax details. 5. New image may partition flash storage in a different way comparing with current image, it does not matter. However, currently active GEOM_MAP partition names affected by upgrade must be specified in /etc/upgrade.conf using "layout" variable. For example, my device has this partitioning: # geom map status Name Status Components map/u-boot N/A flash/spi0 map/kernel N/A flash/spi0 map/rootfs N/A flash/spi0 map/cfg N/A flash/spi0 map/ART N/A flash/spi0 That is, first there is U-Boot loader and its partition is unaffected with upgrade, so it is not mentioned in /etc/upgrade.conf. Then, there are kernel and rootfs partitions and new image spans over them, so they are recited in order: layout='kernel rootfs' Partitions cfg and ART are unaffected with upgrade too, so they are not mentioned. Currently, it is supposed that new image covers contiguous paritions only. There are actually two script: /usr/bin/upgrade and /etc/rc.upgrade. The former creates "flashit" script calling dd to perform actial reflashing after reroot and the latter is fixed script used as /etc/rc for reroot stage to run generated "flashit" script. I've put them online for reference: http://www.grosbein.net/freebsd/mips/upgrade/rc.upgrade http://www.grosbein.net/freebsd/mips/upgrade/upgrade There are number of ways they may and should be improved. For example, I'd like to know if it is possible to voluntary blink LEDs during reflashing device so user has some information on the process.
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?56BA21AF.50207>