[libvirt] [PATCH 09/10] Allow leases to be hotpluged with QEMU guests

Daniel Veillard veillard at redhat.com
Fri May 27 09:29:55 UTC 2011


On Thu, May 19, 2011 at 07:24:24AM -0400, Daniel P. Berrange wrote:
> * 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
>          /*) ;;

  I assume that part is a rogue rebase leftover, right ?

> 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);
>  

  except for .bootstrap, ACK

Daniel

-- 
Daniel Veillard      | libxml Gnome XML XSLT toolkit  http://xmlsoft.org/
daniel at veillard.com  | Rpmfind RPM search engine http://rpmfind.net/
http://veillard.com/ | virtualization library  http://libvirt.org/




More information about the libvir-list mailing list