Skip to content

Commit 41903a5

Browse files
committed
out_logrotate: Validate max_files configuration in out_logrotate and improve directory creation and rotation logic.
Signed-off-by: SagiROosto <[email protected]>
1 parent 74082a9 commit 41903a5

File tree

2 files changed

+78
-1
lines changed

2 files changed

+78
-1
lines changed

plugins/out_logrotate/logrotate.c

Lines changed: 25 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -200,6 +200,12 @@ static int cb_logrotate_init(struct flb_output_instance *ins,
200200
ctx->gzip == FLB_TRUE ? "true" : "false",
201201
ctx->out_path ? ctx->out_path : "not set");
202202

203+
if (ctx->max_files <= 0) {
204+
flb_plg_error(ctx->ins, "invalid max_files=%d; must be >= 1", ctx->max_files);
205+
flb_free(ctx);
206+
return -1;
207+
}
208+
203209
return 0;
204210
}
205211

@@ -511,6 +517,11 @@ static int mkpath(struct flb_output_instance *ins, const char *dir)
511517
}
512518
flb_plg_debug(ins, "creating directory %s", dup_dir);
513519
ret = mkdir(dup_dir, 0755);
520+
if (ret == -1 && errno == EEXIST) {
521+
if (stat(dup_dir, &st) == 0 && S_ISDIR(st.st_mode)) {
522+
ret = 0;
523+
}
524+
}
514525
flb_free(dup_dir);
515526
return ret;
516527
#else
@@ -524,7 +535,13 @@ static int mkpath(struct flb_output_instance *ins, const char *dir)
524535
return ret;
525536
}
526537
flb_plg_debug(ins, "creating directory %s", dir);
527-
return mkdir(dir, 0755);
538+
ret = mkdir(dir, 0755);
539+
if (ret == -1 && errno == EEXIST) {
540+
if (stat(dir, &st) == 0 && S_ISDIR(st.st_mode)) {
541+
ret = 0;
542+
}
543+
}
544+
return ret;
528545
#endif
529546
}
530547

@@ -875,6 +892,13 @@ static int rotate_file(struct flb_logrotate_conf *ctx, const char *filename)
875892
return -1;
876893
}
877894
lock_acquired = 1;
895+
896+
/* Check if rotation is still needed (race condition check) */
897+
if (file_size < ctx->max_size) {
898+
flb_lock_release(&entry->lock, FLB_LOCK_DEFAULT_RETRY_LIMIT,
899+
FLB_LOCK_DEFAULT_RETRY_DELAY);
900+
return 0;
901+
}
878902
}
879903

880904
/* Log rotation event */

tests/runtime/out_logrotate.c

Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@
2323
void flb_test_logrotate_basic_rotation(void);
2424
void flb_test_logrotate_gzip_compression(void);
2525
void flb_test_logrotate_max_files_cleanup(void);
26+
void flb_test_logrotate_max_files_validation(void);
2627
void flb_test_logrotate_format_csv(void);
2728
void flb_test_logrotate_format_ltsv(void);
2829
void flb_test_logrotate_format_plain(void);
@@ -40,6 +41,7 @@ TEST_LIST = {
4041
{"basic_rotation", flb_test_logrotate_basic_rotation},
4142
{"gzip_compression", flb_test_logrotate_gzip_compression},
4243
{"max_files_cleanup", flb_test_logrotate_max_files_cleanup},
44+
{"max_files_validation", flb_test_logrotate_max_files_validation},
4345
{"format_csv", flb_test_logrotate_format_csv},
4446
{"format_ltsv", flb_test_logrotate_format_ltsv},
4547
{"format_plain", flb_test_logrotate_format_plain},
@@ -1272,3 +1274,54 @@ void flb_test_logrotate_max_files_cleanup(void)
12721274
/* Clean up directory and all contents */
12731275
recursive_delete_directory(TEST_LOGPATH);
12741276
}
1277+
1278+
void flb_test_logrotate_max_files_validation(void)
1279+
{
1280+
flb_ctx_t *ctx;
1281+
int out_ffd;
1282+
char logfile[512];
1283+
1284+
/* Clean up any existing directory and contents */
1285+
recursive_delete_directory(TEST_LOGPATH);
1286+
mkdir(TEST_LOGPATH, 0755);
1287+
snprintf(logfile, sizeof(logfile), "%s/%s", TEST_LOGPATH, TEST_LOGFILE);
1288+
1289+
ctx = flb_create();
1290+
TEST_ASSERT(flb_service_set(ctx, "Flush", "1", "Grace", "1",
1291+
"Log_Level", "error", NULL) == 0);
1292+
1293+
/* Test with max_files = 0 */
1294+
out_ffd = flb_output(ctx, (char *) "logrotate", NULL);
1295+
TEST_CHECK(out_ffd >= 0);
1296+
TEST_ASSERT(flb_output_set(ctx, out_ffd,
1297+
"match", "test",
1298+
"file", logfile,
1299+
"max_files", "0",
1300+
NULL) == 0);
1301+
1302+
/* Start should fail */
1303+
TEST_CHECK(flb_start(ctx) == -1);
1304+
1305+
flb_destroy(ctx);
1306+
1307+
/* Test with max_files = -1 */
1308+
ctx = flb_create();
1309+
TEST_ASSERT(flb_service_set(ctx, "Flush", "1", "Grace", "1",
1310+
"Log_Level", "error", NULL) == 0);
1311+
1312+
out_ffd = flb_output(ctx, (char *) "logrotate", NULL);
1313+
TEST_CHECK(out_ffd >= 0);
1314+
TEST_ASSERT(flb_output_set(ctx, out_ffd,
1315+
"match", "test",
1316+
"file", logfile,
1317+
"max_files", "-1",
1318+
NULL) == 0);
1319+
1320+
/* Start should fail */
1321+
TEST_CHECK(flb_start(ctx) == -1);
1322+
1323+
flb_destroy(ctx);
1324+
1325+
/* Clean up directory */
1326+
recursive_delete_directory(TEST_LOGPATH);
1327+
}

0 commit comments

Comments
 (0)