diff --git a/include/fluent-bit/flb_error.h b/include/fluent-bit/flb_error.h index 17c9e07eaeb..545a296d039 100644 --- a/include/fluent-bit/flb_error.h +++ b/include/fluent-bit/flb_error.h @@ -26,6 +26,7 @@ #define FLB_ERR_CFG_FLUSH 20 #define FLB_ERR_CFG_FLUSH_CREATE 21 #define FLB_ERR_CFG_FLUSH_REGISTER 22 +#define FLB_ERR_EVENT_LOOP_CREATE 30 #define FLB_ERR_CUSTOM_INVALID 49 #define FLB_ERR_INPUT_INVALID 50 #define FLB_ERR_INPUT_UNDEF 51 diff --git a/include/fluent-bit/flb_lib.h b/include/fluent-bit/flb_lib.h index 88ff8cb0af3..3293bb41d9b 100644 --- a/include/fluent-bit/flb_lib.h +++ b/include/fluent-bit/flb_lib.h @@ -49,6 +49,8 @@ typedef struct flb_lib_ctx flb_ctx_t; struct flb_processor; FLB_EXPORT void flb_init_env(); +FLB_EXPORT int flb_event_loop_create(flb_ctx_t *ctx); +FLB_EXPORT int flb_event_loop_destroy(flb_ctx_t *ctx); FLB_EXPORT flb_ctx_t *flb_create(); FLB_EXPORT void flb_destroy(flb_ctx_t *ctx); FLB_EXPORT int flb_input(flb_ctx_t *ctx, const char *input, void *data); diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index ac5fe5ef863..d33a590e009 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -8,6 +8,7 @@ set(src flb_api.c flb_csv.c flb_lib.c + flb_event_loop.c flb_log.c flb_env.c flb_file.c diff --git a/src/flb_event_loop.c b/src/flb_event_loop.c new file mode 100644 index 00000000000..e6dd3659f78 --- /dev/null +++ b/src/flb_event_loop.c @@ -0,0 +1,104 @@ +/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ + +/* Fluent Bit + * ========== + * Copyright (C) 2015-2025 The Fluent Bit Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include +#include + +#include + +int flb_event_loop_create(flb_ctx_t *ctx) +{ + int ret; + struct flb_config *config; + + if (ctx == NULL || ctx->config == NULL) + return FLB_LIB_ERROR; + + config = ctx->config; + + /* Create the event loop to receive notifications */ + ctx->event_loop = mk_event_loop_create(256); + if (!ctx->event_loop) + goto error_0; + + config->ch_evl = ctx->event_loop; + + /* Prepare the notification channels */ + ctx->event_channel = flb_calloc(1, sizeof(struct mk_event)); + if (!ctx->event_channel) { + flb_error("[lib] could not allocate event channel"); + goto error_1; + } + + MK_EVENT_ZERO(ctx->event_channel); + + ret = mk_event_channel_create(config->ch_evl, + &config->ch_notif[0], + &config->ch_notif[1], + ctx->event_channel); + if (ret != 0) { + flb_error("[lib] could not create notification channels"); + goto error_2; + } + + return 0; + +error_2: + flb_free(ctx->event_channel); + ctx->event_channel = NULL; +error_1: + mk_event_loop_destroy(ctx->event_loop); + ctx->event_loop = NULL; +error_0: + config->ch_evl = NULL; + return FLB_LIB_ERROR; +} + +int flb_event_loop_destroy(flb_ctx_t *ctx) +{ + int ret; + struct flb_config *config; + + if (ctx == NULL || ctx->config == NULL) + return 0; + + config = ctx->config; + if (ctx->event_channel != NULL) { + ret = mk_event_channel_destroy(config->ch_evl, + config->ch_notif[0], + config->ch_notif[1], + ctx->event_channel); + if (ret != 0) { + /* make sure to close file descriptors */ + close(config->ch_notif[0]); + close(config->ch_notif[1]); + } + flb_free(ctx->event_channel); + ctx->event_channel = NULL; + } + + if (ctx->event_loop != NULL) { + mk_event_loop_destroy(ctx->event_loop); + ctx->event_loop = NULL; + config->ch_evl = NULL; + } + + return 0; +} + diff --git a/src/flb_lib.c b/src/flb_lib.c index 29bc200630a..fc5f391c48b 100644 --- a/src/flb_lib.c +++ b/src/flb_lib.c @@ -184,37 +184,13 @@ flb_ctx_t *flb_create() return NULL; } - /* Create the event loop to receive notifications */ - ctx->event_loop = mk_event_loop_create(256); - if (!ctx->event_loop) { - flb_config_exit(ctx->config); - flb_free(ctx); - return NULL; - } - config->ch_evl = ctx->event_loop; - - /* Prepare the notification channels */ - ctx->event_channel = flb_calloc(1, sizeof(struct mk_event)); - if (!ctx->event_channel) { - perror("calloc"); + ret = flb_event_loop_create(ctx); + if (ret != 0) { flb_config_exit(ctx->config); flb_free(ctx); return NULL; } - MK_EVENT_ZERO(ctx->event_channel); - - ret = mk_event_channel_create(config->ch_evl, - &config->ch_notif[0], - &config->ch_notif[1], - ctx->event_channel); - if (ret != 0) { - flb_error("[lib] could not create notification channels"); - flb_stop(ctx); - flb_destroy(ctx); - return NULL; - } - #ifdef FLB_HAVE_AWS_ERROR_REPORTER if (is_error_reporting_enabled()) { error_reporter = flb_aws_error_reporter_create(); diff --git a/src/flb_utils.c b/src/flb_utils.c index e816651fb4d..e51602ed598 100644 --- a/src/flb_utils.c +++ b/src/flb_utils.c @@ -89,6 +89,9 @@ void flb_utils_error(int err) case FLB_ERR_CFG_FLUSH_REGISTER: msg = "could not register timer for flushing"; break; + case FLB_ERR_EVENT_LOOP_CREATE: + msg = "could not create event loop"; + break; case FLB_ERR_INPUT_INVALID: msg = "invalid input type"; break; diff --git a/src/fluent-bit.c b/src/fluent-bit.c index be5685a1b9e..7013771bdb2 100644 --- a/src/fluent-bit.c +++ b/src/fluent-bit.c @@ -1415,7 +1415,18 @@ static int flb_main_run(int argc, char **argv) #ifdef FLB_HAVE_FORK /* Run in background/daemon mode */ if (config->daemon == FLB_TRUE) { +#if defined(__FreeBSD__) || defined(__NetBSD__) || \ + defined(__OpenBSD__) || defined(__DragonFly__) + flb_event_loop_destroy(ctx); +#endif flb_utils_set_daemon(config); +#if defined(__FreeBSD__) || defined(__NetBSD__) || \ + defined(__OpenBSD__) || defined(__DragonFly__) + if (flb_event_loop_create(ctx) != 0) { + flb_error("[daemon] failed to recreate event loop after daemonizing"); + flb_utils_error(FLB_ERR_EVENT_LOOP_CREATE); + } +#endif } #endif