[libvirt PATCH] qemuProcessUpdateGuestCPU: Check cpu if check=full is set

2021-02-24 Thread Tim Wiederhake
libvirt performs cpu checking if "check" is set to "partial", but skips
checking the cpu if "check" is set to "full".

See https://bugzilla.redhat.com/show_bug.cgi?id=1840770

Signed-off-by: Tim Wiederhake 
---
 src/qemu/qemu_process.c | 8 
 1 file changed, 8 insertions(+)

diff --git a/src/qemu/qemu_process.c b/src/qemu/qemu_process.c
index bfa742577f..5b8c1397ef 100644
--- a/src/qemu/qemu_process.c
+++ b/src/qemu/qemu_process.c
@@ -6149,6 +6149,14 @@ qemuProcessUpdateGuestCPU(virDomainDefPtr def,
 if (virCPUConvertLegacy(hostarch, def->cpu) < 0)
 return -1;
 
+if (def->cpu->check == VIR_CPU_CHECK_FULL) {
+virCPUDefPtr host = virQEMUCapsGetHostModel(qemuCaps, def->virtType,
+
VIR_QEMU_CAPS_HOST_CPU_FULL);
+
+if (virCPUCompare(hostarch, host, def->cpu, true) < 0)
+return -1;
+}
+
 /* nothing to update for host-passthrough / maximum */
 if (def->cpu->mode != VIR_CPU_MODE_HOST_PASSTHROUGH &&
 def->cpu->mode != VIR_CPU_MODE_MAXIMUM) {
-- 
2.26.2



Re: [PATCH v2] qemu: Add missing lock in qemuProcessHandleMonitorEOF

2021-02-24 Thread Michal Privoznik

On 2/25/21 2:39 AM, Peng Liang wrote:

On 2/24/2021 9:59 PM, Michal Privoznik wrote:

On 2/24/21 12:28 PM, Peng Liang wrote:

qemuMonitorUnregister will be called in multiple threads (e.g. threads
in rpc worker pool and the vm event thread).  In some cases, it isn't
protected by the monitor lock, which may lead to call g_source_unref
more than one time and a use-after-free problem eventually.

Add the missing lock in qemuProcessHandleMonitorEOF (which is the only
position missing lock of monitor I found).

Suggested-by: Michal Privoznik 
Signed-off-by: Peng Liang 
---
This patch is v2 of
https://listman.redhat.com/archives/libvir-list/2021-February/msg00945.html.


v1 -> v2:
Locking monitor in qemuProcessHandleMonitorEOF instead of using aotmic
function in qemuMonitorUnregister.

   src/qemu/qemu_monitor.h | 1 +
   src/qemu/qemu_process.c | 2 ++
   2 files changed, 3 insertions(+)

diff --git a/src/qemu/qemu_monitor.h b/src/qemu/qemu_monitor.h
index d25c26343a7f..14e6b1fe9626 100644
--- a/src/qemu/qemu_monitor.h
+++ b/src/qemu/qemu_monitor.h
@@ -427,6 +427,7 @@ bool qemuMonitorWasDisposed(void);
     void qemuMonitorRegister(qemuMonitorPtr mon)
   ATTRIBUTE_NONNULL(1);
+/* Must be called with monitor locked. */
   void qemuMonitorUnregister(qemuMonitorPtr mon)


 From this it's not very clear which function the comment belongs to. We
tend to put comments into .c because that's where tags usually take you
first. So you get the memo first.


Hi Michal,

So, do I need to send another patch to document it in
src/qemu/qemu_monitor.c?


No need I just did:

https://listman.redhat.com/archives/libvir-list/2021-February/msg01202.html

I'll merge it later today.

Michal



Re: [PATCH 04/14] softmmu: remove '-usbdevice' command line option

2021-02-24 Thread Thomas Huth

On 24/02/2021 15.10, Daniel P. Berrangé wrote:

On Wed, Feb 24, 2021 at 02:58:19PM +0100, Thomas Huth wrote:

On 24/02/2021 14.11, Daniel P. Berrangé wrote:

This was replaced by the '-device usb-DEV' option.

Signed-off-by: Daniel P. Berrangé 
---
   docs/system/deprecated.rst   |  9 ---
   docs/system/removed-features.rst |  9 +++
   softmmu/vl.c | 42 
   3 files changed, 9 insertions(+), 51 deletions(-)


Last time I tried to remove -usbdevice, there was some concerns that
-usbdevice braille might still be useful for some people, see the thread
that started here:

  https://lists.nongnu.org/archive/html/qemu-devel/2018-01/msg00651.html

(and Gerd's summary here:
https://lists.nongnu.org/archive/html/qemu-devel/2018-01/msg01520.html )


Urgh, so the current deprecation docs are a bit misleading by saying
-usbdevice is directly mapped to -device.


So we might need a new "sugared" option like "-braille" instead before we
can fully remove -usbdevice? ... or we just keep -usbdevice as a bittersweet
remainder?


I'm not going to implement new CLI options, and if that's needed, we
ought to re-start the clock on the deprecation at that point. So this
points towards just removing the deprecation warning that exists
today. Or alternatively drop support for -usbdevice, except for the
braille type.


After that discussion in 2018, I've removed all of the "annoying" -usbdevice 
parameters already (see commit 99761176eeaf8525). I then more or less waited 
for someone to step up and implement "-braille", but it never happened and I 
forgot about the removal of the remaining -usbdevice parameters. Thinking 
about this again, replacing "-usbdevice braille" with a "-braille usb" does 
indeed not buy us much, so I think the best is maybe to keep the simple 
devices and braille around, update our documentation and remove the 
deprecation warning instead.


 Thomas



Re: [PATCH 33/33] util: virerror: Remove virReportOOMError

2021-02-24 Thread Laine Stump

On 2/24/21 11:17 AM, Peter Krempa wrote:

Trying to report an OOM error is pointless since our infrastructure to
report error needs to allocate memory to report the error.

In addition our code mistakenly reported OOM errors even in cases where
a function could fail for another reason, which would make issues harder
to debug.

Remove the virReportOOMError and backend so that programmers are forced
to think about what can happen. In case when there's another failure
possible a specific error should be reported and otherwise a direct
abort() is better since the logger would abort on g_new anyways.

This patch also removes the syntas-check which forces use of
virReportOOMError instead of using VIR_ERR_NO_MEMORY with other
functions. This allows possible future use when we'd end up in a
situation where trying to recover from an OOM would make sense, such as
when attempting to allocate a massive buffer.

Signed-off-by: Peter Krempa 



and good riddance!

Reviewed-by: Laine Stump 


---
  build-aux/syntax-check.mk |  8 
  src/libvirt_private.syms  |  1 -
  src/util/virerror.c   | 22 --
  src/util/virerror.h   |  8 
  4 files changed, 39 deletions(-)

diff --git a/build-aux/syntax-check.mk b/build-aux/syntax-check.mk
index e51877648a..e1ccb74986 100644
--- a/build-aux/syntax-check.mk
+++ b/build-aux/syntax-check.mk
@@ -490,11 +490,6 @@ sc_prohibit_gettext_noop:
halt='use N_, not gettext_noop' \
  $(_sc_search_regexp)

-sc_prohibit_VIR_ERR_NO_MEMORY:
-   @prohibit='\' \
-   halt='use virReportOOMError, not VIR_ERR_NO_MEMORY' \
- $(_sc_search_regexp)
-
  sc_prohibit_PATH_MAX:
@prohibit='\' \
halt='dynamically allocate paths, do not use PATH_MAX' \
@@ -1895,9 +1890,6 @@ exclude_file_name_regexp--sc_libvirt_unmarked_diagnostics 
= \

  exclude_file_name_regexp--sc_po_check = 
^(docs/|src/rpc/gendispatch\.pl$$|tests/commandtest.c$$)

-exclude_file_name_regexp--sc_prohibit_VIR_ERR_NO_MEMORY = \
-  
^(build-aux/syntax-check\.mk|include/libvirt/virterror\.h|src/remote/remote_daemon_dispatch\.c|src/util/virerror\.c|docs/internals/oomtesting\.html\.in)$$
-
  exclude_file_name_regexp--sc_prohibit_PATH_MAX = \
^build-aux/syntax-check\.mk$$

diff --git a/src/libvirt_private.syms b/src/libvirt_private.syms
index 48f66daab8..7eb37ed797 100644
--- a/src/libvirt_private.syms
+++ b/src/libvirt_private.syms
@@ -2116,7 +2116,6 @@ virLastErrorPrefixMessage;
  virRaiseErrorFull;
  virRaiseErrorObject;
  virReportErrorHelper;
-virReportOOMErrorFull;
  virReportSystemErrorFull;
  virSetError;
  virSetErrorLogPriorityFunc;
diff --git a/src/util/virerror.c b/src/util/virerror.c
index 708081414a..a503cdefdc 100644
--- a/src/util/virerror.c
+++ b/src/util/virerror.c
@@ -1358,28 +1358,6 @@ void virReportSystemErrorFull(int domcode,
  errno = save_errno;
  }

-/**
- * virReportOOMErrorFull:
- * @domcode: the virErrorDomain indicating where it's coming from
- * @filename: filename where error was raised
- * @funcname: function name where error was raised
- * @linenr: line number where error was raised
- *
- * Convenience internal routine called when an out of memory error is
- * detected
- */
-void virReportOOMErrorFull(int domcode,
-   const char *filename,
-   const char *funcname,
-   size_t linenr)
-{
-const char *virerr;
-
-virerr = virErrorMsg(VIR_ERR_NO_MEMORY, NULL);
-virRaiseErrorFull(filename, funcname, linenr,
-  domcode, VIR_ERR_NO_MEMORY, VIR_ERR_ERROR,
-  virerr, NULL, NULL, -1, -1, virerr, NULL);
-}

  /**
   * virSetErrorLogPriorityFunc:
diff --git a/src/util/virerror.h b/src/util/virerror.h
index 9d3e40d65a..da7d7c0afe 100644
--- a/src/util/virerror.h
+++ b/src/util/virerror.h
@@ -174,14 +174,6 @@ void virReportSystemErrorFull(int domcode,
   "Unexpected enum value %d for %s", \
   value, sizeof((typname)1) != 0 ? #typname : 
#typname);

-void virReportOOMErrorFull(int domcode,
-   const char *filename,
-   const char *funcname,
-   size_t linenr);
-
-#define virReportOOMError() \
-virReportOOMErrorFull(VIR_FROM_THIS, __FILE__, __FUNCTION__, __LINE__)
-
  #define virReportError(code, ...) \
  virReportErrorHelper(VIR_FROM_THIS, code, __FILE__, \
   __FUNCTION__, __LINE__, __VA_ARGS__)





Re: [PATCH 32/33] virVMXConvertToUTF8: Report non-OOM error on failure of xmlBufferCreateStatic

2021-02-24 Thread Laine Stump

On 2/24/21 11:17 AM, Peter Krempa wrote:

The function has also non-OOM failure case when the passed string has 0
length, so reporting OOM error is not correct.

Signed-off-by: Peter Krempa 
---
  src/vmx/vmx.c | 8 ++--
  1 file changed, 2 insertions(+), 6 deletions(-)

diff --git a/src/vmx/vmx.c b/src/vmx/vmx.c
index e6c0900a65..73bf7c4f3d 100644
--- a/src/vmx/vmx.c
+++ b/src/vmx/vmx.c
@@ -781,12 +781,8 @@ virVMXConvertToUTF8(const char *encoding, const char 
*string)
  return NULL;
  }

-if (!(input = xmlBufferCreateStatic((char *)string, strlen(string {
-virReportOOMError();
-goto cleanup;
-}
-
-if (xmlCharEncInFunc(handler, utf8, input) < 0) {
+if (!(input = xmlBufferCreateStatic((char *)string, strlen(string))) ||
+xmlCharEncInFunc(handler, utf8, input) < 0) {


I would have left the error messages for the two functions separate, 
with adequate wording to tell which of them failed. But this is at worst 
still better than reporting OOM...




  virReportError(VIR_ERR_INTERNAL_ERROR,
 _("Could not convert from %s to UTF-8 encoding"), 
encoding);
  goto cleanup;





Re: [PATCH 20/33] Don't report OOM error on xmlCopyNode failure

2021-02-24 Thread Laine Stump

On 2/24/21 11:16 AM, Peter Krempa wrote:

Out of memory isn't the only reason the function can fail. Add a message
stating that copying of a XML node failed.


Could it still fail due to OOM as well, though? And if so, is there any 
way of differentiating? (I previously looked into this for some other 
libxml2 function, ended up asking DV, and I believe I was told that 
there isn't any way to tell the difference, but as usual IMBES (I May Be 
Experiencing Senility).


At any rate, your changed message is more correct, since it's not making 
any unsubstantiated assumption about the cause of the error, while 
virRemoveOOMError() was).





Signed-off-by: Peter Krempa 
---
  src/conf/domain_conf.c | 3 ++-
  src/test/test_driver.c | 6 --
  2 files changed, 6 insertions(+), 3 deletions(-)

diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c
index c0881608af..f1fd5320a5 100644
--- a/src/conf/domain_conf.c
+++ b/src/conf/domain_conf.c
@@ -30460,7 +30460,8 @@ virDomainDefSetMetadata(virDomainDefPtr def,
  def->metadata = virXMLNewNode(NULL, "metadata");

  if (!(new = xmlCopyNode(doc->children, 1))) {
-virReportOOMError();
+virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
+   _("Failed to copy XML node"));
  return -1;
  }
  }
diff --git a/src/test/test_driver.c b/src/test/test_driver.c
index bca1297d1d..71ab04aa1a 100644
--- a/src/test/test_driver.c
+++ b/src/test/test_driver.c
@@ -224,7 +224,8 @@ testDomainDefNamespaceParse(xmlXPathContextPtr ctxt,
  for (i = 0; i < n; i++) {
  xmlNodePtr newnode = xmlCopyNode(nodes[i], 1);
  if (!newnode) {
-virReportOOMError();
+virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
+   _("Failed to copy XML node"));
  goto error;
  }

@@ -787,7 +788,8 @@ testParseXMLDocFromFile(xmlNodePtr node, const char *file, 
const char *type)

  ret = xmlCopyNode(xmlDocGetRootElement(doc), 1);
  if (!ret) {
-virReportOOMError();
+virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
+   _("Failed to copy XML node"));
  goto error;
  }
  xmlReplaceNode(node, ret);





Re: [PATCH v2] qemu: Add missing lock in qemuProcessHandleMonitorEOF

2021-02-24 Thread Peng Liang
On 2/24/2021 9:59 PM, Michal Privoznik wrote:
> On 2/24/21 12:28 PM, Peng Liang wrote:
>> qemuMonitorUnregister will be called in multiple threads (e.g. threads
>> in rpc worker pool and the vm event thread).  In some cases, it isn't
>> protected by the monitor lock, which may lead to call g_source_unref
>> more than one time and a use-after-free problem eventually.
>>
>> Add the missing lock in qemuProcessHandleMonitorEOF (which is the only
>> position missing lock of monitor I found).
>>
>> Suggested-by: Michal Privoznik 
>> Signed-off-by: Peng Liang 
>> ---
>> This patch is v2 of
>> https://listman.redhat.com/archives/libvir-list/2021-February/msg00945.html.
>>
>>
>> v1 -> v2:
>> Locking monitor in qemuProcessHandleMonitorEOF instead of using aotmic
>> function in qemuMonitorUnregister.
>>
>>   src/qemu/qemu_monitor.h | 1 +
>>   src/qemu/qemu_process.c | 2 ++
>>   2 files changed, 3 insertions(+)
>>
>> diff --git a/src/qemu/qemu_monitor.h b/src/qemu/qemu_monitor.h
>> index d25c26343a7f..14e6b1fe9626 100644
>> --- a/src/qemu/qemu_monitor.h
>> +++ b/src/qemu/qemu_monitor.h
>> @@ -427,6 +427,7 @@ bool qemuMonitorWasDisposed(void);
>>     void qemuMonitorRegister(qemuMonitorPtr mon)
>>   ATTRIBUTE_NONNULL(1);
>> +/* Must be called with monitor locked. */
>>   void qemuMonitorUnregister(qemuMonitorPtr mon)
> 
> From this it's not very clear which function the comment belongs to. We
> tend to put comments into .c because that's where tags usually take you
> first. So you get the memo first.

Hi Michal,

So, do I need to send another patch to document it in
src/qemu/qemu_monitor.c?

Thanks,
Peng

> 
>>   ATTRIBUTE_NONNULL(1);
>>   void qemuMonitorClose(qemuMonitorPtr mon);
>> diff --git a/src/qemu/qemu_process.c b/src/qemu/qemu_process.c
>> index d930ff9a74f6..bfa742577f32 100644
>> --- a/src/qemu/qemu_process.c
>> +++ b/src/qemu/qemu_process.c
>> @@ -318,7 +318,9 @@ qemuProcessHandleMonitorEOF(qemuMonitorPtr mon,
>>   /* We don't want this EOF handler to be called over and over
>> while the
>>    * thread is waiting for a job.
>>    */
>> +    virObjectLock(mon);
>>   qemuMonitorUnregister(mon);
>> +    virObjectUnlock(mon);
>>     /* We don't want any cleanup from EOF handler (or any other
>>    * thread) to enter qemu namespace. */
>>
> 
> ACK to this hunk. And I'll be pushing it in a few moments.
> 
> Michal
> 
> .




Re: [PATCH 00/33] Remove the now misleading virReportOOMError infra

2021-02-24 Thread Laine Stump

On 2/24/21 11:16 AM, Peter Krempa wrote:

'virReportOOMError' is nowadays mostly useless since an OOM error will
trigger yet another allocation failure in the logger when attempting to
log the error.

Additionally it was also used in few places which can fail with other
failures than OOM.

To prevent both errorneous usage types, let's remove it completely.


Yay!! It bugs me every time I see it.



Re: [PATCH 3/3] Remove redundant variables/labels

2021-02-24 Thread Laine Stump

On 2/23/21 12:24 PM, Kristina Hanicova wrote:

In files: src/lxc/lxc_native: in lxcAddNetworkRouteDefinition(),
src/conf/networkcommon_conf: in virNetDevIPRouteCreate() and
virNetDevIPRouteParseXML()

Signed-off-by: Kristina Hanicova 


Reviewed-by: Laine Stump 



Re: [PATCH 2/3] Use g_autoptr instead of virNetDevIPRouteFree if possible

2021-02-24 Thread Laine Stump

On 2/23/21 12:24 PM, Kristina Hanicova wrote:

In files: src/conf/domain_conf: in virDomainNetIPInfoParseXML(),
src/lxc/lxc_native: in lxcAddNetworkRouteDefinition(),
src/vz/vz_sdk: in prlsdkGetRoutes(), src/conf/networkcommon_conf:
in virNetDevIPRouteCreate()

Signed-off-by: Kristina Hanicova 
---
  src/conf/domain_conf.c| 3 +--
  src/conf/networkcommon_conf.c | 5 ++---
  src/lxc/lxc_native.c  | 3 +--
  src/vz/vz_sdk.c   | 3 +--
  4 files changed, 5 insertions(+), 9 deletions(-)

diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c
index b731744f04..2504911931 100644
--- a/src/conf/domain_conf.c
+++ b/src/conf/domain_conf.c
@@ -7481,7 +7481,7 @@ virDomainNetIPInfoParseXML(const char *source,
 xmlXPathContextPtr ctxt,
 virNetDevIPInfoPtr def)


Not your problem, but I noticed that this function previously had the 
local "nodes" converted to g_autofree, apparently before the rule about 
"don't VIR_FREE an g_auto pointer" (because the change was made by the 
person who later called me on not following the rule :-))


Anyway, it wouldn't fit the theme to fix that in this patch, so it can 
be cleaned up later.



  {
-virNetDevIPRoutePtr route = NULL;
+g_autoptr(virNetDevIPRoute) route = NULL;
  int nnodes;
  int ret = -1;
  size_t i;
@@ -7511,7 +7511,6 @@ virDomainNetIPInfoParseXML(const char *source,
   cleanup:
  if (ret < 0)
  virNetDevIPInfoClear(def);
-virNetDevIPRouteFree(route);
  return ret;
  }
  
diff --git a/src/conf/networkcommon_conf.c b/src/conf/networkcommon_conf.c

index e82dbc3d3d..9e7ad59337 100644
--- a/src/conf/networkcommon_conf.c
+++ b/src/conf/networkcommon_conf.c
@@ -41,7 +41,7 @@ virNetDevIPRouteCreate(const char *errorDetail,
 unsigned int metric,
 bool hasMetric)
  {
-virNetDevIPRoutePtr def = NULL;
+g_autoptr(virNetDevIPRoute) def = NULL;
  virSocketAddr testAddr;
  
  def = g_new0(virNetDevIPRoute, 1);

@@ -209,10 +209,9 @@ virNetDevIPRouteCreate(const char *errorDetail,
  goto error;
  }
  
-return def;

+return g_steal_pointer();
  
   error:

-virNetDevIPRouteFree(def);
  return NULL;
  }
  
diff --git a/src/lxc/lxc_native.c b/src/lxc/lxc_native.c

index b903dc91d6..d5020dafa7 100644
--- a/src/lxc/lxc_native.c
+++ b/src/lxc/lxc_native.c
@@ -441,7 +441,7 @@ lxcAddNetworkRouteDefinition(const char *address,
   virNetDevIPRoutePtr **routes,
   size_t *nroutes)
  {
-virNetDevIPRoutePtr route = NULL;
+g_autoptr(virNetDevIPRoute) route = NULL;
  g_autofree char *familyStr = NULL;
  g_autofree char *zero = NULL;
  
@@ -460,7 +460,6 @@ lxcAddNetworkRouteDefinition(const char *address,

  return 0;
  
   error:

-virNetDevIPRouteFree(route);
  return -1;
  }
  
diff --git a/src/vz/vz_sdk.c b/src/vz/vz_sdk.c

index f49cd983f0..6f712c7a31 100644
--- a/src/vz/vz_sdk.c
+++ b/src/vz/vz_sdk.c
@@ -974,7 +974,7 @@ prlsdkGetRoutes(PRL_HANDLE sdknet, virDomainNetDefPtr net)
  int ret = -1;
  char *gw = NULL;
  char *gw6 = NULL;
-virNetDevIPRoutePtr route = NULL;
+g_autoptr(virNetDevIPRoute) route = NULL;


Interesting. So this function uses route multiple times (once for IPv4 
and once for IPv6), but it's clearing out the first usage by stealing 
the pointer into and array of routes rather than freeing it. I guess 
that's okay, though.




Anyway:

Reviewed-by: Laine Stump 

I'll put this in a branch of things to push after the freeze is over.


  
  if (!(gw = prlsdkGetStringParamVar(PrlVmDevNet_GetDefaultGateway, sdknet)))

  goto cleanup;
@@ -1006,7 +1006,6 @@ prlsdkGetRoutes(PRL_HANDLE sdknet, virDomainNetDefPtr net)
  ret = 0;
  
   cleanup:

-virNetDevIPRouteFree(route);
  VIR_FREE(gw);
  VIR_FREE(gw6);
  





Re: [PATCH 1/3] networkcommon_conf: Use g_autofree where possible

2021-02-24 Thread Laine Stump

On 2/23/21 12:24 PM, Kristina Hanicova wrote:

Signed-off-by: Kristina Hanicova 
---
  src/conf/networkcommon_conf.c | 14 +-
  1 file changed, 5 insertions(+), 9 deletions(-)

diff --git a/src/conf/networkcommon_conf.c b/src/conf/networkcommon_conf.c
index 26eeb6dbda..e82dbc3d3d 100644
--- a/src/conf/networkcommon_conf.c
+++ b/src/conf/networkcommon_conf.c
@@ -228,9 +228,10 @@ virNetDevIPRouteParseXML(const char *errorDetail,
  
  virNetDevIPRoutePtr def = NULL;

  VIR_XPATH_NODE_AUTORESTORE(ctxt)
-char *family = NULL;
-char *address = NULL, *netmask = NULL;
-char *gateway = NULL;
+g_autofree char *family = NULL;
+g_autofree char *address = NULL;
+g_autofree char *netmask = NULL;
+g_autofree char *gateway = NULL;
  unsigned long prefix = 0, metric = 0;
  int prefixRc, metricRc;
  bool hasPrefix = false;
@@ -276,10 +277,6 @@ virNetDevIPRouteParseXML(const char *errorDetail,
   hasMetric);
  
   cleanup:

-VIR_FREE(family);
-VIR_FREE(address);
-VIR_FREE(netmask);
-VIR_FREE(gateway);
  return def;
  }
  
@@ -287,7 +284,7 @@ int

  virNetDevIPRouteFormat(virBufferPtr buf,
 const virNetDevIPRoute *def)
  {
-char *addr = NULL;
+g_autofree char *addr = NULL;
  
  virBufferAddLit(buf, "  
@@ -311,7 +308,6 @@ virNetDevIPRouteFormat(virBufferPtr buf,

  if (!(addr = virSocketAddrFormat(>gateway)))
  return -1;
  virBufferAsprintf(buf, " gateway='%s'", addr);
-VIR_FREE(addr);


This one is a bit more complicated, because "addr" is re-used after 
being freed (twice - first used for address, then for netmask, and 
finally for gateway), and we've made the rule that an auto-freed pointer 
should never be VIR_FREED


So instead of just making the existing pointer g_autofree and 
eliminating its final free, we need to create separate pointers for each 
use:


g_autofree char *address = NULL;
g_autofree char *netmask = NULL;
g_autofree char *gataeway = NULL;

and then use each in the appropriate place.

(if we're lucky, the compiler/optimizer will even be smart enough to 
figure out that the three things are never used at the same time (? 
depending on when the call to the autofree function is injected), and 
internally merge them into a single variable.)


  
  if (def->has_metric && def->metric > 0)

  virBufferAsprintf(buf, " metric='%u'", def->metric);





Re: [libvirt PATCH v4 00/25] Add support for persistent mediated devices

2021-02-24 Thread Jonathon Jongsma
On Mon, 22 Feb 2021 11:08:12 +0100
Erik Skultety  wrote:

> On Wed, Feb 03, 2021 at 11:38:44AM -0600, Jonathon Jongsma wrote:
> > This patch series follows the previously-merged series which added
> > support for transient mediated devices. This series expands mdev
> > support to include persistent device definitions. Again, it relies
> > on mdevctl as the backend.
> > 
> > It follows the common libvirt pattern of APIs by adding the
> > following new APIs for node devices:
> > - virNodeDeviceDefineXML() - defines a persistent device
> > - virNodeDeviceUndefine() - undefines a persistent device
> > - virNodeDeviceCreate() - starts a previously-defined device  
> 
> So, I tested the patches on Friday and have a few notes:
> - all of the driver implementations mentioned ^above need to pass an
> error buffer to the respective mdevctl wrapper, because the generic
> error "Unable to XZY mediated device" doesn't help at all. Kind of
> like with QEMU errors, we need to extract it from an error buffer
> (you already have input and output, so just add another one) --> this
> relates to patches 14,18,21
> 
> - trying to undefine an active mdev reports an error in libvirt
> --> this is both inconsistent with the rest of libvirt's
> subsystems and there's also no reason for it since mdevctl supports it
> --> we need to support transient devices as well  
> 
> - trying to define the following XML hangs for 5s and then fails:
> 
>   pci__06_00_0
>   
> vfio_mdev
>   
>   
> 
> d41787d2-2e0e-4021-8ed2-b6f1ef305a9f
>   
> 

I assume that you have a parent device that supports creating an mdev
of this type? In other words, this was expected to succeed, right?

> 
> -> I debugged this on Friday evening and for some reason
> driver->devs hash table of devices was NULL going through the
> nodeDeviceFindNewMediatedDevice call, but I haven't managed to figure
> out why it was NULL, listing devices worked just fine

So, I often get a 5s delay when trying to define a new mdev. But it
always succeeds after the delay. 

The reason for the delay is that the device is generally not in our
device list the first time we call nodeDeviceFindNewMediatedDevice().
It's usually not in our device list because the device is only added
to the driver's device list after we get a notification from mdevctl
(via monitoring the mdevctl config directory) and then we re-query
mdevctl for the list of defined devices. Because mdevctl is not
blazingly fast[1], and because we do the querying in a separate thread,
the new device has usually not been discovered when we first call
nodeDeviceFindNewMediatedDevice(). So we sleep for 5s before trying
again.

For udev devices, this 5s delay is usually not hit because
nodeDeviceFindNewDevice() first calls 'udevadm settle' before
checking the device list. This waits just long enough to ensure that
pending udev events are handled. Unfortunately we don't have a similar
"wait just long enough" command for mdevctl, so we almost always hit
the 5s retry timeout. 

There are a couple of potential ways to avoid hitting this 5s timeout:
1. directly add a placeholder device to the driver's device list
immediately after calling 'mdevctl define' so that it is guaranteed to
be in the device list when we call nodeDeviceFindNewMediatedDevice().
We can then update that device definition with additional info
when mdevctl is eventually queried.
2. don't wait 5s every time a device is not found. Instead, start with
a small sleep timeout and increase it gradually until we hit the max
timeout. In other words, instead of check; sleep(5); check; sleep(5);
check; sleep(5); we could instead do something like: check; sleep(1);
check; sleep(2); check; sleep(4); check; sleep(8)...


[1]$ time mdevctl list --defined
49bf2346-6747-4ad6-be5a-adc2f0a10b5c :00:02.0 i915-GVTg_V5_8 manual
4fcd3666-e58a-4c63-969c-bd616a158c0d :00:02.0 i915-GVTg_V5_8 manual
5c152919-3a34-4338-b7c9-532f73fa5440 :00:02.0 i915-GVTg_V5_4 manual

real0m0.782s
user0m0.735s
sys 0m0.056s



> 
> - I also prepared several adjustments to how we define the mdevctl
> wrappers + some test adjustments which I wanted to share with you,
> but I haven't tested those thoroughly since I was debugging why that
> XML couldn't be defined, I'll share it when we eliminate the
> underlying problem -> if you're wondering why I didn't just put it
> into the review, well, I figured sharing the code was more
> descriptive than if I used words

Would you like me to wait for this before sending a new series?

Thanks,
Jonathon



[libvirt PATCH] qemu_domainjob: Make copy of owner API

2021-02-24 Thread Jiri Denemark
Using the job owner API name directly works fine as long as it is a
static string or the owner's thread is still running. However, this is
not always the case. For example, when the owner API name is filled in a
job when we're reconnecting to existing domains after daemon restart,
the dynamically allocated owner name will disappear with the
reconnecting thread. Any follow up usage of the pointer will read random
memory.

Signed-off-by: Jiri Denemark 
---
 src/qemu/qemu_domainjob.c | 12 ++--
 src/qemu/qemu_process.c   |  2 +-
 2 files changed, 7 insertions(+), 7 deletions(-)

diff --git a/src/qemu/qemu_domainjob.c b/src/qemu/qemu_domainjob.c
index 3c2c6b9179..b58d6837ad 100644
--- a/src/qemu/qemu_domainjob.c
+++ b/src/qemu/qemu_domainjob.c
@@ -190,7 +190,7 @@ qemuDomainObjResetJob(qemuDomainJobObjPtr job)
 {
 job->active = QEMU_JOB_NONE;
 job->owner = 0;
-job->ownerAPI = NULL;
+g_clear_pointer(>ownerAPI, g_free);
 job->started = 0;
 }
 
@@ -200,7 +200,7 @@ qemuDomainObjResetAgentJob(qemuDomainJobObjPtr job)
 {
 job->agentActive = QEMU_AGENT_JOB_NONE;
 job->agentOwner = 0;
-job->agentOwnerAPI = NULL;
+g_clear_pointer(>agentOwnerAPI, g_free);
 job->agentStarted = 0;
 }
 
@@ -210,7 +210,7 @@ qemuDomainObjResetAsyncJob(qemuDomainJobObjPtr job)
 {
 job->asyncJob = QEMU_ASYNC_JOB_NONE;
 job->asyncOwner = 0;
-job->asyncOwnerAPI = NULL;
+g_clear_pointer(>asyncOwnerAPI, g_free);
 job->asyncStarted = 0;
 job->phase = 0;
 job->mask = QEMU_JOB_DEFAULT_MASK;
@@ -890,7 +890,7 @@ qemuDomainObjBeginJobInternal(virQEMUDriverPtr driver,
   obj, obj->def->name);
 priv->job.active = job;
 priv->job.owner = virThreadSelfID();
-priv->job.ownerAPI = virThreadJobGet();
+priv->job.ownerAPI = g_strdup(virThreadJobGet());
 priv->job.started = now;
 } else {
 VIR_DEBUG("Started async job: %s (vm=%p name=%s)",
@@ -901,7 +901,7 @@ qemuDomainObjBeginJobInternal(virQEMUDriverPtr driver,
 priv->job.current->status = QEMU_DOMAIN_JOB_STATUS_ACTIVE;
 priv->job.asyncJob = asyncJob;
 priv->job.asyncOwner = virThreadSelfID();
-priv->job.asyncOwnerAPI = virThreadJobGet();
+priv->job.asyncOwnerAPI = g_strdup(virThreadJobGet());
 priv->job.asyncStarted = now;
 priv->job.current->started = now;
 }
@@ -917,7 +917,7 @@ qemuDomainObjBeginJobInternal(virQEMUDriverPtr driver,
   qemuDomainAsyncJobTypeToString(priv->job.asyncJob));
 priv->job.agentActive = agentJob;
 priv->job.agentOwner = virThreadSelfID();
-priv->job.agentOwnerAPI = virThreadJobGet();
+priv->job.agentOwnerAPI = g_strdup(virThreadJobGet());
 priv->job.agentStarted = now;
 }
 
diff --git a/src/qemu/qemu_process.c b/src/qemu/qemu_process.c
index bfa742577f..398f63282e 100644
--- a/src/qemu/qemu_process.c
+++ b/src/qemu/qemu_process.c
@@ -3732,7 +3732,7 @@ qemuProcessRecoverJob(virQEMUDriverPtr driver,
 /* Restore the config of the async job which is not persisted */
 priv->jobs_queued++;
 priv->job.asyncJob = QEMU_ASYNC_JOB_BACKUP;
-priv->job.asyncOwnerAPI = virThreadJobGet();
+priv->job.asyncOwnerAPI = g_strdup(virThreadJobGet());
 priv->job.asyncStarted = now;
 
 qemuDomainObjSetAsyncJobMask(vm, (QEMU_JOB_DEFAULT_MASK |
-- 
2.30.0



Re: [PATCH] qemu_monitor: Document qemuMonitorUnregister()

2021-02-24 Thread Andrea Bolognani
On Wed, 2021-02-24 at 15:04 +0100, Michal Privoznik wrote:
> The most important bit is that the caller is expected to pass
> locked monitor.
> 
> Signed-off-by: Michal Privoznik 
> ---
>  src/qemu/qemu_monitor.c | 7 +++
>  1 file changed, 7 insertions(+)

Reviewed-by: Andrea Bolognani 

-- 
Andrea Bolognani / Red Hat / Virtualization



Re: [PATCH v2 16/31] qapi/qom: Add ObjectOptions for confidential-guest-support

2021-02-24 Thread Kevin Wolf
Am 24.02.2021 um 16:21 hat Dr. David Alan Gilbert geschrieben:
> * Kevin Wolf (kw...@redhat.com) wrote:
> > This adds a QAPI schema for the properties of the objects implementing
> > the confidential-guest-support interface.
> > 
> > pef-guest and s390x-pv-guest don't have any properties, so they only
> > need to be added to the ObjectType enum without adding a new branch to
> > ObjectOptions.
> > 
> > Signed-off-by: Kevin Wolf 
> > ---
> >  qapi/qom.json | 37 +
> >  1 file changed, 37 insertions(+)
> > 
> > diff --git a/qapi/qom.json b/qapi/qom.json
> > index e7184122e9..d5f68b5c89 100644
> > --- a/qapi/qom.json
> > +++ b/qapi/qom.json
> > @@ -633,6 +633,38 @@
> >'base': 'RngProperties',
> >'data': { '*filename': 'str' } }
> >  
> > +##
> > +# @SevGuestProperties:
> > +#
> > +# Properties for sev-guest objects.
> > +#
> > +# @sev-device: SEV device to use (default: "/dev/sev")
> > +#
> > +# @dh-cert-file: guest owners DH certificate (encoded with base64)
> > +#
> > +# @session-file: guest owners session parameters (encoded with base64)
> > +#
> > +# @policy: SEV policy value (default: 0x1)
> > +#
> > +# @handle: SEV firmware handle (default: 0)
> > +#
> > +# @cbitpos: C-bit location in page table entry (default: 0)
> > +#
> > +# @reduced-phys-bits: number of bits in physical addresses that become
> > +# unavailable when SEV is enabled
> > +#
> > +# Since: 2.12
> > +##
> > +{ 'struct': 'SevGuestProperties',
> > +  'data': { '*sev-device': 'str',
> > +'*dh-cert-file': 'str',
> > +'*session-file': 'str',
> > +'*policy': 'uint32',
> > +'*handle': 'uint32',
> > +'*cbitpos': 'uint32',
> > +'reduced-phys-bits': 'uint32' },
> > +  'if': 'defined(CONFIG_SEV)' }
> > +
> >  ##
> >  # @ObjectType:
> >  #
> > @@ -661,12 +693,15 @@
> >  'memory-backend-file',
> >  'memory-backend-memfd',
> >  'memory-backend-ram',
> > +{'name': 'pef-guest', 'if': 'defined(CONFIG_PSERIES)' },
> >  'pr-manager-helper',
> >  'rng-builtin',
> >  'rng-egd',
> >  'rng-random',
> >  'secret',
> >  'secret_keyring',
> > +{'name': 'sev-guest', 'if': 'defined(CONFIG_SEV)' },
> > +'s390-pv-guest',
> 
> If pef-guest is conditional on PSERIES< shouldn't this be dependent on
> s390?

The difference is that s390-pv-guest is compiled unconditionally if the
s390x target is built, whereas CONFIG_PSERIES is a separate thing from
building a ppc target.

I actually tried making it conditional on TARGET_S390X at first, but the
code generated from this schema is supposed to be target independent, so
it rightly failed to build because TARGET_* are marked as poisoned in
most of the codebase.

Kevin



[PATCH 13/33] virfirewall: Don't check OOM in ADD_ARG macro

2021-02-24 Thread Peter Krempa
VIR_RESIZE_N can't fail nowadays, adjust the macro.

Signed-off-by: Peter Krempa 
---
 src/util/virfirewall.c | 20 +++-
 1 file changed, 3 insertions(+), 17 deletions(-)

diff --git a/src/util/virfirewall.c b/src/util/virfirewall.c
index 6b04a8011f..95962568f5 100644
--- a/src/util/virfirewall.c
+++ b/src/util/virfirewall.c
@@ -262,10 +262,9 @@ void virFirewallFree(virFirewallPtr firewall)

 #define ADD_ARG(rule, str) \
 do { \
-if (VIR_RESIZE_N(rule->args, \
- rule->argsAlloc, \
- rule->argsLen, 1) < 0) \
-goto no_memory; \
+ignore_value(VIR_RESIZE_N(rule->args, \
+  rule->argsAlloc, \
+  rule->argsLen, 1)); \
  \
 rule->args[rule->argsLen++] = g_strdup(str); \
 } while (0)
@@ -433,9 +432,6 @@ void virFirewallRuleAddArg(virFirewallPtr firewall,
 ADD_ARG(rule, arg);

 return;
-
- no_memory:
-firewall->err = ENOMEM;
 }


@@ -455,9 +451,6 @@ void virFirewallRuleAddArgFormat(virFirewallPtr firewall,
 ADD_ARG(rule, arg);

 return;
-
- no_memory:
-firewall->err = ENOMEM;
 }


@@ -473,9 +466,6 @@ void virFirewallRuleAddArgSet(virFirewallPtr firewall,
 }

 return;
-
- no_memory:
-firewall->err = ENOMEM;
 }


@@ -496,10 +486,6 @@ void virFirewallRuleAddArgList(virFirewallPtr firewall,
 va_end(list);

 return;
-
- no_memory:
-firewall->err = ENOMEM;
-va_end(list);
 }


-- 
2.29.2



[PATCH 15/33] virfirewall: virFirewallAddRuleFullV: Remove OOM check from VIR_APPEND_ELEMENT

2021-02-24 Thread Peter Krempa
VIR_APPEND_ELEMENT_COPY will abort the program on OOM so there's no need
to check.

Signed-off-by: Peter Krempa 
---
 src/util/virfirewall.c | 19 ++-
 1 file changed, 6 insertions(+), 13 deletions(-)

diff --git a/src/util/virfirewall.c b/src/util/virfirewall.c
index 66b33d4a91..bbeb87e72d 100644
--- a/src/util/virfirewall.c
+++ b/src/util/virfirewall.c
@@ -315,24 +315,17 @@ virFirewallAddRuleFullV(virFirewallPtr firewall,
 ADD_ARG(rule, str);

 if (group->addingRollback) {
-if (VIR_APPEND_ELEMENT_COPY(group->rollback,
-group->nrollback,
-rule) < 0)
-goto no_memory;
+ignore_value(VIR_APPEND_ELEMENT_COPY(group->rollback,
+ group->nrollback,
+ rule));
 } else {
-if (VIR_APPEND_ELEMENT_COPY(group->action,
-group->naction,
-rule) < 0)
-goto no_memory;
+ignore_value(VIR_APPEND_ELEMENT_COPY(group->action,
+ group->naction,
+ rule));
 }


 return rule;
-
- no_memory:
-firewall->err = ENOMEM;
-virFirewallRuleFree(rule);
-return NULL;
 }


-- 
2.29.2



[PATCH 18/33] util: xml: Add virXMLBufferCreate wrapper

2021-02-24 Thread Peter Krempa
'xmlBufferCreate' returns NULL only on allocation failure. Add a wrapper
which will call 'abort()' in such case in a centralised spot. It doesn't
make much sense to continue execution from here.

Signed-off-by: Peter Krempa 
---
 src/conf/domain_conf.c   |  5 +
 src/conf/network_conf.c  |  5 +
 src/libvirt_private.syms |  1 +
 src/util/virxml.c| 19 +--
 src/util/virxml.h|  3 +++
 src/vmx/vmx.c|  5 ++---
 6 files changed, 21 insertions(+), 17 deletions(-)

diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c
index 46620d38ed..7a3374b5be 100644
--- a/src/conf/domain_conf.c
+++ b/src/conf/domain_conf.c
@@ -28692,10 +28692,7 @@ virDomainDefFormatInternalSetRootName(virDomainDefPtr 
def,
  * Thankfully, libxml maps what looks like globals into
  * thread-local uses, so we are thread-safe.  */
 xmlIndentTreeOutput = 1;
-if (!(xmlbuf = xmlBufferCreate())) {
-virReportOOMError();
-return -1;
-}
+xmlbuf = virXMLBufferCreate();

 if (xmlNodeDump(xmlbuf, def->metadata->doc, def->metadata,
 virBufferGetIndent(buf) / 2, 1) < 0) {
diff --git a/src/conf/network_conf.c b/src/conf/network_conf.c
index f32710b781..69d99a60e0 100644
--- a/src/conf/network_conf.c
+++ b/src/conf/network_conf.c
@@ -2513,10 +2513,7 @@ virNetworkDefFormatBuf(virBufferPtr buf,
  * Thankfully, libxml maps what looks like globals into
  * thread-local uses, so we are thread-safe.  */
 xmlIndentTreeOutput = 1;
-if (!(xmlbuf = xmlBufferCreate())) {
-virReportOOMError();
-return -1;
-}
+xmlbuf = virXMLBufferCreate();

 if (xmlNodeDump(xmlbuf, def->metadata->doc, def->metadata,
 virBufferGetIndent(buf) / 2, 1) < 0) {
diff --git a/src/libvirt_private.syms b/src/libvirt_private.syms
index 6b7261b987..dd54550b60 100644
--- a/src/libvirt_private.syms
+++ b/src/libvirt_private.syms
@@ -3529,6 +3529,7 @@ virVsockSetGuestCid;

 # util/virxml.h
 virParseScaledValue;
+virXMLBufferCreate;
 virXMLCheckIllegalChars;
 virXMLExtractNamespaceXML;
 virXMLFormatElement;
diff --git a/src/util/virxml.c b/src/util/virxml.c
index 0354251941..3fed2b2a6e 100644
--- a/src/util/virxml.c
+++ b/src/util/virxml.c
@@ -941,12 +941,7 @@ char *
 virXMLNodeToString(xmlDocPtr doc,
xmlNodePtr node)
 {
-g_autoptr(xmlBuffer) xmlbuf = NULL;
-
-if (!(xmlbuf = xmlBufferCreate())) {
-virReportOOMError();
-return NULL;
-}
+g_autoptr(xmlBuffer) xmlbuf = virXMLBufferCreate();

 if (xmlNodeDump(xmlbuf, doc, node, 0, 1) == 0) {
 virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
@@ -1467,3 +1462,15 @@ virParseScaledValue(const char *xpath,
 *val = bytes;
 return 1;
 }
+
+
+xmlBufferPtr
+virXMLBufferCreate(void)
+{
+xmlBufferPtr ret;
+
+if (!(ret = xmlBufferCreate()))
+abort();
+
+return ret;
+}
diff --git a/src/util/virxml.h b/src/util/virxml.h
index e696dd25f5..24a2234506 100644
--- a/src/util/virxml.h
+++ b/src/util/virxml.h
@@ -286,3 +286,6 @@ int virParseScaledValue(const char *xpath,
 unsigned long long scale,
 unsigned long long max,
 bool required);
+
+xmlBufferPtr
+virXMLBufferCreate(void);
diff --git a/src/vmx/vmx.c b/src/vmx/vmx.c
index db535ba260..e6c0900a65 100644
--- a/src/vmx/vmx.c
+++ b/src/vmx/vmx.c
@@ -771,7 +771,7 @@ virVMXConvertToUTF8(const char *encoding, const char 
*string)
 char *result = NULL;
 xmlCharEncodingHandlerPtr handler;
 g_autoptr(xmlBuffer) input = NULL;
-g_autoptr(xmlBuffer) utf8 = NULL;
+g_autoptr(xmlBuffer) utf8 = virXMLBufferCreate();

 handler = xmlFindCharEncodingHandler(encoding);

@@ -781,8 +781,7 @@ virVMXConvertToUTF8(const char *encoding, const char 
*string)
 return NULL;
 }

-if (!(input = xmlBufferCreateStatic((char *)string, strlen(string))) ||
-!(utf8 = xmlBufferCreate())) {
+if (!(input = xmlBufferCreateStatic((char *)string, strlen(string {
 virReportOOMError();
 goto cleanup;
 }
-- 
2.29.2



[PATCH 14/33] virfirewall: Remove OOM checks from virFirewallStartTransaction

2021-02-24 Thread Peter Krempa
Neither virFirewallGroupNew nor VIR_EXPAND_N can fail.

Signed-off-by: Peter Krempa 
---
 src/util/virfirewall.c | 13 +++--
 1 file changed, 3 insertions(+), 10 deletions(-)

diff --git a/src/util/virfirewall.c b/src/util/virfirewall.c
index 95962568f5..66b33d4a91 100644
--- a/src/util/virfirewall.c
+++ b/src/util/virfirewall.c
@@ -517,18 +517,11 @@ void virFirewallStartTransaction(virFirewallPtr firewall,

 VIR_FIREWALL_RETURN_IF_ERROR(firewall);

-if (!(group = virFirewallGroupNew())) {
-firewall->err = ENOMEM;
-return;
-}
+group = virFirewallGroupNew();
 group->actionFlags = flags;

-if (VIR_EXPAND_N(firewall->groups,
- firewall->ngroups, 1) < 0) {
-firewall->err = ENOMEM;
-virFirewallGroupFree(group);
-return;
-}
+ignore_value(VIR_EXPAND_N(firewall->groups,
+  firewall->ngroups, 1));
 firewall->groups[firewall->ngroups - 1] = group;
 firewall->currentGroup = firewall->ngroups - 1;
 }
-- 
2.29.2



[PATCH 25/33] util: iohelper: Don't handle OOM from posix_memalign

2021-02-24 Thread Peter Krempa
Similarly to other allocation calls abort() on failure.

Signed-off-by: Peter Krempa 
---
 src/util/iohelper.c | 7 +++
 1 file changed, 3 insertions(+), 4 deletions(-)

diff --git a/src/util/iohelper.c b/src/util/iohelper.c
index 49d939d290..b8810d16d3 100644
--- a/src/util/iohelper.c
+++ b/src/util/iohelper.c
@@ -27,6 +27,7 @@

 #include 
 #include 
+#include 

 #include "virthread.h"
 #include "virfile.h"
@@ -57,10 +58,8 @@ runIO(const char *path, int fd, int oflags)
 off_t end = 0;

 #if WITH_POSIX_MEMALIGN
-if (posix_memalign(, alignMask + 1, buflen)) {
-virReportOOMError();
-goto cleanup;
-}
+if (posix_memalign(, alignMask + 1, buflen))
+abort();
 buf = base;
 #else
 buf = g_new0(char, buflen + alignMask);
-- 
2.29.2



[PATCH 28/33] libxl: abort() on failure of libxl_cpu_bitmap_alloc()

2021-02-24 Thread Peter Krempa
Attempting to report error in case when we ran out of memory is
pointless.

Signed-off-by: Peter Krempa 
---
 src/libxl/libxl_conf.c   | 6 ++
 src/libxl/libxl_driver.c | 7 +++
 2 files changed, 5 insertions(+), 8 deletions(-)

diff --git a/src/libxl/libxl_conf.c b/src/libxl/libxl_conf.c
index f8db118996..f2bcd77a29 100644
--- a/src/libxl/libxl_conf.c
+++ b/src/libxl/libxl_conf.c
@@ -854,10 +854,8 @@ libxlMakeVnumaList(virDomainDefPtr def,
 goto cleanup;

 libxl_bitmap_init(_bitmap);
-if (libxl_cpu_bitmap_alloc(ctx, _bitmap, b_info->max_vcpus)) {
-virReportOOMError();
-goto cleanup;
-}
+if (libxl_cpu_bitmap_alloc(ctx, _bitmap, b_info->max_vcpus))
+abort();

 do {
 libxl_bitmap_set(_bitmap, cpu);
diff --git a/src/libxl/libxl_driver.c b/src/libxl/libxl_driver.c
index 75a8d46af0..434959d694 100644
--- a/src/libxl/libxl_driver.c
+++ b/src/libxl/libxl_driver.c
@@ -4931,10 +4931,9 @@ libxlDomainGetNumaParameters(virDomainPtr dom,
 if (numnodes <= 0)
 goto cleanup;

-if (libxl_node_bitmap_alloc(cfg->ctx, , 0)) {
-virReportOOMError();
-goto cleanup;
-}
+if (libxl_node_bitmap_alloc(cfg->ctx, , 0))
+abort();
+
 nodes = virBitmapNew(numnodes);

 rc = libxl_domain_get_nodeaffinity(cfg->ctx,
-- 
2.29.2



[PATCH 12/33] virCloseCallbacksGetForConn: Remove OOM handling

2021-02-24 Thread Peter Krempa
VIR_EXPAND_N will abort so we can simplify the hash iterator.

Signed-off-by: Peter Krempa 
---
 src/hypervisor/virclosecallbacks.c | 15 +--
 1 file changed, 1 insertion(+), 14 deletions(-)

diff --git a/src/hypervisor/virclosecallbacks.c 
b/src/hypervisor/virclosecallbacks.c
index 2641f45a22..1fd4dd7adf 100644
--- a/src/hypervisor/virclosecallbacks.c
+++ b/src/hypervisor/virclosecallbacks.c
@@ -241,7 +241,6 @@ struct _virCloseCallbacksList {
 struct virCloseCallbacksData {
 virConnectPtr conn;
 virCloseCallbacksListPtr list;
-bool oom;
 };

 static int
@@ -263,11 +262,7 @@ virCloseCallbacksGetOne(void *payload,
 if (data->conn != closeDef->conn || !closeDef->cb)
 return 0;

-if (VIR_EXPAND_N(data->list->entries,
- data->list->nentries, 1) < 0) {
-data->oom = true;
-return 0;
-}
+ignore_value(VIR_EXPAND_N(data->list->entries, data->list->nentries, 1));

 memcpy(data->list->entries[data->list->nentries - 1].uuid,
uuid, VIR_UUID_BUFLEN);
@@ -286,17 +281,9 @@ virCloseCallbacksGetForConn(virCloseCallbacksPtr 
closeCallbacks,

 data.conn = conn;
 data.list = list;
-data.oom = false;

 virHashForEach(closeCallbacks->list, virCloseCallbacksGetOne, );

-if (data.oom) {
-VIR_FREE(list->entries);
-VIR_FREE(list);
-virReportOOMError();
-return NULL;
-}
-
 return list;
 }

-- 
2.29.2



[PATCH 22/33] virXMLParseHelper: abort() on allocation failure

2021-02-24 Thread Peter Krempa
Signed-off-by: Peter Krempa 
---
 src/util/virxml.c | 6 ++
 1 file changed, 2 insertions(+), 4 deletions(-)

diff --git a/src/util/virxml.c b/src/util/virxml.c
index 62bbafacd6..060b7530fc 100644
--- a/src/util/virxml.c
+++ b/src/util/virxml.c
@@ -789,10 +789,8 @@ virXMLParseHelper(int domcode,

 /* Set up a parser context so we can catch the details of XML errors. */
 pctxt = xmlNewParserCtxt();
-if (!pctxt || !pctxt->sax) {
-virReportOOMError();
-goto error;
-}
+if (!pctxt || !pctxt->sax)
+abort();

 private.domcode = domcode;
 pctxt->_private = 
-- 
2.29.2



[PATCH 21/33] virXMLXPathContextNew: abort() on allocation failure

2021-02-24 Thread Peter Krempa
Signed-off-by: Peter Krempa 
---
 src/util/virxml.c | 6 ++
 1 file changed, 2 insertions(+), 4 deletions(-)

diff --git a/src/util/virxml.c b/src/util/virxml.c
index ebe479f5d3..62bbafacd6 100644
--- a/src/util/virxml.c
+++ b/src/util/virxml.c
@@ -51,10 +51,8 @@ virXMLXPathContextNew(xmlDocPtr xml)
 {
 xmlXPathContextPtr ctxt;

-if (!(ctxt = xmlXPathNewContext(xml))) {
-virReportOOMError();
-return NULL;
-}
+if (!(ctxt = xmlXPathNewContext(xml)))
+abort();

 return ctxt;
 }
-- 
2.29.2



[PATCH 26/33] hyperv: abort() failure of wsmc_fault_new()

2021-02-24 Thread Peter Krempa
The function just allocates a helper object. Reporting errors would be
pointless when we encounter OOM situation.

Signed-off-by: Peter Krempa 
---
 src/hyperv/hyperv_wmi.c | 8 ++--
 1 file changed, 2 insertions(+), 6 deletions(-)

diff --git a/src/hyperv/hyperv_wmi.c b/src/hyperv/hyperv_wmi.c
index 8bb6f591f1..2a898cdf03 100644
--- a/src/hyperv/hyperv_wmi.c
+++ b/src/hyperv/hyperv_wmi.c
@@ -92,12 +92,8 @@ hypervVerifyResponse(WsManClient *client, WsXmlDocH response,
 }

 if (wsmc_check_for_fault(response)) {
-fault = wsmc_fault_new();
-
-if (fault == NULL) {
-virReportOOMError();
-return -1;
-}
+if (!(fault = wsmc_fault_new()))
+abort();

 wsmc_get_fault_data(response, fault);

-- 
2.29.2



[PATCH 31/33] storage: Don't report OOM error on failure of glfs_new

2021-02-24 Thread Peter Krempa
OOM isn't the only failure glfs_new can encounter. Report an error which
might give more insight. libgfapi seems to be setting errno but
reporting a system error migt be misleading.

Signed-off-by: Peter Krempa 
---
 src/storage/storage_backend_gluster.c   | 3 ++-
 src/storage_file/storage_file_backend_gluster.c | 3 ++-
 2 files changed, 4 insertions(+), 2 deletions(-)

diff --git a/src/storage/storage_backend_gluster.c 
b/src/storage/storage_backend_gluster.c
index 8de0cb8a6b..e673922df6 100644
--- a/src/storage/storage_backend_gluster.c
+++ b/src/storage/storage_backend_gluster.c
@@ -114,7 +114,8 @@ virStorageBackendGlusterOpen(virStoragePoolObjPtr pool)

 /* Actually connect to glfs */
 if (!(ret->vol = glfs_new(ret->volname))) {
-virReportOOMError();
+virReportError(VIR_ERR_OPERATION_FAILED,
+   _("failed to create glfs object for '%s'"), 
ret->volname);
 goto error;
 }

diff --git a/src/storage_file/storage_file_backend_gluster.c 
b/src/storage_file/storage_file_backend_gluster.c
index 9b3b783274..8c7a583886 100644
--- a/src/storage_file/storage_file_backend_gluster.c
+++ b/src/storage_file/storage_file_backend_gluster.c
@@ -120,7 +120,8 @@ virStorageFileBackendGlusterInit(virStorageSourcePtr src)
   (unsigned int)drv->uid, (unsigned int)drv->gid);

 if (!(priv->vol = glfs_new(src->volume))) {
-virReportOOMError();
+virReportError(VIR_ERR_OPERATION_FAILED,
+   _("failed to create glfs object for '%s'"), 
src->volume);
 goto error;
 }

-- 
2.29.2



[PATCH 32/33] virVMXConvertToUTF8: Report non-OOM error on failure of xmlBufferCreateStatic

2021-02-24 Thread Peter Krempa
The function has also non-OOM failure case when the passed string has 0
length, so reporting OOM error is not correct.

Signed-off-by: Peter Krempa 
---
 src/vmx/vmx.c | 8 ++--
 1 file changed, 2 insertions(+), 6 deletions(-)

diff --git a/src/vmx/vmx.c b/src/vmx/vmx.c
index e6c0900a65..73bf7c4f3d 100644
--- a/src/vmx/vmx.c
+++ b/src/vmx/vmx.c
@@ -781,12 +781,8 @@ virVMXConvertToUTF8(const char *encoding, const char 
*string)
 return NULL;
 }

-if (!(input = xmlBufferCreateStatic((char *)string, strlen(string {
-virReportOOMError();
-goto cleanup;
-}
-
-if (xmlCharEncInFunc(handler, utf8, input) < 0) {
+if (!(input = xmlBufferCreateStatic((char *)string, strlen(string))) ||
+xmlCharEncInFunc(handler, utf8, input) < 0) {
 virReportError(VIR_ERR_INTERNAL_ERROR,
_("Could not convert from %s to UTF-8 encoding"), 
encoding);
 goto cleanup;
-- 
2.29.2



[PATCH 33/33] util: virerror: Remove virReportOOMError

2021-02-24 Thread Peter Krempa
Trying to report an OOM error is pointless since our infrastructure to
report error needs to allocate memory to report the error.

In addition our code mistakenly reported OOM errors even in cases where
a function could fail for another reason, which would make issues harder
to debug.

Remove the virReportOOMError and backend so that programmers are forced
to think about what can happen. In case when there's another failure
possible a specific error should be reported and otherwise a direct
abort() is better since the logger would abort on g_new anyways.

This patch also removes the syntas-check which forces use of
virReportOOMError instead of using VIR_ERR_NO_MEMORY with other
functions. This allows possible future use when we'd end up in a
situation where trying to recover from an OOM would make sense, such as
when attempting to allocate a massive buffer.

Signed-off-by: Peter Krempa 
---
 build-aux/syntax-check.mk |  8 
 src/libvirt_private.syms  |  1 -
 src/util/virerror.c   | 22 --
 src/util/virerror.h   |  8 
 4 files changed, 39 deletions(-)

diff --git a/build-aux/syntax-check.mk b/build-aux/syntax-check.mk
index e51877648a..e1ccb74986 100644
--- a/build-aux/syntax-check.mk
+++ b/build-aux/syntax-check.mk
@@ -490,11 +490,6 @@ sc_prohibit_gettext_noop:
halt='use N_, not gettext_noop' \
  $(_sc_search_regexp)

-sc_prohibit_VIR_ERR_NO_MEMORY:
-   @prohibit='\' \
-   halt='use virReportOOMError, not VIR_ERR_NO_MEMORY' \
- $(_sc_search_regexp)
-
 sc_prohibit_PATH_MAX:
@prohibit='\' \
halt='dynamically allocate paths, do not use PATH_MAX' \
@@ -1895,9 +1890,6 @@ exclude_file_name_regexp--sc_libvirt_unmarked_diagnostics 
= \

 exclude_file_name_regexp--sc_po_check = 
^(docs/|src/rpc/gendispatch\.pl$$|tests/commandtest.c$$)

-exclude_file_name_regexp--sc_prohibit_VIR_ERR_NO_MEMORY = \
-  
^(build-aux/syntax-check\.mk|include/libvirt/virterror\.h|src/remote/remote_daemon_dispatch\.c|src/util/virerror\.c|docs/internals/oomtesting\.html\.in)$$
-
 exclude_file_name_regexp--sc_prohibit_PATH_MAX = \
^build-aux/syntax-check\.mk$$

diff --git a/src/libvirt_private.syms b/src/libvirt_private.syms
index 48f66daab8..7eb37ed797 100644
--- a/src/libvirt_private.syms
+++ b/src/libvirt_private.syms
@@ -2116,7 +2116,6 @@ virLastErrorPrefixMessage;
 virRaiseErrorFull;
 virRaiseErrorObject;
 virReportErrorHelper;
-virReportOOMErrorFull;
 virReportSystemErrorFull;
 virSetError;
 virSetErrorLogPriorityFunc;
diff --git a/src/util/virerror.c b/src/util/virerror.c
index 708081414a..a503cdefdc 100644
--- a/src/util/virerror.c
+++ b/src/util/virerror.c
@@ -1358,28 +1358,6 @@ void virReportSystemErrorFull(int domcode,
 errno = save_errno;
 }

-/**
- * virReportOOMErrorFull:
- * @domcode: the virErrorDomain indicating where it's coming from
- * @filename: filename where error was raised
- * @funcname: function name where error was raised
- * @linenr: line number where error was raised
- *
- * Convenience internal routine called when an out of memory error is
- * detected
- */
-void virReportOOMErrorFull(int domcode,
-   const char *filename,
-   const char *funcname,
-   size_t linenr)
-{
-const char *virerr;
-
-virerr = virErrorMsg(VIR_ERR_NO_MEMORY, NULL);
-virRaiseErrorFull(filename, funcname, linenr,
-  domcode, VIR_ERR_NO_MEMORY, VIR_ERR_ERROR,
-  virerr, NULL, NULL, -1, -1, virerr, NULL);
-}

 /**
  * virSetErrorLogPriorityFunc:
diff --git a/src/util/virerror.h b/src/util/virerror.h
index 9d3e40d65a..da7d7c0afe 100644
--- a/src/util/virerror.h
+++ b/src/util/virerror.h
@@ -174,14 +174,6 @@ void virReportSystemErrorFull(int domcode,
  "Unexpected enum value %d for %s", \
  value, sizeof((typname)1) != 0 ? #typname : #typname);

-void virReportOOMErrorFull(int domcode,
-   const char *filename,
-   const char *funcname,
-   size_t linenr);
-
-#define virReportOOMError() \
-virReportOOMErrorFull(VIR_FROM_THIS, __FILE__, __FUNCTION__, __LINE__)
-
 #define virReportError(code, ...) \
 virReportErrorHelper(VIR_FROM_THIS, code, __FILE__, \
  __FUNCTION__, __LINE__, __VA_ARGS__)
-- 
2.29.2



[PATCH 29/33] virVBoxSnapshotConfSaveVboxFile: abort() on failure to allocate xmlDoc and comment

2021-02-24 Thread Peter Krempa
'xmlNewDoc' and 'xmlNewDocComment' return NULL only on allocation
failure. Attempting to raise an error is pointless.

Signed-off-by: Peter Krempa 
---
 src/vbox/vbox_snapshot_conf.c | 12 
 1 file changed, 4 insertions(+), 8 deletions(-)

diff --git a/src/vbox/vbox_snapshot_conf.c b/src/vbox/vbox_snapshot_conf.c
index 5792d3175e..4f12d2ebfa 100644
--- a/src/vbox/vbox_snapshot_conf.c
+++ b/src/vbox/vbox_snapshot_conf.c
@@ -996,10 +996,8 @@ 
virVBoxSnapshotConfSaveVboxFile(virVBoxSnapshotConfMachinePtr machine,
 goto cleanup;
 }
 xml = xmlNewDoc(BAD_CAST "1.0");
-if (!xml) {
-virReportOOMError();
-goto cleanup;
-}
+if (!xml)
+abort();

 cur = virXMLNewNode(NULL, "VirtualBox");

@@ -1023,10 +1021,8 @@ 
virVBoxSnapshotConfSaveVboxFile(virVBoxSnapshotConfMachinePtr machine,
"OVERWRITTEN AND LOST.\n"
"Changes to this xml configuration should be made 
using Virtualbox\n"
"or other application using the libvirt API");
-if (!cur) {
-virReportOOMError();
-goto cleanup;
-}
+if (!cur)
+abort();

 if (!xmlAddPrevSibling(xmlDocGetRootElement(xml), cur)) {
 virReportError(VIR_ERR_XML_ERROR, "%s",
-- 
2.29.2



[PATCH 30/33] util: json: Report non-OOM error on yajl failure

2021-02-24 Thread Peter Krempa
The yajl library returns a wide range of error codes so reporting OOM on
any failure is wrong. In case the error was really based by memory issue
the error reporting will probably cause an abort anyways. Change the
error message so that we know that it happened in JSON at least.

Signed-off-by: Peter Krempa 
---
 src/util/virjson.c | 6 --
 1 file changed, 4 insertions(+), 2 deletions(-)

diff --git a/src/util/virjson.c b/src/util/virjson.c
index e74b9fca4f..f2a6024db6 100644
--- a/src/util/virjson.c
+++ b/src/util/virjson.c
@@ -1943,12 +1943,14 @@ virJSONValueToBuffer(virJSONValuePtr object,
 yajl_gen_config(g, yajl_gen_validate_utf8, 1);

 if (virJSONValueToStringOne(object, g) < 0) {
-virReportOOMError();
+virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
+   _("failed to convert virJSONValue to yajl data"));
 goto cleanup;
 }

 if (yajl_gen_get_buf(g, , ) != yajl_gen_status_ok) {
-virReportOOMError();
+virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
+  _("failed to format JSON"));
 goto cleanup;
 }

-- 
2.29.2



[PATCH 23/33] util: virprocess: abort() on CPU_ALLOC failure

2021-02-24 Thread Peter Krempa
Signed-off-by: Peter Krempa 
---
 src/util/virprocess.c | 12 
 1 file changed, 4 insertions(+), 8 deletions(-)

diff --git a/src/util/virprocess.c b/src/util/virprocess.c
index 41c5678537..69d64e9466 100644
--- a/src/util/virprocess.c
+++ b/src/util/virprocess.c
@@ -462,10 +462,8 @@ int virProcessSetAffinity(pid_t pid, virBitmapPtr map, 
bool quiet)
 masklen = CPU_ALLOC_SIZE(numcpus);
 mask = CPU_ALLOC(numcpus);

-if (!mask) {
-virReportOOMError();
-return -1;
-}
+if (!mask)
+abort();

 CPU_ZERO_S(masklen, mask);
 for (i = 0; i < virBitmapSize(map); i++) {
@@ -509,10 +507,8 @@ virProcessGetAffinity(pid_t pid)
 masklen = CPU_ALLOC_SIZE(ncpus);
 mask = CPU_ALLOC(ncpus);

-if (!mask) {
-virReportOOMError();
-return NULL;
-}
+if (!mask)
+abort();

 CPU_ZERO_S(masklen, mask);

-- 
2.29.2



[PATCH 20/33] Don't report OOM error on xmlCopyNode failure

2021-02-24 Thread Peter Krempa
Out of memory isn't the only reason the function can fail. Add a message
stating that copying of a XML node failed.

Signed-off-by: Peter Krempa 
---
 src/conf/domain_conf.c | 3 ++-
 src/test/test_driver.c | 6 --
 2 files changed, 6 insertions(+), 3 deletions(-)

diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c
index c0881608af..f1fd5320a5 100644
--- a/src/conf/domain_conf.c
+++ b/src/conf/domain_conf.c
@@ -30460,7 +30460,8 @@ virDomainDefSetMetadata(virDomainDefPtr def,
 def->metadata = virXMLNewNode(NULL, "metadata");

 if (!(new = xmlCopyNode(doc->children, 1))) {
-virReportOOMError();
+virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
+   _("Failed to copy XML node"));
 return -1;
 }
 }
diff --git a/src/test/test_driver.c b/src/test/test_driver.c
index bca1297d1d..71ab04aa1a 100644
--- a/src/test/test_driver.c
+++ b/src/test/test_driver.c
@@ -224,7 +224,8 @@ testDomainDefNamespaceParse(xmlXPathContextPtr ctxt,
 for (i = 0; i < n; i++) {
 xmlNodePtr newnode = xmlCopyNode(nodes[i], 1);
 if (!newnode) {
-virReportOOMError();
+virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
+   _("Failed to copy XML node"));
 goto error;
 }

@@ -787,7 +788,8 @@ testParseXMLDocFromFile(xmlNodePtr node, const char *file, 
const char *type)

 ret = xmlCopyNode(xmlDocGetRootElement(doc), 1);
 if (!ret) {
-virReportOOMError();
+virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
+   _("Failed to copy XML node"));
 goto error;
 }
 xmlReplaceNode(node, ret);
-- 
2.29.2



[PATCH 17/33] util: virnetlink: Add wrapper for 'nlmsg_alloc_simple'

2021-02-24 Thread Peter Krempa
The function is used in many places and fails only on allocation
failures. Since trying to recover from allocation failure of a small
buffer by reporting error doesn't make sense add a wrapper for
'nlmsg_alloc_simple' which will 'abort()' on failure and replace all
allocations of netlink message with the new helper.

Signed-off-by: Peter Krempa 
---
 src/util/virnetdev.c | 18 +++
 src/util/virnetdevbridge.c   | 10 +++--
 src/util/virnetdevip.c   | 15 -
 src/util/virnetdevvportprofile.c |  6 +
 src/util/virnetlink.c| 38 ++--
 src/util/virnetlink.h|  4 
 6 files changed, 32 insertions(+), 59 deletions(-)

diff --git a/src/util/virnetdev.c b/src/util/virnetdev.c
index 2b4c8b6280..d0c76ce26c 100644
--- a/src/util/virnetdev.c
+++ b/src/util/virnetdev.c
@@ -1596,11 +1596,7 @@ virNetDevSetVfConfig(const char *ifname, int vf,
 if (!macaddr && vlanid < 0)
 return -1;

-nl_msg = nlmsg_alloc_simple(RTM_SETLINK, NLM_F_REQUEST);
-if (!nl_msg) {
-virReportOOMError();
-return rc;
-}
+nl_msg = virNetlinkMsgNew(RTM_SETLINK, NLM_F_REQUEST);

 if (nlmsg_append(nl_msg,  , sizeof(ifinfo), NLMSG_ALIGNTO) < 0)
 goto buffer_too_small;
@@ -3132,11 +3128,7 @@ virNetDevGetFamilyId(const char *family_name,
 unsigned int recvbuflen;
 int ret = -1;

-if (!(nl_msg = nlmsg_alloc_simple(GENL_ID_CTRL,
-  NLM_F_REQUEST | NLM_F_ACK))) {
-virReportOOMError();
-goto cleanup;
-}
+nl_msg = virNetlinkMsgNew(GENL_ID_CTRL, NLM_F_REQUEST | NLM_F_ACK);

 if (nlmsg_append(nl_msg, , sizeof(gmsgh), NLMSG_ALIGNTO) < 0)
 goto cleanup;
@@ -3220,11 +3212,7 @@ virNetDevSwitchdevFeature(const char *ifname,
 if ((rv = virNetDevGetFamilyId(DEVLINK_GENL_NAME, _id)) <= 0)
 return rv;

-if (!(nl_msg = nlmsg_alloc_simple(family_id,
-  NLM_F_REQUEST | NLM_F_ACK))) {
-virReportOOMError();
-goto cleanup;
-}
+nl_msg = virNetlinkMsgNew(family_id, NLM_F_REQUEST | NLM_F_ACK);

 if (nlmsg_append(nl_msg, , sizeof(gmsgh), NLMSG_ALIGNTO) < 0)
 goto cleanup;
diff --git a/src/util/virnetdevbridge.c b/src/util/virnetdevbridge.c
index d475e4c43d..7b5ea4fe1d 100644
--- a/src/util/virnetdevbridge.c
+++ b/src/util/virnetdevbridge.c
@@ -1036,13 +1036,9 @@ virNetDevBridgeFDBAddDel(const virMacAddr *mac, const 
char *ifname,
 if (!(ndm.ndm_state & (NUD_PERMANENT | NUD_REACHABLE)))
 ndm.ndm_state |= NUD_PERMANENT;

-nl_msg = nlmsg_alloc_simple(isAdd ? RTM_NEWNEIGH : RTM_DELNEIGH,
-NLM_F_REQUEST |
-(isAdd ? (NLM_F_CREATE | NLM_F_EXCL) : 0));
-if (!nl_msg) {
-virReportOOMError();
-return -1;
-}
+nl_msg = virNetlinkMsgNew(isAdd ? RTM_NEWNEIGH : RTM_DELNEIGH,
+  NLM_F_REQUEST |
+  (isAdd ? (NLM_F_CREATE | NLM_F_EXCL) : 0));

 if (nlmsg_append(nl_msg, , sizeof(ndm), NLMSG_ALIGNTO) < 0)
 goto buffer_too_small;
diff --git a/src/util/virnetdevip.c b/src/util/virnetdevip.c
index 4eb8ef76d1..83da7bc46d 100644
--- a/src/util/virnetdevip.c
+++ b/src/util/virnetdevip.c
@@ -107,11 +107,8 @@ virNetDevCreateNetlinkAddressMessage(int messageType,
 if ((ifindex = if_nametoindex(ifname)) == 0)
 return NULL;

-if (!(nlmsg = nlmsg_alloc_simple(messageType,
- NLM_F_REQUEST | NLM_F_CREATE | 
NLM_F_EXCL))) {
-virReportOOMError();
-return NULL;
-}
+nlmsg = virNetlinkMsgNew(messageType,
+ NLM_F_REQUEST | NLM_F_CREATE | NLM_F_EXCL);

 memset(, 0, sizeof(ifa));

@@ -323,12 +320,8 @@ virNetDevIPRouteAdd(const char *ifname,
 if ((ifindex = if_nametoindex(ifname)) == 0)
 return -1;

-if (!(nlmsg = nlmsg_alloc_simple(RTM_NEWROUTE,
- NLM_F_REQUEST | NLM_F_CREATE |
- NLM_F_EXCL))) {
-virReportOOMError();
-return -1;
-}
+nlmsg = virNetlinkMsgNew(RTM_NEWROUTE,
+ NLM_F_REQUEST | NLM_F_CREATE | NLM_F_EXCL);

 memset(, 0, sizeof(rtmsg));

diff --git a/src/util/virnetdevvportprofile.c b/src/util/virnetdevvportprofile.c
index 5d6c055b32..c0fc04c699 100644
--- a/src/util/virnetdevvportprofile.c
+++ b/src/util/virnetdevvportprofile.c
@@ -689,11 +689,7 @@ virNetDevVPortProfileOpSetLink(const char *ifname, int 
ifindex,
   ? virUUIDFormat(hostUUID, hostUUIDStr)
   : "(unspecified)"));

-nl_msg = nlmsg_alloc_simple(RTM_SETLINK, NLM_F_REQUEST);
-if (!nl_msg) {
-virReportOOMError();
-return rc;
-}
+nl_msg = virNetlinkMsgNew(RTM_SETLINK, NLM_F_REQUEST);

 if (nlmsg_append(nl_msg,  , sizeof(ifinfo), NLMSG_ALIGNTO) < 0)

[PATCH 27/33] vbox: abort() on allocation failure in UTF8<->UTF16 conversion

2021-02-24 Thread Peter Krempa
Trying to report an error on OOM is pointless since error handling
allocates memory.

Signed-off-by: Peter Krempa 
---
 src/vbox/vbox_common.c | 20 
 src/vbox/vbox_common.h | 15 +--
 2 files changed, 13 insertions(+), 22 deletions(-)

diff --git a/src/vbox/vbox_common.c b/src/vbox/vbox_common.c
index 138403b034..ce9bfbf827 100644
--- a/src/vbox/vbox_common.c
+++ b/src/vbox/vbox_common.c
@@ -5465,17 +5465,9 @@ vboxDomainSnapshotCreateXML(virDomainPtr dom,
 }

 VBOX_UTF8_TO_UTF16(def->parent.name, );
-if (!name) {
-virReportOOMError();
-goto cleanup;
-}

 if (def->parent.description) {
 VBOX_UTF8_TO_UTF16(def->parent.description, );
-if (!description) {
-virReportOOMError();
-goto cleanup;
-}
 }

 rc = gVBoxAPI.UIConsole.TakeSnapshot(console, name, description, 
);
@@ -6475,10 +6467,6 @@ vboxDomainSnapshotGetParent(virDomainSnapshotPtr 
snapshot,
 goto cleanup;
 }
 VBOX_UTF16_TO_UTF8(nameUtf16, );
-if (!name) {
-virReportOOMError();
-goto cleanup;
-}

 ret = virGetDomainSnapshot(dom, name);

@@ -6533,10 +6521,6 @@ vboxDomainSnapshotCurrent(virDomainPtr dom, unsigned int 
flags)
 }

 VBOX_UTF16_TO_UTF8(nameUtf16, );
-if (!name) {
-virReportOOMError();
-goto cleanup;
-}

 ret = virGetDomainSnapshot(dom, name);

@@ -6593,10 +6577,6 @@ static int 
vboxDomainSnapshotIsCurrent(virDomainSnapshotPtr snapshot,
 }

 VBOX_UTF16_TO_UTF8(nameUtf16, );
-if (!name) {
-virReportOOMError();
-goto cleanup;
-}

 ret = STREQ(snapshot->name, name);

diff --git a/src/vbox/vbox_common.h b/src/vbox/vbox_common.h
index 8b1fb2ac30..1fb922aaf0 100644
--- a/src/vbox/vbox_common.h
+++ b/src/vbox/vbox_common.h
@@ -391,8 +391,19 @@ typedef nsISupports IKeyboard;
 } \
 } while (0)

-#define VBOX_UTF16_TO_UTF8(arg1, arg2)  
gVBoxAPI.UPFN.Utf16ToUtf8(data->pFuncs, arg1, arg2)
-#define VBOX_UTF8_TO_UTF16(arg1, arg2)  
gVBoxAPI.UPFN.Utf8ToUtf16(data->pFuncs, arg1, arg2)
+#define VBOX_UTF16_TO_UTF8(arg1, arg2) \
+do { \
+gVBoxAPI.UPFN.Utf16ToUtf8(data->pFuncs, arg1, arg2); \
+if (!*(arg2)) \
+abort(); \
+} while (0)
+
+#define VBOX_UTF8_TO_UTF16(arg1, arg2) \
+do { \
+gVBoxAPI.UPFN.Utf8ToUtf16(data->pFuncs, arg1, arg2); \
+if (!*(arg2)) \
+abort(); \
+} while (0)

 #define VBOX_ADDREF(arg)gVBoxAPI.nsUISupports.AddRef((void 
*)(arg))

-- 
2.29.2



[PATCH 24/33] virURIFormat: abort() on failure

2021-02-24 Thread Peter Krempa
If the argument of 'xmlSaveUri' is non-NULL the function returns NULL on
OOM failure only. Thus we can directly abort rather than try to do the
impossible recovery.

Signed-off-by: Peter Krempa 
---
 src/util/viruri.c | 8 +++-
 1 file changed, 3 insertions(+), 5 deletions(-)

diff --git a/src/util/viruri.c b/src/util/viruri.c
index 0aafd49d6d..1e8808ddc6 100644
--- a/src/util/viruri.c
+++ b/src/util/viruri.c
@@ -238,11 +238,9 @@ virURIFormat(virURIPtr uri)
 if (!xmluri.server && !xmluri.port)
 xmluri.port = -1;

-ret = (char *)xmlSaveUri();
-if (!ret) {
-virReportOOMError();
-return NULL;
-}
+/* xmlSaveUri can fail only on OOM condition if argument is non-NULL */
+if (!(ret = (char *)xmlSaveUri()))
+abort();

 return ret;
 }
-- 
2.29.2



[PATCH 19/33] util: xml: Add wrapper for 'xmlNewNode'

2021-02-24 Thread Peter Krempa
Add a wrapper that will handle the out of memory condition by abort()
and also prevents callers from having to typecast the argument.

Signed-off-by: Peter Krempa 
---
 src/conf/domain_conf.c|  7 ++-
 src/libvirt_private.syms  |  1 +
 src/util/virxml.c | 13 +
 src/util/virxml.h |  4 
 src/vbox/vbox_snapshot_conf.c | 34 +-
 tools/virsh-domain.c  |  5 +
 6 files changed, 30 insertions(+), 34 deletions(-)

diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c
index 7a3374b5be..c0881608af 100644
--- a/src/conf/domain_conf.c
+++ b/src/conf/domain_conf.c
@@ -30456,11 +30456,8 @@ virDomainDefSetMetadata(virDomainDefPtr def,
 return -1;

 /* create the root node if needed */
-if (!def->metadata &&
-!(def->metadata = xmlNewNode(NULL, (unsigned char 
*)"metadata"))) {
-virReportOOMError();
-return -1;
-}
+if (!def->metadata)
+def->metadata = virXMLNewNode(NULL, "metadata");

 if (!(new = xmlCopyNode(doc->children, 1))) {
 virReportOOMError();
diff --git a/src/libvirt_private.syms b/src/libvirt_private.syms
index dd54550b60..48f66daab8 100644
--- a/src/libvirt_private.syms
+++ b/src/libvirt_private.syms
@@ -3533,6 +3533,7 @@ virXMLBufferCreate;
 virXMLCheckIllegalChars;
 virXMLExtractNamespaceXML;
 virXMLFormatElement;
+virXMLNewNode;
 virXMLNodeContentString;
 virXMLNodeNameEqual;
 virXMLNodeSanitizeNamespaces;
diff --git a/src/util/virxml.c b/src/util/virxml.c
index 3fed2b2a6e..ebe479f5d3 100644
--- a/src/util/virxml.c
+++ b/src/util/virxml.c
@@ -1474,3 +1474,16 @@ virXMLBufferCreate(void)

 return ret;
 }
+
+
+xmlNodePtr
+virXMLNewNode(xmlNsPtr ns,
+  const char *name)
+{
+xmlNodePtr ret;
+
+if (!(ret = xmlNewNode(ns, BAD_CAST name)))
+abort();
+
+return ret;
+}
diff --git a/src/util/virxml.h b/src/util/virxml.h
index 24a2234506..d32f77b867 100644
--- a/src/util/virxml.h
+++ b/src/util/virxml.h
@@ -289,3 +289,7 @@ int virParseScaledValue(const char *xpath,

 xmlBufferPtr
 virXMLBufferCreate(void);
+
+xmlNodePtr
+virXMLNewNode(xmlNsPtr ns,
+  const char *name);
diff --git a/src/vbox/vbox_snapshot_conf.c b/src/vbox/vbox_snapshot_conf.c
index f1cae3039a..5792d3175e 100644
--- a/src/vbox/vbox_snapshot_conf.c
+++ b/src/vbox/vbox_snapshot_conf.c
@@ -328,7 +328,7 @@ 
virVBoxSnapshotConfCreateHardDiskNode(virVBoxSnapshotConfHardDiskPtr hardDisk)
 int result = -1;
 size_t i = 0;
 char *uuid = NULL;
-xmlNodePtr ret = xmlNewNode(NULL, BAD_CAST "HardDisk");
+xmlNodePtr ret = virXMLNewNode(NULL, "HardDisk");
 uuid = g_strdup_printf("{%s}", hardDisk->uuid);

 if (xmlNewProp(ret, BAD_CAST "uuid", BAD_CAST uuid) == NULL)
@@ -404,7 +404,7 @@ virVBoxSnapshotConfSerializeSnapshot(xmlNodePtr node,

 /* node description */
 if (snapshot->description != NULL) {
-descriptionNode = xmlNewNode(NULL, BAD_CAST "Description");
+descriptionNode = virXMLNewNode(NULL, "Description");
 xmlNodeSetContent(descriptionNode, BAD_CAST snapshot->description);
 xmlAddChild(node, descriptionNode);
 }
@@ -433,10 +433,10 @@ virVBoxSnapshotConfSerializeSnapshot(xmlNodePtr node,
 xmlAddChild(node, storageControllerNode);

 if (snapshot->nchildren > 0) {
-snapshotsNode = xmlNewNode(NULL, BAD_CAST "Snapshots");
+snapshotsNode = virXMLNewNode(NULL, "Snapshots");
 xmlAddChild(node, snapshotsNode);
 for (i = 0; i < snapshot->nchildren; i++) {
-xmlNodePtr child = xmlNewNode(NULL, BAD_CAST "Snapshot");
+xmlNodePtr child = virXMLNewNode(NULL, "Snapshot");
 xmlAddChild(snapshotsNode, child);
 if (virVBoxSnapshotConfSerializeSnapshot(child, 
snapshot->children[i]) < 0)
 goto cleanup;
@@ -1001,11 +1001,7 @@ 
virVBoxSnapshotConfSaveVboxFile(virVBoxSnapshotConfMachinePtr machine,
 goto cleanup;
 }

-cur = xmlNewNode(NULL, BAD_CAST "VirtualBox");
-if (!cur) {
-virReportOOMError();
-goto cleanup;
-}
+cur = virXMLNewNode(NULL, "VirtualBox");

 if (!xmlNewProp(cur, BAD_CAST "version", BAD_CAST "1.12-linux")) {
 virReportError(VIR_ERR_XML_ERROR, "%s",
@@ -1038,11 +1034,7 @@ 
virVBoxSnapshotConfSaveVboxFile(virVBoxSnapshotConfMachinePtr machine,
 goto cleanup;
 }

-machineNode = xmlNewNode(NULL, BAD_CAST "Machine");
-if (!machineNode) {
-virReportOOMError();
-goto cleanup;
-}
+machineNode = virXMLNewNode(NULL, "Machine");

 if (!xmlNewProp(machineNode, BAD_CAST "uuid", BAD_CAST machine->uuid)) {
 virReportError(VIR_ERR_XML_ERROR, "%s",
@@ -1101,11 +1093,7 @@ 
virVBoxSnapshotConfSaveVboxFile(virVBoxSnapshotConfMachinePtr machine,
 }
 xmlAddChild(xmlDocGetRootElement(xml), 

[PATCH 16/33] virfirewall: Remove impossible OOM error reporting

2021-02-24 Thread Peter Krempa
There's nothing that would set the 'err' field of virFirewallPtr to
ENOMEM so we can remove the checks.

Signed-off-by: Peter Krempa 
---
 src/util/virfirewall.c | 10 +-
 1 file changed, 1 insertion(+), 9 deletions(-)

diff --git a/src/util/virfirewall.c b/src/util/virfirewall.c
index bbeb87e72d..c1b7d2268b 100644
--- a/src/util/virfirewall.c
+++ b/src/util/virfirewall.c
@@ -698,10 +698,6 @@ virFirewallApplyRule(virFirewallPtr firewall,
 if (rule->queryCB(firewall, rule->layer, (const char *const *)lines, 
rule->queryOpaque) < 0)
 return -1;

-if (firewall->err == ENOMEM) {
-virReportOOMError();
-return -1;
-}
 if (firewall->err) {
 virReportSystemError(firewall->err, "%s",
  _("Unable to create rule"));
@@ -769,11 +765,7 @@ virFirewallApply(virFirewallPtr firewall)
_("Failed to initialize a valid firewall backend"));
 goto cleanup;
 }
-if (!firewall || firewall->err == ENOMEM) {
-virReportOOMError();
-goto cleanup;
-}
-if (firewall->err) {
+if (!firewall || firewall->err) {
 virReportSystemError(firewall->err, "%s",
  _("Unable to create rule"));
 goto cleanup;
-- 
2.29.2



[PATCH 11/33] util: vircommand: Remove OOM handling

2021-02-24 Thread Peter Krempa
The OOM error handling is dead code nowadays.

Signed-off-by: Peter Krempa 
---
 src/util/vircommand.c | 96 +--
 1 file changed, 20 insertions(+), 76 deletions(-)

diff --git a/src/util/vircommand.c b/src/util/vircommand.c
index f11caf0d6e..1a4b77ea24 100644
--- a/src/util/vircommand.c
+++ b/src/util/vircommand.c
@@ -90,7 +90,7 @@ struct _virCommandSendBuffer {
 };

 struct _virCommand {
-int has_error; /* ENOMEM on allocation failure, -1 for anything else.  */
+int has_error; /* 0 on success, -1 on error  */

 char **args;
 size_t nargs;
@@ -198,7 +198,6 @@ virCommandFDIsSet(virCommandPtr cmd,
  *
  * Returns: 0 on success,
  *  -1 on usage error,
- *  ENOMEM on OOM
  */
 static int
 virCommandFDSet(virCommandPtr cmd,
@@ -211,8 +210,7 @@ virCommandFDSet(virCommandPtr cmd,
 if (virCommandFDIsSet(cmd, fd))
 return 0;

-if (VIR_EXPAND_N(cmd->passfd, cmd->npassfd, 1) < 0)
-return ENOMEM;
+ignore_value(VIR_EXPAND_N(cmd->passfd, cmd->npassfd, 1));

 cmd->passfd[cmd->npassfd - 1].fd = fd;
 cmd->passfd[cmd->npassfd - 1].flags = flags;
@@ -1344,10 +1342,7 @@ virCommandAddEnv(virCommandPtr cmd,
 }

 /* Arg plus trailing NULL. */
-if (VIR_RESIZE_N(cmd->env, cmd->maxenv, cmd->nenv, 1 + 1) < 0) {
-cmd->has_error = ENOMEM;
-return;
-}
+ignore_value(VIR_RESIZE_N(cmd->env, cmd->maxenv, cmd->nenv, 1 + 1));

 cmd->env[cmd->nenv++] = g_steal_pointer();
 }
@@ -1474,10 +1469,7 @@ virCommandAddEnvPassCommon(virCommandPtr cmd)
 if (!cmd || cmd->has_error)
 return;

-if (VIR_RESIZE_N(cmd->env, cmd->maxenv, cmd->nenv, 9) < 0) {
-cmd->has_error = ENOMEM;
-return;
-}
+ignore_value(VIR_RESIZE_N(cmd->env, cmd->maxenv, cmd->nenv, 9));

 virCommandAddEnvPair(cmd, "LC_ALL", "C");

@@ -1497,10 +1489,7 @@ virCommandAddEnvXDG(virCommandPtr cmd, const char 
*baseDir)
 if (!cmd || cmd->has_error)
 return;

-if (VIR_RESIZE_N(cmd->env, cmd->maxenv, cmd->nenv, 3) < 0) {
-cmd->has_error = ENOMEM;
-return;
-}
+ignore_value(VIR_RESIZE_N(cmd->env, cmd->maxenv, cmd->nenv, 3));

 virCommandAddEnvFormat(cmd, "XDG_DATA_HOME=%s/%s",
baseDir, ".local/share");
@@ -1530,10 +1519,7 @@ virCommandAddArg(virCommandPtr cmd, const char *val)
 }

 /* Arg plus trailing NULL. */
-if (VIR_RESIZE_N(cmd->args, cmd->maxargs, cmd->nargs, 1 + 1) < 0) {
-cmd->has_error = ENOMEM;
-return;
-}
+ignore_value(VIR_RESIZE_N(cmd->args, cmd->maxargs, cmd->nargs, 1 + 1));

 cmd->args[cmd->nargs++] = g_strdup(val);
 }
@@ -1559,10 +1545,7 @@ virCommandAddArgBuffer(virCommandPtr cmd, virBufferPtr 
buf)
 str = g_strdup("");

 /* Arg plus trailing NULL. */
-if (VIR_RESIZE_N(cmd->args, cmd->maxargs, cmd->nargs, 1 + 1) < 0) {
-cmd->has_error = ENOMEM;
-return;
-}
+ignore_value(VIR_RESIZE_N(cmd->args, cmd->maxargs, cmd->nargs, 1 + 1));

 cmd->args[cmd->nargs] = g_steal_pointer();
 cmd->nargs++;
@@ -1591,11 +1574,7 @@ virCommandAddArgFormat(virCommandPtr cmd, const char 
*format, ...)
 va_end(list);

 /* Arg plus trailing NULL. */
-if (VIR_RESIZE_N(cmd->args, cmd->maxargs, cmd->nargs, 1 + 1) < 0) {
-VIR_FREE(arg);
-cmd->has_error = ENOMEM;
-return;
-}
+ignore_value(VIR_RESIZE_N(cmd->args, cmd->maxargs, cmd->nargs, 1 + 1));

 cmd->args[cmd->nargs++] = arg;
 }
@@ -1642,10 +1621,7 @@ virCommandAddArgSet(virCommandPtr cmd, const char 
*const*vals)
 narg++;

 /* narg plus trailing NULL. */
-if (VIR_RESIZE_N(cmd->args, cmd->maxargs, cmd->nargs, narg + 1) < 0) {
-cmd->has_error = ENOMEM;
-return;
-}
+ignore_value(VIR_RESIZE_N(cmd->args, cmd->maxargs, cmd->nargs, narg + 1));

 narg = 0;
 while (vals[narg] != NULL) {
@@ -1678,10 +1654,7 @@ virCommandAddArgList(virCommandPtr cmd, ...)
 va_end(list);

 /* narg plus trailing NULL. */
-if (VIR_RESIZE_N(cmd->args, cmd->maxargs, cmd->nargs, narg + 1) < 0) {
-cmd->has_error = ENOMEM;
-return;
-}
+ignore_value(VIR_RESIZE_N(cmd->args, cmd->maxargs, cmd->nargs, narg + 1));

 va_start(list, cmd);
 while (1) {
@@ -1765,10 +1738,7 @@ virCommandSetSendBuffer(virCommandPtr cmd,
 }

 i = virCommandGetNumSendBuffers(cmd);
-if (VIR_REALLOC_N(cmd->sendBuffers, i + 1) < 0) {
-cmd->has_error = ENOMEM;
-return -1;
-}
+ignore_value(VIR_REALLOC_N(cmd->sendBuffers, i + 1));

 cmd->sendBuffers[i].fd = fd;
 cmd->sendBuffers[i].buffer = buffer;
@@ -2099,11 +2069,7 @@ virCommandToString(virCommandPtr cmd, bool linebreaks)

 /* Cannot assume virCommandRun will be called; so report the error
  * now.  If virCommandRun is called, it will report the same error. */
-if (!cmd ||cmd->has_error == ENOMEM) {
-virReportOOMError();
-

[PATCH 10/33] virDomainDefSetMetadata: Rework memory handling

2021-02-24 Thread Peter Krempa
Switch to use g_autoptr for 'doc' and 'new' local variables.
Additionally report proper error when 'xmlAddChild' fails because OOM is
not the only error it can report.

Signed-off-by: Peter Krempa 
---
 src/conf/domain_conf.c | 34 --
 1 file changed, 16 insertions(+), 18 deletions(-)

diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c
index 6f4487fcfc..46620d38ed 100644
--- a/src/conf/domain_conf.c
+++ b/src/conf/domain_conf.c
@@ -30423,15 +30423,14 @@ virDomainDefSetMetadata(virDomainDefPtr def,
 const char *key,
 const char *uri)
 {
-xmlDocPtr doc = NULL;
+g_autoptr(xmlDoc) doc = NULL;
 xmlNodePtr old;
-xmlNodePtr new = NULL;
-int ret = -1;
+g_autoptr(xmlNode) new = NULL;

 if (type >= VIR_DOMAIN_METADATA_LAST) {
 virReportError(VIR_ERR_INVALID_ARG,
_("unknown metadata type '%d'"), type);
-goto cleanup;
+return -1;
 }

 switch ((virDomainMetadataType) type) {
@@ -30451,23 +30450,24 @@ virDomainDefSetMetadata(virDomainDefPtr def,

 case VIR_DOMAIN_METADATA_ELEMENT:
 if (metadata) {
+
 /* parse and modify the xml from the user */
 if (!(doc = virXMLParseString(metadata, _("(metadata_xml)"
-goto cleanup;
+return -1;

 if (virXMLInjectNamespace(doc->children, uri, key) < 0)
-goto cleanup;
+return -1;

 /* create the root node if needed */
 if (!def->metadata &&
 !(def->metadata = xmlNewNode(NULL, (unsigned char 
*)"metadata"))) {
 virReportOOMError();
-goto cleanup;
+return -1;
 }

 if (!(new = xmlCopyNode(doc->children, 1))) {
 virReportOOMError();
-goto cleanup;
+return -1;
 }
 }

@@ -30477,11 +30477,13 @@ virDomainDefSetMetadata(virDomainDefPtr def,
 xmlFreeNode(old);
 }

-if (new &&
-!(xmlAddChild(def->metadata, new))) {
-xmlFreeNode(new);
-virReportOOMError();
-goto cleanup;
+if (new) {
+if (!(xmlAddChild(def->metadata, new))) {
+virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
+   _("failed to add metadata to XML document"));
+return -1;
+}
+new = NULL;
 }
 break;

@@ -30490,11 +30492,7 @@ virDomainDefSetMetadata(virDomainDefPtr def,
 break;
 }

-ret = 0;
-
- cleanup:
-xmlFreeDoc(doc);
-return ret;
+return 0;
 }


-- 
2.29.2



[PATCH 09/33] lxc_process: Remove OOM handling from logging setup

2021-02-24 Thread Peter Krempa
'virLogGetFilters' doesn't return failure and 'virLogGetOutputs' reports
it's own errors.

Signed-off-by: Peter Krempa 
---
 src/lxc/lxc_process.c | 9 +
 1 file changed, 1 insertion(+), 8 deletions(-)

diff --git a/src/lxc/lxc_process.c b/src/lxc/lxc_process.c
index cbc04a3dcd..679709605e 100644
--- a/src/lxc/lxc_process.c
+++ b/src/lxc/lxc_process.c
@@ -960,21 +960,14 @@ virLXCProcessBuildControllerCmd(virLXCDriverPtr driver,

 if (virLogGetNbFilters() > 0) {
 filterstr = virLogGetFilters();
-if (!filterstr) {
-virReportOOMError();
-goto error;
-}

 virCommandAddEnvPair(cmd, "LIBVIRT_LOG_FILTERS", filterstr);
 }

 if (cfg->log_libvirtd) {
 if (virLogGetNbOutputs() > 0) {
-outputstr = virLogGetOutputs();
-if (!outputstr) {
-virReportOOMError();
+if (!(outputstr = virLogGetOutputs()))
 goto error;
-}

 virCommandAddEnvPair(cmd, "LIBVIRT_LOG_OUTPUTS", outputstr);
 }
-- 
2.29.2



[PATCH 05/33] virCommandAddArgBuffer: Simplify clearing of @buf

2021-02-24 Thread Peter Krempa
Get the buffer contents into a temporary variable with automatic
clearing so that the error branches don't have to reset the buffer.
Additionally handle the NULL string case before assignment.

Signed-off-by: Peter Krempa 
---
 src/util/vircommand.c | 14 +++---
 1 file changed, 7 insertions(+), 7 deletions(-)

diff --git a/src/util/vircommand.c b/src/util/vircommand.c
index b94ab615d5..f11caf0d6e 100644
--- a/src/util/vircommand.c
+++ b/src/util/vircommand.c
@@ -1550,21 +1550,21 @@ virCommandAddArg(virCommandPtr cmd, const char *val)
 void
 virCommandAddArgBuffer(virCommandPtr cmd, virBufferPtr buf)
 {
-if (!cmd || cmd->has_error) {
-virBufferFreeAndReset(buf);
+g_autofree char *str = virBufferContentAndReset(buf);
+
+if (!cmd || cmd->has_error)
 return;
-}
+
+if (!str)
+str = g_strdup("");

 /* Arg plus trailing NULL. */
 if (VIR_RESIZE_N(cmd->args, cmd->maxargs, cmd->nargs, 1 + 1) < 0) {
 cmd->has_error = ENOMEM;
-virBufferFreeAndReset(buf);
 return;
 }

-cmd->args[cmd->nargs] = virBufferContentAndReset(buf);
-if (!cmd->args[cmd->nargs])
-cmd->args[cmd->nargs] = g_strdup("");
+cmd->args[cmd->nargs] = g_steal_pointer();
 cmd->nargs++;
 }

-- 
2.29.2



[PATCH 06/33] virCPUx86DataParse: Don't check error from x86FeatureNames

2021-02-24 Thread Peter Krempa
x86FeatureNames uses virBuffer and thus can't fail nowadays.

Signed-off-by: Peter Krempa 
---
 src/cpu/cpu_x86.c | 6 +-
 1 file changed, 1 insertion(+), 5 deletions(-)

diff --git a/src/cpu/cpu_x86.c b/src/cpu/cpu_x86.c
index 92f945beb4..79c5868ae6 100644
--- a/src/cpu/cpu_x86.c
+++ b/src/cpu/cpu_x86.c
@@ -1856,11 +1856,7 @@ virCPUx86DataParse(xmlXPathContextPtr ctxt)
  */
 #define virX86CpuIncompatible(MSG, CPU_DEF) \
 do { \
-g_autofree char *flagsStr = NULL; \
-if (!(flagsStr = x86FeatureNames(map, ", ", (CPU_DEF { \
-virReportOOMError(); \
-return VIR_CPU_COMPARE_ERROR; \
-} \
+g_autofree char *flagsStr = x86FeatureNames(map, ", ", (CPU_DEF)); 
\
 if (message) \
 *message = g_strdup_printf("%s: %s", _(MSG), flagsStr); \
 VIR_DEBUG("%s: %s", MSG, flagsStr); \
-- 
2.29.2



[PATCH 08/33] virBuildPath: Remove return value

2021-02-24 Thread Peter Krempa
The function can't fail nowadays, remove the return value and adjust
callers.

Signed-off-by: Peter Krempa 
---
 docs/internals/command.html.in |  8 +---
 src/util/virfcp.c  |  3 +--
 src/util/virfile.c |  7 +--
 src/util/virfile.h |  2 +-
 src/util/virhook.c | 14 ++
 src/util/virpci.c  | 11 ++-
 6 files changed, 8 insertions(+), 37 deletions(-)

diff --git a/docs/internals/command.html.in b/docs/internals/command.html.in
index 823d89cc71..634afdc937 100644
--- a/docs/internals/command.html.in
+++ b/docs/internals/command.html.in
@@ -568,13 +568,7 @@ int runhook(const char *drvstr, const char *id,
   char *path;
   virCommandPtr cmd;

-  ret = virBuildPath(path, LIBVIRT_HOOK_DIR, drvstr);
-  if ((ret  0) || (path == NULL)) {
-  virHookReportError(VIR_ERR_INTERNAL_ERROR,
- _("Failed to build path for %s hook"),
- drvstr);
-  return -1;
-  }
+  virBuildPath(path, LIBVIRT_HOOK_DIR, drvstr);

   cmd = virCommandNew(path);
   VIR_FREE(path);
diff --git a/src/util/virfcp.c b/src/util/virfcp.c
index 80773c7c5d..5e8fe72fec 100644
--- a/src/util/virfcp.c
+++ b/src/util/virfcp.c
@@ -40,8 +40,7 @@ virFCIsCapableRport(const char *rport)
 {
 g_autofree char *path = NULL;

-if (virBuildPath(, SYSFS_FC_RPORT_PATH, rport) < 0)
-return false;
+virBuildPath(, SYSFS_FC_RPORT_PATH, rport);

 return virFileExists(path);
 }
diff --git a/src/util/virfile.c b/src/util/virfile.c
index 5710495bbf..27a647d1d0 100644
--- a/src/util/virfile.c
+++ b/src/util/virfile.c
@@ -1308,13 +1308,12 @@ virFileFindMountPoint(const char *type G_GNUC_UNUSED)

 #endif /* defined WITH_MNTENT_H && defined WITH_GETMNTENT_R */

-int
+void
 virBuildPathInternal(char **path, ...)
 {
 char *path_component = NULL;
 g_auto(virBuffer) buf = VIR_BUFFER_INITIALIZER;
 va_list ap;
-int ret = 0;

 va_start(ap, path);

@@ -1329,10 +1328,6 @@ virBuildPathInternal(char **path, ...)
 va_end(ap);

 *path = virBufferContentAndReset();
-if (*path == NULL)
-ret = -1;
-
-return ret;
 }

 /* Read no more than the specified maximum number of bytes. */
diff --git a/src/util/virfile.h b/src/util/virfile.h
index 733d652ac9..f237e98290 100644
--- a/src/util/virfile.h
+++ b/src/util/virfile.h
@@ -300,7 +300,7 @@ char *virFileFindMountPoint(const char *type);
 /* NB: this should be combined with virFileBuildPath */
 #define virBuildPath(path, ...) \
 virBuildPathInternal(path, __VA_ARGS__, NULL)
-int virBuildPathInternal(char **path, ...) G_GNUC_NULL_TERMINATED;
+void virBuildPathInternal(char **path, ...) G_GNUC_NULL_TERMINATED;

 typedef struct _virHugeTLBFS virHugeTLBFS;
 typedef virHugeTLBFS *virHugeTLBFSPtr;
diff --git a/src/util/virhook.c b/src/util/virhook.c
index e4e1945225..b52e2cd814 100644
--- a/src/util/virhook.c
+++ b/src/util/virhook.c
@@ -155,12 +155,7 @@ virHookCheck(int no, const char *driver)
 return -1;
 }

-if (virBuildPath(, LIBVIRT_HOOK_DIR, driver) < 0) {
-virReportError(VIR_ERR_INTERNAL_ERROR,
-   _("Failed to build path for %s hook"),
-   driver);
-return -1;
-}
+virBuildPath(, LIBVIRT_HOOK_DIR, driver);

 if (!virFileExists(path)) {
 VIR_DEBUG("No hook script %s", path);
@@ -405,12 +400,7 @@ virHookCall(int driver,
 if (extra == NULL)
 extra = "-";

-if (virBuildPath(, LIBVIRT_HOOK_DIR, drvstr) < 0) {
-virReportError(VIR_ERR_INTERNAL_ERROR,
-   _("Failed to build path for %s hook"),
-   drvstr);
-return -1;
-}
+virBuildPath(, LIBVIRT_HOOK_DIR, drvstr);

 script_ret = 1;

diff --git a/src/util/virpci.c b/src/util/virpci.c
index 3df4199532..515b642db4 100644
--- a/src/util/virpci.c
+++ b/src/util/virpci.c
@@ -2293,10 +2293,7 @@ virPCIGetPhysicalFunction(const char *vf_sysfs_path,

 *pf = NULL;

-if (virBuildPath(_link, vf_sysfs_path, "physfn") == -1) {
-virReportOOMError();
-return -1;
-}
+virBuildPath(_link, vf_sysfs_path, "physfn");

 if ((*pf = virPCIGetDeviceAddressFromSysfsLink(device_link))) {
 VIR_DEBUG("PF for VF device '%s': " VIR_PCI_DEVICE_ADDRESS_FMT,
@@ -2470,11 +2467,7 @@ virPCIGetNetName(const char *device_link_sysfs_path,

 *netname = NULL;

-if (virBuildPath(_sysfs_net_path, device_link_sysfs_path,
- "net") == -1) {
-virReportOOMError();
-return -1;
-}
+virBuildPath(_sysfs_net_path, device_link_sysfs_path, "net");

 if (virDirOpenQuiet(, pcidev_sysfs_net_path) < 0) {
 /* this *isn't* an error - caller needs to check for netname == NULL */
-- 
2.29.2



[PATCH 07/33] virhostcputest: linuxCPUStatsCompareFiles: Don't check return value of virBufferContentAndReset

2021-02-24 Thread Peter Krempa
The buffer won't encounter OOM condition nowadays

Signed-off-by: Peter Krempa 
---
 tests/virhostcputest.c | 5 +
 1 file changed, 1 insertion(+), 4 deletions(-)

diff --git a/tests/virhostcputest.c b/tests/virhostcputest.c
index 786a363e48..2608f0becc 100644
--- a/tests/virhostcputest.c
+++ b/tests/virhostcputest.c
@@ -141,10 +141,7 @@ linuxCPUStatsCompareFiles(const char *cpustatfile,
 goto fail;
 }

-if (!(actualData = virBufferContentAndReset())) {
-virReportOOMError();
-goto fail;
-}
+actualData = virBufferContentAndReset();

 if (virTestCompareToFile(actualData, outfile) < 0)
 goto fail;
-- 
2.29.2



[PATCH 04/33] virCommandAddEnv: Make stealing of argument more obvious

2021-02-24 Thread Peter Krempa
The function is supposed to always consume the passed environment
variable string. Use a temp variable with autofree and g_steal_pointer
to prevent having to free it manually.

Signed-off-by: Peter Krempa 
---
 src/util/vircommand.c | 9 +
 1 file changed, 5 insertions(+), 4 deletions(-)

diff --git a/src/util/vircommand.c b/src/util/vircommand.c
index 323f841b98..b94ab615d5 100644
--- a/src/util/vircommand.c
+++ b/src/util/vircommand.c
@@ -1325,8 +1325,10 @@ virCommandRawStatus(virCommandPtr cmd)
  * already set, then it is replaced in the list.
  */
 static void
-virCommandAddEnv(virCommandPtr cmd, char *env)
+virCommandAddEnv(virCommandPtr cmd,
+ char *envstr)
 {
+g_autofree char *env = envstr;
 size_t namelen;
 size_t i;

@@ -1336,19 +1338,18 @@ virCommandAddEnv(virCommandPtr cmd, char *env)
 /* + 1 because we want to match the '=' character too. */
 if (STREQLEN(cmd->env[i], env, namelen + 1)) {
 VIR_FREE(cmd->env[i]);
-cmd->env[i] = env;
+cmd->env[i] = g_steal_pointer();
 return;
 }
 }

 /* Arg plus trailing NULL. */
 if (VIR_RESIZE_N(cmd->env, cmd->maxenv, cmd->nenv, 1 + 1) < 0) {
-VIR_FREE(env);
 cmd->has_error = ENOMEM;
 return;
 }

-cmd->env[cmd->nenv++] = env;
+cmd->env[cmd->nenv++] = g_steal_pointer();
 }

 /**
-- 
2.29.2



[PATCH 03/33] virDomainDefSetMetadata: Avoid temporary variable for string copy

2021-02-24 Thread Peter Krempa
Since error checking was removed when switching to g_strdup, it doesn't
make much sense to have 'tmp' around.

Signed-off-by: Peter Krempa 
---
 src/conf/domain_conf.c | 15 ++-
 1 file changed, 6 insertions(+), 9 deletions(-)

diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c
index b731744f04..6f4487fcfc 100644
--- a/src/conf/domain_conf.c
+++ b/src/conf/domain_conf.c
@@ -30426,7 +30426,6 @@ virDomainDefSetMetadata(virDomainDefPtr def,
 xmlDocPtr doc = NULL;
 xmlNodePtr old;
 xmlNodePtr new = NULL;
-char *tmp = NULL;
 int ret = -1;

 if (type >= VIR_DOMAIN_METADATA_LAST) {
@@ -30437,19 +30436,17 @@ virDomainDefSetMetadata(virDomainDefPtr def,

 switch ((virDomainMetadataType) type) {
 case VIR_DOMAIN_METADATA_DESCRIPTION:
-if (STRNEQ_NULLABLE(metadata, ""))
-tmp = g_strdup(metadata);
+g_clear_pointer(>description, g_free);

-VIR_FREE(def->description);
-def->description = tmp;
+if (STRNEQ_NULLABLE(metadata, ""))
+def->description = g_strdup(metadata);
 break;

 case VIR_DOMAIN_METADATA_TITLE:
-if (STRNEQ_NULLABLE(metadata, ""))
-tmp = g_strdup(metadata);
+g_clear_pointer(>title, g_free);

-VIR_FREE(def->title);
-def->title = tmp;
+if (STRNEQ_NULLABLE(metadata, ""))
+def->title = g_strdup(metadata);
 break;

 case VIR_DOMAIN_METADATA_ELEMENT:
-- 
2.29.2



[PATCH 02/33] util: xml: Introduce autoptr cleanup support for 'xmlNode'

2021-02-24 Thread Peter Krempa
Signed-off-by: Peter Krempa 
---
 src/util/virxml.h | 1 +
 1 file changed, 1 insertion(+)

diff --git a/src/util/virxml.h b/src/util/virxml.h
index f73b8975ba..e696dd25f5 100644
--- a/src/util/virxml.h
+++ b/src/util/virxml.h
@@ -255,6 +255,7 @@ G_DEFINE_AUTO_CLEANUP_CLEAR_FUNC(virXPathContextNodeSave, 
virXPathContextNodeRes
 G_DEFINE_AUTOPTR_CLEANUP_FUNC(xmlDoc, xmlFreeDoc);
 G_DEFINE_AUTOPTR_CLEANUP_FUNC(xmlXPathContext, xmlXPathFreeContext);
 G_DEFINE_AUTOPTR_CLEANUP_FUNC(xmlBuffer, xmlBufferFree);
+G_DEFINE_AUTOPTR_CLEANUP_FUNC(xmlNode, xmlFreeNode);

 typedef int (*virXMLNamespaceParse)(xmlXPathContextPtr ctxt, void **nsdata);
 typedef void (*virXMLNamespaceFree)(void *nsdata);
-- 
2.29.2



[PATCH 01/33] Remove useless comments for VIR_FROM_THIS definition

2021-02-24 Thread Peter Krempa
Signed-off-by: Peter Krempa 
---
 src/util/virpci.c   | 1 -
 src/util/virscsi.c  | 1 -
 src/util/virscsivhost.c | 1 -
 3 files changed, 3 deletions(-)

diff --git a/src/util/virpci.c b/src/util/virpci.c
index 8147ce11e9..3df4199532 100644
--- a/src/util/virpci.c
+++ b/src/util/virpci.c
@@ -103,7 +103,6 @@ struct _virPCIDeviceList {
 };


-/* For virReportOOMError()  and virReportSystemError() */
 #define VIR_FROM_THIS VIR_FROM_NONE

 /* Specifications referenced in comments:
diff --git a/src/util/virscsi.c b/src/util/virscsi.c
index 2a9f6da76a..d0ba33e254 100644
--- a/src/util/virscsi.c
+++ b/src/util/virscsi.c
@@ -37,7 +37,6 @@

 #define SYSFS_SCSI_DEVICES "/sys/bus/scsi/devices"

-/* For virReportOOMError()  and virReportSystemError() */
 #define VIR_FROM_THIS VIR_FROM_NONE

 VIR_LOG_INIT("util.scsi");
diff --git a/src/util/virscsivhost.c b/src/util/virscsivhost.c
index b7bf0da1b3..a0dfb8021a 100644
--- a/src/util/virscsivhost.c
+++ b/src/util/virscsivhost.c
@@ -28,7 +28,6 @@
 #include "virstring.h"
 #include "viralloc.h"

-/* For virReportOOMError()  and virReportSystemError() */
 #define VIR_FROM_THIS VIR_FROM_NONE

 VIR_LOG_INIT("util.scsihost");
-- 
2.29.2



[PATCH 00/33] Remove the now misleading virReportOOMError infra

2021-02-24 Thread Peter Krempa
'virReportOOMError' is nowadays mostly useless since an OOM error will
trigger yet another allocation failure in the logger when attempting to
log the error.

Additionally it was also used in few places which can fail with other
failures than OOM.

To prevent both errorneous usage types, let's remove it completely. In
the rare case we'd want to allocate a massive buffer and want to fail
gracefully we still can use virReportError with VIR_ERR_NO_MEMORY.

The series starts by some cleanup, then removes error handling from
places where it's now dead code as we'll abort before the reporting,
then converts some real OOM scenarios to abort() directly and lastly
fixes the error message for cases where other errors are possible and
lastly removes virReportOOMError.

Pipelines are stuck, so hopefully it will go through:
https://gitlab.com/pipo.sk/libvirt/-/pipelines/261161989

Peter Krempa (33):
  Remove useless comments for VIR_FROM_THIS definition
  util: xml: Introduce autoptr cleanup support for 'xmlNode'
  virDomainDefSetMetadata: Avoid temporary variable for string copy
  virCommandAddEnv: Make stealing of argument more obvious
  virCommandAddArgBuffer: Simplify clearing of @buf
  virCPUx86DataParse: Don't check error from x86FeatureNames
  virhostcputest: linuxCPUStatsCompareFiles: Don't check return value of
virBufferContentAndReset
  virBuildPath: Remove return value
  lxc_process: Remove OOM handling from logging setup
  virDomainDefSetMetadata: Rework memory handling
  util: vircommand: Remove OOM handling
  virCloseCallbacksGetForConn: Remove OOM handling
  virfirewall: Don't check OOM in ADD_ARG macro
  virfirewall: Remove OOM checks from virFirewallStartTransaction
  virfirewall: virFirewallAddRuleFullV: Remove OOM check from
VIR_APPEND_ELEMENT
  virfirewall: Remove impossible OOM error reporting
  util: virnetlink: Add wrapper for 'nlmsg_alloc_simple'
  util: xml: Add virXMLBufferCreate wrapper
  util: xml: Add wrapper for 'xmlNewNode'
  Don't report OOM error on xmlCopyNode failure
  virXMLXPathContextNew: abort() on allocation failure
  virXMLParseHelper: abort() on allocation failure
  util: virprocess: abort() on CPU_ALLOC failure
  virURIFormat: abort() on failure
  util: iohelper: Don't handle OOM from posix_memalign
  hyperv: abort() failure of wsmc_fault_new()
  vbox: abort() on allocation failure in UTF8<->UTF16 conversion
  libxl: abort() on failure of libxl_cpu_bitmap_alloc()
  virVBoxSnapshotConfSaveVboxFile: abort() on failure to allocate xmlDoc
and comment
  util: json: Report non-OOM error on yajl failure
  storage: Don't report OOM error on failure of glfs_new
  virVMXConvertToUTF8: Report non-OOM error on failure of
xmlBufferCreateStatic
  util: virerror: Remove virReportOOMError

 build-aux/syntax-check.mk |   8 --
 docs/internals/command.html.in|   8 +-
 src/conf/domain_conf.c|  62 -
 src/conf/network_conf.c   |   5 +-
 src/cpu/cpu_x86.c |   6 +-
 src/hyperv/hyperv_wmi.c   |   8 +-
 src/hypervisor/virclosecallbacks.c|  15 +--
 src/libvirt_private.syms  |   3 +-
 src/libxl/libxl_conf.c|   6 +-
 src/libxl/libxl_driver.c  |   7 +-
 src/lxc/lxc_process.c |   9 +-
 src/storage/storage_backend_gluster.c |   3 +-
 .../storage_file_backend_gluster.c|   3 +-
 src/test/test_driver.c|   6 +-
 src/util/iohelper.c   |   7 +-
 src/util/vircommand.c | 119 +-
 src/util/virerror.c   |  22 
 src/util/virerror.h   |   8 --
 src/util/virfcp.c |   3 +-
 src/util/virfile.c|   7 +-
 src/util/virfile.h|   2 +-
 src/util/virfirewall.c|  62 ++---
 src/util/virhook.c|  14 +--
 src/util/virjson.c|   6 +-
 src/util/virnetdev.c  |  18 +--
 src/util/virnetdevbridge.c|  10 +-
 src/util/virnetdevip.c|  15 +--
 src/util/virnetdevvportprofile.c  |   6 +-
 src/util/virnetlink.c |  38 +++---
 src/util/virnetlink.h |   4 +
 src/util/virpci.c |  12 +-
 src/util/virprocess.c |  12 +-
 src/util/virscsi.c|   1 -
 src/util/virscsivhost.c   |   1 -
 src/util/viruri.c |   8 +-
 src/util/virxml.c |  44 ---
 src/util/virxml.h |   8 ++
 src/vbox/vbox_common.c|  20 ---
 src/vbox/vbox_common.h|  15 ++-
 

Re: [PATCH v2 00/31] qapi/qom: QAPIfy --object and object-add

2021-02-24 Thread Peter Krempa
On Wed, Feb 24, 2021 at 14:52:24 +0100, Kevin Wolf wrote:
> This series adds a QAPI type for the properties of all user creatable
> QOM types and finally makes the --object command line option (in all
> binaries) and the object-add monitor commands (in QMP and HMP) use the
> new ObjectOptions union.
> 
> This change improves things in more than just one way:
> 
> 1. Documentation for QOM object types has always been lacking. Adding
>the schema, we get documentation for every property.
> 
> 2. It prevents bugs by performing parts of the input validation (e.g.
>checking presence of mandatory properties) already in QAPI instead of
>relying on separate manual implementations in each class.
> 
> 3. It provides QAPI introspection for user creatable objects.
> 
> 4. Non-scalar properties are now supported everywhere because the
>command line parsers (including HMP) use the keyval parser now.

I've updated and posted another version of the libvirt patches which add
testing that our generated props conform to the schema and also deals
with the dropped 'props' wrapper:

https://listman.redhat.com/archives/libvir-list/2021-February/msg01212.html

Libvirt's test pass after it without any change, so on behalf of libvirt

ACKed-by: Peter Krempa 



[PATCH v2 12/12] [DON'T PUSH] Force-check all configs with latest capabilities

2021-02-24 Thread Peter Krempa
Hack the qemuxml2argvtest to force-validate everything with latest
capabilities. The result is expected:

190) QEMU XML-2-ARGV disk-network-tlsx509-vxhs.x86_64-5.0.0... 
failed to validate -blockdev 
'{"driver":"vxhs","tls-creds":"objlibvirt-3-storage_tls0","vdisk-id":"eb90327c-8302-4725-9e1b-4e85ed4dc251","server":{"host":"192.168.0.1","port":""},"node-name":"libvirt-3-storage","cache":{"direct":true,"no-flush":false},"auto-read-only":true,"discard":"unmap"}'
 against QAPI schema: {
   ERROR: variant 'vxhs' for discriminator 'driver' not found

FAILED
1036) QEMU XML-2-ARGV launch-security-sev.x86_64-2.12.0 ... 
failed to validate -object 
'{"qom-type":"sev-guest","id":"sev0","cbitpos":47,"reduced-phys-bits":1,"policy":1,"dh-cert-file":"/tmp/lib/domain--1-QEMUGuest1/dh_cert.base64","session-file":"/tmp/lib/domain--1-QEMUGuest1/session.base64"}'
 against QAPI schema: {
   ERROR: variant 'sev-guest' for discriminator 'qom-type' not found

FAILED
1037) QEMU XML-2-ARGV launch-security-sev-missing-platform-info.x86_64-2.12.0 
... failed to validate -object 
'{"qom-type":"sev-guest","id":"sev0","cbitpos":47,"reduced-phys-bits":1,"policy":1,"dh-cert-file":"/tmp/lib/domain--1-QEMUGuest1/dh_cert.base64","session-file":"/tmp/lib/domain--1-QEMUGuest1/session.base64"}'
 against QAPI schema: {
   ERROR: variant 'sev-guest' for discriminator 'qom-type' not found

FAILED

'vxhs' was deprecated/removed and is also not an '-object' and
'sev-guest' was not enabled on the box I used for generating the
capabilities.
---
 tests/qemuxml2argvtest.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/tests/qemuxml2argvtest.c b/tests/qemuxml2argvtest.c
index a5e40c218a..1c4ba16bbf 100644
--- a/tests/qemuxml2argvtest.c
+++ b/tests/qemuxml2argvtest.c
@@ -529,8 +529,8 @@ testCompareXMLToArgvValidateSchema(virQEMUDriverPtr drv,
 bool netdevQAPIfied = false;
 bool objectQAPIfied = false;

-/* comment out with line comment to enable schema checking for non _CAPS 
tests
-if (!info->schemafile)
+///* comment out with line comment to enable schema checking for non _CAPS 
tests
+//if (!info->schemafile)
 info->schemafile =  
testQemuGetLatestCapsForArch(virArchToString(info->arch), "replies");
 // */

-- 
2.29.2



[PATCH v2 03/12] qemu: command: Generate commandline of iothread objects JSON

2021-02-24 Thread Peter Krempa
The commandline generator for 'iothread' objects has a private
implementation of the properties. Convert it to JSON so that it can be
later validated.

Signed-off-by: Peter Krempa 
---
 src/qemu/qemu_command.c | 18 +++---
 1 file changed, 11 insertions(+), 7 deletions(-)

diff --git a/src/qemu/qemu_command.c b/src/qemu/qemu_command.c
index 579b00c029..7bdcdab95a 100644
--- a/src/qemu/qemu_command.c
+++ b/src/qemu/qemu_command.c
@@ -7228,15 +7228,19 @@ qemuBuildIOThreadCommandLine(virCommandPtr cmd,
 if (def->niothreadids == 0)
 return 0;

-/* Create iothread objects using the defined iothreadids list
- * and the defined id and name from the list. These may be used
- * by a disk definition which will associate to an iothread by
- * supplying a value of an id from the list
- */
 for (i = 0; i < def->niothreadids; i++) {
+g_autoptr(virJSONValue) props = NULL;
+g_auto(virBuffer) buf = VIR_BUFFER_INITIALIZER;
+g_autofree char *alias = g_strdup_printf("iothread%u", 
def->iothreadids[i]->iothread_id);
+
+if (qemuMonitorCreateObjectProps(, "iothread", alias, NULL) < 0)
+return -1;
+
+if (virQEMUBuildObjectCommandlineFromJSON(, props) < 0)
+return -1;
+
 virCommandAddArg(cmd, "-object");
-virCommandAddArgFormat(cmd, "iothread,id=iothread%u",
-   def->iothreadids[i]->iothread_id);
+virCommandAddArgBuffer(cmd, );
 }

 return 0;
-- 
2.29.2



[PATCH v2 04/12] qemu: capabilities: Introduce QEMU_CAPS_OBJECT_QAPIFIED

2021-02-24 Thread Peter Krempa
Starting from qemu-6.0 the parameters of -object/object-add are formally
described by the QAPI schema. Additionally this changes the nesting of
the properties as the 'props' nested object will be flattened to the
parent.

We'll need to detect whether qemu switched to this new approach to
generate the objects with proper nesting and also allow testing.

The capability is based on the presence of the 'secret' object in the
'qom-type' enum.

Signed-off-by: Peter Krempa 
---
 src/qemu/qemu_capabilities.c | 4 
 src/qemu/qemu_capabilities.h | 3 +++
 2 files changed, 7 insertions(+)

diff --git a/src/qemu/qemu_capabilities.c b/src/qemu/qemu_capabilities.c
index f40d6d77be..d1452f6354 100644
--- a/src/qemu/qemu_capabilities.c
+++ b/src/qemu/qemu_capabilities.c
@@ -618,6 +618,9 @@ VIR_ENUM_IMPL(virQEMUCaps,
   "memory-backend-file.x-use-canonical-path-for-ramblock-id",
   "vnc-opts",
   "migration-param.block-bitmap-mapping",
+
+  /* 395 */
+  "object.qapified",
 );


@@ -1553,6 +1556,7 @@ static struct virQEMUCapsStringFlags 
virQEMUCapsQMPSchemaQueries[] = {
 { "netdev_add/arg-type/+vhost-vdpa", QEMU_CAPS_NETDEV_VHOST_VDPA },
 { "migrate-set-parameters/arg-type/block-bitmap-mapping/bitmaps/transform",
   QEMU_CAPS_MIGRATION_PARAM_BLOCK_BITMAP_MAPPING },
+{ "object-add/arg-type/qom-type/^secret", QEMU_CAPS_OBJECT_QAPIFIED },
 };

 typedef struct _virQEMUCapsObjectTypeProps virQEMUCapsObjectTypeProps;
diff --git a/src/qemu/qemu_capabilities.h b/src/qemu/qemu_capabilities.h
index a5b6c7f104..193432246d 100644
--- a/src/qemu/qemu_capabilities.h
+++ b/src/qemu/qemu_capabilities.h
@@ -599,6 +599,9 @@ typedef enum { /* virQEMUCapsFlags grouping marker for 
syntax-check */
 QEMU_CAPS_VNC_OPTS, /* -vnc uses QemuOpts parser instead of custom code */
 QEMU_CAPS_MIGRATION_PARAM_BLOCK_BITMAP_MAPPING, /* block-bitmap-mapping in 
migrate-set-parameters */

+/* 395 */
+QEMU_CAPS_OBJECT_QAPIFIED, /* parameters for object-add are formally 
described */
+
 QEMU_CAPS_LAST /* this must always be the last item */
 } virQEMUCapsFlags;

-- 
2.29.2



[PATCH v2 02/12] qemu: command: Generate commandline of 'sev0' sev-guest object via JSON

2021-02-24 Thread Peter Krempa
While the 'sev0' sev-guest object will never be hotplugged, but we want
to generate it through JSON so that we'll be able to validate all
parameters of '-object' against the QAPI schema once 'object-add' is
qapified in qemu.

Signed-off-by: Peter Krempa 
---
 src/qemu/qemu_command.c   | 32 +++
 ...v-missing-platform-info.x86_64-2.12.0.args |  2 +-
 .../launch-security-sev.x86_64-2.12.0.args|  2 +-
 3 files changed, 20 insertions(+), 16 deletions(-)

diff --git a/src/qemu/qemu_command.c b/src/qemu/qemu_command.c
index 9538bc9a2a..579b00c029 100644
--- a/src/qemu/qemu_command.c
+++ b/src/qemu/qemu_command.c
@@ -9444,9 +9444,11 @@ static int
 qemuBuildSEVCommandLine(virDomainObjPtr vm, virCommandPtr cmd,
 virDomainSEVDefPtr sev)
 {
+g_autoptr(virJSONValue) props = NULL;
 g_auto(virBuffer) buf = VIR_BUFFER_INITIALIZER;
 qemuDomainObjPrivatePtr priv = vm->privateData;
-char *path = NULL;
+g_autofree char *dhpath = NULL;
+g_autofree char *sessionpath = NULL;

 if (!sev)
 return 0;
@@ -9454,21 +9456,23 @@ qemuBuildSEVCommandLine(virDomainObjPtr vm, 
virCommandPtr cmd,
 VIR_DEBUG("policy=0x%x cbitpos=%d reduced_phys_bits=%d",
   sev->policy, sev->cbitpos, sev->reduced_phys_bits);

-virBufferAsprintf(, "sev-guest,id=sev0,cbitpos=%d", sev->cbitpos);
-virBufferAsprintf(, ",reduced-phys-bits=%d", sev->reduced_phys_bits);
-virBufferAsprintf(, ",policy=0x%x", sev->policy);
+if (sev->dh_cert)
+dhpath = g_strdup_printf("%s/dh_cert.base64", priv->libDir);

-if (sev->dh_cert) {
-path = g_strdup_printf("%s/dh_cert.base64", priv->libDir);
-virBufferAsprintf(, ",dh-cert-file=%s", path);
-VIR_FREE(path);
-}
+if (sev->session)
+sessionpath = g_strdup_printf("%s/session.base64", priv->libDir);

-if (sev->session) {
-path = g_strdup_printf("%s/session.base64", priv->libDir);
-virBufferAsprintf(, ",session-file=%s", path);
-VIR_FREE(path);
-}
+if (qemuMonitorCreateObjectProps(, "sev-guest", "sev0",
+ "u:cbitpos", sev->cbitpos,
+ "u:reduced-phys-bits", 
sev->reduced_phys_bits,
+ "u:policy", sev->policy,
+ "S:dh-cert-file", dhpath,
+ "S:session-file", sessionpath,
+ NULL) < 0)
+return -1;
+
+if (virQEMUBuildObjectCommandlineFromJSON(, props) < 0)
+return -1;

 virCommandAddArg(cmd, "-object");
 virCommandAddArgBuffer(cmd, );
diff --git 
a/tests/qemuxml2argvdata/launch-security-sev-missing-platform-info.x86_64-2.12.0.args
 
b/tests/qemuxml2argvdata/launch-security-sev-missing-platform-info.x86_64-2.12.0.args
index f6cbd016df..717a21b7b0 100644
--- 
a/tests/qemuxml2argvdata/launch-security-sev-missing-platform-info.x86_64-2.12.0.args
+++ 
b/tests/qemuxml2argvdata/launch-security-sev-missing-platform-info.x86_64-2.12.0.args
@@ -29,7 +29,7 @@ file=/tmp/lib/domain--1-QEMUGuest1/master-key.aes \
 -device piix3-usb-uhci,id=usb,bus=pci.0,addr=0x1.0x2 \
 -drive file=/dev/HostVG/QEMUGuest1,format=raw,if=none,id=drive-ide0-0-0 \
 -device ide-hd,bus=ide.0,unit=0,drive=drive-ide0-0-0,id=ide0-0-0,bootindex=1 \
--object sev-guest,id=sev0,cbitpos=47,reduced-phys-bits=1,policy=0x1,\
+-object sev-guest,id=sev0,cbitpos=47,reduced-phys-bits=1,policy=1,\
 dh-cert-file=/tmp/lib/domain--1-QEMUGuest1/dh_cert.base64,\
 session-file=/tmp/lib/domain--1-QEMUGuest1/session.base64 \
 -sandbox on,obsolete=deny,elevateprivileges=deny,spawn=deny,\
diff --git a/tests/qemuxml2argvdata/launch-security-sev.x86_64-2.12.0.args 
b/tests/qemuxml2argvdata/launch-security-sev.x86_64-2.12.0.args
index f6cbd016df..717a21b7b0 100644
--- a/tests/qemuxml2argvdata/launch-security-sev.x86_64-2.12.0.args
+++ b/tests/qemuxml2argvdata/launch-security-sev.x86_64-2.12.0.args
@@ -29,7 +29,7 @@ file=/tmp/lib/domain--1-QEMUGuest1/master-key.aes \
 -device piix3-usb-uhci,id=usb,bus=pci.0,addr=0x1.0x2 \
 -drive file=/dev/HostVG/QEMUGuest1,format=raw,if=none,id=drive-ide0-0-0 \
 -device ide-hd,bus=ide.0,unit=0,drive=drive-ide0-0-0,id=ide0-0-0,bootindex=1 \
--object sev-guest,id=sev0,cbitpos=47,reduced-phys-bits=1,policy=0x1,\
+-object sev-guest,id=sev0,cbitpos=47,reduced-phys-bits=1,policy=1,\
 dh-cert-file=/tmp/lib/domain--1-QEMUGuest1/dh_cert.base64,\
 session-file=/tmp/lib/domain--1-QEMUGuest1/session.base64 \
 -sandbox on,obsolete=deny,elevateprivileges=deny,spawn=deny,\
-- 
2.29.2



[PATCH v2 06/12] qemu: command: Introduce raw JSON passthrough for '-object' for testing

2021-02-24 Thread Peter Krempa
The qemu commandline builder's QEMU_BUILD_COMMANDLINE_VALIDATE_KEEP_JSON
flag disables JSON->commandline conversion so that our qemuxml2argvtest
can use the commandline test repostitory for validating our JSON props
generators which are in many cases used on the montitor where we need to
conform to the schema.

Wire this up for the -object/object-add pair by adding a flag to
virQEMUBuildObjectCommandlineFromJSON to pass through JSON and pipe
through the 'flags' variable where necessary.

Signed-off-by: Peter Krempa 
---
 src/qemu/qemu_command.c | 264 
 src/util/virqemu.c  |  16 ++-
 src/util/virqemu.h  |   3 +-
 3 files changed, 176 insertions(+), 107 deletions(-)

diff --git a/src/qemu/qemu_command.c b/src/qemu/qemu_command.c
index 7bdcdab95a..c4bb6a87bb 100644
--- a/src/qemu/qemu_command.c
+++ b/src/qemu/qemu_command.c
@@ -190,7 +190,8 @@ VIR_ENUM_IMPL(qemuNumaPolicy,
  */
 static int
 qemuBuildMasterKeyCommandLine(virCommandPtr cmd,
-  qemuDomainObjPrivatePtr priv)
+  qemuDomainObjPrivatePtr priv,
+  unsigned int flags)
 {
 g_autofree char *alias = NULL;
 g_autofree char *path = NULL;
@@ -223,7 +224,8 @@ qemuBuildMasterKeyCommandLine(virCommandPtr cmd,
  NULL) < 0)
 return -1;

-if (virQEMUBuildObjectCommandlineFromJSON(, props) < 0)
+if (virQEMUBuildObjectCommandlineFromJSON(, props,
+  (flags & 
QEMU_BUILD_COMMANDLINE_VALIDATE_KEEP_JSON)) < 0)
 return -1;

 virCommandAddArg(cmd, "-object");
@@ -699,6 +701,7 @@ qemuBuildSecretInfoProps(qemuDomainSecretInfoPtr secinfo,
  * qemuBuildObjectSecretCommandLine:
  * @cmd: the command to modify
  * @secinfo: pointer to the secret info object
+ * @flags: commandline builder flags
  *
  * If the secinfo is available and associated with an AES secret,
  * then format the command line for the secret object. This object
@@ -709,7 +712,8 @@ qemuBuildSecretInfoProps(qemuDomainSecretInfoPtr secinfo,
  */
 static int
 qemuBuildObjectSecretCommandLine(virCommandPtr cmd,
- qemuDomainSecretInfoPtr secinfo)
+ qemuDomainSecretInfoPtr secinfo,
+ unsigned int flags)
 {
 g_auto(virBuffer) buf = VIR_BUFFER_INITIALIZER;
 g_autoptr(virJSONValue) props = NULL;
@@ -717,7 +721,8 @@ qemuBuildObjectSecretCommandLine(virCommandPtr cmd,
 if (qemuBuildSecretInfoProps(secinfo, ) < 0)
 return -1;

-if (virQEMUBuildObjectCommandlineFromJSON(, props) < 0)
+if (virQEMUBuildObjectCommandlineFromJSON(, props,
+  (flags & 
QEMU_BUILD_COMMANDLINE_VALIDATE_KEEP_JSON)) < 0)
 return -1;

 virCommandAddArg(cmd, "-object");
@@ -865,6 +870,7 @@ qemuBuildTLSx509BackendProps(const char *tlspath,
  *  (optional)
  * @alias: TLS object alias
  * @qemuCaps: capabilities
+ * @flags: commandline builder flags
  *
  * Create the command line for a TLS object
  *
@@ -877,7 +883,8 @@ qemuBuildTLSx509CommandLine(virCommandPtr cmd,
 bool verifypeer,
 const char *certEncSecretAlias,
 const char *alias,
-virQEMUCapsPtr qemuCaps)
+virQEMUCapsPtr qemuCaps,
+unsigned int flags)
 {
 g_auto(virBuffer) buf = VIR_BUFFER_INITIALIZER;
 g_autoptr(virJSONValue) props = NULL;
@@ -886,7 +893,8 @@ qemuBuildTLSx509CommandLine(virCommandPtr cmd,
  certEncSecretAlias, qemuCaps, ) < 0)
 return -1;

-if (virQEMUBuildObjectCommandlineFromJSON(, props) < 0)
+if (virQEMUBuildObjectCommandlineFromJSON(, props,
+  (flags & 
QEMU_BUILD_COMMANDLINE_VALIDATE_KEEP_JSON)) < 0)
 return -1;

 virCommandAddArg(cmd, "-object");
@@ -1976,14 +1984,16 @@ 
qemuBuildFloppyCommandLineControllerOptions(virCommandPtr cmd,

 static int
 qemuBuildObjectCommandline(virCommandPtr cmd,
-   virJSONValuePtr objProps)
+   virJSONValuePtr objProps,
+   unsigned int flags)
 {
 g_auto(virBuffer) buf = VIR_BUFFER_INITIALIZER;

 if (!objProps)
 return 0;

-if (virQEMUBuildObjectCommandlineFromJSON(, objProps) < 0)
+if (virQEMUBuildObjectCommandlineFromJSON(, objProps,
+  (flags & 
QEMU_BUILD_COMMANDLINE_VALIDATE_KEEP_JSON)) < 0)
 return -1;

 virCommandAddArg(cmd, "-object");
@@ -1995,16 +2005,17 @@ qemuBuildObjectCommandline(virCommandPtr cmd,

 static int
 qemuBuildBlockStorageSourceAttachDataCommandline(virCommandPtr cmd,
- 

[PATCH v2 10/12] qemumonitorjsontest: Remove bomb guarding object-add

2021-02-24 Thread Peter Krempa
Libvirt is now prepared for QAPIfied object-add.

Signed-off-by: Peter Krempa 
---
 tests/qemumonitorjsontest.c | 14 --
 1 file changed, 14 deletions(-)

diff --git a/tests/qemumonitorjsontest.c b/tests/qemumonitorjsontest.c
index 82c74e2ef9..48b41c908a 100644
--- a/tests/qemumonitorjsontest.c
+++ b/tests/qemumonitorjsontest.c
@@ -2740,20 +2740,6 @@ testQAPISchemaObjectDeviceAdd(const void *opaque)
 return -1;
 }

-if (virQEMUQAPISchemaPathGet("object-add/arg-type", schema, ) < 0) {
-fprintf(stderr, "schema for 'objectadd' not found\n");
-return -1;
-}
-
-if (testQEMUSchemaEntryMatchTemplate(entry,
- "str:qom-type",
- "str:id",
- "any:props",
- NULL) < 0) {
-VIR_TEST_VERBOSE("object-add has unexpected members in schema");
-return -1;
-}
-
 return 0;
 }

-- 
2.29.2



[PATCH v2 01/12] qemu: command: Generate commandline of 'masterKey0' secret via JSON

2021-02-24 Thread Peter Krempa
While the 'masterKey0' secret object will never be hotplugged we want to
generate it through JSON so that we'll be able to validate all
parameters of '-object' against the QAPI schema once 'object-add' is
qapified in qemu.

Signed-off-by: Peter Krempa 
---
 src/qemu/qemu_command.c | 12 ++--
 1 file changed, 10 insertions(+), 2 deletions(-)

diff --git a/src/qemu/qemu_command.c b/src/qemu/qemu_command.c
index f255b0f881..9538bc9a2a 100644
--- a/src/qemu/qemu_command.c
+++ b/src/qemu/qemu_command.c
@@ -195,6 +195,7 @@ qemuBuildMasterKeyCommandLine(virCommandPtr cmd,
 g_autofree char *alias = NULL;
 g_autofree char *path = NULL;
 g_auto(virBuffer) buf = VIR_BUFFER_INITIALIZER;
+g_autoptr(virJSONValue) props = NULL;

 /* If the -object secret does not exist, then just return. This just
  * means the domain won't be able to use a secret master key and is
@@ -216,9 +217,16 @@ qemuBuildMasterKeyCommandLine(virCommandPtr cmd,
 if (!(path = qemuDomainGetMasterKeyFilePath(priv->libDir)))
 return -1;

+if (qemuMonitorCreateObjectProps(, "secret", alias,
+ "s:format", "raw",
+ "s:file", path,
+ NULL) < 0)
+return -1;
+
+if (virQEMUBuildObjectCommandlineFromJSON(, props) < 0)
+return -1;
+
 virCommandAddArg(cmd, "-object");
-virBufferAsprintf(, "secret,id=%s,format=raw,file=", alias);
-virQEMUBuildBufferEscapeComma(, path);
 virCommandAddArgBuffer(cmd, );

 return 0;
-- 
2.29.2



[PATCH v2 08/12] qemuMonitorCreateObjectPropsWrap: Open-code in qemuBuildMemoryBackendProps

2021-02-24 Thread Peter Krempa
There's just one caller left. Since qemuBuildMemoryBackendProps is too
complex to be modified for now, just move the adding of 'id' and 'qom'
type directly into the function.

Signed-off-by: Peter Krempa 
---
 src/qemu/qemu_command.c |  6 --
 src/qemu/qemu_monitor.c | 15 ---
 src/qemu/qemu_monitor.h |  4 
 3 files changed, 4 insertions(+), 21 deletions(-)

diff --git a/src/qemu/qemu_command.c b/src/qemu/qemu_command.c
index c4bb6a87bb..31b20a4f12 100644
--- a/src/qemu/qemu_command.c
+++ b/src/qemu/qemu_command.c
@@ -3284,10 +3284,12 @@ qemuBuildMemoryBackendProps(virJSONValuePtr 
*backendProps,
 rc = 0;
 }

-if (!(*backendProps = qemuMonitorCreateObjectPropsWrap(backendType, alias,
-   )))
+if (virJSONValueObjectPrependString(props, "id", alias) < 0 ||
+virJSONValueObjectPrependString(props, "qom-type", backendType) < 0)
 return -1;

+*backendProps = g_steal_pointer();
+
 return rc;
 }

diff --git a/src/qemu/qemu_monitor.c b/src/qemu/qemu_monitor.c
index 8b88c8f922..121c21be5c 100644
--- a/src/qemu/qemu_monitor.c
+++ b/src/qemu/qemu_monitor.c
@@ -3010,21 +3010,6 @@ qemuMonitorAddDeviceArgs(qemuMonitorPtr mon,
 }


-virJSONValuePtr
-qemuMonitorCreateObjectPropsWrap(const char *type,
- const char *alias,
- virJSONValuePtr *props)
-{
-
-if (virJSONValueObjectPrependString(*props, "id", alias) < 0 ||
-virJSONValueObjectPrependString(*props, "qom-type", type))
-return NULL;
-
-return g_steal_pointer(props);
-}
-
-
-
 /**
  * qemuMonitorCreateObjectProps:
  * @propsret: returns full object properties
diff --git a/src/qemu/qemu_monitor.h b/src/qemu/qemu_monitor.h
index d25c26343a..c6ffd51ce8 100644
--- a/src/qemu/qemu_monitor.h
+++ b/src/qemu/qemu_monitor.h
@@ -1006,10 +1006,6 @@ int qemuMonitorAddDeviceWithFd(qemuMonitorPtr mon,
 int qemuMonitorDelDevice(qemuMonitorPtr mon,
  const char *devalias);

-virJSONValuePtr qemuMonitorCreateObjectPropsWrap(const char *type,
- const char *alias,
- virJSONValuePtr *props);
-
 int qemuMonitorCreateObjectProps(virJSONValuePtr *propsret,
  const char *type,
  const char *alias,
-- 
2.29.2



[PATCH v2 11/12] tests: qemucapabilities: Update qemu caps for object-add qapification

2021-02-24 Thread Peter Krempa
qemu qapified object-add, which means that it's introspectable via
query-qmp-schema. Update the qemu-6.0 capabilities to commit
XX

TODO: update to pushed version
---
 .../caps_6.0.0.x86_64.replies | 3238 -
 .../caps_6.0.0.x86_64.xml |   83 +-
 2 files changed, 2471 insertions(+), 850 deletions(-)

diff --git a/tests/qemucapabilitiesdata/caps_6.0.0.x86_64.replies 
b/tests/qemucapabilitiesdata/caps_6.0.0.x86_64.replies
index 04ebd04583..d878522c75 100644
--- a/tests/qemucapabilitiesdata/caps_6.0.0.x86_64.replies
+++ b/tests/qemucapabilitiesdata/caps_6.0.0.x86_64.replies
@@ -21,7 +21,7 @@
   "minor": 2,
   "major": 5
 },
-"package": "v5.2.0-2208-gc79f01c945"
+"package": "v5.2.0-2362-g25fa357a8e"
   },
   "id": "libvirt-2"
 }
@@ -45,9 +45,6 @@

 {
   "return": [
-{
-  "name": "object-add"
-},
 {
   "name": "device_add"
 },
@@ -210,6 +207,9 @@
 {
   "name": "object-del"
 },
+{
+  "name": "object-add"
+},
 {
   "name": "qom-list-properties"
 },
@@ -667,6 +667,10 @@
   "name": "vhost-user-vsock-device",
   "parent": "vhost-vsock-common"
 },
+{
+  "name": "virtio-blk-pci-transitional",
+  "parent": "virtio-blk-pci-base"
+},
 {
   "name": "pcie-pci-bridge",
   "parent": "base-pci-bridge"
@@ -675,6 +679,10 @@
   "name": "pc-q35-2.11-machine",
   "parent": "generic-pc-machine"
 },
+{
+  "name": "virtio-crypto-device",
+  "parent": "virtio-device"
+},
 {
   "name": "isa-applesmc",
   "parent": "isa-device"
@@ -692,35 +700,35 @@
   "parent": "bus"
 },
 {
-  "name": "virtio-crypto-device",
-  "parent": "virtio-device"
+  "name": "Denverton-x86_64-cpu",
+  "parent": "x86_64-cpu"
 },
 {
   "name": "chardev-testdev",
   "parent": "chardev"
 },
 {
-  "name": "Denverton-x86_64-cpu",
-  "parent": "x86_64-cpu"
+  "name": "usb-wacom-tablet",
+  "parent": "usb-device"
 },
 {
-  "name": "pci-ipmi-bt",
-  "parent": "pci-device"
+  "name": "Icelake-Server-v1-x86_64-cpu",
+  "parent": "x86_64-cpu"
 },
 {
-  "name": "sev-guest",
-  "parent": "confidential-guest-support"
+  "name": "chardev-stdio",
+  "parent": "chardev-fd"
 },
 {
-  "name": "usb-redir",
-  "parent": "usb-device"
+  "name": "pci-ipmi-bt",
+  "parent": "pci-device"
 },
 {
   "name": "filter-buffer",
   "parent": "netfilter"
 },
 {
-  "name": "usb-wacom-tablet",
+  "name": "usb-redir",
   "parent": "usb-device"
 },
 {
@@ -732,8 +740,8 @@
   "parent": "pci-vga"
 },
 {
-  "name": "virtio-blk-pci-transitional",
-  "parent": "virtio-blk-pci-base"
+  "name": "kvm-pit",
+  "parent": "pit-common"
 },
 {
   "name": "Haswell-v1-x86_64-cpu",
@@ -756,8 +764,8 @@
   "parent": "generic-pc-machine"
 },
 {
-  "name": "kvm-pit",
-  "parent": "pit-common"
+  "name": "sev-guest",
+  "parent": "confidential-guest-support"
 },
 {
   "name": "ich9-usb-uhci5",
@@ -812,8 +820,8 @@
   "parent": "usb-device"
 },
 {
-  "name": "chardev-serial",
-  "parent": "chardev-fd"
+  "name": "chardev-pty",
+  "parent": "chardev"
 },
 {
   "name": "virtio-blk-device",
@@ -848,8 +856,8 @@
   "parent": "generic-pc-machine"
 },
 {
-  "name": "chardev-pty",
-  "parent": "chardev"
+  "name": "chardev-serial",
+  "parent": "chardev-fd"
 },
 {
   "name": "qtest-accel",
@@ -979,14 +987,14 @@
   "name": "pci-ipmi-kcs",
   "parent": "pci-device"
 },
-{
-  "name": "intel-iommu-iommu-memory-region",
-  "parent": "qemu:iommu-memory-region"
-},
 {
   "name": "xio3130-downstream",
   "parent": "pcie-slot"
 },
+{
+  "name": "intel-iommu-iommu-memory-region",
+  "parent": "qemu:iommu-memory-region"
+},
 {
   "name": "vhost-user-vsock-pci-non-transitional",
   "parent": "vhost-user-vsock-pci-base"
@@ -995,14 +1003,14 @@
   "name": "pc-i440fx-2.3-machine",
   "parent": "generic-pc-machine"
 },
-{
-  "name": "PCI",
-  "parent": "bus"
-},
 {
   "name": "microvm-machine",
   "parent": "x86-machine"
 },
+{
+  "name": "PCI",
+  "parent": "bus"
+},
 {
   "name": "sdhci-bus",
   "parent": "sd-bus"
@@ -1104,8 +1112,8 @@
   "parent": "pci-device"
 },
 {
-  "name": "virtio-input-host-pci",
-  "parent": "virtio-input-host-pci-base-type"
+  "name": "virtio-9p-pci-transitional",
+  "parent": "virtio-9p-pci-base"
 },
 {
   "name": "nvdimm",
@@ -1116,8 +1124,8 @@
   "parent": "generic-pc-machine"
 },
 {
-  "name": "virtio-9p-pci-transitional",
-  "parent": "virtio-9p-pci-base"
+  

[PATCH v2 05/12] tests: qemuxml2argv: Validate generation of JSON props for object-add

2021-02-24 Thread Peter Krempa
Similarly to the validation for blockdev-add and netdev_add, use the
qemuxml2argv test repository to drive validation of props for
object-add.

Signed-off-by: Peter Krempa 
---
 tests/qemuxml2argvtest.c | 20 
 1 file changed, 20 insertions(+)

diff --git a/tests/qemuxml2argvtest.c b/tests/qemuxml2argvtest.c
index d6d707cd24..a5e40c218a 100644
--- a/tests/qemuxml2argvtest.c
+++ b/tests/qemuxml2argvtest.c
@@ -527,6 +527,7 @@ testCompareXMLToArgvValidateSchema(virQEMUDriverPtr drv,
 g_autoptr(virCommand) cmd = NULL;
 unsigned int parseFlags = info->parseFlags;
 bool netdevQAPIfied = false;
+bool objectQAPIfied = false;

 /* comment out with line comment to enable schema checking for non _CAPS 
tests
 if (!info->schemafile)
@@ -570,6 +571,7 @@ testCompareXMLToArgvValidateSchema(virQEMUDriverPtr drv,
 return -1;

 netdevQAPIfied = 
!virQEMUQAPISchemaPathExists("netdev_add/arg-type/type/!string", schema);
+objectQAPIfied = 
virQEMUQAPISchemaPathExists("object-add/arg-type/qom-type/^secret", schema);

 for (i = 0; i < nargs; i++) {
 g_auto(virBuffer) debug = VIR_BUFFER_INITIALIZER;
@@ -603,6 +605,24 @@ testCompareXMLToArgvValidateSchema(virQEMUDriverPtr drv,
 return -1;
 }

+i++;
+} else if (STREQ(args[i], "-object")) {
+
+if (!objectQAPIfied) {
+i++;
+continue;
+}
+
+if (!(jsonargs = virJSONValueFromString(args[i + 1])))
+return -1;
+
+if (testQEMUSchemaValidateCommand("object-add", jsonargs,
+  schema, false, false, ) < 
0) {
+VIR_TEST_VERBOSE("failed to validate -object '%s' against QAPI 
schema: %s",
+ args[i + 1], virBufferCurrentContent());
+return -1;
+}
+
 i++;
 }
 }
-- 
2.29.2



[PATCH v2 07/12] qemu: monitor: Make wrapping of 'props' of 'object-add' optional

2021-02-24 Thread Peter Krempa
Construct the JSON object which is used for object-add without the
'props' wrapper and add the wrapper only in the monitor code.

This simplifies the JSON->commandline generator in the first place and
also prepares for upcoming qemu where 'props' will be removed.

Signed-off-by: Peter Krempa 
---
 src/qemu/qemu_monitor.c | 68 +
 src/util/virqemu.c  | 42 +
 2 files changed, 62 insertions(+), 48 deletions(-)

diff --git a/src/qemu/qemu_monitor.c b/src/qemu/qemu_monitor.c
index ed35da17e1..8b88c8f922 100644
--- a/src/qemu/qemu_monitor.c
+++ b/src/qemu/qemu_monitor.c
@@ -109,6 +109,9 @@ struct _qemuMonitor {
 qemuMonitorReportDomainLogError logFunc;
 void *logOpaque;
 virFreeCallback logDestroy;
+
+/* true if qemu no longer wants 'props' sub-object of object-add */
+bool objectAddNoWrap;
 };

 /**
@@ -3012,14 +3015,12 @@ qemuMonitorCreateObjectPropsWrap(const char *type,
  const char *alias,
  virJSONValuePtr *props)
 {
-virJSONValuePtr ret;

-ignore_value(virJSONValueObjectCreate(,
-  "s:qom-type", type,
-  "s:id", alias,
-  "A:props", props,
-  NULL));
-return ret;
+if (virJSONValueObjectPrependString(*props, "id", alias) < 0 ||
+virJSONValueObjectPrependString(*props, "qom-type", type))
+return NULL;
+
+return g_steal_pointer(props);
 }


@@ -3039,26 +3040,28 @@ qemuMonitorCreateObjectProps(virJSONValuePtr *propsret,
  const char *alias,
  ...)
 {
-virJSONValuePtr props = NULL;
-int ret = -1;
+g_autoptr(virJSONValue) props = NULL;
+int rc;
 va_list args;

-*propsret = NULL;
+if (virJSONValueObjectCreate(,
+ "s:qom-type", type,
+ "s:id", alias,
+ NULL) < 0)
+return -1;
+

 va_start(args, alias);

-if (virJSONValueObjectCreateVArgs(, args) < 0)
-goto cleanup;
+rc = virJSONValueObjectAddVArgs(props, args);

-if (!(*propsret = qemuMonitorCreateObjectPropsWrap(type, alias, )))
-goto cleanup;
+va_end(args);

-ret = 0;
+if (rc < 0)
+return -1;

- cleanup:
-virJSONValueFree(props);
-va_end(args);
-return ret;
+*propsret = g_steal_pointer();
+return 0;
 }


@@ -3078,6 +3081,7 @@ qemuMonitorAddObject(qemuMonitorPtr mon,
  virJSONValuePtr *props,
  char **alias)
 {
+g_autoptr(virJSONValue) pr = NULL;
 const char *type = NULL;
 const char *id = NULL;
 g_autofree char *aliasCopy = NULL;
@@ -3105,7 +3109,31 @@ qemuMonitorAddObject(qemuMonitorPtr mon,
 if (alias)
 aliasCopy = g_strdup(id);

-if (qemuMonitorJSONAddObject(mon, props) < 0)
+if (mon->objectAddNoWrap) {
+pr = g_steal_pointer(props);
+} else {
+/* we need to create a wrapper which has the 'qom-type' and 'id' and
+ * store everything else under a 'props' sub-object */
+g_autoptr(virJSONValue) typeobj = NULL;
+g_autoptr(virJSONValue) idobj = NULL;
+
+ignore_value(virJSONValueObjectRemoveKey(*props, "qom-type", 
));
+ignore_value(virJSONValueObjectRemoveKey(*props, "id", ));
+
+if (!virJSONValueObjectGetKey(*props, 0)) {
+virJSONValueFree(*props);
+*props = NULL;
+}
+
+if (virJSONValueObjectCreate(,
+ "s:qom-type", type,
+ "s:id", id,
+ "A:props", props,
+ NULL) < 0)
+return -1;
+}
+
+if (qemuMonitorJSONAddObject(mon, ) < 0)
 return -1;

 if (alias)
diff --git a/src/util/virqemu.c b/src/util/virqemu.c
index c420b144e1..5fe142394c 100644
--- a/src/util/virqemu.c
+++ b/src/util/virqemu.c
@@ -303,32 +303,6 @@ virQEMUBuildNetdevCommandlineFromJSON(virJSONValuePtr 
props,
 }


-static int
-virQEMUBuildObjectCommandlineFromJSONInternal(virBufferPtr buf,
-  const char *type,
-  const char *alias,
-  virJSONValuePtr props)
-{
-if (!type || !alias) {
-virReportError(VIR_ERR_INTERNAL_ERROR,
-   _("missing 'type'(%s) or 'alias'(%s) field of QOM 
'object'"),
-   NULLSTR(type), NULLSTR(alias));
-return -1;
-}
-
-virBufferAsprintf(buf, "%s,id=%s", type, alias);
-
-if (props) {
-virBufferAddLit(buf, ",");
-if (virQEMUBuildCommandLineJSON(props, buf, NULL,
-

[PATCH v2 00/12] qemu: Prepare for QAPIfied object-add

2021-02-24 Thread Peter Krempa
QEMU plans to QAPIfy object add. This series prepares for the API change
(drop of 'props' wrapper for the object) and adds testing based on our
qemuxml2argv test data which forces the output to JSON and validates it
agains the schema.

Based on Kevin's qemu patches:
https://listman.redhat.com/archives/libvir-list/2021-February/msg01168.html

Last patch forces more files to be processed and as the summary suggest
will not be pushed.

The patch updating qemucapabilitiesdata will be updated after Kevin's
patches hit upstream repo.

Peter Krempa (12):
  qemu: command: Generate commandline of 'masterKey0' secret via JSON
  qemu: command: Generate commandline of 'sev0' sev-guest object via
JSON
  qemu: command: Generate commandline of iothread objects JSON
  qemu: capabilities: Introduce QEMU_CAPS_OBJECT_QAPIFIED
  tests: qemuxml2argv: Validate generation of JSON props for object-add
  qemu: command: Introduce raw JSON passthrough for '-object' for
testing
  qemu: monitor: Make wrapping of 'props' of 'object-add' optional
  qemuMonitorCreateObjectPropsWrap: Open-code in
qemuBuildMemoryBackendProps
  qemu: monitor: Don't add 'props' wrapper if qemu has
QEMU_CAPS_OBJECT_QAPIFIED
  qemumonitorjsontest: Remove bomb guarding object-add
  tests: qemucapabilities: Update qemu caps for object-add qapification
  [DON'T PUSH] Force-check all configs with latest capabilities

 src/qemu/qemu_capabilities.c  |4 +
 src/qemu/qemu_capabilities.h  |3 +
 src/qemu/qemu_command.c   |  326 +-
 src/qemu/qemu_monitor.c   |   78 +-
 src/qemu/qemu_monitor.h   |4 -
 src/util/virqemu.c|   48 +-
 src/util/virqemu.h|3 +-
 .../caps_6.0.0.x86_64.replies | 3238 -
 .../caps_6.0.0.x86_64.xml |   83 +-
 tests/qemumonitorjsontest.c   |   14 -
 ...v-missing-platform-info.x86_64-2.12.0.args |2 +-
 .../launch-security-sev.x86_64-2.12.0.args|2 +-
 tests/qemuxml2argvtest.c  |   24 +-
 13 files changed, 2775 insertions(+), 1054 deletions(-)

-- 
2.29.2



[PATCH v2 09/12] qemu: monitor: Don't add 'props' wrapper if qemu has QEMU_CAPS_OBJECT_QAPIFIED

2021-02-24 Thread Peter Krempa
Set 'objectAddNoWrap' when the capability is present.

Signed-off-by: Peter Krempa 
---
 src/qemu/qemu_monitor.c | 5 +
 1 file changed, 5 insertions(+)

diff --git a/src/qemu/qemu_monitor.c b/src/qemu/qemu_monitor.c
index 121c21be5c..1e4c4809b1 100644
--- a/src/qemu/qemu_monitor.c
+++ b/src/qemu/qemu_monitor.c
@@ -32,6 +32,7 @@
 #include "qemu_monitor_json.h"
 #include "qemu_domain.h"
 #include "qemu_process.h"
+#include "qemu_capabilities.h"
 #include "virerror.h"
 #include "viralloc.h"
 #include "virlog.h"
@@ -672,6 +673,7 @@ qemuMonitorOpenInternal(virDomainObjPtr vm,
 qemuMonitorCallbacksPtr cb,
 void *opaque)
 {
+qemuDomainObjPrivatePtr priv = vm->privateData;
 qemuMonitorPtr mon;
 g_autoptr(GError) gerr = NULL;

@@ -704,6 +706,9 @@ qemuMonitorOpenInternal(virDomainObjPtr vm,
 mon->cb = cb;
 mon->callbackOpaque = opaque;

+if (priv)
+mon->objectAddNoWrap = virQEMUCapsGet(priv->qemuCaps, 
QEMU_CAPS_OBJECT_QAPIFIED);
+
 if (virSetCloseExec(mon->fd) < 0) {
 virReportError(VIR_ERR_INTERNAL_ERROR,
"%s", _("Unable to set monitor close-on-exec flag"));
-- 
2.29.2



Re: [PATCH v2 28/31] hmp: QAPIfy object_add

2021-02-24 Thread Dr. David Alan Gilbert
* Kevin Wolf (kw...@redhat.com) wrote:
> This switches the HMP command object_add from a QemuOpts-based parser to
> user_creatable_add_from_str() which uses a keyval parser and enforces
> the QAPI schema.
> 
> Apart from being a cleanup, this makes non-scalar properties and help
> accessible. In order for help to be printed to the monitor instead of
> stdout, the printf() calls in the help functions are changed to
> qemu_printf().
> 
> Signed-off-by: Kevin Wolf 

Reviewed-by: Dr. David Alan Gilbert 

> ---
>  monitor/hmp-cmds.c  | 17 ++---
>  qom/object_interfaces.c | 11 ++-
>  hmp-commands.hx |  2 +-
>  3 files changed, 9 insertions(+), 21 deletions(-)
> 
> diff --git a/monitor/hmp-cmds.c b/monitor/hmp-cmds.c
> index 3c88a4faef..652cf9ff21 100644
> --- a/monitor/hmp-cmds.c
> +++ b/monitor/hmp-cmds.c
> @@ -1670,24 +1670,11 @@ void hmp_netdev_del(Monitor *mon, const QDict *qdict)
>  
>  void hmp_object_add(Monitor *mon, const QDict *qdict)
>  {
> +const char *options = qdict_get_str(qdict, "object");
>  Error *err = NULL;
> -QemuOpts *opts;
> -Object *obj = NULL;
> -
> -opts = qemu_opts_from_qdict(qemu_find_opts("object"), qdict, );
> -if (err) {
> -goto end;
> -}
>  
> -obj = user_creatable_add_opts(opts, );
> -qemu_opts_del(opts);
> -
> -end:
> +user_creatable_add_from_str(options, );
>  hmp_handle_error(mon, err);
> -
> -if (obj) {
> -object_unref(obj);
> -}
>  }
>  
>  void hmp_getfd(Monitor *mon, const QDict *qdict)
> diff --git a/qom/object_interfaces.c b/qom/object_interfaces.c
> index 54f0dadfea..c4982dd7a0 100644
> --- a/qom/object_interfaces.c
> +++ b/qom/object_interfaces.c
> @@ -13,6 +13,7 @@
>  #include "qemu/help_option.h"
>  #include "qemu/module.h"
>  #include "qemu/option.h"
> +#include "qemu/qemu-print.h"
>  #include "qapi/opts-visitor.h"
>  #include "qemu/config-file.h"
>  
> @@ -212,11 +213,11 @@ static void user_creatable_print_types(void)
>  {
>  GSList *l, *list;
>  
> -printf("List of user creatable objects:\n");
> +qemu_printf("List of user creatable objects:\n");
>  list = object_class_get_list_sorted(TYPE_USER_CREATABLE, false);
>  for (l = list; l != NULL; l = l->next) {
>  ObjectClass *oc = OBJECT_CLASS(l->data);
> -printf("  %s\n", object_class_get_name(oc));
> +qemu_printf("  %s\n", object_class_get_name(oc));
>  }
>  g_slist_free(list);
>  }
> @@ -247,12 +248,12 @@ static bool user_creatable_print_type_properites(const 
> char *type)
>  }
>  g_ptr_array_sort(array, (GCompareFunc)qemu_pstrcmp0);
>  if (array->len > 0) {
> -printf("%s options:\n", type);
> +qemu_printf("%s options:\n", type);
>  } else {
> -printf("There are no options for %s.\n", type);
> +qemu_printf("There are no options for %s.\n", type);
>  }
>  for (i = 0; i < array->len; i++) {
> -printf("%s\n", (char *)array->pdata[i]);
> +qemu_printf("%s\n", (char *)array->pdata[i]);
>  }
>  g_ptr_array_set_free_func(array, g_free);
>  g_ptr_array_free(array, true);
> diff --git a/hmp-commands.hx b/hmp-commands.hx
> index d4001f9c5d..6f5d9ce2fb 100644
> --- a/hmp-commands.hx
> +++ b/hmp-commands.hx
> @@ -1337,7 +1337,7 @@ ERST
>  
>  {
>  .name   = "object_add",
> -.args_type  = "object:O",
> +.args_type  = "object:S",
>  .params = "[qom-type=]type,id=str[,prop=value][,...]",
>  .help   = "create QOM object",
>  .cmd= hmp_object_add,
> -- 
> 2.29.2
> 
-- 
Dr. David Alan Gilbert / dgilb...@redhat.com / Manchester, UK



Re: [PATCH v2 16/31] qapi/qom: Add ObjectOptions for confidential-guest-support

2021-02-24 Thread Dr. David Alan Gilbert
* Kevin Wolf (kw...@redhat.com) wrote:
> This adds a QAPI schema for the properties of the objects implementing
> the confidential-guest-support interface.
> 
> pef-guest and s390x-pv-guest don't have any properties, so they only
> need to be added to the ObjectType enum without adding a new branch to
> ObjectOptions.
> 
> Signed-off-by: Kevin Wolf 
> ---
>  qapi/qom.json | 37 +
>  1 file changed, 37 insertions(+)
> 
> diff --git a/qapi/qom.json b/qapi/qom.json
> index e7184122e9..d5f68b5c89 100644
> --- a/qapi/qom.json
> +++ b/qapi/qom.json
> @@ -633,6 +633,38 @@
>'base': 'RngProperties',
>'data': { '*filename': 'str' } }
>  
> +##
> +# @SevGuestProperties:
> +#
> +# Properties for sev-guest objects.
> +#
> +# @sev-device: SEV device to use (default: "/dev/sev")
> +#
> +# @dh-cert-file: guest owners DH certificate (encoded with base64)
> +#
> +# @session-file: guest owners session parameters (encoded with base64)
> +#
> +# @policy: SEV policy value (default: 0x1)
> +#
> +# @handle: SEV firmware handle (default: 0)
> +#
> +# @cbitpos: C-bit location in page table entry (default: 0)
> +#
> +# @reduced-phys-bits: number of bits in physical addresses that become
> +# unavailable when SEV is enabled
> +#
> +# Since: 2.12
> +##
> +{ 'struct': 'SevGuestProperties',
> +  'data': { '*sev-device': 'str',
> +'*dh-cert-file': 'str',
> +'*session-file': 'str',
> +'*policy': 'uint32',
> +'*handle': 'uint32',
> +'*cbitpos': 'uint32',
> +'reduced-phys-bits': 'uint32' },
> +  'if': 'defined(CONFIG_SEV)' }
> +
>  ##
>  # @ObjectType:
>  #
> @@ -661,12 +693,15 @@
>  'memory-backend-file',
>  'memory-backend-memfd',
>  'memory-backend-ram',
> +{'name': 'pef-guest', 'if': 'defined(CONFIG_PSERIES)' },
>  'pr-manager-helper',
>  'rng-builtin',
>  'rng-egd',
>  'rng-random',
>  'secret',
>  'secret_keyring',
> +{'name': 'sev-guest', 'if': 'defined(CONFIG_SEV)' },
> +'s390-pv-guest',

If pef-guest is conditional on PSERIES< shouldn't this be dependent on
s390?

Dave

>  'throttle-group',
>  'tls-creds-anon',
>  'tls-creds-psk',
> @@ -716,6 +751,8 @@
>'rng-random': 'RngRandomProperties',
>'secret': 'SecretProperties',
>'secret_keyring': 'SecretKeyringProperties',
> +  'sev-guest':  { 'type': 'SevGuestProperties',
> +  'if': 'defined(CONFIG_SEV)' },
>'throttle-group': 'ThrottleGroupProperties',
>'tls-creds-anon': 'TlsCredsAnonProperties',
>'tls-creds-psk':  'TlsCredsPskProperties',
> -- 
> 2.29.2
> 
-- 
Dr. David Alan Gilbert / dgilb...@redhat.com / Manchester, UK



Re: [PATCH 00/14] deprecations: remove many old deprecations

2021-02-24 Thread Philippe Mathieu-Daudé
On 2/24/21 3:38 PM, Peter Maydell wrote:
> On Wed, 24 Feb 2021 at 13:21, Daniel P. Berrangé  wrote:
>>
>> The following features have been deprecated for well over the 2
>> release cycle we promise
>>
>>   ``-usbdevice`` (since 2.10.0)
>>   ``-drive file=3Djson:{...{'driver':'file'}}`` (since 3.0)
>>   ``-vnc acl`` (since 4.0.0)
>>   ``-mon ...,control=3Dreadline,pretty=3Don|off`` (since 4.1)
> 
> Are the literal '=3D' here intended ?

No, this is a git-publish bug:
https://github.com/stefanha/git-publish/issues/88

Apparently the fix is not yet backported to Fedora.



Re: [PATCH 00/14] deprecations: remove many old deprecations

2021-02-24 Thread Daniel P . Berrangé
On Wed, Feb 24, 2021 at 02:38:43PM +, Peter Maydell wrote:
> On Wed, 24 Feb 2021 at 13:21, Daniel P. Berrangé  wrote:
> >
> > The following features have been deprecated for well over the 2
> > release cycle we promise
> >
> >   ``-usbdevice`` (since 2.10.0)
> >   ``-drive file=3Djson:{...{'driver':'file'}}`` (since 3.0)
> >   ``-vnc acl`` (since 4.0.0)
> >   ``-mon ...,control=3Dreadline,pretty=3Don|off`` (since 4.1)
> 
> Are the literal '=3D' here intended ?

git-publish has done something wierd to the cover letter encoding that
I don't understand.


Regards,
Daniel
-- 
|: https://berrange.com  -o-https://www.flickr.com/photos/dberrange :|
|: https://libvirt.org -o-https://fstop138.berrange.com :|
|: https://entangle-photo.org-o-https://www.instagram.com/dberrange :|



Re: [PATCH 11/14] block: remove 'encryption_key_missing' flag from QAPI

2021-02-24 Thread Thomas Huth

On 24/02/2021 14.11, Daniel P. Berrangé wrote:

This has been hardcoded to "false" since 2.10.0, since secrets required
to unlock block devices are now always provided upfront instead of using
interactive prompts.

Signed-off-by: Daniel P. Berrangé 
---
  block/qapi.c |  1 -
  docs/system/deprecated.rst   | 10 ---
  docs/system/removed-features.rst | 10 +++
  qapi/block-core.json |  8 --
  tests/qemu-iotests/184.out   |  6 ++--
  tests/qemu-iotests/191.out   | 48 +++-
  tests/qemu-iotests/273.out   | 15 --
  7 files changed, 33 insertions(+), 65 deletions(-)

diff --git a/block/qapi.c b/block/qapi.c
index 84a0aadc09..3acc118c44 100644
--- a/block/qapi.c
+++ b/block/qapi.c
@@ -62,7 +62,6 @@ BlockDeviceInfo *bdrv_block_device_info(BlockBackend *blk,
  info->ro = bs->read_only;
  info->drv= g_strdup(bs->drv->format_name);
  info->encrypted  = bs->encrypted;
-info->encryption_key_missing = false;
  
  info->cache = g_new(BlockdevCacheInfo, 1);

  *info->cache = (BlockdevCacheInfo) {
diff --git a/docs/system/deprecated.rst b/docs/system/deprecated.rst
index cb88fea94f..e746a63edf 100644
--- a/docs/system/deprecated.rst
+++ b/docs/system/deprecated.rst
@@ -147,16 +147,6 @@ Use argument ``id`` instead.
  
  Use argument ``id`` instead.
  
-``query-named-block-nodes`` result ``encryption_key_missing`` (since 2.10.0)

-
-
-Always false.
-
-``query-block`` result ``inserted.encryption_key_missing`` (since 2.10.0)
-'
-
-Always false.
-
  ``blockdev-add`` empty string argument ``backing`` (since 2.10.0)
  '
  
diff --git a/docs/system/removed-features.rst b/docs/system/removed-features.rst

index bb6bc8dfc8..583f14f02e 100644
--- a/docs/system/removed-features.rst
+++ b/docs/system/removed-features.rst
@@ -112,6 +112,16 @@ chardev client socket with ``wait`` option (removed in 6.0)
  Character devices creating sockets in client mode should not specify
  the 'wait' field, which is only applicable to sockets in server mode
  
+``query-named-block-nodes`` result ``encryption_key_missing`` (removed in 6.0)

+''
+
+Always false.


Should that be "Removed with no replacement", too ? (just like the one below)


+``query-block`` result ``inserted.encryption_key_missing`` (removed in 6.0)
+'''
+
+Removed with no replacement
+


Apart from that nit:
Reviewed-by: Thomas Huth 



Re: [PATCH 00/14] deprecations: remove many old deprecations

2021-02-24 Thread Peter Maydell
On Wed, 24 Feb 2021 at 13:21, Daniel P. Berrangé  wrote:
>
> The following features have been deprecated for well over the 2
> release cycle we promise
>
>   ``-usbdevice`` (since 2.10.0)
>   ``-drive file=3Djson:{...{'driver':'file'}}`` (since 3.0)
>   ``-vnc acl`` (since 4.0.0)
>   ``-mon ...,control=3Dreadline,pretty=3Don|off`` (since 4.1)

Are the literal '=3D' here intended ?


thanks
-- PMM




Re: [PATCH 10/14] hw/scsi: remove 'scsi-disk' device

2021-02-24 Thread Thomas Huth

On 24/02/2021 14.11, Daniel P. Berrangé wrote:

The 'scsi-hd' and 'scsi-cd' devices provide suitable alternatives.

Signed-off-by: Daniel P. Berrangé 
---
  docs/system/deprecated.rst   |  9 -
  docs/system/removed-features.rst |  6 
  hw/i386/pc.c |  1 -
  hw/scsi/scsi-disk.c  | 62 
  hw/sparc64/sun4u.c   |  1 -
  scripts/device-crash-test|  1 -
  tests/qemu-iotests/051   |  2 --
  tests/qemu-iotests/051.pc.out| 10 --
  8 files changed, 6 insertions(+), 86 deletions(-)


I see some occurrances of "scsi-disk" in the config files in the 
docs/config/ directory, too ... I guess they should also be removed?



diff --git a/hw/sparc64/sun4u.c b/hw/sparc64/sun4u.c
index d7c27144ba..cda7df36e3 100644
--- a/hw/sparc64/sun4u.c
+++ b/hw/sparc64/sun4u.c
@@ -749,7 +749,6 @@ static char *sun4u_fw_dev_path(FWPathProvider *p, BusState 
*bus,
 DeviceState *dev)
  {
  PCIDevice *pci;
-int bus_id;
  
  if (!strcmp(object_get_typename(OBJECT(dev)), "pbm-bridge")) {

  pci = PCI_DEVICE(dev);


This lonely hunk should be squashed into the previous (ide-disk) patch instead.

 Thomas



Re: [PATCH 09/14] hw/ide: remove 'ide-drive' device

2021-02-24 Thread Thomas Huth

On 24/02/2021 14.11, Daniel P. Berrangé wrote:

The 'ide-hd' and 'ide-cd' devices provide suitable alternatives.

Signed-off-by: Daniel P. Berrangé 
---
  docs/qdev-device-use.txt |  2 +-
  docs/system/deprecated.rst   |  6 -
  docs/system/removed-features.rst |  9 
  hw/i386/pc.c |  1 -
  hw/ide/qdev.c| 38 
  hw/ppc/mac_newworld.c| 13 ---
  hw/ppc/mac_oldworld.c| 13 ---
  hw/sparc64/sun4u.c   | 14 
  scripts/device-crash-test|  1 -
  softmmu/vl.c |  1 -
  tests/qemu-iotests/051   |  2 --
  tests/qemu-iotests/051.pc.out| 10 -
  12 files changed, 10 insertions(+), 100 deletions(-)

diff --git a/docs/qdev-device-use.txt b/docs/qdev-device-use.txt
index 245cdf29c7..2408889334 100644
--- a/docs/qdev-device-use.txt
+++ b/docs/qdev-device-use.txt
@@ -388,7 +388,7 @@ type.
  some DEVNAMEs:
  
  default device  suppressing DEVNAMEs

-CD-ROM  ide-cd, ide-drive, ide-hd, scsi-cd, scsi-hd
+CD-ROM  ide-cd, ide-hd, scsi-cd, scsi-hd
  floppy  floppy, isa-fdc
  parallelisa-parallel
  serial  isa-serial
diff --git a/docs/system/deprecated.rst b/docs/system/deprecated.rst
index c69887dca8..f5c82a46dc 100644
--- a/docs/system/deprecated.rst
+++ b/docs/system/deprecated.rst
@@ -242,12 +242,6 @@ this CPU is also deprecated.
  System emulator devices
  ---
  
-``ide-drive`` (since 4.2)

-'
-
-The 'ide-drive' device is deprecated. Users should use 'ide-hd' or
-'ide-cd' as appropriate to get an IDE hard disk or CD-ROM as needed.
-
  ``scsi-disk`` (since 4.2)
  '
  
diff --git a/docs/system/removed-features.rst b/docs/system/removed-features.rst

index 870a222062..8fd3fafb32 100644
--- a/docs/system/removed-features.rst
+++ b/docs/system/removed-features.rst
@@ -213,6 +213,15 @@ This machine has been renamed ``fuloong2e``.
  These machine types were very old and likely could not be used for live
  migration from old QEMU versions anymore. Use a newer machine type instead.
  
+System emulator devices

+---
+
+``ide-drive`` (removed in 6.0)
+''
+
+The 'ide-drive' device has been removed. Users should use 'ide-hd' or
+'ide-cd' as appropriate to get an IDE hard disk or CD-ROM as needed.
+
  Related binaries
  
  
diff --git a/hw/i386/pc.c b/hw/i386/pc.c

index 8aa85dec54..828122e21e 100644
--- a/hw/i386/pc.c
+++ b/hw/i386/pc.c
@@ -342,7 +342,6 @@ GlobalProperty pc_compat_1_4[] = {
  { "scsi-disk", "discard_granularity", "0" },
  { "ide-hd", "discard_granularity", "0" },
  { "ide-cd", "discard_granularity", "0" },
-{ "ide-drive", "discard_granularity", "0" },
  { "virtio-blk-pci", "discard_granularity", "0" },
  /* DEV_NVECTORS_UNSPECIFIED as a uint32_t string: */
  { "virtio-serial-pci", "vectors", "0x" },
diff --git a/hw/ide/qdev.c b/hw/ide/qdev.c
index 8cd19fa5e9..e70ebc83a0 100644
--- a/hw/ide/qdev.c
+++ b/hw/ide/qdev.c
@@ -283,20 +283,6 @@ static void ide_cd_realize(IDEDevice *dev, Error **errp)
  ide_dev_initfn(dev, IDE_CD, errp);
  }
  
-static void ide_drive_realize(IDEDevice *dev, Error **errp)

-{
-DriveInfo *dinfo = NULL;
-
-warn_report("'ide-drive' is deprecated, "
-"please use 'ide-hd' or 'ide-cd' instead");
-
-if (dev->conf.blk) {
-dinfo = blk_legacy_dinfo(dev->conf.blk);
-}
-
-ide_dev_initfn(dev, dinfo && dinfo->media_cd ? IDE_CD : IDE_HD, errp);
-}


I wonder whether we now could also make the "media" parameter of "-drive" as 
deprecated?


Anyway, for this patch:
Reviewed-by: Thomas Huth 



Re: [PATCH 04/14] softmmu: remove '-usbdevice' command line option

2021-02-24 Thread Daniel P . Berrangé
On Wed, Feb 24, 2021 at 02:58:19PM +0100, Thomas Huth wrote:
> On 24/02/2021 14.11, Daniel P. Berrangé wrote:
> > This was replaced by the '-device usb-DEV' option.
> > 
> > Signed-off-by: Daniel P. Berrangé 
> > ---
> >   docs/system/deprecated.rst   |  9 ---
> >   docs/system/removed-features.rst |  9 +++
> >   softmmu/vl.c | 42 
> >   3 files changed, 9 insertions(+), 51 deletions(-)
> 
> Last time I tried to remove -usbdevice, there was some concerns that
> -usbdevice braille might still be useful for some people, see the thread
> that started here:
> 
>  https://lists.nongnu.org/archive/html/qemu-devel/2018-01/msg00651.html
> 
> (and Gerd's summary here:
> https://lists.nongnu.org/archive/html/qemu-devel/2018-01/msg01520.html )

Urgh, so the current deprecation docs are a bit misleading by saying
-usbdevice is directly mapped to -device.

> So we might need a new "sugared" option like "-braille" instead before we
> can fully remove -usbdevice? ... or we just keep -usbdevice as a bittersweet
> remainder?

I'm not going to implement new CLI options, and if that's needed, we
ought to re-start the clock on the deprecation at that point. So this
points towards just removing the deprecation warning that exists
today. Or alternatively drop support for -usbdevice, except for the
braille type.

Regards,
Daniel
-- 
|: https://berrange.com  -o-https://www.flickr.com/photos/dberrange :|
|: https://libvirt.org -o-https://fstop138.berrange.com :|
|: https://entangle-photo.org-o-https://www.instagram.com/dberrange :|



[PATCH] qemu_monitor: Document qemuMonitorUnregister()

2021-02-24 Thread Michal Privoznik
The most important bit is that the caller is expected to pass
locked monitor.

Signed-off-by: Michal Privoznik 
---
 src/qemu/qemu_monitor.c | 7 +++
 1 file changed, 7 insertions(+)

diff --git a/src/qemu/qemu_monitor.c b/src/qemu/qemu_monitor.c
index ed35da17e1..73f337a6be 100644
--- a/src/qemu/qemu_monitor.c
+++ b/src/qemu/qemu_monitor.c
@@ -850,6 +850,13 @@ qemuMonitorRegister(qemuMonitorPtr mon)
 }
 
 
+/**
+ * qemuMonitorUnregister:
+ * @mon: monitor object
+ *
+ * Unregister monitor from the event loop. The monitor object
+ * must be locked before calling this function.
+ */
 void
 qemuMonitorUnregister(qemuMonitorPtr mon)
 {
-- 
2.26.2



Re: [PATCH v2] qemu: Add missing lock in qemuProcessHandleMonitorEOF

2021-02-24 Thread Michal Privoznik

On 2/24/21 12:28 PM, Peng Liang wrote:

qemuMonitorUnregister will be called in multiple threads (e.g. threads
in rpc worker pool and the vm event thread).  In some cases, it isn't
protected by the monitor lock, which may lead to call g_source_unref
more than one time and a use-after-free problem eventually.

Add the missing lock in qemuProcessHandleMonitorEOF (which is the only
position missing lock of monitor I found).

Suggested-by: Michal Privoznik 
Signed-off-by: Peng Liang 
---
This patch is v2 of 
https://listman.redhat.com/archives/libvir-list/2021-February/msg00945.html.

v1 -> v2:
Locking monitor in qemuProcessHandleMonitorEOF instead of using aotmic
function in qemuMonitorUnregister.

  src/qemu/qemu_monitor.h | 1 +
  src/qemu/qemu_process.c | 2 ++
  2 files changed, 3 insertions(+)

diff --git a/src/qemu/qemu_monitor.h b/src/qemu/qemu_monitor.h
index d25c26343a7f..14e6b1fe9626 100644
--- a/src/qemu/qemu_monitor.h
+++ b/src/qemu/qemu_monitor.h
@@ -427,6 +427,7 @@ bool qemuMonitorWasDisposed(void);
  
  void qemuMonitorRegister(qemuMonitorPtr mon)

  ATTRIBUTE_NONNULL(1);
+/* Must be called with monitor locked. */
  void qemuMonitorUnregister(qemuMonitorPtr mon)


From this it's not very clear which function the comment belongs to. We 
tend to put comments into .c because that's where tags usually take you 
first. So you get the memo first.



  ATTRIBUTE_NONNULL(1);
  void qemuMonitorClose(qemuMonitorPtr mon);
diff --git a/src/qemu/qemu_process.c b/src/qemu/qemu_process.c
index d930ff9a74f6..bfa742577f32 100644
--- a/src/qemu/qemu_process.c
+++ b/src/qemu/qemu_process.c
@@ -318,7 +318,9 @@ qemuProcessHandleMonitorEOF(qemuMonitorPtr mon,
  /* We don't want this EOF handler to be called over and over while the
   * thread is waiting for a job.
   */
+virObjectLock(mon);
  qemuMonitorUnregister(mon);
+virObjectUnlock(mon);
  
  /* We don't want any cleanup from EOF handler (or any other

   * thread) to enter qemu namespace. */



ACK to this hunk. And I'll be pushing it in a few moments.

Michal



[PATCH v2 31/31] qom: Drop QemuOpts based interfaces

2021-02-24 Thread Kevin Wolf
user_creatable_add_opts() has only a single user left, which is a test
case. Rewrite the test to use user_creatable_add_type() instead (which
is the remaining function that doesn't require a QAPI schema) and drop
the QemuOpts related functions.

Signed-off-by: Kevin Wolf 
---
 include/qom/object_interfaces.h | 59 
 qom/object_interfaces.c | 81 -
 tests/check-qom-proplist.c  | 42 -
 3 files changed, 20 insertions(+), 162 deletions(-)

diff --git a/include/qom/object_interfaces.h b/include/qom/object_interfaces.h
index fb32330901..ac6c33ceac 100644
--- a/include/qom/object_interfaces.h
+++ b/include/qom/object_interfaces.h
@@ -99,51 +99,6 @@ Object *user_creatable_add_type(const char *type, const char 
*id,
  */
 void user_creatable_add_qapi(ObjectOptions *options, Error **errp);
 
-/**
- * user_creatable_add_opts:
- * @opts: the object definition
- * @errp: if an error occurs, a pointer to an area to store the error
- *
- * Create an instance of the user creatable object whose type
- * is defined in @opts by the 'qom-type' option, placing it
- * in the object composition tree with name provided by the
- * 'id' field. The remaining options in @opts are used to
- * initialize the object properties.
- *
- * Returns: the newly created object or NULL on error
- */
-Object *user_creatable_add_opts(QemuOpts *opts, Error **errp);
-
-
-/**
- * user_creatable_add_opts_predicate:
- * @type: the QOM type to be added
- *
- * A callback function to determine whether an object
- * of type @type should be created. Instances of this
- * callback should be passed to user_creatable_add_opts_foreach
- */
-typedef bool (*user_creatable_add_opts_predicate)(const char *type);
-
-/**
- * user_creatable_add_opts_foreach:
- * @opaque: a user_creatable_add_opts_predicate callback or NULL
- * @opts: options to create
- * @errp: unused
- *
- * An iterator callback to be used in conjunction with
- * the qemu_opts_foreach() method for creating a list of
- * objects from a set of QemuOpts
- *
- * The @opaque parameter can be passed a user_creatable_add_opts_predicate
- * callback to filter which types of object are created during iteration.
- * When it fails, report the error.
- *
- * Returns: 0 on success, -1 when an error was reported.
- */
-int user_creatable_add_opts_foreach(void *opaque,
-QemuOpts *opts, Error **errp);
-
 /**
  * user_creatable_parse_str:
  * @optarg: the object definition string as passed on the command line
@@ -190,20 +145,6 @@ bool user_creatable_add_from_str(const char *optarg, Error 
**errp);
  */
 void user_creatable_process_cmdline(const char *optarg);
 
-/**
- * user_creatable_print_help:
- * @type: the QOM type to be added
- * @opts: options to create
- *
- * Prints help if requested in @type or @opts. Note that if @type is neither
- * "help"/"?" nor a valid user creatable type, no help will be printed
- * regardless of @opts.
- *
- * Returns: true if a help option was found and help was printed, false
- * otherwise.
- */
-bool user_creatable_print_help(const char *type, QemuOpts *opts);
-
 /**
  * user_creatable_del:
  * @id: the unique ID for the object
diff --git a/qom/object_interfaces.c b/qom/object_interfaces.c
index 1c29f45b41..25cc54fcd7 100644
--- a/qom/object_interfaces.c
+++ b/qom/object_interfaces.c
@@ -10,12 +10,9 @@
 #include "qapi/qobject-input-visitor.h"
 #include "qapi/qobject-output-visitor.h"
 #include "qom/object_interfaces.h"
-#include "qemu/help_option.h"
 #include "qemu/module.h"
 #include "qemu/option.h"
 #include "qemu/qemu-print.h"
-#include "qapi/opts-visitor.h"
-#include "qemu/config-file.h"
 
 bool user_creatable_complete(UserCreatable *uc, Error **errp)
 {
@@ -131,60 +128,6 @@ void user_creatable_add_qapi(ObjectOptions *options, Error 
**errp)
 visit_free(v);
 }
 
-Object *user_creatable_add_opts(QemuOpts *opts, Error **errp)
-{
-Visitor *v;
-QDict *pdict;
-Object *obj;
-const char *id = qemu_opts_id(opts);
-char *type = qemu_opt_get_del(opts, "qom-type");
-
-if (!type) {
-error_setg(errp, QERR_MISSING_PARAMETER, "qom-type");
-return NULL;
-}
-if (!id) {
-error_setg(errp, QERR_MISSING_PARAMETER, "id");
-qemu_opt_set(opts, "qom-type", type, _abort);
-g_free(type);
-return NULL;
-}
-
-qemu_opts_set_id(opts, NULL);
-pdict = qemu_opts_to_qdict(opts, NULL);
-
-v = opts_visitor_new(opts);
-obj = user_creatable_add_type(type, id, pdict, v, errp);
-visit_free(v);
-
-qemu_opts_set_id(opts, (char *) id);
-qemu_opt_set(opts, "qom-type", type, _abort);
-g_free(type);
-qobject_unref(pdict);
-return obj;
-}
-
-
-int user_creatable_add_opts_foreach(void *opaque, QemuOpts *opts, Error **errp)
-{
-bool (*type_opt_predicate)(const char *, QemuOpts *) = opaque;
-Object *obj = NULL;
-const char *type;
-
-type = qemu_opt_get(opts, 

[PATCH v2 23/31] qom: Factor out user_creatable_process_cmdline()

2021-02-24 Thread Kevin Wolf
The implementation for --object can be shared between
qemu-storage-daemon and other binaries, so move it into a function in
qom/object_interfaces.c that is accessible from everywhere.

This also requires moving the implementation of qmp_object_add() into a
new user_creatable_add_qapi(), because qom/qom-qmp-cmds.c is not linked
for tools.

user_creatable_print_help_from_qdict() can become static now.

Signed-off-by: Kevin Wolf 
---
 include/qom/object_interfaces.h  | 41 +++
 qom/object_interfaces.c  | 50 +++-
 qom/qom-qmp-cmds.c   | 20 +--
 storage-daemon/qemu-storage-daemon.c | 22 +---
 4 files changed, 79 insertions(+), 54 deletions(-)

diff --git a/include/qom/object_interfaces.h b/include/qom/object_interfaces.h
index 5299603f50..1e6c51b541 100644
--- a/include/qom/object_interfaces.h
+++ b/include/qom/object_interfaces.h
@@ -2,6 +2,7 @@
 #define OBJECT_INTERFACES_H
 
 #include "qom/object.h"
+#include "qapi/qapi-types-qom.h"
 #include "qapi/visitor.h"
 
 #define TYPE_USER_CREATABLE "user-creatable"
@@ -86,6 +87,18 @@ Object *user_creatable_add_type(const char *type, const char 
*id,
 const QDict *qdict,
 Visitor *v, Error **errp);
 
+/**
+ * user_creatable_add_qapi:
+ * @options: the object definition
+ * @errp: if an error occurs, a pointer to an area to store the error
+ *
+ * Create an instance of the user creatable object according to the
+ * options passed in @opts as described in the QAPI schema documentation.
+ *
+ * Returns: the newly created object or NULL on error
+ */
+void user_creatable_add_qapi(ObjectOptions *options, Error **errp);
+
 /**
  * user_creatable_add_opts:
  * @opts: the object definition
@@ -131,6 +144,21 @@ typedef bool (*user_creatable_add_opts_predicate)(const 
char *type);
 int user_creatable_add_opts_foreach(void *opaque,
 QemuOpts *opts, Error **errp);
 
+/**
+ * user_creatable_process_cmdline:
+ * @optarg: the object definition string as passed on the command line
+ *
+ * Create an instance of the user creatable object by parsing optarg
+ * with a keyval parser and implicit key 'qom-type', converting the
+ * result to ObjectOptions and calling into qmp_object_add().
+ *
+ * If a help option is given, print help instead and exit.
+ *
+ * This function is only meant to be called during command line parsing.
+ * It exits the process on failure or after printing help.
+ */
+void user_creatable_process_cmdline(const char *optarg);
+
 /**
  * user_creatable_print_help:
  * @type: the QOM type to be added
@@ -145,19 +173,6 @@ int user_creatable_add_opts_foreach(void *opaque,
  */
 bool user_creatable_print_help(const char *type, QemuOpts *opts);
 
-/**
- * user_creatable_print_help_from_qdict:
- * @args: options to create
- *
- * Prints help considering the other options given in @args (if "qom-type" is
- * given and valid, print properties for the type, otherwise print valid types)
- *
- * In contrast to user_creatable_print_help(), this function can't return that
- * no help was requested. It should only be called if we know that help is
- * requested and it will always print some help.
- */
-void user_creatable_print_help_from_qdict(QDict *args);
-
 /**
  * user_creatable_del:
  * @id: the unique ID for the object
diff --git a/qom/object_interfaces.c b/qom/object_interfaces.c
index 7d8a4b77b8..efb48249d5 100644
--- a/qom/object_interfaces.c
+++ b/qom/object_interfaces.c
@@ -2,10 +2,13 @@
 
 #include "qemu/cutils.h"
 #include "qapi/error.h"
+#include "qapi/qapi-commands-qom.h"
+#include "qapi/qapi-visit-qom.h"
 #include "qapi/qmp/qdict.h"
 #include "qapi/qmp/qerror.h"
 #include "qapi/qmp/qjson.h"
 #include "qapi/qobject-input-visitor.h"
+#include "qapi/qobject-output-visitor.h"
 #include "qom/object_interfaces.h"
 #include "qemu/help_option.h"
 #include "qemu/module.h"
@@ -104,6 +107,29 @@ out:
 return obj;
 }
 
+void user_creatable_add_qapi(ObjectOptions *options, Error **errp)
+{
+Visitor *v;
+QObject *qobj;
+QDict *props;
+Object *obj;
+
+v = qobject_output_visitor_new();
+visit_type_ObjectOptions(v, NULL, , _abort);
+visit_complete(v, );
+visit_free(v);
+
+props = qobject_to(QDict, qobj);
+qdict_del(props, "qom-type");
+qdict_del(props, "id");
+
+v = qobject_input_visitor_new(QOBJECT(props));
+obj = user_creatable_add_type(ObjectType_str(options->qom_type),
+  options->id, props, v, errp);
+object_unref(obj);
+visit_free(v);
+}
+
 Object *user_creatable_add_opts(QemuOpts *opts, Error **errp)
 {
 Visitor *v;
@@ -247,7 +273,7 @@ bool user_creatable_print_help(const char *type, QemuOpts 
*opts)
 return false;
 }
 
-void user_creatable_print_help_from_qdict(QDict *args)
+static void user_creatable_print_help_from_qdict(QDict *args)
 {
 const char *type = qdict_get_try_str(args, 

[PATCH v2 22/31] qom: Remove user_creatable_add_dict()

2021-02-24 Thread Kevin Wolf
This function is now unused and can be removed.

Signed-off-by: Kevin Wolf 
---
 include/qom/object_interfaces.h | 18 --
 qom/object_interfaces.c | 32 
 2 files changed, 50 deletions(-)

diff --git a/include/qom/object_interfaces.h b/include/qom/object_interfaces.h
index 9b9938b8c0..5299603f50 100644
--- a/include/qom/object_interfaces.h
+++ b/include/qom/object_interfaces.h
@@ -86,24 +86,6 @@ Object *user_creatable_add_type(const char *type, const char 
*id,
 const QDict *qdict,
 Visitor *v, Error **errp);
 
-/**
- * user_creatable_add_dict:
- * @qdict: the object definition
- * @keyval: if true, use a keyval visitor for processing @qdict (i.e.
- *  assume that all @qdict values are strings); otherwise, use
- *  the normal QObject visitor (i.e. assume all @qdict values
- *  have the QType expected by the QOM object type)
- * @errp: if an error occurs, a pointer to an area to store the error
- *
- * Create an instance of the user creatable object that is defined by
- * @qdict.  The object type is taken from the QDict key 'qom-type', its
- * ID from the key 'id'. The remaining entries in @qdict are used to
- * initialize the object properties.
- *
- * Returns: %true on success, %false on failure.
- */
-bool user_creatable_add_dict(QDict *qdict, bool keyval, Error **errp);
-
 /**
  * user_creatable_add_opts:
  * @opts: the object definition
diff --git a/qom/object_interfaces.c b/qom/object_interfaces.c
index b9a99c8bf4..7d8a4b77b8 100644
--- a/qom/object_interfaces.c
+++ b/qom/object_interfaces.c
@@ -104,38 +104,6 @@ out:
 return obj;
 }
 
-bool user_creatable_add_dict(QDict *qdict, bool keyval, Error **errp)
-{
-Visitor *v;
-Object *obj;
-g_autofree char *type = NULL;
-g_autofree char *id = NULL;
-
-type = g_strdup(qdict_get_try_str(qdict, "qom-type"));
-if (!type) {
-error_setg(errp, QERR_MISSING_PARAMETER, "qom-type");
-return false;
-}
-qdict_del(qdict, "qom-type");
-
-id = g_strdup(qdict_get_try_str(qdict, "id"));
-if (!id) {
-error_setg(errp, QERR_MISSING_PARAMETER, "id");
-return false;
-}
-qdict_del(qdict, "id");
-
-if (keyval) {
-v = qobject_input_visitor_new_keyval(QOBJECT(qdict));
-} else {
-v = qobject_input_visitor_new(QOBJECT(qdict));
-}
-obj = user_creatable_add_type(type, id, qdict, v, errp);
-visit_free(v);
-object_unref(obj);
-return !!obj;
-}
-
 Object *user_creatable_add_opts(QemuOpts *opts, Error **errp)
 {
 Visitor *v;
-- 
2.29.2



[PATCH v2 19/31] qapi/qom: QAPIfy object-add

2021-02-24 Thread Kevin Wolf
This converts object-add from 'gen': false to the ObjectOptions QAPI
type. As an immediate benefit, clients can now use QAPI schema
introspection for user creatable QOM objects.

It is also the first step towards making the QAPI schema the only
external interface for the creation of user creatable objects. Once all
other places (HMP and command lines of the system emulator and all
tools) go through QAPI, too, some object implementations can be
simplified because some checks (e.g. that mandatory options are set) are
already performed by QAPI, and in another step, QOM boilerplate code
could be generated from the schema.

Signed-off-by: Kevin Wolf 
---
 qapi/qom.json| 11 +--
 include/qom/object_interfaces.h  |  7 ---
 hw/block/xen-block.c | 16 
 monitor/misc.c   |  2 --
 qom/qom-qmp-cmds.c   | 25 +++--
 storage-daemon/qemu-storage-daemon.c |  2 --
 6 files changed, 32 insertions(+), 31 deletions(-)

diff --git a/qapi/qom.json b/qapi/qom.json
index 6793342e81..e5b219df58 100644
--- a/qapi/qom.json
+++ b/qapi/qom.json
@@ -839,13 +839,6 @@
 #
 # Create a QOM object.
 #
-# @qom-type: the class name for the object to be created
-#
-# @id: the name of the new object
-#
-# Additional arguments depend on qom-type and are passed to the backend
-# unchanged.
-#
 # Returns: Nothing on success
 #  Error if @qom-type is not a valid class name
 #
@@ -859,9 +852,7 @@
 # <- { "return": {} }
 #
 ##
-{ 'command': 'object-add',
-  'data': {'qom-type': 'str', 'id': 'str'},
-  'gen': false } # so we can get the additional arguments
+{ 'command': 'object-add', 'data': 'ObjectOptions', 'boxed': true }
 
 ##
 # @object-del:
diff --git a/include/qom/object_interfaces.h b/include/qom/object_interfaces.h
index 07d5cc8832..9b9938b8c0 100644
--- a/include/qom/object_interfaces.h
+++ b/include/qom/object_interfaces.h
@@ -196,11 +196,4 @@ bool user_creatable_del(const char *id, Error **errp);
  */
 void user_creatable_cleanup(void);
 
-/**
- * qmp_object_add:
- *
- * QMP command handler for object-add. See the QAPI schema for documentation.
- */
-void qmp_object_add(QDict *qdict, QObject **ret_data, Error **errp);
-
 #endif
diff --git a/hw/block/xen-block.c b/hw/block/xen-block.c
index a3b69e2709..ac82d54063 100644
--- a/hw/block/xen-block.c
+++ b/hw/block/xen-block.c
@@ -836,17 +836,17 @@ static XenBlockIOThread *xen_block_iothread_create(const 
char *id,
 {
 ERRP_GUARD();
 XenBlockIOThread *iothread = g_new(XenBlockIOThread, 1);
-QDict *opts;
-QObject *ret_data = NULL;
+ObjectOptions *opts;
 
 iothread->id = g_strdup(id);
 
-opts = qdict_new();
-qdict_put_str(opts, "qom-type", TYPE_IOTHREAD);
-qdict_put_str(opts, "id", id);
-qmp_object_add(opts, _data, errp);
-qobject_unref(opts);
-qobject_unref(ret_data);
+opts = g_new(ObjectOptions, 1);
+*opts = (ObjectOptions) {
+.qom_type = OBJECT_TYPE_IOTHREAD,
+.id = g_strdup(id),
+};
+qmp_object_add(opts, errp);
+qapi_free_ObjectOptions(opts);
 
 if (*errp) {
 g_free(iothread->id);
diff --git a/monitor/misc.c b/monitor/misc.c
index a7650ed747..42efd9e2ab 100644
--- a/monitor/misc.c
+++ b/monitor/misc.c
@@ -235,8 +235,6 @@ static void monitor_init_qmp_commands(void)
  qmp_query_qmp_schema, QCO_ALLOW_PRECONFIG);
 qmp_register_command(_commands, "device_add", qmp_device_add,
  QCO_NO_OPTIONS);
-qmp_register_command(_commands, "object-add", qmp_object_add,
- QCO_NO_OPTIONS);
 
 QTAILQ_INIT(_cap_negotiation_commands);
 qmp_register_command(_cap_negotiation_commands, "qmp_capabilities",
diff --git a/qom/qom-qmp-cmds.c b/qom/qom-qmp-cmds.c
index 19fd5e117f..e577a96adf 100644
--- a/qom/qom-qmp-cmds.c
+++ b/qom/qom-qmp-cmds.c
@@ -19,8 +19,11 @@
 #include "qapi/error.h"
 #include "qapi/qapi-commands-qdev.h"
 #include "qapi/qapi-commands-qom.h"
+#include "qapi/qapi-visit-qom.h"
 #include "qapi/qmp/qdict.h"
 #include "qapi/qmp/qerror.h"
+#include "qapi/qobject-input-visitor.h"
+#include "qapi/qobject-output-visitor.h"
 #include "qemu/cutils.h"
 #include "qom/object_interfaces.h"
 #include "qom/qom-qobject.h"
@@ -223,9 +226,27 @@ ObjectPropertyInfoList *qmp_qom_list_properties(const char 
*typename,
 return prop_list;
 }
 
-void qmp_object_add(QDict *qdict, QObject **ret_data, Error **errp)
+void qmp_object_add(ObjectOptions *options, Error **errp)
 {
-user_creatable_add_dict(qdict, false, errp);
+Visitor *v;
+QObject *qobj;
+QDict *props;
+Object *obj;
+
+v = qobject_output_visitor_new();
+visit_type_ObjectOptions(v, NULL, , _abort);
+visit_complete(v, );
+visit_free(v);
+
+props = qobject_to(QDict, qobj);
+qdict_del(props, "qom-type");
+qdict_del(props, "id");
+
+v = qobject_input_visitor_new(QOBJECT(props));
+obj = 

[PATCH v2 27/31] qom: Add user_creatable_add_from_str()

2021-02-24 Thread Kevin Wolf
This is a version of user_creatable_process_cmdline() with an Error
parameter that never calls exit() and is therefore usable in HMP.

Signed-off-by: Kevin Wolf 
---
 include/qom/object_interfaces.h | 16 
 qom/object_interfaces.c | 29 -
 2 files changed, 40 insertions(+), 5 deletions(-)

diff --git a/include/qom/object_interfaces.h b/include/qom/object_interfaces.h
index 1e6c51b541..07511e6cff 100644
--- a/include/qom/object_interfaces.h
+++ b/include/qom/object_interfaces.h
@@ -144,6 +144,22 @@ typedef bool (*user_creatable_add_opts_predicate)(const 
char *type);
 int user_creatable_add_opts_foreach(void *opaque,
 QemuOpts *opts, Error **errp);
 
+/**
+ * user_creatable_add_from_str:
+ * @optarg: the object definition string as passed on the command line
+ * @errp: if an error occurs, a pointer to an area to store the error
+ *
+ * Create an instance of the user creatable object by parsing optarg
+ * with a keyval parser and implicit key 'qom-type', converting the
+ * result to ObjectOptions and calling into qmp_object_add().
+ *
+ * If a help option is given, print help instead.
+ *
+ * Returns: true when an object was successfully created, false when an error
+ * occurred (*errp is set then) or help was printed (*errp is not set).
+ */
+bool user_creatable_add_from_str(const char *optarg, Error **errp);
+
 /**
  * user_creatable_process_cmdline:
  * @optarg: the object definition string as passed on the command line
diff --git a/qom/object_interfaces.c b/qom/object_interfaces.c
index efb48249d5..54f0dadfea 100644
--- a/qom/object_interfaces.c
+++ b/qom/object_interfaces.c
@@ -282,26 +282,45 @@ static void user_creatable_print_help_from_qdict(QDict 
*args)
 }
 }
 
-void user_creatable_process_cmdline(const char *optarg)
+bool user_creatable_add_from_str(const char *optarg, Error **errp)
 {
+ERRP_GUARD();
 QDict *args;
 bool help;
 Visitor *v;
 ObjectOptions *options;
 
-args = keyval_parse(optarg, "qom-type", , _fatal);
+args = keyval_parse(optarg, "qom-type", , errp);
+if (*errp) {
+return false;
+}
 if (help) {
 user_creatable_print_help_from_qdict(args);
-exit(EXIT_SUCCESS);
+qobject_unref(args);
+return false;
 }
 
 v = qobject_input_visitor_new_keyval(QOBJECT(args));
-visit_type_ObjectOptions(v, NULL, , _fatal);
+visit_type_ObjectOptions(v, NULL, , errp);
 visit_free(v);
 qobject_unref(args);
 
-user_creatable_add_qapi(options, _fatal);
+if (*errp) {
+goto out;
+}
+
+user_creatable_add_qapi(options, errp);
+out:
 qapi_free_ObjectOptions(options);
+return !*errp;
+}
+
+void user_creatable_process_cmdline(const char *optarg)
+{
+if (!user_creatable_add_from_str(optarg, _fatal)) {
+/* Help was printed */
+exit(EXIT_SUCCESS);
+}
 }
 
 bool user_creatable_del(const char *id, Error **errp)
-- 
2.29.2



Re: [PATCH 04/14] softmmu: remove '-usbdevice' command line option

2021-02-24 Thread Thomas Huth

On 24/02/2021 14.11, Daniel P. Berrangé wrote:

This was replaced by the '-device usb-DEV' option.

Signed-off-by: Daniel P. Berrangé 
---
  docs/system/deprecated.rst   |  9 ---
  docs/system/removed-features.rst |  9 +++
  softmmu/vl.c | 42 
  3 files changed, 9 insertions(+), 51 deletions(-)


Last time I tried to remove -usbdevice, there was some concerns that 
-usbdevice braille might still be useful for some people, see the thread 
that started here:


 https://lists.nongnu.org/archive/html/qemu-devel/2018-01/msg00651.html

(and Gerd's summary here: 
https://lists.nongnu.org/archive/html/qemu-devel/2018-01/msg01520.html )


So we might need a new "sugared" option like "-braille" instead before we 
can fully remove -usbdevice? ... or we just keep -usbdevice as a bittersweet 
remainder?


 Thomas



[PATCH v2 28/31] hmp: QAPIfy object_add

2021-02-24 Thread Kevin Wolf
This switches the HMP command object_add from a QemuOpts-based parser to
user_creatable_add_from_str() which uses a keyval parser and enforces
the QAPI schema.

Apart from being a cleanup, this makes non-scalar properties and help
accessible. In order for help to be printed to the monitor instead of
stdout, the printf() calls in the help functions are changed to
qemu_printf().

Signed-off-by: Kevin Wolf 
---
 monitor/hmp-cmds.c  | 17 ++---
 qom/object_interfaces.c | 11 ++-
 hmp-commands.hx |  2 +-
 3 files changed, 9 insertions(+), 21 deletions(-)

diff --git a/monitor/hmp-cmds.c b/monitor/hmp-cmds.c
index 3c88a4faef..652cf9ff21 100644
--- a/monitor/hmp-cmds.c
+++ b/monitor/hmp-cmds.c
@@ -1670,24 +1670,11 @@ void hmp_netdev_del(Monitor *mon, const QDict *qdict)
 
 void hmp_object_add(Monitor *mon, const QDict *qdict)
 {
+const char *options = qdict_get_str(qdict, "object");
 Error *err = NULL;
-QemuOpts *opts;
-Object *obj = NULL;
-
-opts = qemu_opts_from_qdict(qemu_find_opts("object"), qdict, );
-if (err) {
-goto end;
-}
 
-obj = user_creatable_add_opts(opts, );
-qemu_opts_del(opts);
-
-end:
+user_creatable_add_from_str(options, );
 hmp_handle_error(mon, err);
-
-if (obj) {
-object_unref(obj);
-}
 }
 
 void hmp_getfd(Monitor *mon, const QDict *qdict)
diff --git a/qom/object_interfaces.c b/qom/object_interfaces.c
index 54f0dadfea..c4982dd7a0 100644
--- a/qom/object_interfaces.c
+++ b/qom/object_interfaces.c
@@ -13,6 +13,7 @@
 #include "qemu/help_option.h"
 #include "qemu/module.h"
 #include "qemu/option.h"
+#include "qemu/qemu-print.h"
 #include "qapi/opts-visitor.h"
 #include "qemu/config-file.h"
 
@@ -212,11 +213,11 @@ static void user_creatable_print_types(void)
 {
 GSList *l, *list;
 
-printf("List of user creatable objects:\n");
+qemu_printf("List of user creatable objects:\n");
 list = object_class_get_list_sorted(TYPE_USER_CREATABLE, false);
 for (l = list; l != NULL; l = l->next) {
 ObjectClass *oc = OBJECT_CLASS(l->data);
-printf("  %s\n", object_class_get_name(oc));
+qemu_printf("  %s\n", object_class_get_name(oc));
 }
 g_slist_free(list);
 }
@@ -247,12 +248,12 @@ static bool user_creatable_print_type_properites(const 
char *type)
 }
 g_ptr_array_sort(array, (GCompareFunc)qemu_pstrcmp0);
 if (array->len > 0) {
-printf("%s options:\n", type);
+qemu_printf("%s options:\n", type);
 } else {
-printf("There are no options for %s.\n", type);
+qemu_printf("There are no options for %s.\n", type);
 }
 for (i = 0; i < array->len; i++) {
-printf("%s\n", (char *)array->pdata[i]);
+qemu_printf("%s\n", (char *)array->pdata[i]);
 }
 g_ptr_array_set_free_func(array, g_free);
 g_ptr_array_free(array, true);
diff --git a/hmp-commands.hx b/hmp-commands.hx
index d4001f9c5d..6f5d9ce2fb 100644
--- a/hmp-commands.hx
+++ b/hmp-commands.hx
@@ -1337,7 +1337,7 @@ ERST
 
 {
 .name   = "object_add",
-.args_type  = "object:O",
+.args_type  = "object:S",
 .params = "[qom-type=]type,id=str[,prop=value][,...]",
 .help   = "create QOM object",
 .cmd= hmp_object_add,
-- 
2.29.2



[PATCH v2 25/31] qemu-img: Use user_creatable_process_cmdline() for --object

2021-02-24 Thread Kevin Wolf
This switches qemu-img from a QemuOpts-based parser for --object to
user_creatable_process_cmdline() which uses a keyval parser and enforces
the QAPI schema.

Apart from being a cleanup, this makes non-scalar properties accessible.

Signed-off-by: Kevin Wolf 
---
 qemu-img.c | 239 -
 1 file changed, 33 insertions(+), 206 deletions(-)

diff --git a/qemu-img.c b/qemu-img.c
index e2952fe955..ebf8661e2a 100644
--- a/qemu-img.c
+++ b/qemu-img.c
@@ -226,23 +226,6 @@ static void QEMU_NORETURN help(void)
 exit(EXIT_SUCCESS);
 }
 
-static QemuOptsList qemu_object_opts = {
-.name = "object",
-.implied_opt_name = "qom-type",
-.head = QTAILQ_HEAD_INITIALIZER(qemu_object_opts.head),
-.desc = {
-{ }
-},
-};
-
-static bool qemu_img_object_print_help(const char *type, QemuOpts *opts)
-{
-if (user_creatable_print_help(type, opts)) {
-exit(0);
-}
-return true;
-}
-
 /*
  * Is @optarg safe for accumulate_options()?
  * It is when multiple of them can be joined together separated by ','.
@@ -566,14 +549,9 @@ static int img_create(int argc, char **argv)
 case 'u':
 flags |= BDRV_O_NO_BACKING;
 break;
-case OPTION_OBJECT: {
-QemuOpts *opts;
-opts = qemu_opts_parse_noisily(_object_opts,
-   optarg, true);
-if (!opts) {
-goto fail;
-}
-}   break;
+case OPTION_OBJECT:
+user_creatable_process_cmdline(optarg);
+break;
 }
 }
 
@@ -589,12 +567,6 @@ static int img_create(int argc, char **argv)
 }
 optind++;
 
-if (qemu_opts_foreach(_object_opts,
-  user_creatable_add_opts_foreach,
-  qemu_img_object_print_help, _fatal)) {
-goto fail;
-}
-
 /* Get image size, if specified */
 if (optind < argc) {
 int64_t sval;
@@ -804,14 +776,9 @@ static int img_check(int argc, char **argv)
 case 'U':
 force_share = true;
 break;
-case OPTION_OBJECT: {
-QemuOpts *opts;
-opts = qemu_opts_parse_noisily(_object_opts,
-   optarg, true);
-if (!opts) {
-return 1;
-}
-}   break;
+case OPTION_OBJECT:
+user_creatable_process_cmdline(optarg);
+break;
 case OPTION_IMAGE_OPTS:
 image_opts = true;
 break;
@@ -831,12 +798,6 @@ static int img_check(int argc, char **argv)
 return 1;
 }
 
-if (qemu_opts_foreach(_object_opts,
-  user_creatable_add_opts_foreach,
-  qemu_img_object_print_help, _fatal)) {
-return 1;
-}
-
 ret = bdrv_parse_cache_mode(cache, , );
 if (ret < 0) {
 error_report("Invalid source cache option: %s", cache);
@@ -1034,14 +995,9 @@ static int img_commit(int argc, char **argv)
 return 1;
 }
 break;
-case OPTION_OBJECT: {
-QemuOpts *opts;
-opts = qemu_opts_parse_noisily(_object_opts,
-   optarg, true);
-if (!opts) {
-return 1;
-}
-}   break;
+case OPTION_OBJECT:
+user_creatable_process_cmdline(optarg);
+break;
 case OPTION_IMAGE_OPTS:
 image_opts = true;
 break;
@@ -1058,12 +1014,6 @@ static int img_commit(int argc, char **argv)
 }
 filename = argv[optind++];
 
-if (qemu_opts_foreach(_object_opts,
-  user_creatable_add_opts_foreach,
-  qemu_img_object_print_help, _fatal)) {
-return 1;
-}
-
 flags = BDRV_O_RDWR | BDRV_O_UNMAP;
 ret = bdrv_parse_cache_mode(cache, , );
 if (ret < 0) {
@@ -1423,15 +1373,9 @@ static int img_compare(int argc, char **argv)
 case 'U':
 force_share = true;
 break;
-case OPTION_OBJECT: {
-QemuOpts *opts;
-opts = qemu_opts_parse_noisily(_object_opts,
-   optarg, true);
-if (!opts) {
-ret = 2;
-goto out4;
-}
-}   break;
+case OPTION_OBJECT:
+user_creatable_process_cmdline(optarg);
+break;
 case OPTION_IMAGE_OPTS:
 image_opts = true;
 break;
@@ -1450,13 +1394,6 @@ static int img_compare(int argc, char **argv)
 filename1 = argv[optind++];
 filename2 = argv[optind++];
 
-if (qemu_opts_foreach(_object_opts,
-  user_creatable_add_opts_foreach,
-  qemu_img_object_print_help, _fatal)) {
-ret = 2;
-goto out4;
-}
-
 /* Initialize before goto 

[PATCH v2 24/31] qemu-io: Use user_creatable_process_cmdline() for --object

2021-02-24 Thread Kevin Wolf
This switches qemu-io from a QemuOpts-based parser for --object to
user_creatable_process_cmdline() which uses a keyval parser and enforces
the QAPI schema.

Apart from being a cleanup, this makes non-scalar properties accessible.

Signed-off-by: Kevin Wolf 
---
 qemu-io.c | 33 +++--
 1 file changed, 3 insertions(+), 30 deletions(-)

diff --git a/qemu-io.c b/qemu-io.c
index ac88d8bd40..bf902302e9 100644
--- a/qemu-io.c
+++ b/qemu-io.c
@@ -477,23 +477,6 @@ enum {
 OPTION_IMAGE_OPTS = 257,
 };
 
-static QemuOptsList qemu_object_opts = {
-.name = "object",
-.implied_opt_name = "qom-type",
-.head = QTAILQ_HEAD_INITIALIZER(qemu_object_opts.head),
-.desc = {
-{ }
-},
-};
-
-static bool qemu_io_object_print_help(const char *type, QemuOpts *opts)
-{
-if (user_creatable_print_help(type, opts)) {
-exit(0);
-}
-return true;
-}
-
 static QemuOptsList file_opts = {
 .name = "file",
 .implied_opt_name = "file",
@@ -550,7 +533,6 @@ int main(int argc, char **argv)
 qcrypto_init(_fatal);
 
 module_call_init(MODULE_INIT_QOM);
-qemu_add_opts(_object_opts);
 qemu_add_opts(_trace_opts);
 bdrv_init();
 
@@ -612,14 +594,9 @@ int main(int argc, char **argv)
 case 'U':
 force_share = true;
 break;
-case OPTION_OBJECT: {
-QemuOpts *qopts;
-qopts = qemu_opts_parse_noisily(_object_opts,
-optarg, true);
-if (!qopts) {
-exit(1);
-}
-}   break;
+case OPTION_OBJECT:
+user_creatable_process_cmdline(optarg);
+break;
 case OPTION_IMAGE_OPTS:
 imageOpts = true;
 break;
@@ -644,10 +621,6 @@ int main(int argc, char **argv)
 exit(1);
 }
 
-qemu_opts_foreach(_object_opts,
-  user_creatable_add_opts_foreach,
-  qemu_io_object_print_help, _fatal);
-
 if (!trace_init_backends()) {
 exit(1);
 }
-- 
2.29.2



[PATCH v2 30/31] vl: QAPIfy -object

2021-02-24 Thread Kevin Wolf
This switches the system emulator from a QemuOpts-based parser for
-object to user_creatable_parse_str() which uses a keyval parser and
enforces the QAPI schema.

Apart from being a cleanup, this makes non-scalar properties accessible.

This adopts a similar model as -blockdev uses: When parsing the option,
create the ObjectOptions and queue them. At the later point where we
used to create objects for the collected QemuOpts, the ObjectOptions
queue is processed instead.

A complication compared to -blockdev is that object definitions are
supported in -readconfig and -writeconfig.

After this patch, -readconfig still works, though it still goes through
the QemuOpts parser, which means that improvements like non-scalar
properties are still not available in config files.

-writeconfig stops working for -object. Tough luck. It has never
supported all options (not even the common ones), so supporting one less
isn't the end of the world. As object definitions from -readconfig still
go through QemuOpts, they are still included in -writeconfig output,
which at least prevents destroying your existing configuration when you
just wanted to add another option.

Signed-off-by: Kevin Wolf 
---
 softmmu/vl.c | 109 +++
 1 file changed, 84 insertions(+), 25 deletions(-)

diff --git a/softmmu/vl.c b/softmmu/vl.c
index b219ce1f35..205c254542 100644
--- a/softmmu/vl.c
+++ b/softmmu/vl.c
@@ -113,6 +113,7 @@
 #include "sysemu/replay.h"
 #include "qapi/qapi-events-run-state.h"
 #include "qapi/qapi-visit-block-core.h"
+#include "qapi/qapi-visit-qom.h"
 #include "qapi/qapi-visit-ui.h"
 #include "qapi/qapi-commands-block-core.h"
 #include "qapi/qapi-commands-migration.h"
@@ -132,6 +133,14 @@ typedef struct BlockdevOptionsQueueEntry {
 
 typedef QSIMPLEQ_HEAD(, BlockdevOptionsQueueEntry) BlockdevOptionsQueue;
 
+typedef struct ObjectOptionsQueueEntry {
+ObjectOptions *options;
+Location loc;
+QTAILQ_ENTRY(ObjectOptionsQueueEntry) next;
+} ObjectOptionsQueueEntry;
+
+typedef QTAILQ_HEAD(, ObjectOptionsQueueEntry) ObjectOptionsQueue;
+
 static const char *cpu_option;
 static const char *mem_path;
 static const char *incoming;
@@ -143,6 +152,7 @@ static int snapshot;
 static bool preconfig_requested;
 static QemuPluginList plugin_list = QTAILQ_HEAD_INITIALIZER(plugin_list);
 static BlockdevOptionsQueue bdo_queue = QSIMPLEQ_HEAD_INITIALIZER(bdo_queue);
+static ObjectOptionsQueue obj_queue = QTAILQ_HEAD_INITIALIZER(obj_queue);
 static bool nographic = false;
 static int mem_prealloc; /* force preallocation of physical target memory */
 static ram_addr_t ram_size;
@@ -1691,12 +1701,9 @@ static int machine_set_property(void *opaque,
  * cannot be created here, as it depends on the chardev
  * already existing.
  */
-static bool object_create_early(const char *type, QemuOpts *opts)
+static bool object_create_early(ObjectOptions *options)
 {
-if (user_creatable_print_help(type, opts)) {
-exit(0);
-}
-
+const char *type = ObjectType_str(options->qom_type);
 /*
  * Objects should not be made "delayed" without a reason.  If you
  * add one, state the reason in a comment!
@@ -1744,6 +1751,56 @@ static bool object_create_early(const char *type, 
QemuOpts *opts)
 return true;
 }
 
+static void object_queue_create(bool early)
+{
+ObjectOptionsQueueEntry *entry, *next;
+
+QTAILQ_FOREACH_SAFE(entry, _queue, next, next) {
+if (early != object_create_early(entry->options)) {
+continue;
+}
+QTAILQ_REMOVE(_queue, entry, next);
+loc_push_restore(>loc);
+user_creatable_add_qapi(entry->options, _fatal);
+loc_pop(>loc);
+qapi_free_ObjectOptions(entry->options);
+g_free(entry);
+}
+}
+
+/*
+ * -readconfig still parses things into QemuOpts. Convert any such
+ *  configurations to an ObjectOptionsQueueEntry.
+ *
+ *  This is more restricted than the normal -object parser because QemuOpts
+ *  parsed things, so no support for non-scalar properties. Help is also not
+ *  supported (but this shouldn't be requested in a config file anyway).
+ */
+static int object_readconfig_to_qapi(void *opaque, QemuOpts *opts, Error 
**errp)
+{
+ERRP_GUARD();
+ObjectOptionsQueueEntry *entry;
+ObjectOptions *options;
+QDict *args = qemu_opts_to_qdict(opts, NULL);
+Visitor *v;
+
+v = qobject_input_visitor_new_keyval(QOBJECT(args));
+visit_type_ObjectOptions(v, NULL, , errp);
+visit_free(v);
+qobject_unref(args);
+
+if (*errp) {
+return -1;
+}
+
+entry = g_new0(ObjectOptionsQueueEntry, 1);
+entry->options = options;
+loc_save(>loc);
+QTAILQ_INSERT_TAIL(_queue, entry, next);
+
+return 0;
+}
+
 static void qemu_apply_machine_options(void)
 {
 MachineClass *machine_class = MACHINE_GET_CLASS(current_machine);
@@ -1816,8 +1873,8 @@ static void qemu_create_early_backends(void)
 }
 
 

[PATCH v2 21/31] qemu-storage-daemon: Implement --object with qmp_object_add()

2021-02-24 Thread Kevin Wolf
This QAPIfies --object and ensures that QMP and the command line option
behave the same.

Signed-off-by: Kevin Wolf 
---
 storage-daemon/qemu-storage-daemon.c | 21 ++---
 1 file changed, 10 insertions(+), 11 deletions(-)

diff --git a/storage-daemon/qemu-storage-daemon.c 
b/storage-daemon/qemu-storage-daemon.c
index d8d172cc60..0dfb9c1448 100644
--- a/storage-daemon/qemu-storage-daemon.c
+++ b/storage-daemon/qemu-storage-daemon.c
@@ -38,6 +38,7 @@
 #include "qapi/qapi-visit-block-core.h"
 #include "qapi/qapi-visit-block-export.h"
 #include "qapi/qapi-visit-control.h"
+#include "qapi/qapi-visit-qom.h"
 #include "qapi/qmp/qdict.h"
 #include "qapi/qmp/qstring.h"
 #include "qapi/qobject-input-visitor.h"
@@ -130,15 +131,6 @@ enum {
 
 extern QemuOptsList qemu_chardev_opts;
 
-static QemuOptsList qemu_object_opts = {
-.name = "object",
-.implied_opt_name = "qom-type",
-.head = QTAILQ_HEAD_INITIALIZER(qemu_object_opts.head),
-.desc = {
-{ }
-},
-};
-
 static void init_qmp_commands(void)
 {
 qmp_init_marshal(_commands);
@@ -263,14 +255,22 @@ static void process_options(int argc, char *argv[])
 {
 QDict *args;
 bool help;
+Visitor *v;
+ObjectOptions *options;
 
 args = keyval_parse(optarg, "qom-type", , _fatal);
 if (help) {
 user_creatable_print_help_from_qdict(args);
 exit(EXIT_SUCCESS);
 }
-user_creatable_add_dict(args, true, _fatal);
+
+v = qobject_input_visitor_new_keyval(QOBJECT(args));
+visit_type_ObjectOptions(v, NULL, , _fatal);
+visit_free(v);
 qobject_unref(args);
+
+qmp_object_add(options, _fatal);
+qapi_free_ObjectOptions(options);
 break;
 }
 default:
@@ -295,7 +295,6 @@ int main(int argc, char *argv[])
 
 module_call_init(MODULE_INIT_QOM);
 module_call_init(MODULE_INIT_TRACE);
-qemu_add_opts(_object_opts);
 qemu_add_opts(_trace_opts);
 qcrypto_init(_fatal);
 bdrv_init();
-- 
2.29.2



[PATCH v2 07/31] qapi/qom: Add ObjectOptions for memory-backend-*

2021-02-24 Thread Kevin Wolf
This adds a QAPI schema for the properties of the memory-backend-*
objects.

HostMemPolicy has to be moved to an include file that can be used by the
storage daemon, too, because ObjectOptions must be the same in all
binaries if we don't want to compile the whole code multiple times.

Signed-off-by: Kevin Wolf 
---
 qapi/common.json  |  20 
 qapi/machine.json |  22 +
 qapi/qom.json | 118 +-
 3 files changed, 138 insertions(+), 22 deletions(-)

diff --git a/qapi/common.json b/qapi/common.json
index 716712d4b3..2dad4fadc3 100644
--- a/qapi/common.json
+++ b/qapi/common.json
@@ -145,3 +145,23 @@
 ##
 { 'enum': 'PCIELinkWidth',
   'data': [ '1', '2', '4', '8', '12', '16', '32' ] }
+
+##
+# @HostMemPolicy:
+#
+# Host memory policy types
+#
+# @default: restore default policy, remove any nondefault policy
+#
+# @preferred: set the preferred host nodes for allocation
+#
+# @bind: a strict policy that restricts memory allocation to the
+#host nodes specified
+#
+# @interleave: memory allocations are interleaved across the set
+#  of host nodes specified
+#
+# Since: 2.1
+##
+{ 'enum': 'HostMemPolicy',
+  'data': [ 'default', 'preferred', 'bind', 'interleave' ] }
diff --git a/qapi/machine.json b/qapi/machine.json
index 330189efe3..4322aee782 100644
--- a/qapi/machine.json
+++ b/qapi/machine.json
@@ -8,6 +8,8 @@
 # = Machines
 ##
 
+{ 'include': 'common.json' }
+
 ##
 # @SysEmuTarget:
 #
@@ -897,26 +899,6 @@
'policy': 'HmatCacheWritePolicy',
'line': 'uint16' }}
 
-##
-# @HostMemPolicy:
-#
-# Host memory policy types
-#
-# @default: restore default policy, remove any nondefault policy
-#
-# @preferred: set the preferred host nodes for allocation
-#
-# @bind: a strict policy that restricts memory allocation to the
-#host nodes specified
-#
-# @interleave: memory allocations are interleaved across the set
-#  of host nodes specified
-#
-# Since: 2.1
-##
-{ 'enum': 'HostMemPolicy',
-  'data': [ 'default', 'preferred', 'bind', 'interleave' ] }
-
 ##
 # @memsave:
 #
diff --git a/qapi/qom.json b/qapi/qom.json
index a6a5049707..1a869006a1 100644
--- a/qapi/qom.json
+++ b/qapi/qom.json
@@ -5,6 +5,7 @@
 # See the COPYING file in the top-level directory.
 
 { 'include': 'authz.json' }
+{ 'include': 'common.json' }
 
 ##
 # = QEMU Object Model (QOM)
@@ -272,6 +273,113 @@
 '*poll-grow': 'int',
 '*poll-shrink': 'int' } }
 
+##
+# @MemoryBackendProperties:
+#
+# Properties for objects of classes derived from memory-backend.
+#
+# @merge: if true, mark the memory as mergeable (default depends on the machine
+# type)
+#
+# @dump: if true, include the memory in core dumps (default depends on the
+#machine type)
+#
+# @host-nodes: the list of NUMA host nodes to bind the memory to
+#
+# @policy: the NUMA policy (default: 'default')
+#
+# @prealloc: if true, preallocate memory (default: false)
+#
+# @prealloc-threads: number of CPU threads to use for prealloc (default: 1)
+#
+# @share: if false, the memory is private to QEMU; if true, it is shared
+# (default: false)
+#
+# @size: size of the memory region in bytes
+#
+# @x-use-canonical-path-for-ramblock-id: if true, the canoncial path is used
+#for ramblock-id. Disable this for 4.0
+#machine types or older to allow
+#migration with newer QEMU versions.
+#(default: false generally, but true
+#for machine types <= 4.0)
+#
+# Since: 2.1
+##
+{ 'struct': 'MemoryBackendProperties',
+  'data': { '*dump': 'bool',
+'*host-nodes': ['uint16'],
+'*merge': 'bool',
+'*policy': 'HostMemPolicy',
+'*prealloc': 'bool',
+'*prealloc-threads': 'uint32',
+'*share': 'bool',
+'size': 'size',
+'*x-use-canonical-path-for-ramblock-id': 'bool' } }
+
+##
+# @MemoryBackendFileProperties:
+#
+# Properties for memory-backend-file objects.
+#
+# @align: the base address alignment when QEMU mmap(2) @mem-path. Some
+# backend store specified by @mem-path requires an alignment different
+# than the default one used by QEMU, e.g. the device DAX /dev/dax0.0
+# requires 2M alignment rather than 4K. In such cases, users can
+# specify the required alignment via this option.
+# 0 selects a default alignment (currently the page size). (default: 0)
+#
+# @discard-data: if true, the file contents can be destroyed when QEMU exits,
+#to avoid unnecessarily flushing data to the backing file. Note
+#that ``discard-data`` is only an optimization, and QEMU might
+#not discard file contents if it aborts unexpectedly or is
+#terminated using SIGKILL. (default: false)
+#
+# @mem-path: 

[PATCH v2 29/31] qom: Add user_creatable_parse_str()

2021-02-24 Thread Kevin Wolf
The system emulator has a more complicated way of handling command line
options in that it reorders options before it processes them. This means
that parsing object options and creating the object happen at two
different points. Split the parsing part into a separate function that
can be reused by the system emulator command line.

Signed-off-by: Kevin Wolf 
---
 include/qom/object_interfaces.h | 15 +++
 qom/object_interfaces.c | 20 ++--
 2 files changed, 29 insertions(+), 6 deletions(-)

diff --git a/include/qom/object_interfaces.h b/include/qom/object_interfaces.h
index 07511e6cff..fb32330901 100644
--- a/include/qom/object_interfaces.h
+++ b/include/qom/object_interfaces.h
@@ -144,6 +144,21 @@ typedef bool (*user_creatable_add_opts_predicate)(const 
char *type);
 int user_creatable_add_opts_foreach(void *opaque,
 QemuOpts *opts, Error **errp);
 
+/**
+ * user_creatable_parse_str:
+ * @optarg: the object definition string as passed on the command line
+ * @errp: if an error occurs, a pointer to an area to store the error
+ *
+ * Parses the option for the user creatable object with a keyval parser and
+ * implicit key 'qom-type', converting the result to ObjectOptions.
+ *
+ * If a help option is given, print help instead.
+ *
+ * Returns: ObjectOptions on success, NULL when an error occurred (*errp is set
+ * then) or help was printed (*errp is not set).
+ */
+ObjectOptions *user_creatable_parse_str(const char *optarg, Error **errp);
+
 /**
  * user_creatable_add_from_str:
  * @optarg: the object definition string as passed on the command line
diff --git a/qom/object_interfaces.c b/qom/object_interfaces.c
index c4982dd7a0..1c29f45b41 100644
--- a/qom/object_interfaces.c
+++ b/qom/object_interfaces.c
@@ -283,7 +283,7 @@ static void user_creatable_print_help_from_qdict(QDict 
*args)
 }
 }
 
-bool user_creatable_add_from_str(const char *optarg, Error **errp)
+ObjectOptions *user_creatable_parse_str(const char *optarg, Error **errp)
 {
 ERRP_GUARD();
 QDict *args;
@@ -293,12 +293,12 @@ bool user_creatable_add_from_str(const char *optarg, 
Error **errp)
 
 args = keyval_parse(optarg, "qom-type", , errp);
 if (*errp) {
-return false;
+return NULL;
 }
 if (help) {
 user_creatable_print_help_from_qdict(args);
 qobject_unref(args);
-return false;
+return NULL;
 }
 
 v = qobject_input_visitor_new_keyval(QOBJECT(args));
@@ -306,12 +306,20 @@ bool user_creatable_add_from_str(const char *optarg, 
Error **errp)
 visit_free(v);
 qobject_unref(args);
 
-if (*errp) {
-goto out;
+return options;
+}
+
+bool user_creatable_add_from_str(const char *optarg, Error **errp)
+{
+ERRP_GUARD();
+ObjectOptions *options;
+
+options = user_creatable_parse_str(optarg, errp);
+if (!options) {
+return false;
 }
 
 user_creatable_add_qapi(options, errp);
-out:
 qapi_free_ObjectOptions(options);
 return !*errp;
 }
-- 
2.29.2



[PATCH v2 26/31] qemu-nbd: Use user_creatable_process_cmdline() for --object

2021-02-24 Thread Kevin Wolf
This switches qemu-nbd from a QemuOpts-based parser for --object to
user_creatable_process_cmdline() which uses a keyval parser and enforces
the QAPI schema.

Apart from being a cleanup, this makes non-scalar properties accessible.

Signed-off-by: Kevin Wolf 
---
 qemu-nbd.c | 34 +++---
 1 file changed, 3 insertions(+), 31 deletions(-)

diff --git a/qemu-nbd.c b/qemu-nbd.c
index b1b9430a8f..93ef4e288f 100644
--- a/qemu-nbd.c
+++ b/qemu-nbd.c
@@ -401,24 +401,6 @@ static QemuOptsList file_opts = {
 },
 };
 
-static QemuOptsList qemu_object_opts = {
-.name = "object",
-.implied_opt_name = "qom-type",
-.head = QTAILQ_HEAD_INITIALIZER(qemu_object_opts.head),
-.desc = {
-{ }
-},
-};
-
-static bool qemu_nbd_object_print_help(const char *type, QemuOpts *opts)
-{
-if (user_creatable_print_help(type, opts)) {
-exit(0);
-}
-return true;
-}
-
-
 static QCryptoTLSCreds *nbd_get_tls_creds(const char *id, bool list,
   Error **errp)
 {
@@ -594,7 +576,6 @@ int main(int argc, char **argv)
 qcrypto_init(_fatal);
 
 module_call_init(MODULE_INIT_QOM);
-qemu_add_opts(_object_opts);
 qemu_add_opts(_trace_opts);
 qemu_init_exec_dir(argv[0]);
 
@@ -747,14 +728,9 @@ int main(int argc, char **argv)
 case '?':
 error_report("Try `%s --help' for more information.", argv[0]);
 exit(EXIT_FAILURE);
-case QEMU_NBD_OPT_OBJECT: {
-QemuOpts *opts;
-opts = qemu_opts_parse_noisily(_object_opts,
-   optarg, true);
-if (!opts) {
-exit(EXIT_FAILURE);
-}
-}   break;
+case QEMU_NBD_OPT_OBJECT:
+user_creatable_process_cmdline(optarg);
+break;
 case QEMU_NBD_OPT_TLSCREDS:
 tlscredsid = optarg;
 break;
@@ -802,10 +778,6 @@ int main(int argc, char **argv)
 export_name = "";
 }
 
-qemu_opts_foreach(_object_opts,
-  user_creatable_add_opts_foreach,
-  qemu_nbd_object_print_help, _fatal);
-
 if (!trace_init_backends()) {
 exit(1);
 }
-- 
2.29.2



[PATCH v2 18/31] qapi/qom: Add ObjectOptions for x-remote-object

2021-02-24 Thread Kevin Wolf
This adds a QAPI schema for the properties of the x-remote-object
object.

Signed-off-by: Kevin Wolf 
---
 qapi/qom.json | 20 ++--
 1 file changed, 18 insertions(+), 2 deletions(-)

diff --git a/qapi/qom.json b/qapi/qom.json
index f8ff322df0..6793342e81 100644
--- a/qapi/qom.json
+++ b/qapi/qom.json
@@ -641,6 +641,20 @@
 { 'struct': 'PrManagerHelperProperties',
   'data': { 'path': 'str' } }
 
+##
+# @RemoteObjectProperties:
+#
+# Properties for x-remote-object objects.
+#
+# @fd: file descriptor name previously passed via 'getfd' command
+#
+# @devid: the id of the device to be associated with the file descriptor
+#
+# Since: 6.0
+##
+{ 'struct': 'RemoteObjectProperties',
+  'data': { 'fd': 'str', 'devid': 'str' } }
+
 ##
 # @RngProperties:
 #
@@ -762,7 +776,8 @@
 'tls-creds-anon',
 'tls-creds-psk',
 'tls-creds-x509',
-'tls-cipher-suites'
+'tls-cipher-suites',
+'x-remote-object'
   ] }
 
 ##
@@ -815,7 +830,8 @@
   'tls-creds-anon': 'TlsCredsAnonProperties',
   'tls-creds-psk':  'TlsCredsPskProperties',
   'tls-creds-x509': 'TlsCredsX509Properties',
-  'tls-cipher-suites':  'TlsCredsProperties'
+  'tls-cipher-suites':  'TlsCredsProperties',
+  'x-remote-object':'RemoteObjectProperties'
   } }
 
 ##
-- 
2.29.2



[PATCH v2 05/31] qapi/qom: Add ObjectOptions for cryptodev-*

2021-02-24 Thread Kevin Wolf
This adds a QAPI schema for the properties of the cryptodev-* objects.

These interfaces have some questionable aspects (cryptodev-backend is
really an abstract base class without function, and the queues option
only makes sense for cryptodev-vhost-user), but as the goal is to
represent the existing interface in QAPI, leave these things in place.

Signed-off-by: Kevin Wolf 
---
 qapi/qom.json | 34 ++
 1 file changed, 34 insertions(+)

diff --git a/qapi/qom.json b/qapi/qom.json
index 30ed179bc1..1dbc95fb53 100644
--- a/qapi/qom.json
+++ b/qapi/qom.json
@@ -204,6 +204,34 @@
   'returns': [ 'ObjectPropertyInfo' ],
   'allow-preconfig': true }
 
+##
+# @CryptodevBackendProperties:
+#
+# Properties for cryptodev-backend and cryptodev-backend-builtin objects.
+#
+# @queues: the number of queues for the cryptodev backend. Ignored for
+#  cryptodev-backend and must be 1 for cryptodev-backend-builtin.
+#  (default: 1)
+#
+# Since: 2.8
+##
+{ 'struct': 'CryptodevBackendProperties',
+  'data': { '*queues': 'uint32' } }
+
+##
+# @CryptodevVhostUserProperties:
+#
+# Properties for cryptodev-vhost-user objects.
+#
+# @chardev: the name of a unix domain socket character device that connects to
+#   the vhost-user server
+#
+# Since: 2.12
+##
+{ 'struct': 'CryptodevVhostUserProperties',
+  'base': 'CryptodevBackendProperties',
+  'data': { 'chardev': 'str' } }
+
 ##
 # @IothreadProperties:
 #
@@ -239,6 +267,9 @@
 'authz-listfile',
 'authz-pam',
 'authz-simple',
+'cryptodev-backend',
+'cryptodev-backend-builtin',
+'cryptodev-vhost-user',
 'iothread'
   ] }
 
@@ -262,6 +293,9 @@
   'authz-listfile': 'AuthZListFileProperties',
   'authz-pam':  'AuthZPAMProperties',
   'authz-simple':   'AuthZSimpleProperties',
+  'cryptodev-backend':  'CryptodevBackendProperties',
+  'cryptodev-backend-builtin':  'CryptodevBackendProperties',
+  'cryptodev-vhost-user':   'CryptodevVhostUserProperties',
   'iothread':   'IothreadProperties'
   } }
 
-- 
2.29.2



[PATCH v2 20/31] qom: Make "object" QemuOptsList optional

2021-02-24 Thread Kevin Wolf
This code is going away anyway, but for a few more commits, we'll be in
a state where some binaries still use QemuOpts and others don't. If the
"object" QemuOptsList doesn't even exist, we don't have to remove (or
fail to remove, and therefore abort) a user creatable object from it.

Signed-off-by: Kevin Wolf 
---
 qom/object_interfaces.c | 7 +--
 1 file changed, 5 insertions(+), 2 deletions(-)

diff --git a/qom/object_interfaces.c b/qom/object_interfaces.c
index 1e9ad6f08a..b9a99c8bf4 100644
--- a/qom/object_interfaces.c
+++ b/qom/object_interfaces.c
@@ -290,6 +290,7 @@ void user_creatable_print_help_from_qdict(QDict *args)
 
 bool user_creatable_del(const char *id, Error **errp)
 {
+QemuOptsList *opts_list;
 Object *container;
 Object *obj;
 
@@ -309,8 +310,10 @@ bool user_creatable_del(const char *id, Error **errp)
  * if object was defined on the command-line, remove its corresponding
  * option group entry
  */
-qemu_opts_del(qemu_opts_find(qemu_find_opts_err("object", _abort),
- id));
+opts_list = qemu_find_opts_err("object", NULL);
+if (opts_list) {
+qemu_opts_del(qemu_opts_find(opts_list, id));
+}
 
 object_unparent(obj);
 return true;
-- 
2.29.2



[PATCH v2 14/31] qapi/qom: Add ObjectOptions for filter-*

2021-02-24 Thread Kevin Wolf
This adds a QAPI schema for the properties of the filter-* objects.

Some parts of the interface (in particular NetfilterProperties.position)
are very unusual for QAPI, but for now just describe the existing
interface.

net.json can't be included in qom.json because the storage daemon
doesn't have it. NetFilterDirection is still required in the new object
property definitions in qom.json, so move this enum to common.json.

Signed-off-by: Kevin Wolf 
---
 qapi/common.json |  20 +++
 qapi/net.json|  20 ---
 qapi/qom.json| 143 +++
 3 files changed, 163 insertions(+), 20 deletions(-)

diff --git a/qapi/common.json b/qapi/common.json
index 2dad4fadc3..b87e7f9039 100644
--- a/qapi/common.json
+++ b/qapi/common.json
@@ -165,3 +165,23 @@
 ##
 { 'enum': 'HostMemPolicy',
   'data': [ 'default', 'preferred', 'bind', 'interleave' ] }
+
+##
+# @NetFilterDirection:
+#
+# Indicates whether a netfilter is attached to a netdev's transmit queue or
+# receive queue or both.
+#
+# @all: the filter is attached both to the receive and the transmit
+#   queue of the netdev (default).
+#
+# @rx: the filter is attached to the receive queue of the netdev,
+#  where it will receive packets sent to the netdev.
+#
+# @tx: the filter is attached to the transmit queue of the netdev,
+#  where it will receive packets sent by the netdev.
+#
+# Since: 2.5
+##
+{ 'enum': 'NetFilterDirection',
+  'data': [ 'all', 'rx', 'tx' ] }
diff --git a/qapi/net.json b/qapi/net.json
index c31748c87f..af3f5b0fda 100644
--- a/qapi/net.json
+++ b/qapi/net.json
@@ -492,26 +492,6 @@
 'vhost-user': 'NetdevVhostUserOptions',
 'vhost-vdpa': 'NetdevVhostVDPAOptions' } }
 
-##
-# @NetFilterDirection:
-#
-# Indicates whether a netfilter is attached to a netdev's transmit queue or
-# receive queue or both.
-#
-# @all: the filter is attached both to the receive and the transmit
-#   queue of the netdev (default).
-#
-# @rx: the filter is attached to the receive queue of the netdev,
-#  where it will receive packets sent to the netdev.
-#
-# @tx: the filter is attached to the transmit queue of the netdev,
-#  where it will receive packets sent by the netdev.
-#
-# Since: 2.5
-##
-{ 'enum': 'NetFilterDirection',
-  'data': [ 'all', 'rx', 'tx' ] }
-
 ##
 # @RxState:
 #
diff --git a/qapi/qom.json b/qapi/qom.json
index 8e4414f843..e3357f5123 100644
--- a/qapi/qom.json
+++ b/qapi/qom.json
@@ -313,6 +313,137 @@
   'data': { 'addr': 'str' ,
 '*id-list': 'str' } }
 
+##
+# @NetfilterInsert:
+#
+# Indicates where to insert a netfilter relative to a given other filter.
+#
+# @before: insert before the specified filter
+#
+# @behind: insert behind the specified filter
+#
+# Since: 5.0
+##
+{ 'enum': 'NetfilterInsert',
+  'data': [ 'before', 'behind' ] }
+
+##
+# @NetfilterProperties:
+#
+# Properties for objects of classes derived from netfilter.
+#
+# @netdev: id of the network device backend to filter
+#
+# @queue: indicates which queue(s) to filter (default: all)
+#
+# @status: indicates whether the filter is enabled ("on") or disabled ("off")
+#  (default: "on")
+#
+# @position: specifies where the filter should be inserted in the filter list.
+#"head" means the filter is inserted at the head of the filter 
list,
+#before any existing filters.
+#"tail" means the filter is inserted at the tail of the filter 
list,
+#behind any existing filters (default).
+#"id=" means the filter is inserted before or behind the filter
+#specified by , depending on the @insert property.
+#(default: "tail")
+#
+# @insert: where to insert the filter relative to the filter given in 
@position.
+#  Ignored if @position is "head" or "tail". (default: behind)
+#
+# Since: 2.5
+##
+{ 'struct': 'NetfilterProperties',
+  'data': { 'netdev': 'str',
+'*queue': 'NetFilterDirection',
+'*status': 'str',
+'*position': 'str',
+'*insert': 'NetfilterInsert' } }
+
+##
+# @FilterBufferProperties:
+#
+# Properties for filter-buffer objects.
+#
+# @interval: a non-zero interval in microseconds.  All packets arriving in the
+#given interval are delayed until the end of the interval.
+#
+# Since: 2.5
+##
+{ 'struct': 'FilterBufferProperties',
+  'base': 'NetfilterProperties',
+  'data': { 'interval': 'uint32' } }
+
+##
+# @FilterDumpProperties:
+#
+# Properties for filter-dump objects.
+#
+# @file: the filename where the dumped packets should be stored
+#
+# @maxlen: maximum number of bytes in a packet that are stored (default: 65536)
+#
+# Since: 2.5
+##
+{ 'struct': 'FilterDumpProperties',
+  'base': 'NetfilterProperties',
+  'data': { 'file': 'str',
+'*maxlen': 'uint32' } }
+
+##
+# @FilterMirrorProperties:
+#
+# Properties for filter-mirror objects.
+#
+# @outdev: the name of a character device backend to which all incoming packets
+#

[PATCH v2 10/31] qapi/qom: Add ObjectOptions for secret*, deprecate 'loaded'

2021-02-24 Thread Kevin Wolf
This adds a QAPI schema for the properties of the secret* objects.

The 'loaded' property doesn't seem to make sense as an external
interface: It is automatically set to true in ucc->complete, and
explicitly setting it to true earlier just means that additional options
will be silently ignored.

In other words, the 'loaded' property is useless. Mark it as deprecated
in the schema from the start.

Signed-off-by: Kevin Wolf 
---
 qapi/crypto.json   | 61 ++
 qapi/qom.json  |  5 
 docs/system/deprecated.rst | 11 +++
 3 files changed, 77 insertions(+)

diff --git a/qapi/crypto.json b/qapi/crypto.json
index 2aebe6fa20..0fef3de66d 100644
--- a/qapi/crypto.json
+++ b/qapi/crypto.json
@@ -381,3 +381,64 @@
   'discriminator': 'format',
   'data': {
   'luks': 'QCryptoBlockAmendOptionsLUKS' } }
+
+##
+# @SecretCommonProperties:
+#
+# Properties for objects of classes derived from secret-common.
+#
+# @loaded: if true, the secret is loaded immediately when applying this option
+#  and will probably fail when processing the next option. Don't use;
+#  only provided for compatibility. (default: false)
+#
+# @format: the data format that the secret is provided in (default: raw)
+#
+# @keyid: the name of another secret that should be used to decrypt the
+# provided data. If not present, the data is assumed to be unencrypted.
+#
+# @iv: the random initialization vector used for encryption of this particular
+#  secret. Should be a base64 encrypted string of the 16-byte IV. Mandatory
+#  if @keyid is given. Ignored if @keyid is absent.
+#
+# Features:
+# @deprecated: Member @loaded is deprecated.  Setting true doesn't make sense,
+#  and false is already the default.
+#
+# Since: 2.6
+##
+{ 'struct': 'SecretCommonProperties',
+  'data': { '*loaded': { 'type': 'bool', 'features': ['deprecated'] },
+'*format': 'QCryptoSecretFormat',
+'*keyid': 'str',
+'*iv': 'str' } }
+
+##
+# @SecretProperties:
+#
+# Properties for secret objects.
+#
+# Either @data or @file must be provided, but not both.
+#
+# @data: the associated with the secret from
+#
+# @file: the filename to load the data associated with the secret from
+#
+# Since: 2.6
+##
+{ 'struct': 'SecretProperties',
+  'base': 'SecretCommonProperties',
+  'data': { '*data': 'str',
+'*file': 'str' } }
+
+##
+# @SecretKeyringProperties:
+#
+# Properties for secret_keyring objects.
+#
+# @serial: serial number that identifies a key to get from the kernel
+#
+# Since: 5.1
+##
+{ 'struct': 'SecretKeyringProperties',
+  'base': 'SecretCommonProperties',
+  'data': { 'serial': 'int32' } }
diff --git a/qapi/qom.json b/qapi/qom.json
index 449dca8ec5..2668ad8369 100644
--- a/qapi/qom.json
+++ b/qapi/qom.json
@@ -7,6 +7,7 @@
 { 'include': 'authz.json' }
 { 'include': 'block-core.json' }
 { 'include': 'common.json' }
+{ 'include': 'crypto.json' }
 
 ##
 # = QEMU Object Model (QOM)
@@ -449,6 +450,8 @@
 'rng-builtin',
 'rng-egd',
 'rng-random',
+'secret',
+'secret_keyring',
 'throttle-group'
   ] }
 
@@ -483,6 +486,8 @@
   'rng-builtin':'RngProperties',
   'rng-egd':'RngEgdProperties',
   'rng-random': 'RngRandomProperties',
+  'secret': 'SecretProperties',
+  'secret_keyring': 'SecretKeyringProperties',
   'throttle-group': 'ThrottleGroupProperties'
   } }
 
diff --git a/docs/system/deprecated.rst b/docs/system/deprecated.rst
index 79991c2893..78b175cb59 100644
--- a/docs/system/deprecated.rst
+++ b/docs/system/deprecated.rst
@@ -155,6 +155,17 @@ other options have been processed.  This will either have 
no effect (if
 ``opened`` was the last option) or cause errors.  The property is therefore
 useless and should not be specified.
 
+``loaded`` property of ``secret`` and ``secret_keyring`` objects (since 6.0.0)
+''
+
+The only effect of specifying ``loaded=on`` in the command line or QMP
+``object-add`` is that the secret is loaded immediately, possibly before all
+other options have been processed.  This will either have no effect (if
+``loaded`` was the last option) or cause options to be effectively ignored as
+if they were not given.  The property is therefore useless and should not be
+specified.
+
+
 QEMU Machine Protocol (QMP) commands
 
 
-- 
2.29.2



[PATCH v2 08/31] qapi/qom: Add ObjectOptions for rng-*, deprecate 'opened'

2021-02-24 Thread Kevin Wolf
This adds a QAPI schema for the properties of the rng-* objects.

The 'opened' property doesn't seem to make sense as an external
interface: It is automatically set to true in ucc->complete, and
explicitly setting it to true earlier just means that trying to set
additional options will result in an error. After the property has once
been set to true (i.e. when the object construction has completed), it
can never be reset to false. In other words, the 'opened' property is
useless. Mark it as deprecated in the schema from the start.

Signed-off-by: Kevin Wolf 
---
 qapi/qom.json  | 56 --
 docs/system/deprecated.rst |  9 ++
 2 files changed, 63 insertions(+), 2 deletions(-)

diff --git a/qapi/qom.json b/qapi/qom.json
index 1a869006a1..73f28f9608 100644
--- a/qapi/qom.json
+++ b/qapi/qom.json
@@ -380,6 +380,52 @@
 '*hugetlbsize': 'size',
 '*seal': 'bool' } }
 
+##
+# @RngProperties:
+#
+# Properties for objects of classes derived from rng.
+#
+# @opened: if true, the device is opened immediately when applying this option
+#  and will probably fail when processing the next option. Don't use;
+#  only provided for compatibility. (default: false)
+#
+# Features:
+# @deprecated: Member @opened is deprecated.  Setting true doesn't make sense,
+#  and false is already the default.
+#
+# Since: 1.3
+##
+{ 'struct': 'RngProperties',
+  'data': { '*opened': { 'type': 'bool', 'features': ['deprecated'] } } }
+
+##
+# @RngEgdProperties:
+#
+# Properties for rng-egd objects.
+#
+# @chardev: the name of a character device backend that provides the connection
+#   to the RNG daemon
+#
+# Since: 1.3
+##
+{ 'struct': 'RngEgdProperties',
+  'base': 'RngProperties',
+  'data': { 'chardev': 'str' } }
+
+##
+# @RngRandomProperties:
+#
+# Properties for rng-random objects.
+#
+# @filename: the filename of the device on the host to obtain entropy from
+#(default: "/dev/urandom")
+#
+# Since: 1.3
+##
+{ 'struct': 'RngRandomProperties',
+  'base': 'RngProperties',
+  'data': { '*filename': 'str' } }
+
 ##
 # @ObjectType:
 #
@@ -398,7 +444,10 @@
 'iothread',
 'memory-backend-file',
 'memory-backend-memfd',
-'memory-backend-ram'
+'memory-backend-ram',
+'rng-builtin',
+'rng-egd',
+'rng-random'
   ] }
 
 ##
@@ -428,7 +477,10 @@
   'iothread':   'IothreadProperties',
   'memory-backend-file':'MemoryBackendFileProperties',
   'memory-backend-memfd':   'MemoryBackendMemfdProperties',
-  'memory-backend-ram': 'MemoryBackendProperties'
+  'memory-backend-ram': 'MemoryBackendProperties',
+  'rng-builtin':'RngProperties',
+  'rng-egd':'RngEgdProperties',
+  'rng-random': 'RngRandomProperties'
   } }
 
 ##
diff --git a/docs/system/deprecated.rst b/docs/system/deprecated.rst
index 00b694e053..79991c2893 100644
--- a/docs/system/deprecated.rst
+++ b/docs/system/deprecated.rst
@@ -146,6 +146,15 @@ library enabled as a cryptography provider.
 Neither the ``nettle`` library, or the built-in cryptography provider are
 supported on FIPS enabled hosts.
 
+``opened`` property of ``rng-*`` objects (since 6.0.0)
+''
+
+The only effect of specifying ``opened=on`` in the command line or QMP
+``object-add`` is that the device is opened immediately, possibly before all
+other options have been processed.  This will either have no effect (if
+``opened`` was the last option) or cause errors.  The property is therefore
+useless and should not be specified.
+
 QEMU Machine Protocol (QMP) commands
 
 
-- 
2.29.2



[PATCH v2 03/31] qapi/qom: Add ObjectOptions for iothread

2021-02-24 Thread Kevin Wolf
Add an ObjectOptions union that will eventually describe the options of
all user creatable object types. As unions can't exist without any
branches, also add the first object type.

This adds a QAPI schema for the properties of the iothread object.

Signed-off-by: Kevin Wolf 
---
 qapi/qom.json | 53 +++
 1 file changed, 53 insertions(+)

diff --git a/qapi/qom.json b/qapi/qom.json
index 96c91c1faf..bf2ecb34be 100644
--- a/qapi/qom.json
+++ b/qapi/qom.json
@@ -202,6 +202,59 @@
   'returns': [ 'ObjectPropertyInfo' ],
   'allow-preconfig': true }
 
+##
+# @IothreadProperties:
+#
+# Properties for iothread objects.
+#
+# @poll-max-ns: the maximum number of nanoseconds to busy wait for events.
+#   0 means polling is disabled (default: 32768 on POSIX hosts,
+#   0 otherwise)
+#
+# @poll-grow: the multiplier used to increase the polling time when the
+# algorithm detects it is missing events due to not polling long
+# enough. 0 selects a default behaviour (default: 0)
+#
+# @poll-shrink: the divisor used to decrease the polling time when the
+#   algorithm detects it is spending too long polling without
+#   encountering events. 0 selects a default behaviour (default: 0)
+#
+# Since: 2.0
+##
+{ 'struct': 'IothreadProperties',
+  'data': { '*poll-max-ns': 'int',
+'*poll-grow': 'int',
+'*poll-shrink': 'int' } }
+
+##
+# @ObjectType:
+#
+# Since: 6.0
+##
+{ 'enum': 'ObjectType',
+  'data': [
+'iothread'
+  ] }
+
+##
+# @ObjectOptions:
+#
+# Describes the options of a user creatable QOM object.
+#
+# @qom-type: the class name for the object to be created
+#
+# @id: the name of the new object
+#
+# Since: 6.0
+##
+{ 'union': 'ObjectOptions',
+  'base': { 'qom-type': 'ObjectType',
+'id': 'str' },
+  'discriminator': 'qom-type',
+  'data': {
+  'iothread':   'IothreadProperties'
+  } }
+
 ##
 # @object-add:
 #
-- 
2.29.2



[PATCH v2 11/31] qapi/qom: Add ObjectOptions for tls-*, deprecate 'loaded'

2021-02-24 Thread Kevin Wolf
This adds a QAPI schema for the properties of the tls-* objects.

The 'loaded' property doesn't seem to make sense as an external
interface: It is automatically set to true in ucc->complete, and
explicitly setting it to true earlier just means that additional options
will be silently ignored.

In other words, the 'loaded' property is useless. Mark it as deprecated
in the schema from the start.

Signed-off-by: Kevin Wolf 
---
 qapi/crypto.json | 98 
 qapi/qom.json| 12 +-
 2 files changed, 108 insertions(+), 2 deletions(-)

diff --git a/qapi/crypto.json b/qapi/crypto.json
index 0fef3de66d..7116ae9a46 100644
--- a/qapi/crypto.json
+++ b/qapi/crypto.json
@@ -442,3 +442,101 @@
 { 'struct': 'SecretKeyringProperties',
   'base': 'SecretCommonProperties',
   'data': { 'serial': 'int32' } }
+
+##
+# @TlsCredsProperties:
+#
+# Properties for objects of classes derived from tls-creds.
+#
+# @verify-peer: if true the peer credentials will be verified once the
+#   handshake is completed.  This is a no-op for anonymous
+#   credentials. (default: true)
+#
+# @dir: the path of the directory that contains the credential files
+#
+# @endpoint: whether the QEMU network backend that uses the credentials will be
+#acting as a client or as a server (default: client)
+#
+# @priority: a gnutls priority string as described at
+#https://gnutls.org/manual/html_node/Priority-Strings.html
+#
+# Since: 2.5
+##
+{ 'struct': 'TlsCredsProperties',
+  'data': { '*verify-peer': 'bool',
+'*dir': 'str',
+'*endpoint': 'QCryptoTLSCredsEndpoint',
+'*priority': 'str' } }
+
+##
+# @TlsCredsAnonProperties:
+#
+# Properties for tls-creds-anon objects.
+#
+# @loaded: if true, the credentials are loaded immediately when applying this
+#  option and will ignore options that are processed later. Don't use;
+#  only provided for compatibility. (default: false)
+#
+# Features:
+# @deprecated: Member @loaded is deprecated.  Setting true doesn't make sense,
+#  and false is already the default.
+#
+# Since: 2.5
+##
+{ 'struct': 'TlsCredsAnonProperties',
+  'base': 'TlsCredsProperties',
+  'data': { '*loaded': { 'type': 'bool', 'features': ['deprecated'] } } }
+
+##
+# @TlsCredsPskProperties:
+#
+# Properties for tls-creds-psk objects.
+#
+# @loaded: if true, the credentials are loaded immediately when applying this
+#  option and will ignore options that are processed later. Don't use;
+#  only provided for compatibility. (default: false)
+#
+# @username: the username which will be sent to the server.  For clients only.
+#If absent, "qemu" is sent and the property will read back as an
+#empty string.
+#
+# Features:
+# @deprecated: Member @loaded is deprecated.  Setting true doesn't make sense,
+#  and false is already the default.
+#
+# Since: 3.0
+##
+{ 'struct': 'TlsCredsPskProperties',
+  'base': 'TlsCredsProperties',
+  'data': { '*loaded': { 'type': 'bool', 'features': ['deprecated'] },
+'*username': 'str' } }
+
+##
+# @TlsCredsX509Properties:
+#
+# Properties for tls-creds-x509 objects.
+#
+# @loaded: if true, the credentials are loaded immediately when applying this
+#  option and will ignore options that are processed later. Don't use;
+#  only provided for compatibility. (default: false)
+#
+# @sanity-check: if true, perform some sanity checks before using the
+#credentials (default: true)
+#
+# @passwordid: For the server-key.pem and client-key.pem files which contain
+#  sensitive private keys, it is possible to use an encrypted
+#  version by providing the @passwordid parameter.  This provides
+#  the ID of a previously created secret object containing the
+#  password for decryption.
+#
+# Features:
+# @deprecated: Member @loaded is deprecated.  Setting true doesn't make sense,
+#  and false is already the default.
+#
+# Since: 2.5
+##
+{ 'struct': 'TlsCredsX509Properties',
+  'base': 'TlsCredsProperties',
+  'data': { '*loaded': { 'type': 'bool', 'features': ['deprecated'] },
+'*sanity-check': 'bool',
+'*passwordid': 'str' } }
diff --git a/qapi/qom.json b/qapi/qom.json
index 2668ad8369..f22b7aa99b 100644
--- a/qapi/qom.json
+++ b/qapi/qom.json
@@ -452,7 +452,11 @@
 'rng-random',
 'secret',
 'secret_keyring',
-'throttle-group'
+'throttle-group',
+'tls-creds-anon',
+'tls-creds-psk',
+'tls-creds-x509',
+'tls-cipher-suites'
   ] }
 
 ##
@@ -488,7 +492,11 @@
   'rng-random': 'RngRandomProperties',
   'secret': 'SecretProperties',
   'secret_keyring': 'SecretKeyringProperties',
-  'throttle-group': 'ThrottleGroupProperties'
+  'throttle-group': 'ThrottleGroupProperties',
+  

[PATCH v2 13/31] qapi/qom: Add ObjectOptions for colo-compare

2021-02-24 Thread Kevin Wolf
This adds a QAPI schema for the properties of the colo-compare object.

Signed-off-by: Kevin Wolf 
---
 qapi/qom.json | 49 +
 1 file changed, 49 insertions(+)

diff --git a/qapi/qom.json b/qapi/qom.json
index 4b1cd4b8dc..8e4414f843 100644
--- a/qapi/qom.json
+++ b/qapi/qom.json
@@ -222,6 +222,53 @@
   'data': { 'if': 'str',
 'canbus': 'str' } }
 
+##
+# @ColoCompareProperties:
+#
+# Properties for colo-compare objects.
+#
+# @primary_in: name of the character device backend to use for the primary
+#  input (incoming packets are redirected to @outdev)
+#
+# @secondary_in: name of the character device backend to use for secondary
+#input (incoming packets are only compared to the input on
+#@primary_in and then dropped)
+#
+# @outdev: name of the character device backend to use for output
+#
+# @iothread: name of the iothread to run in
+#
+# @notify_dev: name of the character device backend to be used to communicate
+#  with the remote colo-frame (only for Xen COLO)
+#
+# @compare_timeout: the maximum time to hold a packet from @primary_in for
+#   comparison with an incoming packet on @secondary_in in
+#   milliseconds (default: 3000)
+#
+# @expired_scan_cycle: the interval at which colo-compare checks whether
+#  packets from @primary have timed out, in milliseconds
+#  (default: 3000)
+#
+# @max_queue_size: the maximum number of packets to keep in the queue for
+#  comparing with incoming packets from @secondary_in.  If the
+#  queue is full and addtional packets are received, the
+#  addtional packets are dropped. (default: 1024)
+#
+# @vnet_hdr_support: if true, vnet header support is enabled (default: false)
+#
+# Since: 2.8
+##
+{ 'struct': 'ColoCompareProperties',
+  'data': { 'primary_in': 'str',
+'secondary_in': 'str',
+'outdev': 'str',
+'iothread': 'str',
+'*notify_dev': 'str',
+'*compare_timeout': 'uint64',
+'*expired_scan_cycle': 'uint32',
+'*max_queue_size': 'uint32',
+'*vnet_hdr_support': 'bool' } }
+
 ##
 # @CryptodevBackendProperties:
 #
@@ -456,6 +503,7 @@
 'authz-simple',
 'can-bus',
 'can-host-socketcan',
+'colo-compare',
 'cryptodev-backend',
 'cryptodev-backend-builtin',
 'cryptodev-vhost-user',
@@ -497,6 +545,7 @@
   'authz-pam':  'AuthZPAMProperties',
   'authz-simple':   'AuthZSimpleProperties',
   'can-host-socketcan': 'CanHostSocketcanProperties',
+  'colo-compare':   'ColoCompareProperties',
   'cryptodev-backend':  'CryptodevBackendProperties',
   'cryptodev-backend-builtin':  'CryptodevBackendProperties',
   'cryptodev-vhost-user':   'CryptodevVhostUserProperties',
-- 
2.29.2



[PATCH v2 12/31] qapi/qom: Add ObjectOptions for can-*

2021-02-24 Thread Kevin Wolf
This adds a QAPI schema for the properties of the can-* objects.

can-bus doesn't have any properties, so it only needs to be added to the
ObjectType enum without adding a new branch to ObjectOptions.

Signed-off-by: Kevin Wolf 
---
 qapi/qom.json | 18 ++
 1 file changed, 18 insertions(+)

diff --git a/qapi/qom.json b/qapi/qom.json
index f22b7aa99b..4b1cd4b8dc 100644
--- a/qapi/qom.json
+++ b/qapi/qom.json
@@ -207,6 +207,21 @@
   'returns': [ 'ObjectPropertyInfo' ],
   'allow-preconfig': true }
 
+##
+# @CanHostSocketcanProperties:
+#
+# Properties for can-host-socketcan objects.
+#
+# @if: interface name of the host system CAN bus to connect to
+#
+# @canbus: object ID of the can-bus object to connect to the host interface
+#
+# Since: 2.12
+##
+{ 'struct': 'CanHostSocketcanProperties',
+  'data': { 'if': 'str',
+'canbus': 'str' } }
+
 ##
 # @CryptodevBackendProperties:
 #
@@ -439,6 +454,8 @@
 'authz-listfile',
 'authz-pam',
 'authz-simple',
+'can-bus',
+'can-host-socketcan',
 'cryptodev-backend',
 'cryptodev-backend-builtin',
 'cryptodev-vhost-user',
@@ -479,6 +496,7 @@
   'authz-listfile': 'AuthZListFileProperties',
   'authz-pam':  'AuthZPAMProperties',
   'authz-simple':   'AuthZSimpleProperties',
+  'can-host-socketcan': 'CanHostSocketcanProperties',
   'cryptodev-backend':  'CryptodevBackendProperties',
   'cryptodev-backend-builtin':  'CryptodevBackendProperties',
   'cryptodev-vhost-user':   'CryptodevVhostUserProperties',
-- 
2.29.2



[PATCH v2 17/31] qapi/qom: Add ObjectOptions for input-*

2021-02-24 Thread Kevin Wolf
This adds a QAPI schema for the properties of the input-* objects.

ui.json cannot be included in qom.json because the storage daemon can't
use it, so move GrabToggleKeys to common.json.

Signed-off-by: Kevin Wolf 
---
 qapi/common.json | 12 ++
 qapi/qom.json| 58 
 qapi/ui.json | 13 +--
 3 files changed, 71 insertions(+), 12 deletions(-)

diff --git a/qapi/common.json b/qapi/common.json
index b87e7f9039..7c976296f0 100644
--- a/qapi/common.json
+++ b/qapi/common.json
@@ -185,3 +185,15 @@
 ##
 { 'enum': 'NetFilterDirection',
   'data': [ 'all', 'rx', 'tx' ] }
+
+##
+# @GrabToggleKeys:
+#
+# Keys to toggle input-linux between host and guest.
+#
+# Since: 4.0
+#
+##
+{ 'enum': 'GrabToggleKeys',
+  'data': [ 'ctrl-ctrl', 'alt-alt', 'shift-shift','meta-meta', 'scrolllock',
+'ctrl-scrolllock' ] }
diff --git a/qapi/qom.json b/qapi/qom.json
index d5f68b5c89..f8ff322df0 100644
--- a/qapi/qom.json
+++ b/qapi/qom.json
@@ -444,6 +444,60 @@
   'base': 'NetfilterProperties',
   'data': { '*vnet_hdr_support': 'bool' } }
 
+##
+# @InputBarrierProperties:
+#
+# Properties for input-barrier objects.
+#
+# @name: the screen name as declared in the screens section of barrier.conf
+#
+# @server: hostname of the Barrier server (default: "localhost")
+#
+# @port: TCP port of the Barrier server (default: "24800")
+#
+# @x-origin: x coordinate of the leftmost pixel on the guest screen
+#(default: "0")
+#
+# @y-origin: y coordinate of he topmost pixel on the guest screen (default: 
"0")
+#
+# @width: the width of secondary screen in pixels (default: "1920")
+#
+# @height: the height of secondary screen in pixels (default: "1080")
+#
+# Since: 4.2
+##
+{ 'struct': 'InputBarrierProperties',
+  'data': { 'name': 'str',
+'*server': 'str',
+'*port': 'str',
+'*x-origin': 'str',
+'*y-origin': 'str',
+'*width': 'str',
+'*height': 'str' } }
+
+##
+# @InputLinuxProperties:
+#
+# Properties for input-linux objects.
+#
+# @evdev: the path of the host evdev device to use
+#
+# @grab_all: if true, grab is toggled for all devices (e.g. both keyboard and
+#mouse) instead of just one device (default: false)
+#
+# @repeat: enables auto-repeat events (default: false)
+#
+# @grab-toggle: the key or key combination that toggles device grab
+#   (default: ctrl-ctrl)
+#
+# Since: 2.6
+##
+{ 'struct': 'InputLinuxProperties',
+  'data': { 'evdev': 'str',
+'*grab_all': 'bool',
+'*repeat': 'bool',
+'*grab-toggle': 'GrabToggleKeys' } }
+
 ##
 # @IothreadProperties:
 #
@@ -689,6 +743,8 @@
 'filter-redirector',
 'filter-replay',
 'filter-rewriter',
+'input-barrier',
+'input-linux',
 'iothread',
 'memory-backend-file',
 'memory-backend-memfd',
@@ -741,6 +797,8 @@
   'filter-redirector':  'FilterRedirectorProperties',
   'filter-replay':  'NetfilterProperties',
   'filter-rewriter':'FilterRewriterProperties',
+  'input-barrier':  'InputBarrierProperties',
+  'input-linux':'InputLinuxProperties',
   'iothread':   'IothreadProperties',
   'memory-backend-file':'MemoryBackendFileProperties',
   'memory-backend-memfd':   'MemoryBackendMemfdProperties',
diff --git a/qapi/ui.json b/qapi/ui.json
index d08d72b439..cc1882108b 100644
--- a/qapi/ui.json
+++ b/qapi/ui.json
@@ -6,6 +6,7 @@
 # = Remote desktop
 ##
 
+{ 'include': 'common.json' }
 { 'include': 'sockets.json' }
 
 ##
@@ -1021,18 +1022,6 @@
 '*head'  : 'int',
 'events' : [ 'InputEvent' ] } }
 
-##
-# @GrabToggleKeys:
-#
-# Keys to toggle input-linux between host and guest.
-#
-# Since: 4.0
-#
-##
-{ 'enum': 'GrabToggleKeys',
-  'data': [ 'ctrl-ctrl', 'alt-alt', 'shift-shift','meta-meta', 'scrolllock',
-'ctrl-scrolllock' ] }
-
 ##
 # @DisplayGTK:
 #
-- 
2.29.2



[PATCH v2 16/31] qapi/qom: Add ObjectOptions for confidential-guest-support

2021-02-24 Thread Kevin Wolf
This adds a QAPI schema for the properties of the objects implementing
the confidential-guest-support interface.

pef-guest and s390x-pv-guest don't have any properties, so they only
need to be added to the ObjectType enum without adding a new branch to
ObjectOptions.

Signed-off-by: Kevin Wolf 
---
 qapi/qom.json | 37 +
 1 file changed, 37 insertions(+)

diff --git a/qapi/qom.json b/qapi/qom.json
index e7184122e9..d5f68b5c89 100644
--- a/qapi/qom.json
+++ b/qapi/qom.json
@@ -633,6 +633,38 @@
   'base': 'RngProperties',
   'data': { '*filename': 'str' } }
 
+##
+# @SevGuestProperties:
+#
+# Properties for sev-guest objects.
+#
+# @sev-device: SEV device to use (default: "/dev/sev")
+#
+# @dh-cert-file: guest owners DH certificate (encoded with base64)
+#
+# @session-file: guest owners session parameters (encoded with base64)
+#
+# @policy: SEV policy value (default: 0x1)
+#
+# @handle: SEV firmware handle (default: 0)
+#
+# @cbitpos: C-bit location in page table entry (default: 0)
+#
+# @reduced-phys-bits: number of bits in physical addresses that become
+# unavailable when SEV is enabled
+#
+# Since: 2.12
+##
+{ 'struct': 'SevGuestProperties',
+  'data': { '*sev-device': 'str',
+'*dh-cert-file': 'str',
+'*session-file': 'str',
+'*policy': 'uint32',
+'*handle': 'uint32',
+'*cbitpos': 'uint32',
+'reduced-phys-bits': 'uint32' },
+  'if': 'defined(CONFIG_SEV)' }
+
 ##
 # @ObjectType:
 #
@@ -661,12 +693,15 @@
 'memory-backend-file',
 'memory-backend-memfd',
 'memory-backend-ram',
+{'name': 'pef-guest', 'if': 'defined(CONFIG_PSERIES)' },
 'pr-manager-helper',
 'rng-builtin',
 'rng-egd',
 'rng-random',
 'secret',
 'secret_keyring',
+{'name': 'sev-guest', 'if': 'defined(CONFIG_SEV)' },
+'s390-pv-guest',
 'throttle-group',
 'tls-creds-anon',
 'tls-creds-psk',
@@ -716,6 +751,8 @@
   'rng-random': 'RngRandomProperties',
   'secret': 'SecretProperties',
   'secret_keyring': 'SecretKeyringProperties',
+  'sev-guest':  { 'type': 'SevGuestProperties',
+  'if': 'defined(CONFIG_SEV)' },
   'throttle-group': 'ThrottleGroupProperties',
   'tls-creds-anon': 'TlsCredsAnonProperties',
   'tls-creds-psk':  'TlsCredsPskProperties',
-- 
2.29.2



  1   2   >