Skip to content

Commit 60db310

Browse files
alecholmespwhelan
authored andcommitted
in_calyptia_fleet: Only commit fleet config when successfully reloaded
Signed-off-by: Alec Holmes <[email protected]>
1 parent 7798a84 commit 60db310

File tree

4 files changed

+124
-52
lines changed

4 files changed

+124
-52
lines changed

include/fluent-bit/flb_config.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -286,6 +286,7 @@ struct flb_config {
286286
unsigned int hot_reloaded_count;
287287
int shutdown_by_hot_reloading;
288288
int hot_reloading;
289+
int hot_reload_succeeded;
289290

290291
/* Routing */
291292
size_t route_mask_size;

plugins/in_calyptia_fleet/in_calyptia_fleet.c

Lines changed: 121 additions & 52 deletions
Original file line numberDiff line numberDiff line change
@@ -573,34 +573,19 @@ static int is_fleet_config(struct flb_in_calyptia_fleet_config *ctx, struct flb_
573573
is_timestamped_fleet_config(ctx, cfg);
574574
}
575575

576-
static int exists_new_fleet_config(struct flb_in_calyptia_fleet_config *ctx)
576+
static int exists_fleet_config(struct flb_in_calyptia_fleet_config *ctx,
577+
const char *ref_name)
577578
{
578579
int ret = FLB_FALSE;
579-
flb_sds_t cfgnewname;
580-
581-
cfgnewname = fleet_config_deref(ctx, "new");
582-
if (cfgnewname == NULL) {
583-
return FLB_FALSE;
584-
}
585-
586-
ret = access(cfgnewname, F_OK) == 0 ? FLB_TRUE : FLB_FALSE;
587-
flb_sds_destroy(cfgnewname);
588-
589-
return ret;
590-
}
591-
592-
static int exists_old_fleet_config(struct flb_in_calyptia_fleet_config *ctx)
593-
{
594-
int ret = FLB_FALSE;
595-
flb_sds_t cfgoldname;
580+
flb_sds_t config_path;
596581

597-
cfgoldname = fleet_config_deref(ctx, "old");
598-
if (cfgoldname == NULL) {
582+
config_path = fleet_config_deref(ctx, ref_name);
583+
if (config_path == NULL) {
599584
return FLB_FALSE;
600585
}
601586

602-
ret = access(cfgoldname, F_OK) == 0 ? FLB_TRUE : FLB_FALSE;
603-
flb_sds_destroy(cfgoldname);
587+
ret = access(config_path, F_OK) == 0 ? FLB_TRUE : FLB_FALSE;
588+
flb_sds_destroy(config_path);
604589

605590
return ret;
606591
}
@@ -633,13 +618,15 @@ static void *do_reload(void *data)
633618
/* avoid reloading the current configuration... just use our new one! */
634619
flb_context_set(reload->flb);
635620
reload->flb->config->enable_hot_reload = FLB_TRUE;
621+
reload->flb->config->hot_reload_succeeded = FLB_FALSE;
636622
if (reload->flb->config->conf_path_file) {
637623
flb_sds_destroy(reload->flb->config->conf_path_file);
638624
}
639625
reload->flb->config->conf_path_file = reload->cfg_path;
640626

641-
flb_free(reload);
642627
sleep(5);
628+
flb_info("reloading configuration from path: %s", reload->cfg_path);
629+
flb_free(reload);
643630
#ifndef FLB_SYSTEM_WINDOWS
644631
kill(getpid(), SIGHUP);
645632
#else
@@ -1575,50 +1562,67 @@ static int calyptia_config_delete_by_ref(struct flb_in_calyptia_fleet_config *ct
15751562
return FLB_TRUE;
15761563
}
15771564

1578-
15791565
static int calyptia_config_add(struct flb_in_calyptia_fleet_config *ctx,
1580-
const char *cfgname)
1566+
flb_sds_t cfgname)
15811567
{
1582-
flb_sds_t current_config = NULL;
1568+
flb_sds_t derefed_cur_config_path;
1569+
flb_sds_t derefed_new_config_path;
15831570
flb_sds_t cur_ref_filename;
15841571

1585-
current_config = fleet_config_deref(ctx, "new");
1586-
if (current_config == NULL) {
1587-
current_config = fleet_config_deref(ctx, "cur");
1572+
/* Repoint the old ref to the current ref (if it exists) */
1573+
derefed_cur_config_path = fleet_config_deref(ctx, "cur");
1574+
if (derefed_cur_config_path != NULL) {
1575+
if (fleet_config_set_ref(ctx, "old", derefed_cur_config_path) == FLB_FALSE) {
1576+
flb_plg_error(ctx->ins, "unable to move current configuration to old");
1577+
flb_sds_destroy(derefed_cur_config_path);
1578+
return FLB_FALSE;
1579+
}
1580+
1581+
flb_sds_destroy(derefed_cur_config_path);
15881582
}
15891583

1590-
/* If there's a current config, copy it to the old ref file */
1591-
if (current_config != NULL) {
1592-
if (fleet_config_set_ref(ctx, "old", current_config) == FLB_FALSE) {
1593-
flb_sds_destroy(current_config);
1584+
/* If there is uncommitted and different new config, delete it first */
1585+
derefed_new_config_path = fleet_config_deref(ctx, "new");
1586+
if (derefed_new_config_path != NULL
1587+
&& strcmp(derefed_new_config_path, cfgname) != 0) {
1588+
if (calyptia_config_delete_by_ref(ctx, "new") == FLB_FALSE) {
1589+
flb_plg_error(ctx->ins, "unable to delete new configuration by ref");
1590+
flb_sds_destroy(derefed_new_config_path);
15941591
return FLB_FALSE;
15951592
}
15961593
}
1594+
if (derefed_new_config_path != NULL) {
1595+
flb_sds_destroy(derefed_new_config_path);
1596+
}
15971597

15981598
/* Set the new ref file to the new config */
15991599
if (fleet_config_set_ref(ctx, "new", cfgname) == FLB_FALSE) {
1600-
flb_plg_error(ctx->ins, "unable to create new configuration reference.");
1601-
flb_sds_destroy(current_config);
1600+
flb_plg_error(ctx->ins, "unable to set new configuration by ref");
16021601
return FLB_FALSE;
16031602
}
16041603

16051604
/* Delete the current ref file if it exists */
16061605
cur_ref_filename = fleet_config_ref_filename(ctx, "cur");
16071606
if (cur_ref_filename != NULL) {
1607+
flb_plg_info(ctx->ins, "deleting current ref file: %s", cur_ref_filename);
16081608
unlink(cur_ref_filename);
16091609
flb_sds_destroy(cur_ref_filename);
16101610
}
16111611

1612-
flb_sds_destroy(current_config);
16131612
return FLB_TRUE;
16141613
}
16151614

1615+
/**
1616+
* Commits the latest received config as the valid, now-current config.
1617+
* This updates the ref file for the current config file to point to the
1618+
* new config file, and then deletes the old config file.
1619+
*/
16161620
static int calyptia_config_commit(struct flb_in_calyptia_fleet_config *ctx)
16171621
{
16181622
flb_sds_t config_path = NULL;
16191623
flb_sds_t new_ref_filename = NULL;
16201624

1621-
if (exists_new_fleet_config(ctx) == FLB_FALSE) {
1625+
if (exists_fleet_config(ctx, "new") == FLB_FALSE) {
16221626
flb_plg_info(ctx->ins, "no new configuration to commit");
16231627
return FLB_FALSE;
16241628
}
@@ -1637,7 +1641,7 @@ static int calyptia_config_commit(struct flb_in_calyptia_fleet_config *ctx)
16371641
}
16381642

16391643
/* Delete the old config and its ref file */
1640-
if (exists_old_fleet_config(ctx) == FLB_TRUE) {
1644+
if (exists_fleet_config(ctx, "old") == FLB_TRUE) {
16411645
if (calyptia_config_delete_by_ref(ctx, "old") == FLB_FALSE) {
16421646
flb_plg_error(ctx->ins, "unable to delete old configuration by ref");
16431647
return FLB_FALSE;
@@ -1652,8 +1656,11 @@ static int calyptia_config_commit(struct flb_in_calyptia_fleet_config *ctx)
16521656
return FLB_FALSE;
16531657
}
16541658

1659+
flb_plg_info(ctx->ins, "deleting config ref file: %s", new_ref_filename);
16551660
unlink(new_ref_filename);
16561661
flb_sds_destroy(new_ref_filename);
1662+
1663+
flb_plg_info(ctx->ins, "committed new config: %s", config_path);
16571664
flb_sds_destroy(config_path);
16581665

16591666
return FLB_TRUE;
@@ -1665,7 +1672,7 @@ static int calyptia_config_rollback(struct flb_in_calyptia_fleet_config *ctx)
16651672
flb_sds_t old_ref_filename = NULL;
16661673

16671674
/* Delete the new config and its ref file */
1668-
if (exists_new_fleet_config(ctx) == FLB_TRUE) {
1675+
if (exists_fleet_config(ctx, "new") == FLB_TRUE) {
16691676
if (calyptia_config_delete_by_ref(ctx, "new") == FLB_FALSE) {
16701677
flb_plg_error(ctx->ins, "unable to delete new configuration by ref");
16711678
return FLB_FALSE;
@@ -1685,6 +1692,7 @@ static int calyptia_config_rollback(struct flb_in_calyptia_fleet_config *ctx)
16851692
flb_sds_destroy(old_config_path);
16861693
return FLB_FALSE;
16871694
}
1695+
flb_plg_info(ctx->ins, "rolled back to previous config: %s", old_config_path);
16881696
flb_sds_destroy(old_config_path);
16891697

16901698
/* Delete the old config ref */
@@ -1700,6 +1708,51 @@ static int calyptia_config_rollback(struct flb_in_calyptia_fleet_config *ctx)
17001708
return FLB_TRUE;
17011709
}
17021710

1711+
/**
1712+
* Checks if the last config was successfully reloaded and if so, commits it.
1713+
* This considers a newly received config to be successfully reloaded if
1714+
* the current context indicates it was loaded from the new config file.
1715+
*
1716+
* This returns FLB_TRUE (even if the config was not committed) and
1717+
* FLB_FALSE if there was an error.
1718+
*/
1719+
static int commit_config_if_reloaded(struct flb_in_calyptia_fleet_config *ctx)
1720+
{
1721+
struct flb_config *config;
1722+
1723+
/* Get the current configuration */
1724+
config = ctx->ins->config;
1725+
if (config == NULL) {
1726+
return FLB_TRUE;
1727+
}
1728+
1729+
if (config->hot_reloading == FLB_TRUE) {
1730+
return FLB_TRUE;
1731+
}
1732+
1733+
if (config->hot_reload_succeeded != FLB_TRUE) {
1734+
/* The config either hasn't been reloaded yet or the reload failed */
1735+
return FLB_TRUE;
1736+
}
1737+
1738+
/* Check if the current config is from a new fleet config file */
1739+
if (exists_fleet_config(ctx, "new") == FLB_FALSE) {
1740+
return FLB_TRUE;
1741+
}
1742+
1743+
if (is_new_fleet_config(ctx, config)) {
1744+
/* The config was successfully reloaded from the new file, commit it */
1745+
if (calyptia_config_commit(ctx) == FLB_TRUE) {
1746+
flb_plg_info(ctx->ins, "committed reloaded configuration");
1747+
} else {
1748+
flb_plg_error(ctx->ins, "failed to commit reloaded configuration");
1749+
return FLB_FALSE;
1750+
}
1751+
}
1752+
1753+
return FLB_TRUE;
1754+
}
1755+
17031756
static void fleet_config_get_properties(flb_sds_t *buf, struct mk_list *props, int fleet_config_legacy_format)
17041757
{
17051758
struct mk_list *head;
@@ -1985,22 +2038,25 @@ static int in_calyptia_fleet_collect(struct flb_input_instance *ins,
19852038
struct flb_config *config,
19862039
void *in_context)
19872040
{
1988-
int ret = -1;
19892041
struct flb_in_calyptia_fleet_config *ctx = in_context;
19902042

19912043
if (ctx->fleet_id == NULL) {
19922044
if (get_calyptia_fleet_id_by_name(ctx, config) == -1) {
19932045
flb_plg_error(ctx->ins, "unable to find fleet: %s", ctx->fleet_name);
1994-
goto fleet_id_error;
2046+
FLB_INPUT_RETURN(-1);
19952047
}
19962048
}
19972049

1998-
if (get_calyptia_fleet_config(ctx) != FLB_TRUE) {
1999-
ret = -1;
2050+
/* Update symlinks if a recent reload was successful */
2051+
if (commit_config_if_reloaded(ctx) == FLB_FALSE) {
2052+
FLB_INPUT_RETURN(-1);
20002053
}
20012054

2002-
fleet_id_error:
2003-
FLB_INPUT_RETURN(ret);
2055+
if (get_calyptia_fleet_config(ctx) == -1) {
2056+
FLB_INPUT_RETURN(-1);
2057+
}
2058+
2059+
FLB_INPUT_RETURN(0);
20042060
}
20052061

20062062
static int create_fleet_directory(struct flb_in_calyptia_fleet_config *ctx)
@@ -2093,16 +2149,16 @@ static int fleet_cur_chdir(struct flb_in_calyptia_fleet_config *ctx)
20932149
static int load_fleet_config(struct flb_in_calyptia_fleet_config *ctx)
20942150
{
20952151
flb_ctx_t *flb_ctx = flb_context_get();
2096-
flb_sds_t config_path = NULL;
2152+
flb_sds_t config_path;
20972153

20982154
/* check if we are already using the fleet configuration file. */
20992155
if (is_fleet_config(ctx, flb_ctx->config) == FLB_FALSE) {
21002156
flb_plg_debug(ctx->ins, "loading configuration file");
21012157

2102-
/* Find the current config file, or as backup, the new one */
2158+
/* Find the current config file, or as backup, the old one */
21032159
config_path = fleet_config_deref(ctx, "cur");
21042160
if (config_path == NULL) {
2105-
config_path = fleet_config_deref(ctx, "new");
2161+
config_path = fleet_config_deref(ctx, "old");
21062162
}
21072163

21082164
if (config_path != NULL) {
@@ -2359,6 +2415,7 @@ static int in_calyptia_fleet_init(struct flb_input_instance *in,
23592415
int upstream_flags;
23602416
struct flb_in_calyptia_fleet_config *ctx;
23612417
(void) data;
2418+
flb_sds_t new_config_path;
23622419

23632420
#ifdef _WIN32
23642421
char *tmpdir;
@@ -2461,15 +2518,27 @@ static int in_calyptia_fleet_init(struct flb_input_instance *in,
24612518
create_fleet_header(ctx);
24622519
}
24632520

2521+
/* If there is an uncommitted new config, delete it */
2522+
new_config_path = fleet_config_deref(ctx, "new");
2523+
if (new_config_path != NULL
2524+
&& is_new_fleet_config(ctx, config) == FLB_FALSE) {
2525+
flb_plg_warn(ctx->ins, "deleting uncommitted new config: %s", new_config_path);
2526+
if (calyptia_config_delete_by_ref(ctx, "new") == FLB_FALSE) {
2527+
flb_plg_error(ctx->ins, "unable to delete uncommitted new config");
2528+
flb_sds_destroy(new_config_path);
2529+
in_calyptia_fleet_destroy(ctx);
2530+
return -1;
2531+
}
2532+
flb_sds_destroy(new_config_path);
2533+
} else if (new_config_path != NULL) {
2534+
flb_sds_destroy(new_config_path);
2535+
}
2536+
24642537
/* if we load a new configuration then we will be reloaded anyways */
24652538
if (load_fleet_config(ctx) == FLB_TRUE) {
24662539
return 0;
24672540
}
24682541

2469-
if (is_fleet_config(ctx, config)) {
2470-
calyptia_config_commit(ctx);
2471-
}
2472-
24732542
/* Set our collector based on time */
24742543
ret = flb_input_set_collector_time(in,
24752544
in_calyptia_fleet_collect,

src/flb_config.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -307,6 +307,7 @@ struct flb_config *flb_config_init()
307307
config->hot_reloaded_count = 0;
308308
config->shutdown_by_hot_reloading = FLB_FALSE;
309309
config->hot_reloading = FLB_FALSE;
310+
config->hot_reload_succeeded = FLB_FALSE;
310311

311312
#ifdef FLB_SYSTEM_WINDOWS
312313
config->win_maxstdio = 512;

src/flb_reload.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -549,6 +549,7 @@ int flb_reload(flb_ctx_t *ctx, struct flb_cf *cf_opts)
549549
new_config->hot_reloaded_count = reloaded_count;
550550
flb_debug("[reload] hot reloaded %d time(s)", reloaded_count);
551551
new_config->hot_reloading = FLB_FALSE;
552+
new_config->hot_reload_succeeded = FLB_TRUE;
552553

553554
return 0;
554555
}

0 commit comments

Comments
 (0)