ADD_SUBDIRECTORY(src/upgrade-apply)
ADD_SUBDIRECTORY(src/blkid-print)
ADD_SUBDIRECTORY(data)
+ADD_SUBDIRECTORY(scripts/rw-upgrade)
%define upgrade_support_dir %{_libexecdir}/upgrade-support
+%define upgrade_scripts_dir %TZ_SYS_UPGRADE
Name: upgrade-engine
Summary: Upgrade engine for Tizen
-Version: 7.5.0
+Version: 7.5.1
Release: 0
Group: System
License: Apache-2.0
Requires: tar
Requires: gzip
+# from factory-reset:
+Requires: %{_bindir}/rstsmack
+
%description
Update engine for updating Tizen platform images using delta files
generated by upgrade-tools.
-DCMAKE_INSTALL_PREFIX=%{_prefix} \
-DIMG_VERIFIER_ROOT_CA_DIR=%{img_verifier_root_ca_dir} \
-DUPGRADE_INITRD_LIST_DIR=%{upgrade_initrd_list_dir} \
+ -DUPGRADE_SCRIPTS_DIR=%{upgrade_scripts_dir} \
+ -DUPGRADE_VAR_DIR=%TZ_SYS_VAR \
+ -DUPGRADE_PKGSCRIPTS_DIR=%TZ_SYS_UPGRADE_SCRIPTS \
+ -DUNIT_DIR=%{_unitdir} \
.
make %{?jobs:-j%jobs}
install -m 644 scripts/clone_partitions/clone_partitions_recovery.service %{buildroot}%{_unitdir}
ln -s ../clone_partitions_recovery.service %{buildroot}%{_unitdir}/recovery.service.wants/
+# rw-update
+mkdir -p %{buildroot}%{_unitdir}/system-update.target.wants
+mkdir -p %{buildroot}%{_unitdir}/data-checkpoint.target.wants
+mkdir -p %{buildroot}%{_unitdir}/delayed.target.wants
+ln -s ../getty.target %{buildroot}%{_unitdir}/system-update.target.wants
+ln -s ../cynara.socket %{buildroot}%{_unitdir}/system-update.target.wants
+ln -s ../dbus.socket %{buildroot}%{_unitdir}/system-update.target.wants
+ln -s ../udev-sdb-init.service %{buildroot}%{_unitdir}/system-update.target.wants
+ln -s ../offline-update.service %{buildroot}%{_unitdir}/system-update.target.wants
+ln -s ../udev-trigger-dmbow@.service %{buildroot}%{_unitdir}/system-update.target.wants/udev-trigger-dmbow@user.service
+ln -s ../data-checkpoint.target %{buildroot}%{_unitdir}/system-update.target.wants
+ln -s ../data-checkpoint.service %{buildroot}%{_unitdir}/data-checkpoint.target.wants/data-checkpoint.service
+ln -s ../update-post.service %{buildroot}%{_unitdir}/system-update.target.wants
+ln -s ../update-finalize.service %{buildroot}%{_unitdir}/delayed.target.wants
+
+%posttrans
+newrulesfile=99-sdb-switch.rules
+newrulespath=%{upgrade_scripts_dir}/$newrulesfile
+rulesdir=/usr/lib/udev/rules.d
+if [ -e "$rulesdir/$newrulesfile" ]; then
+ echo "$newrulesfile exists. Skip creating symlink"
+else
+ mkdir -p "$rulesdir"
+ ln -sf "$newrulespath" "$rulesdir"
+fi
+
%files
%license LICENSE
%manifest upgrade.manifest
# Image verifier
%{_sbindir}/img-verifier
%attr(755,root,root) %{img_verifier_root_ca_dir}
+# rw-upgrade
+%{_unitdir}/data-checkpoint.service
+%{_unitdir}/data-checkpoint.target
+%{_unitdir}/data-checkpoint.target.wants/data-checkpoint.service
+%{_unitdir}/delayed.target.wants/update-finalize.service
+%{_unitdir}/offline-update.service
+%{_unitdir}/system-update.target.wants/cynara.socket
+%{_unitdir}/system-update.target.wants/data-checkpoint.target
+%{_unitdir}/system-update.target.wants/dbus.socket
+%{_unitdir}/system-update.target.wants/getty.target
+%{_unitdir}/system-update.target.wants/offline-update.service
+%{_unitdir}/system-update.target.wants/udev-sdb-init.service
+%{_unitdir}/system-update.target.wants/udev-trigger-dmbow@user.service
+%{_unitdir}/system-update.target.wants/update-post.service
+%{_unitdir}/udev-sdb-init.service
+%{_unitdir}/udev-trigger-dmbow@.service
+%{_unitdir}/update-finalize.service
+%{_unitdir}/update-post.service
+%{upgrade_scripts_dir}/99-sdb-switch.rules
+%{upgrade_scripts_dir}/install-sdb-rule.sh
+%{upgrade_scripts_dir}/record-version.sh
+%{upgrade_scripts_dir}/rw-update-macro.inc
+%{upgrade_scripts_dir}/update-checkpoint-create.sh
+%{upgrade_scripts_dir}/update-finalize.sh
+%{upgrade_scripts_dir}/update-init.sh
+%{upgrade_scripts_dir}/update-post.sh
+%{upgrade_scripts_dir}/update.sh
--- /dev/null
+SUBSYSTEM=="switch", ATTR{name}=="usb_cable", ATTR{state}=="1", RUN+="/usr/bin/direct_set_debug.sh --sdb-set"
+SUBSYSTEM=="switch", ATTR{name}=="usb_cable", ATTR{state}=="0", RUN+="/usr/bin/direct_set_debug.sh --sdb-unset"
--- /dev/null
+CONFIGURE_FILE(install-sdb-rule.sh.in install-sdb-rule.sh @ONLY)
+CONFIGURE_FILE(update-init.sh.in update-init.sh @ONLY)
+CONFIGURE_FILE(update.sh.in update.sh @ONLY)
+CONFIGURE_FILE(update-finalize.sh.in update-finalize.sh @ONLY)
+CONFIGURE_FILE(record-version.sh.in record-version.sh @ONLY)
+CONFIGURE_FILE(udev-sdb-init.service.in udev-sdb-init.service @ONLY)
+CONFIGURE_FILE(offline-update.service.in offline-update.service @ONLY)
+CONFIGURE_FILE(data-checkpoint.service.in data-checkpoint.service @ONLY)
+
+INSTALL(FILES
+ udev-sdb-init.service
+ offline-update.service
+ data-checkpoint.service
+ data-checkpoint.target
+ update-post.service
+ update-finalize.service
+ udev-trigger-dmbow@.service
+ DESTINATION ${UNIT_DIR})
+
+INSTALL(FILES
+ 99-sdb-switch.rules
+ rw-update-macro.inc
+ DESTINATION ${UPGRADE_SCRIPTS_DIR})
+
+INSTALL(FILES
+ install-sdb-rule.sh
+ record-version.sh
+ update-init.sh
+ update.sh
+ update-checkpoint-create.sh
+ update-post.sh
+ update-finalize.sh
+ DESTINATION ${UPGRADE_SCRIPTS_DIR}
+ PERMISSIONS OWNER_READ OWNER_EXECUTE GROUP_READ GROUP_EXECUTE WORLD_READ WORLD_EXECUTE)
--- /dev/null
+[Unit]
+Description=Data checkpoint
+DefaultDependencies=no
+Before=systemd-journald.service opt.mount opt-usr.mount mnt-inform.mount
+
+
+[Service]
+Type=oneshot
+ExecStart=@UPGRADE_SCRIPTS_DIR@/update-checkpoint-create.sh
+RemainAfterExit=yes
+StandardOutput=journal+console
+StandardError=journal+console
+SmackProcessLabel=System
+
+[Install]
+WantedBy=data-checkpoint.target
+
--- /dev/null
+[Unit]
+Description=Data checkpoint
+DefaultDependencies=no
+Conflicts=shutdown.target
+Before=local-fs-pre.target
+OnFailure=emergency.target
+OnFailureJobMode=replace-irreversibly
--- /dev/null
+#!/bin/bash
+
+PATH="/usr/bin:/bin:/usr/sbin:/sbin"
+
+SDB_RULE="99-sdb-switch.rules"
+DEST=/opt/data/update
+
+if [ ! -e ${DEST}/${SDB_RULE} ]; then
+ /bin/mkdir -p ${DEST}
+ /bin/cp @UPGRADE_SCRIPTS_DIR@/${SDB_RULE} ${DEST}
+fi
--- /dev/null
+[Unit]
+Description=System update script service
+DefaultDependencies=no
+Requires=sysinit.target
+After=sysinit.target
+
+[Service]
+Type=oneshot
+SmackProcessLabel=System::Privileged
+ExecStartPre=/bin/rm -f @UPGRADE_VAR_DIR@/log/system-rw-update.log
+ExecStart=@UPGRADE_SCRIPTS_DIR@/update-init.sh
+StandardOutput=file:@UPGRADE_VAR_DIR@/log/system-rw-update.log
+StandardError=file:@UPGRADE_VAR_DIR@/log/system-rw-update.log
--- /dev/null
+#!/bin/sh
+PATH="/usr/bin:/bin:/usr/sbin:/sbin"
+
+RW_MACRO=@UPGRADE_SCRIPTS_DIR@/rw-update-macro.inc
+
+if [ -e ${RW_MACRO} ]; then
+ source ${RW_MACRO}
+ write_version_info
+fi
--- /dev/null
+#!/bin/sh
+
+STAT="/usr/bin/stat"
+OLD_VER=
+NEW_VER=
+OLD_VER_INFO="/opt/etc/version"
+COLOR_ERROR='\033[01;31m'
+COLOR_DEBUG='\033[01;34m'
+COLOR_NOTIFY='\033[01;33m'
+COLOR_RESET='\033[00;00m'
+
+DEBUG()
+{
+ LOG_TEXT=$1
+ echo -e "${COLOR_DEBUG}${LOG_TEXT}${COLOR_RESET}"
+}
+
+ERROR()
+{
+ LOG_TEXT=$1
+ echo -e "${COLOR_ERROR}${LOG_TEXT}${COLOR_RESET}"
+}
+
+NOTIFY()
+{
+ LOG_TEXT=$1
+ echo -e "${COLOR_NOTIFY}${LOG_TEXT}${COLOR_RESET}"
+}
+
+CRITICAL_LOG()
+{
+ LOG="[$SCRIPT_NAME]$1"
+ dlogsend -k "$LOG"
+ if [ "$2" != "" ]; then
+ echo "$LOG" >> "$2"
+ fi
+ echo "$LOG"
+}
+
+# Convert version to 4 digits
+convert_version() {
+ i=0
+ VER=(0 0 0 0)
+ for ENT in $(echo "$1" | tr "." "\n"); do
+ VER[$i]=$ENT
+ ((i++))
+ done
+ CVT_VER=${VER[0]}.${VER[1]}.${VER[2]}.${VER[3]}
+}
+
+get_version_info() {
+ if [ -f $OLD_VER_INFO ]; then
+ source $OLD_VER_INFO
+ fi
+ NEW_VER=$(cat /etc/config/model-config.xml | grep platform.version\" \
+ | sed -e 's/.*>\(.*\)<.*/\1/' | head -1)
+ convert_version $NEW_VER
+ NEW_VER=$CVT_VER
+}
+
+write_version_info() {
+ get_version_info
+ echo "OLD_VER=$NEW_VER" > $OLD_VER_INFO
+ /bin/chmod 775 $OLD_VER_INFO
+ /bin/chown .system_fw $OLD_VER_INFO
+}
+
+BACKUP_ZIP="/usr/system/RestoreDir/opt.zip"
+
+restore_from_zip() {
+
+ TARGET_FILE=$1
+ TARGET_DIR=$(dirname /$TARGET_FILE)
+
+ echo "restore_from_zip: $TARGET_FILE"
+ if [ ! -d $TARGET_DIR ]; then
+ mkdir -p $TARGET_DIR
+ fi
+
+ # The attributes of directory can not be overwritten by unzip.
+ # Unzip the directory into temp path and copy it to original path.
+ if [ "z${TARGET_FILE: -1}" = "z/" ]; then
+ RESTORE_DIR_PATH="/tmp/restored_dir"
+ mkdir -p $RESTORE_DIR_PATH
+ unzip -oX $BACKUP_ZIP $TARGET_FILE -d $RESTORE_DIR_PATH > /dev/null
+ cp -af $RESTORE_DIR_PATH/$TARGET_FILE $TARGET_DIR
+ rm -rf $RESTORE_DIR_PATH
+ else
+ unzip -oX $BACKUP_ZIP $TARGET_FILE -d / > /dev/null
+ fi
+
+ # Restore smack label
+ TMP=$(mktemp /tmp/smackinfo.XXXXXX)
+ PATH_FOR_SMACK=$(echo $TARGET_FILE | sed -e "s/\/$//")
+ SMACK_VAL=$(grep "$PATH_FOR_SMACK " /usr/system/RestoreDir/smack_label.txt | \
+ { read FILE SMACK; echo $SMACK; })
+ if [ "z$SMACK_VAL" = "z" ]; then
+ echo "No smack label for $PATH_FOR_SMACK"
+ else
+ echo "/$PATH_FOR_SMACK $SMACK_VAL" > $TMP
+ rstsmack $TMP
+ fi
+ rm $TMP
+}
+
+restore_backup_file() {
+
+ OVERWRITE=
+ RESTORE_PATH=
+
+ while [ "z$1" != "z" ]; do
+ case $1 in
+ -f )
+ OVERWRITE=$1
+ ;;
+ -r )
+ ;;
+ * )
+ RESTORE_PATH=$1
+ ;;
+ esac
+ shift
+ done
+
+ if [ "z$RESTORE_PATH" = "z" ]; then
+ echo "There is no file to restore"
+ return
+ fi
+
+ if [ ! "z${RESTORE_PATH:0:1}" = "z/" ]; then
+ echo "Full path of file is required"
+ return
+ fi
+
+ if [ -e "$RESTORE_PATH" ]; then
+ if [ ! "z$OVERWRITE" = "z" ]; then
+ echo "Warning: $RESTORE_PATH already exists. It will be overwritten"
+ else
+ echo "Error: $RESTORE_PATH already exists"
+ return
+ fi
+ fi
+
+ # Check if the target file is backed up
+ PATH_FOR_ZIP=$(echo $RESTORE_PATH | sed -e "s/^\///")
+ FOUND_FILES=$(unzip -l $BACKUP_ZIP | awk '{print $4}' | \
+ grep "^$PATH_FOR_ZIP")
+ FOUND_FILE=$(echo "$FOUND_FILES" | \
+ grep -E "$PATH_FOR_ZIP$|$PATH_FOR_ZIP/$")
+ if [ "z$FOUND_FILE" = "z" ]; then
+ echo "Error: $RESTORE_PATH was not backed up"
+ return
+ fi
+
+ echo "restore_backup_file: $RESTORE_PATH"
+ if [ ! "z${FOUND_FILE: -1}" = "z/" ]; then
+ restore_from_zip $FOUND_FILE
+ else
+ for FILE in $FOUND_FILES; do
+ restore_from_zip $FILE
+ done
+ fi
+}
+
+COMMIT_BOW_PARTITION()
+{
+ LABEL=${1}
+
+ BOWDEV_PATH=/dev/mapper/bowdev_${LABEL}
+ DM_NUMBER=$(($("${STAT}" -c "0x%T" $(readlink -f ${BOWDEV_PATH}))))
+ echo 2 > /sys/block/dm-${DM_NUMBER}/bow/state
+ NOTIFY "Changes on partition ${LABEL} commited (dm-bow)"
+}
+
+COMMIT_F2FS_PARTITION()
+{
+ LABEL=${1}
+ PART_DEVICE=${2}
+
+ mount -o remount,checkpoint=enable "${PART_DEVICE}"
+ NOTIFY "Changes on partition ${LABEL} commited (f2fs)"
+}
+
+DELETE_BTRFS_PARTITION() {
+ PART="$1"
+ MNT_POINT="$("$FINDMNT" "$PART" -o TARGET)"
+ if [ "$MNT_POINT" = "" ]; then
+ ERROR "Unable to find btrfs mountpoint for: $PART"
+ return
+ fi
+ NOTIFY "Deleting btrfs snapshot"
+ umount "${MNT_POINT}"
+ mount -o subvolid=5,rw "${PART}" "${MNT_POINT}"
+ btrfs subvolume delete "$MNT_POINT"/fota/RO_update
+ rm -rf "$MNT_POINT/fota/RO_update"
+ umount "${MOUNT_POINT}"
+ mount -o rw "${PART}" "${MNT_POINT}"
+}
+
+
+COMMIT_BTRFS_PARTITION()
+{
+ LABEL=${1}
+ PART_SYSTEM_DATA=$(blkid --match-token PARTLABEL="${LABEL}" -o device -l || blkid --match-token LABEL="${LABEL}" -o device -l)
+ DELETE_BTRFS_PARTITION "${PART_SYSTEM_DATA}"
+ NOTIFY "Changes on partition ${LABEL} commited (btrfs)"
+}
+
+COMMIT_PARTITION()
+{
+ LABEL=${1}
+
+ PART_DEVICE=$(blkid --match-token PARTLABEL="${LABEL}" -o device -l || blkid --match-token LABEL="${LABEL}" -o device -l)
+ if [ -z "${PART_DEVICE}" ]; then
+ NOTIFY "WARNING: Partition ${LABEL} not found"
+ return
+ fi
+
+ TYPE=$(blkid ${PART_DEVICE} -o value -s TYPE | tail -n 1)
+ if [ "${TYPE}" = "ext4" ]; then
+ COMMIT_BOW_PARTITION "${LABEL}"
+ elif [ "${TYPE}" = "f2fs" ]; then
+ COMMIT_F2FS_PARTITION "${LABEL}" ${PART_DEVICE}
+ elif [ "${TYPE}" = "btrfs" ]; then
+ COMMIT_BTRFS_PARTITION "${LABEL}"
+ else
+ ERROR "ERROR: Cannot commit ${LABEL}: Unsupported filesystem ${TYPE}"
+ fi
+}
+
+COMMIT_CHANGES()
+{
+ COMMIT_PARTITION system-data
+ COMMIT_PARTITION user
+ if [[ ! $(</proc/cmdline) =~ partition_ab= ]]; then
+ # Support legacy (non-A/B) case
+ COMMIT_PARTITION hal
+ fi
+}
--- /dev/null
+[Unit]
+Description=Install rule for udev sdb
+DefaultDependencies=no
+Before=sysinit.target systemd-udevd.service
+
+[Service]
+SmackProcessLabel=System
+Type=oneshot
+ExecStart=@UPGRADE_SCRIPTS_DIR@/install-sdb-rule.sh
--- /dev/null
+# If coldplug (systemd-udev-trigger.service) is called before the "local file
+# system" target is reached, it will not be possible to mount created bow
+# device because it will have the "SYSTEMD_READY=0" flag. This unit trigger the
+# change action on the bow device to remove that flag, then systemd sees the
+# device as available.
+
+[Unit]
+Description=Trigger the change action on DM-BOW device if system update
+DefaultDependencies=no
+After=systemd-udev-trigger.service
+Before=opt.mount opt-usr.mount
+ConditionPathExists=/dev/mapper/bowdev_%i
+
+[Service]
+SmackProcessLabel=System
+Type=oneshot
+User=system_fw
+Group=system_fw
+Capabilities=cap_dac_override=i
+SecureBits=keep-caps
+ExecStart=/usr/sbin/udevadm trigger -c change /dev/mapper/bowdev_%i
--- /dev/null
+#!/bin/bash
+PATH="/usr/bin:/bin:/usr/sbin:/sbin"
+
+SYNC="/bin/sync"
+REBOOT="/sbin/reboot"
+MOUNT="/bin/mount"
+UMOUNT="/bin/umount"
+BLKID="/usr/sbin/blkid"
+DMSETUP="/usr/sbin/dmsetup"
+FSTRIM="/usr/sbin/fstrim"
+STAT="/usr/bin/stat"
+
+SYSTEM_DATA_MNT="opt"
+USER_MNT="opt/usr"
+HAL_MNT="hal"
+BTRFS="/usr/sbin/btrfs"
+
+exit_handler() {
+ if [ $? -ne 0 ]; then
+ echo "[Error] Failure to create checkpoint. Reboot."
+ reboot -f
+ exit 1
+ fi
+ echo "[Debug] Checkpoint created"
+}
+
+get_partition_id() {
+ PART_ROOTFS=$("$BLKID" --match-token PARTLABEL=rootfs -o device -l || "$BLKID" --match-token LABEL=rootfs -o device -l)
+ PART_SYSTEM_DATA=$("$BLKID" --match-token PARTLABEL=system-data -o device -l || "$BLKID" --match-token LABEL=system-data -o device -l)
+ PART_USER=$("$BLKID" --match-token PARTLABEL=user -o device -l || "$BLKID" --match-token LABEL=user -o device -l)
+ if [[ ! $(</proc/cmdline) =~ partition_ab= ]]; then
+ PART_HAL=$("$BLKID" --match-token PARTLABEL=hal -o device -l || "$BLKID" --match-token LABEL=hal -o device -l)
+ else
+ PART_HAL=""
+ fi
+}
+
+mount_bow_partition() {
+ LABEL=${1}
+ PARTITION=${2}
+ DIRECTORY=${3}
+ BOWDEV_NAME=bowdev_${LABEL}
+ BOWDEV_PATH=/dev/mapper/${BOWDEV_NAME}
+ SECTORS=$(</sys/class/block/$(lsblk -no NAME ${PARTITION})/size)
+
+ "${DMSETUP}" create ${BOWDEV_NAME} --table "0 ${SECTORS} bow ${PARTITION}"
+ "${MOUNT}" ${BOWDEV_PATH} ${DIRECTORY}
+ "${SYNC}"
+ "${FSTRIM}" -v ${DIRECTORY}
+
+ DM_NUMBER=$(($("${STAT}" -c "0x%T" $(readlink -f ${BOWDEV_PATH}))))
+ echo 1 > /sys/block/dm-${DM_NUMBER}/bow/state
+ if [ "$(</sys/block/dm-${DM_NUMBER}/bow/state)" = "1" ]; then
+ echo "[Debug] Mounted ${PARTITION} as DM-BOW"
+ return 0
+ else
+ echo "[Error] Failure to create checkpoint for ${PARTITION}"
+ return 1
+ fi
+}
+
+mount_f2fs_partition() {
+ LABEL=${1}
+ PARTITION=${2}
+ DIRECTORY=${3}
+ if "${MOUNT}" -o checkpoint=disable ${PARTITION} ${DIRECTORY}; then
+ echo "[Debug] Mounted ${PARTITION} as F2FS checkpoint=disable"
+ return 0
+ else
+ echo "[Error] Failure to mount partition ${PARTITION}"
+ return 1
+ fi
+}
+
+mount_btrfs_partition() {
+ LABEL=${1}
+ PARTITION=${2}
+ DIRECTORY=${3}
+ "${MOUNT}" -o subvolid=5,rw "${PARTITION}" "${DIRECTORY}"
+ mkdir -p "${DIRECTORY}/fota"
+ "$BTRFS" subvolume snapshot "$DIRECTORY/ROOTFS" "$DIRECTORY/fota/RO_update"
+ "$UMOUNT" "${DIRECTORY}"
+ "$MOUNT" -o rw "${PARTITION}" "${DIRECTORY}"
+ echo "[Debug] Mounted ${PARTITION} as btrfs"
+ return 0
+}
+
+mount_checkpoint_partition() {
+ LABEL=${1}
+ PARTITION=${2}
+ DIRECTORY=${3}
+ FSTYPE=$(lsblk -o FSTYPE -n "${PARTITION}")
+
+ if [ "${FSTYPE}" = "ext4" ]; then
+ mount_bow_partition ${LABEL} ${PARTITION} ${DIRECTORY}
+ elif [ "${FSTYPE}" = "f2fs" ]; then
+ mount_f2fs_partition ${LABEL} ${PARTITION} ${DIRECTORY}
+ elif [ "${FSTYPE}" = "btrfs" ]; then
+ mount_btrfs_partition ${LABEL} ${PARTITION} ${DIRECTORY}
+ else
+ mount ${PARTITION} ${DIRECTORY}
+ fi
+ return $?
+}
+
+trap exit_handler EXIT
+
+get_partition_id
+
+mount_checkpoint_partition system-data ${PART_SYSTEM_DATA} /${SYSTEM_DATA_MNT} || exit 1
+if [ ! -z "${PART_USER}" ]; then
+ mount_checkpoint_partition user ${PART_USER} /${USER_MNT} || exit 1
+fi
+
+if [ ! -z "${PART_HAL}" ] && [ ! -d "/${HAL_MNT}/lib" ]
+then
+ # Workaround code to check whether /hal/lib directory is exist
+ mount_checkpoint_partition hal ${PART_HAL} /${HAL_MNT} || exit 1
+fi
+
+exit 0
--- /dev/null
+[Unit]
+Description=Finalize OS update
+DefaultDependencies=no
+After=system-delayed-target-done.service
+ConditionKernelCommandLine=bootmode=fota
+
+[Service]
+Type=oneshot
+SmackProcessLabel=System
+ExecStart=/usr/share/upgrade/update-finalize.sh
+RemainAfterExit=true
+
--- /dev/null
+#!/bin/bash
+
+PATH=/bin:/usr/bin:/sbin:/usr/sbin
+
+RW_MACRO=@UPGRADE_SCRIPTS_DIR@/rw-update-macro.inc
+
+HAL_SET_UPGRADE_STATUS=/usr/bin/device_board_set_upgrade_status
+
+SCRIPT_NAME=$(basename $0)
+CRITICAL_LOG()
+{
+ LOG="[$SCRIPT_NAME]$1"
+ dlogsend -k "$LOG"
+ if [ "$2" != "" ]; then
+ echo "$LOG" >> "$2"
+ fi
+ echo "$LOG"
+}
+
+SET_UPGRADE_STATUS()
+{
+ ${HAL_SET_UPGRADE_STATUS} "$1"
+ if [ $? -eq 0 ]; then
+ CRITICAL_LOG "set_upgrade_status success: ${1}"
+ else
+ CRITICAL_LOG "set_upgrade_status failed: ${1}"
+ fi
+}
+
+if [ -f $RW_MACRO ];
+then
+ source $RW_MACRO
+else
+ ERROR "FAIL: Upgrade macro does not exist"
+ UPDATE_PREPARE_ERR=1
+fi
+
+# TOOD: check if system is stable
+UPDATE_SUCCESS=1
+
+if [ -z ${UPDATE_PREPARE_ERR+x} ] && [ "${UPDATE_SUCCESS}" == "1" ]; then
+ /usr/bin/device_board_clear_boot_mode
+ COMMIT_CHANGES
+ /usr/bin/device_board_clear_partition_ab_cloned
+ /usr/bin/device_board_set_boot_success
+ SET_UPGRADE_STATUS 100
+ reboot -f
+else
+ reboot -f fota
+fi
--- /dev/null
+#!/bin/sh
+#
+# RW update initialize script
+#
+PATH=/bin:/usr/bin:/sbin:/usr/sbin
+RW_MACRO=@UPGRADE_SCRIPTS_DIR@/rw-update-macro.inc
+RW_UPDATE=@UPGRADE_SCRIPTS_DIR@/update.sh
+DEBUG_MODE_FILE=/opt/usr/.upgdebug
+
+if [ -f $RW_MACRO ]; then
+ source $RW_MACRO
+fi
+
+# Restore rpm db
+rm -rf /var/lib/rpm/*
+restore_backup_file -f /opt/var/lib/rpm
+
+# Permission Update for shared directories
+/etc/gumd/useradd.d/91_user-dbspace-permissions.post owner
+
+sleep 10
+if [ -f ${DEBUG_MODE_FILE} ]; then
+ DEBUG_MODE_FILE_OWNER=$(/bin/ls -l ${DEBUG_MODE_FILE} | /bin/cut -d " " -f 3)
+ if [ "${DEBUG_MODE_FILE_OWNER}" = "root" ]; then
+ echo "Enter RW debug mode"
+ echo "If you want to continue FOTA, please run ${RW_UPDATE}"
+ exit
+ fi
+
+ echo "Warning: somebody make non-root debug mode file... ignore it"
+fi
+
+exec /bin/sh $RW_UPDATE
--- /dev/null
+[Unit]
+Description=RW Update finalization
+DefaultDependencies=no
+Wants=offline-update.service
+After=offline-update.service
+IgnoreOnIsolate=true
+
+[Service]
+Type=oneshot
+SmackProcessLabel=System
+ExecStart=/usr/share/upgrade/update-post.sh
+
--- /dev/null
+#!/bin/bash
+
+PATH=/bin:/usr/bin:/sbin:/usr/sbin
+
+if [[ $(</proc/cmdline) =~ partition_ab= ]]
+then
+ # Finalize upgrade right after RW-Upgrade
+ #
+ # It's possible to start upgraded system and check if there are any errors
+ # there. This allows doing checking at later point of time, potentially
+ # catching more errors from new system (eg. some apps failing to start
+ # after upgrade). Current approach is to commit data after upgrade scripts
+ # succeeds, which simply means that system is guaranted to be upgraded even
+ # if some of the apps would fail.
+ /usr/share/upgrade/update-finalize.sh
+ # systemctl isolate default.target
+else
+ reboot -f
+fi
+
--- /dev/null
+#!/bin/bash
+#
+# System RW Update Script
+#
+STATUS_FILE="/opt/data/update/RW.STATUS"
+COLOR_ERROR='\033[01;31m'
+COLOR_DEBUG='\033[01;34m'
+COLOR_NOTIFY='\033[01;33m'
+COLOR_RESET='\033[00;00m'
+PATH=/bin:/usr/bin:/sbin:/usr/sbin
+SHELL=/bin/bash
+
+UPDATE_SCRIPT_DIR=@UPGRADE_PKGSCRIPTS_DIR@
+UPDATE_DATA_DIR=/opt/data/update
+SDB_RULE=${UPDATE_DATA_DIR}/99-sdb-switch.rules
+HAL_SET_UPGRADE_STATUS=/usr/bin/device_board_set_upgrade_status
+HAL_PROGRESS_MIN=80
+HAL_PROGRESS_MAX=99
+
+RW_MACRO=@UPGRADE_SCRIPTS_DIR@/rw-update-macro.inc
+RW_UPDATE_FLAG=/opt/.do_rw_update
+
+SCRIPT_NAME=$(basename $0)
+
+DEBUG()
+{
+ LOG_TEXT=$1
+ echo -e "${COLOR_DEBUG}${LOG_TEXT}${COLOR_RESET}"
+}
+
+ERROR()
+{
+ LOG_TEXT=$1
+ echo -e "${COLOR_ERROR}${LOG_TEXT}${COLOR_RESET}"
+}
+
+NOTIFY()
+{
+ LOG_TEXT=$1
+ echo -e "${COLOR_NOTIFY}${LOG_TEXT}${COLOR_RESET}"
+}
+
+CRITICAL_LOG()
+{
+ LOG="[$SCRIPT_NAME]$1"
+ dlogsend -k "$LOG"
+ if [ "$2" != "" ]; then
+ echo "$LOG" >> "$2"
+ fi
+ echo "$LOG"
+}
+
+PROGRESS_DIR=/tmp/upgrade
+PROGRESS_INIT()
+{
+ mkdir -p ${PROGRESS_DIR}
+ echo "$1" > ${PROGRESS_DIR}/total
+ echo "0" > ${PROGRESS_DIR}/progress
+ chsmack -a _ ${PROGRESS_DIR}
+ chsmack -a _ ${PROGRESS_DIR}/total
+ chsmack -a _ ${PROGRESS_DIR}/progress
+
+ # if GUI is available, run the GUI
+ if [ -e "/usr/bin/rw-update-ani" ]; then
+ export XDG_RUNTIME_DIR=/run
+ export TBM_DISPLAY_SERVER=1
+ /usr/bin/rw-update-ani --wait &
+ fi
+}
+
+PROGRESS()
+{
+ echo "$1" > ${PROGRESS_DIR}/progress
+}
+
+# This result file will be used for Platform Update Control API to get update result.
+UPDATE_RESULT_FILE=${UPDATE_DATA_DIR}/result
+UPI_RW_UPDATE_ERROR_NONE=00
+UPI_RW_UPDATE_ERROR_PREFIX=FA
+UPI_RW_UPDATE_ERROR_FAIL=${UPI_RW_UPDATE_ERROR_PREFIX}1A
+SET_UPDATE_RESULT()
+{
+ echo "$1" > ${UPDATE_RESULT_FILE}
+}
+
+SET_UPGRADE_STATUS()
+{
+ ${HAL_SET_UPGRADE_STATUS} "$1"
+ if [ $? -eq 0 ]; then
+ CRITICAL_LOG "set_upgrade_status success: ${1}"
+ else
+ CRITICAL_LOG "set_upgrade_status failed: ${1}"
+ fi
+}
+
+if [[ $(</proc/cmdline) =~ partition_ab= ]] && [ ! -f ${RW_UPDATE_FLAG} ]
+then
+ NOTIFY "${RW_UPDATE_FLAG} file does not exist. Cancel RW Upgrade."
+ SET_UPGRADE_STATUS -1
+ exit
+fi
+
+NOTIFY "----------------------------------------------------------------------"
+NOTIFY "System RW update: rw update started"
+
+UPDATE_PREPARE_ERR=0
+UPDATE_PROGRESS_ERR=0
+
+if [ -f $RW_MACRO ];
+then
+ source $RW_MACRO
+else
+ ERROR "FAIL: Upgrade macro does not exist"
+ UPDATE_PREPARE_ERR=1
+fi
+
+if [ ! -d ${UPDATE_SCRIPT_DIR} ]
+then
+ ERROR "FAIL: Upgrade directory does not exist"
+ UPDATE_PREPARE_ERR=1
+fi
+
+# Execute update scripts
+if [ ${UPDATE_PREPARE_ERR} = "1" ]
+then
+ ERROR "FAIL: Update preparation was failed"
+ SET_UPDATE_RESULT ${UPI_RW_UPDATE_ERROR_FAIL}
+ SET_UPGRADE_STATUS -1
+else
+ get_version_info
+ DEBUG "Version OLD: ${OLD_VER}, NEW: ${NEW_VER}"
+
+ TOTAL_TASKS=`ls -l ${UPDATE_SCRIPT_DIR} | grep -c '^-'`
+ PROGRESS_INIT ${TOTAL_TASKS}
+
+ UPDATE_SCRIPTS=`/bin/ls ${UPDATE_SCRIPT_DIR}`
+ NOTIFY "TOTAL TASKS: ${TOTAL_TASKS}"
+ for UPSCRIPT in ${UPDATE_SCRIPTS}; do
+ NOTIFY "CURRENT TASK: ${CURRENT_TASK} ${UPSCRIPT}"
+ ${SHELL} ${UPDATE_SCRIPT_DIR}/${UPSCRIPT}
+ if [ $? -ne 0 ]; then
+ ERROR "[FAIL] ${UPSCRIPT}"
+ UPDATE_PROGRESS_ERR=1
+ else
+ DEBUG "[DONE] ${UPSCRIPT}"
+ fi
+ PROGRESS ${CURRENT_TASK}
+ SET_UPGRADE_STATUS $((HAL_PROGRESS_MIN + ((HAL_PROGRESS_MAX - HAL_PROGRESS_MIN)*CURRENT_TASK)/TOTAL_TASKS ))
+ CURRENT_TASK=$(( ${CURRENT_TASK} + 1 ))
+ done
+
+ write_version_info
+
+ if [ ${UPDATE_PROGRESS_ERR} = "1" ]
+ then
+ NOTIFY "SUCCESS: Upgrade finished, but some scripts are failed"
+ SET_UPDATE_RESULT ${UPI_RW_UPDATE_ERROR_FAIL}
+ else
+ NOTIFY "SUCCESS: Upgrade successfully finished"
+ SET_UPDATE_RESULT ${UPI_RW_UPDATE_ERROR_NONE}
+ fi
+fi
+
+if [ -e ${SDB_RULE} ]; then
+ rm ${SDB_RULE}
+fi
+
+rm ${RW_UPDATE_FLAG}
+
+/bin/sync
+NOTIFY "----------------------------------------------------------------------"
+
+if [[ ! $(</proc/cmdline) =~ partition_ab= ]]
+then
+ rm ${STATUS_FILE}
+ COMMIT_CHANGES
+fi
+#Reboot by update-finalize.service