diff --git a/interfaces/innerkits/fs_manager/fstab.c b/interfaces/innerkits/fs_manager/fstab.c index a35878f3fe58bf8ce13238b7680c8eaedd2323cc..bf8a4e6e540690403f99153c63573a4630a47969 100644 --- a/interfaces/innerkits/fs_manager/fstab.c +++ b/interfaces/innerkits/fs_manager/fstab.c @@ -338,6 +338,16 @@ int GetBlockDeviceByMountPoint(const char *mountPoint, const Fstab *fstab, char return 0; } +int GetBlockDeviceByName(const char *deviceName, const Fstab *fstab, char* miscDev, size_t size) +{ + for (FstabItem *item = fstab->head; item != NULL; item = item->next) { + if (strstr(item->deviceName, deviceName) != NULL) { + BEGET_CHECK_RETURN_VALUE(strcpy_s(miscDev, size, item->deviceName) != 0, 0); + } + } + return -1; +} + static const struct MountFlags mountFlags[] = { { "noatime", MS_NOATIME }, { "noexec", MS_NOEXEC }, @@ -487,21 +497,114 @@ unsigned long GetMountFlags(char *mountFlag, char *fsSpecificData, size_t fsSpec return flags; } -int GetBlockDevicePath(const char *partName, char *path, int size) +int GetBlockDevicePath(const char *partName, char *path, size_t size) { - char *fstabFile = GetFstabFile(path, size); - if (fstabFile == NULL) { - return -1; - } - Fstab *fstab = ReadFstabFromFile(fstabFile, false); + Fstab *fstab = LoadFstabFromCommandLine(); if (fstab == NULL) { - return -1; + BEGET_LOGI("fstab not found from cmdline, try to get it from file"); + char *fstabFile = GetFstabFile(path, size); + BEGET_CHECK_RETURN_VALUE(fstabFile != NULL, -1); + fstab = ReadFstabFromFile(fstabFile, false); } + BEGET_CHECK_RETURN_VALUE(fstab != NULL, -1); int ret = GetBlockDeviceByMountPoint(partName, fstab, path, size); + BEGET_INFO_CHECK(ret == 0, ret = GetBlockDeviceByName(partName, fstab, path, size), + "mount point not found, try to get it by device name"); ReleaseFstab(fstab); return ret; } +#define OHOS_REQUIRED_MOUNT_PREFIX "ohos.required_mount." +/* + * Fstab includes block device node, mount point, file system type, MNT_ Flags and options. + * We separate them by spaces in fstab.required file, but the separator is '@' in CmdLine. + * The prefix "ohos.required_mount." is the flag of required fstab information in CmdLine. + * Format as shown below: + * @@@@ + * e.g. + * ohos.required_mount.system=/dev/block/xxx/by-name/system@/usr@ext4@ro,barrier=1@wait,required + */ +static int ParseRequiredMountInfo(const char *item, Fstab *fstab) +{ + char mountOptions[MAX_BUFFER_LEN] = {}; + char partName[NAME_SIZE] = {}; + // Sanity checks + BEGET_CHECK(!(item == NULL || *item == '\0' || fstab == NULL), return -1); + + char *p = NULL; + const char *q = item; + if ((p = strstr(item, "=")) != NULL) { + q = item + strlen(OHOS_REQUIRED_MOUNT_PREFIX); // Get partition name + BEGET_CHECK(!(q == NULL || *q == '\0' || (p - q) <= 0), return -1); + BEGET_ERROR_CHECK(strncpy_s(partName, NAME_SIZE -1, q, p - q) == EOK, + return -1, "Failed to copy required partition name"); + p++; // skip '=' + BEGET_ERROR_CHECK(strncpy_s(mountOptions, MAX_BUFFER_LEN -1, p, strlen(p)) == EOK, + return -1, "Failed to copy required mount info: %s", item); + } + BEGET_LOGV("Mount option of partition %s is [%s]", partName, mountOptions); + if (ParseFstabPerLine(mountOptions, fstab, false, "@") < 0) { + BEGET_LOGE("Failed to parse mount options of partition \' %s \', options: %s", partName, mountOptions); + return -1; + } + return 0; +} + +Fstab* LoadFstabFromCommandLine(void) +{ + Fstab *fstab = NULL; + char *cmdline = ReadFileData(BOOT_CMD_LINE); + bool isDone = false; + + BEGET_ERROR_CHECK(cmdline != NULL, return NULL, "Read from \'/proc/cmdline\' failed, err = %d", errno); + TrimTail(cmdline, '\n'); + BEGET_ERROR_CHECK((fstab = (Fstab *)calloc(1, sizeof(Fstab))) != NULL, return NULL, + "Allocate memory for FS table failed, err = %d", errno); + char *start = cmdline; + char *end = start + strlen(cmdline); + while (start < end) { + char *token = strstr(start, " "); + if (token == NULL) { + break; + } + + // Startswith " " + if (token == start) { + start++; + continue; + } + *token = '\0'; + if (strncmp(start, OHOS_REQUIRED_MOUNT_PREFIX, + strlen(OHOS_REQUIRED_MOUNT_PREFIX)) != 0) { + start = token + 1; + continue; + } + isDone = true; + if (ParseRequiredMountInfo(start, fstab) < 0) { + BEGET_LOGE("Failed to parse \' %s \'", start); + isDone = false; + break; + } + start = token + 1; + } + + // handle last one + if (start < end) { + if (strncmp(start, OHOS_REQUIRED_MOUNT_PREFIX, + strlen(OHOS_REQUIRED_MOUNT_PREFIX)) == 0 && + ParseRequiredMountInfo(start, fstab) < 0) { + BEGET_LOGE("Failed to parse \' %s \'", start); + isDone = false; + } + } + + if (!isDone) { + ReleaseFstab(fstab); + fstab = NULL; + } + free(cmdline); + return fstab; +} #ifdef __cplusplus #if __cplusplus } diff --git a/interfaces/innerkits/fs_manager/fstab_mount.c b/interfaces/innerkits/fs_manager/fstab_mount.c index 2ffa4120f0e109392270cd5d84ce47899996bd60..e12f25235a508f73fe62c6ef744d193db6b6a7d2 100644 --- a/interfaces/innerkits/fs_manager/fstab_mount.c +++ b/interfaces/innerkits/fs_manager/fstab_mount.c @@ -21,9 +21,11 @@ #include #include #include +#include #include "beget_ext.h" #include "fs_manager/fs_manager.h" #include "init_utils.h" +#include "param/init_param.h" #include "securec.h" #ifdef __cplusplus @@ -35,6 +37,8 @@ extern "C" { #define FS_MANAGER_BUFFER_SIZE 512 #define BLOCK_SIZE_BUFFER (64) #define RESIZE_BUFFER_SIZE 1024 +const off_t MISC_PARTITION_ACTIVE_SLOT_OFFSET = 1400; +const off_t MISC_PARTITION_ACTIVE_SLOT_SIZE = 4; bool IsSupportedFilesystem(const char *fsType) { @@ -285,6 +289,68 @@ static int Mount(const char *source, const char *target, const char *fsType, return rc; } +static int GetSlotInfoFromParameter(const char *slotInfoName) +{ + char name[PARAM_NAME_LEN_MAX] = {0}; + BEGET_ERROR_CHECK(sprintf_s(name, sizeof(name), "ohos.boot.%s", slotInfoName) > 0, + return -1, "Failed to format slot parameter name"); + char value[PARAM_VALUE_LEN_MAX] = {0}; + uint32_t valueLen = PARAM_VALUE_LEN_MAX; + return SystemGetParameter(name, value, &valueLen) == 0 ? atoi(value) : -1; +} + +static int GetSlotInfoFromCmdLine(const char *slotInfoName) +{ + char value[MAX_BUFFER_LEN] = {0}; + char *buffer = ReadFileData(BOOT_CMD_LINE); + BEGET_ERROR_CHECK(buffer != NULL, return -1, "Failed to read cmdline"); + BEGET_ERROR_CHECK(GetProcCmdlineValue(slotInfoName, buffer, value, MAX_BUFFER_LEN) == 0, + free(buffer); buffer = NULL; return -1, "Failed to get %s value from cmdline", slotInfoName); + free(buffer); + buffer = NULL; + return atoi(value); +} + +static int GetSlotInfoFromMisc(off_t offset, off_t size) +{ + char miscDev[MAX_BUFFER_LEN] = {0}; + BEGET_ERROR_CHECK(GetBlockDevicePath("/misc", miscDev, MAX_BUFFER_LEN) == 0, + return -1, "Failed to get misc device"); + int fd = open(miscDev, O_RDWR | O_CLOEXEC, S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH); + BEGET_ERROR_CHECK(fd >= 0, return -1, "Failed to open misc device, errno %d", errno); + BEGET_ERROR_CHECK(lseek(fd, offset, SEEK_SET) >= 0, close(fd); return -1, + "Failed to lseek misc device fd, errno %d", errno); + int slotInfo = 0; + BEGET_ERROR_CHECK(read(fd, &slotInfo, size) == size, close(fd); return -1, + "Failed to read current slot from misc, errno %d", errno); + close(fd); + return slotInfo; +} + +int GetBootSlots(void) +{ + int bootSlots = GetSlotInfoFromParameter("bootslots"); + BEGET_CHECK_RETURN_VALUE(bootSlots <= 0, bootSlots); + BEGET_LOGI("No valid slot value found from parameter, try to get it from cmdline"); + return GetSlotInfoFromCmdLine("bootslots"); +} + +int GetCurrentSlot(void) +{ + // get current slot from parameter + int currentSlot = GetSlotInfoFromParameter("currentslot"); + BEGET_CHECK_RETURN_VALUE(currentSlot <= 0, currentSlot); + BEGET_LOGI("No valid slot value found from parameter, try to get it from cmdline"); + + // get current slot from cmdline + currentSlot = GetSlotInfoFromCmdLine("currentslot"); + BEGET_CHECK_RETURN_VALUE(currentSlot <= 0, currentSlot); + BEGET_LOGI("No valid slot value found from cmdline, try to get it from misc"); + + // get current slot from misc + return GetSlotInfoFromMisc(MISC_PARTITION_ACTIVE_SLOT_OFFSET, MISC_PARTITION_ACTIVE_SLOT_SIZE); +} + int MountOneItem(FstabItem *item) { if (item == NULL) { @@ -333,6 +399,21 @@ int MountOneItem(FstabItem *item) return rc; } +static void AdjustPartitionNameByPartitionSlot(FstabItem *item) +{ + BEGET_CHECK_ONLY_RETURN(strstr(item->deviceName, "/system") != NULL || + strstr(item->deviceName, "/vendor") != NULL); + char buffer[MAX_BUFFER_LEN] = {0}; + int slot = GetCurrentSlot(); + BEGET_ERROR_CHECK(slot > 0 && slot <= MAX_SLOT, slot = 1, "slot value %d is invalid, set default value", slot); + BEGET_INFO_CHECK(slot > 1, return, "default partition doesn't need to add suffix"); + BEGET_ERROR_CHECK(sprintf_s(buffer, sizeof(buffer), "%s_%c", item->deviceName, 'a' + slot - 1) > 0, + return, "Failed to format partition name suffix, use default partition name"); + free(item->deviceName); + item->deviceName = strdup(buffer); + BEGET_LOGI("partition name with slot suffix: %s", item->deviceName); +} + static int CheckRequiredAndMount(FstabItem *item, bool required) { int rc = 0; @@ -341,6 +422,9 @@ static int CheckRequiredAndMount(FstabItem *item, bool required) } if (required) { // Mount partition during first startup. if (FM_MANAGER_REQUIRED_ENABLED(item->fsManagerFlags)) { + int bootSlots = GetBootSlots(); + BEGET_INFO_CHECK(bootSlots <= 1, AdjustPartitionNameByPartitionSlot(item), + "boot slots is %d, now adjust partition name according to current slot", bootSlots); rc = MountOneItem(item); } } else { // Mount partition during second startup. diff --git a/interfaces/innerkits/include/fs_manager/fs_manager.h b/interfaces/innerkits/include/fs_manager/fs_manager.h index 225557a2b044e745756ab468d52ecc70a561d149..f0e1b52be90ec872ce0a9934fce46dc796a2c514 100644 --- a/interfaces/innerkits/include/fs_manager/fs_manager.h +++ b/interfaces/innerkits/include/fs_manager/fs_manager.h @@ -29,6 +29,8 @@ extern "C" { #define FS_MANAGER_CHECK 0x00000001 #define FS_MANAGER_WAIT 0x00000002 #define FS_MANAGER_REQUIRED 0x00000004 +#define NAME_SIZE 32 +#define MAX_SLOT 2 #define VALID_FS_MANAGER_FLAGS (FS_MANAGER_CHECK | FS_MANAGER_WAIT | FS_MANAGER_REQUIRED) #define FS_MANAGER_FLAGS_ENABLED(fsMgrFlags, flag) (((fsMgrFlags) & FS_MANAGER_##flag) != 0) @@ -56,6 +58,21 @@ typedef struct { struct FstabItem *head; } Fstab; +typedef enum SlotFlag { + UNBOOT = 0, + ACTIVE = 1, +} SlotFlag; + +typedef struct SlotInfo { + int slotName; + char *slotSuffix; + SlotFlag slotFlag; + unsigned int retryCount; + unsigned int reserved; +} SlotInfo; + +Fstab* LoadFstabFromCommandLine(void); +int GetSlotInfo(void); void ReleaseFstab(Fstab *fstab); Fstab *ReadFstabFromFile(const char *file, bool procMounts); FstabItem *FindFstabItemForPath(Fstab fstab, const char *path); @@ -63,6 +80,7 @@ FstabItem* FindFstabItemForMountPoint(Fstab fstab, const char *mp); int ParseFstabPerLine(char *str, Fstab *fstab, bool procMounts, const char *separator); int GetBlockDeviceByMountPoint(const char *mountPoint, const Fstab *fstab, char *deviceName, int nameLen); +int GetBlockDeviceByName(const char *deviceName, const Fstab *fstab, char* miscDev, size_t size); bool IsSupportedFilesystem(const char *fsType); int DoFormat(const char *devPath, const char *fsType); int MountOneItem(FstabItem *item); @@ -73,7 +91,7 @@ int UmountAllWithFstabFile(const char *file); unsigned long GetMountFlags(char *mountFlag, char *fsSpecificFlags, size_t fsSpecificFlagSize, const char *mountPoint); -int GetBlockDevicePath(const char *partName, char *path, int size); +int GetBlockDevicePath(const char *partName, char *path, size_t size); // Get fscrypt policy if exist int LoadFscryptPolicy(char *buf, size_t size); diff --git a/services/begetctl/BUILD.gn b/services/begetctl/BUILD.gn index 7b5d8702d12bf1b367424a84fb36bb20c0d222de..118071c1f80a2d85d4e69904513917d14d8d356c 100755 --- a/services/begetctl/BUILD.gn +++ b/services/begetctl/BUILD.gn @@ -124,6 +124,14 @@ if (defined(ohos_lite)) { "sandbox", "dump_service", ] + + if (product_name == "rk3568") { + sources += [ "partitionslot.cpp" ] + external_deps += + [ "drivers_peripheral_partitionslot:libpartition_slot_manager" ] + symlink_target_name += [ "partitionslot" ] + } + install_images = [ "system" ] install_enable = true part_name = "init" diff --git a/services/begetctl/partitionslot.cpp b/services/begetctl/partitionslot.cpp new file mode 100644 index 0000000000000000000000000000000000000000..47a8c857fc03f9272db9b8e754da8ee2bcf5be83 --- /dev/null +++ b/services/begetctl/partitionslot.cpp @@ -0,0 +1,96 @@ +/* + * Copyright (c) 2022 Huawei Device 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 + +#include "begetctl.h" +#include "partitionslot_manager.h" + +using namespace OHOS::HDI::Partitionslot::V1_0; +const int32_t PARTITION_ARGC = 2; + +static int GetSlot(BShellHandle handle, int32_t argc, char *argv[]) +{ + std::cout << "Command: partitionslot getslot" << std::endl; + int bootSlots = 0; + int currentSlot = PartitionSlotManager::GetInstance()->GetCurrentSlot(bootSlots); + std::cout << "The number of slots: " << bootSlots << "," << "current slot: " << currentSlot << std::endl; + return 0; +} + +static int GetSuffix(BShellHandle handle, int32_t argc, char *argv[]) +{ + if (argc != PARTITION_ARGC) { + BShellCmdHelp(handle, argc, argv); + return 0; + } + std::cout << "Command: partitionslot getsuffix" << std::endl; + int slot = atoi(argv[1]); + std::string suffix = ""; + PartitionSlotManager::GetInstance()->GetSlotSuffix(slot, suffix); + std::cout << "The slot " << slot << " matches with suffix: " << suffix << std::endl; + return 0; +} + +static int SetActiveSlot(BShellHandle handle, int32_t argc, char *argv[]) +{ + if (argc != PARTITION_ARGC) { + BShellCmdHelp(handle, argc, argv); + return 0; + } + std::cout << "Command: partitionslot setactive" << std::endl; + int slot = atoi(argv[1]); + PartitionSlotManager::GetInstance()->SetActiveSlot(slot); + std::cout << "Set active slot: " << slot << std::endl; + return 0; +} + +static int SetUnbootSlot(BShellHandle handle, int32_t argc, char *argv[]) +{ + if (argc != PARTITION_ARGC) { + BShellCmdHelp(handle, argc, argv); + return 0; + } + std::cout << "Command: partitionslot setunboot" << std::endl; + int slot = atoi(argv[1]); + PartitionSlotManager::GetInstance()->SetSlotUnbootable(slot); + std::cout << "Set unboot slot: " << slot << std::endl; + return 0; +} + +MODULE_CONSTRUCTOR(void) +{ + CmdInfo infos[] = { + { + (char *)"partitionslot", GetSlot, (char *)"get the number of slots and current slot", + (char *)"partitionslot getslot", (char *)"partitionslot getslot" + }, + { + (char *)"partitionslot", GetSuffix, (char *)"get suffix that matches with the slot", + (char *)"partitionslot getsuffix [slot]", (char *)"partitionslot getsuffix" + }, + { + (char *)"partitionslot", SetActiveSlot, (char *)"set active slot", + (char *)"partitionslot setactive [slot]", (char *)"partitionslot setactive" + }, + { + (char *)"partitionslot", SetUnbootSlot, (char *)"set unboot slot", + (char *)"partitionslot setunboot [slot]", (char *)"partitionslot setunboot" + } + }; + for (size_t i = sizeof(infos) / sizeof(infos[0]); i > 0; i--) { + BShellEnvRegitsterCmd(GetShellHandle(), &infos[i - 1]); + } +} diff --git a/services/init/standard/init_mount.c b/services/init/standard/init_mount.c index 7930f676eeebe6f867432b36495766a46cef133c..9786cbe33472f8430ed3dc43a10a0d28f376b5a1 100644 --- a/services/init/standard/init_mount.c +++ b/services/init/standard/init_mount.c @@ -32,98 +32,6 @@ int MountRequriedPartitions(const Fstab *fstab) return rc; } -#define OHOS_REQUIRED_MOUNT_PREFIX "ohos.required_mount." -/* - * Fstab includes block device node, mount point, file system type, MNT_ Flags and options. - * We separate them by spaces in fstab.required file, but the separator is '@' in CmdLine. - * The prefix "ohos.required_mount." is the flag of required fstab information in CmdLine. - * Format as shown below: - * @@@@ - * e.g. - * ohos.required_mount.system=/dev/block/xxx/by-name/system@/usr@ext4@ro,barrier=1@wait,required - */ -static int ParseRequiredMountInfo(const char *item, Fstab *fstab) -{ - char mountOptions[MAX_BUFFER_LEN] = {}; - char partName[PARTITION_NAME_SIZE] = {}; - // Sanity checks - INIT_CHECK(!(item == NULL || *item == '\0' || fstab == NULL), return -1); - - char *p = NULL; - const char *q = item; - if ((p = strstr(item, "=")) != NULL) { - q = item + strlen(OHOS_REQUIRED_MOUNT_PREFIX); // Get partition name - INIT_CHECK(!(q == NULL || *q == '\0' || (p - q) <= 0), return -1); - INIT_ERROR_CHECK(strncpy_s(partName, PARTITION_NAME_SIZE -1, q, p - q) == EOK, - return -1, "Failed to copy required partition name"); - p++; // skip '=' - INIT_ERROR_CHECK(strncpy_s(mountOptions, MAX_BUFFER_LEN -1, p, strlen(p)) == EOK, - return -1, "Failed to copy required mount info: %s", item); - } - INIT_LOGV("Mount option of partition %s is [%s]", partName, mountOptions); - if (ParseFstabPerLine(mountOptions, fstab, false, "@") < 0) { - INIT_LOGE("Failed to parse mount options of partition \' %s \', options: %s", partName, mountOptions); - return -1; - } - return 0; -} - -static Fstab* LoadFstabFromCommandLine(void) -{ - Fstab *fstab = NULL; - char *cmdline = ReadFileData(BOOT_CMD_LINE); - bool isDone = false; - - INIT_ERROR_CHECK(cmdline != NULL, return NULL, "Read from \'/proc/cmdline\' failed, err = %d", errno); - TrimTail(cmdline, '\n'); - INIT_ERROR_CHECK((fstab = (Fstab *)calloc(1, sizeof(Fstab))) != NULL, return NULL, - "Allocate memory for FS table failed, err = %d", errno); - char *start = cmdline; - char *end = start + strlen(cmdline); - while (start < end) { - char *token = strstr(start, " "); - if (token == NULL) { - break; - } - - // Startswith " " - if (token == start) { - start++; - continue; - } - *token = '\0'; - if (strncmp(start, OHOS_REQUIRED_MOUNT_PREFIX, - strlen(OHOS_REQUIRED_MOUNT_PREFIX)) != 0) { - start = token + 1; - continue; - } - isDone = true; - if (ParseRequiredMountInfo(start, fstab) < 0) { - INIT_LOGE("Failed to parse \' %s \'", start); - isDone = false; - break; - } - start = token + 1; - } - - // handle last one - if (start < end) { - if (strncmp(start, OHOS_REQUIRED_MOUNT_PREFIX, - strlen(OHOS_REQUIRED_MOUNT_PREFIX)) == 0 && - ParseRequiredMountInfo(start, fstab) < 0) { - INIT_LOGE("Failed to parse \' %s \'", start); - isDone = false; - } - } - - if (!isDone) { - ReleaseFstab(fstab); - fstab = NULL; - } - free(cmdline); - return fstab; -} - Fstab* LoadRequiredFstab(void) { Fstab *fstab = NULL; diff --git a/services/init/standard/init_mount.h b/services/init/standard/init_mount.h index a3b0173c2ae96e932f6cb374247015e1732754ff..c4c89a0c3227cf198b4f0821a9c70439f8ff79d4 100644 --- a/services/init/standard/init_mount.h +++ b/services/init/standard/init_mount.h @@ -23,7 +23,6 @@ extern "C" { #endif #endif -#define PARTITION_NAME_SIZE 32 Fstab* LoadRequiredFstab(void); int MountRequriedPartitions(const Fstab *fstab); #ifdef __cplusplus diff --git a/services/param/manager/param_server.c b/services/param/manager/param_server.c index 5126184363d0a03acfb833d2ded93da1a9b82d80..357d6dd1ccd3fc36ea7d8976b072067ba097d1d8 100755 --- a/services/param/manager/param_server.c +++ b/services/param/manager/param_server.c @@ -120,6 +120,8 @@ INIT_LOCAL_API int LoadParamFromCmdLine(void) }, {OHOS_BOOT"reboot_reason", CommonDealFun }, + {OHOS_BOOT"bootslots", CommonDealFun + }, {OHOS_BOOT"sn", SnDealFun } }; diff --git a/ueventd/ueventd.c b/ueventd/ueventd.c index 51f7cac67fb5301f7e340fdea31943dba46deb06..5755dab60e09adfe814de9a8e83c1570ac4ac37c 100644 --- a/ueventd/ueventd.c +++ b/ueventd/ueventd.c @@ -182,7 +182,8 @@ static void HandleRequiredBlockDeviceNodes(const struct Uevent *uevent, char **d INIT_LOGI("%s match with required partition %s success, now handle it", uevent->syspath, deviceName); HandleBlockDeviceEvent(uevent); return; - } else if (strstr(devices[i], uevent->partitionName) != NULL) { + } else if (strstr(devices[i], uevent->partitionName) != NULL || + strstr(uevent->partitionName, "vendor") != NULL || strstr(uevent->partitionName, "system") != NULL) { INIT_LOGI("Handle required partitionName %s", uevent->partitionName); HandleBlockDeviceEvent(uevent); return;