]> xenbits.xensource.com Git - libvirt.git/commitdiff
qemu: Introduce job queue size limit
authorMichal Privoznik <mprivozn@redhat.com>
Fri, 12 Aug 2011 13:29:37 +0000 (15:29 +0200)
committerMichal Privoznik <mprivozn@redhat.com>
Mon, 5 Sep 2011 16:14:08 +0000 (18:14 +0200)
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.

src/qemu/libvirtd_qemu.aug
src/qemu/qemu.conf
src/qemu/qemu_conf.c
src/qemu/qemu_conf.h
src/qemu/qemu_domain.c
src/qemu/qemu_domain.h

index d018ac259d01ddbf1bd51aef1b36ff77b4b7f5b1..6c145c7d82cc3396840049aeeab19f8360af58ce 100644 (file)
@@ -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
index 79c6e8510b5dd795af6c47c9eddc0a730c48f8b4..4da5d5a13fddcd0391f15c2050f1657686483d9c 100644 (file)
 # 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
index 443e08d7bbccdf0effc37760fc4b55bfe615b909..d1bf075659f433b6e5144cbd0f0f34ce86db4f2e 100644 (file)
@@ -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;
 }
index 5469a63abef9be761bd46810693080c9401b2ec2..e8b92a49820337bc9b8bdf85834ab9b25da3cb71 100644 (file)
@@ -109,6 +109,8 @@ struct qemud_driver {
 
     int maxProcesses;
 
+    int max_queued;
+
     virCapsPtr caps;
 
     virDomainEventStatePtr domainEventState;
index 675c6dff9b068047387096c409dfd4492acc7275..982bad6c7e8f7ed283df5e6d13e6babfe3e08add 100644 (file)
@@ -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);
index e12ca8e8f60ab130f9d39258ae7060b1392271f2..55875fe4dec223200793859a8bc0caf5c73c14bd 100644 (file)
@@ -113,6 +113,8 @@ struct _qemuDomainObjPrivate {
     char *lockState;
 
     bool fakeReboot;
+
+    int jobs_queued;
 };
 
 struct qemuDomainWatchdogEvent