vmspawn-qmp: convert DriveInfo to a refcounted object

In preparation for runtime block-device hotplug, where in-flight QMP
callbacks need to keep a slot reference on the DriveInfo while the bridge
also holds it in its block-device registry. Today each DriveInfo has
exactly one owner; switch the API from drive_info_free() /
drive_info_freep to drive_info_ref() / drive_info_unref() /
drive_info_unrefp so future code can take additional refs without the
caller losing track of ownership.

drive_info_new() initialises n_ref to 1 (one ref for the caller). The
existing drive_infos_done() and the prepare_*_drive() callers in
vmspawn.c are switched to the unref form. No behaviour change: each
DriveInfo still has exactly one ref at every point in this commit.

Signed-off-by: Christian Brauner (Amutable) <brauner@kernel.org>
This commit is contained in:
Christian Brauner
2026-04-24 14:39:25 +02:00
parent 06816dfee3
commit f0c1dc50ef
3 changed files with 11 additions and 8 deletions
+6 -4
View File
@@ -31,15 +31,15 @@ DriveInfo* drive_info_new(void) {
return NULL;
*d = (DriveInfo) {
.n_ref = 1,
.fd = -EBADF,
.overlay_fd = -EBADF,
};
return d;
}
DriveInfo* drive_info_free(DriveInfo *d) {
if (!d)
return NULL;
static DriveInfo* drive_info_free(DriveInfo *d) {
assert(d);
free(d->path);
free(d->format);
@@ -52,10 +52,12 @@ DriveInfo* drive_info_free(DriveInfo *d) {
return mfree(d);
}
DEFINE_TRIVIAL_REF_UNREF_FUNC(DriveInfo, drive_info, drive_info_free);
void drive_infos_done(DriveInfos *infos) {
assert(infos);
FOREACH_ARRAY(d, infos->drives, infos->n_drives)
drive_info_free(*d);
drive_info_unref(*d);
infos->drives = mfree(infos->drives);
infos->n_drives = 0;
infos->scsi_pcie_port = mfree(infos->scsi_pcie_port);
+3 -2
View File
@@ -71,6 +71,7 @@ typedef enum QmpDriveFlags {
* Each DriveInfo is individually heap-allocated so it can be handed off
* to the block device registry via TAKE_PTR. */
typedef struct DriveInfo {
unsigned n_ref;
char *path; /* original path (for logging; not passed to QEMU) */
char *format; /* "raw" or "qcow2" */
char *disk_driver; /* "virtio-blk-pci", "scsi-hd", "scsi-cd", "nvme" */
@@ -83,8 +84,8 @@ typedef struct DriveInfo {
} DriveInfo;
DriveInfo* drive_info_new(void);
DriveInfo* drive_info_free(DriveInfo *d);
DEFINE_TRIVIAL_CLEANUP_FUNC(DriveInfo *, drive_info_free);
DECLARE_TRIVIAL_REF_UNREF_FUNC(DriveInfo, drive_info);
DEFINE_TRIVIAL_CLEANUP_FUNC(DriveInfo *, drive_info_unref);
typedef struct DriveInfos {
DriveInfo **drives; /* array of individually heap-allocated entries */
+2 -2
View File
@@ -2319,7 +2319,7 @@ static int prepare_primary_drive(const char *runtime_dir, DriveInfos *drives) {
if (r < 0)
return log_error_errno(r, "Failed to extract filename from path '%s': %m", arg_image);
_cleanup_(drive_info_freep) DriveInfo *d = drive_info_new();
_cleanup_(drive_info_unrefp) DriveInfo *d = drive_info_new();
if (!d)
return log_oom();
@@ -2389,7 +2389,7 @@ static int prepare_extra_drives(DriveInfos *drives) {
DiskType dt = drive->disk_type >= 0 ? drive->disk_type : arg_image_disk_type;
_cleanup_(drive_info_freep) DriveInfo *d = drive_info_new();
_cleanup_(drive_info_unrefp) DriveInfo *d = drive_info_new();
if (!d)
return log_oom();