mirror of
https://gitlab.com/libvirt/libvirt.git
synced 2024-12-25 01:34:11 +03: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"
|
||||
| int_entry "max_processes"
|
||||
| str_entry "lock_manager"
|
||||
| int_entry "max_queued"
|
||||
|
||||
(* Each enty in the config is one of the following three ... *)
|
||||
let entry = vnc_entry
|
||||
|
@ -309,3 +309,10 @@
|
||||
# disk), uncomment this
|
||||
#
|
||||
# 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);
|
||||
}
|
||||
|
||||
p = virConfGetValue(conf, "max_queued");
|
||||
CHECK_TYPE("max_queued", VIR_CONF_LONG);
|
||||
if (p) driver->max_queued = p->l;
|
||||
|
||||
virConfFree (conf);
|
||||
return 0;
|
||||
}
|
||||
|
@ -109,6 +109,8 @@ struct qemud_driver {
|
||||
|
||||
int maxProcesses;
|
||||
|
||||
int max_queued;
|
||||
|
||||
virCapsPtr caps;
|
||||
|
||||
virDomainEventStatePtr domainEventState;
|
||||
|
@ -713,6 +713,8 @@ qemuDomainObjBeginJobInternal(struct qemud_driver *driver,
|
||||
unsigned long long then;
|
||||
bool nested = job == QEMU_JOB_ASYNC_NESTED;
|
||||
|
||||
priv->jobs_queued++;
|
||||
|
||||
if (virTimeMs(&now) < 0)
|
||||
return -1;
|
||||
then = now + QEMU_JOB_WAIT_TIME;
|
||||
@ -722,6 +724,11 @@ qemuDomainObjBeginJobInternal(struct qemud_driver *driver,
|
||||
qemuDriverUnlock(driver);
|
||||
|
||||
retry:
|
||||
if (driver->max_queued &&
|
||||
priv->jobs_queued > driver->max_queued) {
|
||||
goto error;
|
||||
}
|
||||
|
||||
while (!nested && !qemuDomainJobAllowed(priv, job)) {
|
||||
if (virCondWaitUntil(&priv->job.asyncCond, &obj->lock, then) < 0)
|
||||
goto error;
|
||||
@ -761,9 +768,15 @@ error:
|
||||
if (errno == ETIMEDOUT)
|
||||
qemuReportError(VIR_ERR_OPERATION_TIMEOUT,
|
||||
"%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
|
||||
virReportSystemError(errno,
|
||||
"%s", _("cannot acquire job mutex"));
|
||||
priv->jobs_queued--;
|
||||
if (driver_locked) {
|
||||
virDomainObjUnlock(obj);
|
||||
qemuDriverLock(driver);
|
||||
@ -844,6 +857,8 @@ int qemuDomainObjEndJob(struct qemud_driver *driver, virDomainObjPtr obj)
|
||||
{
|
||||
qemuDomainObjPrivatePtr priv = obj->privateData;
|
||||
|
||||
priv->jobs_queued--;
|
||||
|
||||
qemuDomainObjResetJob(priv);
|
||||
qemuDomainObjSaveJob(driver, obj);
|
||||
virCondSignal(&priv->job.cond);
|
||||
@ -856,6 +871,8 @@ qemuDomainObjEndAsyncJob(struct qemud_driver *driver, virDomainObjPtr obj)
|
||||
{
|
||||
qemuDomainObjPrivatePtr priv = obj->privateData;
|
||||
|
||||
priv->jobs_queued--;
|
||||
|
||||
qemuDomainObjResetAsyncJob(priv);
|
||||
qemuDomainObjSaveJob(driver, obj);
|
||||
virCondBroadcast(&priv->job.asyncCond);
|
||||
|
@ -113,6 +113,8 @@ struct _qemuDomainObjPrivate {
|
||||
char *lockState;
|
||||
|
||||
bool fakeReboot;
|
||||
|
||||
int jobs_queued;
|
||||
};
|
||||
|
||||
struct qemuDomainWatchdogEvent
|
||||
|
Loading…
Reference in New Issue
Block a user