mirror of
https://github.com/linux-msm/rmtfs.git
synced 2024-11-23 12:14:12 +08:00
rmtfs: Sync rmtfs server with rproc instance
Add sigterm/sigint handlers to enable graceful rmtfs server bringdown on first instance of SIGINT/SIGTERM. Start/Stop the remoteproc instance on RMTFS service up and SIGINT/SIGTERM respectively. Force quit on second instance of SIGINT/SIGTERM. Signed-off-by: Sibi Sankar <sibis@codeaurora.org> [bjorn: Pipe for event loop signaling, reworked /sys traversal] Signed-off-by: Bjorn Andersson <bjorn.andersson@linaro.org>
This commit is contained in:
parent
42edb9c07a
commit
976aa0ddbe
4
Makefile
4
Makefile
@ -1,10 +1,10 @@
|
||||
OUT := rmtfs
|
||||
|
||||
CFLAGS += -Wall -g -O2
|
||||
LDFLAGS += -lqrtr -ludev
|
||||
LDFLAGS += -lqrtr -ludev -lpthread
|
||||
prefix = /usr/local
|
||||
|
||||
SRCS := qmi_rmtfs.c rmtfs.c sharedmem.c storage.c util.c
|
||||
SRCS := qmi_rmtfs.c rmtfs.c rproc.c sharedmem.c storage.c util.c
|
||||
OBJS := $(SRCS:.c=.o)
|
||||
|
||||
$(OUT): $(OBJS)
|
||||
|
75
rmtfs.c
75
rmtfs.c
@ -2,14 +2,18 @@
|
||||
#include <sys/socket.h>
|
||||
#include <sys/types.h>
|
||||
#include <ctype.h>
|
||||
#include <dirent.h>
|
||||
#include <err.h>
|
||||
#include <errno.h>
|
||||
#include <fcntl.h>
|
||||
#include <libqrtr.h>
|
||||
#include <limits.h>
|
||||
#include <signal.h>
|
||||
#include <stdarg.h>
|
||||
#include <stdbool.h>
|
||||
#include <stdint.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
|
||||
@ -22,6 +26,7 @@
|
||||
#define RMTFS_QMI_INSTANCE 0
|
||||
|
||||
static struct rmtfs_mem *rmem;
|
||||
static sig_atomic_t sig_int_count;
|
||||
|
||||
static bool dbgprintf_enabled;
|
||||
static void dbgprintf(const char *fmt, ...)
|
||||
@ -410,9 +415,15 @@ static int handle_rmtfs(int sock)
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int run_rmtfs(void)
|
||||
static int sig_int_count;
|
||||
|
||||
static int run_rmtfs(int rprocfd)
|
||||
{
|
||||
bool sig_int_handled = false;
|
||||
int rmtfs_fd;
|
||||
fd_set rfds;
|
||||
char done;
|
||||
int nfds;
|
||||
int ret;
|
||||
|
||||
rmtfs_fd = qrtr_open(RMTFS_QMI_SERVICE);
|
||||
@ -430,16 +441,40 @@ static int run_rmtfs(void)
|
||||
return ret;
|
||||
}
|
||||
|
||||
if (rprocfd >= 0)
|
||||
rproc_start();
|
||||
|
||||
for (;;) {
|
||||
ret = qrtr_poll(rmtfs_fd, -1);
|
||||
if (rprocfd >= 0 && sig_int_count == 1 && !sig_int_handled) {
|
||||
rproc_stop();
|
||||
sig_int_handled = true;
|
||||
} else if (sig_int_count > 1) {
|
||||
break;
|
||||
}
|
||||
|
||||
FD_ZERO(&rfds);
|
||||
FD_SET(rmtfs_fd, &rfds);
|
||||
if (rprocfd >= 0)
|
||||
FD_SET(rprocfd, &rfds);
|
||||
nfds = MAX(rmtfs_fd, rprocfd) + 1;
|
||||
|
||||
ret = select(nfds, &rfds, NULL, NULL, NULL);
|
||||
if (ret < 0 && errno != EINTR)
|
||||
break;
|
||||
else if (ret < 0 && errno == EINTR)
|
||||
continue;
|
||||
|
||||
ret = handle_rmtfs(rmtfs_fd);
|
||||
if (ret == -ENETRESET)
|
||||
break;
|
||||
if (rprocfd >= 0 && FD_ISSET(rprocfd, &rfds)) {
|
||||
ret = read(rprocfd, &done, 1);
|
||||
if (!ret || done == 'Y')
|
||||
break;
|
||||
}
|
||||
|
||||
if (FD_ISSET(rmtfs_fd, &rfds)) {
|
||||
ret = handle_rmtfs(rmtfs_fd);
|
||||
if (ret == -ENETRESET)
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
close(rmtfs_fd);
|
||||
@ -447,15 +482,22 @@ static int run_rmtfs(void)
|
||||
return ret;
|
||||
}
|
||||
|
||||
static void sig_int_handler(int signo)
|
||||
{
|
||||
sig_int_count++;
|
||||
}
|
||||
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
struct sigaction action;
|
||||
bool use_partitions = false;
|
||||
bool read_only = false;
|
||||
int rprocfd = -1;
|
||||
int ret;
|
||||
int option;
|
||||
const char *storage_root = NULL;
|
||||
|
||||
while ((option = getopt(argc, argv, "o:Prv")) != -1) {
|
||||
while ((option = getopt(argc, argv, "o:Prsv")) != -1) {
|
||||
switch (option) {
|
||||
/* -o sets the directory where EFS images are stored. */
|
||||
case 'o':
|
||||
@ -472,6 +514,11 @@ int main(int argc, char **argv)
|
||||
read_only = true;
|
||||
break;
|
||||
|
||||
/* enable sync for the mss rproc instance */
|
||||
case 's':
|
||||
rprocfd = rproc_init();
|
||||
break;
|
||||
|
||||
/* -v is for verbose */
|
||||
case 'v':
|
||||
dbgprintf_enabled = 1;
|
||||
@ -483,6 +530,13 @@ int main(int argc, char **argv)
|
||||
}
|
||||
}
|
||||
|
||||
sigemptyset(&action.sa_mask);
|
||||
action.sa_handler = sig_int_handler;
|
||||
action.sa_flags = 0;
|
||||
|
||||
sigaction(SIGINT, &action, NULL);
|
||||
sigaction(SIGTERM, &action, NULL);
|
||||
|
||||
rmem = rmtfs_mem_open();
|
||||
if (!rmem)
|
||||
return 1;
|
||||
@ -493,15 +547,8 @@ int main(int argc, char **argv)
|
||||
goto close_rmtfs_mem;
|
||||
}
|
||||
|
||||
for (;;) {
|
||||
ret = run_rmtfs();
|
||||
|
||||
if (ret <= 0 && ret != -ENETRESET)
|
||||
break;
|
||||
}
|
||||
|
||||
do {
|
||||
ret = run_rmtfs();
|
||||
ret = run_rmtfs(rprocfd);
|
||||
} while (ret == -ENETRESET);
|
||||
|
||||
storage_exit();
|
||||
|
4
rmtfs.h
4
rmtfs.h
@ -35,4 +35,8 @@ void storage_exit(void);
|
||||
ssize_t storage_pread(const struct rmtfd *rmtfd, void *buf, size_t nbyte, off_t offset);
|
||||
ssize_t storage_pwrite(struct rmtfd *rmtfd, const void *buf, size_t nbyte, off_t offset);
|
||||
|
||||
int rproc_init(void);
|
||||
int rproc_start(void);
|
||||
int rproc_stop(void);
|
||||
|
||||
#endif
|
||||
|
137
rproc.c
Normal file
137
rproc.c
Normal file
@ -0,0 +1,137 @@
|
||||
#include <sys/syscall.h>
|
||||
#include <sys/types.h>
|
||||
#include <dirent.h>
|
||||
#include <errno.h>
|
||||
#include <fcntl.h>
|
||||
#include <stdint.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <pthread.h>
|
||||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#include "rmtfs.h"
|
||||
|
||||
#define RPROC_BASE_PATH "/sys/bus/platform/drivers/qcom-q6v5-mss/"
|
||||
|
||||
static pthread_t start_thread;
|
||||
static pthread_t stop_thread;
|
||||
static int rproc_state_fd;
|
||||
static int rproc_pipe[2];
|
||||
|
||||
int rproc_init(void)
|
||||
{
|
||||
struct dirent *device_de;
|
||||
struct dirent *rproc_de;
|
||||
int rproc_base_fd;
|
||||
DIR *rproc_dir;
|
||||
DIR *base_dir;
|
||||
int device_fd;
|
||||
int rproc_fd;
|
||||
int base_fd;
|
||||
int ret;
|
||||
|
||||
rproc_state_fd = -1;
|
||||
|
||||
base_fd = open(RPROC_BASE_PATH, O_RDONLY | O_DIRECTORY);
|
||||
if (base_fd < 0)
|
||||
return -1;
|
||||
|
||||
base_dir = fdopendir(base_fd);
|
||||
if (!base_dir) {
|
||||
fprintf(stderr, "failed to open mss driver path\n");
|
||||
close(base_fd);
|
||||
return -1;
|
||||
}
|
||||
|
||||
while (rproc_state_fd < 0 && (device_de = readdir(base_dir)) != NULL) {
|
||||
if (!strcmp(device_de->d_name, ".") ||
|
||||
!strcmp(device_de->d_name, ".."))
|
||||
continue;
|
||||
|
||||
device_fd = openat(base_fd, device_de->d_name, O_RDONLY | O_DIRECTORY);
|
||||
if (device_fd < 0)
|
||||
continue;
|
||||
|
||||
rproc_base_fd = openat(device_fd, "remoteproc", O_RDONLY | O_DIRECTORY);
|
||||
if (rproc_base_fd < 0) {
|
||||
close(device_fd);
|
||||
continue;
|
||||
}
|
||||
|
||||
rproc_dir = fdopendir(rproc_base_fd);
|
||||
while (rproc_state_fd < 0 && (rproc_de = readdir(rproc_dir)) != NULL) {
|
||||
if (!strcmp(rproc_de->d_name, ".") ||
|
||||
!strcmp(rproc_de->d_name, ".."))
|
||||
continue;
|
||||
|
||||
rproc_fd = openat(rproc_base_fd, rproc_de->d_name, O_RDONLY | O_DIRECTORY);
|
||||
if (rproc_fd < 0)
|
||||
continue;
|
||||
|
||||
rproc_state_fd = openat(rproc_fd, "state", O_WRONLY);
|
||||
if (rproc_state_fd < 0) {
|
||||
fprintf(stderr,
|
||||
"unable to open remoteproc \"state\" control file of %s\n",
|
||||
device_de->d_name);
|
||||
}
|
||||
|
||||
close(rproc_fd);
|
||||
|
||||
}
|
||||
closedir(rproc_dir);
|
||||
close(rproc_base_fd);
|
||||
close(device_fd);
|
||||
}
|
||||
closedir(base_dir);
|
||||
close(base_fd);
|
||||
|
||||
if (rproc_state_fd < 0)
|
||||
return -1;
|
||||
|
||||
ret = pipe(rproc_pipe);
|
||||
if (ret < 0) {
|
||||
close(rproc_state_fd);
|
||||
return -1;
|
||||
}
|
||||
|
||||
return rproc_pipe[0];
|
||||
}
|
||||
|
||||
static void *do_rproc_start(void *unused)
|
||||
{
|
||||
ssize_t ret;
|
||||
|
||||
ret = pwrite(rproc_state_fd, "start", 5, 0);
|
||||
if (ret < 4)
|
||||
fprintf(stderr, "failed to update start state\n");
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
int rproc_start()
|
||||
{
|
||||
return pthread_create(&start_thread, NULL, do_rproc_start, NULL);
|
||||
}
|
||||
|
||||
static void *do_rproc_stop(void *unused)
|
||||
{
|
||||
ssize_t ret;
|
||||
|
||||
ret = pwrite(rproc_state_fd, "stop", 4, 0);
|
||||
if (ret < 4)
|
||||
fprintf(stderr, "failed to update stop state\n");
|
||||
|
||||
ret = write(rproc_pipe[1], "Y", 1);
|
||||
if (ret != 1) {
|
||||
fprintf(stderr, "failed to signal event loop about exit\n");
|
||||
exit(0);
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
int rproc_stop(void)
|
||||
{
|
||||
return pthread_create(&stop_thread, NULL, do_rproc_stop, NULL);
|
||||
}
|
Loading…
Reference in New Issue
Block a user