]> git.ipfire.org Git - thirdparty/knot-dns.git/commitdiff
server: abort possible open zone transaction when shutdown
authorDaniel Salzman <daniel.salzman@nic.cz>
Thu, 5 Dec 2019 14:25:42 +0000 (15:25 +0100)
committerDaniel Salzman <daniel.salzman@nic.cz>
Sat, 7 Dec 2019 20:03:18 +0000 (21:03 +0100)
src/knot/server/server.c
src/knot/zone/zonedb-load.c
src/knot/zone/zonedb.c
src/knot/zone/zonedb.h
tests-extra/tests/ctl/shutdown/test.py [new file with mode: 0644]
tests/knot/test_zonedb.c

index ee7a72125f5718e510406be4b8a0ef7b814c1ac8..92998a714e9e0f1fae02fe8e12b79a00bc64e7e2 100644 (file)
@@ -458,7 +458,7 @@ void server_deinit(server_t *server)
        worker_pool_destroy(server->workers);
 
        /* Free zone database. */
-       knot_zonedb_deep_free(&server->zone_db);
+       knot_zonedb_deep_free(&server->zone_db, true);
 
        /* Free remaining events. */
        evsched_deinit(&server->sched);
index 59f16386b488edd06fb302f6a2eb04b695299bcd..790d7e0b664f914f1c292f64a73ad17d94494362 100644 (file)
@@ -317,7 +317,7 @@ static void remove_old_zonedb(conf_t *conf, knot_zonedb_t *db_old,
        knot_zonedb_iter_free(it);
 
        if (full) {
-               knot_zonedb_deep_free(&db_old);
+               knot_zonedb_deep_free(&db_old, false);
        } else {
                knot_zonedb_free(&db_old);
        }
index 58b98f7bc27342ffed4220653a9a3b0e446bc8ae..9d28fd0be33b60c610505a63f1a55172ac97a06b 100644 (file)
@@ -24,7 +24,7 @@
 #include "contrib/ucw/mempool.h"
 
 /*! \brief Discard zone in zone database. */
-static void discard_zone(zone_t *zone)
+static void discard_zone(zone_t *zone, bool abort_txn)
 {
        // Don't flush if removed zone (no previous configuration available).
        if (conf_rawid_exists(conf(), C_ZONE, zone->name, knot_dname_size(zone->name))) {
@@ -39,6 +39,9 @@ static void discard_zone(zone_t *zone)
                }
        }
 
+       if (abort_txn) {
+               zone_control_clear(zone);
+       }
        zone_free(&zone);
 }
 
@@ -155,12 +158,12 @@ void knot_zonedb_free(knot_zonedb_t **db)
        *db = NULL;
 }
 
-void knot_zonedb_deep_free(knot_zonedb_t **db)
+void knot_zonedb_deep_free(knot_zonedb_t **db, bool abort_txn)
 {
        if (db == NULL || *db == NULL) {
                return;
        }
 
-       knot_zonedb_foreach(*db, discard_zone);
+       knot_zonedb_foreach(*db, discard_zone, abort_txn);
        knot_zonedb_free(db);
 }
index a162d6dfda26d3ee036284062c29df83924a40d9..d35f9a0df40832309181d89241be51f06afb848b 100644 (file)
@@ -120,5 +120,6 @@ void knot_zonedb_free(knot_zonedb_t **db);
  * \brief Destroys and deallocates the whole zone database including the zones.
  *
  * \param db Zone database to be destroyed.
+ * \param abort_txn Indication that possible zone transactions are aborted.
  */
-void knot_zonedb_deep_free(knot_zonedb_t **db);
+void knot_zonedb_deep_free(knot_zonedb_t **db, bool abort_txn);
diff --git a/tests-extra/tests/ctl/shutdown/test.py b/tests-extra/tests/ctl/shutdown/test.py
new file mode 100644 (file)
index 0000000..83629f5
--- /dev/null
@@ -0,0 +1,32 @@
+#!/usr/bin/env python3
+
+'''Test on server shutdown when a zone transaction is open.'''
+
+import psutil
+from dnstest.libknot import libknot
+from dnstest.test import Test
+from dnstest.utils import *
+
+t = Test()
+
+knot = t.server("knot")
+zone = t.zone("example.com.")
+t.link(zone, knot)
+
+ctl = libknot.control.KnotCtl()
+
+t.start()
+
+ctl.connect(os.path.join(knot.dir, "knot.sock"))
+ctl.send_block(cmd="zone-begin", zone=zone[0].name)
+ctl.receive_block()
+ctl.send(libknot.control.KnotCtlType.END)
+ctl.close()
+
+knot.stop()
+t.sleep(1)
+
+if psutil.pid_exists(knot.proc.pid):
+    set_err("Server still running")
+
+t.end()
index 30beb9a03ddce9b03b75f7e1a0ea94a8d688e1fe..3ef7632fea0033515bfabeb99b470b234ed75c08 100644 (file)
@@ -110,6 +110,6 @@ int main(int argc, char *argv[])
        ok(nr_passed == ZONE_COUNT, "zonedb: removed all zones");
 
 cleanup:
-       knot_zonedb_deep_free(&db);
+       knot_zonedb_deep_free(&db, false);
        return 0;
 }