Skip to content

Commit ec61c24

Browse files
authored
Merge pull request syslog-ng#5118 from HofiOne/update-persist-state
Update persist state instead of dropping it
2 parents e854282 + 0bfada8 commit ec61c24

7 files changed

+106
-28
lines changed

lib/persist-state.c

+22
Original file line numberDiff line numberDiff line change
@@ -359,6 +359,28 @@ _persist_state_copy_entry(PersistState *self, const PersistEntryHandle from, Per
359359
persist_state_unmap_entry(self, to);
360360
}
361361

362+
gboolean
363+
persist_state_copy_entry(PersistState *self, const gchar *old_key, const gchar *new_key)
364+
{
365+
gsize size;
366+
guint8 version;
367+
PersistEntryHandle old_handle = persist_state_lookup_entry(self, old_key, &size, &version);
368+
if (!old_handle)
369+
return FALSE;
370+
371+
PersistEntryHandle new_handle = persist_state_alloc_entry(self, new_key, size);
372+
if (!new_handle)
373+
return FALSE;
374+
375+
_persist_state_copy_entry(self, old_handle, new_handle, size);
376+
377+
msg_debug("Persistent entry copied",
378+
evt_tag_str("from", old_key),
379+
evt_tag_str("to", new_key));
380+
381+
return TRUE;
382+
}
383+
362384
gboolean
363385
persist_state_move_entry(PersistState *self, const gchar *old_key, const gchar *new_key)
364386
{

lib/persist-state.h

+1
Original file line numberDiff line numberDiff line change
@@ -98,6 +98,7 @@ gboolean persist_state_remove_entry(PersistState *self, const gchar *persist_nam
9898

9999
gchar *persist_state_lookup_string(PersistState *self, const gchar *key, gsize *length, guint8 *version);
100100
gboolean persist_state_rename_entry(PersistState *self, const gchar *old_key, const gchar *new_key);
101+
gboolean persist_state_copy_entry(PersistState *self, const gchar *old_key, const gchar *new_key);
101102
gboolean persist_state_move_entry(PersistState *self, const gchar *old_key, const gchar *new_key);
102103
void persist_state_alloc_string(PersistState *self, const gchar *persist_name, const gchar *value, gssize len);
103104

modules/affile/file-reader.c

+78-14
Original file line numberDiff line numberDiff line change
@@ -44,31 +44,57 @@
4444
#include <errno.h>
4545
#include <time.h>
4646
#include <stdlib.h>
47+
#include <glib/gprintf.h>
4748

4849
#include <iv.h>
4950

50-
static inline const gchar *
51+
static inline gint G_GNUC_PRINTF(2, 3)
52+
_format_g_va_string(gchar **strp, const gchar *format, ...)
53+
{
54+
va_list args;
55+
56+
va_start(args, format);
57+
gint result = g_vasprintf(strp, format, args);
58+
va_end(args);
59+
60+
return result;
61+
}
62+
63+
static const gchar *
5164
_format_persist_name(const LogPipe *s)
5265
{
5366
const FileReader *self = (const FileReader *)s;
5467
guint name_hash = g_str_hash(self->filename->str);
55-
gchar persist_name[1024];
68+
const gint max_persist_name_len = 1024;
69+
gchar *persist_name = NULL;
5670

57-
/* same wildcard file sources even with persist-name defined can be the same
58-
file name hash is added as well to ensure uniquiness
71+
/* same wildcard file sources even with persist-name defined can be the same, so
72+
file name hash is added as well to ensure uniquiness always
73+
also adding now the filename (or at least an end part of it) for debug aid purpose
5974
*/
75+
gint used_len;
6076
if (self->owner->super.super.persist_name)
77+
used_len = _format_g_va_string(&persist_name, "%s.%s.%u.curpos", self->persist_name_prefix,
78+
self->owner->super.super.persist_name, name_hash);
79+
else
80+
used_len = _format_g_va_string(&persist_name, "%s.%u.curpos", self->persist_name_prefix, name_hash);
81+
g_assert(used_len > 0);
82+
83+
if (used_len < max_persist_name_len - 2 - 1) /* () and the terminating NUL */
6184
{
62-
g_snprintf(persist_name, sizeof(persist_name), "affile_sd.%s.%u.curpos",
63-
self->owner->super.super.persist_name, name_hash);
85+
gchar *base_name = persist_name;
86+
gint filename_len = strlen(self->filename->str);
87+
gint remaining_len = max_persist_name_len - used_len - 2 - 1; /* () and the terminating NUL */
88+
persist_name = NULL; /* glib requires the input ptr to be NULL otherwise returning with -1 from g_vasprintf */
89+
_format_g_va_string(&persist_name, "%s(%s)", base_name,
90+
self->filename->str + MAX(0, filename_len - remaining_len));
91+
g_free(base_name);
6492
}
65-
else
66-
g_snprintf(persist_name, sizeof(persist_name), "affile_sd.%u.curpos", name_hash);
6793

68-
return g_strdup(persist_name);
94+
return persist_name;
6995
}
7096

71-
static const gchar *
97+
static inline const gchar *
7298
_generate_persist_name(const LogPipe *s)
7399
{
74100
FileReader *self = (FileReader *) s;
@@ -86,6 +112,40 @@ _generate_persist_name(const LogPipe *s)
86112
return self->persist_name;
87113
}
88114

115+
static inline const gchar *
116+
_format_legacy_persist_name(const LogPipe *s)
117+
{
118+
const FileReader *self = (const FileReader *)s;
119+
static gchar persist_name[1024];
120+
121+
if (self->owner->super.super.persist_name)
122+
g_snprintf(persist_name, sizeof(persist_name), "affile_sd.%s.curpos", self->owner->super.super.persist_name);
123+
else
124+
g_snprintf(persist_name, sizeof(persist_name), "affile_sd_curpos(%s)", self->filename->str);
125+
126+
return persist_name;
127+
}
128+
129+
static gboolean
130+
_update_legacy_persist_name(FileReader *self)
131+
{
132+
GlobalConfig *cfg = log_pipe_get_config(&self->super);
133+
134+
if (cfg->state == NULL)
135+
return TRUE;
136+
137+
const gchar *current_persist_name = _generate_persist_name(&self->super);
138+
const gchar *legacy_persist_name = _format_legacy_persist_name(&self->super);
139+
140+
if (persist_state_entry_exists(cfg->state, current_persist_name))
141+
return TRUE;
142+
143+
if (FALSE == persist_state_entry_exists(cfg->state, legacy_persist_name))
144+
return TRUE;
145+
146+
return persist_state_copy_entry(cfg->state, legacy_persist_name, current_persist_name);
147+
}
148+
89149
static void
90150
_recover_state(LogPipe *s, GlobalConfig *cfg, LogProtoServer *proto)
91151
{
@@ -94,7 +154,7 @@ _recover_state(LogPipe *s, GlobalConfig *cfg, LogProtoServer *proto)
94154
if (!self->options->restore_state)
95155
return;
96156

97-
if (!log_proto_server_restart_with_state(proto, cfg->state, _generate_persist_name(s)))
157+
if (!log_proto_server_restart_with_state(proto, cfg->state, log_pipe_get_persist_name(s)))
98158
{
99159
msg_error("Error converting persistent state from on-disk format, losing file position information",
100160
evt_tag_str("filename", self->filename->str));
@@ -430,6 +490,8 @@ file_reader_queue_method(LogPipe *s, LogMessage *msg, const LogPathOptions *path
430490
gboolean
431491
file_reader_init_method(LogPipe *s)
432492
{
493+
_update_legacy_persist_name((FileReader *)s);
494+
433495
return _reader_open_file(s, TRUE);
434496
}
435497

@@ -456,7 +518,7 @@ void
456518
file_reader_remove_persist_state(FileReader *self)
457519
{
458520
GlobalConfig *cfg = log_pipe_get_config(&self->super);
459-
const gchar *old_persist_name = _generate_persist_name(&self->super);
521+
const gchar *old_persist_name = log_pipe_get_persist_name(&self->super);
460522
gchar *new_persist_name = g_strdup_printf("%s_REMOVED", old_persist_name);
461523
/* This is required to clean the persist entry from file during restart */
462524
persist_state_remove_entry(cfg->state, old_persist_name);
@@ -482,7 +544,8 @@ file_reader_cue_buffer_flush(FileReader *self)
482544
void
483545
file_reader_init_instance (FileReader *self, const gchar *filename,
484546
FileReaderOptions *options, FileOpener *opener,
485-
LogSrcDriver *owner, GlobalConfig *cfg)
547+
LogSrcDriver *owner, GlobalConfig *cfg,
548+
const gchar *persist_name_prefix)
486549
{
487550
log_pipe_init_instance (&self->super, cfg);
488551
self->super.init = file_reader_init_method;
@@ -491,6 +554,7 @@ file_reader_init_instance (FileReader *self, const gchar *filename,
491554
self->super.notify = file_reader_notify_method;
492555
self->super.free_fn = file_reader_free_method;
493556
self->super.generate_persist_name = _generate_persist_name;
557+
self->persist_name_prefix = persist_name_prefix;
494558
self->filename = g_string_new (filename);
495559
self->options = options;
496560
self->opener = opener;
@@ -504,7 +568,7 @@ file_reader_new(const gchar *filename, FileReaderOptions *options, FileOpener *o
504568
{
505569
FileReader *self = g_new0(FileReader, 1);
506570

507-
file_reader_init_instance (self, filename, options, opener, owner, cfg);
571+
file_reader_init_instance (self, filename, options, opener, owner, cfg, "affile_sd");
508572
return self;
509573
}
510574

modules/affile/file-reader.h

+2-2
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,7 @@ struct _FileReader
4545
FileOpener *opener;
4646
LogReader *reader;
4747
const gchar *persist_name;
48+
const gchar *persist_name_prefix;
4849

4950
void (*on_file_moved)(FileReader *);
5051
};
@@ -59,8 +60,7 @@ FileReader *file_reader_new(const gchar *filename, FileReaderOptions *options, F
5960
GlobalConfig *cfg);
6061

6162
void file_reader_init_instance(FileReader *self, const gchar *filename, FileReaderOptions *options, FileOpener *opener,
62-
LogSrcDriver *owner,
63-
GlobalConfig *cfg);
63+
LogSrcDriver *owner, GlobalConfig *cfg, const gchar *persist_name_prefix);
6464

6565
gboolean file_reader_init_method(LogPipe *s);
6666
gboolean file_reader_deinit_method(LogPipe *s);

modules/affile/tests/test_wildcard_file_reader.c

+2-1
Original file line numberDiff line numberDiff line change
@@ -105,7 +105,8 @@ void iv_task_register(struct iv_task *_t)
105105

106106
void file_reader_init_instance(FileReader *self, const gchar *filename,
107107
FileReaderOptions *options, FileOpener *opener,
108-
LogSrcDriver *owner, GlobalConfig *cfg)
108+
LogSrcDriver *owner, GlobalConfig *cfg,
109+
const gchar *persist_name_prefix)
109110
{
110111
log_pipe_init_instance(&self->super, cfg);
111112
self->reader = log_reader_new(cfg);

modules/affile/wildcard-file-reader.c

+1-1
Original file line numberDiff line numberDiff line change
@@ -162,7 +162,7 @@ wildcard_file_reader_new(const gchar *filename, FileReaderOptions *options, File
162162
GlobalConfig *cfg)
163163
{
164164
WildcardFileReader *self = g_new0(WildcardFileReader, 1);
165-
file_reader_init_instance(&self->super, filename, options, opener, owner, cfg);
165+
file_reader_init_instance(&self->super, filename, options, opener, owner, cfg, "wildcard_file_sd");
166166
self->super.super.init = _init;
167167
self->super.super.notify = _notify;
168168
self->super.super.deinit = _deinit;

news/bugfix-5091.md

-10
Original file line numberDiff line numberDiff line change
@@ -39,13 +39,3 @@ NOTE:
3939

4040
- The issue occurred regardless of the presence of the `persist-name()` option.
4141
- It affected not only the simplified example of the legacy wildcard `file()` but also the new `wildcard-file()` source.
42-
43-
**<u>WARNING</u>**, the main issue causing this problem was that the generated final persist names for the
44-
`file()` and `wildcard-file()` sources were not always unique. To fix this, we had to change the format of
45-
the names used in the persist files. These changes will result in the loss of persist information in the
46-
`syslog-ng` persist files!
47-
48-
**<u>BE AWARE</u>**, ensure that all your existing wildcard `file()` and `wildcard-file()` sources are fully processed before
49-
installing the new version of `syslog-ng`. Otherwise, the content of those files will be reprocessed from the
50-
beginning at the next startup of the updated `syslog-ng`, as the file read positions in the persist files will be
51-
ignored due to the changed persist names.

0 commit comments

Comments
 (0)