diff --git a/src/config_format/flb_cf_fluentbit.c b/src/config_format/flb_cf_fluentbit.c index c9e5ef8e529..8f3ee566161 100644 --- a/src/config_format/flb_cf_fluentbit.c +++ b/src/config_format/flb_cf_fluentbit.c @@ -772,6 +772,7 @@ struct flb_cf *flb_cf_fluentbit_create(struct flb_cf *cf, char *file_path, char *buf, size_t size) { int ret; + int cf_created = FLB_FALSE; struct local_ctx ctx; ino_t ino_table[FLB_CF_FILE_NUM_LIMIT]; int ino_num = 0; @@ -781,13 +782,14 @@ struct flb_cf *flb_cf_fluentbit_create(struct flb_cf *cf, if (!cf) { return NULL; } + cf_created = FLB_TRUE; flb_cf_set_origin_format(cf, FLB_CF_CLASSIC); } ret = local_init(&ctx, file_path); if (ret != 0) { - if (cf) { + if (cf_created == FLB_TRUE) { flb_cf_destroy(cf); } return NULL; @@ -798,7 +800,9 @@ struct flb_cf *flb_cf_fluentbit_create(struct flb_cf *cf, local_exit(&ctx); if (ret == -1) { - flb_cf_destroy(cf); + if (cf_created == FLB_TRUE) { + flb_cf_destroy(cf); + } if (ino_num >= FLB_CF_FILE_NUM_LIMIT) { flb_error("Too many config files. Limit = %d", FLB_CF_FILE_NUM_LIMIT); } diff --git a/src/config_format/flb_cf_yaml.c b/src/config_format/flb_cf_yaml.c index 675ee6dd9e3..f05f2385d20 100644 --- a/src/config_format/flb_cf_yaml.c +++ b/src/config_format/flb_cf_yaml.c @@ -3188,6 +3188,7 @@ struct flb_cf *flb_cf_yaml_create(struct flb_cf *conf, char *file_path, char *buf, size_t size) { int ret; + int conf_created = FLB_FALSE; struct local_ctx ctx; if (!conf) { @@ -3195,6 +3196,7 @@ struct flb_cf *flb_cf_yaml_create(struct flb_cf *conf, char *file_path, if (!conf) { return NULL; } + conf_created = FLB_TRUE; flb_cf_set_origin_format(conf, FLB_CF_YAML); } else { @@ -3205,7 +3207,9 @@ struct flb_cf *flb_cf_yaml_create(struct flb_cf *conf, char *file_path, ret = local_init(&ctx); if (ret == -1) { - flb_cf_destroy(conf); + if (conf_created == FLB_TRUE) { + flb_cf_destroy(conf); + } return NULL; } @@ -3213,7 +3217,9 @@ struct flb_cf *flb_cf_yaml_create(struct flb_cf *conf, char *file_path, ret = read_config(conf, &ctx, NULL, file_path); if (ret == -1) { - flb_cf_destroy(conf); + if (conf_created == FLB_TRUE) { + flb_cf_destroy(conf); + } local_exit(&ctx); return NULL; } diff --git a/src/flb_reload.c b/src/flb_reload.c index 39c1e0d8017..76d38abac68 100644 --- a/src/flb_reload.c +++ b/src/flb_reload.c @@ -466,6 +466,7 @@ int flb_reload(flb_ctx_t *ctx, struct flb_cf *cf_opts) struct flb_config *new_config; flb_ctx_t *new_ctx = NULL; struct flb_cf *new_cf; + struct flb_cf *loaded_cf; struct flb_cf *original_cf; int verbose; int reloaded_count = 0; @@ -551,14 +552,18 @@ int flb_reload(flb_ctx_t *ctx, struct flb_cf *cf_opts) /* Create another config format context */ if (file != NULL) { - new_cf = flb_cf_create_from_file(new_cf, file); + loaded_cf = flb_cf_create_from_file(new_cf, file); - if (!new_cf) { + if (!loaded_cf) { flb_sds_destroy(file); + flb_cf_destroy(new_cf); + flb_destroy(new_ctx); old_config->hot_reloading = FLB_FALSE; flb_reload_watchdog_cleanup(watchdog_ctx); return FLB_RELOAD_HALTED; } + + new_cf = loaded_cf; } /* Load external plugins via command line */ diff --git a/tests/internal/config_format_fluentbit.c b/tests/internal/config_format_fluentbit.c index 3f158573963..b13c91a717e 100644 --- a/tests/internal/config_format_fluentbit.c +++ b/tests/internal/config_format_fluentbit.c @@ -18,6 +18,7 @@ #define FLB_003 FLB_TESTS_DATA_PATH "/data/config_format/classic/recursion.conf" #define FLB_004 FLB_TESTS_DATA_PATH "/data/config_format/classic/issue6281.conf" #define FLB_005 FLB_TESTS_DATA_PATH "/data/config_format/classic/nolimitline.conf" +#define FLB_006 FLB_TESTS_DATA_PATH "/data/config_format/classic/missing_include.conf" #define ERROR_LOG "fluentbit_conf_error.log" @@ -166,7 +167,8 @@ void missing_value() void indent_level_error() { - struct flb_cf *cf; + struct flb_cf *cf; + struct flb_cf *ret; FILE *fp = NULL; char *expected_strs[] = {"invalid", "indent", "level"}; struct str_list expected = { @@ -188,32 +190,29 @@ void indent_level_error() exit(EXIT_FAILURE); } - cf = flb_cf_fluentbit_create(cf, FLB_002, NULL, 0); - TEST_CHECK(cf == NULL); + ret = flb_cf_fluentbit_create(cf, FLB_002, NULL, 0); + TEST_CHECK(ret == NULL); fflush(fp); fclose(fp); fp = fopen(ERROR_LOG, "r"); if (!TEST_CHECK(fp != NULL)) { TEST_MSG("fopen failed. errno=%d path=%s", errno, ERROR_LOG); - if (cf != NULL) { - flb_cf_destroy(cf); - } + flb_cf_destroy(cf); unlink(ERROR_LOG); exit(EXIT_FAILURE); } check_str_list(&expected, fp); - if (cf != NULL) { - flb_cf_destroy(cf); - } + flb_cf_destroy(cf); fclose(fp); unlink(ERROR_LOG); } void recursion() { - struct flb_cf *cf; + struct flb_cf *cf; + struct flb_cf *ret; cf = flb_cf_create(); if (!TEST_CHECK(cf != NULL)) { @@ -221,11 +220,34 @@ void recursion() exit(EXIT_FAILURE); } - cf = flb_cf_fluentbit_create(cf, FLB_003, NULL, 0); + ret = flb_cf_fluentbit_create(cf, FLB_003, NULL, 0); + if (ret != NULL) { + flb_cf_destroy(ret); + } + else { + flb_cf_destroy(cf); + } /* No SIGSEGV means success */ } +void test_caller_owned_error() +{ + struct flb_cf *cf; + struct flb_cf *ret; + + cf = flb_cf_create(); + if (!TEST_CHECK(cf != NULL)) { + TEST_MSG("flb_cf_create failed"); + exit(EXIT_FAILURE); + } + + ret = flb_cf_fluentbit_create(cf, FLB_006, NULL, 0); + TEST_CHECK(ret == NULL); + + flb_cf_destroy(cf); +} + /* * https://github.com/fluent/fluent-bit/issues/6281 @@ -346,6 +368,7 @@ TEST_LIST = { { "missing_value_issue5880" , missing_value}, { "indent_level_error" , indent_level_error}, { "recursion" , recursion}, + { "caller_owned_error" , test_caller_owned_error}, { "not_current_dir_files", not_current_dir_files}, { "no_limit_line", test_nolimit_line}, { "snake_case_key", test_snake_case_key}, diff --git a/tests/internal/config_format_yaml.c b/tests/internal/config_format_yaml.c index 118104407e3..14445314755 100644 --- a/tests/internal/config_format_yaml.c +++ b/tests/internal/config_format_yaml.c @@ -32,6 +32,7 @@ #define FLB_004 FLB_TESTS_CONF_PATH "/stream_processor.yaml" #define FLB_005 FLB_TESTS_CONF_PATH "/plugins.yaml" #define FLB_006 FLB_TESTS_CONF_PATH "/upstream.yaml" +#define FLB_007 FLB_TESTS_CONF_PATH "/missing_include.yaml" #define FLB_000_WIN FLB_TESTS_CONF_PATH "\\fluent-bit-windows.yaml" #define FLB_BROKEN_PLUGIN_VARIANT FLB_TESTS_CONF_PATH "/broken_plugin_variant.yaml" @@ -873,6 +874,23 @@ static void test_invalid_property() } } +static void test_caller_owned_error() +{ + struct flb_cf *cf; + struct flb_cf *ret; + + cf = flb_cf_create(); + if (!TEST_CHECK(cf != NULL)) { + TEST_MSG("flb_cf_create failed"); + exit(EXIT_FAILURE); + } + + ret = flb_cf_yaml_create(cf, FLB_007, NULL, 0); + TEST_CHECK(ret == NULL); + + flb_cf_destroy(cf); +} + TEST_LIST = { { "basic" , test_basic}, { "customs section", test_customs_section}, @@ -887,5 +905,6 @@ TEST_LIST = { { "plugins", test_plugins}, { "upstream_servers", test_upstream_servers}, { "invalid_input_property", test_invalid_property}, + { "caller_owned_error", test_caller_owned_error}, { 0 } }; diff --git a/tests/internal/data/config_format/classic/missing_include.conf b/tests/internal/data/config_format/classic/missing_include.conf new file mode 100644 index 00000000000..7673018aa39 --- /dev/null +++ b/tests/internal/data/config_format/classic/missing_include.conf @@ -0,0 +1 @@ +@INCLUDE missing.conf diff --git a/tests/internal/data/config_format/yaml/missing_include.yaml b/tests/internal/data/config_format/yaml/missing_include.yaml new file mode 100644 index 00000000000..d63f36207d7 --- /dev/null +++ b/tests/internal/data/config_format/yaml/missing_include.yaml @@ -0,0 +1,2 @@ +includes: + - missing.yaml diff --git a/tests/internal/data/reload/yaml/missing_include.yaml b/tests/internal/data/reload/yaml/missing_include.yaml new file mode 100644 index 00000000000..6239a628926 --- /dev/null +++ b/tests/internal/data/reload/yaml/missing_include.yaml @@ -0,0 +1,2 @@ +includes: + - missing_reload_include.yaml diff --git a/tests/internal/reload.c b/tests/internal/reload.c index c4d258c00ee..c56759f9eb9 100644 --- a/tests/internal/reload.c +++ b/tests/internal/reload.c @@ -19,8 +19,9 @@ #include "flb_tests_internal.h" -#define FLB_YAML FLB_TESTS_DATA_PATH "/data/reload/yaml/processor.yaml" -#define FLB_CLASSIC FLB_TESTS_DATA_PATH "/data/reload/fluent-bit.conf" +#define FLB_YAML FLB_TESTS_DATA_PATH "/data/reload/yaml/processor.yaml" +#define FLB_YAML_MISSING_INCLUDE FLB_TESTS_DATA_PATH "/data/reload/yaml/missing_include.yaml" +#define FLB_CLASSIC FLB_TESTS_DATA_PATH "/data/reload/fluent-bit.conf" void test_reconstruct_cf() { @@ -247,6 +248,60 @@ void test_reload_yaml() flb_destroy(ctx); } +/* data/reload/yaml/missing_include.yaml */ +void test_reload_yaml_missing_include() +{ + struct flb_cf *cf = NULL; + struct flb_cf *cf_opts; + struct flb_cf_section *section; + struct cfl_variant *ret; + flb_ctx_t *ctx; + int status; + + cf_opts = flb_cf_create(); + TEST_CHECK(cf_opts != NULL); + + section = flb_cf_section_create(cf_opts, "INPUT", 5); + TEST_CHECK(section != NULL); + + ret = flb_cf_section_property_add(cf_opts, section->properties, "name", 0, "dummy", 0); + TEST_CHECK(ret != NULL); + + ctx = flb_create(); + if (!TEST_CHECK(ctx != NULL)) { + TEST_MSG("flb_create failed"); + exit(EXIT_FAILURE); + } + + cf = ctx->config->cf_main; + + status = flb_reload_reconstruct_cf(cf_opts, cf); + TEST_CHECK(status == 0); + + cf = flb_cf_create_from_file(cf, FLB_YAML); + TEST_CHECK(cf != NULL); + + ctx->config->conf_path_file = flb_sds_create(FLB_YAML); + ctx->config->enable_hot_reload = FLB_TRUE; + + status = flb_config_load_config_format(ctx->config, cf); + TEST_CHECK(status == 0); + + status = flb_start(ctx); + TEST_CHECK(status == 0); + + flb_sds_destroy(ctx->config->conf_path_file); + ctx->config->conf_path_file = flb_sds_create(FLB_YAML_MISSING_INCLUDE); + + status = flb_reload(ctx, cf_opts); + TEST_CHECK(status == FLB_RELOAD_HALTED); + + flb_cf_destroy(cf_opts); + + flb_stop(ctx); + flb_destroy(ctx); +} + /* Test hot reload watchdog timeout functionality */ #ifndef FLB_SYSTEM_WINDOWS void test_reload_watchdog_timeout() @@ -394,6 +449,7 @@ TEST_LIST = { { "reconstruct_cf" , test_reconstruct_cf}, { "reload" , test_reload}, { "reload_yaml" , test_reload_yaml}, + { "reload_yaml_missing_include", test_reload_yaml_missing_include}, { "reload_watchdog_timeout", test_reload_watchdog_timeout}, { 0 } };