From 03625d7c928be02258f8c963846a4b9926415c9d Mon Sep 17 00:00:00 2001 From: Yuichiro NAITO Date: Wed, 12 Nov 2025 17:22:50 +0900 Subject: [PATCH 1/7] lib: Re-create the event loop after daemonizing on BSD platforms. Because kqueue(2) is not inherited by the child process. Signed-off-by: Yuichiro NAITO --- include/fluent-bit/flb_error.h | 1 + include/fluent-bit/flb_lib.h | 2 + src/flb_lib.c | 105 +++++++++++++++++++++++++-------- src/flb_utils.c | 3 + src/fluent-bit.c | 11 ++++ 5 files changed, 96 insertions(+), 26 deletions(-) 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..33dc3ab4481 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_create_event_loop(flb_ctx_t *ctx); +FLB_EXPORT int flb_destroy_event_loop(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/flb_lib.c b/src/flb_lib.c index 29bc200630a..882bc59e501 100644 --- a/src/flb_lib.c +++ b/src/flb_lib.c @@ -140,6 +140,83 @@ void flb_init_env() cmt_initialize(); } +int flb_create_event_loop(flb_ctx_t *ctx) +{ + int ret; + struct flb_config *config; + + if (ctx == 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) + return FLB_LIB_ERROR; + + 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"); + 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; + return FLB_LIB_ERROR; +} + +int flb_destroy_event_loop(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; + } + + return 0; +} + flb_ctx_t *flb_create() { int ret; @@ -184,37 +261,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_create_event_loop(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..1f38d3b9574 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_destroy_event_loop(ctx); +#endif flb_utils_set_daemon(config); +#if defined(__FreeBSD__) || defined(__NetBSD__) || \ + defined(__OpenBSD__) || defined(__DragonFly__) + if (flb_create_event_loop(ctx) != 0) { + flb_error("[daemon] failed to recreate event loop after daemonizing"); + flb_utils_error(FLB_ERR_EVENT_LOOP_CREATE); + } +#endif } #endif From 21f3c59cf531988381143537821d280e7e686074 Mon Sep 17 00:00:00 2001 From: Yuichiro NAITO Date: Tue, 25 Nov 2025 12:21:02 +0900 Subject: [PATCH 2/7] event_loop: Introduce 'flb_event_loop.c'. This file contains 'flb_event_loop_*' functions. Signed-off-by: Yuichiro NAITO --- include/fluent-bit/flb_lib.h | 4 +- src/CMakeLists.txt | 1 + src/flb_event_loop.c | 101 +++++++++++++++++++++++++++++++++++ src/flb_lib.c | 79 +-------------------------- src/fluent-bit.c | 4 +- 5 files changed, 107 insertions(+), 82 deletions(-) create mode 100644 src/flb_event_loop.c diff --git a/include/fluent-bit/flb_lib.h b/include/fluent-bit/flb_lib.h index 33dc3ab4481..3293bb41d9b 100644 --- a/include/fluent-bit/flb_lib.h +++ b/include/fluent-bit/flb_lib.h @@ -49,8 +49,8 @@ typedef struct flb_lib_ctx flb_ctx_t; struct flb_processor; FLB_EXPORT void flb_init_env(); -FLB_EXPORT int flb_create_event_loop(flb_ctx_t *ctx); -FLB_EXPORT int flb_destroy_event_loop(flb_ctx_t *ctx); +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..d7330bddf8f --- /dev/null +++ b/src/flb_event_loop.c @@ -0,0 +1,101 @@ +/* -*- 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) + 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) + return FLB_LIB_ERROR; + + 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"); + 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; + 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; + } + + return 0; +} + diff --git a/src/flb_lib.c b/src/flb_lib.c index 882bc59e501..fc5f391c48b 100644 --- a/src/flb_lib.c +++ b/src/flb_lib.c @@ -140,83 +140,6 @@ void flb_init_env() cmt_initialize(); } -int flb_create_event_loop(flb_ctx_t *ctx) -{ - int ret; - struct flb_config *config; - - if (ctx == 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) - return FLB_LIB_ERROR; - - 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"); - 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; - return FLB_LIB_ERROR; -} - -int flb_destroy_event_loop(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; - } - - return 0; -} - flb_ctx_t *flb_create() { int ret; @@ -261,7 +184,7 @@ flb_ctx_t *flb_create() return NULL; } - ret = flb_create_event_loop(ctx); + ret = flb_event_loop_create(ctx); if (ret != 0) { flb_config_exit(ctx->config); flb_free(ctx); diff --git a/src/fluent-bit.c b/src/fluent-bit.c index 1f38d3b9574..7013771bdb2 100644 --- a/src/fluent-bit.c +++ b/src/fluent-bit.c @@ -1417,12 +1417,12 @@ static int flb_main_run(int argc, char **argv) if (config->daemon == FLB_TRUE) { #if defined(__FreeBSD__) || defined(__NetBSD__) || \ defined(__OpenBSD__) || defined(__DragonFly__) - flb_destroy_event_loop(ctx); + flb_event_loop_destroy(ctx); #endif flb_utils_set_daemon(config); #if defined(__FreeBSD__) || defined(__NetBSD__) || \ defined(__OpenBSD__) || defined(__DragonFly__) - if (flb_create_event_loop(ctx) != 0) { + 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); } From 5ce38c312be3a671f537c3746c2ab0a3d23fbf1c Mon Sep 17 00:00:00 2001 From: Yuichiro NAITO Date: Tue, 25 Nov 2025 17:12:15 +0900 Subject: [PATCH 3/7] event_loop: add NULL check for config member in 'flb_ctx_t'. Set NULL for the 'ch_evl' member after destroying. Signed-off-by: Yuichiro NAITO --- src/flb_event_loop.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/flb_event_loop.c b/src/flb_event_loop.c index d7330bddf8f..2c2352a2d14 100644 --- a/src/flb_event_loop.c +++ b/src/flb_event_loop.c @@ -27,7 +27,7 @@ int flb_event_loop_create(flb_ctx_t *ctx) int ret; struct flb_config *config; - if (ctx == NULL) + if (ctx == NULL || ctx->config == NULL) return FLB_LIB_ERROR; config = ctx->config; @@ -94,6 +94,7 @@ int flb_event_loop_destroy(flb_ctx_t *ctx) if (ctx->event_loop != NULL) { mk_event_loop_destroy(ctx->event_loop); ctx->event_loop = NULL; + config->ch_evl = NULL; } return 0; From 9581c8d995f436afc5b56d7694e99a6ca58ea169 Mon Sep 17 00:00:00 2001 From: Yuichiro NAITO Date: Tue, 25 Nov 2025 19:06:14 +0900 Subject: [PATCH 4/7] event_loop: refactor an error message. Signed-off-by: Yuichiro NAITO --- src/flb_event_loop.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/flb_event_loop.c b/src/flb_event_loop.c index 2c2352a2d14..8e5129a791c 100644 --- a/src/flb_event_loop.c +++ b/src/flb_event_loop.c @@ -42,7 +42,7 @@ int flb_event_loop_create(flb_ctx_t *ctx) /* Prepare the notification channels */ ctx->event_channel = flb_calloc(1, sizeof(struct mk_event)); if (!ctx->event_channel) { - perror("calloc"); + flb_error("[lib] could not allocate event channel"); goto error_1; } From 53a212caed4b74e459424e3809e5ebaee8b26b62 Mon Sep 17 00:00:00 2001 From: Yuichiro NAITO Date: Tue, 25 Nov 2025 21:58:07 +0900 Subject: [PATCH 5/7] event_loop: Clean up 'config->ch_evl' in an error case. Signed-off-by: Yuichiro NAITO --- src/flb_event_loop.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/flb_event_loop.c b/src/flb_event_loop.c index 8e5129a791c..e6dd3659f78 100644 --- a/src/flb_event_loop.c +++ b/src/flb_event_loop.c @@ -35,7 +35,7 @@ int flb_event_loop_create(flb_ctx_t *ctx) /* Create the event loop to receive notifications */ ctx->event_loop = mk_event_loop_create(256); if (!ctx->event_loop) - return FLB_LIB_ERROR; + goto error_0; config->ch_evl = ctx->event_loop; @@ -65,6 +65,8 @@ int flb_event_loop_create(flb_ctx_t *ctx) error_1: mk_event_loop_destroy(ctx->event_loop); ctx->event_loop = NULL; +error_0: + config->ch_evl = NULL; return FLB_LIB_ERROR; } From e3753696d6628cf3d62af52b981696b91471f78c Mon Sep 17 00:00:00 2001 From: Yuichiro NAITO Date: Fri, 28 Nov 2025 15:42:59 +0900 Subject: [PATCH 6/7] event_loop: Use 'mk_event_closesocket()' instead of 'close()'. Because of compatibility for Windows. Signed-off-by: Yuichiro NAITO --- src/flb_event_loop.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/flb_event_loop.c b/src/flb_event_loop.c index e6dd3659f78..c8fe23d6a90 100644 --- a/src/flb_event_loop.c +++ b/src/flb_event_loop.c @@ -20,7 +20,7 @@ #include #include -#include +#include int flb_event_loop_create(flb_ctx_t *ctx) { @@ -86,8 +86,8 @@ int flb_event_loop_destroy(flb_ctx_t *ctx) ctx->event_channel); if (ret != 0) { /* make sure to close file descriptors */ - close(config->ch_notif[0]); - close(config->ch_notif[1]); + mk_event_closesocket(config->ch_notif[0]); + mk_event_closesocket(config->ch_notif[1]); } flb_free(ctx->event_channel); ctx->event_channel = NULL; From 1bb6d3b2664818625405a479f5f42ca4e7eebf30 Mon Sep 17 00:00:00 2001 From: Yuichiro NAITO Date: Mon, 1 Dec 2025 11:21:42 +0900 Subject: [PATCH 7/7] event_loop: Leave file descriptor handling to the monkey library. Signed-off-by: Yuichiro NAITO --- src/flb_event_loop.c | 16 ++++------------ 1 file changed, 4 insertions(+), 12 deletions(-) diff --git a/src/flb_event_loop.c b/src/flb_event_loop.c index c8fe23d6a90..780baf64b64 100644 --- a/src/flb_event_loop.c +++ b/src/flb_event_loop.c @@ -20,8 +20,6 @@ #include #include -#include - int flb_event_loop_create(flb_ctx_t *ctx) { int ret; @@ -72,7 +70,6 @@ int flb_event_loop_create(flb_ctx_t *ctx) int flb_event_loop_destroy(flb_ctx_t *ctx) { - int ret; struct flb_config *config; if (ctx == NULL || ctx->config == NULL) @@ -80,15 +77,10 @@ int flb_event_loop_destroy(flb_ctx_t *ctx) 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 */ - mk_event_closesocket(config->ch_notif[0]); - mk_event_closesocket(config->ch_notif[1]); - } + mk_event_channel_destroy(config->ch_evl, + config->ch_notif[0], + config->ch_notif[1], + ctx->event_channel); flb_free(ctx->event_channel); ctx->event_channel = NULL; }