Skip to content

Conversation

@yuichiro-naito
Copy link

@yuichiro-naito yuichiro-naito commented Nov 17, 2025

Recreate the event loop after daemonizing on BSD platforms.
Because kqueue(2) is not inherited by the child process.

Before reopening, we need to close event channel sockets that were initially created, so as not to leak the sockets. However, the libmonkey interface mk_event_channel_destroy tries to delete sockets from the kqueue. It will fail after daemonizing. We have to call mk_event_channel_destroy before daemonizing.

Fixes #11170


Enter [N/A] in the box, if an item is not applicable to your change.

Testing
Before we can approve your change; please submit the following in a comment:

  • Example configuration file for the change
  • Debug log output from testing the change
  • Attached Valgrind output that shows no leaks or memory corruption was found

If this is a change to packaging of containers or native binaries then please confirm it works for all targets.

  • Run local packaging test showing all targets (including any new ones) build.
  • Set ok-package-test label to test for all targets (requires maintainer to do).

Documentation

  • Documentation required for this feature

Backporting

  • Backport to latest stable release.

Fluent Bit is licensed under Apache 2.0, by submitting this pull request I understand that this code will be released under the terms of that license.

Summary by CodeRabbit

  • New Features

    • Exposes public controls to explicitly create and destroy the event-processing loop.
  • Improvements

    • More consistent cleanup and lifecycle management of event-processing resources for improved stability.
    • Daemon-mode on BSD-family systems now reinitializes event processing after daemonization to reduce runtime issues.
  • Bug Fixes

    • Adds a dedicated error code and user-facing message for event-loop creation failures to aid diagnostics.

✏️ Tip: You can customize this high-level summary in your review settings.

@coderabbitai
Copy link

coderabbitai bot commented Nov 17, 2025

Walkthrough

Added exported APIs flb_event_loop_create() and flb_event_loop_destroy() and moved event-loop setup/teardown into these functions. flb_create() now calls the creator. On BSD daemonize path the event loop is destroyed before fork and recreated after fork; new error code and message for event-loop creation failures were added.

Changes

Cohort / File(s) Change Summary
Public headers
include/fluent-bit/flb_lib.h
Added exported declarations: int flb_event_loop_create(flb_ctx_t *ctx); and int flb_event_loop_destroy(flb_ctx_t *ctx);.
Event-loop implementation
src/flb_event_loop.c
New file implementing flb_event_loop_create() (creates mk_event_loop, allocates ctx->event_channel, creates notification channels) and flb_event_loop_destroy() (destroys channels and event loop with guarded cleanup and resource release).
Core refactor
src/flb_lib.c
Replaced inline event-loop/channel creation in flb_create() with a call to flb_event_loop_create(ctx); preserved existing error handling and failure return paths.
Daemonization (BSD)
src/fluent-bit.c
On FreeBSD/NetBSD/OpenBSD/DragonFly, destroy event loop before daemonizing and recreate it after fork; on recreate failure log error "[daemon] failed to recreate event loop after daemonizing" and follow existing error path.
Error codes & messages
include/fluent-bit/flb_error.h, src/flb_utils.c
Added FLB_ERR_EVENT_LOOP_CREATE and mapped it to message "could not create event loop" in error utilities.
Build system
src/CMakeLists.txt
Added flb_event_loop.c to core source list.

Sequence Diagram(s)

sequenceDiagram
    participant App as Application
    participant Lib as libfluent-bit
    participant OS as Kernel (BSD)

    rect `#DDEFFF`
    Note over App,Lib: Startup
    App->>Lib: flb_create()
    Lib->>Lib: flb_event_loop_create(ctx)
    Lib->>OS: create kqueue / event channel
    end

    rect `#FFEBD9`
    Note over App,Lib: Daemonize (BSD)
    App->>Lib: flb_main_run(daemonize)
    Lib->>Lib: flb_event_loop_destroy(ctx)
    Lib->>OS: fork()
    OS->>OS: child created (kqueue not inherited)
    end

    rect `#E6FFE7`
    Note over Lib,App: Post-fork recovery
    Lib->>Lib: flb_event_loop_create(ctx)
    Lib->>OS: recreate kqueue / event channel
    Lib->>App: resume startup / signal handling
    end
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~25 minutes

  • Inspect resource allocation and cleanup in src/flb_event_loop.c (malloc/free, mk_event_channel create/destroy).
  • Verify BSD daemonize timing and error logging in src/fluent-bit.c.
  • Confirm header export macros in include/fluent-bit/flb_lib.h and CMake inclusion.

Suggested reviewers

  • edsiper

Poem

🐇 I fixed the loop before the leap,

Forked the path where kqueues sleep,
I tore it down and stitched it neat,
Now signals find their way to me,
Hopping onward, tiny paws keep beat.

Pre-merge checks and finishing touches

❌ Failed checks (1 warning)
Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. You can run @coderabbitai generate docstrings to improve docstring coverage.
✅ Passed checks (4 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title accurately describes the main change: recreating the event loop after daemonizing on BSD platforms, which directly addresses the linked issue #11170.
Linked Issues check ✅ Passed The PR successfully implements all coding requirements from issue #11170: extracting event loop creation/destruction into public APIs [flb_event_loop_create, flb_event_loop_destroy], destroying the event loop before daemonizing and recreating it afterward on BSD platforms, adding FLB_ERR_EVENT_LOOP_CREATE error code, and proper resource cleanup.
Out of Scope Changes check ✅ Passed All changes are within scope: extracting event loop management into dedicated functions, adding platform-specific BSD daemonization logic, introducing the related error code, and updating build configuration. No unrelated modifications detected.
✨ Finishing touches
  • 📝 Generate docstrings
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment

📜 Recent review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 9581c8d and 53a212c.

📒 Files selected for processing (1)
  • src/flb_event_loop.c (1 hunks)
🧰 Additional context used
🧠 Learnings (1)
📚 Learning: 2025-11-21T06:23:29.770Z
Learnt from: cosmo0920
Repo: fluent/fluent-bit PR: 11171
File: include/fluent-bit/flb_lib.h:52-53
Timestamp: 2025-11-21T06:23:29.770Z
Learning: In Fluent Bit core (fluent/fluent-bit repository), function descriptions/documentation are not required for newly added functions in header files.

Applied to files:

  • src/flb_event_loop.c
🧬 Code graph analysis (1)
src/flb_event_loop.c (3)
lib/monkey/mk_core/mk_event.c (3)
  • mk_event_loop_create (61-88)
  • mk_event_channel_create (181-190)
  • mk_event_loop_destroy (91-96)
include/fluent-bit/flb_mem.h (2)
  • flb_calloc (84-96)
  • flb_free (126-128)
lib/monkey/include/monkey/mk_core/mk_event.h (1)
  • MK_EVENT_ZERO (135-138)
🔇 Additional comments (2)
src/flb_event_loop.c (2)

25-71: LGTM! Event loop creation logic is sound.

The function correctly handles resource allocation and cleanup:

  • NULL validation prevents invalid access
  • Error labels follow reverse cleanup order (error_2 → error_1 → error_0)
  • config->ch_evl is consistently maintained across all paths (success and failures)
  • All critical issues from past reviews have been properly addressed (error logging, NULL assignments, header includes)

73-103: LGTM! Event loop destruction properly handles the BSD kqueue edge case.

The function is well-designed:

  • Safe NULL checks prevent invalid access
  • The fallback close() on lines 89-90 correctly handles the BSD scenario where mk_event_channel_destroy fails after daemonizing (kqueue no longer valid but fds still need cleanup)
  • All resources are freed and pointers are NULLed, making the function idempotent
  • config->ch_evl lifecycle remains synchronized with ctx->event_loop

This implementation directly addresses the core issue described in the PR objectives.

Tip

📝 Customizable high-level summaries are now available in beta!

You can now customize how CodeRabbit generates the high-level summary in your pull requests — including its content, structure, tone, and formatting.

  • Provide your own instructions using the high_level_summary_instructions setting.
  • Format the summary however you like (bullet lists, tables, multi-section layouts, contributor stats, etc.).
  • Use high_level_summary_in_walkthrough to move the summary from the description to the walkthrough section.

Example instruction:

"Divide the high-level summary into five sections:

  1. 📝 Description — Summarize the main change in 50–60 words, explaining what was done.
  2. 📓 References — List relevant issues, discussions, documentation, or related PRs.
  3. 📦 Dependencies & Requirements — Mention any new/updated dependencies, environment variable changes, or configuration updates.
  4. 📊 Contributor Summary — Include a Markdown table showing contributions:
    | Contributor | Lines Added | Lines Removed | Files Changed |
  5. ✔️ Additional Notes — Add any extra reviewer context.
    Keep each section concise (under 200 words) and use bullet or numbered lists for clarity."

Note: This feature is currently in beta for Pro-tier users, and pricing will be announced later.


Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 3

📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 73d20d0 and 4d12928.

📒 Files selected for processing (3)
  • include/fluent-bit/flb_lib.h (1 hunks)
  • src/flb_lib.c (2 hunks)
  • src/fluent-bit.c (1 hunks)
🧰 Additional context used
🧬 Code graph analysis (3)
include/fluent-bit/flb_lib.h (1)
src/flb_lib.c (2)
  • flb_create_event_loop (143-180)
  • flb_destroy_event_loop (182-205)
src/flb_lib.c (4)
lib/monkey/mk_core/mk_event.c (4)
  • mk_event_loop_create (61-88)
  • mk_event_channel_create (181-190)
  • mk_event_channel_destroy (193-202)
  • mk_event_loop_destroy (91-96)
src/flb_config.c (1)
  • flb_config_exit (488-672)
include/fluent-bit/flb_mem.h (2)
  • flb_free (126-128)
  • flb_calloc (84-96)
lib/monkey/include/monkey/mk_core/mk_event.h (1)
  • MK_EVENT_ZERO (135-138)
src/fluent-bit.c (2)
src/flb_lib.c (2)
  • flb_destroy_event_loop (182-205)
  • flb_create_event_loop (143-180)
src/flb_utils.c (2)
  • flb_utils_set_daemon (178-209)
  • flb_utils_error (69-158)

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 0

🧹 Nitpick comments (3)
src/flb_lib.c (3)

143-187: Good improvements to error handling; consider resetting config->ch_evl on failure.

The function now properly addresses most critical issues from the previous review:

  • NULL validation for ctx is present.
  • Error paths correctly clean up allocated resources via goto labels.
  • No longer calls flb_stop() or flb_destroy() during initialization.
  • Pointers are set to NULL after cleanup.

However, config->ch_evl is assigned on line 158 but is not reset to NULL in the error paths (lines 183-186). If this function returns an error, config->ch_evl will point to freed memory, which could be problematic if any code (other than the immediate caller's cleanup) attempts to use it.

Consider this adjustment:

 error_1:
     mk_event_loop_destroy(ctx->event_loop);
     ctx->event_loop = NULL;
+    config->ch_evl = NULL;
     return FLB_LIB_ERROR;

163-163: Consider removing or adjusting the perror call.

flb_calloc can return NULL without setting errno (particularly in the OSSFUZZ failure-injection path), so perror("calloc") may print a misleading error message.

You can either remove it or replace it with a direct error message:

     ctx->event_channel = flb_calloc(1, sizeof(struct mk_event));
     if (!ctx->event_channel) {
-        perror("calloc");
+        flb_error("[lib] failed to allocate event_channel");
         goto error_1;
     }

189-218: Good defensive NULL checks; minor consistency improvements possible.

The function now properly checks for NULL before freeing/destroying and sets pointers to NULL afterward, addressing the main concerns from the previous review.

A few optional refinements for consistency and defensive programming:

  1. Line 208 uses free() instead of flb_free(), which is inconsistent with the rest of the codebase.
  2. Lines 205-206 close file descriptors without checking if they're valid or resetting them afterward, which could be improved for robustness.

Optional improvements:

         if (ret != 0) {
             /* make sure to close file descriptors */
-            close(config->ch_notif[0]);
-            close(config->ch_notif[1]);
+            if (config->ch_notif[0] >= 0) {
+                close(config->ch_notif[0]);
+                config->ch_notif[0] = -1;
+            }
+            if (config->ch_notif[1] >= 0) {
+                close(config->ch_notif[1]);
+                config->ch_notif[1] = -1;
+            }
         }
-        free(ctx->event_channel);
+        flb_free(ctx->event_channel);
         ctx->event_channel = NULL;
📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 4d12928 and 6aa2773.

📒 Files selected for processing (2)
  • src/flb_lib.c (2 hunks)
  • src/fluent-bit.c (1 hunks)
🚧 Files skipped from review as they are similar to previous changes (1)
  • src/fluent-bit.c
🧰 Additional context used
🧬 Code graph analysis (1)
src/flb_lib.c (3)
lib/monkey/mk_core/mk_event.c (4)
  • mk_event_loop_create (61-88)
  • mk_event_channel_create (181-190)
  • mk_event_loop_destroy (91-96)
  • mk_event_channel_destroy (193-202)
include/fluent-bit/flb_mem.h (2)
  • flb_calloc (84-96)
  • flb_free (126-128)
lib/monkey/include/monkey/mk_core/mk_event.h (1)
  • MK_EVENT_ZERO (135-138)
🔇 Additional comments (1)
src/flb_lib.c (1)

264-269: LGTM! Clean integration of the new event loop creation API.

The refactoring successfully delegates event loop setup to flb_create_event_loop() and handles failures appropriately by cleaning up the config and context before returning NULL.

@cosmo0920
Copy link
Contributor

@coderabbitai review

@coderabbitai
Copy link

coderabbitai bot commented Nov 18, 2025

✅ Actions performed

Review triggered.

Note: CodeRabbit is an incremental review system and does not re-review already reviewed commits. This command is applicable only when automatic reviews are paused.

@cosmo0920
Copy link
Contributor

The patches are really good but we need to add Signed-off line on each of commit.
So, could you follow the instructions on this? https://github.com/fluent/fluent-bit/pull/11171/checks?check_run_id=55564201840

@cosmo0920 cosmo0920 changed the title Recreate the event loop after daemonizing on BSD platforms. lib: Recreate the event loop after daemonizing on BSD platforms. Nov 18, 2025
@yuichiro-naito
Copy link
Author

I rebased my patch to master and squashed 2 commits into 1 commit.
I wrote the category name in the commit message, and also added 'Signed-off-by'.

@yuichiro-naito
Copy link
Author

I updated the category in the commit message to 'lib:'.

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 0

🧹 Nitpick comments (1)
include/fluent-bit/flb_lib.h (1)

52-53: LGTM! Consider adding API documentation for these lifecycle functions.

The new public APIs are well-designed and correctly solve the BSD kqueue inheritance issue. The function signatures are consistent with the existing API, and the implementations (from the code snippets) show proper error handling and resource cleanup.

However, since these functions expose event loop lifecycle management as part of the public API, brief documentation would help library users understand:

  • When these functions should be called (e.g., around fork on BSD platforms)
  • Return value semantics (0 for success, FLB_LIB_ERROR/-1 for failure)
  • Relationship with flb_create()/flb_destroy() (typically not needed unless forking)

This suggestion is optional since the existing header style generally omits function documentation.

📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 403a863 and 971f916.

📒 Files selected for processing (3)
  • include/fluent-bit/flb_lib.h (1 hunks)
  • src/flb_lib.c (2 hunks)
  • src/fluent-bit.c (1 hunks)
🚧 Files skipped from review as they are similar to previous changes (2)
  • src/flb_lib.c
  • src/fluent-bit.c
🧰 Additional context used
🧬 Code graph analysis (1)
include/fluent-bit/flb_lib.h (1)
src/flb_lib.c (2)
  • flb_create_event_loop (143-187)
  • flb_destroy_event_loop (189-218)

@yuichiro-naito
Copy link
Author

I updated my patch to introduce a new error code 'FLB_ERR_EVENT_LOOP_CREATE'.
And also change to use flb_free function instead of free.

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 971f916 and 03625d7.

📒 Files selected for processing (5)
  • include/fluent-bit/flb_error.h (1 hunks)
  • include/fluent-bit/flb_lib.h (1 hunks)
  • src/flb_lib.c (2 hunks)
  • src/flb_utils.c (1 hunks)
  • src/fluent-bit.c (1 hunks)
🚧 Files skipped from review as they are similar to previous changes (2)
  • src/flb_lib.c
  • src/fluent-bit.c
🧰 Additional context used
🧬 Code graph analysis (1)
include/fluent-bit/flb_lib.h (1)
src/flb_lib.c (2)
  • flb_create_event_loop (143-187)
  • flb_destroy_event_loop (189-218)
🔇 Additional comments (2)
include/fluent-bit/flb_error.h (1)

29-29: LGTM!

The new error code FLB_ERR_EVENT_LOOP_CREATE is properly defined with value 30, following the existing naming convention and leaving room for future flush-related error codes.

src/flb_utils.c (1)

92-94: LGTM!

The error handling for FLB_ERR_EVENT_LOOP_CREATE is properly integrated into the switch statement with a clear error message. Since this error code (30) is below FLB_ERR_FILTER_INVALID (201), the function will call exit(EXIT_FAILURE) at line 159, which is appropriate for a critical event loop creation failure.

@edsiper
Copy link
Member

edsiper commented Nov 21, 2025

I recommend implementing a src/flb_event_loop.c with these new function calls which names are prefixed with flb_event_loop_SOMETHING();

@yuichiro-naito
Copy link
Author

I renamed the function names to flb_event_loop_* and moved them to the new file flb_event_loop.c. And added the source file name to CMakeLists.txt.
The prototypes are still written in flb_lib.h. The flb_event_loop.h file already exists and seems to be used for a different purpose.

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 03625d7 and 42ec95b.

📒 Files selected for processing (5)
  • include/fluent-bit/flb_lib.h (1 hunks)
  • src/CMakeLists.txt (1 hunks)
  • src/flb_event_loop.c (1 hunks)
  • src/flb_lib.c (1 hunks)
  • src/fluent-bit.c (1 hunks)
🚧 Files skipped from review as they are similar to previous changes (1)
  • src/fluent-bit.c
🧰 Additional context used
🧠 Learnings (10)
📚 Learning: 2025-11-21T06:23:29.770Z
Learnt from: cosmo0920
Repo: fluent/fluent-bit PR: 11171
File: include/fluent-bit/flb_lib.h:52-53
Timestamp: 2025-11-21T06:23:29.770Z
Learning: In Fluent Bit core (fluent/fluent-bit repository), function descriptions/documentation are not required for newly added functions in header files.

Applied to files:

  • include/fluent-bit/flb_lib.h
📚 Learning: 2025-08-31T12:46:11.940Z
Learnt from: ThomasDevoogdt
Repo: fluent/fluent-bit PR: 9277
File: .github/workflows/pr-compile-check.yaml:147-151
Timestamp: 2025-08-31T12:46:11.940Z
Learning: In fluent-bit CMakeLists.txt, the system library preference flags are defined as FLB_PREFER_SYSTEM_LIB_ZSTD and FLB_PREFER_SYSTEM_LIB_KAFKA with the FLB_ prefix.

Applied to files:

  • include/fluent-bit/flb_lib.h
📚 Learning: 2025-08-31T12:46:11.940Z
Learnt from: ThomasDevoogdt
Repo: fluent/fluent-bit PR: 9277
File: .github/workflows/pr-compile-check.yaml:147-151
Timestamp: 2025-08-31T12:46:11.940Z
Learning: In fluent-bit, the correct CMake flag for using system librdkafka is `FLB_PREFER_SYSTEM_LIB_KAFKA=ON`.

Applied to files:

  • include/fluent-bit/flb_lib.h
📚 Learning: 2025-08-29T06:25:27.250Z
Learnt from: shadowshot-x
Repo: fluent/fluent-bit PR: 10794
File: tests/internal/aws_compress.c:93-107
Timestamp: 2025-08-29T06:25:27.250Z
Learning: In Fluent Bit, ZSTD compression is enabled by default and is treated as a core dependency, not requiring conditional compilation guards like `#ifdef FLB_HAVE_ZSTD`. Unlike some other optional components such as ARROW/PARQUET (which use `#ifdef FLB_HAVE_ARROW` guards), ZSTD support is always available and doesn't need build-time conditionals. ZSTD headers are included directly without guards across multiple plugins and core components.

Applied to files:

  • include/fluent-bit/flb_lib.h
📚 Learning: 2025-08-29T06:25:27.250Z
Learnt from: shadowshot-x
Repo: fluent/fluent-bit PR: 10794
File: tests/internal/aws_compress.c:93-107
Timestamp: 2025-08-29T06:25:27.250Z
Learning: In Fluent Bit, ZSTD compression is enabled by default and is treated as a core dependency, not requiring conditional compilation guards like `#ifdef FLB_HAVE_ZSTD`. Unlike some other optional components, ZSTD support is always available and doesn't need build-time conditionals.

Applied to files:

  • include/fluent-bit/flb_lib.h
📚 Learning: 2025-08-29T06:24:26.170Z
Learnt from: shadowshot-x
Repo: fluent/fluent-bit PR: 10794
File: tests/internal/aws_compress.c:39-42
Timestamp: 2025-08-29T06:24:26.170Z
Learning: In Fluent Bit, ZSTD compression support is enabled by default and does not require conditional compilation guards (like #ifdef FLB_HAVE_ZSTD) around ZSTD-related code declarations and implementations.

Applied to files:

  • include/fluent-bit/flb_lib.h
📚 Learning: 2025-09-04T07:28:37.083Z
Learnt from: cosmo0920
Repo: fluent/fluent-bit PR: 10832
File: src/wasm/CMakeLists.txt:112-131
Timestamp: 2025-09-04T07:28:37.083Z
Learning: In fluent-bit CMake files, the user cosmo0920 prefers treating Git as a command rather than a package, emphasizing that Git is not a pkg-config retrievable package but just a command.

Applied to files:

  • include/fluent-bit/flb_lib.h
📚 Learning: 2025-08-29T06:24:55.855Z
Learnt from: shadowshot-x
Repo: fluent/fluent-bit PR: 10794
File: src/aws/flb_aws_compress.c:52-56
Timestamp: 2025-08-29T06:24:55.855Z
Learning: ZSTD compression is always available in Fluent Bit and does not require conditional compilation guards. Unlike Arrow/Parquet which use #ifdef FLB_HAVE_ARROW guards, ZSTD is built unconditionally with flb_zstd.c included directly in src/CMakeLists.txt and a bundled ZSTD library at lib/zstd-1.5.7/.

Applied to files:

  • include/fluent-bit/flb_lib.h
📚 Learning: 2025-08-29T06:25:02.561Z
Learnt from: shadowshot-x
Repo: fluent/fluent-bit PR: 10794
File: tests/internal/aws_compress.c:7-7
Timestamp: 2025-08-29T06:25:02.561Z
Learning: In Fluent Bit, ZSTD (zstandard) compression library is bundled directly in the source tree at `lib/zstd-1.5.7` and is built unconditionally as a static library. Unlike optional external dependencies, ZSTD does not use conditional compilation guards like `FLB_HAVE_ZSTD` and is always available. Headers like `<fluent-bit/flb_zstd.h>` can be included directly without guards.

Applied to files:

  • include/fluent-bit/flb_lib.h
📚 Learning: 2025-08-29T06:24:44.797Z
Learnt from: shadowshot-x
Repo: fluent/fluent-bit PR: 10794
File: src/aws/flb_aws_compress.c:26-26
Timestamp: 2025-08-29T06:24:44.797Z
Learning: In Fluent Bit, ZSTD support is always available and enabled by default. The build system automatically detects and uses either the system libzstd library or builds the bundled ZSTD version. Unlike other optional dependencies like Arrow which use conditional compilation guards (e.g., FLB_HAVE_ARROW), ZSTD does not require conditional includes or build flags.

Applied to files:

  • include/fluent-bit/flb_lib.h
🧬 Code graph analysis (3)
src/flb_event_loop.c (3)
lib/monkey/mk_core/mk_event.c (4)
  • mk_event_loop_create (61-88)
  • mk_event_channel_create (181-190)
  • mk_event_loop_destroy (91-96)
  • mk_event_channel_destroy (193-202)
include/fluent-bit/flb_mem.h (2)
  • flb_calloc (84-96)
  • flb_free (126-128)
lib/monkey/include/monkey/mk_core/mk_event.h (1)
  • MK_EVENT_ZERO (135-138)
src/flb_lib.c (1)
src/flb_event_loop.c (1)
  • flb_event_loop_create (23-67)
include/fluent-bit/flb_lib.h (1)
src/flb_event_loop.c (2)
  • flb_event_loop_create (23-67)
  • flb_event_loop_destroy (69-98)
🔇 Additional comments (5)
src/flb_event_loop.c (2)

23-67: LGTM! Proper error handling and resource cleanup.

The function correctly validates inputs, handles allocation failures, and ensures all error paths properly clean up resources and null pointers. The goto-based error handling pattern is appropriate for resource cleanup chains.


69-98: LGTM! All previous review concerns addressed.

The function now has:

  • Proper NULL checks for ctx and ctx->config
  • Defensive NULL checks before destroying resources
  • Consistent use of flb_free() instead of free()
  • Proper pointer nulling after cleanup
  • Defensive FD closing when mk_event_channel_destroy fails

Excellent defensive programming.

src/flb_lib.c (1)

187-192: LGTM! Clean integration of the new event loop lifecycle API.

The refactoring properly delegates event loop creation to the new flb_event_loop_create() function while maintaining the existing error handling behavior.

src/CMakeLists.txt (1)

11-11: LGTM! Correct build integration.

The new event loop source file is properly added to the Core Source set.

include/fluent-bit/flb_lib.h (1)

52-53: LGTM! Proper public API declarations.

The new event loop lifecycle functions are correctly declared and exported. Based on learnings, function documentation is not required for newly added functions in Fluent Bit core.

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🧹 Nitpick comments (1)
src/flb_event_loop.c (1)

23-67: Consider using flb_error() instead of perror().

Line 43 uses perror("calloc") which writes directly to stderr. For consistency with the rest of the codebase and better integration with Fluent Bit's logging system, consider using flb_error() instead.

Apply this diff:

     ctx->event_channel = flb_calloc(1, sizeof(struct mk_event));
     if (!ctx->event_channel) {
-        perror("calloc");
+        flb_error("[lib] could not allocate memory for event channel");
         goto error_1;
     }
📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 42ec95b and 2a09157.

📒 Files selected for processing (5)
  • include/fluent-bit/flb_lib.h (1 hunks)
  • src/CMakeLists.txt (1 hunks)
  • src/flb_event_loop.c (1 hunks)
  • src/flb_lib.c (1 hunks)
  • src/fluent-bit.c (1 hunks)
🚧 Files skipped from review as they are similar to previous changes (3)
  • src/flb_lib.c
  • src/CMakeLists.txt
  • include/fluent-bit/flb_lib.h
🧰 Additional context used
🧠 Learnings (4)
📚 Learning: 2025-11-21T06:23:29.770Z
Learnt from: cosmo0920
Repo: fluent/fluent-bit PR: 11171
File: include/fluent-bit/flb_lib.h:52-53
Timestamp: 2025-11-21T06:23:29.770Z
Learning: In Fluent Bit core (fluent/fluent-bit repository), function descriptions/documentation are not required for newly added functions in header files.

Applied to files:

  • src/flb_event_loop.c
  • src/fluent-bit.c
📚 Learning: 2025-09-04T12:35:22.872Z
Learnt from: shadowshot-x
Repo: fluent/fluent-bit PR: 10825
File: plugins/out_s3/s3.c:1339-1344
Timestamp: 2025-09-04T12:35:22.872Z
Learning: In the Fluent Bit S3 plugin, the user prefers to maintain current retry_limit behavior without special handling for FLB_OUT_RETRY_UNLIMITED (-1), as there's no documentation indicating -1 should be used for infinite retries and consistency with current logic is preferred.

Applied to files:

  • src/fluent-bit.c
📚 Learning: 2025-09-04T12:35:36.904Z
Learnt from: shadowshot-x
Repo: fluent/fluent-bit PR: 10825
File: plugins/out_s3/s3.c:3275-3282
Timestamp: 2025-09-04T12:35:36.904Z
Learning: The out_s3 plugin intentionally uses a simple numeric comparison for retry_limit (chunk->failures >= ctx->ins->retry_limit) rather than the standard Fluent Bit pattern that checks for FLB_OUT_RETRY_UNLIMITED (-1). The maintainer wants to keep this current behavior for consistency within the plugin.

Applied to files:

  • src/fluent-bit.c
📚 Learning: 2025-09-04T12:32:46.030Z
Learnt from: shadowshot-x
Repo: fluent/fluent-bit PR: 10825
File: plugins/out_s3/s3.c:0-0
Timestamp: 2025-09-04T12:32:46.030Z
Learning: In Fluent Bit plugins, avoid creating plugin-local config_map entries that duplicate core functionality. The core already provides Retry_Limit parsed into ins->retry_limit, so plugins should use that directly rather than defining their own retry_limit configuration option.

Applied to files:

  • src/fluent-bit.c
🧬 Code graph analysis (2)
src/flb_event_loop.c (3)
lib/monkey/mk_core/mk_event.c (4)
  • mk_event_loop_create (61-88)
  • mk_event_channel_create (181-190)
  • mk_event_loop_destroy (91-96)
  • mk_event_channel_destroy (193-202)
include/fluent-bit/flb_mem.h (2)
  • flb_calloc (84-96)
  • flb_free (126-128)
lib/monkey/include/monkey/mk_core/mk_event.h (1)
  • MK_EVENT_ZERO (135-138)
src/fluent-bit.c (2)
src/flb_event_loop.c (2)
  • flb_event_loop_destroy (69-98)
  • flb_event_loop_create (23-67)
src/flb_utils.c (1)
  • flb_utils_set_daemon (181-212)
🔇 Additional comments (1)
src/fluent-bit.c (1)

1418-1429: LGTM! BSD event loop recreation logic is correct.

The implementation correctly addresses the BSD-specific issue where kqueue(2) file descriptors are not inherited across fork(). Destroying the event loop before daemonizing and recreating it after ensures the child process has a valid event loop.

This file contains 'flb_event_loop_*' functions.

Signed-off-by: Yuichiro NAITO <[email protected]>
Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 0

🧹 Nitpick comments (2)
src/flb_event_loop.c (2)

30-33: Add NULL check for ctx->config before dereferencing.

Line 33 dereferences ctx->config without verifying it's not NULL. While flb_create() sets ctx->config before calling this function, defensive programming would add validation here for safety when the function is called from other contexts (e.g., BSD daemonization path after flb_event_loop_destroy).

     if (ctx == NULL)
         return FLB_LIB_ERROR;

+    if (ctx->config == NULL)
+        return FLB_LIB_ERROR;
+
     config = ctx->config;

79-97: Consider clearing config->ch_evl for consistency.

In flb_event_loop_create(), config->ch_evl is assigned the event loop pointer (line 40). For symmetry and to avoid a dangling pointer, consider clearing it in the destroy path.

     if (ctx->event_loop != NULL) {
         mk_event_loop_destroy(ctx->event_loop);
         ctx->event_loop = NULL;
+        config->ch_evl = NULL;
     }
📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 2a09157 and 21f3c59.

📒 Files selected for processing (5)
  • include/fluent-bit/flb_lib.h (1 hunks)
  • src/CMakeLists.txt (1 hunks)
  • src/flb_event_loop.c (1 hunks)
  • src/flb_lib.c (1 hunks)
  • src/fluent-bit.c (1 hunks)
🚧 Files skipped from review as they are similar to previous changes (2)
  • src/CMakeLists.txt
  • include/fluent-bit/flb_lib.h
🧰 Additional context used
🧠 Learnings (4)
📚 Learning: 2025-11-21T06:23:29.770Z
Learnt from: cosmo0920
Repo: fluent/fluent-bit PR: 11171
File: include/fluent-bit/flb_lib.h:52-53
Timestamp: 2025-11-21T06:23:29.770Z
Learning: In Fluent Bit core (fluent/fluent-bit repository), function descriptions/documentation are not required for newly added functions in header files.

Applied to files:

  • src/flb_event_loop.c
  • src/fluent-bit.c
📚 Learning: 2025-09-04T12:35:22.872Z
Learnt from: shadowshot-x
Repo: fluent/fluent-bit PR: 10825
File: plugins/out_s3/s3.c:1339-1344
Timestamp: 2025-09-04T12:35:22.872Z
Learning: In the Fluent Bit S3 plugin, the user prefers to maintain current retry_limit behavior without special handling for FLB_OUT_RETRY_UNLIMITED (-1), as there's no documentation indicating -1 should be used for infinite retries and consistency with current logic is preferred.

Applied to files:

  • src/fluent-bit.c
📚 Learning: 2025-09-04T12:35:36.904Z
Learnt from: shadowshot-x
Repo: fluent/fluent-bit PR: 10825
File: plugins/out_s3/s3.c:3275-3282
Timestamp: 2025-09-04T12:35:36.904Z
Learning: The out_s3 plugin intentionally uses a simple numeric comparison for retry_limit (chunk->failures >= ctx->ins->retry_limit) rather than the standard Fluent Bit pattern that checks for FLB_OUT_RETRY_UNLIMITED (-1). The maintainer wants to keep this current behavior for consistency within the plugin.

Applied to files:

  • src/fluent-bit.c
📚 Learning: 2025-09-04T12:32:46.030Z
Learnt from: shadowshot-x
Repo: fluent/fluent-bit PR: 10825
File: plugins/out_s3/s3.c:0-0
Timestamp: 2025-09-04T12:32:46.030Z
Learning: In Fluent Bit plugins, avoid creating plugin-local config_map entries that duplicate core functionality. The core already provides Retry_Limit parsed into ins->retry_limit, so plugins should use that directly rather than defining their own retry_limit configuration option.

Applied to files:

  • src/fluent-bit.c
🧬 Code graph analysis (2)
src/flb_lib.c (1)
src/flb_event_loop.c (1)
  • flb_event_loop_create (25-69)
src/fluent-bit.c (2)
src/flb_event_loop.c (2)
  • flb_event_loop_destroy (71-100)
  • flb_event_loop_create (25-69)
src/flb_utils.c (2)
  • flb_utils_set_daemon (181-212)
  • flb_utils_error (69-161)
🔇 Additional comments (3)
src/flb_lib.c (1)

187-192: Clean refactoring of event loop creation.

The delegation to flb_event_loop_create(ctx) properly encapsulates the event loop setup logic. Error handling correctly cleans up ctx->config and ctx before returning NULL, maintaining the original behavior.

src/flb_event_loop.c (1)

25-69: Event loop creation implementation looks solid.

The function properly:

  • Uses goto-based cleanup for error paths
  • Frees allocated resources and nulls pointers on failure
  • Returns appropriate error codes

The error handling pattern is clean and prevents resource leaks.

src/fluent-bit.c (1)

1418-1429: BSD daemonization fix is correct and verified.

The ch_evl synchronization is properly handled:

  • Parent process exits at line 191 of flb_utils.c immediately after fork
  • Child process continues and reassigns config->ch_evl in flb_event_loop_create() before any use
  • No dangling pointer issue exists because the parent terminates before it could reference the destroyed event loop

Set NULL for the 'ch_evl' member after destroying.

Signed-off-by: Yuichiro NAITO <[email protected]>
Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🧹 Nitpick comments (1)
src/flb_event_loop.c (1)

36-36: Consider defining a named constant for the event loop size.

The magic number 256 for the event loop size reduces readability. Consider defining a constant like FLB_EVENT_LOOP_SIZE or similar to make the code more maintainable.

Example:

+#define FLB_EVENT_LOOP_SIZE 256
+
 int flb_event_loop_create(flb_ctx_t *ctx)
 {
     ...
-    ctx->event_loop = mk_event_loop_create(256);
+    ctx->event_loop = mk_event_loop_create(FLB_EVENT_LOOP_SIZE);
📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 21f3c59 and 5ce38c3.

📒 Files selected for processing (1)
  • src/flb_event_loop.c (1 hunks)
🧰 Additional context used
🧠 Learnings (1)
📚 Learning: 2025-11-21T06:23:29.770Z
Learnt from: cosmo0920
Repo: fluent/fluent-bit PR: 11171
File: include/fluent-bit/flb_lib.h:52-53
Timestamp: 2025-11-21T06:23:29.770Z
Learning: In Fluent Bit core (fluent/fluent-bit repository), function descriptions/documentation are not required for newly added functions in header files.

Applied to files:

  • src/flb_event_loop.c
🔇 Additional comments (3)
src/flb_event_loop.c (3)

1-24: LGTM! Includes are appropriate.

The header includes all necessary dependencies: flb_lib.h for context types, flb_mem.h for memory functions, and unistd.h for close().


85-89: Excellent defensive cleanup for the BSD kqueue issue.

The manual close() calls when mk_event_channel_destroy fails are essential for the BSD fork scenario. When the kqueue becomes invalid after daemonizing, mk_event_channel_destroy will fail but the file descriptors still need to be closed to prevent leaks.


71-101: Consider propagating destroy failures to the caller.

The function always returns 0 (success) even when mk_event_channel_destroy fails (line 85). While best-effort cleanup is often appropriate for destroy functions, returning success might hide issues from callers who expect to be notified of cleanup problems. Consider whether callers need to know about partial failures.

If error propagation is desired, you could:

 int flb_event_loop_destroy(flb_ctx_t *ctx)
 {
     int ret;
+    int failed = 0;
     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]);
+            failed = 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;
+    return failed ? FLB_LIB_ERROR : 0;
 }

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🧹 Nitpick comments (1)
src/flb_event_loop.c (1)

80-90: Optionally log mk_event_channel_destroy failures for easier debugging

In flb_event_loop_destroy, if mk_event_channel_destroy fails you close the FDs directly, which is good for resource safety, but the failure is silent. Given how tricky kqueue/daemonization issues can be, a log here would help operational debugging without changing behavior:

     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 */
+            flb_error("[lib] could not destroy notification channels, closing fds directly");
+            /* make sure to close file descriptors */
             close(config->ch_notif[0]);
             close(config->ch_notif[1]);
         }

Purely a diagnostics improvement; feel free to skip if you want to keep teardown quieter.

📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 5ce38c3 and 9581c8d.

📒 Files selected for processing (1)
  • src/flb_event_loop.c (1 hunks)
🧰 Additional context used
🧠 Learnings (1)
📚 Learning: 2025-11-21T06:23:29.770Z
Learnt from: cosmo0920
Repo: fluent/fluent-bit PR: 11171
File: include/fluent-bit/flb_lib.h:52-53
Timestamp: 2025-11-21T06:23:29.770Z
Learning: In Fluent Bit core (fluent/fluent-bit repository), function descriptions/documentation are not required for newly added functions in header files.

Applied to files:

  • src/flb_event_loop.c

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Fluent-bit doesn't stop while running in background mode on BSD platforms

3 participants