mirror of
https://gitlab.com/libvirt/libvirt.git
synced 2025-02-23 03:42:19 +00:00
qemu: Introduce job queue size limit
This patch creates an optional BeginJob queue size limit. When active, all other attempts above level will fail. To set this feature assign desired value to max_queued variable in qemu.conf. Setting it to 0 turns it off.
This commit is contained in:
parent
597fe3cee6
commit
3005cacb69
@ -51,6 +51,7 @@ module Libvirtd_qemu =
|
|||||||
| bool_entry "set_process_name"
|
| bool_entry "set_process_name"
|
||||||
| int_entry "max_processes"
|
| int_entry "max_processes"
|
||||||
| str_entry "lock_manager"
|
| str_entry "lock_manager"
|
||||||
|
| int_entry "max_queued"
|
||||||
|
|
||||||
(* Each enty in the config is one of the following three ... *)
|
(* Each enty in the config is one of the following three ... *)
|
||||||
let entry = vnc_entry
|
let entry = vnc_entry
|
||||||
|
@ -309,3 +309,10 @@
|
|||||||
# disk), uncomment this
|
# disk), uncomment this
|
||||||
#
|
#
|
||||||
# lock_manager = "sanlock"
|
# lock_manager = "sanlock"
|
||||||
|
|
||||||
|
# Set limit of maximum APIs queued on one domain. All other APIs
|
||||||
|
# over this threshold will fail on acquiring job lock. Specially,
|
||||||
|
# setting to zero turns this feature off.
|
||||||
|
# Note, that job lock is per domain.
|
||||||
|
#
|
||||||
|
# max_queued = 0
|
||||||
|
@ -458,6 +458,10 @@ int qemudLoadDriverConfig(struct qemud_driver *driver,
|
|||||||
VIR_FREE(lockConf);
|
VIR_FREE(lockConf);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
p = virConfGetValue(conf, "max_queued");
|
||||||
|
CHECK_TYPE("max_queued", VIR_CONF_LONG);
|
||||||
|
if (p) driver->max_queued = p->l;
|
||||||
|
|
||||||
virConfFree (conf);
|
virConfFree (conf);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -109,6 +109,8 @@ struct qemud_driver {
|
|||||||
|
|
||||||
int maxProcesses;
|
int maxProcesses;
|
||||||
|
|
||||||
|
int max_queued;
|
||||||
|
|
||||||
virCapsPtr caps;
|
virCapsPtr caps;
|
||||||
|
|
||||||
virDomainEventStatePtr domainEventState;
|
virDomainEventStatePtr domainEventState;
|
||||||
|
@ -713,6 +713,8 @@ qemuDomainObjBeginJobInternal(struct qemud_driver *driver,
|
|||||||
unsigned long long then;
|
unsigned long long then;
|
||||||
bool nested = job == QEMU_JOB_ASYNC_NESTED;
|
bool nested = job == QEMU_JOB_ASYNC_NESTED;
|
||||||
|
|
||||||
|
priv->jobs_queued++;
|
||||||
|
|
||||||
if (virTimeMs(&now) < 0)
|
if (virTimeMs(&now) < 0)
|
||||||
return -1;
|
return -1;
|
||||||
then = now + QEMU_JOB_WAIT_TIME;
|
then = now + QEMU_JOB_WAIT_TIME;
|
||||||
@ -722,6 +724,11 @@ qemuDomainObjBeginJobInternal(struct qemud_driver *driver,
|
|||||||
qemuDriverUnlock(driver);
|
qemuDriverUnlock(driver);
|
||||||
|
|
||||||
retry:
|
retry:
|
||||||
|
if (driver->max_queued &&
|
||||||
|
priv->jobs_queued > driver->max_queued) {
|
||||||
|
goto error;
|
||||||
|
}
|
||||||
|
|
||||||
while (!nested && !qemuDomainJobAllowed(priv, job)) {
|
while (!nested && !qemuDomainJobAllowed(priv, job)) {
|
||||||
if (virCondWaitUntil(&priv->job.asyncCond, &obj->lock, then) < 0)
|
if (virCondWaitUntil(&priv->job.asyncCond, &obj->lock, then) < 0)
|
||||||
goto error;
|
goto error;
|
||||||
@ -761,9 +768,15 @@ error:
|
|||||||
if (errno == ETIMEDOUT)
|
if (errno == ETIMEDOUT)
|
||||||
qemuReportError(VIR_ERR_OPERATION_TIMEOUT,
|
qemuReportError(VIR_ERR_OPERATION_TIMEOUT,
|
||||||
"%s", _("cannot acquire state change lock"));
|
"%s", _("cannot acquire state change lock"));
|
||||||
|
else if (driver->max_queued &&
|
||||||
|
priv->jobs_queued > driver->max_queued)
|
||||||
|
qemuReportError(VIR_ERR_OPERATION_FAILED,
|
||||||
|
"%s", _("cannot acquire state change lock "
|
||||||
|
"due to max_queued limit"));
|
||||||
else
|
else
|
||||||
virReportSystemError(errno,
|
virReportSystemError(errno,
|
||||||
"%s", _("cannot acquire job mutex"));
|
"%s", _("cannot acquire job mutex"));
|
||||||
|
priv->jobs_queued--;
|
||||||
if (driver_locked) {
|
if (driver_locked) {
|
||||||
virDomainObjUnlock(obj);
|
virDomainObjUnlock(obj);
|
||||||
qemuDriverLock(driver);
|
qemuDriverLock(driver);
|
||||||
@ -844,6 +857,8 @@ int qemuDomainObjEndJob(struct qemud_driver *driver, virDomainObjPtr obj)
|
|||||||
{
|
{
|
||||||
qemuDomainObjPrivatePtr priv = obj->privateData;
|
qemuDomainObjPrivatePtr priv = obj->privateData;
|
||||||
|
|
||||||
|
priv->jobs_queued--;
|
||||||
|
|
||||||
qemuDomainObjResetJob(priv);
|
qemuDomainObjResetJob(priv);
|
||||||
qemuDomainObjSaveJob(driver, obj);
|
qemuDomainObjSaveJob(driver, obj);
|
||||||
virCondSignal(&priv->job.cond);
|
virCondSignal(&priv->job.cond);
|
||||||
@ -856,6 +871,8 @@ qemuDomainObjEndAsyncJob(struct qemud_driver *driver, virDomainObjPtr obj)
|
|||||||
{
|
{
|
||||||
qemuDomainObjPrivatePtr priv = obj->privateData;
|
qemuDomainObjPrivatePtr priv = obj->privateData;
|
||||||
|
|
||||||
|
priv->jobs_queued--;
|
||||||
|
|
||||||
qemuDomainObjResetAsyncJob(priv);
|
qemuDomainObjResetAsyncJob(priv);
|
||||||
qemuDomainObjSaveJob(driver, obj);
|
qemuDomainObjSaveJob(driver, obj);
|
||||||
virCondBroadcast(&priv->job.asyncCond);
|
virCondBroadcast(&priv->job.asyncCond);
|
||||||
|
@ -113,6 +113,8 @@ struct _qemuDomainObjPrivate {
|
|||||||
char *lockState;
|
char *lockState;
|
||||||
|
|
||||||
bool fakeReboot;
|
bool fakeReboot;
|
||||||
|
|
||||||
|
int jobs_queued;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct qemuDomainWatchdogEvent
|
struct qemuDomainWatchdogEvent
|
||||||
|
Loading…
x
Reference in New Issue
Block a user