]> git-server-git.apps.pok.os.sepia.ceph.com Git - ceph-ci.git/commitdiff
nvmeofgw: prevent map corruption while processing beacons from deleted gws squid-nvmeof-8.0
authorLeonid Chernin <leonidc@il.ibm.com>
Mon, 8 Dec 2025 20:54:44 +0000 (22:54 +0200)
committerLeonid Chernin <leonidc@il.ibm.com>
Tue, 23 Dec 2025 07:21:19 +0000 (09:21 +0200)
Fix race issue of map corruption when deleted gw sends beacons
but this gw data was removed from pending map and still exists in map.
Process beacons only if GW's data exists in both maps:
main-map and pending-map, otherwise just ignore beacons.

fixes: https://tracker.ceph.com/issues/74160

Signed-off-by: Leonid Chernin <leonidc@il.ibm.com>
src/mon/NVMeofGwMon.cc

index 9ba23eb0e9b030222fe1856ec65b709351fdaed2..b354e6152e6c1bfebd1efd4feda8d055fe79c7d2 100644 (file)
@@ -514,11 +514,15 @@ bool NVMeofGwMon::prepare_beacon(MonOpRequestRef op)
   NVMeofGwMap ack_map;
   auto& group_gws = map.created_gws[group_key];
   auto gw = group_gws.find(gw_id);
+  auto& pend_gws =  pending_map.created_gws[group_key];
+  auto pend_gw = pend_gws.find(gw_id);
+
+  bool gw_exists = (gw != group_gws.end() && (pend_gw != pend_gws.end()));
   const BeaconSubsystems& sub = m->get_subsystems();
   auto now = ceph::coarse_mono_clock::now();
 
   if (avail == gw_availability_t::GW_CREATED) {
-    if (gw == group_gws.end()) {
+    if (!gw_exists) {
       gw_created = false;
       dout(10) << "Warning: GW " << gw_id << " group_key " << group_key
               << " was not found in the  map.Created_gws "
@@ -546,9 +550,10 @@ bool NVMeofGwMon::prepare_beacon(MonOpRequestRef op)
       goto set_propose;
     }
   // gw already created
-  } else {
-    // if GW reports Available but in monitor's database it is Unavailable
-    if (gw != group_gws.end()) {
+
+  } else { // first GW beacon should come with avail = Created
+    // if GW reports Avail/Unavail but in monitor's database it is Unavailable
+    if (gw_exists) {
       // it means it did not perform "exit" after failover was set by
       // NVMeofGWMon
       if ((pending_map.created_gws[group_key][gw_id].availability ==
@@ -567,9 +572,8 @@ bool NVMeofGwMon::prepare_beacon(MonOpRequestRef op)
       }
     }
   }
-
-  // At this stage the gw has to be in the Created_gws
-  if (gw == group_gws.end()) {
+  // Beacon from GW in !Created state but it does not appear in the map
+  if (!gw_exists) {
     dout(4) << "GW that does not appear in the map sends beacon, ignore "
        << gw_id << dendl;
     mon.no_reply(op);