Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #!/bin/bash
- #
- # � 2010 Western Digital Technologies, Inc. All rights reserved.
- #
- # updateFirmwareFromFile.sh <filename> [check_filesize]"
- #
- # post entries to updatelog
- uplog()
- {
- logtext=${@}
- logtag="`basename $0`:`date -u +"%D %T"`:"
- echo "${logtag}${logtext}" 2>&1 | tee -a ${updatelog}
- }
- # flag error after attempting to apply upgrade using dpkg
- pre-update_error()
- {
- errortext=${@}
- echo "Error fw_update_status: ${errortext}" 2>&1 | tee -a ${updatelog}
- echo ${errortext} > /tmp/fw_update_status
- uplog ${errortext}
- rm -f ${FW_UPDATE_MUTEX}
- sleep 1
- exit 1
- }
- # prepare for pkg upgrades
- pkg_upgrade_init()
- {
- ledCtrl.sh LED_EV_FW_UPDATE LED_STAT_IN_PROG
- incUpdateCount.pm firmware_update
- ## - TODO: Use signal & run-levels
- ## Stop processes
- [ -e /etc/init.d/cron ] && /etc/init.d/cron stop 2>/dev/null
- [ -e /etc/init.d/monitorio ] && /etc/init.d/monitorio stop 2>/dev/null
- [ -e /etc/init.d/monitorTemperature ] && /etc/init.d/monitorTemperature stop 2>/dev/null
- [ -e /etc/init.d/twonky ] && /etc/init.d/twonky stop 2>/dev/null
- [ -e /etc/init.d/access ] && /etc/init.d/access stop 2>/dev/null
- [ -e /etc/init.d/itunes ] && /etc/init.d/itunes stop 2>/dev/null
- [ -e /etc/init.d/orion ] && /etc/init.d/orion stop 2>/dev/null
- [ -e /etc/init.d/wdphotodbmergerd ] && /etc/init.d/wdphotodbmergerd stop 2>/dev/null
- [ -e /etc/init.d/wdmcserverd ] && /etc/init.d/wdmcserverd stop 2>/dev/null
- [ -e /etc/init.d/samba ] && /etc/init.d/samba stop 2>/dev/null
- [ -e /etc/init.d/netatalk ] && /etc/init.d/netatalk stop 2>/dev/null
- [ -e /etc/init.d/upnp_nas ] && /etc/init.d/upnp_nas stop 2>/dev/null
- [ -e /etc/init.d/wddispatcherd ] && /etc/init.d/wddispatcherd stop 2>/dev/null
- [ -e /etc/init.d/wdnotifierd ] && /etc/init.d/wdnotifierd stop 2>/dev/null
- #
- wdAutoMountAdm.pm shutdownCleanup
- [ -e /etc/init.d/wdAutoMount ] && /etc/init.d/wdnotifierd stop 2>/dev/null
- [ -e /etc/init.d/nfs-kernel-server ] && /etc/init.d/nfs-kernel-server stop 2>/dev/null
- [ -e /etc/init.d/nfs-common ] && /etc/init.d/nfs-common stop 2>/dev/null
- sync
- sleep 2
- }
- #
- pkg_upgrade_exec()
- {
- if [ "${system_boot_type}" == "flash" ]; then
- dpkg --fsys-tarfile ${filename} | tar xOf - ./upgrade.sh > /tmp/upgrade.sh
- status=$?
- if [ ${status} -eq 0 ]; then
- chmod +x /tmp/upgrade.sh
- /tmp/upgrade.sh ${filename} 2>&1 | tee -a ${updatelog}
- status=$?
- fi
- else
- #upgrade
- if [ -n "${update_container}" ] && [ -n "${package_newfile}" ]; then
- pkg_name=${package_newfile}
- pkg_type=${pkg_name%%-*}
- pkg_id=${pkg_name#*-}
- pkg_id=${pkg_id%%-*}
- uplog "Extracting wd.container packages for Package ID: ${package_newfile}, into ${pkg_upgrades_dir}/${pkg_type}_${pkg_id}"
- mkdir -p ${pkg_upgrades_dir}/${pkg_type}_${pkg_id}
- chmod -R 777 ${pkg_upgrades_dir}/${pkg_type}_${pkg_id}
- dpkg -i --force-overwrite ${filename} 2>&1 | tee -a ${updatelog}
- status=$?
- mv -v ${pkg_upgrades_dir}/*.deb ${pkg_upgrades_dir}/${pkg_type}_${pkg_id}/
- elif [ -z "${update_container}" ]; then
- # if upgrade dir is empty, then copy from backup location
- [ ! "$( ls -A ${pkg_upgrades_dir} )" ] && cp -av /usr/local/nas/upgrade/* ${pkg_upgrades_dir}
- # get upgrade-version
- tmp_dir=`mktemp -d`
- dpkg --control ${filename} ${tmp_dir}
- new_upgrade_version="0"
- [ -f $tmp_dir/upgrade-version ] && new_upgrade_version=`cat $tmp_dir/upgrade-version`
- current_upgrade_version="0"
- [ -f ${pkg_upgrades_dir}/upgrade-version ] && current_upgrade_version=`cat ${pkg_upgrades_dir}/upgrade-version`
- uplog "new_upgrade_version=$((new_upgrade_version))"
- uplog "current_upgrade_version=$((current_upgrade_version))"
- cp -v $tmp_dir/upgrade-version ${pkg_upgrades_dir}/upgrade-version
- if [ $((current_upgrade_version)) -gt $((new_upgrade_version)) ]; then
- # use current upgrade scripts to drive upgrade
- touch /tmp/downgrade
- uplog "Use current upgrade scripts to drive upgrade"
- ${pkg_upgrades_dir}/preinst 2>&1 | tee -a ${updatelog}
- uplog "Extract rootfs..."
- dpkg --fsys-tarfile ${filename} | tar -xvf - -C / --wildcards --no-anchored 'rootfs.*' 2>&1 | tee -a ${updatelog}
- uplog "Run postinst"
- ${pkg_upgrades_dir}/postinst 2>&1 | tee -a ${updatelog}
- else
- uplog "Newer upgrade scripts in update package, use normal update method"
- dpkg -i --force-overwrite --force-depends ${filename} 2>&1 | tee -a ${updatelog}
- fi
- status=$?
- fi
- fi
- }
- # flag error after attempting to apply upgrade using dpkg
- update_error()
- {
- error=${1}
- echo ${error} > /tmp/fw_update_status
- uplog ${error}
- echo "Error fw_update_status: ${error}" 2>&1 | tee -a ${updatelog}
- [ -z "${update_container}" ] && restoreRaid
- ledCtrl.sh LED_EV_FW_UPDATE LED_STAT_OK
- rm -f ${FW_UPDATE_MUTEX}
- exit 1
- }
- pkg_upgrade_verify()
- {
- cat ${updatelog} | grep -q "not a debian format archive"
- if [ $? -eq 0 ]; then
- update_error "failed 200 \"invalid firmware package\""
- fi
- cat ${updatelog} | grep -q "Install not supported"
- if [ $? -eq 0 ]; then
- update_error "failed 200 \"invalid firmware package\""
- fi
- cat ${updatelog} | grep -q "dpkg-deb: subprocess <decompress> returned error"
- if [ $? -eq 0 ]; then
- update_error "failed 202 \"upgrade download failure\""
- fi
- if [ ${status} -ne 0 ]; then
- echo "dkpg exited with non-zero status: ${status}"
- update_error "Update failed. Check ${updatelog} for details."
- fi
- }
- ## section: main script
- PATH=/sbin:/bin:/usr/bin:/usr/sbin:/usr/local/bin:/usr/local/sbin
- source /usr/local/sbin/data-volume-config_helper.sh 2>/dev/null
- source /etc/system.conf
- [ -f /usr/local/sbin/ledConfig.sh ] && . /usr/local/sbin/ledConfig.sh
- filename=${1}
- check_size=${2:-""}
- test=${3:-""}
- # check params
- if [ $# -lt 1 ]; then
- echo "usage: updateFirmwareFromFile.sh <filename> [check_filesize]"
- exit 1
- fi
- if [ ! -f ${filename} ]; then
- echo "File not found"
- exit 1
- fi
- # set a 'non-idle' status for the manual update-from-file case
- [ ! -f /tmp/fw_update_status ] && echo "downloading" > /tmp/fw_update_status
- logtag="`basename $0`:`date -u +"%D %T"`:"
- logger -s -t "${logtag}" "( $@ )"
- # initiate updatelog
- updatelog="/CacheVolume/update.log"
- echo "${logtag}upgrade start: $@" 2>&1 | tee ${updatelog}
- FW_UPDATE_MUTEX=/tmp/fw_update_mutex
- [ -f ${FW_UPDATE_MUTEX} ] && exit 0
- touch ${FW_UPDATE_MUTEX}
- uplog "check_size=${check_size}"
- # require that all internal drives be present before upgrade
- driveList=(`internalDrives`)
- if [ "${#driveList[@]}" -lt "${MIN_ROOTFS_DRIVE_COUNT}" ]; then
- error="failed 205 \"all drives must be present for upgrade\""
- pre-update_error $error
- fi
- # check disk usage
- dfout=`df | grep /DataVolume`
- avail=`echo "$dfout" | awk '{printf("%d",$2-$3)}'`
- if [ "${avail}" -lt "${fwUpdateSpace}" ] && [ "${system_boot_type}" != "flash" ]; then
- error="failed 201 \"not enough space on device for upgrade\""
- echo ${error} > /tmp/fw_update_status
- pre-update_error $error
- fi
- if [ "${check_size}" != "" ] && [ "${test}" == "test_size" ]; then
- uplog "truncating file for size test..."
- blocksize_ls_original=$(ls -l ${filename} | cut -d' ' -f5)
- uplog "blocksize_ls_original=$blocksize_ls_original"
- dd if=${filename} of=${filename}-new bs=1M count=120
- mv ${filename}-new ${filename}
- fi
- # check file size if file was downloaded
- if [ "${check_size}" != "" ]; then
- FileSize=( $(cat /tmp/fw_upgrade_filesize) )
- blocksize_dpkg0="${FileSize[0]}"
- blocksize_dpkg1="${FileSize[1]}"
- blocksize_ls=$(ls -l ${filename} | cut -d' ' -f5)
- uplog "blocksize_dpkg0=$blocksize_dpkg0"
- uplog "blocksize_dpkg1=$blocksize_dpkg1"
- uplog "blocksize_ls=$blocksize_ls"
- if [ "${blocksize_dpkg0}" != "${blocksize_ls}" ] && [ "${blocksize_dpkg1}" != "${blocksize_ls}" ]; then
- error="failed 202 \"failed download file size check\""
- pre-update_error "${error}"
- fi
- fi
- version_current=`cat /etc/version | tr -d .-`
- version_newfile=`dpkg -f ${filename} Version`
- version_newfile=`echo ${version_newfile} | tr -d .-`
- package_newfile=`dpkg -f ${filename} Package`
- # extract master package and update-container names
- master_package_new=${package_newfile%%-*}
- update_container=${package_newfile#*-}
- update_container=${update_container%%-*}
- [ "${master_package_name}" == "${update_container}" ] && update_container=''
- uplog "version_current=$version_current"
- uplog "version_newfile=$version_newfile"
- uplog "package_newfile=$package_newfile"
- uplog "master_package_name=$master_package_name"
- uplog "master_package_new=$master_package_new"
- uplog "update_container=$update_container"
- # declare arithmetic variable types (ensure conversion to base 10)
- let "vnew = $((10#$version_newfile))"
- package_newfile=`dpkg -f ${filename} Package`
- # extract master package and update-container names
- master_package_new=${package_newfile%%-*}
- update_container=${package_newfile#*-}
- update_container=${update_container%%-*}
- [ "${master_package_name}" == "${update_container}" ] && update_container=''
- uplog "version_current=$version_current"
- uplog "version_newfile=$version_newfile"
- uplog "package_newfile=$package_newfile"
- uplog "master_package_name=$master_package_name"
- uplog "master_package_new=$master_package_new"
- uplog "update_container=$update_container"
- # declare arithmetic variable types (ensure conversion to base 10)
- let "vnew = $((10#$version_newfile))"
- let "vnow = $((10#$version_current))"
- if [ "${master_package_new}" == "wd.container" ] || [ "${master_package_new}" == "wd.group" ] || [ "${master_package_new}" == "wd.supergroup" ]; then
- uplog "Package compatiblities will be enforced by the incomming policy rules."
- else
- # enforce same 'master-package' name
- if [ "${master_package_name}" != "${master_package_new}" ]; then
- error="failed 200 \"invalid firmware package\""
- pre-update_error $error
- fi
- # ITR#34229: don't allow down rev code to be applied
- # -but allow 'patch updates" with any version
- if [ -z "${update_container}" ] && [ "${vnew}" -lt "${vnow}" ]; then
- error="failed 200 \"invalid firmware package\""
- pre-update_error $error
- fi
- fi
- status=1
- # Prepare for package upgrade
- pkg_upgrade_init
- # Do pkg upgrades
- pkg_upgrade_exec
- # Verify upgrade
- pkg_upgrade_verify
- # Unmount & reboot
- rm -f ${FW_UPDATE_MUTEX}
- umount -f /nfs/Public
- umount -f /nfs/TimeMachineBackup
- umount -f /nfs/SmartWare
- umount -f /proc/fs/nfsd
- # sleep 10 seconds to allow UI to detect update
- sleep 10
- reboot -f -h -i &
- exit ${status}
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement