All Virtuozzo development lists (kernel + QEMU)
 help / color / mirror / Atom feed
From: "Denis V. Lunev" <den@openvz.org>
To: svt-core@virtuozzo.com
Cc: andrey.drobyshev@virtuozzo.com, den@openvz.org
Subject: [PATCH v2-hci-8.0 0/2] migration/cpr: lock the cpr state #VSTOR-145529
Date: Fri, 18 Sep 2026 16:36:27 +0200	[thread overview]
Message-ID: <20260918143629.236874-1-den@openvz.org> (raw)

A guest died with SIGSEGV in find_fd() after a routine libvirtd restart.
The fd registry in cpr_state has no lock, and since we started saving
chardev connection fds it is reached from more than one thread.

A socket chardev saves and drops its connection fd in
tcp_chr_new_client() and tcp_chr_free_connection(), which run in the
chardev's GMainContext. For libvirt's monitor that context belongs to the
QMP iothread, while the guest agent channels and the serial pty stay on
the main loop. A libvirtd restart reconnects all of them at once, so two
threads run QLIST_INSERT_HEAD and QLIST_REMOVE on one list. The core on
mhw0501 shows the head left on an entry the iothread allocated and freed,
with the real list intact and unreachable behind it.

Taking the BQL in the chardev hooks is not an option. The chardev layer
never takes it, monitor_cleanup() stops the QMP iothread while holding
it, and the iothread exists precisely so out-of-band commands keep
working when the main thread will not release it. The lock belongs to the
registry.

The body is worded free of chardev and QLIST specifics on purpose: the
same text serves upstream, where cpr.c has been rewritten around a
GHashTable and nothing reaches the state off the main thread. Patch 1 is
that shared part, so it stops at the fd accessors. Patch 2 covers the
ramblock list, which upstream does not have.

v1 -> v2, all of it narrowing the lock to a leaf over the list alone:

- out of the vmstate walks. The save walk runs the subsection callbacks
  and hands each fd to the peer with a blocking write, and a load hook
  that saved an fd would deadlock against itself. The load side needs no
  lock anyway, running before qemu_create_early_backends().
- out of cpr_open_fd(), which held it across qemu_open().
- patch 1's commit message trimmed to match.

So cpr_state_save() now walks the fd list unlocked and can still race a
chardev accept. Closing that needs a copy of the list taken under the
lock, which first needs cpr_cpu_hotplug_needed() to use its opaque
instead of the global cpr_state.

Tested on dev-cl04 against this base: migrate-cpr-exec, migration-test
--full, check-unit and the raw iotests all pass. The qcow2 iotests leave
vz-kernel-cbt and vz-mt-vendor, which fail the same way on the parent
commit.

Denis V. Lunev (2):
  migration/cpr: lock the saved fds #VSTOR-145529
  migration/cpr: lock the ramblocks #VSTOR-145529

 migration/cpr.c | 69 ++++++++++++++++++++++++++++++++++++++++++++++++---------
 1 file changed, 58 insertions(+), 11 deletions(-)


base-commit: 87f111d087cff956908ccb22daedb596b3734877
-- 
2.53.0


             reply	other threads:[~2026-09-18 14:37 UTC|newest]

Thread overview: 3+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2026-09-18 14:36 Denis V. Lunev [this message]
2026-09-18 14:36 ` [PATCH v2-hci-8.0 1/2] migration/cpr: lock the saved fds #VSTOR-145529 Denis V. Lunev
2026-09-18 14:36 ` [PATCH v2-hci-8.0 2/2] migration/cpr: lock the ramblocks #VSTOR-145529 Denis V. Lunev

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20260918143629.236874-1-den@openvz.org \
    --to=den@openvz.org \
    --cc=andrey.drobyshev@virtuozzo.com \
    --cc=svt-core@virtuozzo.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.