Add support for Online Update. 19/309619/4 accepted/tizen/unified/20240430.020636 accepted/tizen/unified/toolchain/20240507.011854 accepted/tizen/unified/x/20240430.094831 accepted/tizen/unified/x/20240507.051014
authorMateusz Moscicki <m.moscicki2@partner.samsung.com>
Fri, 12 Apr 2024 14:33:21 +0000 (16:33 +0200)
committerMateusz Moscicki <m.moscicki2@partner.samsung.com>
Mon, 22 Apr 2024 13:36:55 +0000 (15:36 +0200)
Run Online Update if bootmode is set to fota.
Additionally a bow-restore tool is added which is used to revert data
changes during a data migration during the OS Upgrade.

Change-Id: I73e17329a86541bb3067976cecd2a6a4dc4f8509

data/initrd-file.list
packaging/initrd.spec
scripts/init.sh

index 7728c97..37913c1 100644 (file)
@@ -40,6 +40,7 @@ PROGS="
 /usr/bin/chroot
 /usr/bin/ls
 /usr/bin/cat
+/usr/sbin/bow-restore
 /usr/sbin/fsck
 /usr/sbin/fsck.ext4
 /usr/sbin/resize2fs
index 2e4aea2..6c587ee 100644 (file)
@@ -23,6 +23,7 @@ Requires(posttrans): btrfs-progs
 Requires(posttrans): f2fs-tools
 Requires(posttrans): kmod-compat
 Requires(posttrans): nbd-client
+Requires(posttrans): bow-restore
 Requires(post):      /sbin/ldconfig
 Requires(postun):    /sbin/ldconfig
 Requires:            parse-dynparts
index 0916d52..9d45991 100755 (executable)
@@ -18,6 +18,7 @@ IN_INITRAMFS=0
 NEED_RESIZEFS=1
 USERFS_ENCRYPTED=0
 FS_RETRY_COUNT=10
+BOOT_MODE=
 
 BLKID_LINES=()
 
@@ -259,6 +260,39 @@ function check_flags()
     fi
 }
 
+#------------------------------------------------
+#       restore_checkpoint
+#------------------------------------------------
+restore_checkpoint() {
+    # Any existing checkpoint means that the RW update was unexpectedly
+    # aborded, so we must roll back the changes and update again.
+    echo "Checkpoint restore"
+    PART="${1}"
+    FS_TYPE="$(blkid -o value -s TYPE "${PART}")"
+    if [ "$FS_TYPE" = "ext4" ]; then
+        bow-restore "${PART}"
+    elif [ "$FS_TYPE" = "f2fs" ]; then
+        # f2fs does not need a restore - if the data was not commited before
+        # the reboot, any changes were discarded
+        :
+    else
+        echo "Checkpoint restore error: unknown filesystem ${FS_TYPE} on ${PART}"
+    fi
+}
+
+#------------------------------------------------
+#       restore_partitions
+#------------------------------------------------
+restore_partitions() {
+    echo "Restore partitions"
+
+    if [ ! "z${USERFS}" = "z" ]; then
+        restore_checkpoint "${USERFS}"
+    fi
+    if [ ! "z${DATAFS}" = "z" ]; then
+        restore_checkpoint "${DATAFS}"
+    fi
+}
 
 function process_rootfs()
 {
@@ -335,7 +369,10 @@ function process_datafs()
         /sbin/resize2fs -f $DATAFS
     fi
     /sbin/fsck -y $DATAFS
-    /bin/mount $DATAFS $DATAFS_MNT
+
+    # We don't mount $DATAFS here, platform mounts it,
+    # because if it's an upgrade, we may need to create a checkpoint
+    # /bin/mount $DATAFS $DATAFS_MNT
 }
 
 
@@ -370,7 +407,8 @@ function process_userfs()
         /sbin/fsck -y $USERFS
     fi
 
-    # We don't mount $USERFS here, platform mounts it.
+    # We don't mount $USERFS here, platform mounts it,
+    # because if it's an upgrade, we may need to create a checkpoint
 }
 
 function process_halfs()
@@ -389,7 +427,18 @@ function write_resized_flag()
     if [ x"$DATAFS" = "x" ]; then return; fi
     if [ "$NEED_RESIZEFS" = "0" ]; then return; fi
 
+    # We want to create a flag indicating that resize2fs has already been
+    # executed, but DATAFS partition will be mounted by systemd later. So we
+    # have to do this kind of ugly mouting and unmounting, to be able to create
+    # flag, and then for systemd to mount the partition in the normal way or
+    # via dm-bow (during an upgrade).
+    # Fortunately, it will only execute once, on the first boot after the
+    # images have been flashed.
+    /bin/mount "$DATAFS" "$DATAFS_MNT"
+
     echo " " > ${DATAFS_MNT}/var/.resizefs_done
+
+    /bin/umount "$DATAFS_MNT"
 }
 
 
@@ -436,16 +485,23 @@ function pivot_root()
 
 function change_root()
 {
+    ADDON=
+    INIT_BINARY=/sbin/init
+    if [ "$BOOT_MODE" == "fota" ]; then
+        ADDON="--unit=online-update.target"
+        INIT_BINARY=/usr/lib/systemd/systemd
+    fi
+
     if [ $$ = 1 ]
     then
         if [ "$IN_INITRD" = "1" ]
         then
-            exec chroot . /sbin/init $@
+            exec chroot . "$INIT_BINARY" "$ADDON" $@
         elif [ "$IN_INITRAMFS" = "1" ]
         then
-            exec switch_root $ROOTFS_MNT /sbin/init $@
+            exec switch_root $ROOTFS_MNT "$INIT_BINARY" "$ADDON" $@
         else
-            exec /usr/lib/systemd/systemd $@
+            exec /usr/lib/systemd/systemd "$ADDON" $@
         fi
     fi
 }
@@ -467,6 +523,18 @@ function process_special_filesystem() {
     mount -o nosuid,noexec,nodev -t proc proc /proc
 }
 
+check_bootmode() {
+    read -r cmdline </proc/cmdline
+    echo "Kernel command line: $cmdline"
+    for element in $cmdline; do
+        key="${element%%=*}"
+        if [ "$key" = "bootmode" ]; then
+            BOOT_MODE="${element#*=}"
+            break;
+        fi
+    done
+}
+
 if [ x$container = "x" ]; then
     process_special_filesystem
 else
@@ -478,6 +546,7 @@ print_boot_info
 check_network
 setup_nbd
 wait_find_partitions
+restore_partitions
 check_flags
 
 process_rootfs
@@ -489,6 +558,7 @@ write_resized_flag
 
 load_kernel_modules
 pivot_root
+check_bootmode
 change_root $@
 
 # WARNING! never rearch