Commit af578293 authored by Libor Peltan's avatar Libor Peltan

Merge branch 'kasp_db_sweep' into 'master'

kasp db: better organized code for clearing orphans in kasp db

See merge request !998
parents f0e8a6db 6c5ecae8
......@@ -1065,24 +1065,14 @@ static int orphans_purge(ctl_args_t *args)
if (args->data[KNOT_CTL_IDX_ZONE] == NULL) {
// Purge KASP DB.
if (only_orphan || MATCH_AND_FILTER(args, CTL_FILTER_PURGE_KASPDB)) {
list_t zones;
if (knot_lmdb_open(&args->server->kaspdb) == KNOT_EOK &&
kasp_db_list_zones(&args->server->kaspdb, &zones) == KNOT_EOK) {
ptrnode_t *zn;
WALK_LIST(zn, zones) {
knot_dname_t *zone_name = (knot_dname_t *)zn->d;
if (!zone_exists(zone_name, &args->server->zone_db)) {
(void)kasp_db_delete_all(&args->server->kaspdb, zone_name);
}
knot_dname_free(zone_name, NULL);
}
ptrlist_free(&zones, NULL);
}
(void)kasp_db_sweep(&args->server->kaspdb,
zone_exists, args->server->zone_db);
}
// Purge zone journals of unconfigured zones.
if (only_orphan || MATCH_AND_FILTER(args, CTL_FILTER_PURGE_JOURNAL)) {
(void)journals_walk(&args->server->journaldb, drop_journal_if_orphan, args->server);
(void)journals_walk(&args->server->journaldb,
drop_journal_if_orphan, args->server);
}
// Purge timers of unconfigured zones.
......
......@@ -223,6 +223,29 @@ int kasp_db_delete_all(knot_lmdb_db_t *db, const knot_dname_t *zone)
return txn.ret;
}
int kasp_db_sweep(knot_lmdb_db_t *db, sweep_cb keep_zone, void *cb_data)
{
if (!knot_lmdb_exists(db)) {
return KNOT_EOK;
}
int ret = knot_lmdb_open(db);
if (ret != KNOT_EOK) {
return ret;
}
knot_lmdb_txn_t txn = { 0 };
knot_lmdb_begin(db, &txn, true);
bool found = knot_lmdb_first(&txn);
while (found) {
if (*(const uint8_t *)txn.cur_key.mv_data != KASPDBKEY_POLICYLAST &&
!keep_zone((const knot_dname_t *)txn.cur_key.mv_data + 1, cb_data)) {
knot_lmdb_del_cur(&txn);
}
found = knot_lmdb_next(&txn);
}
knot_lmdb_commit(&txn);
return txn.ret;
}
int kasp_db_add_key(knot_lmdb_db_t *db, const knot_dname_t *zone_name, const key_params_t *params)
{
MDB_val v = params_serialize(params);
......@@ -381,44 +404,6 @@ int kasp_db_set_policy_last(knot_lmdb_db_t *db, const char *policy_string, const
return txn.ret;
}
static void add_dname_to_list(list_t *dst, const knot_dname_t *dname, int *ret)
{
ptrnode_t *n;
WALK_LIST(n, *dst) {
if (knot_dname_is_equal(n->d, dname)) {
return;
}
}
knot_dname_t *copy = knot_dname_copy(dname, NULL);
if (copy == NULL) {
*ret = KNOT_ENOMEM;
} else {
ptrlist_add(dst, copy, NULL);
}
}
int kasp_db_list_zones(knot_lmdb_db_t *db, list_t *dst)
{
knot_lmdb_txn_t txn = { 0 };
knot_lmdb_begin(db, &txn, false);
init_list(dst);
bool found = knot_lmdb_first(&txn);
while (found) {
const knot_dname_t *zone;
if (*(uint8_t *)txn.cur_key.mv_data != KASPDBKEY_POLICYLAST &&
knot_dname_size((zone = txn.cur_key.mv_data + 1)) < txn.cur_key.mv_size) {
add_dname_to_list(dst, zone, &txn.ret);
}
found = knot_lmdb_next(&txn);
}
knot_lmdb_abort(&txn);
if (txn.ret != KNOT_EOK) {
ptrlist_deep_free(dst, NULL);
return txn.ret;
}
return (EMPTY_LIST(*dst) ? KNOT_ENOENT : KNOT_EOK);
}
int kasp_db_store_offline_records(knot_lmdb_db_t *db, knot_time_t for_time, const key_records_t *r)
{
MDB_val k = make_key_time(KASPDBKEY_OFFLINE_RECORDS, r->rrsig.owner, for_time);
......
......@@ -64,6 +64,17 @@ int kasp_db_delete_key(knot_lmdb_db_t *db, const knot_dname_t *zone_name, const
*/
int kasp_db_delete_all(knot_lmdb_db_t *db, const knot_dname_t *zone_name);
/*!
* \brief Selectively delete zones from the database.
*
* \param db KASP dababase.
* \param keep_zone Filtering callback.
* \param cb_data Data passed to callback function.
*
* \return KNOT_E*
*/
int kasp_db_sweep(knot_lmdb_db_t *db, sweep_cb keep_zone, void *cb_data);
/*!
* \brief Add a key to the DB (possibly overwrite) and link it to a zone.
*
......@@ -174,18 +185,6 @@ int kasp_db_get_policy_last(knot_lmdb_db_t *db, const char *policy_string,
int kasp_db_set_policy_last(knot_lmdb_db_t *db, const char *policy_string, const char *last_lp_keyid,
const knot_dname_t *new_lp_zone, const char *new_lp_keyid);
/*!
* \brief List all zones that have anything stored in KASP db.
*
* It's quite slow, but we expect KASP db not to be so large.
*
* \param db KASP db
* \param dst List of zone names
*
* \return KNOT_E*
*/
int kasp_db_list_zones(knot_lmdb_db_t *db, list_t *dst);
/*!
* \brief Store pre-generated records for offline KSK usage.
*
......
......@@ -19,6 +19,7 @@
#include <lmdb.h>
#include <stdbool.h>
#include <stdint.h>
#include <stdlib.h>
#include <pthread.h>
......@@ -57,6 +58,14 @@ typedef enum {
KNOT_LMDB_FORCE = 4, /*! \brief If no matching key found, consider it a transaction failure (KNOT_ENOENT). */
} knot_lmdb_find_t;
/*!
* \brief Callback used in sweep functions.
*
* \retval true for zones to preserve.
* \retval false for zones to remove.
*/
typedef bool (*sweep_cb)(const uint8_t *zone, void *data);
/*!
* \brief Initialise the DB handling structure.
*
......
......@@ -76,14 +76,6 @@ int zone_timers_write(knot_lmdb_db_t *db, const knot_dname_t *zone,
*/
int zone_timers_write_all(knot_lmdb_db_t *db, knot_zonedb_t *zonedb);
/*!
* \brief Callback used in \ref zone_timers_sweep.
*
* \retval true for zones to preserve.
* \retval false for zones to remove.
*/
typedef bool (*sweep_cb)(const knot_dname_t *zone, void *data);
/*!
* \brief Selectively delete zones from the database.
*
......
......@@ -175,12 +175,6 @@ int main(int argc, char *argv[])
is_int(KNOT_EOK, ret, "kasp_db: load lastsigned_serial");
is_int(2, serial, "kasp_db: lastsigned_serial preserved");
ret = kasp_db_list_zones(db, &l);
is_int(KNOT_EOK, ret, "kasp_db: list_zones");
is_int(2, list_size(&l), "kasp_db: reports two zones");
is_int(0, knot_dname_cmp(((ptrnode_t *)HEAD(l))->d, zone1) | knot_dname_cmp(((ptrnode_t *)TAIL(l))->d, zone2), "kasp_db: listed correct zones");
ptrlist_deep_free(&l, NULL);
ret = kasp_db_add_key(db, zone1, &params1);
ok(ret == KNOT_EOK, "kasp_db: add key1");
ret = kasp_db_add_key(db, zone2, &params2);
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment