From: Christian Brauner Date: Tue, 21 Apr 2026 22:23:02 +0000 (+0200) Subject: vmspawn-qmp: convert DriveInfo to a refcounted object X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=f0c1dc50ef0fcc38af438f445ceaed3cefb242d1;p=thirdparty%2Fsystemd.git 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) --- diff --git a/src/vmspawn/vmspawn-qmp.c b/src/vmspawn/vmspawn-qmp.c index 702e2e658e9..23ae4f73f82 100644 --- a/src/vmspawn/vmspawn-qmp.c +++ b/src/vmspawn/vmspawn-qmp.c @@ -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); diff --git a/src/vmspawn/vmspawn-qmp.h b/src/vmspawn/vmspawn-qmp.h index 0bc73c90abc..391ac2d5bda 100644 --- a/src/vmspawn/vmspawn-qmp.h +++ b/src/vmspawn/vmspawn-qmp.h @@ -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 */ diff --git a/src/vmspawn/vmspawn.c b/src/vmspawn/vmspawn.c index 029ae4eacd2..e927812fe7a 100644 --- a/src/vmspawn/vmspawn.c +++ b/src/vmspawn/vmspawn.c @@ -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();