FreeNAS Code
This project has moved to github - see https://github.com/freenas
Brought to you by:
cochard,
mattolander
#!/bin/sh # # /etc/rc.firmware # part of FreeNAS (http://www.freenas.org) # Copyright (C) 2005-2010 Olivier Cochard-Labbe <olivier@freenas.org>. # All rights reserved. # # Based on m0n0wall (http://m0n0.ch/wall) # Copyright (C) 2003-2007 Manuel Kasper <mk@neon1.net>. # All rights reserved. # # Script usage: # rc.firmware <args> [<file>] # Where <args> can take the following values: # - enable: Create a 64MB ram drive in ${FTMP} # - disable: Erase ram drive # - upgrade <file> : Do an embedded release (IMG file) upgrade using the file <file> # - fullupgrade <file> : Do a full release (TGZ file) upgrade using the file <file> SIZE="128M" CFDEVICE=`cat /etc/cfdevice | sed -e 's/[a-h]$//'` FTMP="/var/tmp/ftmp" backup_chflags() { TOPROCESS="bin lib libexec sbin usr" for files in $TOPROCESS; do /usr/sbin/mtree -Pcp /${files} | /usr/bin/gzip -9 > /tmp/chflags.dist.${files}.gz done } restore_chflags() { TOPROCESS="bin lib libexec sbin usr" for files in $TOPROCESS; do cd / && /usr/bin/zcat /tmp/chflags.dist.${files}.gz | /usr/sbin/mtree -PU -p /${files} done } remove_chflags() { TOPROCESS="bin lib libexec sbin usr" for files in $TOPROCESS; do /bin/chflags -R noschg /${files} /bin/chmod -R u+rw /${files} done } case $1 in enable) # Redirect I/O to console. exec </dev/console >/dev/console 2>/dev/console # Use auto-unit feature to automatically select an unused device. /sbin/mdmfs -m 0 -s $SIZE -b 8192 -f 1024 md ${FTMP} > /dev/null 2>&1 if [ 0 != $? ]; then # successful? msg="ERROR: Failed to create in-memory file system." printf "\n\33[31m%s\33[0m\n" "${msg}" /usr/bin/logger "UPGRADE ${msg}" exit 1 fi ;; disable) # Redirect I/O to console. exec </dev/console >/dev/console 2>/dev/console # Get the md device. mdid=`/sbin/mount -p | /usr/bin/grep ${FTMP} | /usr/bin/awk '{print $1}'` # Umount in-memory file system. /sbin/umount -f ${FTMP} > /dev/null 2>&1 if [ 0 != $? ]; then # successful? msg="ERROR: Failed to umount in-memory file system." printf "\n\33[31m%s\33[0m\n" "${msg}" /usr/bin/logger "UPGRADE ${msg}" exit 1 fi # Detach md device. /sbin/mdconfig -d -u ${mdid} ;; upgrade) # Wait 5 seconds before beginning sleep 5 # Redirect I/O to console. exec </dev/console >/dev/console 2>/dev/console printf "\n\n\33[37m%s\33[0m\n" "Firmware upgrade in progress. Please wait..." # Check if firmware file exists if [ ! -r "$2" ]; then msg="ERROR: Firmware file does not exist." printf "\n\33[31m%s\33[0m\n" "${msg}" /usr/bin/logger "UPGRADE ${msg}" exit 1 fi # Test firmware file /usr/bin/gzip -t "$2" 2>&1 if [ 0 != $? ]; then msg="ERROR: Firmware file is corrupted." printf "\n\33[31m%s\33[0m\n" "${msg}" /usr/bin/logger "UPGRADE ${msg}" exit 1 fi # Backup config mkdir /tmp/configbak cp -p /conf/* /tmp/configbak if [ -f /cf/boot.config ]; then cp -p /cf/boot.config /tmp/configbak fi # Unmount /cf /sbin/umount -f /cf if [ 0 != $? ]; then # successful? msg="ERROR: Failed to umount '/cf'!" printf "\33[31m%s\33[0m\n" "${msg}" /usr/bin/logger "UPGRADE ${msg}" fi # dd image onto card result=1 if [ -r "$2" ]; then /usr/bin/gzip -cd "$2" | /bin/dd of=/dev/${CFDEVICE} ibs=16k obs=16k > /dev/null 2>&1 result=$? if [ 0 != ${result} ]; then # successful? msg="ERROR: Failed to install firmware image on '/dev/${CFDEVICE}'!" printf "\33[31m%s\33[0m\n" "${msg}" /usr/bin/logger "UPGRADE ${msg}" else msg="Firmware installed successful." printf "\33[37;44m%s\33[0m\n" "${msg}" /usr/bin/logger "UPGRADE: ${msg}" fi fi # Mount /cf read-write /sbin/mount -w -o noatime /cf # Restore config cp -p /tmp/configbak/* /conf if [ -f /conf/boot.config ]; then mv /conf/boot.config /cf fi rm -r /tmp/configbak # Remount /cf read-only /sbin/umount -f /cf /sbin/mount -r /cf # Reboot system if upgrade was successful. if [ 0 -eq ${result} ]; then msg="Rebooting system..." printf "\33[37m%s\33[0m\n" "${msg}" /usr/bin/logger "${msg}" /sbin/shutdown -r now > /dev/null 2>&1 else exit 1 fi ;; fullupgrade) # Wait 5 seconds before beginning. sleep 5 # Redirect I/O to console. exec </dev/console >/dev/console 2>/dev/console printf "\n\n\33[37m%s\33[0m\n" "Firmware upgrade in progress. Please wait..." # Check if firmware file exists. if [ ! -r "$2" ]; then msg="ERROR: Firmware file does not exist." printf "\33[31m%s\33[0m\n" "${msg}" /usr/bin/logger "UPGRADE ${msg}" exit 1 fi # Test firmware file /usr/bin/gzip -t "$2" 2>&1 if [ 0 != $? ]; then msg="ERROR: Firmware file is corrupted." printf "\33[31m%s\33[0m\n" "${msg}" /usr/bin/logger "UPGRADE ${msg}" exit 1 fi backup_chflags remove_chflags # backup config /bin/mkdir -p /tmp/configbak cp -p /conf/* /tmp/configbak 2>/dev/null if [ -f /boot.config ]; then cp -p /boot.config /tmp/configbak 2>/dev/null fi /usr/bin/tar xzUPf "$2" -C / 2>&1 result=$? if [ 0 != ${result} ]; then # successful? msg="ERROR: Failed to upgrade firmware!" printf "\33[31m%s\33[0m\n" "${msg}" /usr/bin/logger "UPGRADE ${msg}" else msg="Firmware installed successful." printf "\33[37;44m%s\33[0m\n" "${msg}" /usr/bin/logger "UPGRADE: ${msg}" fi # restore config cp -p /tmp/configbak/* /conf 2>/dev/null if [ -f /conf/boot.config ]; then mv /conf/boot.config / 2>/dev/null fi rm -r /tmp/configbak # restore /etc symlinks rm /etc/hosts ln -s /var/etc/hosts /etc/hosts restore_chflags # Start upgrade script to remove obsolete files /etc/install/upgrade.sh clean / # Reboot system if upgrade was successful. if [ 0 -eq ${result} ]; then msg="Rebooting system..." printf "\33[37m%s\33[0m\n" "${msg}" /usr/bin/logger "${msg}" /sbin/shutdown -r now > /dev/null 2>&1 else exit 1 fi ;; esac exit 0