commit a0a86356fb75f58f574be3f798b8553f30757553 from: Stefan Sperling date: Tue Sep 02 09:28:54 2025 UTC run one access.c process per server to avoid it becoming a bottleneck commit - 97e0634664f953267d4dca4b99383e4dfb25b817 commit + a0a86356fb75f58f574be3f798b8553f30757553 blob - ebf0ba06b3f3b8c25adc16140de61303b4d6d6b3 blob + 514205b24b104a80a2b51b84839c77490c9f78cf --- gotwebd/access.c +++ gotwebd/access.c @@ -37,13 +37,10 @@ static void access_shutdown(void) { struct gotwebd *env = gotwebd_env; - int i; imsgbuf_clear(&env->iev_parent->ibuf); + imsgbuf_clear(&env->iev_login->ibuf); - for (i = 0; i < env->nserver; i++) - imsgbuf_clear(&env->iev_login[i].ibuf); - free(env->iev_parent); free(env->iev_login); free(env); @@ -193,10 +190,7 @@ access_check(uid_t uid, struct gotwebd_access_rule_lis static void access_launch(struct gotwebd *env) { - int i; - - for (i = 0; i < env->nserver; i++) - event_add(&env->iev_login[i].ev, NULL); + event_add(&env->iev_login->ev, NULL); } static void @@ -251,14 +245,14 @@ recv_login_pipe(struct gotwebd *env, struct imsg *imsg struct imsgev *iev; int fd; - if (env->server_cnt >= env->nserver) - fatalx("too many login pipes received"); - fd = imsg_get_fd(imsg); if (fd == -1) fatalx("invalid login pipe fd"); - iev = &env->iev_login[env->server_cnt]; + iev = calloc(1, sizeof(*iev)); + if (iev == NULL) + fatal("calloc"); + if (imsgbuf_init(&iev->ibuf, fd) == -1) fatal("imsgbuf_init"); imsgbuf_allow_fdpass(&iev->ibuf); @@ -268,7 +262,7 @@ recv_login_pipe(struct gotwebd *env, struct imsg *imsg event_set(&iev->ev, fd, EV_READ, access_dispatch_login, iev); imsg_event_add(iev); - env->server_cnt++; + env->iev_login = iev; } static void @@ -389,11 +383,6 @@ gotwebd_access(struct gotwebd *env, int fd) env->iev_parent); event_add(&env->iev_parent->ev, NULL); - env->nserver = env->prefork_gotwebd; - env->iev_login = calloc(env->nserver, sizeof(*env->iev_login)); - if (env->iev_login == NULL) - fatal("calloc"); - signal(SIGPIPE, SIG_IGN); signal_set(&sighup, SIGHUP, access_sighdlr, env); blob - 453a31f9322abec89be8bdabd70c4897958d6883 blob + ddc6de1b9c5a3a6800e85b6e3dd01bba38d54cf0 --- gotwebd/gotwebd.c +++ gotwebd/gotwebd.c @@ -143,6 +143,22 @@ main_compose_login(struct gotwebd *env, uint32_t type, for (i = 0; i < env->nserver; ++i) { ret = send_imsg(&env->iev_login[i], type, fd, data, len); + if (ret) + break; + } + + return ret; +} + +int +main_compose_access(struct gotwebd *env, uint32_t type, int fd, + const void *data, uint16_t len) +{ + size_t i; + int ret = 0; + + for (i = 0; i < env->nserver; ++i) { + ret = send_imsg(&env->iev_access[i], type, fd, data, len); if (ret) break; } @@ -720,9 +736,6 @@ main(int argc, char **argv) env->iev_auth = calloc(1, sizeof(*env->iev_auth)); if (env->iev_auth == NULL) fatal("calloc"); - env->iev_access = calloc(1, sizeof(*env->iev_access)); - if (env->iev_access == NULL) - fatal("calloc"); env->nserver = env->prefork_gotwebd; env->iev_server = calloc(env->nserver, sizeof(*env->iev_server)); if (env->iev_server == NULL) @@ -730,14 +743,15 @@ main(int argc, char **argv) env->iev_login = calloc(env->nserver, sizeof(*env->iev_login)); if (env->iev_login == NULL) fatal("calloc"); + env->iev_access = calloc(env->nserver, sizeof(*env->iev_access)); + if (env->iev_access == NULL) + fatal("calloc"); env->iev_gotweb = calloc(env->nserver, sizeof(*env->iev_gotweb)); if (env->iev_gotweb == NULL) fatal("calloc"); spawn_process(env, argv0, env->iev_auth, GOTWEBD_PROC_AUTH, gotwebd_username, gotwebd_dispatch_auth); - spawn_process(env, argv0, env->iev_access, GOTWEBD_PROC_ACCESS, - gotwebd_username, gotwebd_dispatch_access); for (i = 0; i < env->nserver; ++i) { spawn_process(env, argv0, &env->iev_server[i], @@ -746,6 +760,9 @@ main(int argc, char **argv) spawn_process(env, argv0, &env->iev_login[i], GOTWEBD_PROC_LOGIN, gotwebd_username, gotwebd_dispatch_login); + spawn_process(env, argv0, &env->iev_access[i], + GOTWEBD_PROC_ACCESS, gotwebd_username, + gotwebd_dispatch_access); spawn_process(env, argv0, &env->iev_gotweb[i], GOTWEBD_PROC_GOTWEB, gotwebd_username, gotwebd_dispatch_gotweb); @@ -804,13 +821,14 @@ main(int argc, char **argv) static void connect_children(struct gotwebd *env) { - struct imsgev *iev_server, *iev_login, *iev_gotweb; + struct imsgev *iev_server, *iev_login, *iev_access, *iev_gotweb; int pipe[2]; int i; for (i = 0; i < env->nserver; i++) { iev_server = &env->iev_server[i]; iev_login = &env->iev_login[i]; + iev_access = &env->iev_access[i]; iev_gotweb = &env->iev_gotweb[i]; if (socketpair(AF_UNIX, SOCK_STREAM, PF_UNSPEC, pipe) == -1) @@ -842,7 +860,7 @@ connect_children(struct gotwebd *env) if (send_imsg(iev_login, GOTWEBD_IMSG_CTL_PIPE, pipe[0], NULL, 0)) fatal("send_imsg"); - if (send_imsg(env->iev_access, GOTWEBD_IMSG_CTL_PIPE, pipe[1], + if (send_imsg(iev_access, GOTWEBD_IMSG_CTL_PIPE, pipe[1], NULL, 0)) fatal("send_imsg"); } @@ -860,15 +878,17 @@ gotwebd_configure(struct gotwebd *env, uid_t uid, gid_ /* gotweb need to reload its config. */ env->servers_pending = env->prefork_gotwebd; env->login_pending = env->prefork_gotwebd; + env->access_pending = env->prefork_gotwebd; env->gotweb_pending = env->prefork_gotwebd; arc4random_buf(auth_token_secret, sizeof(auth_token_secret)); /* send our global access rules */ - config_set_access_rules(env->iev_access, &env->access_rules); for (i = 0; i < env->nserver; ++i) { config_set_access_rules(&env->iev_login[i], &env->access_rules); + config_set_access_rules(&env->iev_access[i], + &env->access_rules); config_set_access_rules(&env->iev_gotweb[i], &env->access_rules); } @@ -884,47 +904,48 @@ gotwebd_configure(struct gotwebd *env, uid_t uid, gid_ if (main_compose_gotweb(env, GOTWEBD_IMSG_CFG_SRV, -1, srv, sizeof(*srv)) == -1) fatal("main_compose_gotweb GOTWEBD_IMSG_CFG_SRV"); - if (send_imsg(env->iev_access, GOTWEBD_IMSG_CFG_SRV, + if (main_compose_access(env, GOTWEBD_IMSG_CFG_SRV, -1, srv, sizeof(*srv)) == -1) fatal("send_imsg GOTWEBD_IMSG_CFG_SRV"); /* send per-server access rules */ - config_set_access_rules(env->iev_access, &srv->access_rules); for (i = 0; i < env->nserver; ++i) { config_set_access_rules(&env->iev_login[i], &srv->access_rules); + config_set_access_rules(&env->iev_access[i], + &srv->access_rules); config_set_access_rules(&env->iev_gotweb[i], &srv->access_rules); } /* send repositories and per-repository access rules */ TAILQ_FOREACH(repo, &srv->repos, entry) { - config_set_repository(env->iev_access, repo); - config_set_access_rules(env->iev_access, - &repo->access_rules); - for (i = 0; i < env->nserver; i++) { config_set_repository(&env->iev_login[i], repo); + config_set_repository(&env->iev_access[i], + repo); config_set_repository(&env->iev_gotweb[i], repo); config_set_access_rules(&env->iev_login[i], &repo->access_rules); + config_set_access_rules(&env->iev_access[i], + &repo->access_rules); config_set_access_rules(&env->iev_gotweb[i], &repo->access_rules); } } - if (imsgbuf_flush(&env->iev_access->ibuf) == -1) - fatal("imsgbuf_flush"); - imsg_event_add(env->iev_access); - for (i = 0; i < env->nserver; i++) { if (imsgbuf_flush(&env->iev_login[i].ibuf) == -1) fatal("imsgbuf_flush"); imsg_event_add(&env->iev_login[i]); + if (imsgbuf_flush(&env->iev_access[i].ibuf) == -1) + fatal("imsgbuf_flush"); + imsg_event_add(&env->iev_access[i]); + if (imsgbuf_flush(&env->iev_gotweb[i].ibuf) == -1) fatal("imsgbuf_flush"); imsg_event_add(&env->iev_gotweb[i]); @@ -940,32 +961,32 @@ gotwebd_configure(struct gotwebd *env, uid_t uid, gid_ if (main_compose_login(env, GOTWEBD_IMSG_AUTH_CONF, -1, &env->auth_config, sizeof(env->auth_config)) == -1) fatal("main_compose_login GOTWEB_IMSG_AUTH_CONF"); + if (main_compose_access(env, GOTWEBD_IMSG_AUTH_CONF, -1, + &env->auth_config, sizeof(env->auth_config)) == -1) + fatal("send_imsg GOTWEB_IMSG_AUTH_CONF"); if (main_compose_gotweb(env, GOTWEBD_IMSG_AUTH_CONF, -1, &env->auth_config, sizeof(env->auth_config)) == -1) fatal("main_compose_login GOTWEB_IMSG_AUTH_CONF"); - if (send_imsg(env->iev_access, GOTWEBD_IMSG_AUTH_CONF, -1, - &env->auth_config, sizeof(env->auth_config)) == -1) - fatal("send_imsg GOTWEB_IMSG_AUTH_CONF"); if (main_compose_login(env, GOTWEBD_IMSG_WWW_UID, -1, &env->www_uid, sizeof(env->www_uid)) == -1) fatal("main_compose_login GOTWEB_IMSG_WWW_UID"); + if (main_compose_access(env, GOTWEBD_IMSG_WWW_UID, -1, + &env->www_uid, sizeof(env->www_uid)) == -1) + fatal("send_imsg GOTWEB_IMSG_WWW_UID"); if (main_compose_gotweb(env, GOTWEBD_IMSG_WWW_UID, -1, &env->www_uid, sizeof(env->www_uid)) == -1) fatal("main_compose_login GOTWEB_IMSG_WWW_UID"); - if (send_imsg(env->iev_access, GOTWEBD_IMSG_WWW_UID, -1, - &env->www_uid, sizeof(env->www_uid)) == -1) - fatal("send_imsg GOTWEB_IMSG_WWW_UID"); if (main_compose_login(env, GOTWEBD_IMSG_AUTH_SECRET, -1, auth_token_secret, sizeof(auth_token_secret)) == -1) fatal("main_compose_login GOTWEB_IMSG_AUTH_SECRET"); + if (main_compose_access(env, GOTWEBD_IMSG_AUTH_SECRET, -1, + auth_token_secret, sizeof(auth_token_secret)) == -1) + fatal("send_imsg GOTWEB_IMSG_AUTH_SECRET"); if (main_compose_auth(env, GOTWEBD_IMSG_AUTH_SECRET, -1, auth_token_secret, sizeof(auth_token_secret)) == -1) fatal("main_compose_gotweb GOTWEB_IMSG_AUTH_SECRET"); - if (send_imsg(env->iev_access, GOTWEBD_IMSG_AUTH_SECRET, -1, - auth_token_secret, sizeof(auth_token_secret)) == -1) - fatal("send_imsg GOTWEB_IMSG_AUTH_SECRET"); explicit_bzero(auth_token_secret, sizeof(auth_token_secret)); @@ -1008,6 +1029,14 @@ gotwebd_configure_done(struct gotwebd *env) fatal("main_compose_login GOTWEBD_IMSG_CTL_START"); } + if (env->access_pending > 0) { + env->access_pending--; + if (env->access_pending == 0 && + main_compose_access(env, GOTWEBD_IMSG_CTL_START, + -1, NULL, 0) == -1) + fatal("main_compose_access GOTWEBD_IMSG_CTL_START"); + } + if (env->gotweb_pending > 0) { env->gotweb_pending--; if (env->gotweb_pending == 0 && @@ -1016,13 +1045,11 @@ gotwebd_configure_done(struct gotwebd *env) fatal("main_compose_sockets GOTWEBD_IMSG_CTL_START"); } - if (env->servers_pending == 0 && env->gotweb_pending == 0) { + if (env->servers_pending == 0 && env->gotweb_pending == 0 && + env->login_pending == 0 && env->access_pending == 0) { if (main_compose_auth(env, GOTWEBD_IMSG_CTL_START, -1, NULL, 0) == -1) fatal("main_compose_auth GOTWEBD_IMSG_CTL_START"); - if (send_imsg(env->iev_access, GOTWEBD_IMSG_CTL_START, - -1, NULL, 0) == -1) - fatal("send_imsg GOTWEBD_IMSG_CTL_START"); } } @@ -1039,10 +1066,12 @@ gotwebd_shutdown(void) env->iev_auth->ibuf.fd = -1; free(env->iev_auth); - event_del(&env->iev_access->ev); - imsgbuf_clear(&env->iev_access->ibuf); - close(env->iev_access->ibuf.fd); - env->iev_access->ibuf.fd = -1; + for (i = 0; i < env->nserver; ++i) { + event_del(&env->iev_access[i].ev); + imsgbuf_clear(&env->iev_access[i].ibuf); + close(env->iev_access[i].ibuf.fd); + env->iev_access[i].ibuf.fd = -1; + } free(env->iev_access); for (i = 0; i < env->nserver; ++i) { blob - e3a745e3df95c9878c6d2fe4843e85f4d2aaafbe blob + 658f263f082bd8a2d7cec58e8364388d004e3531 --- gotwebd/gotwebd.h +++ gotwebd/gotwebd.h @@ -435,6 +435,7 @@ struct gotwebd { uint16_t prefork_gotwebd; int servers_pending; int login_pending; + int access_pending; int gotweb_pending; int server_cnt; @@ -521,6 +522,8 @@ int sockets_compose_main(struct gotwebd *, uint32_t, const void *, uint16_t); int main_compose_login(struct gotwebd *, uint32_t, int, const void *, uint16_t); +int main_compose_access(struct gotwebd *, uint32_t, int, + const void *, uint16_t); int login_compose_main(struct gotwebd *, uint32_t, const void *, uint16_t); int main_compose_gotweb(struct gotwebd *, uint32_t, int,