Re: [libvirt] [PATCHv3 11/12] qemu: Implement memory device hotplug

2015-03-23 Thread Peter Krempa
On Thu, Mar 19, 2015 at 18:40:36 -0400, John Ferlan wrote:
> 
> 
> On 03/17/2015 10:20 AM, Peter Krempa wrote:
> > Add code to hot-add memory devices to running qemu instances.
> > ---
> > 
> > Notes:
> > Version 3:
> > - added comment to clarify that @mem is always consumed by 
> > qemuDomainAttachMemory
> > Version 2:
> > - no change
> > 
> > Version 2:
> > - no change
> > 
> >  src/qemu/qemu_command.c |  4 +--
> >  src/qemu/qemu_command.h | 15 
> >  src/qemu/qemu_driver.c  |  5 ++-
> >  src/qemu/qemu_hotplug.c | 95 
> > +
> >  src/qemu/qemu_hotplug.h |  3 ++
> >  5 files changed, 119 insertions(+), 3 deletions(-)
> > 
> > @@ -1672,6 +1672,101 @@ qemuDomainAttachRNGDevice(virQEMUDriverPtr driver,

...

> >  }
> > 
> > 
> > +/**
> > + * qemuDomainAttachMemory:
> > + * @driver: qemu driver data
> > + * @vm: VM object
> > + * @mem: Definition of the memory device to be attached. @mem is always 
> > consumed
> > + *
> > + * Attaches memory device described by @mem to domain @vm.
> > + *
> > + * Returns 0 on success -1 on error.
> > + */
> > +int
> > +qemuDomainAttachMemory(virQEMUDriverPtr driver,
> > +   virDomainObjPtr vm,
> > +   virDomainMemoryDefPtr mem)
> > +{
> > +qemuDomainObjPrivatePtr priv = vm->privateData;
> > +virQEMUDriverConfigPtr cfg = virQEMUDriverGetConfig(driver);
> > +char *devstr = NULL;
> > +char *objalias = NULL;
> > +const char *backendType;
> > +virJSONValuePtr props = NULL;
> > +int id;
> > +int ret = -1;
> > +
> > +if (virAsprintf(&mem->info.alias, "dimm%zu", vm->def->nmems) < 0)
> > +goto cleanup;
> > +
> > +if (virAsprintf(&objalias, "mem%s", mem->info.alias) < 0)
> > +goto cleanup;
> > +
> > +if (!(devstr = qemuBuildMemoryDeviceStr(mem, priv->qemuCaps)))
> > +goto cleanup;
> > +
> > +qemuDomainMemoryDeviceAlignSize(mem);
> > +
> > +if (qemuBuildMemoryBackendStr(mem->size, mem->pagesize,
> > +  mem->targetNode, mem->sourceNodes, NULL,
> > +  vm->def, priv->qemuCaps, cfg,
> > +  &backendType, &props, true) < 0)
> 
> Coverity determines that qemuBuildMemoryBackendStr can return props here
> with a -1 return and thus leak props
> 
> That's because qemuBuildMemoryBackendStr sets the returned *backendProps
> and sets the local props to NULL before the (!hugepages) code which if
> it fails won't cause 'props' to be free'd properly
> 
> Adding the virJSONValueFree(props); makes Coverity happy again.

I'll fix qemuBuildMemoryBackendStr separately rather than adding a
pseudo-hack that would violate the style we are using for functions that
return via argument.

Peter


signature.asc
Description: Digital signature
--
libvir-list mailing list
libvir-list@redhat.com
https://www.redhat.com/mailman/listinfo/libvir-list

Re: [libvirt] [PATCHv3 11/12] qemu: Implement memory device hotplug

2015-03-19 Thread John Ferlan


On 03/17/2015 10:20 AM, Peter Krempa wrote:
> Add code to hot-add memory devices to running qemu instances.
> ---
> 
> Notes:
> Version 3:
> - added comment to clarify that @mem is always consumed by 
> qemuDomainAttachMemory
> Version 2:
> - no change
> 
> Version 2:
> - no change
> 
>  src/qemu/qemu_command.c |  4 +--
>  src/qemu/qemu_command.h | 15 
>  src/qemu/qemu_driver.c  |  5 ++-
>  src/qemu/qemu_hotplug.c | 95 
> +
>  src/qemu/qemu_hotplug.h |  3 ++
>  5 files changed, 119 insertions(+), 3 deletions(-)
> 
> diff --git a/src/qemu/qemu_command.c b/src/qemu/qemu_command.c
> index 2d85567..1f72437 100644
> --- a/src/qemu/qemu_command.c
> +++ b/src/qemu/qemu_command.c
> @@ -4599,7 +4599,7 @@ qemuBuildControllerDevStr(virDomainDefPtr domainDef,
>   * other configuration was used (to detect legacy configurations). Returns
>   * -1 in case of an error.
>   */
> -static int
> +int
>  qemuBuildMemoryBackendStr(unsigned long long size,
>unsigned long long pagesize,
>int guestNode,
> @@ -4872,7 +4872,7 @@ qemuBuildMemoryDimmBackendStr(virDomainMemoryDefPtr mem,
>  }
> 
> 
> -static char *
> +char *
>  qemuBuildMemoryDeviceStr(virDomainMemoryDefPtr mem,
>   virQEMUCapsPtr qemuCaps)
>  {
> diff --git a/src/qemu/qemu_command.h b/src/qemu/qemu_command.h
> index ee81f92..a29db41 100644
> --- a/src/qemu/qemu_command.h
> +++ b/src/qemu/qemu_command.h
> @@ -162,6 +162,21 @@ char *qemuBuildSoundDevStr(virDomainDefPtr domainDef,
> virDomainSoundDefPtr sound,
> virQEMUCapsPtr qemuCaps);
> 
> +int qemuBuildMemoryBackendStr(unsigned long long size,
> +  unsigned long long pagesize,
> +  int guestNode,
> +  virBitmapPtr userNodeset,
> +  virBitmapPtr autoNodeset,
> +  virDomainDefPtr def,
> +  virQEMUCapsPtr qemuCaps,
> +  virQEMUDriverConfigPtr cfg,
> +  const char **backendType,
> +  virJSONValuePtr *backendProps,
> +  bool force);
> +
> +char *qemuBuildMemoryDeviceStr(virDomainMemoryDefPtr mem,
> +   virQEMUCapsPtr qemuCaps);
> +
>  /* Legacy, pre device support */
>  char *qemuBuildPCIHostdevPCIDevStr(virDomainHostdevDefPtr dev,
> virQEMUCapsPtr qemuCaps);
> diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c
> index e948cca..cbdf279 100644
> --- a/src/qemu/qemu_driver.c
> +++ b/src/qemu/qemu_driver.c
> @@ -7649,8 +7649,11 @@ qemuDomainAttachDeviceLive(virDomainObjPtr vm,
>  dev->data.rng = NULL;
>  break;
> 
> -/*TODO: implement later */
>  case VIR_DOMAIN_DEVICE_MEMORY:
> +ret = qemuDomainAttachMemory(driver, vm,
> + dev->data.memory);
> +dev->data.memory = NULL;
> +break;

FWIW: Although there is a note in the AttachMemory code about
consumption it may be worth noting here too just so no one in the future
"sees" it missing and adds it thinking it's necessary

> 
>  case VIR_DOMAIN_DEVICE_NONE:
>  case VIR_DOMAIN_DEVICE_FS:
> diff --git a/src/qemu/qemu_hotplug.c b/src/qemu/qemu_hotplug.c
> index 5c5ad0e..88c5e3c 100644
> --- a/src/qemu/qemu_hotplug.c
> +++ b/src/qemu/qemu_hotplug.c
> @@ -1672,6 +1672,101 @@ qemuDomainAttachRNGDevice(virQEMUDriverPtr driver,
>  }
> 
> 
> +/**
> + * qemuDomainAttachMemory:
> + * @driver: qemu driver data
> + * @vm: VM object
> + * @mem: Definition of the memory device to be attached. @mem is always 
> consumed
> + *
> + * Attaches memory device described by @mem to domain @vm.
> + *
> + * Returns 0 on success -1 on error.
> + */
> +int
> +qemuDomainAttachMemory(virQEMUDriverPtr driver,
> +   virDomainObjPtr vm,
> +   virDomainMemoryDefPtr mem)
> +{
> +qemuDomainObjPrivatePtr priv = vm->privateData;
> +virQEMUDriverConfigPtr cfg = virQEMUDriverGetConfig(driver);
> +char *devstr = NULL;
> +char *objalias = NULL;
> +const char *backendType;
> +virJSONValuePtr props = NULL;
> +int id;
> +int ret = -1;
> +
> +if (virAsprintf(&mem->info.alias, "dimm%zu", vm->def->nmems) < 0)
> +goto cleanup;
> +
> +if (virAsprintf(&objalias, "mem%s", mem->info.alias) < 0)
> +goto cleanup;
> +
> +if (!(devstr = qemuBuildMemoryDeviceStr(mem, priv->qemuCaps)))
> +goto cleanup;
> +
> +qemuDomainMemoryDeviceAlignSize(mem);
> +
> +if (qemuBuildMemoryBackendStr(mem->size, mem->pagesize,
> +  mem->targetNode, mem->sourceNodes, NULL,
> +  vm->def, priv->qemuCaps, cfg,
> +   

[libvirt] [PATCHv3 11/12] qemu: Implement memory device hotplug

2015-03-17 Thread Peter Krempa
Add code to hot-add memory devices to running qemu instances.
---

Notes:
Version 3:
- added comment to clarify that @mem is always consumed by 
qemuDomainAttachMemory
Version 2:
- no change

Version 2:
- no change

 src/qemu/qemu_command.c |  4 +--
 src/qemu/qemu_command.h | 15 
 src/qemu/qemu_driver.c  |  5 ++-
 src/qemu/qemu_hotplug.c | 95 +
 src/qemu/qemu_hotplug.h |  3 ++
 5 files changed, 119 insertions(+), 3 deletions(-)

diff --git a/src/qemu/qemu_command.c b/src/qemu/qemu_command.c
index 2d85567..1f72437 100644
--- a/src/qemu/qemu_command.c
+++ b/src/qemu/qemu_command.c
@@ -4599,7 +4599,7 @@ qemuBuildControllerDevStr(virDomainDefPtr domainDef,
  * other configuration was used (to detect legacy configurations). Returns
  * -1 in case of an error.
  */
-static int
+int
 qemuBuildMemoryBackendStr(unsigned long long size,
   unsigned long long pagesize,
   int guestNode,
@@ -4872,7 +4872,7 @@ qemuBuildMemoryDimmBackendStr(virDomainMemoryDefPtr mem,
 }


-static char *
+char *
 qemuBuildMemoryDeviceStr(virDomainMemoryDefPtr mem,
  virQEMUCapsPtr qemuCaps)
 {
diff --git a/src/qemu/qemu_command.h b/src/qemu/qemu_command.h
index ee81f92..a29db41 100644
--- a/src/qemu/qemu_command.h
+++ b/src/qemu/qemu_command.h
@@ -162,6 +162,21 @@ char *qemuBuildSoundDevStr(virDomainDefPtr domainDef,
virDomainSoundDefPtr sound,
virQEMUCapsPtr qemuCaps);

+int qemuBuildMemoryBackendStr(unsigned long long size,
+  unsigned long long pagesize,
+  int guestNode,
+  virBitmapPtr userNodeset,
+  virBitmapPtr autoNodeset,
+  virDomainDefPtr def,
+  virQEMUCapsPtr qemuCaps,
+  virQEMUDriverConfigPtr cfg,
+  const char **backendType,
+  virJSONValuePtr *backendProps,
+  bool force);
+
+char *qemuBuildMemoryDeviceStr(virDomainMemoryDefPtr mem,
+   virQEMUCapsPtr qemuCaps);
+
 /* Legacy, pre device support */
 char *qemuBuildPCIHostdevPCIDevStr(virDomainHostdevDefPtr dev,
virQEMUCapsPtr qemuCaps);
diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c
index e948cca..cbdf279 100644
--- a/src/qemu/qemu_driver.c
+++ b/src/qemu/qemu_driver.c
@@ -7649,8 +7649,11 @@ qemuDomainAttachDeviceLive(virDomainObjPtr vm,
 dev->data.rng = NULL;
 break;

-/*TODO: implement later */
 case VIR_DOMAIN_DEVICE_MEMORY:
+ret = qemuDomainAttachMemory(driver, vm,
+ dev->data.memory);
+dev->data.memory = NULL;
+break;

 case VIR_DOMAIN_DEVICE_NONE:
 case VIR_DOMAIN_DEVICE_FS:
diff --git a/src/qemu/qemu_hotplug.c b/src/qemu/qemu_hotplug.c
index 5c5ad0e..88c5e3c 100644
--- a/src/qemu/qemu_hotplug.c
+++ b/src/qemu/qemu_hotplug.c
@@ -1672,6 +1672,101 @@ qemuDomainAttachRNGDevice(virQEMUDriverPtr driver,
 }


+/**
+ * qemuDomainAttachMemory:
+ * @driver: qemu driver data
+ * @vm: VM object
+ * @mem: Definition of the memory device to be attached. @mem is always 
consumed
+ *
+ * Attaches memory device described by @mem to domain @vm.
+ *
+ * Returns 0 on success -1 on error.
+ */
+int
+qemuDomainAttachMemory(virQEMUDriverPtr driver,
+   virDomainObjPtr vm,
+   virDomainMemoryDefPtr mem)
+{
+qemuDomainObjPrivatePtr priv = vm->privateData;
+virQEMUDriverConfigPtr cfg = virQEMUDriverGetConfig(driver);
+char *devstr = NULL;
+char *objalias = NULL;
+const char *backendType;
+virJSONValuePtr props = NULL;
+int id;
+int ret = -1;
+
+if (virAsprintf(&mem->info.alias, "dimm%zu", vm->def->nmems) < 0)
+goto cleanup;
+
+if (virAsprintf(&objalias, "mem%s", mem->info.alias) < 0)
+goto cleanup;
+
+if (!(devstr = qemuBuildMemoryDeviceStr(mem, priv->qemuCaps)))
+goto cleanup;
+
+qemuDomainMemoryDeviceAlignSize(mem);
+
+if (qemuBuildMemoryBackendStr(mem->size, mem->pagesize,
+  mem->targetNode, mem->sourceNodes, NULL,
+  vm->def, priv->qemuCaps, cfg,
+  &backendType, &props, true) < 0)
+goto cleanup;
+
+if (virDomainMemoryInsert(vm->def, mem) < 0) {
+virJSONValueFree(props);
+goto cleanup;
+}
+
+qemuDomainObjEnterMonitor(driver, vm);
+if (qemuMonitorAddObject(priv->mon, backendType, objalias, props) < 0)
+goto removedef;
+
+if (qemuMonitorAddDevice(priv->mon, devstr) < 0) {
+virErrorPtr err = virSaveLastError();
+ignore_value(qemuMonitorDelObject(priv->mon, obj