SIGN IN SIGN UP

nvmeof: fix data races on monitor-client state shared with the timer

send_beacon() runs on the timer thread under beacon_lock, while
handle_nvmeof_gw_map() runs on the dispatch thread under lock. both
touch osdmap_epoch, gwmap_epoch, last_map_time, set_group_id,
cluster_beacon_diff_included and the gw map, each written under one lock
and read under the other.

only the gw map race matters in practice. send_beacon walks it with
get_gw_state() while handle reassigns it with map = new_map, so a beacon
can follow a freed node and crash the ceph-nvmeof-monitor-client. the
beacons then stop, and if the restart outlasts the monitor's beacon
grace the gateway is marked down and its namespaces fail over to a
standby. the scalar races are word-sized stale reads with no observed
symptom. nvmeof gateway deployments only.

user i/o is unaffected unless that failover fires, since the block data
path never runs the racy code. on failover multipath hosts briefly
repath to the standby and single-path ones stall on the owned
namespaces, with no data loss or corruption either way.

make the shared scalars atomic and keep the map private to the dispatch
thread. send_beacon only needs to know whether this gateway is in the
map, so it reads an atomic gw_in_map flag that handle publishes instead
of the map.

send_beacon also read cluster_beacon_diff_included twice per beacon, to
pick the payload and to set its format flag, so a concurrent flip could
tag a diff payload as full. snapshot it once.

Signed-off-by: Kefu Chai <k.chai@proxmox.com>
K
Kefu Chai committed
fdbd18af9a3085891820f34aa2868056bb54bcb0
Parent: c11c714