diff --git a/ChangeLog.txt b/ChangeLog.txt index 8aef3827..43235d9a 100644 --- a/ChangeLog.txt +++ b/ChangeLog.txt @@ -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. diff --git a/man/mosquitto.conf.5.xml b/man/mosquitto.conf.5.xml index c490c60b..ef304bfc 100644 --- a/man/mosquitto.conf.5.xml +++ b/man/mosquitto.conf.5.xml @@ -419,13 +419,15 @@ seconds - The number of seconds that mosquitto will wait + + 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). + effect if the built-in persistence is enabled. Defaults + to 1800 seconds (30 minutes). + This option applies globally. @@ -445,6 +447,7 @@ as a time in seconds. + Applies to built-in persistence only. This option applies globally. Reloaded on reload signal. @@ -1003,18 +1006,25 @@ log_timestamp_format %Y-%m-%dT%H:%M:%S [ true | false ] - If true, 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 false, the data - will be stored in memory only. Defaults to - false. + + If true, then built-in persistence + is enabled. It is recommended that a plugin based persistence + is used instead. + + + + 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 false, + the data will be stored in memory only. Defaults to + false. + 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 file name - The filename to use for the persistent database. - Defaults to mosquitto.db. + + The filename to use for the built-in persistent database. + Defaults to mosquitto.db. + This option applies globally. @@ -1042,8 +1054,12 @@ log_timestamp_format %Y-%m-%dT%H:%M:%S path - The path where the persistence database should be - stored. If not given, then the current directory is used. + + 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. + This option applies globally. diff --git a/src/plugin_callbacks.c b/src/plugin_callbacks.c index 0ad729a9..51678066 100644 --- a/src/plugin_callbacks.c +++ b/src/plugin_callbacks.c @@ -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); } diff --git a/src/retain.c b/src/retain.c index 45ef9bba..6c615709 100644 --- a/src/retain.c +++ b/src/retain.c @@ -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);