mirror of
https://gitlab.com/libvirt/libvirt.git
synced 2025-02-02 09:55:18 +00:00
lxc: Add job support to lxc driver
Follows the pattern used in the libxl driver for managing multiple, simultaneous jobs within the driver. Signed-off-by: Katerina Koukiou <k.koukiou@gmail.com>
This commit is contained in:
parent
71d2c172ed
commit
03e9077bd1
@ -30,22 +30,164 @@
|
||||
#include "virstring.h"
|
||||
#include "virutil.h"
|
||||
#include "virfile.h"
|
||||
#include "virtime.h"
|
||||
|
||||
#define VIR_FROM_THIS VIR_FROM_LXC
|
||||
#define LXC_NAMESPACE_HREF "http://libvirt.org/schemas/domain/lxc/1.0"
|
||||
|
||||
VIR_ENUM_IMPL(virLXCDomainJob, LXC_JOB_LAST,
|
||||
"none",
|
||||
"query",
|
||||
"destroy",
|
||||
"modify",
|
||||
);
|
||||
|
||||
VIR_LOG_INIT("lxc.lxc_domain");
|
||||
|
||||
static void *virLXCDomainObjPrivateAlloc(void)
|
||||
static int
|
||||
virLXCDomainObjInitJob(virLXCDomainObjPrivatePtr priv)
|
||||
{
|
||||
memset(&priv->job, 0, sizeof(priv->job));
|
||||
|
||||
if (virCondInit(&priv->job.cond) < 0)
|
||||
return -1;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void
|
||||
virLXCDomainObjResetJob(virLXCDomainObjPrivatePtr priv)
|
||||
{
|
||||
struct virLXCDomainJobObj *job = &priv->job;
|
||||
|
||||
job->active = LXC_JOB_NONE;
|
||||
job->owner = 0;
|
||||
}
|
||||
|
||||
static void
|
||||
virLXCDomainObjFreeJob(virLXCDomainObjPrivatePtr priv)
|
||||
{
|
||||
ignore_value(virCondDestroy(&priv->job.cond));
|
||||
}
|
||||
|
||||
/* Give up waiting for mutex after 30 seconds */
|
||||
#define LXC_JOB_WAIT_TIME (1000ull * 30)
|
||||
|
||||
/*
|
||||
* obj must be locked before calling, virLXCDriverPtr 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
|
||||
virLXCDomainObjBeginJob(virLXCDriverPtr driver ATTRIBUTE_UNUSED,
|
||||
virDomainObjPtr obj,
|
||||
enum virLXCDomainJob job)
|
||||
{
|
||||
virLXCDomainObjPrivatePtr priv = obj->privateData;
|
||||
unsigned long long now;
|
||||
unsigned long long then;
|
||||
|
||||
if (virTimeMillisNow(&now) < 0)
|
||||
return -1;
|
||||
then = now + LXC_JOB_WAIT_TIME;
|
||||
|
||||
virObjectRef(obj);
|
||||
|
||||
while (priv->job.active) {
|
||||
VIR_DEBUG("Wait normal job condition for starting job: %s",
|
||||
virLXCDomainJobTypeToString(job));
|
||||
if (virCondWaitUntil(&priv->job.cond, &obj->parent.lock, then) < 0)
|
||||
goto error;
|
||||
}
|
||||
|
||||
virLXCDomainObjResetJob(priv);
|
||||
|
||||
VIR_DEBUG("Starting job: %s", virLXCDomainJobTypeToString(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)",
|
||||
virLXCDomainJobTypeToString(job),
|
||||
obj->def->name,
|
||||
virLXCDomainJobTypeToString(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 virLXCDomainBeginJob() 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
|
||||
virLXCDomainObjEndJob(virLXCDriverPtr driver ATTRIBUTE_UNUSED,
|
||||
virDomainObjPtr obj)
|
||||
{
|
||||
virLXCDomainObjPrivatePtr priv = obj->privateData;
|
||||
enum virLXCDomainJob job = priv->job.active;
|
||||
|
||||
VIR_DEBUG("Stopping job: %s",
|
||||
virLXCDomainJobTypeToString(job));
|
||||
|
||||
virLXCDomainObjResetJob(priv);
|
||||
virCondSignal(&priv->job.cond);
|
||||
|
||||
return virObjectUnref(obj);
|
||||
}
|
||||
|
||||
|
||||
static void *
|
||||
virLXCDomainObjPrivateAlloc(void)
|
||||
{
|
||||
virLXCDomainObjPrivatePtr priv;
|
||||
|
||||
if (VIR_ALLOC(priv) < 0)
|
||||
return NULL;
|
||||
|
||||
if (virLXCDomainObjInitJob(priv) < 0) {
|
||||
VIR_FREE(priv);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return priv;
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
virLXCDomainObjPrivateFree(void *data)
|
||||
{
|
||||
virLXCDomainObjPrivatePtr priv = data;
|
||||
|
||||
virCgroupFree(&priv->cgroup);
|
||||
virLXCDomainObjFreeJob(priv);
|
||||
VIR_FREE(priv);
|
||||
}
|
||||
|
||||
|
||||
|
||||
VIR_ENUM_IMPL(virLXCDomainNamespace,
|
||||
VIR_LXC_DOMAIN_NAMESPACE_LAST,
|
||||
"sharenet",
|
||||
@ -190,16 +332,6 @@ virDomainXMLNamespace virLXCDriverDomainXMLNamespace = {
|
||||
};
|
||||
|
||||
|
||||
static void virLXCDomainObjPrivateFree(void *data)
|
||||
{
|
||||
virLXCDomainObjPrivatePtr priv = data;
|
||||
|
||||
virCgroupFree(&priv->cgroup);
|
||||
|
||||
VIR_FREE(priv);
|
||||
}
|
||||
|
||||
|
||||
static int
|
||||
virLXCDomainObjPrivateXMLFormat(virBufferPtr buf,
|
||||
virDomainObjPtr vm)
|
||||
|
@ -27,6 +27,7 @@
|
||||
# include "lxc_conf.h"
|
||||
# include "lxc_monitor.h"
|
||||
|
||||
|
||||
typedef enum {
|
||||
VIR_LXC_DOMAIN_NAMESPACE_SHARENET = 0,
|
||||
VIR_LXC_DOMAIN_NAMESPACE_SHAREIPC,
|
||||
@ -53,6 +54,28 @@ struct _lxcDomainDef {
|
||||
char *ns_val[VIR_LXC_DOMAIN_NAMESPACE_LAST];
|
||||
};
|
||||
|
||||
|
||||
/* Only 1 job is allowed at any time
|
||||
* A job includes *all* lxc.so api, even those just querying
|
||||
* information, not merely actions */
|
||||
|
||||
enum virLXCDomainJob {
|
||||
LXC_JOB_NONE = 0, /* Always set to 0 for easy if (jobActive) conditions */
|
||||
LXC_JOB_QUERY, /* Doesn't change any state */
|
||||
LXC_JOB_DESTROY, /* Destroys the domain (cannot be masked out) */
|
||||
LXC_JOB_MODIFY, /* May change state */
|
||||
LXC_JOB_LAST
|
||||
};
|
||||
VIR_ENUM_DECL(virLXCDomainJob)
|
||||
|
||||
|
||||
struct virLXCDomainJobObj {
|
||||
virCond cond; /* Use to coordinate jobs */
|
||||
enum virLXCDomainJob active; /* Currently running job */
|
||||
int owner; /* Thread which set current job */
|
||||
};
|
||||
|
||||
|
||||
typedef struct _virLXCDomainObjPrivate virLXCDomainObjPrivate;
|
||||
typedef virLXCDomainObjPrivate *virLXCDomainObjPrivatePtr;
|
||||
struct _virLXCDomainObjPrivate {
|
||||
@ -65,10 +88,24 @@ struct _virLXCDomainObjPrivate {
|
||||
|
||||
virCgroupPtr cgroup;
|
||||
char *machineName;
|
||||
|
||||
struct virLXCDomainJobObj job;
|
||||
};
|
||||
|
||||
extern virDomainXMLNamespace virLXCDriverDomainXMLNamespace;
|
||||
extern virDomainXMLPrivateDataCallbacks virLXCDriverPrivateDataCallbacks;
|
||||
extern virDomainDefParserConfig virLXCDriverDomainDefParserConfig;
|
||||
|
||||
int
|
||||
virLXCDomainObjBeginJob(virLXCDriverPtr driver,
|
||||
virDomainObjPtr obj,
|
||||
enum virLXCDomainJob job)
|
||||
ATTRIBUTE_RETURN_CHECK;
|
||||
|
||||
bool
|
||||
virLXCDomainObjEndJob(virLXCDriverPtr driver,
|
||||
virDomainObjPtr obj)
|
||||
ATTRIBUTE_RETURN_CHECK;
|
||||
|
||||
|
||||
#endif /* __LXC_DOMAIN_H__ */
|
||||
|
Loading…
x
Reference in New Issue
Block a user