Import system-rw-upgrade 55/280155/1
authorKarol Lewandowski <k.lewandowsk@samsung.com>
Wed, 24 Aug 2022 09:29:52 +0000 (11:29 +0200)
committerKarol Lewandowski <k.lewandowsk@samsung.com>
Wed, 24 Aug 2022 11:32:09 +0000 (13:32 +0200)
This commit imports system-rw-upgrade from commit fbb4ba4cf ("Add critical log where upgrade
status is changing").

Following changes were made with repect to original repository:

 - move scripts and unit files under scripts/rw-upgrade

 - move logic behind installing scripts and unit files to scripts/rw-upgrade/CMakeLists.txt

 - depend only on UPGRADE_ variables

 - integrate build into new spec

Change-Id: I305fe67d2ac32df7d2b9d05b51b67a1fb808a68b

19 files changed:
CMakeLists.txt
packaging/upgrade-engine.spec
scripts/rw-upgrade/99-sdb-switch.rules [new file with mode: 0644]
scripts/rw-upgrade/CMakeLists.txt [new file with mode: 0644]
scripts/rw-upgrade/data-checkpoint.service.in [new file with mode: 0644]
scripts/rw-upgrade/data-checkpoint.target [new file with mode: 0644]
scripts/rw-upgrade/install-sdb-rule.sh.in [new file with mode: 0644]
scripts/rw-upgrade/offline-update.service.in [new file with mode: 0644]
scripts/rw-upgrade/record-version.sh.in [new file with mode: 0644]
scripts/rw-upgrade/rw-update-macro.inc [new file with mode: 0644]
scripts/rw-upgrade/udev-sdb-init.service.in [new file with mode: 0644]
scripts/rw-upgrade/udev-trigger-dmbow@.service [new file with mode: 0644]
scripts/rw-upgrade/update-checkpoint-create.sh [new file with mode: 0644]
scripts/rw-upgrade/update-finalize.service [new file with mode: 0644]
scripts/rw-upgrade/update-finalize.sh.in [new file with mode: 0644]
scripts/rw-upgrade/update-init.sh.in [new file with mode: 0644]
scripts/rw-upgrade/update-post.service [new file with mode: 0644]
scripts/rw-upgrade/update-post.sh [new file with mode: 0644]
scripts/rw-upgrade/update.sh.in [new file with mode: 0644]

index ed144fc..1861131 100644 (file)
@@ -45,3 +45,4 @@ ADD_SUBDIRECTORY(src/img-verifier)
 ADD_SUBDIRECTORY(src/upgrade-apply)
 ADD_SUBDIRECTORY(src/blkid-print)
 ADD_SUBDIRECTORY(data)
+ADD_SUBDIRECTORY(scripts/rw-upgrade)
index 6a4696a..2970792 100644 (file)
@@ -1,8 +1,9 @@
 %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
@@ -22,6 +23,9 @@ BuildRequires:  libtar-devel
 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.
@@ -44,6 +48,10 @@ LDFLAGS="$LDFLAGS"
        -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}
@@ -67,6 +75,32 @@ mkdir -p %{buildroot}%{_unitdir}/recovery.service.wants
 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
@@ -91,3 +125,30 @@ ln -s ../clone_partitions_recovery.service %{buildroot}%{_unitdir}/recovery.serv
 # 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
diff --git a/scripts/rw-upgrade/99-sdb-switch.rules b/scripts/rw-upgrade/99-sdb-switch.rules
new file mode 100644 (file)
index 0000000..75238f5
--- /dev/null
@@ -0,0 +1,2 @@
+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"
diff --git a/scripts/rw-upgrade/CMakeLists.txt b/scripts/rw-upgrade/CMakeLists.txt
new file mode 100644 (file)
index 0000000..48dddc8
--- /dev/null
@@ -0,0 +1,34 @@
+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)
diff --git a/scripts/rw-upgrade/data-checkpoint.service.in b/scripts/rw-upgrade/data-checkpoint.service.in
new file mode 100644 (file)
index 0000000..ed5d32f
--- /dev/null
@@ -0,0 +1,17 @@
+[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
+
diff --git a/scripts/rw-upgrade/data-checkpoint.target b/scripts/rw-upgrade/data-checkpoint.target
new file mode 100644 (file)
index 0000000..b4694c5
--- /dev/null
@@ -0,0 +1,7 @@
+[Unit]
+Description=Data checkpoint
+DefaultDependencies=no
+Conflicts=shutdown.target
+Before=local-fs-pre.target
+OnFailure=emergency.target
+OnFailureJobMode=replace-irreversibly
diff --git a/scripts/rw-upgrade/install-sdb-rule.sh.in b/scripts/rw-upgrade/install-sdb-rule.sh.in
new file mode 100644 (file)
index 0000000..bb90ceb
--- /dev/null
@@ -0,0 +1,11 @@
+#!/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
diff --git a/scripts/rw-upgrade/offline-update.service.in b/scripts/rw-upgrade/offline-update.service.in
new file mode 100644 (file)
index 0000000..b1d153d
--- /dev/null
@@ -0,0 +1,13 @@
+[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
diff --git a/scripts/rw-upgrade/record-version.sh.in b/scripts/rw-upgrade/record-version.sh.in
new file mode 100644 (file)
index 0000000..2a59877
--- /dev/null
@@ -0,0 +1,9 @@
+#!/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
diff --git a/scripts/rw-upgrade/rw-update-macro.inc b/scripts/rw-upgrade/rw-update-macro.inc
new file mode 100644 (file)
index 0000000..5ed8aea
--- /dev/null
@@ -0,0 +1,239 @@
+#!/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
+}
diff --git a/scripts/rw-upgrade/udev-sdb-init.service.in b/scripts/rw-upgrade/udev-sdb-init.service.in
new file mode 100644 (file)
index 0000000..aaaf8aa
--- /dev/null
@@ -0,0 +1,9 @@
+[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
diff --git a/scripts/rw-upgrade/udev-trigger-dmbow@.service b/scripts/rw-upgrade/udev-trigger-dmbow@.service
new file mode 100644 (file)
index 0000000..85c92ef
--- /dev/null
@@ -0,0 +1,21 @@
+# 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
diff --git a/scripts/rw-upgrade/update-checkpoint-create.sh b/scripts/rw-upgrade/update-checkpoint-create.sh
new file mode 100644 (file)
index 0000000..525f1a4
--- /dev/null
@@ -0,0 +1,121 @@
+#!/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
diff --git a/scripts/rw-upgrade/update-finalize.service b/scripts/rw-upgrade/update-finalize.service
new file mode 100644 (file)
index 0000000..2a059c6
--- /dev/null
@@ -0,0 +1,12 @@
+[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
+
diff --git a/scripts/rw-upgrade/update-finalize.sh.in b/scripts/rw-upgrade/update-finalize.sh.in
new file mode 100644 (file)
index 0000000..172de40
--- /dev/null
@@ -0,0 +1,50 @@
+#!/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
diff --git a/scripts/rw-upgrade/update-init.sh.in b/scripts/rw-upgrade/update-init.sh.in
new file mode 100644 (file)
index 0000000..f7b89c0
--- /dev/null
@@ -0,0 +1,33 @@
+#!/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
diff --git a/scripts/rw-upgrade/update-post.service b/scripts/rw-upgrade/update-post.service
new file mode 100644 (file)
index 0000000..67f958e
--- /dev/null
@@ -0,0 +1,12 @@
+[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
+
diff --git a/scripts/rw-upgrade/update-post.sh b/scripts/rw-upgrade/update-post.sh
new file mode 100644 (file)
index 0000000..dd52044
--- /dev/null
@@ -0,0 +1,20 @@
+#!/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
+
diff --git a/scripts/rw-upgrade/update.sh.in b/scripts/rw-upgrade/update.sh.in
new file mode 100644 (file)
index 0000000..43653e2
--- /dev/null
@@ -0,0 +1,178 @@
+#!/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