diff --git a/docker/bin/setup b/docker/bin/setup index 31d14292..1568f9e2 100755 --- a/docker/bin/setup +++ b/docker/bin/setup @@ -1,6 +1,5 @@ #!/bin/bash - export SETUP_LOG=/var/log/postgresql/postgresql-13-main.log cat > /etc/postgresql/13/main/pg_hba.conf <<-EOF diff --git a/docker/scram/config.conf b/docker/scram/config.conf index 08b0dfd4..12800eae 100644 --- a/docker/scram/config.conf +++ b/docker/scram/config.conf @@ -54,7 +54,7 @@ database "scram_db" { } daemonize yes -pid_file "odyssey/data/odyssey.pid" +pid_file "/var/run/odyssey.pid" unix_socket_dir "/tmp" unix_socket_mode "0644" diff --git a/sources/cron.c b/sources/cron.c index c2135c91..d33aeead 100644 --- a/sources/cron.c +++ b/sources/cron.c @@ -197,26 +197,36 @@ static void od_cron_err_stat(od_cron_t *cron) od_route_pool_unlock(router->route_pool) } -od_attribute_noreturn() static void od_cron(void *arg) +static void od_cron(void *arg) { od_cron_t *cron = arg; od_instance_t *instance = cron->global->instance; cron->stat_time_us = machine_time_us(); + cron->online = 1; int stats_tick = 0; for (;;) { - /* mark and sweep expired idle server connections */ - od_cron_expire(cron); - - /* update statistics */ - if (++stats_tick >= instance->config.stats_interval) { - od_cron_stat(cron); - stats_tick = 0; + if (!cron->online) { + return; } - od_cron_err_stat(cron); + // we take a lock here + // to prevent usage routes that are deallocated while shutdown + pthread_mutex_lock(&cron->lock); + { + /* mark and sweep expired idle server connections */ + od_cron_expire(cron); + /* update statistics */ + if (++stats_tick >= instance->config.stats_interval) { + od_cron_stat(cron); + stats_tick = 0; + } + + od_cron_err_stat(cron); + } + pthread_mutex_unlock(&cron->lock); /* 1 second soft interval */ machine_sleep(1000); } @@ -227,6 +237,9 @@ void od_cron_init(od_cron_t *cron) cron->stat_time_us = 0; cron->global = NULL; cron->startup_errors = 0; + + cron->online = 0; + pthread_mutex_init(&cron->lock, NULL); } int od_cron_start(od_cron_t *cron, od_global_t *global) @@ -235,10 +248,18 @@ int od_cron_start(od_cron_t *cron, od_global_t *global) od_instance_t *instance = global->instance; int64_t coroutine_id; coroutine_id = machine_coroutine_create(od_cron, cron); - if (coroutine_id == -1) { + if (coroutine_id == INVALID_COROUTINE_ID) { od_error(&instance->logger, "cron", NULL, NULL, "failed to start cron coroutine"); - return -1; + return NOT_OK_RESPONSE; } - return 0; + + return OK_RESPONSE; +} + +od_retcode_t od_cron_stop(od_cron_t *cron) +{ + cron->online = 0; + pthread_mutex_lock(&cron->lock); + return OK_RESPONSE; } diff --git a/sources/cron.h b/sources/cron.h index 2865305a..73802a5d 100644 --- a/sources/cron.h +++ b/sources/cron.h @@ -13,6 +13,9 @@ struct od_cron { uint64_t stat_time_us; od_global_t *global; od_atomic_u64_t startup_errors; + + pthread_mutex_t lock; + int online; }; void od_cron_init(od_cron_t *); diff --git a/sources/frontend.c b/sources/frontend.c index 29f75cf0..116823b7 100644 --- a/sources/frontend.c +++ b/sources/frontend.c @@ -547,7 +547,8 @@ static inline bool od_should_drop_connection(od_client_t *client, /* fall through */ case OD_RULE_POOL_TRANSACTION: { //TODO:: drop no more than X connection per sec/min/whatever - if (od_likely(instance->shutdown_worker_id == INVALID_ID)) { + if (od_likely(instance->shutdown_worker_id == + INVALID_COROUTINE_ID)) { // try to optimize likely path return false; } diff --git a/sources/instance.c b/sources/instance.c index 1f131966..e300c42f 100644 --- a/sources/instance.c +++ b/sources/instance.c @@ -16,7 +16,7 @@ void od_instance_init(od_instance_t *instance) od_config_init(&instance->config); instance->config_file = NULL; - instance->shutdown_worker_id = INVALID_ID; + instance->shutdown_worker_id = INVALID_COROUTINE_ID; sigset_t mask; sigemptyset(&mask); diff --git a/sources/macro.h b/sources/macro.h index e127e6da..4c72e0a2 100644 --- a/sources/macro.h +++ b/sources/macro.h @@ -24,6 +24,6 @@ typedef int od_retcode_t; /*misc*/ -#define INVALID_ID -1 +#define INVALID_COROUTINE_ID -1 #endif /* ODYSSEY_MACRO_H */ diff --git a/sources/route.h b/sources/route.h index 8e0b9400..cc8e6539 100644 --- a/sources/route.h +++ b/sources/route.h @@ -33,6 +33,9 @@ struct od_route { static inline void od_route_init(od_route_t *route, bool extra_route_logging) { route->rule = NULL; + + route->tcp_connections = 0; + od_route_id_init(&route->id); od_server_pool_init(&route->server_pool); od_client_pool_init(&route->client_pool); diff --git a/sources/sighandler.c b/sources/sighandler.c index 4a35324e..c24a92f4 100644 --- a/sources/sighandler.c +++ b/sources/sighandler.c @@ -7,7 +7,7 @@ static inline od_retcode_t od_system_gracefully_killer_invoke(od_system_t *system) { od_instance_t *instance = system->global->instance; - if (instance->shutdown_worker_id != INVALID_ID) { + if (instance->shutdown_worker_id != INVALID_COROUTINE_ID) { return OK_RESPONSE; } int64_t mid; @@ -46,6 +46,10 @@ od_attribute_noreturn() void od_system_shutdown(od_system_t *system, { od_log(&instance->logger, "system", NULL, NULL, "SIGINT received, shutting down"); + + // lock here + od_cron_stop(system->global->cron); + od_worker_pool_stop(system->global->worker_pool); od_router_free(system->global->router); /* Prevent OpenSSL usage during deinitialization */ @@ -55,22 +59,6 @@ od_attribute_noreturn() void od_system_shutdown(od_system_t *system, exit(0); } -od_attribute_noreturn() void od_system_shutdown_fast(od_system_t *system, - od_instance_t *instance) -{ - od_log(&instance->logger, "system", NULL, NULL, - "SIGTERM received, shutting down"); - od_worker_pool_stop(system->global->worker_pool); - od_router_free(system->global->router); - - /* No time for caution */ - od_system_cleanup(system); - - /* TODO: */ - od_modules_unload_fast(system->global->modules); - exit(0); -} - void od_system_signal_handler(void *arg) { od_system_t *system = arg; @@ -100,8 +88,6 @@ void od_system_signal_handler(void *arg) break; switch (rc) { case SIGTERM: - od_system_shutdown_fast(system, instance); - break; case SIGINT: od_system_shutdown(system, instance); break;