diff --git a/package/system/procd/Makefile b/package/system/procd/Makefile index adc8933e0f..52c181c8f7 100644 --- a/package/system/procd/Makefile +++ b/package/system/procd/Makefile @@ -1,14 +1,14 @@ include $(TOPDIR)/rules.mk PKG_NAME:=procd -PKG_VERSION:=2014-06-06 +PKG_VERSION:=2014-06-10 PKG_RELEASE=$(PKG_SOURCE_VERSION) PKG_SOURCE_PROTO:=git PKG_SOURCE_URL:=git://nbd.name/luci2/procd.git PKG_SOURCE_SUBDIR:=$(PKG_NAME)-$(PKG_VERSION) -PKG_SOURCE_VERSION:=53c1ea6b9ade10eff3cec07519db862b365a4233 +PKG_SOURCE_VERSION:=b76eda6cd8ba061f49af4074838e6a42ae94144c PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION)-$(PKG_SOURCE_VERSION).tar.gz CMAKE_INSTALL:=1 @@ -25,12 +25,19 @@ TARGET_LDFLAGS += $(if $(CONFIG_USE_EGLIBC),-lrt) define Package/procd SECTION:=base CATEGORY:=Base system - DEPENDS:=+ubusd +ubus +libjson-script +ubox +USE_EGLIBC:librt +libubox +libubus + DEPENDS:=+ubusd +ubus +libjson-script +ubox +USE_EGLIBC:librt +libubox +libubus +NAND_SUPPORT:procd-nand + TITLE:=OpenWrt system process manager +endef + +define Package/procd-nand + SECTION:=utils + CATEGORY:=Utilities + DEPENDS:=@NAND_SUPPORT +ubi-utils TITLE:=OpenWrt system process manager endef define Package/procd/install - $(INSTALL_DIR) $(1)/sbin $(1)/etc $(1)/lib/functions + $(INSTALL_DIR) $(1)/sbin $(1)/etc $(1)/lib/functions $(CP) $(PKG_INSTALL_DIR)/usr/sbin/{init,procd,askfirst,udevtrigger} $(1)/sbin/ $(INSTALL_BIN) ./files/reload_config $(1)/sbin/ @@ -38,4 +45,12 @@ define Package/procd/install $(INSTALL_DATA) ./files/procd.sh $(1)/lib/functions/ endef +define Package/procd-nand/install + $(INSTALL_DIR) $(1)/sbin $(1)/lib/upgrade + + $(CP) $(PKG_INSTALL_DIR)/usr/sbin/upgraded $(1)/sbin/ + $(INSTALL_DATA) ./files/nand.sh $(1)/lib/upgrade/ +endef + $(eval $(call BuildPackage,procd)) +$(eval $(call BuildPackage,procd-nand)) diff --git a/package/system/procd/files/nand.sh b/package/system/procd/files/nand.sh new file mode 100644 index 0000000000..7d1a55db0c --- /dev/null +++ b/package/system/procd/files/nand.sh @@ -0,0 +1,303 @@ +#!/bin/sh +# Copyright (C) 2014 OpenWrt.org +# + +. /lib/functions.sh + +# combined-image uses 64k blocks +CI_BLKSZ=65536 +# 'data' partition on NAND contains UBI +CI_UBIPART="ubi" + +nand_find_volume() { + local ubidevdir ubivoldir + ubidevdir="/sys/devices/virtual/ubi/$1" + [ ! -d "$ubidevdir" ] && return 1 + for ubivoldir in $ubidevdir/${1}_*; do + [ ! -d "$ubivoldir" ] && continue + if [ "$( cat $ubivoldir/name )" = "$2" ]; then + basename $ubivoldir + return 0 + fi + done +} + +nand_find_ubi() { + local ubidevdir ubidev mtdnum + mtdnum="$( find_mtd_index $1 )" + [ ! "$mtdnum" ] && return 1 + for ubidevdir in /sys/devices/virtual/ubi/ubi*; do + [ ! -d "$ubidevdir" ] && continue + cmtdnum="$( cat $ubidevdir/mtd_num )" + [ ! "$mtdnum" ] && continue + if [ "$mtdnum" = "$cmtdnum" ]; then + ubidev=$( basename $ubidevdir ) + echo $ubidev + return 0 + fi + done +} + +nand_restore_config() { + sync + local ubidev=$( nand_find_ubi $CI_UBIPART ) + local ubivol="$( nand_find_volume $ubidev rootfs_data )" + [ ! "$ubivol" ] && + ubivol="$( nand_find_volume $ubidev rootfs )" + mkdir /tmp/new_root + if ! mount -t ubifs /dev/$ubivol /tmp/new_root; then + echo "mounting ubifs $ubivol failed" + rmdir /tmp/new_root + return 1 + fi + mv "$1" "/tmp/new_root/sysupgrade.tgz" + umount /tmp/new_root + sync + rmdir /tmp/new_root +} + +nand_upgrade_ubinized() { + local upgrade_image="$1" + local conf_tar="$2" + local save_config="$3" + local mtdnum="$( find_mtd_index "$CI_UBIPART" )" + if [ ! "$mtdnum" ]; then + echo "cannot find mtd device $CI_UBIPART" + return 1; + fi + local mtddev="/dev/mtd${mtdnum}" + ubidetach -p "${mtddev}" || true + sync + ubiformat "${mtddev}" -y -f "$upgrade_image" + ubiattach -p "${mtddev}" + sync + if [ -f "$conf_tar" -a "$save_config" -eq 1 ]; then + nand_restore_config "$conf_tar" + fi + return 0; +} + +# get the first 4 bytes (magic) of a given file starting at offset in hex format +get_magic_long_at() { + dd if="$2" skip=$1 bs=$CI_BLKSZ count=1 2>/dev/null | hexdump -v -n 4 -e '1/1 "%02x"' +} + +identify() { + local block; + local magic=$( get_magic_long_at ${2:-0} "$1" ) + case "$magic" in + "55424923") + echo "ubi" + ;; + "31181006") + echo "ubifs" + ;; + "68737173") + echo "squashfs" + ;; + "d00dfeed") + echo "fit" + ;; + "4349"*) + echo "combined" + ;; + *) + echo "unknown $magic" + ;; + esac +} + +nand_upgrade_combined_ubi() { + local kernel_image="$1" + local kernel_length=0 + local rootfs_image="$2" + local rootfs_length=`ls -la $rootfs_image | awk '{ print $5}')` + local conf_tar="$3" + local has_env="${4:-0}" + + local root_fs="$( identify "$rootfs_image" )" + local mtdnum="$( find_mtd_index "$CI_UBIPART" )" + local has_kernel=0 + + [ -z "$kernel_image" ] || { + has_kernel=1 + kernel_length=`ls -la $kernel_image | awk '{ print $5}')` + echo "kernel length $kernel_length" + } + [ "$has_kernel" = 0 ] || echo "kernel is inside ubi" + echo "rootfs type $root_fs, length $rootfs_length" + + if [ ! "$mtdnum" ]; then + echo "cannot find ubi mtd partition $CI_UBIPART" + return 1 + fi + local ubidev="$( nand_find_ubi "$CI_UBIPART" )" + if [ ! "$ubidev" ]; then + ubiattach -m "$mtdnum" + sync + ubidev="$( nand_find_ubi "$CI_UBIPART" )" + fi + if [ ! "$ubidev" ]; then + ubiformat /dev/mtd$mtdnum -y + ubiattach -m "$mtdnum" + sync + ubidev="$( nand_find_ubi "$CI_UBIPART" )" + [ -z "$has_env" ] || { + ubimkvol /dev/$ubidev -n 0 -N ubootenv -s 1MiB + ubimkvol /dev/$ubidev -n 1 -N ubootenv2 -s 1MiB + } + fi + local kern_ubivol="$( nand_find_volume $ubidev kernel )" + local root_ubivol="$( nand_find_volume $ubidev rootfs )" + local data_ubivol="$( nand_find_volume $ubidev rootfs_data )" + + # remove ubiblock device of rootfs + local root_ubiblk="ubiblock${root_ubivol:3}" + if [ "$root_ubivol" -a -e "/dev/$root_ubiblk" ]; then + echo "removing $root_ubiblk" + if ! ubiblock -r /dev/$root_ubivol; then + echo "cannot remove $root_ubiblk" + return 1; + fi + fi + + # kill volumes + if [ "$kern_ubivol" ]; then + ubirmvol /dev/$ubidev -N kernel || true + fi + if [ "$root_ubivol" ]; then + ubirmvol /dev/$ubidev -N rootfs || true + fi + if [ "$data_ubivol" ]; then + ubirmvol /dev/$ubidev -N rootfs_data || true + fi + + # update kernel + if [ "$has_kernel" = "1" ]; then + if ! ubimkvol /dev/$ubidev -N kernel -s $kernel_length; then + echo "cannot create kernel volume" + return 1; + fi + fi + + # update rootfs + local root_size_param + if [ "$root_fs" = "ubifs" ]; then + root_size_param="-m" + else + root_size_param="-s $rootfs_length" + fi + if ! ubimkvol /dev/$ubidev -N rootfs $root_size_param; then + echo "cannot create rootfs volume" + return 1; + fi + + # create rootfs_data for non-ubifs rootfs + if [ "$root_fs" != "ubifs" ]; then + if ! ubimkvol /dev/$ubidev -N rootfs_data -m; then + echo "cannot initialize rootfs_data volume" + return 1 + fi + fi + sync + + if [ "$has_kernel" = "1" ]; then + local kern_ubivol="$( nand_find_volume $ubidev kernel )" + ubiupdatevol /dev/$kern_ubivol -s $kernel_length $kernel_image + fi + + local root_ubivol="$( nand_find_volume $ubidev rootfs )" + ubiupdatevol /dev/$root_ubivol -s $rootfs_length $rootfs_image + if [ -f "$conf_tar" ]; then + nand_restore_config "$conf_tar" + fi + echo "sysupgrade successfull" + return 0 +} + +nand_do_upgrade_stage1() { + local board_name="$1" + local tar_file="$2" + local kernel_file="" + local kernel_file="" + + tar xzf $tar_file -C /tmp/ + [ -f "/tmp/sysupgrade-$board_name/CONTROL" ] || { + echo "failed to find /tmp/sysupgrade-$board_name/CONTROL" + return 1 + } + + kernel_file=/tmp/sysupgrade-$board_name/kernel + [ -f "$kernel_file" ] || { + echo "$kernel_file is missing" + return 1 + } + + rootfs_file=/tmp/sysupgrade-$board_name/root + [ -f "$rootfs_file" ] || { + echo "$rootfs_file is missing" + return 1 + } + + echo -n /tmp/sysupgrade-$board_name > /tmp/sysupgrade-nand-folder + cp /sbin/upgraded /tmp/ + + return 0 +} + +nand_do_upgrade_stage2() { + rootfs_file=$1/root + kernel_file=$1/kernel + config_file=$1/config + + [ -f $config_file ] || config_file="" + + . $1/CONTROL + + [ "$UBI_KERNEL" = "1" ] || { + mtd write $kernel_file kernel + kernel_file="" + } + nand_upgrade_combined_ubi "$kernel_file" "$rootfs_file" "$conf_tar" "$UBI_ENV" + reboot -f +} + +nand_do_upgrade() { + [ $1 = "nand" ] && { + [ -d "$2" ] && { + touch /tmp/sysupgrade + + killall -9 telnetd + killall -9 dropbear + killall -9 ash + + kill_remaining TERM + sleep 3 + kill_remaining KILL + + sleep 1 + + if [ -n "$(rootfs_type)" ]; then + v "Switching to ramdisk..." + run_ramfs ". /lib/functions.sh; include /lib/upgrade; nand_do_upgrade_stage2 $2" + else + nand_do_upgrade_stage2 $2 + fi + return 0 + } + echo "Nand upgrade failed" + exit 1 + } +} + +nand_upgrade_stage1() { + [ -f /tmp/sysupgrade-nand-folder ] && { + folder="$(cat /tmp/sysupgrade-nand-folder)" + [ "$SAVE_CONFIG" = 1 -a -f "$CONF_TAR" ] && + cp $CONF_TAR $folder/config + + ubus call system nandupgrade "{\"folder\": \"$folder\" }" + exit 0 + } +} +append sysupgrade_pre_upgrade nand_upgrade_stage1