]> git.ipfire.org Git - thirdparty/freeradius-server.git/commitdiff
Move SQLite busy timeout to be a driver option
authorNick Porter <nick@portercomputing.co.uk>
Wed, 25 Jun 2025 13:13:42 +0000 (14:13 +0100)
committerNick Porter <nick@portercomputing.co.uk>
Thu, 26 Jun 2025 07:09:34 +0000 (08:09 +0100)
This is a specific kind of timeout - how long to wait for database locks
to be released.

Due to SQLite's very basic locking, it's easy for multiple update
requests to conflict.  This provides a more graceful way to handle the
locks.

raddb/mods-config/sql/driver/sqlite
src/modules/rlm_sql/drivers/rlm_sql_sqlite/rlm_sql_sqlite.c

index f7c7674460a722f8f5a157bf615955a1954fc28a..e4a658c6b2d1650de77fda1396ea1e2b5eecd75d 100644 (file)
@@ -14,4 +14,9 @@ sqlite {
        # a new database file will be created, and the SQL statements
        # contained within the bootstrap file will be executed.
 #      bootstrap = "${modconfdir}/${..:name}/main/sqlite/schema.sql"
+
+       # When a query is run against a locked database, SQLite can
+       # wait for up to this time for the lock to be released rather
+       # than failing immediately.
+       busy_timeout = 0.25s
 }
index 8d1843094a86b70950b2f7a58b932db2d6696663..b7e7609d0988abe1bfc803374927f276a0f3b2b5 100644 (file)
@@ -59,10 +59,12 @@ typedef struct {
 typedef struct {
        char const      *filename;
        bool            bootstrap;
+       fr_time_delta_t busy_timeout;
 } rlm_sql_sqlite_t;
 
 static const conf_parser_t driver_config[] = {
        { FR_CONF_OFFSET_FLAGS("filename", CONF_FLAG_FILE_OUTPUT | CONF_FLAG_REQUIRED, rlm_sql_sqlite_t, filename) },
+       { FR_CONF_OFFSET("busy_timeout", rlm_sql_sqlite_t, busy_timeout) },
        CONF_PARSER_TERMINATOR
 };
 
@@ -367,7 +369,6 @@ static connection_state_t _sql_connection_init(void **h, connection_t *conn, voi
        rlm_sql_t const         *sql = talloc_get_type_abort_const(uctx, rlm_sql_t);
        rlm_sql_sqlite_t        *inst = talloc_get_type_abort(sql->driver_submodule->data, rlm_sql_sqlite_t);
        rlm_sql_sqlite_conn_t   *c;
-       rlm_sql_config_t const  *config = &sql->config;
        int                     status;
 
        MEM(c = talloc_zero(conn, rlm_sql_sqlite_conn_t));
@@ -400,7 +401,7 @@ static connection_state_t _sql_connection_init(void **h, connection_t *conn, voi
                talloc_free(c);
                return CONNECTION_STATE_FAILED;
        }
-       status = sqlite3_busy_timeout(c->db, fr_time_delta_to_msec(config->query_timeout));
+       status = sqlite3_busy_timeout(c->db, fr_time_delta_to_msec(inst->busy_timeout));
        if (sql_check_error(c->db, status) != RLM_SQL_OK) {
                sql_print_error(c->db, status, "Failed setting busy timeout");
                goto error;