Ignore dm-verity corruption when "reboot recovery" is not available 74/277374/4
authorSangYoun Kwak <sy.kwak@samsung.com>
Wed, 6 Jul 2022 02:55:00 +0000 (11:55 +0900)
committerSangYoun Kwak <sy.kwak@samsung.com>
Wed, 6 Jul 2022 07:00:43 +0000 (16:00 +0900)
"reboot recovery" is not available when:
Partitions are not cloned
Upgrade status is in range 1~99
Opposite partition status is not "ok"

Change-Id: I0d9aded5b2336e6827b3e1bfd1659826f510be8d
Signed-off-by: SangYoun Kwak <sy.kwak@samsung.com>
src/storage/storage.c

index 8c8bb7a..0be8829 100644 (file)
@@ -80,6 +80,9 @@
 #define ROOTFS_DMVERITY_CORRUPTED_COUNT_DEFUALT   (1)
 #define ROOTFS_DMVERITY_CORRUPTED_TIMEOUT_DEFUALT (0)
 
+#define PARTITION_STATUS_OK "ok"
+#define PARTITION_STATUS_BUFFER_LEN 16
+
 enum memnoti_level {
        MEMNOTI_LEVEL_FULL = 0,
        MEMNOTI_LEVEL_CRITICAL,
@@ -708,11 +711,16 @@ static void storage_poweroff(GDBusConnection  *conn,
 
 static gboolean reboot_recovery_callback(void *data)
 {
+       int ret_board_api;
        int ret_dbus;
        gint poweroff_retval;
 
        GVariant *poweroff_param = g_variant_new("(ss)", "reboot", "recovery");
 
+       /* toggle partition */
+       ret_board_api = device_board_switch_partition('\0');
+       CRITICAL_LOG("device_board_switch_partition: (%d)", ret_board_api);
+
        ret_dbus = gdbus_call_sync_with_reply_int("org.tizen.system.deviced",
                        "/Org/Tizen/System/DeviceD/PowerOff",
                        "org.tizen.system.deviced.PowerOff",
@@ -731,6 +739,37 @@ static gboolean reboot_recovery_callback(void *data)
        return G_SOURCE_REMOVE;
 }
 
+static int is_recovery_available()
+{
+       int ret_board_api;
+       int cloned;
+       int status;
+
+       /* check if a/b partitions are cloned */
+       ret_board_api = device_board_get_partition_ab_cloned(&cloned);
+       if (ret_board_api != 0) {
+               CRITICAL_LOG("device_board_get_partition_ab_cloned failed: %d", ret_board_api);
+               return 0;
+       }
+       if(cloned != 1) {
+               CRITICAL_LOG("Partition a/b are not cloned");
+               return 0;
+       }
+
+       /* check if fota is running (upgrade status is 1~99) */
+       ret_board_api = device_board_get_upgrade_status(&status);
+       if (ret_board_api != 0) {
+               CRITICAL_LOG("device_board_get_upgrade_status failed: %d", ret_board_api);
+               return 0;
+       }
+       if (status >= 1 && status <= 99) {
+               CRITICAL_LOG("Upgrade is in progress: %d", status);
+               return 0;
+       }
+
+       return 1;
+}
+
 static void dm_verity_uevent_block_handler(struct udev_device *dev)
 {
        static int dm_verity_corrupted_cnt = 0;
@@ -773,15 +812,19 @@ static void dm_verity_uevent_block_handler(struct udev_device *dev)
        /* action: reboot,recovery */
        if (storage_rootfs_recovery_info.action == RECOVERY_ACTION_REBOOT_RECOVERY &&
                        poweroff_g_timeout_event_source_id <= 0) {
+               int recovery_available = is_recovery_available();
+
                /* set current partition status as "corrupted" */
                ret_board_api = device_board_set_partition_status('\0', "corrupted");
                CRITICAL_LOG("device_board_set_partition_status: (%d)", ret_board_api);
                /* clear partition ab cloned */
                ret_board_api = device_board_clear_partition_ab_cloned();
                CRITICAL_LOG("device_board_clear_partition_ab_cloned: (%d)", ret_board_api);
-               /* toggle partition */
-               ret_board_api = device_board_switch_partition('\0');
-               CRITICAL_LOG("device_board_switch_partition: (%d)", ret_board_api);
+
+               if (!recovery_available) {
+                       CRITICAL_LOG("Recovery is not available, do not reboot/recovery");
+                       return;
+               }
 
                poweroff_g_timeout_event_source_id =
                        g_timeout_add(storage_rootfs_recovery_info.dm_verity_corrupted_timeout,