]> git.ipfire.org Git - thirdparty/libvirt.git/commitdiff
qemu: Refresh the current size of virtio-mem on monitor reconnect
authorMichal Privoznik <mprivozn@redhat.com>
Wed, 25 Nov 2020 10:35:00 +0000 (11:35 +0100)
committerMichal Privoznik <mprivozn@redhat.com>
Fri, 1 Oct 2021 09:04:53 +0000 (11:04 +0200)
If the QEMU driver restarts it loses the track of the current size
of virtio-mem (because it's runtime type of information and thus
not stored in XML) and therefore, we have to refresh it when
reconnecting to the domain monitor.

Signed-off-by: Michal Privoznik <mprivozn@redhat.com>
Reviewed-by: Ján Tomko <jtomko@redhat.com>
src/qemu/qemu_domain.c
src/qemu/qemu_monitor.h
src/qemu/qemu_monitor_json.c
src/qemu/qemu_process.c

index 031ca4e00dddee942cc03d0f7debe9f6d9f0788b..a755f8678ea6e4c5d8b769ff5bbb38c2742d659c 100644 (file)
@@ -8212,9 +8212,23 @@ qemuDomainUpdateMemoryDeviceInfo(virQEMUDriver *driver,
         if (!(dimm = virHashLookup(meminfo, mem->info.alias)))
             continue;
 
-        mem->info.type = VIR_DOMAIN_DEVICE_ADDRESS_TYPE_DIMM;
-        mem->info.addr.dimm.slot = dimm->slot;
-        mem->info.addr.dimm.base = dimm->address;
+        switch (mem->model) {
+        case VIR_DOMAIN_MEMORY_MODEL_VIRTIO_MEM:
+            mem->currentsize = VIR_DIV_UP(dimm->size, 1024);
+            break;
+
+        case VIR_DOMAIN_MEMORY_MODEL_DIMM:
+        case VIR_DOMAIN_MEMORY_MODEL_NVDIMM:
+            mem->info.type = VIR_DOMAIN_DEVICE_ADDRESS_TYPE_DIMM;
+            mem->info.addr.dimm.slot = dimm->slot;
+            mem->info.addr.dimm.base = dimm->address;
+            break;
+
+        case VIR_DOMAIN_MEMORY_MODEL_VIRTIO_PMEM:
+        case VIR_DOMAIN_MEMORY_MODEL_NONE:
+        case VIR_DOMAIN_MEMORY_MODEL_LAST:
+            break;
+        }
     }
 
     virHashFree(meminfo);
index 962b5165422ebee5fc9a2b035cb2ec021dd768dd..648fe293edb34f26e86f923e9609cd9a086c3b59 100644 (file)
@@ -1385,10 +1385,13 @@ int qemuMonitorSetIOThread(qemuMonitor *mon,
 
 typedef struct _qemuMonitorMemoryDeviceInfo qemuMonitorMemoryDeviceInfo;
 struct _qemuMonitorMemoryDeviceInfo {
+    /* For pc-dimm */
     unsigned long long address;
     unsigned int slot;
     bool hotplugged;
     bool hotpluggable;
+    /* For virtio-mem */
+    unsigned long long size; /* in bytes */
 };
 
 int qemuMonitorGetMemoryDeviceInfo(qemuMonitor *mon,
index fc3bb388be31fff265f7b55c5d4fd47c6fc8bfe1..1b98baa4c7eb87a568bb2a5b95d0dda037dfc80a 100644 (file)
@@ -7978,7 +7978,6 @@ qemuMonitorJSONGetMemoryDeviceInfo(qemuMonitor *mon,
     virJSONValue *cmd;
     virJSONValue *reply = NULL;
     virJSONValue *data = NULL;
-    qemuMonitorMemoryDeviceInfo *meminfo = NULL;
     size_t i;
 
     if (!(cmd = qemuMonitorJSONMakeCommand("query-memory-devices", NULL)))
@@ -7999,6 +7998,9 @@ qemuMonitorJSONGetMemoryDeviceInfo(qemuMonitor *mon,
 
     for (i = 0; i < virJSONValueArraySize(data); i++) {
         virJSONValue *elem = virJSONValueArrayGet(data, i);
+        g_autofree qemuMonitorMemoryDeviceInfo *meminfo = NULL;
+        virJSONValue *dimminfo;
+        const char *devalias;
         const char *type;
 
         if (!(type = virJSONValueObjectGetString(elem, "type"))) {
@@ -8008,26 +8010,26 @@ qemuMonitorJSONGetMemoryDeviceInfo(qemuMonitor *mon,
             goto cleanup;
         }
 
-        /* dimm memory devices */
-        if (STREQ(type, "dimm")) {
-            virJSONValue *dimminfo;
-            const char *devalias;
-
-            if (!(dimminfo = virJSONValueObjectGetObject(elem, "data"))) {
-                virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
-                               _("query-memory-devices reply data doesn't "
-                                 "contain enum data"));
-                goto cleanup;
-            }
+        if (!(dimminfo = virJSONValueObjectGetObject(elem, "data"))) {
+            virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
+                           _("query-memory-devices reply data doesn't "
+                             "contain enum data"));
+            goto cleanup;
+        }
 
-            if (!(devalias = virJSONValueObjectGetString(dimminfo, "id"))) {
-                virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
-                               _("dimm memory info data is missing 'id'"));
-                goto cleanup;
-            }
+        /* While 'id' attribute is marked as optional in QEMU's QAPI
+         * specification, Libvirt always sets it. Thus we can fail if not
+         * present. */
+        if (!(devalias = virJSONValueObjectGetString(dimminfo, "id"))) {
+            virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
+                           _("dimm memory info data is missing 'id'"));
+            goto cleanup;
+        }
 
-            meminfo = g_new0(qemuMonitorMemoryDeviceInfo, 1);
+        meminfo = g_new0(qemuMonitorMemoryDeviceInfo, 1);
 
+        /* dimm memory devices */
+        if (STREQ(type, "dimm")) {
             if (virJSONValueObjectGetNumberUlong(dimminfo, "addr",
                                                  &meminfo->address) < 0) {
                 virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
@@ -8058,17 +8060,27 @@ qemuMonitorJSONGetMemoryDeviceInfo(qemuMonitor *mon,
 
             }
 
-            if (virHashAddEntry(info, devalias, meminfo) < 0)
+        } else if (STREQ(type, "virtio-mem")) {
+            if (virJSONValueObjectGetNumberUlong(dimminfo, "size",
+                                                 &meminfo->size) < 0) {
+                virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
+                               _("malformed/missing size in virtio memory info"));
                 goto cleanup;
-
-            meminfo = NULL;
+            }
+        } else {
+            /* type not handled yet */
+            continue;
         }
+
+        if (virHashAddEntry(info, devalias, meminfo) < 0)
+            goto cleanup;
+
+        meminfo = NULL;
     }
 
     ret = 0;
 
  cleanup:
-    VIR_FREE(meminfo);
     virJSONValueFree(cmd);
     virJSONValueFree(reply);
     return ret;
index b2c708ff71b74ffa7529ad5e293c9253ddaec5e5..6e6de835407f32cdea8af5bea10f4fdd107687c6 100644 (file)
@@ -8718,6 +8718,9 @@ qemuProcessReconnect(void *opaque)
 
     qemuDomainVcpuPersistOrder(obj->def);
 
+    if (qemuDomainUpdateMemoryDeviceInfo(driver, obj, QEMU_ASYNC_JOB_NONE) < 0)
+        goto error;
+
     if (qemuProcessDetectIOThreadPIDs(driver, obj, QEMU_ASYNC_JOB_NONE) < 0)
         goto error;