mirror of
https://gitlab.com/libvirt/libvirt.git
synced 2025-01-05 04:25:19 +00:00
qemu: implement virtiofs hotunplug
Signed-off-by: Ján Tomko <jtomko@redhat.com> Reviewed-by: Peter Krempa <pkrempa@redhat.com>
This commit is contained in:
parent
b987873034
commit
0d2ea8873b
@ -28918,6 +28918,30 @@ virDomainFSRemove(virDomainDef *def, size_t i)
|
|||||||
return fs;
|
return fs;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ssize_t
|
||||||
|
virDomainFSDefFind(virDomainDef *def,
|
||||||
|
virDomainFSDef *fs)
|
||||||
|
{
|
||||||
|
size_t i = 0;
|
||||||
|
|
||||||
|
for (i = 0; i < def->nfss; i++) {
|
||||||
|
virDomainFSDef *tmp = def->fss[i];
|
||||||
|
|
||||||
|
if (fs->dst && STRNEQ_NULLABLE(fs->dst, tmp->dst))
|
||||||
|
continue;
|
||||||
|
|
||||||
|
if (fs->info.type != VIR_DOMAIN_DEVICE_ADDRESS_TYPE_NONE &&
|
||||||
|
!virDomainDeviceInfoAddressIsEqual(&fs->info, &tmp->info))
|
||||||
|
continue;
|
||||||
|
|
||||||
|
if (fs->info.alias && STRNEQ_NULLABLE(fs->info.alias, tmp->info.alias))
|
||||||
|
continue;
|
||||||
|
|
||||||
|
return i;
|
||||||
|
}
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
virDomainFSDef *
|
virDomainFSDef *
|
||||||
virDomainGetFilesystemForTarget(virDomainDef *def,
|
virDomainGetFilesystemForTarget(virDomainDef *def,
|
||||||
const char *target)
|
const char *target)
|
||||||
|
@ -3765,6 +3765,8 @@ virDomainFSDef *virDomainGetFilesystemForTarget(virDomainDef *def,
|
|||||||
int virDomainFSInsert(virDomainDef *def, virDomainFSDef *fs);
|
int virDomainFSInsert(virDomainDef *def, virDomainFSDef *fs);
|
||||||
int virDomainFSIndexByName(virDomainDef *def, const char *name);
|
int virDomainFSIndexByName(virDomainDef *def, const char *name);
|
||||||
virDomainFSDef *virDomainFSRemove(virDomainDef *def, size_t i);
|
virDomainFSDef *virDomainFSRemove(virDomainDef *def, size_t i);
|
||||||
|
ssize_t virDomainFSDefFind(virDomainDef *def,
|
||||||
|
virDomainFSDef *fs);
|
||||||
|
|
||||||
unsigned int virDomainVideoDefaultRAM(const virDomainDef *def,
|
unsigned int virDomainVideoDefaultRAM(const virDomainDef *def,
|
||||||
const virDomainVideoType type);
|
const virDomainVideoType type);
|
||||||
|
@ -410,6 +410,7 @@ virDomainFeatureTypeFromString;
|
|||||||
virDomainFeatureTypeToString;
|
virDomainFeatureTypeToString;
|
||||||
virDomainFSAccessModeTypeToString;
|
virDomainFSAccessModeTypeToString;
|
||||||
virDomainFSCacheModeTypeToString;
|
virDomainFSCacheModeTypeToString;
|
||||||
|
virDomainFSDefFind;
|
||||||
virDomainFSDefFree;
|
virDomainFSDefFree;
|
||||||
virDomainFSDefNew;
|
virDomainFSDefNew;
|
||||||
virDomainFSDriverTypeToString;
|
virDomainFSDriverTypeToString;
|
||||||
|
@ -5206,6 +5206,47 @@ qemuDomainRemoveRedirdevDevice(virQEMUDriver *driver,
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static int
|
||||||
|
qemuDomainRemoveFSDevice(virQEMUDriver *driver,
|
||||||
|
virDomainObj *vm,
|
||||||
|
virDomainFSDef *fs)
|
||||||
|
{
|
||||||
|
g_autofree char *charAlias = NULL;
|
||||||
|
qemuDomainObjPrivate *priv = vm->privateData;
|
||||||
|
ssize_t idx;
|
||||||
|
int rc = 0;
|
||||||
|
|
||||||
|
VIR_DEBUG("Removing FS device %s from domain %p %s",
|
||||||
|
fs->info.alias, vm, vm->def->name);
|
||||||
|
|
||||||
|
if (fs->fsdriver == VIR_DOMAIN_FS_DRIVER_TYPE_VIRTIOFS) {
|
||||||
|
charAlias = qemuDomainGetVhostUserChrAlias(fs->info.alias);
|
||||||
|
|
||||||
|
qemuDomainObjEnterMonitor(driver, vm);
|
||||||
|
|
||||||
|
if (qemuMonitorDetachCharDev(priv->mon, charAlias) < 0)
|
||||||
|
rc = -1;
|
||||||
|
|
||||||
|
if (qemuDomainObjExitMonitor(driver, vm) < 0)
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
virDomainAuditFS(vm, fs, NULL, "detach", rc == 0);
|
||||||
|
|
||||||
|
if (rc < 0)
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
if (!fs->sock && fs->fsdriver == VIR_DOMAIN_FS_DRIVER_TYPE_VIRTIOFS)
|
||||||
|
qemuVirtioFSStop(driver, vm, fs);
|
||||||
|
|
||||||
|
if ((idx = virDomainFSDefFind(vm->def, fs)) >= 0)
|
||||||
|
virDomainFSRemove(vm->def, idx);
|
||||||
|
qemuDomainReleaseDeviceAddress(vm, &fs->info);
|
||||||
|
virDomainFSDefFree(fs);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
static void
|
static void
|
||||||
qemuDomainRemoveAuditDevice(virDomainObj *vm,
|
qemuDomainRemoveAuditDevice(virDomainObj *vm,
|
||||||
virDomainDeviceDef *detach,
|
virDomainDeviceDef *detach,
|
||||||
@ -5244,6 +5285,10 @@ qemuDomainRemoveAuditDevice(virDomainObj *vm,
|
|||||||
virDomainAuditRedirdev(vm, detach->data.redirdev, "detach", success);
|
virDomainAuditRedirdev(vm, detach->data.redirdev, "detach", success);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case VIR_DOMAIN_DEVICE_FS:
|
||||||
|
virDomainAuditFS(vm, detach->data.fs, NULL, "detach", success);
|
||||||
|
break;
|
||||||
|
|
||||||
case VIR_DOMAIN_DEVICE_LEASE:
|
case VIR_DOMAIN_DEVICE_LEASE:
|
||||||
case VIR_DOMAIN_DEVICE_CONTROLLER:
|
case VIR_DOMAIN_DEVICE_CONTROLLER:
|
||||||
case VIR_DOMAIN_DEVICE_WATCHDOG:
|
case VIR_DOMAIN_DEVICE_WATCHDOG:
|
||||||
@ -5251,7 +5296,6 @@ qemuDomainRemoveAuditDevice(virDomainObj *vm,
|
|||||||
/* These devices don't have associated audit logs */
|
/* These devices don't have associated audit logs */
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case VIR_DOMAIN_DEVICE_FS:
|
|
||||||
case VIR_DOMAIN_DEVICE_SOUND:
|
case VIR_DOMAIN_DEVICE_SOUND:
|
||||||
case VIR_DOMAIN_DEVICE_VIDEO:
|
case VIR_DOMAIN_DEVICE_VIDEO:
|
||||||
case VIR_DOMAIN_DEVICE_GRAPHICS:
|
case VIR_DOMAIN_DEVICE_GRAPHICS:
|
||||||
@ -5349,9 +5393,13 @@ qemuDomainRemoveDevice(virQEMUDriver *driver,
|
|||||||
return -1;
|
return -1;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case VIR_DOMAIN_DEVICE_FS:
|
||||||
|
if (qemuDomainRemoveFSDevice(driver, vm, dev->data.fs) < 0)
|
||||||
|
return -1;
|
||||||
|
break;
|
||||||
|
|
||||||
case VIR_DOMAIN_DEVICE_NONE:
|
case VIR_DOMAIN_DEVICE_NONE:
|
||||||
case VIR_DOMAIN_DEVICE_LEASE:
|
case VIR_DOMAIN_DEVICE_LEASE:
|
||||||
case VIR_DOMAIN_DEVICE_FS:
|
|
||||||
case VIR_DOMAIN_DEVICE_SOUND:
|
case VIR_DOMAIN_DEVICE_SOUND:
|
||||||
case VIR_DOMAIN_DEVICE_VIDEO:
|
case VIR_DOMAIN_DEVICE_VIDEO:
|
||||||
case VIR_DOMAIN_DEVICE_GRAPHICS:
|
case VIR_DOMAIN_DEVICE_GRAPHICS:
|
||||||
@ -6046,6 +6094,31 @@ qemuDomainDetachPrepVsock(virDomainObj *vm,
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static int
|
||||||
|
qemuDomainDetachPrepFS(virDomainObj *vm,
|
||||||
|
virDomainFSDef *match,
|
||||||
|
virDomainFSDef **detach)
|
||||||
|
{
|
||||||
|
ssize_t idx;
|
||||||
|
|
||||||
|
if ((idx = virDomainFSDefFind(vm->def, match)) < 0) {
|
||||||
|
virReportError(VIR_ERR_DEVICE_MISSING, "%s",
|
||||||
|
_("matching filesystem not found"));
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (vm->def->fss[idx]->fsdriver != VIR_DOMAIN_FS_DRIVER_TYPE_VIRTIOFS) {
|
||||||
|
virReportError(VIR_ERR_OPERATION_UNSUPPORTED, "%s",
|
||||||
|
_("only virtiofs filesystems can be hotplugged"));
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
*detach = vm->def->fss[idx];
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
static int
|
static int
|
||||||
qemuDomainDetachDeviceLease(virQEMUDriver *driver,
|
qemuDomainDetachDeviceLease(virQEMUDriver *driver,
|
||||||
virDomainObj *vm,
|
virDomainObj *vm,
|
||||||
@ -6167,6 +6240,12 @@ qemuDomainDetachDeviceLive(virDomainObj *vm,
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
case VIR_DOMAIN_DEVICE_FS:
|
case VIR_DOMAIN_DEVICE_FS:
|
||||||
|
if (qemuDomainDetachPrepFS(vm, match->data.fs,
|
||||||
|
&detach.data.fs) < 0) {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
case VIR_DOMAIN_DEVICE_SOUND:
|
case VIR_DOMAIN_DEVICE_SOUND:
|
||||||
case VIR_DOMAIN_DEVICE_VIDEO:
|
case VIR_DOMAIN_DEVICE_VIDEO:
|
||||||
case VIR_DOMAIN_DEVICE_GRAPHICS:
|
case VIR_DOMAIN_DEVICE_GRAPHICS:
|
||||||
|
Loading…
Reference in New Issue
Block a user