mirror of
https://gitlab.com/libvirt/libvirt.git
synced 2025-01-11 23:37:42 +00:00
libxl: Add job support to libxl driver
Follows the pattern used in the QEMU driver for managing multiple, simultaneous jobs within the driver. Signed-off-by: Jim Fehlig <jfehlig@suse.com>
This commit is contained in:
parent
343119a44b
commit
4b4b61c329
@ -30,10 +30,18 @@
|
|||||||
#include "virerror.h"
|
#include "virerror.h"
|
||||||
#include "virlog.h"
|
#include "virlog.h"
|
||||||
#include "virstring.h"
|
#include "virstring.h"
|
||||||
|
#include "virtime.h"
|
||||||
|
|
||||||
#define VIR_FROM_THIS VIR_FROM_LIBXL
|
#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 */
|
/* Object used to store info related to libxl event registrations */
|
||||||
typedef struct _libxlEventHookInfo libxlEventHookInfo;
|
typedef struct _libxlEventHookInfo libxlEventHookInfo;
|
||||||
typedef libxlEventHookInfo *libxlEventHookInfoPtr;
|
typedef libxlEventHookInfo *libxlEventHookInfoPtr;
|
||||||
@ -284,6 +292,119 @@ static const libxl_osevent_hooks libxl_event_callbacks = {
|
|||||||
.timeout_deregister = libxlDomainObjTimeoutDeregisterEventHook,
|
.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 *
|
static void *
|
||||||
libxlDomainObjPrivateAlloc(void)
|
libxlDomainObjPrivateAlloc(void)
|
||||||
{
|
{
|
||||||
@ -300,6 +421,12 @@ libxlDomainObjPrivateAlloc(void)
|
|||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (libxlDomainObjInitJob(priv) < 0) {
|
||||||
|
virChrdevFree(priv->devs);
|
||||||
|
virObjectUnref(priv);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
return priv;
|
return priv;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -311,6 +438,7 @@ libxlDomainObjPrivateDispose(void *obj)
|
|||||||
if (priv->deathW)
|
if (priv->deathW)
|
||||||
libxl_evdisable_domain_death(priv->ctx, priv->deathW);
|
libxl_evdisable_domain_death(priv->ctx, priv->deathW);
|
||||||
|
|
||||||
|
libxlDomainObjFreeJob(priv);
|
||||||
virChrdevFree(priv->devs);
|
virChrdevFree(priv->devs);
|
||||||
libxl_ctx_free(priv->ctx);
|
libxl_ctx_free(priv->ctx);
|
||||||
if (priv->logger_file)
|
if (priv->logger_file)
|
||||||
|
@ -30,6 +30,31 @@
|
|||||||
# include "libxl_conf.h"
|
# include "libxl_conf.h"
|
||||||
# include "virchrdev.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 struct _libxlDomainObjPrivate libxlDomainObjPrivate;
|
||||||
typedef libxlDomainObjPrivate *libxlDomainObjPrivatePtr;
|
typedef libxlDomainObjPrivate *libxlDomainObjPrivatePtr;
|
||||||
struct _libxlDomainObjPrivate {
|
struct _libxlDomainObjPrivate {
|
||||||
@ -43,6 +68,8 @@ struct _libxlDomainObjPrivate {
|
|||||||
/* console */
|
/* console */
|
||||||
virChrdevsPtr devs;
|
virChrdevsPtr devs;
|
||||||
libxl_evgen_domain_death *deathW;
|
libxl_evgen_domain_death *deathW;
|
||||||
|
|
||||||
|
struct libxlDomainJobObj job;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
@ -53,4 +80,15 @@ extern virDomainDefParserConfig libxlDomainDefParserConfig;
|
|||||||
int
|
int
|
||||||
libxlDomainObjPrivateInitCtx(virDomainObjPtr vm);
|
libxlDomainObjPrivateInitCtx(virDomainObjPtr vm);
|
||||||
|
|
||||||
|
int
|
||||||
|
libxlDomainObjBeginJob(libxlDriverPrivatePtr driver,
|
||||||
|
virDomainObjPtr obj,
|
||||||
|
enum libxlDomainJob job)
|
||||||
|
ATTRIBUTE_RETURN_CHECK;
|
||||||
|
|
||||||
|
bool
|
||||||
|
libxlDomainObjEndJob(libxlDriverPrivatePtr driver,
|
||||||
|
virDomainObjPtr obj)
|
||||||
|
ATTRIBUTE_RETURN_CHECK;
|
||||||
|
|
||||||
#endif /* LIBXL_DOMAIN_H */
|
#endif /* LIBXL_DOMAIN_H */
|
||||||
|
Loading…
x
Reference in New Issue
Block a user