提交 51379f94 编写于 作者: H handyohos

Feat: Add commands for ueventd

1) add trigger and listening mode for ueventd
2) add get log level api
3) add string array api
Signed-off-by: Nhandyohos <zhangxiaotian@huawei.com>

#I7KQM1
上级 9982c26e
......@@ -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
......@@ -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
}
......
......@@ -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;
}
......@@ -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;
}
......@@ -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);
}
}
......
......@@ -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);
}
......
......@@ -15,6 +15,7 @@
#include <limits.h>
#include <poll.h>
#include <unistd.h>
#include <stdbool.h>
#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;
}
......@@ -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}
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册