@cryptotaxi247 / netdata-1 / commits / 68079befb

fix: add procfile parsing for non-seekable files (#21507)

Ilya Mashchenko committed Dec 28, 2025 at 21:39 UTC 68079befbf3a1f77becf0ef0ed46abe4dc4365b0
2 files changed +26 -11
src/libnetdata/procfile/procfile.c
+25 -11
@@ -330,14 +330,29 @@ procfile *procfile_readall(procfile *ff) {
330
331 ff->len += r;
332 }
333 -
334 - // netdata_log_debug(D_PROCFILE, "Rewinding file '%s'", ff->filename);
335 - if(unlikely(lseek(ff->fd, 0, SEEK_SET) == -1)) {
336 - if(unlikely(!(ff->flags & PROCFILE_FLAG_NO_ERROR_ON_FILE_IO))) collector_error(PF_PREFIX ": Cannot rewind on file '%s'.", procfile_filename(ff));
337 - else if(unlikely(ff->flags & PROCFILE_FLAG_ERROR_ON_ERROR_LOG))
338 - netdata_log_error(PF_PREFIX ": Cannot rewind on file '%s'.", procfile_filename(ff));
339 - procfile_close(ff);
340 - return NULL;
333 +
334 + if (unlikely(ff->flags & PROCFILE_FLAG_NONSEEKABLE)) {
335 + char *fn = procfile_filename(ff);
336 + ff = procfile_reopen(ff, fn, NULL, ff->flags);
337 + if (unlikely(!ff))
338 + return NULL;
339 + } else if (unlikely(lseek(ff->fd, 0, SEEK_SET) == -1)) {
340 + // Some procfs files (Ubuntu HWE 24.04 / kernel 6.14) may be non-seekable.
341 + // In that case, "rewind" by reopening.
342 + if (errno == ESPIPE || errno == EINVAL) {
343 + ff->flags |= PROCFILE_FLAG_NONSEEKABLE;
344 + char *fn = procfile_filename(ff);
345 + ff = procfile_reopen(ff, fn, NULL, ff->flags);
346 + if (unlikely(!ff))
347 + return NULL;
348 + } else {
349 + if (unlikely(!(ff->flags & PROCFILE_FLAG_NO_ERROR_ON_FILE_IO)))
350 + collector_error(PF_PREFIX ": Cannot rewind on file '%s'.", procfile_filename(ff));
351 + else if (unlikely(ff->flags & PROCFILE_FLAG_ERROR_ON_ERROR_LOG))
352 + netdata_log_error(PF_PREFIX ": Cannot rewind on file '%s'.", procfile_filename(ff));
353 + procfile_close(ff);
354 + return NULL;
355 + }
356 }
357
358 procfile_lines_reset(ff->lines);
@@ -498,9 +513,8 @@ procfile *procfile_reopen(procfile *ff, const char *filename, const char *separa
513 }
514 ff->stats.opens++;
515
501 - // netdata_log_info("PROCFILE: opened '%s' on fd %d", filename, ff->fd);
502 -
503 - //strncpyz(ff->filename, filename, FILENAME_MAX);
516 + // IMPORTANT: 'filename' parameter must not be used after this point
517 + // as it may point to ff->filename which we're about to free
518 freez(ff->filename);
519 ff->filename = NULL;
520 ff->flags = flags;
src/libnetdata/procfile/procfile.h
+1
@@ -36,6 +36,7 @@ typedef struct {
36 #define PROCFILE_FLAG_DEFAULT 0x00000000 // To store inside `collector.log`
37 #define PROCFILE_FLAG_NO_ERROR_ON_FILE_IO 0x00000001 // Do not log anything
38 #define PROCFILE_FLAG_ERROR_ON_ERROR_LOG 0x00000002 // Store inside `error.log`
39 +#define PROCFILE_FLAG_NONSEEKABLE 0x00000004 // File doesn't support lseek(), reopen instead
40
41 typedef enum __attribute__ ((__packed__)) procfile_separator {
42 PF_CHAR_IS_SEPARATOR,