2d1356
From a3176697f2d1288d3e30ca6aac0d2c5891a6b135 Mon Sep 17 00:00:00 2001
2d1356
Message-Id: <a3176697f2d1288d3e30ca6aac0d2c5891a6b135@dist-git>
2d1356
From: Peter Krempa <pkrempa@redhat.com>
2d1356
Date: Thu, 26 May 2016 12:54:54 +0200
2d1356
Subject: [PATCH] qemu: bulk stats: Don't access possibly blocked storage
2d1356
2d1356
https://bugzilla.redhat.com/show_bug.cgi?id=1339963
2d1356
2d1356
If the stats for a block device can't be acquired from qemu we've
2d1356
fallen back to loading them from the file on the disk in libvirt.
2d1356
2d1356
If qemu is not cooperating due to being stuck on an inaccessible NFS
2d1356
share we would then attempt to read the files and get stuck too with
2d1356
the VM object locked. All other APIs would eventually get stuck waiting
2d1356
on the VM lock.
2d1356
2d1356
Avoid this problem by skipping the block stats if the VM is online but
2d1356
the monitor did not provide any stats.
2d1356
2d1356
Resolves: https://bugzilla.redhat.com/show_bug.cgi?id=1337073
2d1356
(cherry picked from commit 71d2c172edb997bae1e883b2e1bafa97d9f953a1)
2d1356
---
2d1356
 src/qemu/qemu_driver.c | 13 +++++++++++--
2d1356
 1 file changed, 11 insertions(+), 2 deletions(-)
2d1356
2d1356
diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c
2d1356
index 1075237..5e28b21 100644
2d1356
--- a/src/qemu/qemu_driver.c
2d1356
+++ b/src/qemu/qemu_driver.c
2d1356
@@ -19392,13 +19392,22 @@ qemuDomainGetStatsOneBlock(virQEMUDriverPtr driver,
2d1356
         QEMU_ADD_BLOCK_PARAM_UI(record, maxparams, block_idx, "backingIndex",
2d1356
                                 backing_idx);
2d1356
 
2d1356
-    /* use fallback path if data is not available */
2d1356
-    if (!stats || !alias || !(entry = virHashLookup(stats, alias))) {
2d1356
+    /* the VM is offline so we have to go and load the stast from the disk by
2d1356
+     * ourselves */
2d1356
+    if (!virDomainObjIsActive(dom)) {
2d1356
         ret = qemuDomainGetStatsOneBlockFallback(driver, cfg, dom, record,
2d1356
                                                  maxparams, src, block_idx);
2d1356
         goto cleanup;
2d1356
     }
2d1356
 
2d1356
+    /* In case where qemu didn't provide the stats we stop here rather than
2d1356
+     * trying to refresh the stats from the disk. Inability to provide stats is
2d1356
+     * usually caused by blocked storage so this would make libvirtd hang */
2d1356
+    if (!stats || !alias || !(entry = virHashLookup(stats, alias))) {
2d1356
+        ret = 0;
2d1356
+        goto cleanup;
2d1356
+    }
2d1356
+
2d1356
     QEMU_ADD_BLOCK_PARAM_LL(record, maxparams, block_idx,
2d1356
                             "rd.reqs", entry->rd_req);
2d1356
     QEMU_ADD_BLOCK_PARAM_LL(record, maxparams, block_idx,
2d1356
-- 
2d1356
2.8.3
2d1356