vmspawn: track removability as a QmpDriveFlags bit and expose add_block_device
Drives attached at boot via the existing CLI options (--image, --extra-drive) must not be detachable at runtime via the upcoming RemoveStorage Varlink method, while drives added at runtime via AddStorage must be. Track this distinction with a new QMP_DRIVE_REMOVABLE property flag — placed alongside QMP_DRIVE_BLOCK_DEVICE, not in the transient BlockDeviceStateFlags state-machine, since "may be removed" is a permanent property of the drive. vmspawn_qmp_remove_block_device() now early-rejects unknown ids with io.systemd.MachineInstance.NoSuchStorage and immutable drives with io.systemd.MachineInstance.StorageImmutable. vmspawn_qmp_add_block_device() loses its 'static' qualifier and gets a declaration in the header, so the runtime hotplug path (vmspawn-bind-volume.c, next) can dispatch into it directly. Signed-off-by: Christian Brauner (Amutable) <brauner@kernel.org>
This commit is contained in:
@@ -826,7 +826,7 @@ static int on_add_device_add_complete(
|
||||
return 0;
|
||||
|
||||
if (d->link) {
|
||||
(void) sd_varlink_replybo(d->link, SD_JSON_BUILD_PAIR_STRING("id", d->id));
|
||||
(void) sd_varlink_reply(d->link, NULL);
|
||||
d->link = sd_varlink_unref(d->link);
|
||||
}
|
||||
|
||||
@@ -882,7 +882,7 @@ static int qmp_setup_scsi_controller(VmspawnQmpBridge *bridge, const char *pcie_
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int vmspawn_qmp_add_block_device(VmspawnQmpBridge *bridge, DriveInfo *drive) {
|
||||
int vmspawn_qmp_add_block_device(VmspawnQmpBridge *bridge, DriveInfo *drive) {
|
||||
int r;
|
||||
|
||||
assert(bridge);
|
||||
@@ -989,7 +989,6 @@ static int qmp_setup_regular_drive(VmspawnQmpBridge *bridge, DriveInfo *drive) {
|
||||
assert(bridge);
|
||||
assert(drive);
|
||||
assert(drive->fd >= 0);
|
||||
assert(!drive->id);
|
||||
|
||||
return vmspawn_qmp_add_block_device(bridge, drive);
|
||||
}
|
||||
@@ -1028,7 +1027,9 @@ int vmspawn_qmp_remove_block_device(VmspawnQmpBridge *bridge, sd_varlink *link,
|
||||
|
||||
DriveInfo *drive = hashmap_get(bridge->block_devices, id);
|
||||
if (!drive)
|
||||
return reply_qmp_error(link, "Unknown block device id", -ENOENT);
|
||||
return sd_varlink_error(link, "io.systemd.MachineInstance.NoSuchStorage", NULL);
|
||||
if (!FLAGS_SET(drive->flags, QMP_DRIVE_REMOVABLE))
|
||||
return sd_varlink_error(link, "io.systemd.MachineInstance.StorageImmutable", NULL);
|
||||
if (!FLAGS_SET(drive->state, BLOCK_DEVICE_STATE_BLOCKDEV_ADDED))
|
||||
return reply_qmp_error(link, "Block device add pending", -EBUSY);
|
||||
if (FLAGS_SET(drive->state, BLOCK_DEVICE_STATE_REMOVE_PENDING))
|
||||
|
||||
@@ -72,6 +72,7 @@ typedef enum QmpDriveFlags {
|
||||
QMP_DRIVE_BOOT = 1u << 4,
|
||||
QMP_DRIVE_IO_URING = 1u << 5,
|
||||
QMP_DRIVE_DISCARD_NO_UNREF = 1u << 6, /* qcow2 only */
|
||||
QMP_DRIVE_REMOVABLE = 1u << 7, /* may be detached at runtime via RemoveStorage */
|
||||
} QmpDriveFlags;
|
||||
|
||||
typedef enum BlockDeviceStateFlags {
|
||||
@@ -177,5 +178,6 @@ int vmspawn_qmp_setup_drives(VmspawnQmpBridge *bridge, DriveInfos *drives);
|
||||
int vmspawn_qmp_setup_network(VmspawnQmpBridge *bridge, NetworkInfo *network);
|
||||
int vmspawn_qmp_setup_virtiofs(VmspawnQmpBridge *bridge, const VirtiofsInfos *virtiofs);
|
||||
int vmspawn_qmp_setup_vsock(VmspawnQmpBridge *bridge, VsockInfo *vsock);
|
||||
int vmspawn_qmp_add_block_device(VmspawnQmpBridge *bridge, DriveInfo *drive);
|
||||
int vmspawn_qmp_remove_block_device(VmspawnQmpBridge *bridge, sd_varlink *link, const char *id);
|
||||
int vmspawn_qmp_dispatch_device_deleted(VmspawnQmpBridge *bridge, sd_json_variant *data);
|
||||
|
||||
Reference in New Issue
Block a user