From 5a2fcbd2755c916a3b08a3d6e1d93812abba5c04 Mon Sep 17 00:00:00 2001 From: Ilia Petrov Date: Fri, 8 May 2026 09:59:04 +0300 Subject: [PATCH 1/5] kv: add function flb_kv_get_all_key_values The goal of this enhancement is to extend the key-value store API to support retrieving all elements from the linked list in a single call. Currently, the only way to retrieve all elements is to guess the keys and repeatedly call `flb_kv_get_key_value`, which is especially problematic for plugin writers. Signed-off-by: Ilia Petrov --- include/fluent-bit/flb_kv.h | 1 + src/flb_kv.c | 32 ++++++++++++++++++++++++++++++++ 2 files changed, 33 insertions(+) diff --git a/include/fluent-bit/flb_kv.h b/include/fluent-bit/flb_kv.h index 0c4ad82ce1f..84aaabe0c41 100644 --- a/include/fluent-bit/flb_kv.h +++ b/include/fluent-bit/flb_kv.h @@ -41,5 +41,6 @@ struct flb_kv *flb_kv_item_set(struct mk_list *list, void flb_kv_item_destroy(struct flb_kv *kv); void flb_kv_release(struct mk_list *list); const char *flb_kv_get_key_value(const char *key, struct mk_list *list); +struct flb_kv **flb_kv_get_all_key_values(struct mk_list *list); #endif diff --git a/src/flb_kv.c b/src/flb_kv.c index fc3c3545fad..08aa5946a09 100644 --- a/src/flb_kv.c +++ b/src/flb_kv.c @@ -160,3 +160,35 @@ const char *flb_kv_get_key_value(const char *key, struct mk_list *list) return NULL; } + +struct flb_kv **flb_kv_get_all_key_values(struct mk_list *list) +{ + int count; + int i = 0; + struct mk_list *head; + struct flb_kv *kv; + struct flb_kv **arr; + + if (!list) { + return NULL; + } + + count = mk_list_size(list); + if (count == 0) { + return NULL; + } + + arr = flb_calloc(count, sizeof(struct flb_kv *)); + if (!arr) { + flb_errno(); + return NULL; + } + + mk_list_foreach(head, list) { + kv = mk_list_entry(head, struct flb_kv, _head); + arr[i] = kv; + i++; + } + + return arr; +} From 24549d42e29681dec6ee62361839144db0c849b6 Mon Sep 17 00:00:00 2001 From: Ilia Petrov Date: Fri, 8 May 2026 10:12:47 +0300 Subject: [PATCH 2/5] tests: test the new flb_kv_get_all_key_values function Signed-off-by: Ilia Petrov --- tests/internal/kv.c | 37 +++++++++++++++++++++++++++++++++++++ 1 file changed, 37 insertions(+) diff --git a/tests/internal/kv.c b/tests/internal/kv.c index e20d5184692..b95ba198e90 100644 --- a/tests/internal/kv.c +++ b/tests/internal/kv.c @@ -1,6 +1,7 @@ /* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ #include +#include #include "flb_tests_internal.h" static void test_kv_item_set_duplicate() @@ -28,7 +29,43 @@ static void test_kv_item_set_duplicate() flb_kv_release(&list); } +static void test_kv_get_all_key_values() +{ + struct mk_list list; + struct flb_kv **pairs; + + flb_kv_init(&list); + + pairs = flb_kv_get_all_key_values(&list); + TEST_CHECK(pairs == NULL); + + flb_kv_item_set(&list, "host", "localhost"); + flb_kv_item_set(&list, "port", "8080"); + flb_kv_item_set(&list, "path", "/api"); + + pairs = flb_kv_get_all_key_values(&list); + TEST_CHECK(pairs != NULL); + + if (pairs) { + TEST_CHECK(pairs[0] != NULL); + TEST_CHECK(strcmp(pairs[0]->key, "host") == 0); + TEST_CHECK(strcmp(pairs[0]->val, "localhost") == 0); + + TEST_CHECK(pairs[1] != NULL); + TEST_CHECK(strcmp(pairs[1]->key, "port") == 0); + TEST_CHECK(strcmp(pairs[1]->val, "8080") == 0); + + TEST_CHECK(pairs[2] != NULL); + TEST_CHECK(strcmp(pairs[2]->key, "path") == 0); + TEST_CHECK(strcmp(pairs[2]->val, "/api") == 0); + } + + flb_kv_release(&list); + flb_free(pairs); +} + TEST_LIST = { {"kv_item_set_duplicate", test_kv_item_set_duplicate}, + {"kv_get_all_key_values", test_kv_get_all_key_values}, {0} }; From 98978ac1c4e2663ee8f937a00fc31f5eb58fe01c Mon Sep 17 00:00:00 2001 From: Ilia Petrov Date: Fri, 8 May 2026 10:22:36 +0300 Subject: [PATCH 3/5] kv: add out_count parameter to flb_kv_get_all_key_values This out_count parameter is needed so the callers can safely iterate without external assumptions. Signed-off-by: Ilia Petrov --- include/fluent-bit/flb_kv.h | 2 +- src/flb_kv.c | 10 +++++++++- 2 files changed, 10 insertions(+), 2 deletions(-) diff --git a/include/fluent-bit/flb_kv.h b/include/fluent-bit/flb_kv.h index 84aaabe0c41..17213186d51 100644 --- a/include/fluent-bit/flb_kv.h +++ b/include/fluent-bit/flb_kv.h @@ -41,6 +41,6 @@ struct flb_kv *flb_kv_item_set(struct mk_list *list, void flb_kv_item_destroy(struct flb_kv *kv); void flb_kv_release(struct mk_list *list); const char *flb_kv_get_key_value(const char *key, struct mk_list *list); -struct flb_kv **flb_kv_get_all_key_values(struct mk_list *list); +struct flb_kv **flb_kv_get_all_key_values(struct mk_list *list, int *out_count); #endif diff --git a/src/flb_kv.c b/src/flb_kv.c index 08aa5946a09..61464fed81a 100644 --- a/src/flb_kv.c +++ b/src/flb_kv.c @@ -161,7 +161,7 @@ const char *flb_kv_get_key_value(const char *key, struct mk_list *list) return NULL; } -struct flb_kv **flb_kv_get_all_key_values(struct mk_list *list) +struct flb_kv **flb_kv_get_all_key_values(struct mk_list *list, int *out_count) { int count; int i = 0; @@ -169,6 +169,10 @@ struct flb_kv **flb_kv_get_all_key_values(struct mk_list *list) struct flb_kv *kv; struct flb_kv **arr; + if (out_count) { + *out_count = 0; + } + if (!list) { return NULL; } @@ -190,5 +194,9 @@ struct flb_kv **flb_kv_get_all_key_values(struct mk_list *list) i++; } + if (out_count) { + *out_count = count; + } + return arr; } From dd48761bc65b859880997561fa29b157f637b3ff Mon Sep 17 00:00:00 2001 From: Ilia Petrov Date: Fri, 8 May 2026 10:28:10 +0300 Subject: [PATCH 4/5] tests: update the tests for flb_kv_get_all_key_values to use out_count parameter Signed-off-by: Ilia Petrov --- tests/internal/kv.c | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/tests/internal/kv.c b/tests/internal/kv.c index b95ba198e90..e9ca6b1a119 100644 --- a/tests/internal/kv.c +++ b/tests/internal/kv.c @@ -33,18 +33,21 @@ static void test_kv_get_all_key_values() { struct mk_list list; struct flb_kv **pairs; + int count = -1; flb_kv_init(&list); - pairs = flb_kv_get_all_key_values(&list); + pairs = flb_kv_get_all_key_values(&list, &count); TEST_CHECK(pairs == NULL); + TEST_CHECK(count == 0); flb_kv_item_set(&list, "host", "localhost"); flb_kv_item_set(&list, "port", "8080"); flb_kv_item_set(&list, "path", "/api"); - pairs = flb_kv_get_all_key_values(&list); + pairs = flb_kv_get_all_key_values(&list, &count); TEST_CHECK(pairs != NULL); + TEST_CHECK(count == 3); if (pairs) { TEST_CHECK(pairs[0] != NULL); From ff54e1a5a75d6e7e2ebd832b528a25f3fc0b5bf3 Mon Sep 17 00:00:00 2001 From: Ilia Petrov Date: Fri, 8 May 2026 10:30:28 +0300 Subject: [PATCH 5/5] tests: add explicit guards for OOB failure for flb_kv_get_all_key_values Signed-off-by: Ilia Petrov --- tests/internal/kv.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/internal/kv.c b/tests/internal/kv.c index e9ca6b1a119..f630fc5dee0 100644 --- a/tests/internal/kv.c +++ b/tests/internal/kv.c @@ -49,7 +49,7 @@ static void test_kv_get_all_key_values() TEST_CHECK(pairs != NULL); TEST_CHECK(count == 3); - if (pairs) { + if (pairs && count == 3) { TEST_CHECK(pairs[0] != NULL); TEST_CHECK(strcmp(pairs[0]->key, "host") == 0); TEST_CHECK(strcmp(pairs[0]->val, "localhost") == 0);