From: Peter Krempa <[email protected]>

Introduce a new helper for querying disk sizes called
'qemuDomainStorageSourceProbeSize'. It combines what
'qemuDomainStorageUpdatePhysical' and 'qemuStorageLimitsRefresh' query,
but doesn't update the virStorageSource struct. Instead the fetched size
is returned via arguments as pointers.

The idea of this helper is to centralize the two functions it replaces
into a single place with more reasonable semantics w.r.t access of @src
so that it can be later used with unlocked domain object to avoid cases
where stuck storage would make the domain object stuck too.

Signed-off-by: Peter Krempa <[email protected]>
---
 src/qemu/qemu_domain.c | 69 ++++++++++++++++++++++++++++++++++++++++++
 src/qemu/qemu_domain.h |  9 ++++++
 2 files changed, 78 insertions(+)

diff --git a/src/qemu/qemu_domain.c b/src/qemu/qemu_domain.c
index e7afeb3fa0..1792b0e9d0 100644
--- a/src/qemu/qemu_domain.c
+++ b/src/qemu/qemu_domain.c
@@ -53,6 +53,7 @@
 #include "virnetdevbandwidth.h"
 #include "virstoragefile.h"
 #include "storage_source.h"
+#include "storage_file_probe.h"
 #include "virstring.h"
 #include "virprocess.h"
 #include "vircrypto.h"
@@ -11659,6 +11660,74 @@ qemuDomainStorageUpdatePhysical(virQEMUDriverConfig 
*cfg,
 }


+/**
+ * qemuDomainStorageSourceProbeSize:
+ * @cfg: qemu driver configuration object
+ * @vm: domain object
+ * @src: storage source to update
+ * @allocation: filled by current allocation (used) size in bytes (may be NULL)
+ * @capacity: filled by (guest visible) capacity of @src in bytes (may be NULL)
+ * @physical_ret: filed by size of the underlying storage of @src in bytes 
(may be NULL)
+ *
+ * Fetches size information of @src and fills @allocation/@capacity/@physical
+ * (whichever is non-NULL). @src and the fields with same names in that 
structure
+ * are not used/touched.
+ *
+ * Returns 0 on success, -1 on error. No libvirt errors are reported.
+ */
+int
+qemuDomainStorageSourceProbeSize(virQEMUDriverConfig *cfg,
+                                 virDomainObj *vm,
+                                 virStorageSource *src,
+                                 unsigned long long *allocation,
+                                 unsigned long long *capacity,
+                                 unsigned long long *physical_ret)
+{
+    int rc;
+    int fd = -1;
+    struct stat sb;
+    g_autofree char *buf = NULL;
+    ssize_t buflen = 0;
+    unsigned long long physical = 0;
+
+    if (virStorageSourceIsEmpty(src))
+        return 0;
+
+    if (qemuDomainStorageOpenStat(cfg, vm, src, &fd, &sb, true) <= 0)
+        return -1;
+
+    rc = virStorageSourceGetSize(src, fd, &sb, allocation, &physical);
+
+    if (capacity && !qemuBlockStorageSourceIsRaw(src)) {
+        if (virStorageSourceIsLocalStorage(src)) {
+            buflen = virFileReadHeaderFD(fd, VIR_STORAGE_MAX_HEADER, &buf);
+        } else {
+            if ((buflen = virStorageSourceRead(src, 0, VIR_STORAGE_MAX_HEADER, 
&buf)) < 0)
+                virResetLastError();
+        }
+    }
+
+    qemuDomainStorageCloseStat(src, &fd);
+
+    if (rc < 0 || buflen < 0)
+        return -1;
+
+    if (capacity) {
+        *capacity = physical;
+
+        if (!qemuBlockStorageSourceIsRaw(src)) {
+            if (virStorageSourceProbeCapacityFromBuf(src->format, buf, buflen, 
capacity))
+                return -1;
+        }
+    }
+
+    if (physical_ret)
+        *physical_ret = physical;
+
+    return 0;
+}
+
+
 /**
  * qemuDomainCheckCPU:
  * @arch: CPU architecture
diff --git a/src/qemu/qemu_domain.h b/src/qemu/qemu_domain.h
index b321a64e96..9bb8d0f97d 100644
--- a/src/qemu/qemu_domain.h
+++ b/src/qemu/qemu_domain.h
@@ -1176,6 +1176,15 @@ int
 qemuDomainStorageUpdatePhysical(virQEMUDriverConfig *cfg,
                                 virDomainObj *vm,
                                 virStorageSource *src);
+
+int
+qemuDomainStorageSourceProbeSize(virQEMUDriverConfig *cfg,
+                                 virDomainObj *vm,
+                                 virStorageSource *src,
+                                 unsigned long long *allocation,
+                                 unsigned long long *capacity,
+                                 unsigned long long *physical_ret);
+
 virCPUCompareResult
 qemuDomainCheckCPU(virArch arch,
                    virDomainVirtType virtType,
-- 
2.54.0

Reply via email to