frameworks/kvdb: add remote server support

N/A

Enable rpmsg socket support for AMP use case

Signed-off-by: Peter Bee <bijunda1@xiaomi.com>
This commit is contained in:
Peter Bee 2021-03-03 20:50:16 +08:00 committed by openvela-robot
parent 3ce85f5126
commit 97df2e7fd1
5 changed files with 129 additions and 54 deletions

19
Kconfig
View File

@ -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

View File

@ -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}

View File

@ -25,6 +25,7 @@
#include <sys/socket.h>
#include <sys/un.h>
#include <sys/time.h>
#include <netpacket/rpmsg.h>
#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;

2
kvdb.h
View File

@ -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"

124
server.c
View File

@ -23,6 +23,7 @@
#include <sys/socket.h>
#include <sys/un.h>
#include <sys/time.h>
#include <netpacket/rpmsg.h>
#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;
}