mirror of
https://gitlab.com/libvirt/libvirt.git
synced 2025-02-02 01:45:17 +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,
|
||||
virCapsPtr caps) {
|
||||
const char *type;
|
||||
|
@ -1196,7 +1196,7 @@ struct _virDomainDef {
|
||||
int nchannels;
|
||||
virDomainChrDefPtr *channels;
|
||||
|
||||
int nleases;
|
||||
size_t nleases;
|
||||
virDomainLeaseDefPtr *leases;
|
||||
|
||||
/* Only 1 */
|
||||
@ -1400,6 +1400,18 @@ int virDomainControllerInsert(virDomainDefPtr def,
|
||||
void virDomainControllerInsertPreAlloced(virDomainDefPtr def,
|
||||
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,
|
||||
virDomainDefPtr def,
|
||||
const char *xml);
|
||||
|
@ -288,6 +288,12 @@ virDomainHostdevDefFree;
|
||||
virDomainHostdevModeTypeToString;
|
||||
virDomainHostdevSubsysTypeToString;
|
||||
virDomainInputDefFree;
|
||||
virDomainLeaseIndex;
|
||||
virDomainLeaseInsert;
|
||||
virDomainLeaseInsertPreAlloc;
|
||||
virDomainLeaseInsertPreAlloced;
|
||||
virDomainLeaseRemove;
|
||||
virDomainLeaseRemoveAt;
|
||||
virDomainLifecycleCrashTypeFromString;
|
||||
virDomainLifecycleCrashTypeToString;
|
||||
virDomainLifecycleTypeFromString;
|
||||
|
@ -4084,6 +4084,13 @@ qemuDomainAttachDeviceLive(virDomainObjPtr vm,
|
||||
dev->data.controller = NULL;
|
||||
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:
|
||||
qemuDomainObjCheckNetTaint(driver, vm, dev->data.net, -1);
|
||||
ret = qemuDomainAttachNetDevice(dom->conn, driver, vm,
|
||||
@ -4173,6 +4180,9 @@ qemuDomainDetachDeviceLive(virDomainObjPtr vm,
|
||||
case VIR_DOMAIN_DEVICE_CONTROLLER:
|
||||
ret = qemuDomainDetachDeviceControllerLive(driver, vm, dev);
|
||||
break;
|
||||
case VIR_DOMAIN_DEVICE_LEASE:
|
||||
ret = qemuDomainDetachLease(driver, vm, dev->data.lease);
|
||||
break;
|
||||
case VIR_DOMAIN_DEVICE_NET:
|
||||
ret = qemuDomainDetachNetDevice(driver, vm, dev);
|
||||
break;
|
||||
@ -4267,6 +4277,7 @@ qemuDomainAttachDeviceConfig(virDomainDefPtr vmdef,
|
||||
{
|
||||
virDomainDiskDefPtr disk;
|
||||
virDomainNetDefPtr net;
|
||||
virDomainLeaseDefPtr lease;
|
||||
|
||||
switch (dev->type) {
|
||||
case VIR_DOMAIN_DEVICE_DISK:
|
||||
@ -4306,6 +4317,22 @@ qemuDomainAttachDeviceConfig(virDomainDefPtr vmdef,
|
||||
if (qemuDomainAssignPCIAddresses(vmdef) < 0)
|
||||
return -1;
|
||||
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:
|
||||
qemuReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
|
||||
_("persistent attach of device is not supported"));
|
||||
@ -4321,6 +4348,7 @@ qemuDomainDetachDeviceConfig(virDomainDefPtr vmdef,
|
||||
{
|
||||
virDomainDiskDefPtr disk;
|
||||
virDomainNetDefPtr net;
|
||||
virDomainLeaseDefPtr lease;
|
||||
|
||||
switch (dev->type) {
|
||||
case VIR_DOMAIN_DEVICE_DISK:
|
||||
@ -4331,6 +4359,7 @@ qemuDomainDetachDeviceConfig(virDomainDefPtr vmdef,
|
||||
return -1;
|
||||
}
|
||||
break;
|
||||
|
||||
case VIR_DOMAIN_DEVICE_NET:
|
||||
net = dev->data.net;
|
||||
if (virDomainNetRemoveByMac(vmdef, net->mac)) {
|
||||
@ -4342,6 +4371,17 @@ qemuDomainDetachDeviceConfig(virDomainDefPtr vmdef,
|
||||
return -1;
|
||||
}
|
||||
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:
|
||||
qemuReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
|
||||
_("persistent detach of device is not supported"));
|
||||
|
@ -1846,3 +1846,39 @@ cleanup:
|
||||
|
||||
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,
|
||||
virDomainObjPtr vm,
|
||||
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__ */
|
||||
|
Loading…
x
Reference in New Issue
Block a user