]> git-server-git.apps.pok.os.sepia.ceph.com Git - ceph.git/commit
rgw/beast: dispatch connection close on strand during pause 68920/head
authorLumir Sliva <61183145+lumir-sliva@users.noreply.github.com>
Fri, 24 Apr 2026 11:01:23 +0000 (13:01 +0200)
committerAdam C. Emerson <aemerson@redhat.com>
Wed, 8 Jul 2026 21:06:08 +0000 (17:06 -0400)
commit1430b8855352b4d682e1186005861f18e9eb7e45
tree0db86b45080cffb48a01fc86978eb2d24d91afed
parent3ab380f6f8435095cca2c67464c5ca6f06fee81c
rgw/beast: dispatch connection close on strand during pause

AsioFrontend::pause() (and stop()) call ConnectionList::close() from
the realm reloader thread. That invokes socket.close() on every live
connection from a thread that isn't the connection's asio strand, so
the reactor deregisters each socket's descriptor_state racing against
the coroutine that handles the connection. If a keep-alive connection
is starting its next async_read_some() on its strand at the same time,
epoll_reactor::start_op() dereferences the descriptor_state that close
has already freed and radosgw segfaults in an io_context_pool thread.

This matches the race pattern fixed for timeout_timer in 86ad0b891b0:
any caller that touches socket state from outside the strand needs to
be serialized with the coroutine.

Store the coroutine's strand executor on Connection and dispatch the
close onto that strand in ConnectionList::close(). The lambda captures
an intrusive_ptr to Connection so the object lives until the close
actually runs, since connections.clear() unlinks the list entry right
after dispatch.

Tracker: https://tracker.ceph.com/issues/76094
Signed-off-by: Lumir Sliva <61183145+lumir-sliva@users.noreply.github.com>
Update `unittest_rgw_asio_frontend` to run the `io_context` and
execute in a coroutine to match the environment in RGW.

Signed-off-by: Adam C. Emerson <aemerson@redhat.com>
src/rgw/rgw_asio_frontend.cc
src/rgw/rgw_asio_frontend_connection.h
src/test/rgw/test_rgw_asio_frontend_connection.cc