diff --git a/OAT.xml b/OAT.xml index 0cfc6f85984101a02c77fe7ebbd15e9adbbacd7a..62bc1e52b366f0817b98e398d7380a99db126e51 100644 --- a/OAT.xml +++ b/OAT.xml @@ -23,6 +23,7 @@ + diff --git a/begetd.gni b/begetd.gni index 3b74061ca808dc8adcc1993d438841b88e8adfcc..96c2d405ba8dde42a0f590d7405c856c840357ce 100644 --- a/begetd.gni +++ b/begetd.gni @@ -13,6 +13,8 @@ init_innerkits_path = "//base/startup/init/interfaces/innerkits" +# init ota rollback +init_feature_ota_rollback = false declare_args() { enable_ohos_startup_init_feature_watcher = true enable_ohos_startup_init_feature_deviceinfo = true diff --git a/interfaces/innerkits/fs_manager/BUILD.gn b/interfaces/innerkits/fs_manager/BUILD.gn index e0a93d2e707acc35130857bbf6114f90da355ae7..6a00d0efd7f1189201e684e51971a0373947dac1 100755 --- a/interfaces/innerkits/fs_manager/BUILD.gn +++ b/interfaces/innerkits/fs_manager/BUILD.gn @@ -90,6 +90,9 @@ ohos_static_library("libfsmanager_static") { defines += [ "EROFS_OVERLAY" ] } + if (init_feature_ota_rollback) { + defines += [ "OTA_ROLLBACK_SUPPORT" ] + } } public_configs = [ ":libfsmanager_exported_configs" ] @@ -139,6 +142,10 @@ ohos_static_library("libfsmanager_static_real") { defines = [ "SUPPORT_HVB" ] external_deps += [ "hvb:libhvb_static" ] deps += [ "//base/startup/init/ueventd:libueventd_ramdisk_static_real" ] + + if (init_feature_ota_rollback) { + defines += [ "OTA_ROLLBACK_SUPPORT" ] + } } } diff --git a/interfaces/innerkits/fs_manager/fstab_mount.c b/interfaces/innerkits/fs_manager/fstab_mount.c index a067b6198f918878ccf1ca7877f833cd218b11be..1b798764050b5f737ef1a352dd3e1fb3b16adf3a 100755 --- a/interfaces/innerkits/fs_manager/fstab_mount.c +++ b/interfaces/innerkits/fs_manager/fstab_mount.c @@ -50,6 +50,8 @@ extern "C" { #define RESIZE_BUFFER_SIZE 1024 const off_t PARTITION_ACTIVE_SLOT_OFFSET = 1024; const off_t PARTITION_ACTIVE_SLOT_SIZE = 4; +const off_t PARTITION_CHECKPOINT_OFFSET = 1032; +const off_t PARTITION_CHECKPOINT_SIZE = 4; int g_bootSlots = -1; int g_currentSlot = -1; @@ -456,9 +458,46 @@ static int GetSlotInfoFromBootctrl(off_t offset, off_t size) BEGET_INFO_CHECK(read(fd, &slotInfo, sizeof(slotInfo)) == size, close(fd); return -1, "Failed to read current slot from bootctrl, errno %d", errno); close(fd); + BEGET_LOGI("get slotinfo: %d", slotInfo); return slotInfo; } +static int GetCheckpointFromBootctrl(off_t offset, off_t size) +{ + char bootctrlDev[MAX_BUFFER_LEN] = {0}; + // default checkpoint not set, normal mode + int checkpoint = 0; + // Get bootctrl device path + if (GetBlockDevicePath("/bootctrl", bootctrlDev, MAX_BUFFER_LEN) != 0) { + BEGET_LOGE("Failed to get bootctrl device"); + return -1; + } + char *realPath = GetRealPath(bootctrlDev); + if (realPath == NULL) { + BEGET_LOGE("Failed to get bootctrl device real path"); + return -1; + } + int fd = open(realPath, O_RDWR | O_CLOEXEC, S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH); + free(realPath); + if (fd < 0) { + BEGET_LOGE("Failed to open bootctrl device, errno %d", errno); + return -1; + } + if (lseek(fd, offset, SEEK_SET) < 0) { + close(fd); + BEGET_LOGE("Failed to lseek bootctrl device fd, errno %d", errno); + return -1; + } + if (read(fd, &checkpoint, sizeof(checkpoint)) != size) { + close(fd); + BEGET_LOGE("Failed to read current checkpoint from bootctrl, errno %d", errno); + return -1; + } + close(fd); + BEGET_LOGI("get checkpoint: %d", checkpoint); + return checkpoint; +} + int GetBootSlots(void) { if (g_bootSlots != -1) { @@ -482,6 +521,32 @@ int GetCurrentSlot(void) return GetSlotInfoFromBootctrl(PARTITION_ACTIVE_SLOT_OFFSET, PARTITION_ACTIVE_SLOT_SIZE); } +int GetCurrentCheckpoint(void) +{ + return GetCheckpointFromBootctrl(PARTITION_CHECKPOINT_OFFSET, PARTITION_CHECKPOINT_SIZE); +} + +#ifdef OTA_ROLLBACK_SUPPORT +static int DoOtaRollBack(FstabItem *item) +{ + // Get the checkpoint of the current bootctrl + if (strcmp(item->mountPoint, "/data") == 0) { + if (GetCurrentCheckpoint() == 1) { + const char *mountPoint = "/data"; + // Remount data, set checkpoint=disable + const char *options = "checkpoint=disable"; + const char *fsType = NULL; + BEGET_LOGI("remount_point = %s.", mountPoint); + int result = mount(mountPoint, mountPoint, fsType, MS_REMOUNT, options); + if (result != 0) { + BEGET_LOGE("Failed to remount /data"); + return -1; + } + } + } + return 0; +} +#endif static int DoMountOneItem(FstabItem *item) { BEGET_LOGI("Mount device %s to %s", item->deviceName, item->mountPoint); @@ -598,6 +663,13 @@ int MountOneItem(FstabItem *item) if (rc == 0 && (strcmp(item->mountPoint, "/usr") == 0)) { SwitchRoot("/usr"); } +#ifdef OTA_ROLLBACK_SUPPORT + // OTA rollback data + int ret = DoOtaRollBack(item); + if (ret != 0) { + BEGET_LOGW("Failed to rollback data"); + } +#endif #endif if (disableCheckpointRet == 0 && rc == 0) { BEGET_LOGI("start health check process"); diff --git a/interfaces/innerkits/include/fs_manager/fs_manager.h b/interfaces/innerkits/include/fs_manager/fs_manager.h index a77a3a34982f3c365385840d7ef1cfde519255fe..a1d16f3df357548e67f088d55a7d7a0b619a9ef7 100644 --- a/interfaces/innerkits/include/fs_manager/fs_manager.h +++ b/interfaces/innerkits/include/fs_manager/fs_manager.h @@ -92,6 +92,7 @@ typedef struct SlotInfo { Fstab* LoadFstabFromCommandLine(void); int GetBootSlots(void); int GetCurrentSlot(void); +int GetCurrentCheckpoint(void); void ReleaseFstab(Fstab *fstab); Fstab *ReadFstabFromFile(const char *file, bool procMounts); FstabItem *FindFstabItemForPath(Fstab fstab, const char *path); diff --git a/services/begetctl/BUILD.gn b/services/begetctl/BUILD.gn index 77f143fc5167ac17fa2164c9b0d56c36cf1843b2..82ddef1426369d4451632e30d35fa7dba3d0fe61 100755 --- a/services/begetctl/BUILD.gn +++ b/services/begetctl/BUILD.gn @@ -137,7 +137,7 @@ if (defined(ohos_lite)) { if (init_feature_ab_partition) { sources += [ "partitionslot.cpp" ] external_deps += [ - "drivers_interface_partitionslot:libpartitionslot_proxy_1.0", + "drivers_interface_partitionslot:libpartitionslot_proxy_1.1", "hdf_core:libhdi", "hdf_core:libpub_utils", ] diff --git a/services/begetctl/partitionslot.cpp b/services/begetctl/partitionslot.cpp index 2f8ee450b5667c67c715340208820c3d566dd7c5..99c34921878cfbf1adca6d1007491edc5aafde18 100644 --- a/services/begetctl/partitionslot.cpp +++ b/services/begetctl/partitionslot.cpp @@ -17,9 +17,9 @@ #include "begetctl.h" #include "idevmgr_hdi.h" -#include "v1_0/ipartition_slot.h" +#include "v1_1/ipartition_slot.h" -using namespace OHOS::HDI::Partitionslot::V1_0; +using namespace OHOS::HDI::Partitionslot::V1_1; using OHOS::HDI::DeviceManager::V1_0::IDeviceManager; static const int32_t PARTITION_ARGC = 2; diff --git a/services/modules/bootevent/BUILD.gn b/services/modules/bootevent/BUILD.gn index 281d4adf9b700ebf3a2e2de7bfcf9e9bdee9b8fb..454fc091c972eac186ca040f844def8212507837 100755 --- a/services/modules/bootevent/BUILD.gn +++ b/services/modules/bootevent/BUILD.gn @@ -10,7 +10,7 @@ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. - +import("//base/startup/init/begetd.gni") import("//build/ohos.gni") config("bootevent_static_config") { @@ -25,6 +25,11 @@ config("bootevent_static_config") { } ohos_source_set("libbootevent_static") { + sanitize = { + cfi = true + cfi_cross_dso = true + debug = false + } sources = [ "bootevent.c" ] include_dirs = [ ".." ] include_dirs += [ @@ -37,12 +42,20 @@ ohos_source_set("libbootevent_static") { public_external_deps = [ "config_policy:configpolicy_util" ] public_configs += [ "//base/startup/init/interfaces/innerkits/init_module_engine:init_module_engine_exported_config" ] public_external_deps += [ "bounds_checking_function:libsec_static" ] + defines = [] + external_deps = [] if (build_selinux) { include_dirs += [ "//base/startup/init/interfaces/innerkits/include/param" ] external_deps += [ "selinux:libselinux", "selinux_adapter:librestorecon", ] - defines = [ "WITH_SELINUX" ] + defines += [ "WITH_SELINUX" ] + } + if (init_feature_ota_rollback) { + defines += [ "OTA_ROLLBACK_SUPPORT" ] + external_deps += [ "updater:libotainfo" ] } + part_name = "init" + subsystem_name = "startup" } diff --git a/services/modules/bootevent/bootevent.c b/services/modules/bootevent/bootevent.c index 67b68e5c3e1f3a9238e6d6ab1176d41807bcb1ec..cec3929a3494dda1dcc00f8728df1f0b248d8750 100755 --- a/services/modules/bootevent/bootevent.c +++ b/services/modules/bootevent/bootevent.c @@ -29,10 +29,28 @@ #include "init_cmds.h" #include "config_policy_utils.h" +#ifdef OTA_ROLLBACK_SUPPORT +#include "ota_event/ota_event.h" +#include +#endif + #ifdef WITH_SELINUX #include #endif +#ifdef OTA_ROLLBACK_SUPPORT +enum ReturnSetOtaStatus { + SET_OTA_STATUS_FAILED = -1, // Failed to call SetOTAStatus to set information. + BOOT_SUCCESS_IN_OTA = 0, // In the ota stage, startup is complete. + BOOT_SUCCESS_IN_NORMAL = 1, // In the non-ota stage, startup is complete. + BOOT_FAILD_IN_OTA = 2, // In the ota stage, startup is failed. + BOOT_FAILD_IN_NORMAL = 3, // In the non-ota stage, startup is failed. +}; + +int g_eventBootcomplete = 0; + +#endif + static int GetBootSwitchEnable(const char *paramName) { char bootEventOpen[6] = ""; // 6 is length of bool value @@ -314,6 +332,64 @@ static void WriteBooteventSysParam(const char *paramName) "snprintf_s name failed"); SystemWriteParam(name, buf); } +#ifdef OTA_ROLLBACK_SUPPORT +static void RebootSystem(void) +{ + // Accessing address 0, creating an exception, causing the system to restart + *((volatile int *)0) = 0; +} + +static int OTARollback(void) +{ + // Determine if the system is starting up abnormally + int retOta = SET_OTA_STATUS_FAILED; + int bootStatus = g_eventBootcomplete; + + INIT_LOGI("bootStatus = %d.", bootStatus); + retOta = SetOTAStatus(bootStatus); + if (retOta == SET_OTA_STATUS_FAILED) { + INIT_LOGI("Set OTA status failed."); + return -1; + } + INIT_LOGI("retOta = %d.", retOta); + const char *mountPoint = "/data"; + const char *fsType = NULL; + const char *options = "checkpoint=enable"; + int result; + + switch (retOta) { + case BOOT_SUCCESS_IN_OTA: + INIT_LOGI("boot success in OTA, start to remount data."); + // remount data, set checkpoint=enable + BEGET_LOGI("remount_point = %s.", mountPoint); + result = mount(mountPoint, mountPoint, fsType, MS_REMOUNT, options); + if (result != 0) { + BEGET_LOGE("Failed to remount /data"); + return -1; + } + break; + + case BOOT_SUCCESS_IN_NORMAL: + INIT_LOGI("boot success in normal, no process."); + break; + + case BOOT_FAILD_IN_OTA: + INIT_LOGI("boot faild in OTA, start to reboot."); + // reboot system + RebootSystem(); + break; + + case BOOT_FAILD_IN_NORMAL: + INIT_LOGI("boot faild in normal, no process."); + break; + + default: + INIT_LOGI("boot status is unknown."); + break; + } + return 1; +} +#endif static int BootEventParaFireByName(const char *paramName) { @@ -343,10 +419,22 @@ static int BootEventParaFireByName(const char *paramName) if (g_bootEventNum > 0) { return 0; } + +#ifdef OTA_ROLLBACK_SUPPORT + g_eventBootcomplete = 1; + // First reboot in ota phase, check if rollback is needed + int retOta = OTARollback(); + if (retOta != 1) { + INIT_LOGI("boot failed, no process."); + return 0; + } +#endif + // All parameters are fired, set boot completed now ... INIT_LOGI("All boot events are fired, boot complete now ..."); SystemWriteParam(BOOT_EVENT_BOOT_COMPLETED, "true"); SetBootCompleted(true); + SaveServiceBootEvent(); // report complete event ReportSysEvent(); @@ -467,6 +555,14 @@ static int DoUnsetBootEventCmd(int id, const char *name, int argc, const char ** SystemWriteParam(argv[0], "false"); if (g_finished != 0) { +#ifdef OTA_ROLLBACK_SUPPORT + // First reboot in ota phase, check if rollback is needed + int retOta = OTARollback(); + if (retOta != 1) { + INIT_LOGI("boot failed, no process."); + return 0; + } +#endif SystemWriteParam(BOOT_EVENT_BOOT_COMPLETED, "false"); SetBootCompleted(false); g_finished = 0; diff --git a/test/unittest/BUILD.gn b/test/unittest/BUILD.gn index 51192116318e5918ead865cdc062250c3b85a4d6..43c212ee4094aed27f58ffcf9b4e5b76c81e820e 100755 --- a/test/unittest/BUILD.gn +++ b/test/unittest/BUILD.gn @@ -372,7 +372,7 @@ ohos_unittest("init_unittest") { if (init_feature_ab_partition) { sources += [ "//base/startup/init/services/begetctl/partitionslot.cpp" ] external_deps += [ - "drivers_interface_partitionslot:libpartitionslot_proxy_1.0", + "drivers_interface_partitionslot:libpartitionslot_proxy_1.1", "hdf_core:libhdi", "hdf_core:libpub_utils", ] @@ -456,6 +456,12 @@ ohos_unittest("init_unittest") { # test atomic operation sources += [ "//base/startup/init/test/unittest/param/atomic_unittest.cpp" ] + # test ota remount data + sources += [ "//base/startup/init/test/unittest/fs_manager/ota_rollback/ota_data_mount_unittest.cpp" ] + + # test ota check boot success + sources += [ "//base/startup/init/test/unittest/fs_manager/ota_rollback/ota_boot_success_unittest.cpp" ] + cflags_cc = [ "-fexceptions" ] } diff --git a/test/unittest/fs_manager/ota_rollback/ota_boot_success_unittest.cpp b/test/unittest/fs_manager/ota_rollback/ota_boot_success_unittest.cpp new file mode 100755 index 0000000000000000000000000000000000000000..c0b758b01df22d4c665a3bd802adab7ada8f9458 --- /dev/null +++ b/test/unittest/fs_manager/ota_rollback/ota_boot_success_unittest.cpp @@ -0,0 +1,218 @@ +/* + * Copyright (c) 2024 Hunan OpenValley Digital Industry Development Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#include "securec.h" +#include "bootevent.h" +#include +#include "init_utils.h" +#include +#include +#include +#include +#include + +#define BOOTEVENT_LEN 4 +using namespace std; +using namespace testing::ext; +namespace init_ut { +const char* g_bootEventOta1[] = {"bootEvent1", "bootEvent3"}; +const char* g_bootEventOta2[] = {"bootEvent1", "bootEvent4"}; +const char* g_bootEventOta3[] = {"bootEvent2", "bootEvent3"}; +const char* g_bootEventOta4[] = {"bootEvent2", "bootEvent4"}; + +// Define the possible return values for OTA status +enum ReturnSetOtaStatus { + SET_OTA_STATUS_FAILED = -1, // Failed to call SetOTAStatus to set information. + BOOT_SUCCESS_IN_OTA = 0, // In the ota stage, startup is complete. + BOOT_SUCCESS_IN_NORMAL = 1, // In the non-ota stage, startup is complete. + BOOT_FAILD_IN_OTA = 2, // In the ota stage, startup is failed. + BOOT_FAILD_IN_NORMAL = 3, // In the non-ota stage, startup is failed. +}; + +void SystemReadParam(const char* param, char* value, uint32_t* len) +{ + if (strcmp(param, "bootEvent1") == 0 || strcmp(param, "bootEvent3") == 0) { + int ret = strncpy_s(value, *len, "true", strlen("true")); + if (ret != 0) { + printf("strncpy_s failed\n"); + } + } else if (strcmp(param, "bootEvent2") == 0 || strcmp(param, "bootEvent4") == 0) { + int ret = strncpy_s(value, *len, "false", strlen("false")); + if (ret != 0) { + printf("strncpy_s failed\n"); + } + } else { + int ret = strncpy_s(value, *len, "unknown", strlen("unknown")); + if (ret != 0) { + printf("strncpy_s failed\n"); + } + } +} +static int BootEventJudgeBootComplete1(void) +{ + char value[6] = ""; + uint32_t len = sizeof(value); + int booteventLength = sizeof(g_bootEventOta1) / sizeof(g_bootEventOta1[0]); + + for (int i = 0; i < booteventLength; i++) { + SystemReadParam(g_bootEventOta1[i], value, &len); + if (strncmp(value, "true", BOOTEVENT_LEN) != 0) { + return 0; + } + } + return 1; +} +static int BootEventJudgeBootComplete2(void) +{ + char value[6] = ""; + uint32_t len = sizeof(value); + int booteventLength = sizeof(g_bootEventOta2) / sizeof(g_bootEventOta2[0]); + + for (int i = 0; i < booteventLength; i++) { + SystemReadParam(g_bootEventOta2[i], value, &len); + if (strncmp(value, "true", BOOTEVENT_LEN) != 0) { + return 0; + } + } + return 1; +} +static int BootEventJudgeBootComplete3(void) +{ + char value[6] = ""; + uint32_t len = sizeof(value); + int booteventLength = sizeof(g_bootEventOta3) / sizeof(g_bootEventOta3[0]); + + for (int i = 0; i < booteventLength; i++) { + SystemReadParam(g_bootEventOta3[i], value, &len); + if (strncmp(value, "true", BOOTEVENT_LEN) != 0) { + return 0; + } + } + return 1; +} + +static int BootEventJudgeBootComplete4(void) +{ + char value[6] = ""; + uint32_t len = sizeof(value); + int booteventLength = sizeof(g_bootEventOta4) / sizeof(g_bootEventOta4[0]); + + for (int i = 0; i < booteventLength; i++) { + SystemReadParam(g_bootEventOta4[i], value, &len); + if (strncmp(value, "true", BOOTEVENT_LEN) != 0) { + return 0; + } + } + return 1; +} +void RebootSystem() +{ + printf("System is rebooting...\n"); +} +int Mount(const char *source, const char *target, const char *filesystemtype, + unsigned long mountflags, const void *data) +{ + return 0; // Simulate successful mount +} +static int HandleBootStatus(int retOta) +{ + switch (retOta) { + case BOOT_SUCCESS_IN_OTA: + { + const char *mountPoint = "/data"; + const char *fsType = "f2fs"; + const char *options = "checkpoint=enable"; + int result = Mount(mountPoint, mountPoint, fsType, MS_REMOUNT, options); + if (result != 0) { + return -1; + } + printf("boot success in normal, no process.\n"); + break; + } + + case BOOT_SUCCESS_IN_NORMAL: + printf("boot success in normal, no process.\n"); + break; + + case BOOT_FAILD_IN_OTA: + printf("boot faild in OTA, start to reboot.\n"); + RebootSystem(); + break; + + case BOOT_FAILD_IN_NORMAL: + printf("boot faild in normal, no process.\n"); + break; + + case SET_OTA_STATUS_FAILED: + printf("Set OTA status failed, no process.\n"); + break; + + default: + printf("Unknown boot status, no process.\n"); + break; + } + return 1; +} +class OtaRollbackUnitTest : public testing::Test { +public: + static void SetUpTestCase(void) + { + cout << "OTA Rollback Unittest Begin!" << endl; + }; + static void TearDownTestCase(void) + { + cout << "OTA Rollback Unittest End!" << endl; + }; + void SetUp(void) {}; + void TearDown(void) {}; +}; +HWTEST_F(OtaRollbackUnitTest, BootEventJudgeBootComplete_001, TestSize.Level0) +{ + int result1 = BootEventJudgeBootComplete1(); + EXPECT_EQ(result1, 1); + + int result2 = BootEventJudgeBootComplete2(); + EXPECT_EQ(result2, 0); + + int result3 = BootEventJudgeBootComplete3(); + EXPECT_EQ(result3, 0); + + int result4 = BootEventJudgeBootComplete4(); + EXPECT_EQ(result4, 0); +} + +HWTEST_F(OtaRollbackUnitTest, Init_OtaRollback_001, TestSize.Level0) +{ + int result1 = HandleBootStatus(BOOT_SUCCESS_IN_OTA); + EXPECT_EQ(result1, 1); + + int result2 = HandleBootStatus(BOOT_SUCCESS_IN_NORMAL); + EXPECT_EQ(result2, 1); + + int result3 = HandleBootStatus(BOOT_FAILD_IN_OTA); + EXPECT_EQ(result3, 1); + + int result4 = HandleBootStatus(BOOT_FAILD_IN_NORMAL); + EXPECT_EQ(result4, 1); + + int result5 = HandleBootStatus(SET_OTA_STATUS_FAILED); + EXPECT_EQ(result5, 1); + + int result6 = HandleBootStatus(999); + EXPECT_EQ(result6, 1); + + int result7 = HandleBootStatus(-1); + EXPECT_EQ(result7, 1); +} +} \ No newline at end of file diff --git a/test/unittest/fs_manager/ota_rollback/ota_data_mount_unittest.cpp b/test/unittest/fs_manager/ota_rollback/ota_data_mount_unittest.cpp new file mode 100755 index 0000000000000000000000000000000000000000..7ced9c8164b17709e089efcdd0c63fb55109ce97 --- /dev/null +++ b/test/unittest/fs_manager/ota_rollback/ota_data_mount_unittest.cpp @@ -0,0 +1,77 @@ +/* + * Copyright (c) 2024 Hunan OpenValley Digital Industry Development Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "fs_manager/fs_manager.h" +#include +#include "init_utils.h" +#include +#include +#include +#include +#include + +using namespace std; +using namespace testing::ext; +namespace init_ut { +struct Item { + const char *mountPoint; + const char *fsType; +}; +class OtaDataRemountUnitTest : public testing::Test { +public: + static void SetUpTestCase(void) + { + cout << "OTA Data Remount Unittest Begin!" << endl; + }; + static void TearDownTestCase(void) + { + cout << "OTA Data Remount Unittest End!" << endl; + }; + void SetUp(void) {}; + void TearDown(void) {}; +}; +HWTEST_F(OtaDataRemountUnitTest, Init_OtaDataRemount_001, TestSize.Level0) +{ + Item item = {"/data", "f2fs"}; + const char *options = "checkpoint=disable"; + int result = mount(item.mountPoint, item.mountPoint, item.fsType, MS_REMOUNT, options); + EXPECT_EQ(result, 0); + + Item item1 = {"/data", "ext4"}; + int result1 = mount(item1.mountPoint, item1.mountPoint, item1.fsType, MS_REMOUNT, options); + EXPECT_EQ(result1, 0); + + Item item2 = {"/data", "unknown_fs"}; + int result2 = mount(item2.mountPoint, item2.mountPoint, item2.fsType, MS_REMOUNT, options); + EXPECT_EQ(result2, 0); +} + +HWTEST_F(OtaDataRemountUnitTest, Init_OtaDataRemount_002, TestSize.Level0) +{ + Item item = {"/data", "f2fs"}; + const char *options = "checkpoint=enable"; + int result = mount(item.mountPoint, item.mountPoint, item.fsType, MS_REMOUNT, options); + EXPECT_EQ(result, 0); + + Item item1 = {"/data", "ext4"}; + int result1 = mount(item1.mountPoint, item1.mountPoint, item1.fsType, MS_REMOUNT, options); + EXPECT_EQ(result1, 0); + + Item item2 = {"/data", "unknown_fs"}; + int result2 = mount(item2.mountPoint, item2.mountPoint, item2.fsType, MS_REMOUNT, options); + EXPECT_EQ(result2, 0); +} + +} \ No newline at end of file