diff --git a/interfaces/innerkits/include/beget_ext.h b/interfaces/innerkits/include/beget_ext.h index c64b572cdd26a67b046fed9ddb16d38f35e4ed4f..df483c58a1b2f55f9409dcc204c0af69cd29980b 100644 --- a/interfaces/innerkits/include/beget_ext.h +++ b/interfaces/innerkits/include/beget_ext.h @@ -59,6 +59,7 @@ typedef enum InitLogLevel { INIT_PUBLIC_API void StartupLog(InitLogLevel logLevel, uint32_t domain, const char *tag, const char *fmt, ...); INIT_PUBLIC_API void SetInitLogLevel(InitLogLevel level); +INIT_PUBLIC_API InitLogLevel GetInitLogLevel(void); #if defined(INIT_NO_LOG) #define STARTUP_LOGV(domain, tag, fmt, ...) @@ -154,4 +155,4 @@ INIT_PUBLIC_API void SetInitLogLevel(InitLogLevel level); } #endif #endif -#endif \ No newline at end of file +#endif diff --git a/services/include/init_utils.h b/services/include/init_utils.h index 545b390c46afcf69a752e987891fbeb2fc01f0fe..f07901ac1acdcc5116f590d6ce8d1a9afef8b847 100644 --- a/services/include/init_utils.h +++ b/services/include/init_utils.h @@ -99,6 +99,19 @@ void RedirectStdio(int fd); int GetServiceGroupIdByPid(pid_t pid, gid_t *gids, uint32_t gidSize); int GetParameterFromCmdLine(const char *paramName, char *value, size_t valueLen); + +/** + * @brief Get string index from a string array + * + * @param strArray string array + * Attension: last item in the array must be NULL, for example: + * const char *strArray[] = { "val1", "val2", NULL } + * @param target string to be matched + * @param ignoreCase 0 means exact match, others mean ignore case + * @return return 0 if succeed; other values if failed. + */ +int StrArrayGetIndex(const char *strArray[], const char *target, int ignoreCase); + #ifdef __cplusplus #if __cplusplus } diff --git a/services/log/init_log.c b/services/log/init_log.c index 2e7198f844037720db0a9fdfc64c7280429b4549..b45c6341d59f9e88fd48d8cfe444be95d927ee48 100644 --- a/services/log/init_log.c +++ b/services/log/init_log.c @@ -143,4 +143,9 @@ INIT_LOCAL_API void EnableInitLog(InitLogLevel level) { g_logLevel = level; SetInitCommLog(InitLog); -} \ No newline at end of file +} + +INIT_PUBLIC_API InitLogLevel GetInitLogLevel() +{ + return g_logLevel; +} diff --git a/services/utils/init_utils.c b/services/utils/init_utils.c index 7d05fda07c0b73aaee529d0397855c195fbefeff..97bf1ffd8e7324ed920c027dbb168431b1e4edb5 100644 --- a/services/utils/init_utils.c +++ b/services/utils/init_utils.c @@ -696,3 +696,28 @@ uint32_t IntervalTime(struct timespec *startTime, struct timespec *endTime) } return diff; } + +int StrArrayGetIndex(const char *strArray[], const char *target, int ignoreCase) +{ + int i; + + if ((target == NULL) || (target[0] == '\0')) { + return -1; + } + + if (ignoreCase) { + for (i = 0; strArray[i] != NULL; i++) { + if (strcasecmp(strArray[i], target) == 0) { + return i; + } + } + return -1; + } + + for (i = 0; strArray[i] != NULL; i++) { + if (strcmp(strArray[i], target) == 0) { + return i; + } + } + return -1; +} diff --git a/ueventd/ueventd.c b/ueventd/ueventd.c old mode 100755 new mode 100644 index 3701b5c752a885c2e69d75e741e3dad63b7c3577..ee12eacc01077c8b59cd965d0ffd1ed4662ed73d --- a/ueventd/ueventd.c +++ b/ueventd/ueventd.c @@ -245,7 +245,23 @@ static void AddUevent(struct Uevent *uevent, const char *event, size_t len) } else if (STARTSWITH(event, "DEVNUM=")) { uevent->devNum = StringToInt(event + strlen("DEVNUM="), -1); } + // Ignore other events + INIT_LOGV("got uevent message:\n" + "subsystem: %s\n" + "parition: %s:%d\n" + "action: %s\n" + "devpath: %s\n" + "devname: %s\n" + "devnode: %d:%d\n" + "id: %d:%d", + uevent->subsystem, + uevent->partitionName, uevent->partitionNum, + uevent->action, + uevent->syspath, + uevent->deviceName, + uevent->major, uevent->minor, + uevent->ug.uid, uevent->ug.gid); } void ParseUeventMessage(const char *buffer, ssize_t length, struct Uevent *uevent) @@ -299,21 +315,24 @@ static void DoTrigger(const char *ueventPath, int sockFd, char **devices, int nu return; } + INIT_LOGI("------------------------\n" + "\nTry to trigger \" %s \" now ...", ueventPath); int fd = open(ueventPath, O_WRONLY | O_CLOEXEC); if (fd < 0) { INIT_LOGE("Open \" %s \" failed, err = %d", ueventPath, errno); - } else { - ssize_t n = write(fd, "add\n", WRITE_SIZE); - if (n < 0) { - INIT_LOGE("Write \" %s \" failed, err = %d", ueventPath, errno); - close(fd); - } else { - close(fd); - // uevent triggered, now handle it. - if (sockFd >= 0) { - ProcessUevent(sockFd, devices, num); - } - } + return; + } + + ssize_t n = write(fd, "add\n", WRITE_SIZE); + close(fd); + if (n < 0) { + INIT_LOGE("Write \" %s \" failed, err = %d", ueventPath, errno); + return; + } + + // uevent triggered, now handle it. + if (sockFd >= 0) { + ProcessUevent(sockFd, devices, num); } } diff --git a/ueventd/ueventd_device_handler.c b/ueventd/ueventd_device_handler.c old mode 100755 new mode 100644 index 40e87c501eaec16e51a847336e9c028dec535ccf..843d181fd6cc2eef02d8917a3dda38c702ad6020 --- a/ueventd/ueventd_device_handler.c +++ b/ueventd/ueventd_device_handler.c @@ -81,6 +81,7 @@ static void CreateSymbolLinks(const char *deviceNode, char **symLinks) } errno = 0; + INIT_LOGI("symlink %s->%s", deviceNode, linkName); int rc = symlink(deviceNode, linkName); if (rc != 0) { if (errno != EEXIST) { @@ -199,10 +200,12 @@ static int RemoveDeviceNode(const char *deviceNode, char **symLinks) continue; } if (STRINGEQUAL(deviceNode, realPath)) { + INIT_LOGI("unlink %s->%s", linkName); unlink(linkName); } } } + INIT_LOGI("unlink %s->%s", deviceNode); return unlink(deviceNode); } diff --git a/ueventd/ueventd_main.c b/ueventd/ueventd_main.c index e9ee5ab351be97f7c1d3734cee9dc378ec202d65..4c1ee37ab80796c61b89063233b90c0fb1c9d1ca 100644 --- a/ueventd/ueventd_main.c +++ b/ueventd/ueventd_main.c @@ -15,6 +15,7 @@ #include #include +#include #include #include "ueventd.h" #include "ueventd_read_cfg.h" @@ -47,11 +48,27 @@ static void PollUeventdSocketTimeout(int ueventSockFd, bool ondemand) } } -int main(int argc, char **argv) +static int UeventdRetrigger(void) +{ + const char *ueventdConfigs[] = {"/etc/ueventd.config", "/vendor/etc/ueventd.config", NULL}; + int i = 0; + while (ueventdConfigs[i] != NULL) { + ParseUeventdConfigFile(ueventdConfigs[i++]); + } + int ueventSockFd = UeventdSocketInit(); + if (ueventSockFd < 0) { + INIT_LOGE("Failed to create uevent socket!"); + return -1; + } + RetriggerUevent(ueventSockFd, NULL, 0); // Not require boot devices + return 0; +} + +static int UeventdDaemon(int listen_only) { // start log EnableInitLog(INIT_INFO); - char *ueventdConfigs[] = {"/etc/ueventd.config", "/vendor/etc/ueventd.config", NULL}; + const char *ueventdConfigs[] = {"/etc/ueventd.config", "/vendor/etc/ueventd.config", NULL}; int i = 0; while (ueventdConfigs[i] != NULL) { ParseUeventdConfigFile(ueventdConfigs[i++]); @@ -67,7 +84,7 @@ int main(int argc, char **argv) INIT_LOGE("Failed to create uevent socket!"); return -1; } - if (access(UEVENTD_FLAG, F_OK)) { + if (!listen_only && access(UEVENTD_FLAG, F_OK)) { INIT_LOGI("Ueventd started, trigger uevent"); RetriggerUevent(ueventSockFd, NULL, 0); // Not require boot devices int fd = open(UEVENTD_FLAG, O_RDWR | O_CREAT, S_IRUSR | S_IWUSR); @@ -84,3 +101,105 @@ int main(int argc, char **argv) CloseUeventConfig(); return 0; } + +static int UeventdEarlyBoot(void) +{ + int ueventSockFd = UeventdSocketInit(); + if (ueventSockFd < 0) { + return -1; + } + + char *devices[] = { + "/dev/block/vdb", + "/dev/block/vdc" + }; + + RetriggerUevent(ueventSockFd, devices, 2); + close(ueventSockFd); + return 0; +} + +#define UEVENTD_MODE_DEAMON 0 +#define UEVENTD_MODE_EARLY_BOOT 1 +#define UEVENTD_MODE_RETRIGGER 2 +#define UEVENTD_MODE_LISTEN 3 + +static void usage(const char *name) +{ + printf("Usage: %s [OPTION]\n" + "Listening kernel uevent to create device node.\n" + "It will read configs from {/,/system,/chipset}/etc/ueventd.config.\n\n" + "The options may be used to set listening mode.\n" + " -d, --daemon working in deamon mode(default mode)\n" + " -b, --boot working in early booting mode, create required device nodes\n" + " -l, --listen listen in verbose mode\n" + " -r, --retrigger retrigger all uevents\n" + " -v, --verbose log level\n" + " -h, --help print this help info\n", name); +} + +static void UeventdLogPrint(int logLevel, uint32_t domain, const char *tag, const char *fmt, va_list vargs) +{ + if (logLevel < GetInitLogLevel()) { + return; + } + vprintf(fmt, vargs); + printf("\n"); +} + +int main(int argc, char *argv[]) +{ + int opt; + const char *config; + int daemon = UEVENTD_MODE_DEAMON; + + while ((opt = getopt(argc, argv, "drblv:h")) != -1) { + switch (opt) { + case 'd': + daemon = UEVENTD_MODE_DEAMON; + break; + case 'r': + SetInitCommLog(UeventdLogPrint); + daemon = UEVENTD_MODE_RETRIGGER; + break; + case 'b': + SetInitCommLog(UeventdLogPrint); + daemon = UEVENTD_MODE_EARLY_BOOT; + break; + case 'v': + EnableInitLog(atoi(optarg)); + SetInitCommLog(UeventdLogPrint); + break; + case 'l': + EnableInitLog(0); + SetInitCommLog(UeventdLogPrint); + daemon = UEVENTD_MODE_LISTEN; + break; + case 'h': + usage(argv[0]); + exit(0); + break; + default: /* '?' */ + fprintf(stderr, "Usage: %s [-t nsecs] [-n] name\n", + argv[0]); + exit(EXIT_FAILURE); + } + } + + config = NULL; + if (optind >= argc) { + config = argv[optind]; + } + + if (daemon == UEVENTD_MODE_DEAMON) { + return UeventdDaemon(0); + } else if (daemon == UEVENTD_MODE_RETRIGGER) { + return UeventdRetrigger(); + } else if (daemon == UEVENTD_MODE_RETRIGGER) { + return UeventdDaemon(1); + } else { + UeventdEarlyBoot(); + } + + return 0; +} diff --git a/ueventd/ueventd_read_cfg.c b/ueventd/ueventd_read_cfg.c index 394eb2f26aa83c0d4d0fe08335a485b0c5ad4757..f5106ad49e042f510937add3e2eae069da5d213e 100644 --- a/ueventd/ueventd_read_cfg.c +++ b/ueventd/ueventd_read_cfg.c @@ -42,7 +42,7 @@ typedef enum SECTION { typedef int (*ParseConfigFunc)(char *); typedef struct FunctionMapper { - char *name; + const char *name; ParseConfigFunc func; } FUNCTIONMAPPER; @@ -166,7 +166,7 @@ static SECTION GetSection(const char *section) } } -static FUNCTIONMAPPER funcMapper[3] = { +static const FUNCTIONMAPPER funcMapper[3] = { {"device", ParseDeviceConfig}, {"sysfs", ParseSysfsConfig}, {"firmware", ParseFirmwareConfig}