]> git.ipfire.org Git - thirdparty/knot-dns.git/commitdiff
purge: when purging keys, use the "trash bin" instead of delete
authorDavid Vašek <david.vasek@nic.cz>
Mon, 20 Apr 2026 08:08:05 +0000 (10:08 +0200)
committerDavid Vašek <david.vasek@nic.cz>
Fri, 26 Jun 2026 11:20:30 +0000 (13:20 +0200)
doc/operation.rst
doc/reference.rst
src/knot/ctl/commands.c
src/knot/dnssec/kasp/kasp_db.c

index af6ddb7967ed3a26dd7e6bf5a2bb0df12a57b045..9a24dc912129f69f8752a0308e9fad2fea7cdcc2 100644 (file)
@@ -1428,8 +1428,7 @@ The *"trash bin"* can be disabled completely for any DNSSEC policy by setting
 :ref:`policy_trash-delay` to ``0``. In such a case, all keys are discarded immediately
 upon their deletion and never moved to the virtual *"trash bin"*.
 
-If needed, the *"trash bin"* can be emptied at will with either ``keymgr trash-discard``
-or ``knotc -f +keys +orphan zone-purge`` commands.
+If needed, the *"trash bin"* can be emptied at will with ``keymgr trash-discard``.
 
 .. NOTE::
    Contents of the *"trash bin*" is not part of :ref:`online backup<Online backup>`
index 3ed9749505efb4b6cff951ae52e0712a5fa4e045..46702ed7ec62b0f8edc03015e701c7e2321dbc52 100644 (file)
@@ -2360,8 +2360,7 @@ trash-delay
 Discard deleted keys belonging to the policy from the "trash bin" automatically
 after this time following their deletion. Set this parameter to ``0`` to completely
 avoid using the "trash bin" for deleted DNSSEC keys and remove them immediately
-once they are deleted. The "trash bin" may be managed using ``keymgr``, or it can
-be emptied with ``knotc -f zone-purge +keys +orphan --``.
+once they are deleted. The "trash bin" may be managed using ``keymgr``.
 
 *Default:* ``14d`` (14 days)
 
index dbf03d551344b51cf68d5400ae53a725b6c66413..567500ceabd2d9558052102a8690a3fcc979e71d 100644 (file)
@@ -1812,7 +1812,7 @@ static int orphans_purge(ctl_args_t *args)
                                if (MATCH_AND_FILTER(args, CTL_FILTER_PURGE_KEYS)) {
                                        if (knot_lmdb_open(&args->server->kaspdb) == KNOT_EOK) {
                                                ret = kasp_db_delete_keys(&args->server->kaspdb, zone_name,
-                                                                         true, false, false);
+                                                                         true, false, true);
                                                log_if_orphans_error(zone_name, ret, "keys", &failed);
                                        }
                                }
@@ -1879,7 +1879,6 @@ static int zone_purge(zone_t *zone, ctl_args_t *args)
                MATCH_OR_FILTER(args, CTL_FILTER_PURGE_EXPIRE)   * PURGE_ZONE_EXPIRE |
                // Keys purge must be requested explicitly.
                MATCH_AND_FILTER(args, CTL_FILTER_PURGE_KEYS)    * PURGE_ZONE_KEYS |
-               PURGE_ZONE_TRASH |
                PURGE_ZONE_NOSYNC; // Purge even zonefiles with disabled syncing.
 
        zone_set_flag(zone, (zone_flag_t)params);
index ceeedd6198b9e54cb72d0050371d88aac567d133..7f74d90dc8c72ec611074ecb8e297ca6d3cf9f8a 100644 (file)
@@ -10,6 +10,7 @@
 
 #include "contrib/strtonum.h"
 #include "contrib/wire_ctx.h"
+#include "knot/conf/conf.h"
 #include "knot/dnssec/kasp/kasp_zone.h"
 #include "knot/dnssec/key_records.h"
 #include "knot/dnssec/zone-keys.h"
@@ -76,11 +77,6 @@ static bool is_key_related(const MDB_val *key)
        return (*(uint8_t *)key->mv_data == KASPDBKEY_PARAMS);
 }
 
-static bool is_trash_related(const MDB_val *key)
-{
-       return (*(uint8_t *)key->mv_data == KASPDBKEY_TRASH);
-}
-
 static MDB_val make_key_str(keyclass_t kclass, const knot_dname_t *dname, const char *str)
 {
        switch (kclass) {
@@ -480,21 +476,15 @@ int kasp_db_delete_key(knot_lmdb_db_t *db, const knot_dname_t *zone_name, const
 int kasp_db_delete_keys(knot_lmdb_db_t *db, const knot_dname_t *zone_name,
                         bool orphan, bool best, bool use_trash)
 {
-       int ret;
-       knot_kasp_keystore_t *keystores = NULL;
        kdnssec_ctx_t ctx = { 0 };
        uint32_t delay = 0;
 
-       if (orphan) {
-               ret = init_all_keystores(conf(), &keystores);
-       } else {
-               ret = kdnssec_ctx_init(conf(), &ctx, zone_name, db, NULL);
-               keystores = ctx.keystores;
-               delay = (use_trash && ret == KNOT_EOK) ? ctx.policy->trash_delay : delay;
-       }
+       int ret = orphan ? kdnssec_orphan_ctx_init(conf(), &ctx) :
+                          kdnssec_ctx_init(conf(), &ctx, zone_name, db, NULL);
        if (ret != KNOT_EOK) {
                return ret;
        }
+       delay = use_trash ? ctx.policy->trash_delay : delay;
 
        MDB_val prefix = make_key_str(KASPDBKEY_PARAMS, zone_name, NULL);
        knot_lmdb_txn_t txn = { 0 };
@@ -514,7 +504,7 @@ int kasp_db_delete_keys(knot_lmdb_db_t *db, const knot_dname_t *zone_name,
                        if (delay > 0) {
                                ret = make_trash_key(&txn, &txn.cur_key, &txn.cur_val, delay);
                        } else {
-                               ret = kdnssec_delete_from_keystores(keystores, key_id,
+                               ret = kdnssec_delete_from_keystores(ctx.keystores, key_id,
                                                                    zone_name, true, false);
                                ret = (ret == KNOT_ENOENT) ? KNOT_EOK : ret;
                                // Note: if error, it isn't sure that there still is a key to delete.
@@ -536,7 +526,7 @@ int kasp_db_delete_keys(knot_lmdb_db_t *db, const knot_dname_t *zone_name,
        free(prefix.mv_data);
 
        if (orphan) {
-               deinit_all_keystores(&keystores);
+               kdnssec_orphan_ctx_deinit(&ctx);
        } else {
                kdnssec_ctx_deinit(&ctx);
        }
@@ -676,33 +666,28 @@ int kasp_db_sweep_keys(knot_lmdb_db_t *db, sweep_cb keep_zone, void *cb_data)
                return ret;
        }
 
-       knot_kasp_keystore_t *keystores = NULL;
-       ret = init_all_keystores(conf(), &keystores);
-       if (ret != KNOT_EOK) {
-               return ret;
-       }
+       kdnssec_ctx_t ctx = { 0 };
+       ret = kdnssec_orphan_ctx_init(conf(), &ctx);
 
        knot_lmdb_txn_t txn = { 0 };
        knot_lmdb_begin(db, &txn, true);
        knot_lmdb_forwhole(&txn) {
-               if (!is_trash_related(&txn.cur_key) &&
-                   (!is_key_related(&txn.cur_key) ||
-                    keep_zone(cur_key_dname(&txn), cb_data))) {
+               if (!is_key_related(&txn.cur_key) ||
+                   keep_zone(cur_key_dname(&txn), cb_data)) {
                        continue;
                }
+
                char *key_id = NULL;
                if (unmake_key_str(&txn.cur_key, &key_id)) {
                        knot_lmdb_cursor_swap(&txn);
                        size_t count = keyid_inuse(&txn, key_id, NULL);
                        knot_lmdb_cursor_swap(&txn); // Restore the regular cursor.
 
-                       assert(count > 0 || is_trash_related(&txn.cur_key));
-                       if (count < 2) {
-                               ret = kdnssec_delete_from_keystores(keystores, key_id, NULL,
-                                                                   true, false);
-                               ret = (ret == KNOT_ENOENT) ? KNOT_EOK : ret;
+                       assert(count > 0);
+                       if (count == 1) {
+                               ret = make_trash_key(&txn, &txn.cur_key, &txn.cur_val,
+                                                    ctx.policy->trash_delay);
                                if (ret != KNOT_EOK) {
-                                       // Note: it isn't sure that there still is a key to delete.
                                        free(key_id);
                                        break;
                                }
@@ -713,7 +698,7 @@ int kasp_db_sweep_keys(knot_lmdb_db_t *db, sweep_cb keep_zone, void *cb_data)
        }
 
        knot_lmdb_commit(&txn);
-       deinit_all_keystores(&keystores);
+       kdnssec_orphan_ctx_deinit(&ctx);
        return (ret == KNOT_EOK) ? txn.ret : ret;
 }