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);
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);
}
#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))) {
}
}
+ if (abort_txn) {
+ zone_control_clear(zone);
+ }
zone_free(&zone);
}
*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);
}
* \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);
--- /dev/null
+#!/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()
ok(nr_passed == ZONE_COUNT, "zonedb: removed all zones");
cleanup:
- knot_zonedb_deep_free(&db);
+ knot_zonedb_deep_free(&db, false);
return 0;
}