[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]

Re: [libvirt] [PATCH 2/2] Filter out stale domains from xenstore listing



On Fri, Oct 09, 2009 at 10:35:49AM +0100, Daniel P. Berrange wrote:
> The xenstore database sometimes has stale domain IDs which are not
> present in the hypervisor anymore. Filter these out to avoid causing
> confusion
> 
> * src/xen/xs_internal.c: Filter domain IDs against HV's list
> * src/xen/xen_hypervisor.h, src/xen/xen_hypervisor.c: Add new
>   xenHypervisorHasDomain() method for checking ID validity
> ---
>  src/xen/xen_hypervisor.c |   22 ++++++++++++++++++++++
>  src/xen/xen_hypervisor.h |    4 +++-
>  src/xen/xs_internal.c    |   35 ++++++++++++++++++++++++++---------
>  3 files changed, 51 insertions(+), 10 deletions(-)
> 
> diff --git a/src/xen/xen_hypervisor.c b/src/xen/xen_hypervisor.c
> index 3aa3c30..6ab2431 100644
> --- a/src/xen/xen_hypervisor.c
> +++ b/src/xen/xen_hypervisor.c
> @@ -2780,6 +2780,28 @@ xenHypervisorDomainGetOSType (virDomainPtr dom)
>      return strdup("linux");
>  }
>  
> +int
> +xenHypervisorHasDomain(virConnectPtr conn,
> +                       int id)
> +{
> +    xenUnifiedPrivatePtr priv;
> +    xen_getdomaininfo dominfo;
> +
> +    priv = (xenUnifiedPrivatePtr) conn->privateData;
> +    if (priv->handle < 0)
> +        return 0;
> +
> +    XEN_GETDOMAININFO_CLEAR(dominfo);
> +
> +    if (virXen_getdomaininfo(priv->handle, id, &dominfo) < 0)
> +        return 0;
> +
> +    if (XEN_GETDOMAININFO_DOMAIN(dominfo) != id)
> +        return 0;
> +
> +    return 1;
> +}
> +
>  virDomainPtr
>  xenHypervisorLookupDomainByID(virConnectPtr conn,
>                                int id)
> diff --git a/src/xen/xen_hypervisor.h b/src/xen/xen_hypervisor.h
> index 766f676..5971a90 100644
> --- a/src/xen/xen_hypervisor.h
> +++ b/src/xen/xen_hypervisor.h
> @@ -23,7 +23,9 @@ int    xenHypervisorInit                 (void);
>  virCapsPtr xenHypervisorMakeCapabilities (virConnectPtr conn);
>  
>  /* The following calls are made directly by the Xen proxy: */
> -
> +int
> +        xenHypervisorHasDomain(virConnectPtr conn,
> +                               int id);
>  virDomainPtr
>          xenHypervisorLookupDomainByID   (virConnectPtr conn,
>                                           int id);
> diff --git a/src/xen/xs_internal.c b/src/xen/xs_internal.c
> index 0fabcf8..c83cfda 100644
> --- a/src/xen/xs_internal.c
> +++ b/src/xen/xs_internal.c
> @@ -545,8 +545,9 @@ int
>  xenStoreNumOfDomains(virConnectPtr conn)
>  {
>      unsigned int num;
> -    char **idlist;
> -    int ret = -1;
> +    char **idlist = NULL, *endptr;
> +    int i, ret = -1, realnum = 0;
> +    long id;
>      xenUnifiedPrivatePtr priv;
>  
>      if (conn == NULL) {
> @@ -559,10 +560,22 @@ xenStoreNumOfDomains(virConnectPtr conn)
>          virXenStoreError(conn, VIR_ERR_INVALID_ARG, __FUNCTION__);
>          return(-1);
>      }
> +
>      idlist = xs_directory(priv->xshandle, 0, "/local/domain", &num);
>      if (idlist) {
> -        free(idlist);
> -        ret = num;
> +        for (i = 0; i < num; i++) {
> +            id = strtol(idlist[i], &endptr, 10);
> +            if ((endptr == idlist[i]) || (*endptr != 0))
> +                goto out;
> +
> +            /* Sometimes xenstore has stale domain IDs, so filter
> +               against the hypervisor's info */
> +            if (xenHypervisorHasDomain(conn, (int)id))
> +                realnum++;
> +        }
> +out:
> +        VIR_FREE (idlist);
> +        ret = realnum;
>      }
>      return(ret);
>  }
> @@ -579,7 +592,7 @@ xenStoreNumOfDomains(virConnectPtr conn)
>   * Returns the number of domain found or -1 in case of error
>   */
>  static int
> -xenStoreDoListDomains(xenUnifiedPrivatePtr priv, int *ids, int maxids)
> +xenStoreDoListDomains(virConnectPtr conn, xenUnifiedPrivatePtr priv, int *ids, int maxids)
>  {
>      char **idlist = NULL, *endptr;
>      unsigned int num, i;
> @@ -597,7 +610,11 @@ xenStoreDoListDomains(xenUnifiedPrivatePtr priv, int *ids, int maxids)
>          id = strtol(idlist[i], &endptr, 10);
>          if ((endptr == idlist[i]) || (*endptr != 0))
>              goto out;
> -        ids[ret++] = (int) id;
> +
> +        /* Sometimes xenstore has stale domain IDs, so filter
> +           against the hypervisor's info */
> +        if (xenHypervisorHasDomain(conn, (int)id))
> +            ids[ret++] = (int) id;
>      }
>  
>  out:
> @@ -629,7 +646,7 @@ xenStoreListDomains(virConnectPtr conn, int *ids, int maxids)
>      priv = (xenUnifiedPrivatePtr) conn->privateData;
>  
>      xenUnifiedLock(priv);
> -    ret = xenStoreDoListDomains(priv, ids, maxids);
> +    ret = xenStoreDoListDomains(conn, priv, ids, maxids);
>      xenUnifiedUnlock(priv);
>  
>      return(ret);
> @@ -1275,7 +1292,7 @@ retry:
>          virReportOOMError(NULL);
>          return -1;
>      }
> -    nread = xenStoreDoListDomains(priv, new_domids, new_domain_cnt);
> +    nread = xenStoreDoListDomains(conn, priv, new_domids, new_domain_cnt);
>      if (nread != new_domain_cnt) {
>          // mismatch. retry this read
>          VIR_FREE(new_domids);
> @@ -1356,7 +1373,7 @@ retry:
>          virReportOOMError(NULL);
>          return -1;
>      }
> -    nread = xenStoreDoListDomains(priv, new_domids, new_domain_cnt);
> +    nread = xenStoreDoListDomains(conn, priv, new_domids, new_domain_cnt);
>      if (nread != new_domain_cnt) {
>          // mismatch. retry this read
>          VIR_FREE(new_domids);

  Okay so we filter out though an hypervisor call instead of slow xend
  lookup, ACK !

Daniel

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


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]