diff --git a/Kconfig b/Kconfig index 05f36a3..36d9d38 100644 --- a/Kconfig +++ b/Kconfig @@ -29,14 +29,25 @@ config KVDB_STACKSIZE int "stack size" default DEFAULT_TASK_STACKSIZE -config KVDB_COMMIT_INTERVAL - int "commit time interval(sec)" - default 5 +config KVDB_REMOTE_SERVER + bool "KVDB server is on another CPU" + default n + +config KVDB_RPMSG_SERVER_NAME + string "which cpu kvdb server runs on" + depends on KVDB_REMOTE_SERVER + default "ap" config KVDB_TIMEOUT_INTERVAL int "transaction timeout interval(sec)" default 0 +if !KVDB_REMOTE_SERVER + +config KVDB_COMMIT_INTERVAL + int "commit time interval(sec)" + default 5 + config KVDB_PERSIST_PATH string "persistent database path" default "/data/persist.db" @@ -45,4 +56,6 @@ config KVDB_SOURCE_PATH string "database default value source path" default "/etc/build.prop" +endif # !KVDB_REMOTE_SERVER + endif # KVDB diff --git a/Makefile b/Makefile index f6d4bb1..5d438a4 100644 --- a/Makefile +++ b/Makefile @@ -17,8 +17,13 @@ include $(APPDIR)/Make.defs CSRCS = client.c -MAINSRC = server.c setprop.c getprop.c -PROGNAME = kvdbd setprop getprop +MAINSRC = setprop.c getprop.c +PROGNAME = setprop getprop + +ifeq ($(CONFIG_KVDB_REMOTE_SERVER),) +MAINSRC += server.c +PROGNAME += kvdbd +endif CFLAGS += ${shell $(INCDIR) $(INCDIROPT) "$(CC)" $(APPDIR)/external/unqlite} diff --git a/client.c b/client.c index 5022892..86fad0d 100644 --- a/client.c +++ b/client.c @@ -25,6 +25,7 @@ #include #include #include +#include #include "kvdb.h" @@ -49,7 +50,11 @@ static int property_connect(void) { +#ifdef CONFIG_KVDB_REMOTE_SERVER + int fd = socket(AF_RPMSG, SOCK_STREAM, 0); +#else int fd = socket(AF_UNIX, SOCK_STREAM, 0); +#endif if (fd < 0) return -errno; @@ -62,11 +67,20 @@ static int property_connect(void) setsockopt(fd, SOL_SOCKET, SO_RCVTIMEO, &timeout, sizeof(timeout)); #endif - struct sockaddr_un addr; - addr.sun_family = AF_UNIX; - strcpy(addr.sun_path, PROP_SERVER_PATH); +#ifdef CONFIG_KVDB_REMOTE_SERVER + struct sockaddr_rpmsg addr = { + .rp_family = AF_RPMSG, + .rp_name = PROP_SERVER_PATH, + .rp_cpu = CONFIG_KVDB_RPMSG_SERVER_NAME, + }; +#else + struct sockaddr_un addr = { + .sun_family = AF_UNIX, + .sun_path = PROP_SERVER_PATH, + }; +#endif - int ret = connect(fd, (struct sockaddr*)&addr, sizeof(addr)); + int ret = connect(fd, (const struct sockaddr*)&addr, sizeof(addr)); if (ret < 0) { ret = -errno; close(fd); @@ -351,8 +365,8 @@ int property_list(property_callback propfn, void* cookie) *-------------------------------------*/ char msg[PROP_MSG_MAX]; - ret = recv(fd, msg, PROP_MSG_MAX, 0); - if (ret < 4) { + ret = recv(fd, msg, 2, 0); + if (ret < 2) { if (!--ret && !msg[0]) break; /* end the list */ ret = ret < -1 ? -errno : -EINVAL; @@ -367,7 +381,8 @@ int property_list(property_callback propfn, void* cookie) if (--val_len >= PROP_VALUE_MAX) continue; - if (ret != 4 + key_len + val_len) + ret = recv(fd, msg + 2, msg[0] + msg[1], 0); + if (ret != msg[0] + msg[1]) continue; const char* key = msg + 2; diff --git a/kvdb.h b/kvdb.h index cd6b9de..e651ba5 100644 --- a/kvdb.h +++ b/kvdb.h @@ -22,7 +22,7 @@ #define PROP_KEY_MAX 100 #define PROP_VALUE_MAX 100 #define PROP_MSG_MAX (3 + PROP_KEY_MAX + PROP_VALUE_MAX) /* +3 = +1(opcode) +2(len) */ -#define PROP_SERVER_PATH "/kvdbd" +#define PROP_SERVER_PATH "kvdbd" #if defined(__cplusplus) extern "C" diff --git a/server.c b/server.c index fd30dc8..41ba612 100644 --- a/server.c +++ b/server.c @@ -23,6 +23,7 @@ #include #include #include +#include #include "kvdb.h" #include "unqlite.h" @@ -31,6 +32,10 @@ #define KVDB_PERSIST 1 #define KVDB_COUNT 2 +#define KVFD_LOCAL 0 +#define KVFD_REMOTE 1 +#define KVFD_COUNT 2 + /**************************************************************************** * Database Types ****************************************************************************/ @@ -301,33 +306,58 @@ typedef struct kvdb_list_data { * Network Functions ****************************************************************************/ -static int kvdb_bind(void) +static int kvdb_bind(int fd[]) { - int fd = socket(AF_UNIX, SOCK_STREAM, 0); - if (fd < 0) - return -errno; + const int family[] = { + [KVFD_LOCAL] = AF_UNIX, + [KVFD_REMOTE] = AF_RPMSG, + }; - struct sockaddr_un addr; - addr.sun_family = AF_UNIX; - strcpy(addr.sun_path, PROP_SERVER_PATH); + const struct sockaddr_un addr0 = { + .sun_family = AF_UNIX, + .sun_path = PROP_SERVER_PATH, + }; - int ret = bind(fd, (struct sockaddr*)&addr, sizeof(addr)); - if (ret < 0) { - ret = -errno; - goto out; + const struct sockaddr_rpmsg addr1 = { + .rp_family = AF_RPMSG, + .rp_cpu = "", + .rp_name = PROP_SERVER_PATH, + }; + + const struct sockaddr* addr[] = { + [KVFD_LOCAL] = (const struct sockaddr*)&addr0, + [KVFD_REMOTE] = (const struct sockaddr*)&addr1, + }; + + const socklen_t addrlen[] = { + [KVFD_LOCAL] = sizeof(struct sockaddr_un), + [KVFD_REMOTE] = sizeof(struct sockaddr_rpmsg), + }; + + memset(fd, 0, sizeof(int) * KVFD_COUNT); + + for (int i = 0; i < KVFD_COUNT; i++) { + fd[i] = socket(family[i], SOCK_STREAM, 0); + if (fd[i] < 0) + continue; + + int ret = bind(fd[i], addr[i], addrlen[i]); + if (ret < 0) + return ret; + + ret = listen(fd[i], SOMAXCONN); + if (ret < 0) + return ret; } - ret = listen(fd, SOMAXCONN); - if (ret < 0) { - ret = -errno; - goto out; - } + return 0; +} - return fd; - -out: - close(fd); - return ret; +static void kvdb_unbind(int fd[]) +{ + for (int i = 0; i < KVFD_COUNT; i++) + if (fd[i] > 0) + close(fd[i]); } static int kvdb_list_consume(const char* key, size_t key_len, @@ -441,12 +471,18 @@ out: return dirty; } -static void kvdb_server(int fd, unqlite* db[]) +static void kvdb_server(int fd[], unqlite* db[]) { - struct pollfd pfd = { - .fd = fd, - .events = POLLIN, - }; + struct pollfd pfd[KVFD_COUNT]; + int pfd_count = 0; + for (int i = 0; i < KVFD_COUNT; i++) { + if (fd[i] > 0) { + pfd[pfd_count].fd = fd[i]; + pfd[pfd_count].events = POLLIN; + pfd_count++; + } + } + time_t next = 0; while (1) { @@ -463,18 +499,23 @@ static void kvdb_server(int fd, unqlite* db[]) timeout *= 1000; } - if (poll(&pfd, 1, timeout) <= 0) - continue; + int nfds = poll(pfd, pfd_count, timeout); - int newfd = accept(fd, NULL, NULL); - if (newfd < 0) - continue; + for (int i = 0; nfds > 0; i++) { + if ((pfd[i].revents & POLLIN) == 0) + continue; - /* is database changed? */ - if (kvdb_client(newfd, db) && next == 0) { - next = time(NULL) + CONFIG_KVDB_COMMIT_INTERVAL; - if (next == 0) - next++; /* ensure no zero */ + nfds--; + int newfd = accept(pfd[i].fd, NULL, NULL); + if (newfd < 0) + continue; + + /* is database changed? */ + if (kvdb_client(newfd, db) && next == 0) { + next = time(NULL) + CONFIG_KVDB_COMMIT_INTERVAL; + if (next == 0) + next++; /* ensure no zero */ + } } } } @@ -494,12 +535,13 @@ static void kvdb_server(int fd, unqlite* db[]) int main(int argc, char* argv[]) { - int fd = kvdb_bind(); - if (fd < 0) - return -fd; + int fd[KVFD_COUNT]; + int ret = kvdb_bind(fd); + if (ret < 0) + goto out; unqlite* db[KVDB_COUNT]; - int ret = kvdb_init(db); + ret = kvdb_init(db); if (ret < 0) goto out; @@ -507,6 +549,6 @@ int main(int argc, char* argv[]) kvdb_uninit(db); out: - close(fd); + kvdb_unbind(fd); return -ret; }