* 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 --- bootstrap | 12 +------ src/conf/domain_conf.c | 78 ++++++++++++++++++++++++++++++++++++++++++++++ src/conf/domain_conf.h | 14 ++++++++- src/libvirt_private.syms | 6 +++ src/qemu/qemu_driver.c | 36 +++++++++++++++++++++ src/qemu/qemu_hotplug.c | 36 +++++++++++++++++++++ src/qemu/qemu_hotplug.h | 6 +++ 7 files changed, 177 insertions(+), 11 deletions(-) diff --git a/bootstrap b/bootstrap index 522ac70..d32db57 100755 --- a/bootstrap +++ b/bootstrap @@ -1,6 +1,6 @@ #! /bin/sh # Print a version string. -scriptversion=2011-05-16.16; # UTC +scriptversion=2011-05-11.17; # UTC # Bootstrap this package from checked-out sources. @@ -670,18 +670,10 @@ symlink_to_dir() cp -fp "$src" "$dst" } else - # Leave any existing symlink alone, if it already points to the source, - # so that broken build tools that care about symlink times - # aren't confused into doing unnecessary builds. Conversely, if the - # existing symlink's time stamp is older than the source, make it afresh, - # so that broken tools aren't confused into skipping needed builds. See - # <http://lists.gnu.org/archive/html/bug-gnulib/2011-05/msg00326.html>. test -h "$dst" && src_ls=`ls -diL "$src" 2>/dev/null` && set $src_ls && src_i=$1 && dst_ls=`ls -diL "$dst" 2>/dev/null` && set $dst_ls && dst_i=$1 && - test "$src_i" = "$dst_i" && - both_ls=`ls -dt "$src" "$dst"` && - test "X$both_ls" = "X$dst$nl$src" || { + test "$src_i" = "$dst_i" || { dot_dots= case $src in /*) ;; diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c index b6f7740..3c137a1 100644 --- a/src/conf/domain_conf.c +++ b/src/conf/domain_conf.c @@ -5330,6 +5330,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; diff --git a/src/conf/domain_conf.h b/src/conf/domain_conf.h index b0771aa..ca1d792 100644 --- a/src/conf/domain_conf.h +++ b/src/conf/domain_conf.h @@ -1182,7 +1182,7 @@ struct _virDomainDef { int nchannels; virDomainChrDefPtr *channels; - int nleases; + size_t nleases; virDomainLeaseDefPtr *leases; /* Only 1 */ @@ -1381,6 +1381,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); diff --git a/src/libvirt_private.syms b/src/libvirt_private.syms index a2a6de9..a3fe2f1 100644 --- a/src/libvirt_private.syms +++ b/src/libvirt_private.syms @@ -285,6 +285,12 @@ virDomainHostdevDefFree; virDomainHostdevModeTypeToString; virDomainHostdevSubsysTypeToString; virDomainInputDefFree; +virDomainLeaseIndex; +virDomainLeaseInsert; +virDomainLeaseInsertPreAlloc; +virDomainLeaseInsertPreAlloced; +virDomainLeaseRemove; +virDomainLeaseRemoveAt; virDomainLifecycleCrashTypeFromString; virDomainLifecycleCrashTypeToString; virDomainLifecycleTypeFromString; diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c index 6d4a6f4..682ffd9 100644 --- a/src/qemu/qemu_driver.c +++ b/src/qemu/qemu_driver.c @@ -4074,6 +4074,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, @@ -4163,6 +4170,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; @@ -4256,6 +4266,7 @@ qemuDomainAttachDeviceConfig(virDomainDefPtr vmdef, virDomainDeviceDefPtr dev) { virDomainDiskDefPtr disk; + virDomainLeaseDefPtr lease; switch (dev->type) { case VIR_DOMAIN_DEVICE_DISK: @@ -4278,6 +4289,21 @@ qemuDomainAttachDeviceConfig(virDomainDefPtr vmdef, 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")); @@ -4292,6 +4318,7 @@ qemuDomainDetachDeviceConfig(virDomainDefPtr vmdef, virDomainDeviceDefPtr dev) { virDomainDiskDefPtr disk; + virDomainLeaseDefPtr lease; switch (dev->type) { case VIR_DOMAIN_DEVICE_DISK: @@ -4302,6 +4329,15 @@ 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")); diff --git a/src/qemu/qemu_hotplug.c b/src/qemu/qemu_hotplug.c index a8e73c4..c9e2d08 100644 --- a/src/qemu/qemu_hotplug.c +++ b/src/qemu/qemu_hotplug.c @@ -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; +} diff --git a/src/qemu/qemu_hotplug.h b/src/qemu/qemu_hotplug.h index d18b393..009f1f6 100644 --- a/src/qemu/qemu_hotplug.h +++ b/src/qemu/qemu_hotplug.h @@ -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__ */ -- 1.7.4.4 -- libvir-list mailing list libvir-list@xxxxxxxxxx https://www.redhat.com/mailman/listinfo/libvir-list