vmspawn: factor out the synchronous QMP pump

The upcoming boot-time device setup will need the same synchronous
driving of the QMP client before resuming the VM.

Move the loop into a helper, and generalize the error messages.

Signed-off-by: Martin Pitt <martin@amutable.com>
(cherry picked from commit 73833bdddfd4e8a1aa003516a8eda53515c9110f)
This commit is contained in:
Martin Pitt
2026-10-16 17:24:51 +01:00
committed by Luca Boccassi
parent ad0f1d66f2
commit e4c45cae51
+25 -13
View File
@@ -2007,6 +2007,28 @@ int vmspawn_qmp_init(VmspawnQmpBridge **ret, int fd, sd_event *event) {
return 0;
}
/* Canonical sync-on-async pump, matching varlink_call_internal(). The QMP client tracks
* outstanding replies in its own slots set; drain until it's idle. */
static int vmspawn_qmp_bridge_drain(VmspawnQmpBridge *bridge) {
int r;
assert(bridge);
while (!qmp_client_is_idle(bridge->qmp)) {
r = qmp_client_process(bridge->qmp);
if (r < 0)
return log_error_errno(r, "Failed to process QMP messages: %m");
if (r > 0)
continue;
r = qmp_client_wait(bridge->qmp, USEC_INFINITY);
if (r < 0)
return log_error_errno(r, "Failed to wait for QMP messages: %m");
}
return 0;
}
int vmspawn_qmp_probe_features(VmspawnQmpBridge *bridge) {
int r;
@@ -2022,19 +2044,9 @@ int vmspawn_qmp_probe_features(VmspawnQmpBridge *bridge) {
if (r < 0)
return log_error_errno(r, "Failed to issue schema probe: %m");
/* Canonical sync-on-async pump, matching varlink_call_internal(). The QMP client tracks
* outstanding replies in its own slots set; drain until it's idle. */
while (!qmp_client_is_idle(bridge->qmp)) {
r = qmp_client_process(bridge->qmp);
if (r < 0)
return log_error_errno(r, "QMP probe pump failed: %m");
if (r > 0)
continue;
r = qmp_client_wait(bridge->qmp, USEC_INFINITY);
if (r < 0)
return log_error_errno(r, "QMP probe wait failed: %m");
}
r = vmspawn_qmp_bridge_drain(bridge);
if (r < 0)
return r;
/* If fail_pending() drained the slots (transport dropped mid-probe), features can't be
* trusted and we have no QMP channel for device setup anyway. */