From: Libor Peltan Date: Thu, 16 May 2024 09:35:04 +0000 (+0200) Subject: ctl: disallow simultaneous backup and zone transaction X-Git-Tag: v3.4.0~97^2 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=a753d828;p=thirdparty%2Fknot-dns.git ctl: disallow simultaneous backup and zone transaction --- diff --git a/src/knot/ctl/commands.c b/src/knot/ctl/commands.c index ca3822fc4a..3068f31487 100644 --- a/src/knot/ctl/commands.c +++ b/src/knot/ctl/commands.c @@ -652,6 +652,12 @@ static int zone_backup_cmd(zone_t *zone, ctl_args_t *args) return KNOT_EPROGRESS; } + if (ctx->restore_mode && zone->control_update != NULL) { + log_zone_warning(zone->name, "restoring backup not possible due to open control transaction"); + ctx->failed = true; + return KNOT_TXN_EEXISTS; + } + ctx->zone_count++; int ret; @@ -852,6 +858,11 @@ static int zone_txn_begin(zone_t *zone, _unused_ ctl_args_t *args) return KNOT_TXN_EEXISTS; } + if (zone->backup_ctx != NULL) { + log_zone_warning(zone->name, "zone backup/restore pending, try opening control transaction later"); + return KNOT_EAGAIN; + } + zone->control_update = malloc(sizeof(zone_update_t)); if (zone->control_update == NULL) { return KNOT_ENOMEM; diff --git a/tests-extra/tests/ctl/blocking_txn/test.py b/tests-extra/tests/ctl/blocking_txn/test.py index dbfe1646ec..f5dab0761a 100644 --- a/tests-extra/tests/ctl/blocking_txn/test.py +++ b/tests-extra/tests/ctl/blocking_txn/test.py @@ -14,6 +14,19 @@ def background_sign(server, zone_name): except: pass +def background_backup(server, zone_name): + bckdir = "%s/backup" % server.dir + server.ctl("zone-backup +backupdir " + bckdir) + attempts = 10 + while attempts > 0: + attempts -= 1 + try: + time.sleep(2) + server.ctl("zone-restore +backupdir " + bckdir) + attempts = 0 + except: + pass + def run_thr(fun, server, zone_name): threading.Thread(target=fun, args=[server, zone_name]).start() @@ -36,7 +49,31 @@ t.sleep(1) master.ctl("zone-abort " + ZONE) t.sleep(1) -master.zones_wait(zones) # check if server is still sane +serials = master.zones_wait(zones) # check if server is still sane +master.ctl("zone-status " + ZONE) + +# scenario 2: zone restore with open txn + +BACKUP_FIRST = random.choice([False, True]) +detail_log("BACKUP_FIRST: " + str(BACKUP_FIRST)) + +if not BACKUP_FIRST: + master.ctl("zone-begin " + ZONE) +run_thr(background_backup, master, ZONE) +if BACKUP_FIRST: + t.sleep(2.1) + master.zones_wait(zones) + try: + master.ctl("zone-begin " + ZONE) + except: + t.sleep(1) + master.zones_wait(zones) + master.ctl("zone-begin " + ZONE) +master.ctl("zone-set " + ZONE + " dhowedhhjewodw 3600 A 1.2.3.4") +t.sleep(3) +master.ctl("zone-commit " + ZONE) + +master.zones_wait(zones, serials, equal=True, greater=BACKUP_FIRST) master.ctl("zone-status " + ZONE) t.end()