diff --git a/include/fluent-bit/flb_config.h b/include/fluent-bit/flb_config.h index 1cfc6301ff8..ea5912b440b 100644 --- a/include/fluent-bit/flb_config.h +++ b/include/fluent-bit/flb_config.h @@ -21,6 +21,7 @@ #define FLB_CONFIG_H #include +#include #include #include @@ -266,6 +267,8 @@ struct flb_config { int enable_hot_reload; int ensure_thread_safety_on_hot_reloading; unsigned int hot_reloaded_count; + unsigned int hot_reloaded_failures_count; + volatile sig_atomic_t service_is_restarting; int shutdown_by_hot_reloading; int hot_reloading; diff --git a/include/fluent-bit/flb_reload.h b/include/fluent-bit/flb_reload.h index fecfca3fff1..0412fa9370a 100644 --- a/include/fluent-bit/flb_reload.h +++ b/include/fluent-bit/flb_reload.h @@ -35,5 +35,6 @@ int flb_reload_property_check_all(struct flb_config *config); int flb_reload_reconstruct_cf(struct flb_cf *src_cf, struct flb_cf *dest_cf); int flb_reload(flb_ctx_t *ctx, struct flb_cf *cf_opts); +int flb_signal_reload(struct flb_config *config); #endif diff --git a/plugins/in_calyptia_fleet/in_calyptia_fleet.c b/plugins/in_calyptia_fleet/in_calyptia_fleet.c index 14033305f04..5f270f38308 100644 --- a/plugins/in_calyptia_fleet/in_calyptia_fleet.c +++ b/plugins/in_calyptia_fleet/in_calyptia_fleet.c @@ -468,13 +468,9 @@ static void *do_reload(void *data) } reload->flb->config->conf_path_file = reload->cfg_path; - flb_free(reload); sleep(5); -#ifndef FLB_SYSTEM_WINDOWS - kill(getpid(), SIGHUP); -#else - GenerateConsoleCtrlEvent(1 /* CTRL_BREAK_EVENT_1 */, 0); -#endif + flb_signal_reload(reload->flb->config); + flb_free(reload); return NULL; } diff --git a/src/flb_reload.c b/src/flb_reload.c index 2f156bfdcf2..cbdd8c96d0b 100644 --- a/src/flb_reload.c +++ b/src/flb_reload.c @@ -384,12 +384,14 @@ int flb_reload(flb_ctx_t *ctx, struct flb_cf *cf_opts) if (ctx == NULL) { flb_error("[reload] given flb context is NULL"); + ctx->config->hot_reloaded_failures_count++; return FLB_RELOAD_INVALID_CONTEXT; } old_config = ctx->config; if (old_config->enable_hot_reload != FLB_TRUE) { flb_warn("[reload] hot reloading is not enabled"); + old_config->hot_reloaded_failures_count++; return FLB_RELOAD_NOT_ENABLED; } @@ -404,6 +406,7 @@ int flb_reload(flb_ctx_t *ctx, struct flb_cf *cf_opts) */ new_cf = flb_cf_create(); if (!new_cf) { + old_config->hot_reloaded_failures_count++; return FLB_RELOAD_HALTED; } @@ -421,6 +424,7 @@ int flb_reload(flb_ctx_t *ctx, struct flb_cf *cf_opts) } flb_cf_destroy(new_cf); flb_error("[reload] reconstruct cf failed"); + old_config->hot_reloaded_failures_count++; return FLB_RELOAD_HALTED; } } @@ -434,6 +438,7 @@ int flb_reload(flb_ctx_t *ctx, struct flb_cf *cf_opts) flb_cf_destroy(new_cf); flb_error("[reload] creating flb context is failed. Reloading is halted"); + old_config->hot_reloaded_failures_count++; return FLB_RELOAD_HALTED; } @@ -462,6 +467,10 @@ int flb_reload(flb_ctx_t *ctx, struct flb_cf *cf_opts) if (!new_cf) { flb_sds_destroy(file); + flb_destroy(new_ctx); + + old_config->hot_reloading = FLB_FALSE; + old_config->hot_reloaded_failures_count++; return FLB_RELOAD_HALTED; } @@ -476,6 +485,10 @@ int flb_reload(flb_ctx_t *ctx, struct flb_cf *cf_opts) } flb_cf_destroy(new_cf); flb_destroy(new_ctx); + + old_config->hot_reloading = FLB_FALSE; + old_config->hot_reloaded_failures_count++; + flb_error("[reload] reloaded config is invalid. Reloading is halted"); return FLB_RELOAD_HALTED; @@ -489,6 +502,9 @@ int flb_reload(flb_ctx_t *ctx, struct flb_cf *cf_opts) flb_cf_destroy(new_cf); flb_destroy(new_ctx); + old_config->hot_reloading = FLB_FALSE; + old_config->hot_reloaded_failures_count++; + flb_error("[reload] reloaded config format is invalid. Reloading is halted"); return FLB_RELOAD_HALTED; @@ -501,6 +517,9 @@ int flb_reload(flb_ctx_t *ctx, struct flb_cf *cf_opts) flb_cf_destroy(new_cf); flb_destroy(new_ctx); + old_config->hot_reloading = FLB_FALSE; + old_config->hot_reloaded_failures_count++; + flb_error("[reload] reloaded config is invalid. Reloading is halted"); return FLB_RELOAD_HALTED; @@ -528,6 +547,8 @@ int flb_reload(flb_ctx_t *ctx, struct flb_cf *cf_opts) if (ret != 0) { flb_destroy(new_ctx); + old_config->hot_reloading = FLB_FALSE; + old_config->hot_reloaded_failures_count++; flb_error("[reload] loaded configuration contains error(s). Reloading is aborted"); @@ -541,3 +562,19 @@ int flb_reload(flb_ctx_t *ctx, struct flb_cf *cf_opts) return 0; } + +int flb_signal_reload(struct flb_config *config) +{ +#ifndef FLB_SYSTEM_WINDOWS + kill(getpid(), SIGHUP); +#else + /* using the refactor that placed `service_is_restarting` inside + * `flb_config` to use it as a messaging mechanism instead of + * GenerateConsoleCtrlEvent to overcome the fact that windows + * services do not have a console and therefore cannot + * react to console events or handle them (fixes sc-112185). + */ + config->service_is_restarting = FLB_RELOAD_IN_PROGRESS; +#endif + return 0; +} diff --git a/src/fluent-bit.c b/src/fluent-bit.c index 6444b333f2d..0618d5a68f9 100644 --- a/src/fluent-bit.c +++ b/src/fluent-bit.c @@ -72,7 +72,7 @@ extern void win32_started(void); flb_ctx_t *ctx; struct flb_config *config; volatile sig_atomic_t exit_signal = 0; -volatile sig_atomic_t flb_bin_restarting = FLB_RELOAD_IDLE; +pthread_mutex_t reload_mtx; #ifdef FLB_HAVE_LIBBACKTRACE struct flb_stacktrace flb_st; @@ -606,11 +606,14 @@ static void flb_signal_handler(int signal) break; #ifndef FLB_HAVE_STATIC_CONF case SIGHUP: - if (flb_bin_restarting == FLB_RELOAD_IDLE) { - flb_bin_restarting = FLB_RELOAD_IN_PROGRESS; - } - else { - flb_utils_error(FLB_ERR_RELOADING_IN_PROGRESS); + if (pthread_mutex_trylock(&reload_mtx) == 0) { + if (config->service_is_restarting == FLB_RELOAD_IDLE) { + config->service_is_restarting = FLB_RELOAD_IN_PROGRESS; + } + else { + flb_utils_error(FLB_ERR_RELOADING_IN_PROGRESS); + } + pthread_mutex_unlock(&reload_mtx); } break; #endif @@ -647,16 +650,19 @@ static BOOL WINAPI flb_console_handler(DWORD evType) handler_signal = 2; break; case 1 /* CTRL_BREAK_EVENT_1 */: - if (flb_bin_restarting == FLB_RELOAD_IDLE) { - flb_bin_restarting = FLB_RELOAD_IN_PROGRESS; - /* signal the main loop to execute reload. this is necessary since - * all signal handlers in win32 are executed on their own thread. - */ - handler_signal = 1; - flb_bin_restarting = FLB_RELOAD_IDLE; - } - else { - flb_utils_error(FLB_ERR_RELOADING_IN_PROGRESS); + if (pthread_mutex_trylock(&reload_mtx) == 0) { + if (config->service_is_restarting == FLB_RELOAD_IDLE) { + config->service_is_restarting = FLB_RELOAD_IN_PROGRESS; + /* signal the main loop to execute reload. this is necessary since + * all signal handlers in win32 are executed on their own thread. + */ + handler_signal = 1; + config->service_is_restarting = FLB_RELOAD_IDLE; + } + else { + flb_utils_error(FLB_ERR_RELOADING_IN_PROGRESS); + } + pthread_mutex_unlock(&reload_mtx); } break; } @@ -1384,6 +1390,8 @@ int flb_main(int argc, char **argv) } #endif + pthread_mutex_init(&reload_mtx, NULL); + while (ctx->status == FLB_LIB_OK && exit_signal == 0) { sleep(1); @@ -1404,30 +1412,35 @@ int flb_main(int argc, char **argv) #ifdef FLB_SYSTEM_WINDOWS flb_console_handler_set_ctx(ctx, cf_opts); #endif - if (flb_bin_restarting == FLB_RELOAD_IN_PROGRESS) { + pthread_mutex_lock(&reload_mtx); + if (config->service_is_restarting == FLB_RELOAD_IN_PROGRESS) { /* reload by using same config files/path */ ret = flb_reload(ctx, cf_opts); if (ret == 0) { ctx = flb_context_get(); - flb_bin_restarting = FLB_RELOAD_IDLE; + config = ctx->config; + config->service_is_restarting = FLB_RELOAD_IDLE; } else { - flb_bin_restarting = ret; + config->service_is_restarting = ret; } } - if (flb_bin_restarting == FLB_RELOAD_HALTED) { + if (config->service_is_restarting == FLB_RELOAD_HALTED) { sleep(1); - flb_bin_restarting = FLB_RELOAD_IDLE; + config->service_is_restarting = FLB_RELOAD_IDLE; } + pthread_mutex_unlock(&reload_mtx); } if (exit_signal) { flb_signal_exit(exit_signal); } - if (flb_bin_restarting != FLB_RELOAD_ABORTED) { + pthread_mutex_lock(&reload_mtx); + if (config->service_is_restarting != FLB_RELOAD_ABORTED) { ret = ctx->config->exit_status_code; } + pthread_mutex_unlock(&reload_mtx); cf_opts = flb_cf_context_get(); @@ -1449,13 +1462,15 @@ int flb_main(int argc, char **argv) } #endif - if (flb_bin_restarting == FLB_RELOAD_ABORTED) { + pthread_mutex_lock(&reload_mtx); + if (config->service_is_restarting == FLB_RELOAD_ABORTED) { fprintf(stderr, "reloading is aborted and exit\n"); - } - else { - flb_stop(ctx); - flb_destroy(ctx); - } + } + else { + flb_stop(ctx); + flb_destroy(ctx); + } + pthread_mutex_unlock(&reload_mtx); return ret; } diff --git a/src/http_server/api/v2/reload.c b/src/http_server/api/v2/reload.c index 2f8c947cbd9..a90192b91e6 100644 --- a/src/http_server/api/v2/reload.c +++ b/src/http_server/api/v2/reload.c @@ -67,13 +67,7 @@ static void handle_reload_request(mk_request_t *request, struct flb_config *conf http_status = 400; } else { - ret = GenerateConsoleCtrlEvent(1 /* CTRL_BREAK_EVENT_1 */, 0); - if (ret == 0) { - mk_http_status(request, 500); - mk_http_done(request); - return; - } - + flb_signal_reload(config); msgpack_pack_str(&mp_pck, 4); msgpack_pack_str_body(&mp_pck, "done", 4); msgpack_pack_str(&mp_pck, 6); @@ -97,7 +91,7 @@ static void handle_reload_request(mk_request_t *request, struct flb_config *conf http_status = 400; } else { - ret = kill(getpid(), SIGHUP); + ret = flb_signal_reload(config); if (ret != 0) { mk_http_status(request, 500); mk_http_done(request);