Skip to content

Commit dc50818

Browse files
sandy2008claude
andcommitted
in_tail: address inotify reconcile review feedback
- retry inotify_add_watch on next reconcile when a previously rotated file ended up unwatched (e.g. ENOSPC on the first add) - drop the IN_MOVE_SELF block in tail_fs_event; reconcile_file_state already detects inode/name divergence and re-registers the watch via the same retry path - share the truncate reset between adjust_counters and the inotify reconcile path through a new flb_tail_file_reset_on_truncate helper so post-truncate offset_key values stay consistent across both paths - make reconcile_file_state's pending_data_detected out param NULL-able and pass NULL from tail_fs_event where the value was unused Signed-off-by: Sandy Chen <Yuxuan.Chen@morganstanley.com> Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
1 parent 4ebe842 commit dc50818

3 files changed

Lines changed: 54 additions & 74 deletions

File tree

plugins/in_tail/tail_file.c

Lines changed: 30 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -181,6 +181,32 @@ static void update_resumable_offset_state(struct flb_tail_file *file)
181181
flb_tail_file_update_offset_marker(file);
182182
}
183183

184+
int flb_tail_file_reset_on_truncate(struct flb_tail_file *file,
185+
int64_t size_delta,
186+
const char *caller)
187+
{
188+
int64_t offset;
189+
struct flb_tail_config *ctx = file->config;
190+
191+
offset = lseek(file->fd, 0, SEEK_SET);
192+
if (offset == -1) {
193+
flb_errno();
194+
return -1;
195+
}
196+
197+
flb_plg_debug(ctx->ins,
198+
"%s: inode=%"PRIu64" file truncated %s (diff: %"PRId64" bytes)",
199+
caller, file->inode, file->name, size_delta);
200+
201+
file->offset = offset;
202+
file->stream_offset = offset;
203+
file->last_processed_bytes = 0;
204+
file->buf_len = 0;
205+
206+
update_resumable_offset_state(file);
207+
return 0;
208+
}
209+
184210
static uint64_t stat_get_st_dev(struct stat *st)
185211
{
186212
#ifdef FLB_SYSTEM_WINDOWS
@@ -1690,9 +1716,10 @@ int flb_tail_file_remove_all(struct flb_tail_config *ctx)
16901716
static int adjust_counters(struct flb_tail_config *ctx, struct flb_tail_file *file)
16911717
{
16921718
int ret;
1693-
int64_t offset;
16941719
struct stat st;
16951720

1721+
(void) ctx;
1722+
16961723
ret = fstat(file->fd, &st);
16971724
if (ret == -1) {
16981725
flb_errno();
@@ -1706,18 +1733,10 @@ static int adjust_counters(struct flb_tail_config *ctx, struct flb_tail_file *fi
17061733

17071734
/* Check if the file was truncated by comparing current size with previous size */
17081735
if (size_delta < 0) {
1709-
offset = lseek(file->fd, 0, SEEK_SET);
1710-
if (offset == -1) {
1711-
flb_errno();
1736+
if (flb_tail_file_reset_on_truncate(file, size_delta,
1737+
"adjust_counters") == -1) {
17121738
return FLB_TAIL_ERROR;
17131739
}
1714-
1715-
flb_plg_debug(ctx->ins, "adjust_counters: inode=%"PRIu64" file truncated %s (diff: %"PRId64" bytes)",
1716-
file->inode, file->name, size_delta);
1717-
file->offset = offset;
1718-
file->buf_len = 0;
1719-
1720-
update_resumable_offset_state(file);
17211740
}
17221741
else {
17231742
// Avoid negative pending_bytes when fstat() has stale data and size < offset

plugins/in_tail/tail_file.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -155,5 +155,8 @@ static inline off_t flb_tail_file_db_offset(struct flb_tail_file *file)
155155

156156
int flb_tail_file_update_offset_marker(struct flb_tail_file *file);
157157
int flb_tail_file_offset_marker_matches(struct flb_tail_file *file);
158+
int flb_tail_file_reset_on_truncate(struct flb_tail_file *file,
159+
int64_t size_delta,
160+
const char *caller);
158161

159162
#endif

plugins/in_tail/tail_fs_inotify.c

Lines changed: 21 additions & 63 deletions
Original file line numberDiff line numberDiff line change
@@ -164,38 +164,6 @@ static int flb_tail_fs_add_rotated(struct flb_tail_file *file)
164164
return tail_fs_add(file, FLB_FALSE);
165165
}
166166

167-
static int reset_file_on_truncate(struct flb_tail_config *ctx,
168-
struct flb_tail_file *file,
169-
int64_t size_delta,
170-
const char *caller)
171-
{
172-
int64_t offset;
173-
174-
offset = lseek(file->fd, 0, SEEK_SET);
175-
if (offset == -1) {
176-
flb_errno();
177-
return -1;
178-
}
179-
180-
flb_plg_debug(ctx->ins,
181-
"%s: inode=%"PRIu64" file truncated %s (diff: %"PRId64" bytes)",
182-
caller, file->inode, file->name, size_delta);
183-
184-
file->offset = offset;
185-
file->stream_offset = offset;
186-
file->last_processed_bytes = 0;
187-
file->buf_len = 0;
188-
file->pending_bytes = file->size;
189-
190-
#ifdef FLB_HAVE_SQLDB
191-
if (ctx->db) {
192-
flb_tail_db_file_offset(file, ctx);
193-
}
194-
#endif
195-
196-
return 0;
197-
}
198-
199167
static int reconcile_file_state(struct flb_tail_config *ctx,
200168
struct flb_tail_file *file,
201169
const char *caller,
@@ -205,7 +173,9 @@ static int reconcile_file_state(struct flb_tail_config *ctx,
205173
int64_t size_delta;
206174
struct stat st;
207175

208-
*pending_data_detected = FLB_FALSE;
176+
if (pending_data_detected != NULL) {
177+
*pending_data_detected = FLB_FALSE;
178+
}
209179

210180
ret = fstat(file->fd, &st);
211181
if (ret == -1) {
@@ -222,22 +192,24 @@ static int reconcile_file_state(struct flb_tail_config *ctx,
222192

223193
if (size_delta < 0 || st.st_size < file->offset ||
224194
flb_tail_file_offset_marker_matches(file) != FLB_TRUE) {
225-
ret = reset_file_on_truncate(ctx, file, size_delta, caller);
195+
ret = flb_tail_file_reset_on_truncate(file, size_delta, caller);
226196
if (ret == -1) {
227197
return -1;
228198
}
229199
}
230200

231201
if (file->offset < st.st_size) {
232202
file->pending_bytes = (st.st_size - file->offset);
233-
*pending_data_detected = FLB_TRUE;
203+
if (pending_data_detected != NULL) {
204+
*pending_data_detected = FLB_TRUE;
205+
}
234206
}
235207
else {
236208
file->pending_bytes = 0;
237209
}
238210

239211
if (st.st_nlink == 0) {
240-
if (*pending_data_detected == FLB_TRUE) {
212+
if (file->pending_bytes > 0) {
241213
return 0;
242214
}
243215

@@ -268,15 +240,17 @@ static int reconcile_file_state(struct flb_tail_config *ctx,
268240
if (ret == -1) {
269241
return -1;
270242
}
243+
}
244+
else if (ret == -1) {
245+
return -1;
246+
}
271247

248+
if (file->rotated != 0 && file->watch_fd == -1) {
272249
ret = flb_tail_fs_add_rotated(file);
273250
if (ret == -1) {
274251
return -1;
275252
}
276253
}
277-
else if (ret == -1) {
278-
return -1;
279-
}
280254

281255
return 0;
282256
}
@@ -320,7 +294,8 @@ static int tail_fs_event(struct flb_input_instance *ins,
320294
struct flb_tail_config *ctx = in_context;
321295
struct flb_tail_file *file = NULL;
322296
struct inotify_event ev;
323-
int pending_data_detected;
297+
298+
(void) ins;
324299

325300
/* Read the event */
326301
ret = read(ctx->fd_notify, &ev, sizeof(struct inotify_event));
@@ -360,29 +335,12 @@ static int tail_fs_event(struct flb_input_instance *ins,
360335
return -1;
361336
}
362337

363-
/* Check file rotation (only if it has not been rotated before) */
364-
if (ev.mask & IN_MOVE_SELF && file->rotated == 0) {
365-
flb_plg_debug(ins, "inode=%"PRIu64" rotated IN_MOVE SELF '%s'",
366-
file->inode, file->name);
367-
368-
/* A rotated file must be re-registered */
369-
ret = flb_tail_file_rotated(file);
370-
if (ret == -1) {
371-
return -1;
372-
}
373-
374-
ret = flb_tail_fs_remove(ctx, file);
375-
if (ret == -1) {
376-
return -1;
377-
}
378-
379-
ret = flb_tail_fs_add_rotated(file);
380-
if (ret == -1) {
381-
return -1;
382-
}
383-
}
384-
385-
ret = reconcile_file_state(ctx, file, "tail_fs_event", &pending_data_detected);
338+
/*
339+
* IN_MOVE_SELF rotation is handled inside reconcile_file_state via
340+
* flb_tail_file_is_rotated, which detects the inode/name divergence and
341+
* re-registers the watch through the same retry path.
342+
*/
343+
ret = reconcile_file_state(ctx, file, "tail_fs_event", NULL);
386344
if (ret == -1) {
387345
return 0;
388346
}

0 commit comments

Comments
 (0)