diff --git a/board/common/busybox.config b/board/common/busybox.config index 1a3a02eda5..f70c01fc58 100644 --- a/board/common/busybox.config +++ b/board/common/busybox.config @@ -1,7 +1,7 @@ # # Automatically generated make config: don't edit # Busybox version: 1.29.2 -# Fri Jan 25 20:24:12 2019 +# Fri Feb 1 22:19:53 2019 # CONFIG_HAVE_DOT_CONFIG=y @@ -384,9 +384,9 @@ CONFIG_RESET=y # CONFIG_RUN_PARTS is not set # CONFIG_FEATURE_RUN_PARTS_LONG_OPTIONS is not set # CONFIG_FEATURE_RUN_PARTS_FANCY is not set -CONFIG_START_STOP_DAEMON=y -CONFIG_FEATURE_START_STOP_DAEMON_LONG_OPTIONS=y -CONFIG_FEATURE_START_STOP_DAEMON_FANCY=y +# CONFIG_START_STOP_DAEMON is not set +# CONFIG_FEATURE_START_STOP_DAEMON_LONG_OPTIONS is not set +# CONFIG_FEATURE_START_STOP_DAEMON_FANCY is not set CONFIG_WHICH=y # @@ -621,7 +621,7 @@ CONFIG_HWCLOCK=y # CONFIG_IPCS is not set # CONFIG_LAST is not set # CONFIG_FEATURE_LAST_FANCY is not set -# CONFIG_LOSETUP is not set +CONFIG_LOSETUP=y # CONFIG_LSPCI is not set CONFIG_LSUSB=y # CONFIG_MDEV is not set diff --git a/board/common/overlay/etc/init.d/S00datapart b/board/common/overlay/etc/init.d/S00datapart index b1f25768eb..5c76f928fa 100755 --- a/board/common/overlay/etc/init.d/S00datapart +++ b/board/common/overlay/etc/init.d/S00datapart @@ -1,5 +1,8 @@ #!/bin/bash +DATA_OFFS="1024" # up to 1024MB reserved for boot + root + + test -n "${OS_VERSION}" || source /etc/init.d/base case "$1" in @@ -23,7 +26,7 @@ case "$1" in test -b ${data_dev} && exit 0 msg_begin "Creating data partition" - data_start=$((1024 * 2048)) # up to 1024MB reserved for boot + root + data_start=$((DATA_OFFS * 2048)) echo -e "n p 3 diff --git a/board/common/overlay/etc/init.d/S02restorebackups b/board/common/overlay/etc/init.d/S02restorebackups new file mode 100755 index 0000000000..fd5e733a4b --- /dev/null +++ b/board/common/overlay/etc/init.d/S02restorebackups @@ -0,0 +1,47 @@ +#!/bin/bash + +BACKUPS_DIR="/boot" +BACKUP_PATTERN="backup-*.tar.gz" +DATA_DIR="/data" + + +test -n "${OS_VERSION}" || source /etc/init.d/base + + +case "$1" in + start) + if ! ls ${BACKUPS_DIR}/${BACKUP_PATTERN} &>/dev/null; then + exit; # no backups + fi + + mount -o remount,rw /boot + + for file in ${BACKUPS_DIR}/${BACKUP_PATTERN}; do + msg_begin "Restoring backup from $(basename ${file})" + tar -mxf ${file} -C ${DATA_DIR} + if [[ $? == 0 ]]; then + rm ${file} + msg_done + else + msg_fail + fi + done + + # source os_conf again, as it might have changed after restore + test -f /etc/init.d/os_conf && source /etc/init.d/os_conf + if [[ "${OS_DEBUG}" != "true" ]]; then + mount -o remount,ro /boot + fi + ;; + + stop) + true + ;; + + *) + echo "Usage: $0 {start}" + exit 1 +esac + +exit $? + diff --git a/board/common/overlay/etc/init.d/S02modules b/board/common/overlay/etc/init.d/S03modules similarity index 100% rename from board/common/overlay/etc/init.d/S02modules rename to board/common/overlay/etc/init.d/S03modules diff --git a/board/common/overlay/etc/init.d/S03hostname b/board/common/overlay/etc/init.d/S04hostname similarity index 100% rename from board/common/overlay/etc/init.d/S03hostname rename to board/common/overlay/etc/init.d/S04hostname diff --git a/board/common/overlay/etc/init.d/S04syslog b/board/common/overlay/etc/init.d/S05syslog similarity index 100% rename from board/common/overlay/etc/init.d/S04syslog rename to board/common/overlay/etc/init.d/S05syslog diff --git a/board/common/overlay/sbin/fwupdate b/board/common/overlay/sbin/fwupdate index 4e66f01bb5..d9097227eb 100755 --- a/board/common/overlay/sbin/fwupdate +++ b/board/common/overlay/sbin/fwupdate @@ -4,14 +4,14 @@ #### usage #### function exit_usage() { - echo "Usage: fwupdate versions [-j] (lists available versions, optionally outputting json)" - echo " fwupdate current (shows the current version" - echo " fwupdate download (downloads a firmware version)" - echo " fwupdate extract (extracts the downloaded firmware archive)" - echo " fwupdate flashboot (flashes the boot partition from extracted image)" - echo " fwupdate flashreboot (prepares for reboot + root partititon flash)" - echo " fwupdate status (shows the current firmware updating status; see below)" - echo " fwupdate upgrade (performs all the operations necessary for upgrading)" + echo "Usage: fwupdate versions [-j] (lists available versions, optionally outputting json)" + echo " fwupdate current (shows the current version" + echo " fwupdate download (downloads a firmware version)" + echo " fwupdate extract (extracts the downloaded firmware archive)" + echo " fwupdate flashboot (flashes the boot partition from extracted image)" + echo " fwupdate flashreboot (prepares for reboot + root partititon flash)" + echo " fwupdate status (shows the current firmware updating status; see below)" + echo " fwupdate upgrade (performs all the operations necessary for upgrading)" echo "" echo "Statuses:" echo " idle" @@ -33,8 +33,12 @@ fi #### configuration #### +set -a +set -e + SYS_VERSION_FILE=/etc/version SYS_BOARD_FILE=/etc/board +OS_CONF_FILE=/etc/init.d/os_conf MIN_FREE_DISK=$((500*1024)) # 500 MB VER_FILE=version @@ -58,11 +62,15 @@ XZCAT_PID_FILE=xzcat.pid DD_LOG_FILE=dd.log DD_PID_FILE=dd.pid +source ${OS_CONF_FILE} +source ${SYS_VERSION_FILE} + #### disk & partition devices #### BOOT_DEV=$(mount | grep /boot | cut -d ' ' -f 1) ROOT_DEV=${BOOT_DEV:0:-1}2 +DATA_DEV=${BOOT_DEV:0:-1}3 DISK_DEV=$(mount | grep /boot | cut -d ' ' -f 1) if [[ "${ROOT_DEV}" =~ ^([/a-z0-9]+)(p[0-9])$ ]]; then # e.g. /dev/mmcblk0p2 DISK_DEV=${BASH_REMATCH[1]} @@ -77,8 +85,6 @@ fi #### versions #### function show_versions() { - source /etc/init.d/os_conf # we need this for the OS_ vars - board=$(cat ${SYS_BOARD_FILE}) show_json=$1 @@ -112,8 +118,6 @@ function show_versions() { } function show_current() { - source ${SYS_VERSION_FILE} - echo ${OS_VERSION} } @@ -144,8 +148,6 @@ function do_download() { fi fi - source /etc/init.d/os_conf # we need this for the OS_ vars - board=$(cat ${SYS_BOARD_FILE}) url=$1 version=$1 @@ -208,6 +210,34 @@ function download_status() { #### extract #### +function run_pre_upgrade() { + which losetup &>/dev/null || return 0 + + root_start=$(cat ${FW_DIR}/${ROOT_INFO_FILE} | cut -d ' ' -f 1) + tmp_mnt="/tmp/fwupdate_root" + loop="/dev/loop4" + pre_upgrade="${tmp_mnt}/usr/share/pre-upgrade/*" + + mkdir -p ${tmp_mnt} + losetup -o $((root_start * 1024 * 1024)) ${loop} ${FW_DIR}/${FW_FILE_EXTR} + mount ${loop} ${tmp_mnt} + if [[ -d ${pre_upgrade} ]]; then + for script in ${pre_upgrade}/*.sh; do + echo "running pre-upgrade script $(basename ${script})" + if [[ -x ${script} ]] && ! ${script}; then + # non-zero exit status of pre-upgrade script indicates that + # the upgrade process must not be continued + + echo "aborted by pre-upgrade script" + return 1 + fi + done + fi + + umount ${tmp_mnt} + losetup -d ${loop} +} + function do_extract() { echo "extracting..." @@ -249,35 +279,9 @@ function do_extract() { exit 1 fi - # verify available partition space - - fw_boot_info=$(fdisk --bytes -l -o device,start,end,size ${FW_DIR}/${FW_FILE_EXTR} | grep "${FW_FILE_EXTR}1") - fw_boot_info=(${fw_boot_info}) - fw_boot_size=${fw_boot_info[3]} - - fw_root_info=$(fdisk --bytes -l -o device,start,end,size ${FW_DIR}/${FW_FILE_EXTR} | grep "${FW_FILE_EXTR}2") - fw_root_info=(${fw_root_info}) - fw_root_size=${fw_root_info[3]} - - disk_boot_info=$(fdisk --bytes -l -o device,start,end,size ${DISK_DEV} | grep ${BOOT_DEV}) - disk_boot_info=(${disk_boot_info}) - disk_boot_size=${disk_boot_info[3]} - - disk_root_info=$(fdisk --bytes -l -o device,start,end,size ${DISK_DEV} | grep ${ROOT_DEV}) - disk_root_info=(${disk_root_info}) - disk_root_size=${disk_root_info[3]} - - if [[ ${disk_boot_size} -lt ${fw_boot_size} ]]; then - echo "not enough space on boot partition (${fw_boot_size} needed, ${disk_boot_size} available)" 1>&2 - exit 1 - fi - - if [[ ${disk_root_size} -lt ${fw_root_size} ]]; then - echo "not enough space on root partition (${fw_root_size} needed, ${disk_root_size} available)" 1>&2 - exit 1 - fi - # TODO verify hash + + run_pre_upgrade } function extract_status() { @@ -303,18 +307,55 @@ function extract_status() { #### flash boot #### -function flash_boot() { +function reallocate_boot_part() { + boot_info=$(fdisk --bytes -l -o device,start,end,size ${DISK_DEV} | grep "${BOOT_DEV}") + boot_info=(${boot_info}) + + root_info=$(fdisk --bytes -l -o device,start,end,size ${DISK_DEV} | grep "${ROOT_DEV}") + root_info=(${root_info}) + + fw_boot_info=$(fdisk --bytes -l -o device,start,end,size ${FW_DIR}/${FW_FILE_EXTR} | grep "${FW_FILE_EXTR}1") + fw_boot_info=(${fw_boot_info}) + + if [[ ${boot_info[1]} == ${fw_boot_info[1]} ]] && + [[ ${boot_info[2]} == ${fw_boot_info[2]} ]]; then + + return # all good + fi + + echo "reallocating boot partition..." + + # check overlapping with root partition + if [[ ${fw_boot_info[2]} -ge ${root_info[1]} ]]; then + echo "cannot reallocate boot partition: will overlap with root" + return 1 + fi + + fdisk -w auto ${DISK_DEV} >/dev/null < ${FW_DIR}/${ROOT_INFO_FILE} + + reallocate_boot_part dd if=${FW_DIR}/${FW_FILE_EXTR} skip=${boot_start} of=${BOOT_DEV} bs=1048576 count=${boot_size} &>${FW_DIR}/${DD_LOG_FILE} & pid=$! @@ -373,7 +416,51 @@ function flash_cleanup() { #### flash reboot #### -function flash_reboot() { +function reallocate_root_part() { + root_info=$(fdisk --bytes -l -o device,start,end,size ${DISK_DEV} | grep "${ROOT_DEV}") + root_info=(${root_info}) + + data_info=$(fdisk --bytes -l -o device,start,end,size ${DISK_DEV} | grep "${DATA_DEV}") + data_info=(${data_info}) + + fw_root_info=$(fdisk --bytes -l -o device,start,end,size ${FW_DIR}/${FW_FILE_EXTR} | grep "${FW_FILE_EXTR}2") + fw_root_info=(${fw_root_info}) + + if [[ ${root_info[1]} == ${fw_root_info[1]} ]] && + [[ ${root_info[2]} == ${fw_root_info[2]} ]]; then + + return # all good + fi + + echo "reallocating root partition..." + + # check overlapping with data partition + if [[ ${fw_root_info[2]} -ge ${data_info[1]} ]]; then + echo "cannot reallocate root partition: will overlap with data" + return 1 + fi + + fdisk -w auto ${DISK_DEV} >/dev/null <