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:
@@ -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);
|
||||
|
||||
@@ -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 */
|
||||
|
||||
@@ -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();
|
||||
|
||||
|
||||
Reference in New Issue
Block a user