diff options
author | Felix Fietkau <nbd@openwrt.org> | 2011-10-15 19:06:28 +0200 |
---|---|---|
committer | Felix Fietkau <nbd@openwrt.org> | 2011-10-15 19:06:28 +0200 |
commit | 6b3f6f4466e5584f2bdefc55b3ca34186b65acb9 (patch) | |
tree | e604a886feccbd1a6017035470b8c0749b98050b | |
parent | 8c4dface377cf03de38c642b90940530e47296d3 (diff) |
add support for tracking open file descriptors of modules and closing them for created child processes
-rw-r--r-- | main.c | 23 | ||||
-rw-r--r-- | netifd.h | 9 | ||||
-rw-r--r-- | proto-shell.c | 13 | ||||
-rw-r--r-- | ubus.c | 3 |
4 files changed, 42 insertions, 6 deletions
@@ -14,7 +14,9 @@ unsigned int debug_mask = 0; const char *main_path = DEFAULT_MAIN_PATH; const char *resolv_conf = DEFAULT_RESOLV_CONF; static char **global_argv; + static struct list_head process_list = LIST_HEAD_INIT(process_list); +static struct list_head fds = LIST_HEAD_INIT(fds); static void netifd_process_cb(struct uloop_process *proc, int ret) @@ -28,6 +30,7 @@ netifd_process_cb(struct uloop_process *proc, int ret) int netifd_start_process(const char **argv, char **env, struct netifd_process *proc) { + struct netifd_fd *fd; int pid; netifd_kill_process(proc); @@ -44,6 +47,14 @@ netifd_start_process(const char **argv, char **env, struct netifd_process *proc) } if (proc->dir_fd >= 0) fchdir(proc->dir_fd); + + /* close all non-essential fds */ + list_for_each_entry(fd, &fds, list) { + if (fd->proc == proc) + continue; + close(fd->fd); + } + execvp(argv[0], (char **) argv); exit(127); } @@ -70,6 +81,18 @@ netifd_kill_process(struct netifd_process *proc) list_del(&proc->list); } +void +netifd_fd_add(struct netifd_fd *fd) +{ + list_add_tail(&fd->list, &fds); +} + +void +netifd_fd_delete(struct netifd_fd *fd) +{ + list_del(&fd->list); +} + static void netifd_do_restart(struct uloop_timeout *timeout) { execvp(global_argv[0], global_argv); @@ -48,6 +48,12 @@ static inline void no_debug(int level, const char *fmt, ...) { } +struct netifd_fd { + struct list_head list; + struct netifd_process *proc; + int fd; +}; + struct netifd_process { struct list_head list; struct uloop_process uloop; @@ -58,6 +64,9 @@ struct netifd_process { int netifd_start_process(const char **argv, char **env, struct netifd_process *proc); void netifd_kill_process(struct netifd_process *proc); +void netifd_fd_add(struct netifd_fd *fd); +void netifd_fd_delete(struct netifd_fd *fd); + struct device; struct interface; diff --git a/proto-shell.c b/proto-shell.c index d0028c4..c0af99f 100644 --- a/proto-shell.c +++ b/proto-shell.c @@ -18,7 +18,7 @@ #include "interface-ip.h" #include "proto.h" -static int proto_fd; +static struct netifd_fd proto_fd; struct proto_shell_handler { struct list_head list; @@ -469,11 +469,11 @@ proto_shell_attach(const struct proto_handler *h, struct interface *iface, state->proto.cb = proto_shell_handler; state->setup_timeout.cb = proto_shell_setup_timeout_cb; state->setup_task.cb = proto_shell_setup_cb; - state->setup_task.dir_fd = proto_fd; + state->setup_task.dir_fd = proto_fd.fd; state->teardown_task.cb = proto_shell_teardown_cb; - state->teardown_task.dir_fd = proto_fd; + state->teardown_task.dir_fd = proto_fd.fd; state->proto_task.cb = proto_shell_task_cb; - state->proto_task.dir_fd = proto_fd; + state->proto_task.dir_fd = proto_fd.fd; state->handler = container_of(h, struct proto_shell_handler, proto); return &state->proto; @@ -676,10 +676,11 @@ void __init proto_shell_init(void) if (chdir("./proto")) goto close_cur; - proto_fd = open(".", O_RDONLY | O_DIRECTORY); - if (proto_fd < 0) + proto_fd.fd = open(".", O_RDONLY | O_DIRECTORY); + if (proto_fd.fd < 0) goto close_cur; + netifd_fd_add(&proto_fd); glob("./*.sh", 0, NULL, &g); for (i = 0; i < g.gl_pathc; i++) proto_shell_add_script(g.gl_pathv[i]); @@ -11,6 +11,7 @@ static struct ubus_context *ctx = NULL; static struct blob_buf b; +static struct netifd_fd ubus_fd; /* global object */ @@ -105,6 +106,8 @@ netifd_ubus_init(const char *path) DPRINTF("connected as %08x\n", ctx->local_id); uloop_init(); ubus_add_uloop(ctx); + ubus_fd.fd = ctx->sock.fd; + netifd_fd_add(&ubus_fd); ret = ubus_add_object(ctx, &main_object); if (ret) |