Skip to content

Fix catz db update callback registration logic error

Arаm Sаrgsyаn requested to merge 4136-catz-db-update-notify-bug into main

When a catalog zone is updated using AXFR, the zone database is changed, so it is required to unregister the update notification callback from the old database, and register it for the new one.

Currently, here is the order of the steps happening in such scenario:

  1. The zone.c:zone_startload() function registers the notify callback on the new database using dns_zone_catz_enable_db()
  2. The callback, when called, notices that the new 'db' is different than 'catz->db', and unregisters the old callback for 'catz->db', marks that it's unregistered by setting 'catz->db_registered' to false, then it schedules an update if it isn't already scheduled.
  3. The offloaded update process, after completing its job, notices that 'catz->db_registered' is false, and (re)registers the update callback for the current database it is working on. There is no harm here even if it was registered also on step 1, and we can't skip it, because this function can also be called "artificially" during a reconfiguration, and in that case the registration step is required here.

A problem arises when before step 1 an update process was already in a running state, operating on the old database, and finishing its work only after step 2. As described in step 3, dns__catz_update_cb() notices that 'catz->db_registered' is false and registers the callback on the current database it is working on, which, at that state, is already obsolete and unused by the zone. When it detaches the database, the function which is responsible for its cleanup (e.g. free_rbtdb()) asserts because there is a registered update notify callback there.

To fix the problem, instead of delaying the (re)registration to step 3, make sure that the new callback is registered and 'catz->db_registered' is accordingly marked on step 2.

Closes #4136 (closed)

Merge request reports