]> git.ipfire.org Git - thirdparty/systemd.git/commitdiff
vmspawn-qmp: convert DriveInfo to a refcounted object
authorChristian Brauner <brauner@kernel.org>
Tue, 21 Apr 2026 22:23:02 +0000 (00:23 +0200)
committerChristian Brauner <brauner@kernel.org>
Fri, 24 Apr 2026 12:39:25 +0000 (14:39 +0200)
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>
src/vmspawn/vmspawn-qmp.c
src/vmspawn/vmspawn-qmp.h
src/vmspawn/vmspawn.c

index 702e2e658e93b9d8221d4131724bbc7d4a19e44c..23ae4f73f82d7d8267298e4f958680edb4312c70 100644 (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);
index 0bc73c90abc78811d3e7327a921fc5efdcf29cbe..391ac2d5bda4aa7a9342a0b09a043adb21d31c99 100644 (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 */
index 029ae4eacd26330ea45a8732644c2baf48b9755b..e927812fe7a77988e8d75cef7f0601af9b43f8de 100644 (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();