If an object has an established watch, serving a read from replica
eventually leads to an assert in is_degraded_or_backfilling_object()
called from handle_watch_timeout().
The issue is that after can_serve_replica_read() check is satisfied,
we look up the object context. If not found, we fetch the object info
and then call populate_obc_watchers() which sees the recorded watch and
treats it as unconnected, arming HandleWatchTimeout on replica.
Fixes: https://tracker.ceph.com/issues/45795
Signed-off-by: Ilya Dryomov <idryomov@gmail.com>
void PrimaryLogPG::populate_obc_watchers(ObjectContextRef obc)
{
- ceph_assert(is_active());
+ ceph_assert(is_primary() && is_active());
auto it_objects = recovery_state.get_pg_log().get_log().objects.find(obc->obs.oi.soid);
ceph_assert((recovering.count(obc->obs.oi.soid) ||
!is_missing_object(obc->obs.oi.soid)) ||
soid, true,
soid.has_snapset() ? attrs : 0);
- if (is_active())
+ if (is_primary() && is_active())
populate_obc_watchers(obc);
if (pool.info.is_erasure()) {