1d9f0492fSopenharmony_ci/* 2d9f0492fSopenharmony_ci * Copyright (c) 2021 Huawei Device Co., Ltd. 3d9f0492fSopenharmony_ci * Licensed under the Apache License, Version 2.0 (the "License"); 4d9f0492fSopenharmony_ci * you may not use this file except in compliance with the License. 5d9f0492fSopenharmony_ci * You may obtain a copy of the License at 6d9f0492fSopenharmony_ci * 7d9f0492fSopenharmony_ci * http://www.apache.org/licenses/LICENSE-2.0 8d9f0492fSopenharmony_ci * 9d9f0492fSopenharmony_ci * Unless required by applicable law or agreed to in writing, software 10d9f0492fSopenharmony_ci * distributed under the License is distributed on an "AS IS" BASIS, 11d9f0492fSopenharmony_ci * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12d9f0492fSopenharmony_ci * See the License for the specific language governing permissions and 13d9f0492fSopenharmony_ci * limitations under the License. 14d9f0492fSopenharmony_ci */ 15d9f0492fSopenharmony_ci 16d9f0492fSopenharmony_ci#include "ueventd.h" 17d9f0492fSopenharmony_ci#include <dirent.h> 18d9f0492fSopenharmony_ci#include <limits.h> 19d9f0492fSopenharmony_ci#include <fcntl.h> 20d9f0492fSopenharmony_ci#include <errno.h> 21d9f0492fSopenharmony_ci#include <stdlib.h> 22d9f0492fSopenharmony_ci#include <string.h> 23d9f0492fSopenharmony_ci#include <sys/stat.h> 24d9f0492fSopenharmony_ci#include <sys/sysmacros.h> 25d9f0492fSopenharmony_ci#include <fcntl.h> 26d9f0492fSopenharmony_ci#include <unistd.h> 27d9f0492fSopenharmony_ci 28d9f0492fSopenharmony_ci#include "ueventd_device_handler.h" 29d9f0492fSopenharmony_ci#include "ueventd_firmware_handler.h" 30d9f0492fSopenharmony_ci#include "ueventd_read_cfg.h" 31d9f0492fSopenharmony_ci#include "ueventd_socket.h" 32d9f0492fSopenharmony_ci#include "ueventd_utils.h" 33d9f0492fSopenharmony_ci#include "securec.h" 34d9f0492fSopenharmony_ci#define INIT_LOG_TAG "ueventd" 35d9f0492fSopenharmony_ci#include "init_log.h" 36d9f0492fSopenharmony_ci#include "init_utils.h" 37d9f0492fSopenharmony_ci 38d9f0492fSopenharmony_ci// buffer size refer to kernel kobject uevent 39d9f0492fSopenharmony_ci#define UEVENT_BUFFER_SIZE (2048 + 1) 40d9f0492fSopenharmony_cichar bootDevice[CMDLINE_VALUE_LEN_MAX] = { 0 }; 41d9f0492fSopenharmony_ci#define WRITE_SIZE 4 42d9f0492fSopenharmony_ci 43d9f0492fSopenharmony_cistatic const char *actions[] = { 44d9f0492fSopenharmony_ci [ACTION_ADD] = "add", 45d9f0492fSopenharmony_ci [ACTION_REMOVE] = "remove", 46d9f0492fSopenharmony_ci [ACTION_CHANGE] = "change", 47d9f0492fSopenharmony_ci [ACTION_MOVE] = "move", 48d9f0492fSopenharmony_ci [ACTION_ONLINE] = "online", 49d9f0492fSopenharmony_ci [ACTION_OFFLINE] = "offline", 50d9f0492fSopenharmony_ci [ACTION_BIND] = "bind", 51d9f0492fSopenharmony_ci [ACTION_UNBIND] = "unbind", 52d9f0492fSopenharmony_ci [ACTION_UNKNOWN] = "unknown", 53d9f0492fSopenharmony_ci}; 54d9f0492fSopenharmony_ci 55d9f0492fSopenharmony_cistatic SUBSYSTEMTYPE GetSubsystemType(const char *subsystem) 56d9f0492fSopenharmony_ci{ 57d9f0492fSopenharmony_ci if (subsystem == NULL || *subsystem == '\0') { 58d9f0492fSopenharmony_ci return SUBSYSTEM_EMPTY; 59d9f0492fSopenharmony_ci } 60d9f0492fSopenharmony_ci 61d9f0492fSopenharmony_ci if (strcmp(subsystem, "block") == 0) { 62d9f0492fSopenharmony_ci return SUBSYSTEM_BLOCK; 63d9f0492fSopenharmony_ci } else if (strcmp(subsystem, "platform") == 0) { 64d9f0492fSopenharmony_ci return SUBSYSTEM_PLATFORM; 65d9f0492fSopenharmony_ci } else if (strcmp(subsystem, "firmware") == 0) { 66d9f0492fSopenharmony_ci return SUBSYSTEM_FIRMWARE; 67d9f0492fSopenharmony_ci } else { 68d9f0492fSopenharmony_ci return SUBSYSTEM_OTHERS; 69d9f0492fSopenharmony_ci } 70d9f0492fSopenharmony_ci} 71d9f0492fSopenharmony_ci 72d9f0492fSopenharmony_ciconst char *ActionString(ACTION action) 73d9f0492fSopenharmony_ci{ 74d9f0492fSopenharmony_ci return actions[action]; 75d9f0492fSopenharmony_ci} 76d9f0492fSopenharmony_ci 77d9f0492fSopenharmony_cistatic ACTION GetUeventAction(const char *action) 78d9f0492fSopenharmony_ci{ 79d9f0492fSopenharmony_ci if (action == NULL || *action == '\0') { 80d9f0492fSopenharmony_ci return ACTION_UNKNOWN; 81d9f0492fSopenharmony_ci } 82d9f0492fSopenharmony_ci 83d9f0492fSopenharmony_ci if (STRINGEQUAL(action, "add")) { 84d9f0492fSopenharmony_ci return ACTION_ADD; 85d9f0492fSopenharmony_ci } else if (STRINGEQUAL(action, "remove")) { 86d9f0492fSopenharmony_ci return ACTION_REMOVE; 87d9f0492fSopenharmony_ci } else if (STRINGEQUAL(action, "change")) { 88d9f0492fSopenharmony_ci return ACTION_CHANGE; 89d9f0492fSopenharmony_ci } else if (STRINGEQUAL(action, "move")) { 90d9f0492fSopenharmony_ci return ACTION_MOVE; 91d9f0492fSopenharmony_ci } else if (STRINGEQUAL(action, "online")) { 92d9f0492fSopenharmony_ci return ACTION_ONLINE; 93d9f0492fSopenharmony_ci } else if (STRINGEQUAL(action, "offline")) { 94d9f0492fSopenharmony_ci return ACTION_OFFLINE; 95d9f0492fSopenharmony_ci } else if (STRINGEQUAL(action, "bind")) { 96d9f0492fSopenharmony_ci return ACTION_BIND; 97d9f0492fSopenharmony_ci } else if (STRINGEQUAL(action, "unbind")) { 98d9f0492fSopenharmony_ci return ACTION_UNBIND; 99d9f0492fSopenharmony_ci } else { 100d9f0492fSopenharmony_ci return ACTION_UNKNOWN; 101d9f0492fSopenharmony_ci } 102d9f0492fSopenharmony_ci} 103d9f0492fSopenharmony_ci 104d9f0492fSopenharmony_ciSTATIC void HandleUevent(const struct Uevent *uevent) 105d9f0492fSopenharmony_ci{ 106d9f0492fSopenharmony_ci if (uevent->action == ACTION_ADD || uevent->action == ACTION_CHANGE || uevent->action == ACTION_ONLINE) { 107d9f0492fSopenharmony_ci ChangeSysAttributePermissions(uevent->syspath); 108d9f0492fSopenharmony_ci } 109d9f0492fSopenharmony_ci 110d9f0492fSopenharmony_ci SUBSYSTEMTYPE type = GetSubsystemType(uevent->subsystem); 111d9f0492fSopenharmony_ci switch (type) { 112d9f0492fSopenharmony_ci case SUBSYSTEM_BLOCK: 113d9f0492fSopenharmony_ci HandleBlockDeviceEvent(uevent); 114d9f0492fSopenharmony_ci break; 115d9f0492fSopenharmony_ci case SUBSYSTEM_FIRMWARE: 116d9f0492fSopenharmony_ci HandleFimwareDeviceEvent(uevent); 117d9f0492fSopenharmony_ci break; 118d9f0492fSopenharmony_ci case SUBSYSTEM_OTHERS: 119d9f0492fSopenharmony_ci HandleOtherDeviceEvent(uevent); 120d9f0492fSopenharmony_ci break; 121d9f0492fSopenharmony_ci default: 122d9f0492fSopenharmony_ci break; 123d9f0492fSopenharmony_ci } 124d9f0492fSopenharmony_ci} 125d9f0492fSopenharmony_ci 126d9f0492fSopenharmony_ci#define DEFAULT_RW_MODE (S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP | S_IROTH | S_IWOTH) 127d9f0492fSopenharmony_ci 128d9f0492fSopenharmony_citypedef struct { 129d9f0492fSopenharmony_ci const char *dev; 130d9f0492fSopenharmony_ci mode_t mode; 131d9f0492fSopenharmony_ci} DYNAMIC_DEVICE_NODE; 132d9f0492fSopenharmony_ci 133d9f0492fSopenharmony_ci#define DEV_NODE_PATH_PREFIX "/dev/" 134d9f0492fSopenharmony_ci#define DEV_NODE_PATH_PREFIX_LEN 5 135d9f0492fSopenharmony_ci 136d9f0492fSopenharmony_cistatic const DYNAMIC_DEVICE_NODE DYNAMIC_DEVICES[] = { 137d9f0492fSopenharmony_ci { DEV_NODE_PATH_PREFIX"tty", S_IFCHR | DEFAULT_RW_MODE }, 138d9f0492fSopenharmony_ci { DEV_NODE_PATH_PREFIX"binder", S_IFCHR | DEFAULT_RW_MODE }, 139d9f0492fSopenharmony_ci { DEV_NODE_PATH_PREFIX"console", S_IFCHR | S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP }, 140d9f0492fSopenharmony_ci { DEV_NODE_PATH_PREFIX"mapper/control", S_IFCHR | DEFAULT_RW_MODE } 141d9f0492fSopenharmony_ci}; 142d9f0492fSopenharmony_ci 143d9f0492fSopenharmony_cistatic void HandleRequiredDynamicDeviceNodes(const struct Uevent *uevent) 144d9f0492fSopenharmony_ci{ 145d9f0492fSopenharmony_ci mode_t mask; 146d9f0492fSopenharmony_ci size_t idx = 0; 147d9f0492fSopenharmony_ci 148d9f0492fSopenharmony_ci if (uevent->deviceName == NULL) { 149d9f0492fSopenharmony_ci return; 150d9f0492fSopenharmony_ci } 151d9f0492fSopenharmony_ci 152d9f0492fSopenharmony_ci while (idx < sizeof(DYNAMIC_DEVICES) / sizeof(DYNAMIC_DEVICES[0])) { 153d9f0492fSopenharmony_ci if (strcmp(uevent->deviceName, DYNAMIC_DEVICES[idx].dev + DEV_NODE_PATH_PREFIX_LEN) != 0) { 154d9f0492fSopenharmony_ci idx++; 155d9f0492fSopenharmony_ci continue; 156d9f0492fSopenharmony_ci } 157d9f0492fSopenharmony_ci 158d9f0492fSopenharmony_ci if (strcmp(uevent->deviceName, "mapper/control") == 0) { 159d9f0492fSopenharmony_ci HandleOtherDeviceEvent(uevent); 160d9f0492fSopenharmony_ci return; 161d9f0492fSopenharmony_ci } 162d9f0492fSopenharmony_ci 163d9f0492fSopenharmony_ci // Matched 164d9f0492fSopenharmony_ci mask = umask(0); 165d9f0492fSopenharmony_ci if (mknod(DYNAMIC_DEVICES[idx].dev, DYNAMIC_DEVICES[idx].mode, 166d9f0492fSopenharmony_ci makedev((unsigned int)uevent->major, (unsigned int)uevent->minor)) != 0) { 167d9f0492fSopenharmony_ci INIT_LOGE("Create device node %s failed. %s", DYNAMIC_DEVICES[idx].dev, strerror(errno)); 168d9f0492fSopenharmony_ci } 169d9f0492fSopenharmony_ci // Restore umask 170d9f0492fSopenharmony_ci umask(mask); 171d9f0492fSopenharmony_ci break; 172d9f0492fSopenharmony_ci } 173d9f0492fSopenharmony_ci} 174d9f0492fSopenharmony_ci 175d9f0492fSopenharmony_cistatic void HandleRequiredBlockDeviceNodes(const struct Uevent *uevent, char **devices, int num) 176d9f0492fSopenharmony_ci{ 177d9f0492fSopenharmony_ci for (int i = 0; i < num; i++) { 178d9f0492fSopenharmony_ci if (uevent->partitionName == NULL) { 179d9f0492fSopenharmony_ci if (strstr(devices[i], uevent->deviceName) != NULL) { 180d9f0492fSopenharmony_ci INIT_LOGI("%s match with required partition %s success, now handle it", devices[i], uevent->deviceName); 181d9f0492fSopenharmony_ci HandleBlockDeviceEvent(uevent); 182d9f0492fSopenharmony_ci return; 183d9f0492fSopenharmony_ci } 184d9f0492fSopenharmony_ci } else if (strstr(devices[i], uevent->partitionName) != NULL || 185d9f0492fSopenharmony_ci strstr(uevent->partitionName, "vendor") != NULL || 186d9f0492fSopenharmony_ci strstr(uevent->partitionName, "system") != NULL || 187d9f0492fSopenharmony_ci strstr(uevent->partitionName, "chipset") != NULL || 188d9f0492fSopenharmony_ci strstr(uevent->partitionName, "boot") != NULL || 189d9f0492fSopenharmony_ci strstr(uevent->partitionName, "ramdisk") != NULL || 190d9f0492fSopenharmony_ci strstr(uevent->partitionName, "rvt") != NULL || 191d9f0492fSopenharmony_ci strstr(uevent->partitionName, "dtbo") != NULL) { 192d9f0492fSopenharmony_ci INIT_LOGI("Handle required partitionName %s", uevent->partitionName); 193d9f0492fSopenharmony_ci HandleBlockDeviceEvent(uevent); 194d9f0492fSopenharmony_ci return; 195d9f0492fSopenharmony_ci } 196d9f0492fSopenharmony_ci } 197d9f0492fSopenharmony_ci INIT_LOGW("Not found device for partitionName %s ", uevent->partitionName); 198d9f0492fSopenharmony_ci} 199d9f0492fSopenharmony_ci 200d9f0492fSopenharmony_cistatic void HandleUeventRequired(const struct Uevent *uevent, char **devices, int num) 201d9f0492fSopenharmony_ci{ 202d9f0492fSopenharmony_ci INIT_ERROR_CHECK(devices != NULL && num > 0, return, "Fault parameters"); 203d9f0492fSopenharmony_ci if (uevent->action == ACTION_ADD) { 204d9f0492fSopenharmony_ci ChangeSysAttributePermissions(uevent->syspath); 205d9f0492fSopenharmony_ci } 206d9f0492fSopenharmony_ci SUBSYSTEMTYPE type = GetSubsystemType(uevent->subsystem); 207d9f0492fSopenharmony_ci if (type == SUBSYSTEM_BLOCK) { 208d9f0492fSopenharmony_ci HandleRequiredBlockDeviceNodes(uevent, devices, num); 209d9f0492fSopenharmony_ci } else if (type == SUBSYSTEM_OTHERS) { 210d9f0492fSopenharmony_ci HandleRequiredDynamicDeviceNodes(uevent); 211d9f0492fSopenharmony_ci } else { 212d9f0492fSopenharmony_ci return; 213d9f0492fSopenharmony_ci } 214d9f0492fSopenharmony_ci} 215d9f0492fSopenharmony_ci 216d9f0492fSopenharmony_cistatic void AddUevent(struct Uevent *uevent, const char *event, size_t len) 217d9f0492fSopenharmony_ci{ 218d9f0492fSopenharmony_ci if (STARTSWITH(event, "DEVPATH=")) { 219d9f0492fSopenharmony_ci uevent->syspath = event + strlen("DEVPATH="); 220d9f0492fSopenharmony_ci } else if (STARTSWITH(event, "SUBSYSTEM=")) { 221d9f0492fSopenharmony_ci uevent->subsystem = event + strlen("SUBSYSTEM="); 222d9f0492fSopenharmony_ci } else if (STARTSWITH(event, "ACTION=")) { 223d9f0492fSopenharmony_ci uevent->action = GetUeventAction(event + strlen("ACTION=")); 224d9f0492fSopenharmony_ci } else if (STARTSWITH(event, "DEVNAME=")) { 225d9f0492fSopenharmony_ci uevent->deviceName = event + strlen("DEVNAME="); 226d9f0492fSopenharmony_ci } else if (STARTSWITH(event, "PARTNAME=")) { 227d9f0492fSopenharmony_ci uevent->partitionName = event + strlen("PARTNAME="); 228d9f0492fSopenharmony_ci } else if (STARTSWITH(event, "PARTN=")) { 229d9f0492fSopenharmony_ci uevent->partitionNum = StringToInt(event + strlen("PARTN="), -1); 230d9f0492fSopenharmony_ci } else if (STARTSWITH(event, "MAJOR=")) { 231d9f0492fSopenharmony_ci uevent->major = StringToInt(event + strlen("MAJOR="), -1); 232d9f0492fSopenharmony_ci } else if (STARTSWITH(event, "MINOR=")) { 233d9f0492fSopenharmony_ci uevent->minor = StringToInt(event + strlen("MINOR="), -1); 234d9f0492fSopenharmony_ci } else if (STARTSWITH(event, "DEVUID")) { 235d9f0492fSopenharmony_ci uevent->ug.uid = (uid_t)StringToInt(event + strlen("DEVUID="), 0); 236d9f0492fSopenharmony_ci } else if (STARTSWITH(event, "DEVGID")) { 237d9f0492fSopenharmony_ci uevent->ug.gid = (gid_t)StringToInt(event + strlen("DEVGID="), 0); 238d9f0492fSopenharmony_ci } else if (STARTSWITH(event, "FIRMWARE=")) { 239d9f0492fSopenharmony_ci uevent->firmware = event + strlen("FIRMWARE="); 240d9f0492fSopenharmony_ci } else if (STARTSWITH(event, "BUSNUM=")) { 241d9f0492fSopenharmony_ci uevent->busNum = StringToInt(event + strlen("BUSNUM="), -1); 242d9f0492fSopenharmony_ci } else if (STARTSWITH(event, "DEVNUM=")) { 243d9f0492fSopenharmony_ci uevent->devNum = StringToInt(event + strlen("DEVNUM="), -1); 244d9f0492fSopenharmony_ci } 245d9f0492fSopenharmony_ci 246d9f0492fSopenharmony_ci // Ignore other events 247d9f0492fSopenharmony_ci INIT_LOGV("got uevent message:\n" 248d9f0492fSopenharmony_ci "subsystem: %s\n" 249d9f0492fSopenharmony_ci "parition: %s:%d\n" 250d9f0492fSopenharmony_ci "action: %s\n" 251d9f0492fSopenharmony_ci "devpath: %s\n" 252d9f0492fSopenharmony_ci "devname: %s\n" 253d9f0492fSopenharmony_ci "devnode: %d:%d\n" 254d9f0492fSopenharmony_ci "id: %d:%d", 255d9f0492fSopenharmony_ci uevent->subsystem, 256d9f0492fSopenharmony_ci uevent->partitionName, uevent->partitionNum, 257d9f0492fSopenharmony_ci uevent->action, 258d9f0492fSopenharmony_ci uevent->syspath, 259d9f0492fSopenharmony_ci uevent->deviceName, 260d9f0492fSopenharmony_ci uevent->major, uevent->minor, 261d9f0492fSopenharmony_ci uevent->ug.uid, uevent->ug.gid); 262d9f0492fSopenharmony_ci} 263d9f0492fSopenharmony_ci 264d9f0492fSopenharmony_civoid ParseUeventMessage(const char *buffer, ssize_t length, struct Uevent *uevent) 265d9f0492fSopenharmony_ci{ 266d9f0492fSopenharmony_ci if (buffer == NULL || uevent == NULL || length == 0) { 267d9f0492fSopenharmony_ci // Ignore invalid buffer 268d9f0492fSopenharmony_ci return; 269d9f0492fSopenharmony_ci } 270d9f0492fSopenharmony_ci 271d9f0492fSopenharmony_ci // reset partition number, major and minor. 272d9f0492fSopenharmony_ci uevent->partitionName = NULL; 273d9f0492fSopenharmony_ci uevent->partitionNum = -1; 274d9f0492fSopenharmony_ci uevent->major = -1; 275d9f0492fSopenharmony_ci uevent->minor = -1; 276d9f0492fSopenharmony_ci uevent->busNum = -1; 277d9f0492fSopenharmony_ci uevent->devNum = -1; 278d9f0492fSopenharmony_ci ssize_t pos = 0; 279d9f0492fSopenharmony_ci while (pos < length) { 280d9f0492fSopenharmony_ci const char *event = buffer + pos; 281d9f0492fSopenharmony_ci size_t len = strlen(event); 282d9f0492fSopenharmony_ci if (len == 0) { 283d9f0492fSopenharmony_ci break; 284d9f0492fSopenharmony_ci } 285d9f0492fSopenharmony_ci AddUevent(uevent, event, len); 286d9f0492fSopenharmony_ci pos += (ssize_t)len + 1; 287d9f0492fSopenharmony_ci } 288d9f0492fSopenharmony_ci} 289d9f0492fSopenharmony_ci 290d9f0492fSopenharmony_civoid ProcessUevent(int sockFd, char **devices, int num) 291d9f0492fSopenharmony_ci{ 292d9f0492fSopenharmony_ci // One more bytes for '\0' 293d9f0492fSopenharmony_ci char ueventBuffer[UEVENT_BUFFER_SIZE] = {}; 294d9f0492fSopenharmony_ci ssize_t n = 0; 295d9f0492fSopenharmony_ci struct Uevent uevent = {}; 296d9f0492fSopenharmony_ci while ((n = ReadUeventMessage(sockFd, ueventBuffer, sizeof(ueventBuffer) - 1)) > 0) { 297d9f0492fSopenharmony_ci ParseUeventMessage(ueventBuffer, n, &uevent); 298d9f0492fSopenharmony_ci if (uevent.syspath == NULL) { 299d9f0492fSopenharmony_ci INIT_LOGV("Ignore unexpected uevent"); 300d9f0492fSopenharmony_ci return; 301d9f0492fSopenharmony_ci } 302d9f0492fSopenharmony_ci if (devices != NULL && num > 0) { 303d9f0492fSopenharmony_ci HandleUeventRequired(&uevent, devices, num); 304d9f0492fSopenharmony_ci } else { 305d9f0492fSopenharmony_ci HandleUevent(&uevent); 306d9f0492fSopenharmony_ci } 307d9f0492fSopenharmony_ci } 308d9f0492fSopenharmony_ci} 309d9f0492fSopenharmony_ci 310d9f0492fSopenharmony_cistatic void DoTrigger(const char *ueventPath, int sockFd, char **devices, int num) 311d9f0492fSopenharmony_ci{ 312d9f0492fSopenharmony_ci if (ueventPath == NULL || ueventPath[0] == '\0') { 313d9f0492fSopenharmony_ci return; 314d9f0492fSopenharmony_ci } 315d9f0492fSopenharmony_ci 316d9f0492fSopenharmony_ci INIT_LOGV("------------------------\n" 317d9f0492fSopenharmony_ci "\nTry to trigger \" %s \" now ...", ueventPath); 318d9f0492fSopenharmony_ci int fd = open(ueventPath, O_WRONLY | O_CLOEXEC); 319d9f0492fSopenharmony_ci if (fd < 0) { 320d9f0492fSopenharmony_ci INIT_LOGE("Open \" %s \" failed, err = %d", ueventPath, errno); 321d9f0492fSopenharmony_ci return; 322d9f0492fSopenharmony_ci } 323d9f0492fSopenharmony_ci 324d9f0492fSopenharmony_ci ssize_t n = write(fd, "add\n", WRITE_SIZE); 325d9f0492fSopenharmony_ci close(fd); 326d9f0492fSopenharmony_ci if (n < 0) { 327d9f0492fSopenharmony_ci INIT_LOGE("Write \" %s \" failed, err = %d", ueventPath, errno); 328d9f0492fSopenharmony_ci return; 329d9f0492fSopenharmony_ci } 330d9f0492fSopenharmony_ci 331d9f0492fSopenharmony_ci // uevent triggered, now handle it. 332d9f0492fSopenharmony_ci if (sockFd >= 0) { 333d9f0492fSopenharmony_ci ProcessUevent(sockFd, devices, num); 334d9f0492fSopenharmony_ci } 335d9f0492fSopenharmony_ci} 336d9f0492fSopenharmony_ci 337d9f0492fSopenharmony_cistatic void Trigger(const char *path, int sockFd, char **devices, int num) 338d9f0492fSopenharmony_ci{ 339d9f0492fSopenharmony_ci if (path == NULL) { 340d9f0492fSopenharmony_ci return; 341d9f0492fSopenharmony_ci } 342d9f0492fSopenharmony_ci DIR *dir = opendir(path); 343d9f0492fSopenharmony_ci if (dir == NULL) { 344d9f0492fSopenharmony_ci return; 345d9f0492fSopenharmony_ci } 346d9f0492fSopenharmony_ci struct dirent *dirent = NULL; 347d9f0492fSopenharmony_ci while ((dirent = readdir(dir)) != NULL) { 348d9f0492fSopenharmony_ci if (dirent->d_name[0] == '.') { 349d9f0492fSopenharmony_ci continue; 350d9f0492fSopenharmony_ci } 351d9f0492fSopenharmony_ci if (dirent->d_type == DT_DIR) { 352d9f0492fSopenharmony_ci char pathBuffer[PATH_MAX]; 353d9f0492fSopenharmony_ci if (snprintf_s(pathBuffer, PATH_MAX, PATH_MAX - 1, "%s/%s", path, dirent->d_name) == -1) { 354d9f0492fSopenharmony_ci continue; 355d9f0492fSopenharmony_ci } 356d9f0492fSopenharmony_ci Trigger(pathBuffer, sockFd, devices, num); 357d9f0492fSopenharmony_ci } else { 358d9f0492fSopenharmony_ci if (strcmp(dirent->d_name, "uevent") != 0) { 359d9f0492fSopenharmony_ci continue; 360d9f0492fSopenharmony_ci } 361d9f0492fSopenharmony_ci char ueventBuffer[PATH_MAX]; 362d9f0492fSopenharmony_ci if (snprintf_s(ueventBuffer, PATH_MAX, PATH_MAX - 1, "%s/%s", path, "uevent") == -1) { 363d9f0492fSopenharmony_ci INIT_LOGW("Cannot build uevent path under %s", path); 364d9f0492fSopenharmony_ci continue; 365d9f0492fSopenharmony_ci } 366d9f0492fSopenharmony_ci DoTrigger(ueventBuffer, sockFd, devices, num); 367d9f0492fSopenharmony_ci } 368d9f0492fSopenharmony_ci } 369d9f0492fSopenharmony_ci closedir(dir); 370d9f0492fSopenharmony_ci} 371d9f0492fSopenharmony_ci 372d9f0492fSopenharmony_civoid RetriggerUeventByPath(int sockFd, char *path) 373d9f0492fSopenharmony_ci{ 374d9f0492fSopenharmony_ci Trigger(path, sockFd, NULL, 0); 375d9f0492fSopenharmony_ci} 376d9f0492fSopenharmony_ci 377d9f0492fSopenharmony_civoid RetriggerUevent(int sockFd, char **devices, int num) 378d9f0492fSopenharmony_ci{ 379d9f0492fSopenharmony_ci int ret = GetParameterFromCmdLine("default_boot_device", bootDevice, CMDLINE_VALUE_LEN_MAX); 380d9f0492fSopenharmony_ci INIT_CHECK_ONLY_ELOG(ret == 0, "Failed get default_boot_device value from cmdline"); 381d9f0492fSopenharmony_ci Trigger("/sys/block", sockFd, devices, num); 382d9f0492fSopenharmony_ci Trigger("/sys/class", sockFd, devices, num); 383d9f0492fSopenharmony_ci Trigger("/sys/devices", sockFd, devices, num); 384d9f0492fSopenharmony_ci} 385