mirror of
https://gitlab.com/libvirt/libvirt.git
synced 2024-08-28 11:31:16 +00:00
Allow leases to be hotpluged with QEMU guests
* src/conf/domain_conf.c, src/conf/domain_conf.h: APIs for inserting/finding/removing virDomainLeaseDefPtr instances * src/qemu/qemu_driver.c: Wire up hotplug/unplug for leases * src/qemu/qemu_hotplug.h, src/qemu/qemu_hotplug.c: Support for hotplug and unplug of leases
This commit is contained in:
parent
7474560bef
commit
30ffe7bceb
@ -5395,6 +5395,84 @@ void virDomainControllerInsertPreAlloced(virDomainDefPtr def,
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
int virDomainLeaseIndex(virDomainDefPtr def,
|
||||||
|
virDomainLeaseDefPtr lease)
|
||||||
|
{
|
||||||
|
virDomainLeaseDefPtr vlease;
|
||||||
|
int i;
|
||||||
|
|
||||||
|
for (i = 0; i < def->nleases; i++) {
|
||||||
|
vlease = def->leases[i];
|
||||||
|
/* Either both must have lockspaces present which match.. */
|
||||||
|
if (vlease->lockspace && lease->lockspace &&
|
||||||
|
STRNEQ(vlease->lockspace, lease->lockspace))
|
||||||
|
continue;
|
||||||
|
/* ...or neither must have a lockspace present */
|
||||||
|
if (vlease->lockspace || lease->lockspace)
|
||||||
|
continue;
|
||||||
|
if (STREQ(vlease->key, lease->key))
|
||||||
|
return i;
|
||||||
|
}
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
int virDomainLeaseInsertPreAlloc(virDomainDefPtr def)
|
||||||
|
{
|
||||||
|
if (VIR_EXPAND_N(def->leases, def->nleases, 1) < 0) {
|
||||||
|
virReportOOMError();
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int virDomainLeaseInsert(virDomainDefPtr def,
|
||||||
|
virDomainLeaseDefPtr lease)
|
||||||
|
{
|
||||||
|
if (virDomainLeaseInsertPreAlloc(def) < 0)
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
virDomainLeaseInsertPreAlloced(def, lease);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void virDomainLeaseInsertPreAlloced(virDomainDefPtr def,
|
||||||
|
virDomainLeaseDefPtr lease)
|
||||||
|
{
|
||||||
|
if (lease == NULL)
|
||||||
|
VIR_SHRINK_N(def->leases, def->nleases, 1);
|
||||||
|
else
|
||||||
|
def->leases[def->nleases-1] = lease;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void virDomainLeaseRemoveAt(virDomainDefPtr def, size_t i)
|
||||||
|
{
|
||||||
|
if (def->nleases > 1) {
|
||||||
|
memmove(def->leases + i,
|
||||||
|
def->leases + i + 1,
|
||||||
|
sizeof(*def->leases) *
|
||||||
|
(def->nleases - (i + 1)));
|
||||||
|
VIR_SHRINK_N(def->leases, def->nleases, 1);
|
||||||
|
} else {
|
||||||
|
VIR_FREE(def->leases);
|
||||||
|
def->nleases = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
int virDomainLeaseRemove(virDomainDefPtr def,
|
||||||
|
virDomainLeaseDefPtr lease)
|
||||||
|
{
|
||||||
|
int i = virDomainLeaseIndex(def, lease);
|
||||||
|
if (i < 0)
|
||||||
|
return -1;
|
||||||
|
virDomainLeaseRemoveAt(def, i);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
static char *virDomainDefDefaultEmulator(virDomainDefPtr def,
|
static char *virDomainDefDefaultEmulator(virDomainDefPtr def,
|
||||||
virCapsPtr caps) {
|
virCapsPtr caps) {
|
||||||
const char *type;
|
const char *type;
|
||||||
|
@ -1196,7 +1196,7 @@ struct _virDomainDef {
|
|||||||
int nchannels;
|
int nchannels;
|
||||||
virDomainChrDefPtr *channels;
|
virDomainChrDefPtr *channels;
|
||||||
|
|
||||||
int nleases;
|
size_t nleases;
|
||||||
virDomainLeaseDefPtr *leases;
|
virDomainLeaseDefPtr *leases;
|
||||||
|
|
||||||
/* Only 1 */
|
/* Only 1 */
|
||||||
@ -1400,6 +1400,18 @@ int virDomainControllerInsert(virDomainDefPtr def,
|
|||||||
void virDomainControllerInsertPreAlloced(virDomainDefPtr def,
|
void virDomainControllerInsertPreAlloced(virDomainDefPtr def,
|
||||||
virDomainControllerDefPtr controller);
|
virDomainControllerDefPtr controller);
|
||||||
|
|
||||||
|
|
||||||
|
int virDomainLeaseIndex(virDomainDefPtr def,
|
||||||
|
virDomainLeaseDefPtr lease);
|
||||||
|
int virDomainLeaseInsert(virDomainDefPtr def,
|
||||||
|
virDomainLeaseDefPtr lease);
|
||||||
|
int virDomainLeaseInsertPreAlloc(virDomainDefPtr def);
|
||||||
|
void virDomainLeaseInsertPreAlloced(virDomainDefPtr def,
|
||||||
|
virDomainLeaseDefPtr lease);
|
||||||
|
void virDomainLeaseRemoveAt(virDomainDefPtr def, size_t i);
|
||||||
|
int virDomainLeaseRemove(virDomainDefPtr def,
|
||||||
|
virDomainLeaseDefPtr lease);
|
||||||
|
|
||||||
int virDomainSaveXML(const char *configDir,
|
int virDomainSaveXML(const char *configDir,
|
||||||
virDomainDefPtr def,
|
virDomainDefPtr def,
|
||||||
const char *xml);
|
const char *xml);
|
||||||
|
@ -288,6 +288,12 @@ virDomainHostdevDefFree;
|
|||||||
virDomainHostdevModeTypeToString;
|
virDomainHostdevModeTypeToString;
|
||||||
virDomainHostdevSubsysTypeToString;
|
virDomainHostdevSubsysTypeToString;
|
||||||
virDomainInputDefFree;
|
virDomainInputDefFree;
|
||||||
|
virDomainLeaseIndex;
|
||||||
|
virDomainLeaseInsert;
|
||||||
|
virDomainLeaseInsertPreAlloc;
|
||||||
|
virDomainLeaseInsertPreAlloced;
|
||||||
|
virDomainLeaseRemove;
|
||||||
|
virDomainLeaseRemoveAt;
|
||||||
virDomainLifecycleCrashTypeFromString;
|
virDomainLifecycleCrashTypeFromString;
|
||||||
virDomainLifecycleCrashTypeToString;
|
virDomainLifecycleCrashTypeToString;
|
||||||
virDomainLifecycleTypeFromString;
|
virDomainLifecycleTypeFromString;
|
||||||
|
@ -4084,6 +4084,13 @@ qemuDomainAttachDeviceLive(virDomainObjPtr vm,
|
|||||||
dev->data.controller = NULL;
|
dev->data.controller = NULL;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case VIR_DOMAIN_DEVICE_LEASE:
|
||||||
|
ret = qemuDomainAttachLease(driver, vm,
|
||||||
|
dev->data.lease);
|
||||||
|
if (ret == 0)
|
||||||
|
dev->data.lease = NULL;
|
||||||
|
break;
|
||||||
|
|
||||||
case VIR_DOMAIN_DEVICE_NET:
|
case VIR_DOMAIN_DEVICE_NET:
|
||||||
qemuDomainObjCheckNetTaint(driver, vm, dev->data.net, -1);
|
qemuDomainObjCheckNetTaint(driver, vm, dev->data.net, -1);
|
||||||
ret = qemuDomainAttachNetDevice(dom->conn, driver, vm,
|
ret = qemuDomainAttachNetDevice(dom->conn, driver, vm,
|
||||||
@ -4173,6 +4180,9 @@ qemuDomainDetachDeviceLive(virDomainObjPtr vm,
|
|||||||
case VIR_DOMAIN_DEVICE_CONTROLLER:
|
case VIR_DOMAIN_DEVICE_CONTROLLER:
|
||||||
ret = qemuDomainDetachDeviceControllerLive(driver, vm, dev);
|
ret = qemuDomainDetachDeviceControllerLive(driver, vm, dev);
|
||||||
break;
|
break;
|
||||||
|
case VIR_DOMAIN_DEVICE_LEASE:
|
||||||
|
ret = qemuDomainDetachLease(driver, vm, dev->data.lease);
|
||||||
|
break;
|
||||||
case VIR_DOMAIN_DEVICE_NET:
|
case VIR_DOMAIN_DEVICE_NET:
|
||||||
ret = qemuDomainDetachNetDevice(driver, vm, dev);
|
ret = qemuDomainDetachNetDevice(driver, vm, dev);
|
||||||
break;
|
break;
|
||||||
@ -4267,6 +4277,7 @@ qemuDomainAttachDeviceConfig(virDomainDefPtr vmdef,
|
|||||||
{
|
{
|
||||||
virDomainDiskDefPtr disk;
|
virDomainDiskDefPtr disk;
|
||||||
virDomainNetDefPtr net;
|
virDomainNetDefPtr net;
|
||||||
|
virDomainLeaseDefPtr lease;
|
||||||
|
|
||||||
switch (dev->type) {
|
switch (dev->type) {
|
||||||
case VIR_DOMAIN_DEVICE_DISK:
|
case VIR_DOMAIN_DEVICE_DISK:
|
||||||
@ -4306,6 +4317,22 @@ qemuDomainAttachDeviceConfig(virDomainDefPtr vmdef,
|
|||||||
if (qemuDomainAssignPCIAddresses(vmdef) < 0)
|
if (qemuDomainAssignPCIAddresses(vmdef) < 0)
|
||||||
return -1;
|
return -1;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case VIR_DOMAIN_DEVICE_LEASE:
|
||||||
|
lease = dev->data.lease;
|
||||||
|
if (virDomainLeaseIndex(vmdef, lease) >= 0) {
|
||||||
|
qemuReportError(VIR_ERR_INVALID_ARG,
|
||||||
|
_("Lease %s in lockspace %s already exists"),
|
||||||
|
lease->key, NULLSTR(lease->lockspace));
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
if (virDomainLeaseInsert(vmdef, lease) < 0)
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
/* vmdef has the pointer. Generic codes for vmdef will do all jobs */
|
||||||
|
dev->data.lease = NULL;
|
||||||
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
qemuReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
|
qemuReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
|
||||||
_("persistent attach of device is not supported"));
|
_("persistent attach of device is not supported"));
|
||||||
@ -4321,6 +4348,7 @@ qemuDomainDetachDeviceConfig(virDomainDefPtr vmdef,
|
|||||||
{
|
{
|
||||||
virDomainDiskDefPtr disk;
|
virDomainDiskDefPtr disk;
|
||||||
virDomainNetDefPtr net;
|
virDomainNetDefPtr net;
|
||||||
|
virDomainLeaseDefPtr lease;
|
||||||
|
|
||||||
switch (dev->type) {
|
switch (dev->type) {
|
||||||
case VIR_DOMAIN_DEVICE_DISK:
|
case VIR_DOMAIN_DEVICE_DISK:
|
||||||
@ -4331,6 +4359,7 @@ qemuDomainDetachDeviceConfig(virDomainDefPtr vmdef,
|
|||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case VIR_DOMAIN_DEVICE_NET:
|
case VIR_DOMAIN_DEVICE_NET:
|
||||||
net = dev->data.net;
|
net = dev->data.net;
|
||||||
if (virDomainNetRemoveByMac(vmdef, net->mac)) {
|
if (virDomainNetRemoveByMac(vmdef, net->mac)) {
|
||||||
@ -4342,6 +4371,17 @@ qemuDomainDetachDeviceConfig(virDomainDefPtr vmdef,
|
|||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case VIR_DOMAIN_DEVICE_LEASE:
|
||||||
|
lease = dev->data.lease;
|
||||||
|
if (virDomainLeaseRemove(vmdef, lease) < 0) {
|
||||||
|
qemuReportError(VIR_ERR_INVALID_ARG,
|
||||||
|
_("Lease %s in lockspace %s does not exist"),
|
||||||
|
lease->key, NULLSTR(lease->lockspace));
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
qemuReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
|
qemuReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
|
||||||
_("persistent detach of device is not supported"));
|
_("persistent detach of device is not supported"));
|
||||||
|
@ -1846,3 +1846,39 @@ cleanup:
|
|||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int qemuDomainAttachLease(struct qemud_driver *driver,
|
||||||
|
virDomainObjPtr vm,
|
||||||
|
virDomainLeaseDefPtr lease)
|
||||||
|
{
|
||||||
|
if (virDomainLeaseInsertPreAlloc(vm->def) < 0)
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
if (virDomainLockLeaseAttach(driver->lockManager, vm, lease) < 0) {
|
||||||
|
virDomainLeaseInsertPreAlloced(vm->def, NULL);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
virDomainLeaseInsertPreAlloced(vm->def, lease);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int qemuDomainDetachLease(struct qemud_driver *driver,
|
||||||
|
virDomainObjPtr vm,
|
||||||
|
virDomainLeaseDefPtr lease)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
|
||||||
|
if ((i = virDomainLeaseIndex(vm->def, lease)) < 0) {
|
||||||
|
qemuReportError(VIR_ERR_INVALID_ARG,
|
||||||
|
_("Lease %s in lockspace %s does not exist"),
|
||||||
|
lease->key, NULLSTR(lease->lockspace));
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (virDomainLockLeaseDetach(driver->lockManager, vm, lease) < 0)
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
virDomainLeaseRemoveAt(vm->def, i);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
@ -85,6 +85,12 @@ int qemuDomainDetachHostUsbDevice(struct qemud_driver *driver,
|
|||||||
int qemuDomainDetachHostDevice(struct qemud_driver *driver,
|
int qemuDomainDetachHostDevice(struct qemud_driver *driver,
|
||||||
virDomainObjPtr vm,
|
virDomainObjPtr vm,
|
||||||
virDomainDeviceDefPtr dev);
|
virDomainDeviceDefPtr dev);
|
||||||
|
int qemuDomainAttachLease(struct qemud_driver *driver,
|
||||||
|
virDomainObjPtr vm,
|
||||||
|
virDomainLeaseDefPtr lease);
|
||||||
|
int qemuDomainDetachLease(struct qemud_driver *driver,
|
||||||
|
virDomainObjPtr vm,
|
||||||
|
virDomainLeaseDefPtr lease);
|
||||||
|
|
||||||
|
|
||||||
#endif /* __QEMU_HOTPLUG_H__ */
|
#endif /* __QEMU_HOTPLUG_H__ */
|
||||||
|
Loading…
Reference in New Issue
Block a user