vmspawn-qmp: take temporary ref in drive_info_add_fail

drive_info_add_fail() calls bridge_unregister_drive() followed by
drive_info_unref(), then continues to access the DriveInfo object.
While all current callers hold their own reference, it is a bit
fragile and it trips static analyzers. Take a local reference.

CID#1655804

Follow-up for 1d0a8e5dbd
This commit is contained in:
Luca Boccassi
2026-05-05 14:39:38 +01:00
parent 83436d4b7e
commit 5eb256c99b
+12 -9
View File
@@ -730,23 +730,26 @@ static int drive_info_add_fail(DriveInfo *d, int error, const char *error_desc)
if (FLAGS_SET(d->state, BLOCK_DEVICE_STATE_ADD_FAILED))
return 0;
vmspawn_qmp_block_device_teardown(d->bridge->qmp, d->qmp_node_name, d->state);
d->state = BLOCK_DEVICE_STATE_ADD_FAILED;
/* Pin the object alive across bridge_unregister_drive() + drive_info_unref() below. */
_cleanup_(drive_info_unrefp) DriveInfo *ref = drive_info_ref(d);
if (bridge_unregister_drive(d->bridge, d))
drive_info_unref(d);
vmspawn_qmp_block_device_teardown(ref->bridge->qmp, ref->qmp_node_name, ref->state);
ref->state = BLOCK_DEVICE_STATE_ADD_FAILED;
if (d->link) {
(void) reply_qmp_error(d->link, error_desc, error);
d->link = sd_varlink_unref(d->link);
if (bridge_unregister_drive(ref->bridge, ref))
drive_info_unref(ref);
if (ref->link) {
(void) reply_qmp_error(ref->link, error_desc, error);
ref->link = sd_varlink_unref(ref->link);
return 0;
}
log_error_errno(error, "Block device '%s' setup failed: %s",
strna(d->id), strna(error_desc));
strna(ref->id), strna(error_desc));
/* Boot-time (link == NULL) is always fatal — even for late-arriving ephemeral replies. */
return sd_event_exit(qmp_client_get_event(d->bridge->qmp), error);
return sd_event_exit(qmp_client_get_event(ref->bridge->qmp), error);
}
/* Rolls back the up-front registry insert on a sync error path. */