[libvirt] [PATCH 01/11] libxl: Add job support to libxl driver

Michal Privoznik mprivozn at redhat.com
Tue Feb 11 14:36:21 UTC 2014


On 07.02.2014 04:53, Jim Fehlig wrote:
> Follows the pattern used in the QEMU driver for managing multiple,
> simultaneous jobs within the driver.
>
> Signed-off-by: Jim Fehlig <jfehlig at suse.com>
> ---
>   src/libxl/libxl_domain.c | 128 +++++++++++++++++++++++++++++++++++++++++++++++
>   src/libxl/libxl_domain.h |  37 ++++++++++++++
>   2 files changed, 165 insertions(+)
>
> diff --git a/src/libxl/libxl_domain.c b/src/libxl/libxl_domain.c
> index eb2e50e..fdc4661 100644
> --- a/src/libxl/libxl_domain.c
> +++ b/src/libxl/libxl_domain.c
> @@ -30,10 +30,18 @@
>   #include "virerror.h"
>   #include "virlog.h"
>   #include "virstring.h"
> +#include "virtime.h"
>
>   #define VIR_FROM_THIS VIR_FROM_LIBXL
>
>
> +VIR_ENUM_IMPL(libxlDomainJob, LIBXL_JOB_LAST,
> +              "none",
> +              "query",
> +              "destroy",
> +              "modify",
> +);
> +
>   /* Object used to store info related to libxl event registrations */
>   typedef struct _libxlEventHookInfo libxlEventHookInfo;
>   typedef libxlEventHookInfo *libxlEventHookInfoPtr;
> @@ -284,6 +292,119 @@ static const libxl_osevent_hooks libxl_event_callbacks = {
>       .timeout_deregister = libxlDomainObjTimeoutDeregisterEventHook,
>   };
>
> +static int
> +libxlDomainObjInitJob(libxlDomainObjPrivatePtr priv)
> +{
> +    memset(&priv->job, 0, sizeof(priv->job));
> +
> +    if (virCondInit(&priv->job.cond) < 0)
> +        return -1;
> +
> +    return 0;
> +}
> +
> +static void
> +libxlDomainObjResetJob(libxlDomainObjPrivatePtr priv)
> +{
> +    struct libxlDomainJobObj *job = &priv->job;
> +
> +    job->active = LIBXL_JOB_NONE;
> +    job->owner = 0;
> +}
> +
> +static void
> +libxlDomainObjFreeJob(libxlDomainObjPrivatePtr priv)
> +{
> +    ignore_value(virCondDestroy(&priv->job.cond));
> +}
> +
> +/* Give up waiting for mutex after 30 seconds */
> +#define LIBXL_JOB_WAIT_TIME (1000ull * 30)
> +
> +/*
> + * obj must be locked before calling, libxlDriverPrivatePtr must NOT be locked
> + *
> + * This must be called by anything that will change the VM state
> + * in any way
> + *
> + * Upon successful return, the object will have its ref count increased,
> + * successful calls must be followed by EndJob eventually
> + */
> +int
> +libxlDomainObjBeginJob(libxlDriverPrivatePtr driver ATTRIBUTE_UNUSED,
> +                       virDomainObjPtr obj,
> +                       enum libxlDomainJob job)
> +{
> +    libxlDomainObjPrivatePtr priv = obj->privateData;
> +    unsigned long long now;
> +    unsigned long long then;
> +
> +    if (virTimeMillisNow(&now) < 0)
> +        return -1;
> +    then = now + LIBXL_JOB_WAIT_TIME;
> +
> +    virObjectRef(obj);
> +
> +    while (priv->job.active) {
> +        VIR_DEBUG("Wait normal job condition for starting job: %s",
> +                  libxlDomainJobTypeToString(job));
> +        if (virCondWaitUntil(&priv->job.cond, &obj->parent.lock, then) < 0)
> +            goto error;
> +    }
> +
> +    libxlDomainObjResetJob(priv);
> +
> +    VIR_DEBUG("Starting job: %s", libxlDomainJobTypeToString(job));
> +    priv->job.active = job;
> +    priv->job.owner = virThreadSelfID();
> +
> +    return 0;
> +
> +error:
> +    VIR_WARN("Cannot start job (%s) for domain %s;"
> +             " current job is (%s) owned by (%d)",
> +             libxlDomainJobTypeToString(job),
> +             obj->def->name,
> +             libxlDomainJobTypeToString(priv->job.active),
> +             priv->job.owner);
> +
> +    if (errno == ETIMEDOUT)
> +        virReportError(VIR_ERR_OPERATION_TIMEOUT,
> +                       "%s", _("cannot acquire state change lock"));
> +    else
> +        virReportSystemError(errno,
> +                             "%s", _("cannot acquire job mutex"));
> +
> +    virObjectUnref(obj);
> +    return -1;
> +}
> +
> +/*
> + * obj must be locked before calling
> + *
> + * To be called after completing the work associated with the
> + * earlier libxlDomainBeginJob() call
> + *
> + * Returns true if the remaining reference count on obj is
> + * non-zero, false if the reference count has dropped to zero
> + * and obj is disposed.
> + */
> +bool
> +libxlDomainObjEndJob(libxlDriverPrivatePtr driver ATTRIBUTE_UNUSED,
> +                     virDomainObjPtr obj)
> +{
> +    libxlDomainObjPrivatePtr priv = obj->privateData;
> +    enum libxlDomainJob job = priv->job.active;
> +
> +    VIR_DEBUG("Stopping job: %s",
> +              libxlDomainJobTypeToString(job));
> +
> +    libxlDomainObjResetJob(priv);
> +    virCondSignal(&priv->job.cond);
> +
> +    return virObjectUnref(obj);
> +}
> +
>   static void *
>   libxlDomainObjPrivateAlloc(void)
>   {
> @@ -300,6 +421,12 @@ libxlDomainObjPrivateAlloc(void)
>           return NULL;
>       }
>
> +    if (libxlDomainObjInitJob(priv) < 0) {
> +        virChrdevFree(priv->devs);
> +        virObjectUnref(priv);
> +        return NULL;
> +    }
> +
>       return priv;
>   }
>
> @@ -311,6 +438,7 @@ libxlDomainObjPrivateDispose(void *obj)
>       if (priv->deathW)
>           libxl_evdisable_domain_death(priv->ctx, priv->deathW);
>
> +    libxlDomainObjFreeJob(priv);
>       virChrdevFree(priv->devs);
>       libxl_ctx_free(priv->ctx);
>       if (priv->logger_file)
> diff --git a/src/libxl/libxl_domain.h b/src/libxl/libxl_domain.h
> index 8565820..4decc40 100644
> --- a/src/libxl/libxl_domain.h
> +++ b/src/libxl/libxl_domain.h
> @@ -30,6 +30,31 @@
>   # include "libxl_conf.h"
>   # include "virchrdev.h"
>
> +# define JOB_MASK(job)                  (1 << (job - 1))
> +# define DEFAULT_JOB_MASK               \
> +    (JOB_MASK(LIBXL_JOB_DESTROY) |      \
> +     JOB_MASK(LIBXL_JOB_ABORT))
> +
> +/* Only 1 job is allowed at any time
> + * A job includes *all* libxl.so api, even those just querying
> + * information, not merely actions */
> +enum libxlDomainJob {
> +    LIBXL_JOB_NONE = 0,      /* Always set to 0 for easy if (jobActive) conditions */
> +    LIBXL_JOB_QUERY,         /* Doesn't change any state */
> +    LIBXL_JOB_DESTROY,       /* Destroys the domain (cannot be masked out) */
> +    LIBXL_JOB_MODIFY,        /* May change state */
> +
> +    LIBXL_JOB_LAST
> +};
> +VIR_ENUM_DECL(libxlDomainJob)
> +
> +
> +struct libxlDomainJobObj {
> +    virCond cond;                       /* Use to coordinate jobs */
> +    enum libxlDomainJob active;         /* Currently running job */
> +    int owner;                          /* Thread which set current job */
> +};
> +
>   typedef struct _libxlDomainObjPrivate libxlDomainObjPrivate;
>   typedef libxlDomainObjPrivate *libxlDomainObjPrivatePtr;
>   struct _libxlDomainObjPrivate {
> @@ -43,6 +68,8 @@ struct _libxlDomainObjPrivate {
>       /* console */
>       virChrdevsPtr devs;
>       libxl_evgen_domain_death *deathW;
> +
> +    struct libxlDomainJobObj job;
>   };
>
>
> @@ -53,4 +80,14 @@ extern virDomainDefParserConfig libxlDomainDefParserConfig;
>   int
>   libxlDomainObjPrivateInitCtx(virDomainObjPtr vm);
>
> +int
> +libxlDomainObjBeginJob(libxlDriverPrivatePtr driver,
> +                       virDomainObjPtr obj,
> +                       enum libxlDomainJob job)
> +    ATTRIBUTE_RETURN_CHECK;
> +
> +bool
> +libxlDomainObjEndJob(libxlDriverPrivatePtr driver,
> +                     virDomainObjPtr obj);
> +
>   #endif /* LIBXL_DOMAIN_H */
>

ACK

Michal




More information about the libvir-list mailing list