]> git.ipfire.org Git - thirdparty/knot-dns.git/commitdiff
ctl: disallow simultaneous backup and zone transaction
authorLibor Peltan <libor.peltan@nic.cz>
Thu, 16 May 2024 09:35:04 +0000 (11:35 +0200)
committerDaniel Salzman <daniel.salzman@nic.cz>
Fri, 17 May 2024 07:31:56 +0000 (09:31 +0200)
src/knot/ctl/commands.c
tests-extra/tests/ctl/blocking_txn/test.py

index ca3822fc4a511d38912f6ac3618e77b3c2bc3942..3068f314872d6f280a65a06420fb13e6d211c244 100644 (file)
@@ -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;
index dbfe1646ec31f0c96f473b8c475e4a5aac1d8d08..f5dab0761a2cacef78d4854dbd25483d6abea5e1 100644 (file)
@@ -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()