Forbid running with persistence true and a plugin at the same time.

This commit is contained in:
Roger A. Light 2026-02-07 23:24:38 +00:00
parent efb09624c5
commit a7f3f4c362
4 changed files with 64 additions and 19 deletions

View file

@ -1,6 +1,10 @@
2.1.2 - 2026-02-xx
==================
Broker:
- Forbid running with `persistence true` and with a persistence plugin at the
same time.
Build:
- Build fixes for OpenBSD. Closes #3474.
- Add missing libedit to docker builds. Closes #3476.

View file

@ -419,13 +419,15 @@
<varlistentry>
<term><option>autosave_interval</option> <replaceable>seconds</replaceable></term>
<listitem>
<para>The number of seconds that mosquitto will wait
<para>
The number of seconds that mosquitto will wait
between each time it saves the in-memory database to
disk. If set to 0, the in-memory database will only be
saved when mosquitto exits or when receiving the
SIGUSR1 signal. Note that this setting only has an
effect if persistence is enabled. Defaults to 1800
seconds (30 minutes).</para>
effect if the built-in persistence is enabled. Defaults
to 1800 seconds (30 minutes).
</para>
<para>This option applies globally.</para>
@ -445,6 +447,7 @@
<option>autosave_interval</option> as a time in
seconds.</para>
<para>Applies to built-in persistence only.</para>
<para>This option applies globally.</para>
<para>Reloaded on reload signal.</para>
@ -1003,18 +1006,25 @@ log_timestamp_format %Y-%m-%dT%H:%M:%S
<varlistentry>
<term><option>persistence</option> [ true | false ]</term>
<listitem>
<para>If <replaceable>true</replaceable>, connection,
subscription and message data will be written to the
disk in mosquitto.db at the location dictated by
persistence_location. When mosquitto is restarted, it
will reload the information stored in mosquitto.db. The
data will be written to disk when mosquitto closes and
also at periodic intervals as defined by
autosave_interval. Writing of the persistence database
may also be forced by sending mosquitto the SIGUSR1
signal. If <replaceable>false</replaceable>, the data
will be stored in memory only. Defaults to
<replaceable>false</replaceable>.</para>
<para>
If <replaceable>true</replaceable>, then built-in persistence
is enabled. It is recommended that a plugin based persistence
is used instead.
</para>
<para>
If enabled, connection, subscription and message data
will be written to disk in mosquitto.db at the location
dictated by persistence_location. When mosquitto is
restarted, it will reload the information stored in
mosquitto.db. The data will be written to disk when
mosquitto closes and also at periodic intervals as
defined by autosave_interval. Writing of the persistence
database may also be forced by sending mosquitto the
SIGUSR1 signal. If <replaceable>false</replaceable>,
the data will be stored in memory only. Defaults to
<replaceable>false</replaceable>.
</para>
<para>The persistence file may change its format in a new
version. The broker can currently read all old formats,
but will only save in the latest format. It should always
@ -1031,8 +1041,10 @@ log_timestamp_format %Y-%m-%dT%H:%M:%S
<varlistentry>
<term><option>persistence_file</option> <replaceable>file name</replaceable></term>
<listitem>
<para>The filename to use for the persistent database.
Defaults to mosquitto.db.</para>
<para>
The filename to use for the built-in persistent database.
Defaults to mosquitto.db.
</para>
<para>This option applies globally.</para>
@ -1042,8 +1054,12 @@ log_timestamp_format %Y-%m-%dT%H:%M:%S
<varlistentry>
<term><option>persistence_location</option> <replaceable>path</replaceable></term>
<listitem>
<para>The path where the persistence database should be
stored. If not given, then the current directory is used.</para>
<para>
The path where plugins should store any persistence
data, and the path where the built-in persistence will
store its data. If not given, then the current directory
is used.
</para>
<para>This option applies globally.</para>

View file

@ -216,6 +216,26 @@ BROKER_EXPORT int mosquitto_callback_register(
return MOSQ_ERR_INVAL;
}
if(db.config->persistence && (event == MOSQ_EVT_PERSIST_RESTORE
|| event == MOSQ_EVT_PERSIST_BASE_MSG_ADD
|| event == MOSQ_EVT_PERSIST_BASE_MSG_DELETE
|| event == MOSQ_EVT_PERSIST_RETAIN_MSG_SET
|| event == MOSQ_EVT_PERSIST_RETAIN_MSG_DELETE
|| event == MOSQ_EVT_PERSIST_CLIENT_ADD
|| event == MOSQ_EVT_PERSIST_CLIENT_DELETE
|| event == MOSQ_EVT_PERSIST_CLIENT_UPDATE
|| event == MOSQ_EVT_PERSIST_SUBSCRIPTION_ADD
|| event == MOSQ_EVT_PERSIST_SUBSCRIPTION_DELETE
|| event == MOSQ_EVT_PERSIST_CLIENT_MSG_ADD
|| event == MOSQ_EVT_PERSIST_CLIENT_MSG_DELETE
|| event == MOSQ_EVT_PERSIST_CLIENT_MSG_UPDATE
|| event == MOSQ_EVT_PERSIST_WILL_ADD
|| event == MOSQ_EVT_PERSIST_WILL_DELETE
)){
log__printf(NULL, MOSQ_LOG_ERR, "Error: `persistence true` cannot be used with a persistence plugin.");
return MOSQ_ERR_INVAL;
}
if(event == MOSQ_EVT_CONTROL){
return control__register_callback(identifier, cb_func, event_data, userdata);
}

View file

@ -181,6 +181,11 @@ int retain__store(const char *topic, struct mosquitto__base_msg *base_msg, char
#endif
if(retainhier->retained){
if(retainhier->retained == base_msg){
/* This may occur if multiple persistence providers are used */
return MOSQ_ERR_SUCCESS;
}
if(persist && retainhier->retained->data.topic[0] != '$' && base_msg->data.payloadlen == 0){
/* Only delete if another retained message isn't replacing this one */
plugin_persist__handle_retain_msg_delete(retainhier->retained);