Re: [libvirt] [PATCH] conf: utility function to update entry in def->nets array

2019-09-26 Thread Michal Privoznik

On 9/25/19 6:57 PM, Laine Stump wrote:

A virDomainNetDef object in a domain's nets array might contain a
virDomainHostdevDef, and when this is the case, the domain's hostdevs
array will also have a pointer to this embedded hostdev (this is done
so that internal functions that need to perform some operation on all
hostdevs won't leave out the type='hostdev' network interfaces).

When a network device was updated with virDomainUpdateDeviceFlags(),
we were replacing the entry in the nets array (and free'ing the
original) but forgetting about the pointer in the hostdevs array
(which would then point to the now-free'd hostdev contained in the old
net object.) This often resulted in a libvirtd crash.

The solution is to add a function, virDomainNetUpdate(), called by
qemuDomainUpdateDeviceConfig(), that updates the hostdevs array
appropriately along with the nets array.

Resolves: https://bugzilla.redhat.com/1558934
Signed-off-by: Laine Stump 

---

(I actually think that it was a bad idea to have this "reach over"
pointer in the hostdevs array (I can say that, since it was my idea
:-), and want to eliminate it in favor of using an iterator function
for all operations that need to do something to all hostdevs, but this
bug exists on old, maintained branches, and I wouldn't want to require
backporting anything that disruptive to a stable branch.)

Also, I was unable to reproduce the crashes described in the bug
report using current upstream code, but could witness (by adding a
breakpoint in gdb) the stale pointer when running without this patch,
and the correct pointer when running with the patch)


Agreed, refactoring the whole approach would require a significant 
amount of work and it's not worth it only to fix a crasher.




  src/conf/domain_conf.c   | 41 
  src/conf/domain_conf.h   |  1 +
  src/libvirt_private.syms |  1 +
  src/qemu/qemu_driver.c   |  6 --
  4 files changed, 47 insertions(+), 2 deletions(-)




diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c
index 0753904472..5f63c4f51e 100644
--- a/src/qemu/qemu_driver.c
+++ b/src/qemu/qemu_driver.c
@@ -8786,8 +8786,10 @@ qemuDomainUpdateDeviceConfig(virDomainDefPtr vmdef,
   false) < 0)
  return -1;
  
-virDomainNetDefFree(vmdef->nets[pos]);

-vmdef->nets[pos] = net;
+if (virDomainNetUpdate(vmdef, pos, net))
+return -1;
+
+virDomainNetDefFree(oldDev.data.net);
  dev->data.net = NULL;
  break;
  



The same code pattern occurrs in lxcDomainUpdateDeviceConfig() so you 
may want to fix it the same way as you're doing here. With that,


Reviewed-by: Michal Privoznik 

Michal

--
libvir-list mailing list
libvir-list@redhat.com
https://www.redhat.com/mailman/listinfo/libvir-list


Re: [libvirt] [PATCH 4/6] qemu_driver: use VIR_AUTOFREE() with strings 1/3

2019-09-26 Thread Erik Skultety
On Wed, Sep 18, 2019 at 11:56:56AM -0300, Daniel Henrique Barboza wrote:
> VIR_AUTOFREE is a beautiful macro. Let's use it across the board
> inside qemu_driver.c to make the code a bit tidier and smaller,
> sparing VIR_FREE() calls and sometimes a whole 'cleanup'
> label.
>
> This is a huge change due to the amount of char * declared in
> this file, thus let's split it in 3. This is the first part.
>
> Signed-off-by: Daniel Henrique Barboza 
> ---
...

> @@ -3000,7 +2978,7 @@ virQEMUSaveDataWrite(virQEMUSaveDataPtr data,
>  size_t cookie_len = 0;
>  int ret = -1;
>  size_t zerosLen = 0;
> -char *zeros = NULL;
> +VIR_AUTOFREE(char *) zeros = NULL;
>
>  xml_len = strlen(data->xml) + 1;
>  if (data->cookie)
> @@ -3057,7 +3035,6 @@ virQEMUSaveDataWrite(virQEMUSaveDataPtr data,
>  ret = 0;
>
>   cleanup:

^This cleanup can be dropped.

Erik

--
libvir-list mailing list
libvir-list@redhat.com
https://www.redhat.com/mailman/listinfo/libvir-list


Re: [libvirt] [PATCH 0/2] conf: refresh network ports missing from network driver

2019-09-26 Thread Michal Privoznik

On 9/22/19 1:59 AM, Laine Stump wrote:

Patch 2/2 is the actual fix. 1/2 is just to make the fix simpler.

NB: these two patches should also be included with the other patches for
https://bugzilla.redhat.com/1745815

Laine Stump (2):
   conf: take advantage of VIR_AUTO* in virDomainNetCreatePort()
   conf: refresh network ports missing from network driver on restart

  src/conf/domain_conf.c   | 82 +++-
  src/conf/virnetworkportdef.h |  1 +
  2 files changed, 44 insertions(+), 39 deletions(-)




Reviewed-by: Michal Privoznik 

And I don't care if you squash 1.5/2 into 1/2 as you suggest or push it 
as a separate patch. But please address my comments first.


Michal

--
libvir-list mailing list
libvir-list@redhat.com
https://www.redhat.com/mailman/listinfo/libvir-list


Re: [libvirt] [PATCH 1.5/3] conf: use VIR_AUTOPTR as much as possible for virNetworkPortDefPtr

2019-09-26 Thread Michal Privoznik

On 9/23/19 3:08 AM, Laine Stump wrote:

Since the VIR_DEFINE_AUTOPTR_FUNC() was added for
virNetworkPortDefPtr, I decided to convert all uses of
virNetworkPortDefPtr that were appropriate to use VIR_AUTOPTR. This could be
squashed into patch 1/2, or left separate, or just completely dropped.

Signed-off-by: Laine Stump 
---
  src/conf/domain_conf.c| 58 ++-
  src/conf/virnetworkobj.c  |  3 +-
  src/conf/virnetworkportdef.c  | 52 +--
  tests/virnetworkportxml2xmltest.c |  3 +-
  4 files changed, 53 insertions(+), 63 deletions(-)

diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c
index d1e7ac84e8..d638c455d0 100644
--- a/src/conf/domain_conf.c
+++ b/src/conf/domain_conf.c
@@ -30565,7 +30565,8 @@ virNetworkPortDefPtr
  virDomainNetDefToNetworkPort(virDomainDefPtr dom,
   virDomainNetDefPtr iface)
  {
-virNetworkPortDefPtr port;
+VIR_AUTOPTR(virNetworkPortDef) port = NULL;
+virNetworkPortDefPtr portret = NULL;


Here and in the rest of the patch you don need to introduce XXXret 
variable, because ...


  



-return port;
-
- error:
-virNetworkPortDefFree(port);
-return NULL;
+VIR_STEAL_PTR(portret, port);
+return portret;


.. you can just use VIR_RETURN_PTR(port);


  }



Also, there is one more occurrence of virNetworkPortDefFree() in 
networkPortCreateXML() in src/network/bridge_driver.c. In fact, code 
inspection says that virNetworkPortDef might be leaked there (for 
instance if checks involving @portdef in the middle of the function 
fail), so please squash this in:


diff --git i/src/network/bridge_driver.c w/src/network/bridge_driver.c
index c54be96407..f9ef7eeb6f 100644
--- i/src/network/bridge_driver.c
+++ w/src/network/bridge_driver.c
@@ -5571,7 +5571,7 @@ networkPortCreateXML(virNetworkPtr net,
 virNetworkDriverStatePtr driver = networkGetDriver();
 virNetworkObjPtr obj;
 virNetworkDefPtr def;
-virNetworkPortDefPtr portdef = NULL;
+VIR_AUTOPTR(virNetworkPortDef) portdef = NULL;
 virNetworkPortPtr ret = NULL;
 int rc;

@@ -5621,13 +5621,13 @@ networkPortCreateXML(virNetworkPtr net,

 virErrorPreserveLast(_err);
 ignore_value(networkReleasePort(obj, portdef));
-virNetworkPortDefFree(portdef);
 virErrorRestore(_err);

 goto cleanup;
 }

 ret = virGetNetworkPort(net, portdef->uuid);
+portdef = NULL;
  cleanup:
 virNetworkObjEndAPI();
 return ret;


Michal

--
libvir-list mailing list
libvir-list@redhat.com
https://www.redhat.com/mailman/listinfo/libvir-list


Re: [libvirt] [PATCH 2/6] qemu_driver: use VIR_AUTOUNREF() with virQEMUDriverConfigPtr 2/3

2019-09-26 Thread Erik Skultety
On Wed, Sep 18, 2019 at 11:56:54AM -0300, Daniel Henrique Barboza wrote:
> virQEMUDriverConfigPtr can be auto-unref for the great majority
> of the uses made in qemu_driver, sparing us a virObjectUnref()
> call and sometimes a whole 'cleanup' label.
>
> This patch changes virQEMUDriverConfigPtr declarations to
> use VIR_AUTOUNREF(). 'cleanup' labels were deleted when
> applicable.
>
> Since there are a lot of references to change, let's do it in
> 3 steps. This is step 2.
>
> Signed-off-by: Daniel Henrique Barboza 
> ---
...

> @@ -6360,7 +6348,7 @@ qemuDomainChgIOThread(virQEMUDriverPtr driver,
>virDomainIOThreadAction action,
>unsigned int flags)
>  {
> -virQEMUDriverConfigPtr cfg = NULL;
> +VIR_AUTOUNREF(virQEMUDriverConfigPtr) cfg = NULL;
>  qemuDomainObjPrivatePtr priv;
>  virDomainDefPtr def;
>  virDomainDefPtr persistentDef;
> @@ -6460,7 +6448,6 @@ qemuDomainChgIOThread(virQEMUDriverPtr driver,
>  qemuDomainObjEndJob(driver, vm);
>
>   cleanup:

This 'cleanup' label can be dropped.

Erik

--
libvir-list mailing list
libvir-list@redhat.com
https://www.redhat.com/mailman/listinfo/libvir-list


Re: [libvirt] [PATCH 6/6] qemu_driver: use VIR_AUTOFREE() with strings 3/3

2019-09-26 Thread Erik Skultety
On Wed, Sep 18, 2019 at 11:56:58AM -0300, Daniel Henrique Barboza wrote:
> VIR_AUTOFREE is a beautiful macro. Let's use it across the board
> inside qemu_driver.c to make the code a bit tidier and smaller,
> sparing VIR_FREE() calls and sometimes a whole 'cleanup'
> label.
>
> This is the last part of this change.
>
> Signed-off-by: Daniel Henrique Barboza 
> ---
...

>
> @@ -22506,7 +22479,7 @@ qemuDomainRenameCallback(virDomainObjPtr vm,
>  if (virFileIsLink(old_dom_autostart_link) &&
>  unlink(old_dom_autostart_link) < 0) {
>  virReportSystemError(errno,
> - _("Failed to delete symlink '%s'"),
> +_("Failed to delete symlink '%s'"),

^Undesirable hunk

Same as with VIR_AUTOUNREF, this focuses on strings only, I'd extend this also
for other primitive scalar pointers:

cpuwait in qemuDomainGetStatsVcpu
flags in qemuStateStop

There are other occasions at which we use VIR_FREE and could be replaced, but
those are not scalar type pointers and I the policy I believe we settled with
is not to use VIR_AUTOFREE with compound types, instead a dedicated VIR_AUTOPTR
should be created.

Erik

--
libvir-list mailing list
libvir-list@redhat.com
https://www.redhat.com/mailman/listinfo/libvir-list


Re: [libvirt] [PATCH 3/6] qemu_driver: use VIR_AUTOUNREF() with virQEMUDriverConfigPtr 3/3

2019-09-26 Thread Erik Skultety
On Wed, Sep 18, 2019 at 11:56:55AM -0300, Daniel Henrique Barboza wrote:
> virQEMUDriverConfigPtr can be auto-unref for the great majority
> of the uses made in qemu_driver, sparing us a virObjectUnref()
> call and sometimes a whole 'cleanup' label.
>
> This patch changes virQEMUDriverConfigPtr declarations to
> use VIR_AUTOUNREF(). 'cleanup' labels were deleted when
> applicable.
>
> This is the last part of this change. All but one* instance of
> virQEMUDriverConfigPtr were changed to use VIR_AUTOUNREF().
> 'cleanup' labels were deleted when applicable.
>
> * qemuStateInitialize: we can't auto-unref the pointer since we're
> initializing the qemu_driver object with it.
>
> Signed-off-by: Daniel Henrique Barboza 
> ---

I know you focused on virQEMUDriverConfigPtr primarily, but since you're
following up with VIR_AUTOFREE and touching qemu_driver only, I'd like to do a
better job and use VIR_AUTOUNREF at many more places across the file for:

virCapsPtr caps
virConnectPtr conn
qemuDomainSaveCookiePtr cookie
virQEMUCapsPtr qemuCaps
qemuBlockJobDataPtr job
virDomainCapsPtr domCaps
virNetworkPtr network

(there may be a few more...)

Erik

--
libvir-list mailing list
libvir-list@redhat.com
https://www.redhat.com/mailman/listinfo/libvir-list


Re: [libvirt] [PATCH v3 08/11] driver.c: change URI validation to handle QEMU and vbox case

2019-09-26 Thread Daniel Henrique Barboza



On 9/25/19 7:58 PM, Cole Robinson wrote:

On 9/25/19 9:50 AM, Daniel Henrique Barboza wrote:

The existing QEMU and vbox URI path validation consider
that a privileged user can use both a "/system" and a
"/session" URI. This differs from all the other drivers
that forbids the root user to use "/session" URI.

Let's update virConnectValidateURIPath() to handle these
cases as exceptions, using the already existent 'entityName'
value to handle "QEMU" and "vbox" differently. This allows
us to use the validateURI function in these cases without
changing the existing behavior of other drivers.

Suggested-by: Cole Robinson 
Signed-off-by: Daniel Henrique Barboza 
---
  src/driver.c | 26 --
  1 file changed, 20 insertions(+), 6 deletions(-)

diff --git a/src/driver.c b/src/driver.c
index e627b0c1d7..8f9da35f78 100644
--- a/src/driver.c
+++ b/src/driver.c
@@ -276,16 +276,30 @@ virConnectValidateURIPath(const char *uriPath,
    bool privileged)
  {
  if (privileged) {
-    if (STRNEQ(uriPath, "/system")) {
-    virReportError(VIR_ERR_INTERNAL_ERROR,
-   _("unexpected %s URI path '%s', try 
%s:///system"),

-   entityName, uriPath, entityName);
-    return false;
+    /* TODO: QEMU and vbox drivers allow '/session'
+ * connections as root. This is not ideal, but changing
+ * these drivers to refuse privileged '/session'
+ * connections, like everyone else is already doing, can
+ * break existing applications. Until we decide what to do,
+ * for now we can handle them as exception in this validate
+ * function.
+ */
+    bool compatSessionRoot = (STREQ(entityName, "QEMU") ||
+  STREQ(entityName, "vbox"));
+
+    if ((compatSessionRoot && STRNEQ(uriPath, "/session")) ||
+    STRNEQ(uriPath, "/system")) {
+    virReportError(VIR_ERR_INTERNAL_ERROR,
+   _("unexpected %s URI path '%s', try "
+ "%s:///system"),
+   entityName, uriPath, entityName);
+    return false;
  }


The logic is incorrect here. Try connecting to qemu:///system after 
this change, it will be rejected.


I assumed that any of the checks in 'make check' would fail if I messed
up here. Never assume huh.

(/me wondering if this rewards a unit test)



Also passing in the 'QEMU' instead of 'qemu string means we print the 
wrong URI in the error. I think this needs a v4 :/


I'll fix that and re-spin a v4. I'll also squash the below formatting like
you suggested in patch 01.


Thanks,

DHB





  } else {
  if (STRNEQ(uriPath, "/session")) {
  virReportError(VIR_ERR_INTERNAL_ERROR,
-   _("unexpected %s URI path '%s', try 
%s:///session"),

+   _("unexpected %s URI path '%s', try "
+ "%s:///session"),
 entityName, uriPath, entityName);


This formatting should be squashed into patch #1 IMO

Thanks,
Cole


--
libvir-list mailing list
libvir-list@redhat.com
https://www.redhat.com/mailman/listinfo/libvir-list

Re: [libvirt] [PATCH v3 03/22] build-aux: rewrite po file minimizer in Python

2019-09-26 Thread Ján Tomko

On Thu, Sep 26, 2019 at 02:16:04PM +0100, Daniel P. Berrangé wrote:

On Thu, Sep 26, 2019 at 12:39:39PM +0200, Erik Skultety wrote:

On Tue, Sep 24, 2019 at 03:58:44PM +0100, Daniel P. Berrangé wrote:
question 1) what's the benefit of compiling a regex and using it only once? Btw
python does cache every pattern passed to re.match (and friends) so compilation
IMO hardly ever makes sense unless you're doing 1000s of searches for the same


Some of the scripts here are run on the whole libvirt codebase so that
is the case here. For example just removing the pre-compilation of
regexes for comments from the spacing check script bumped the execution
time from 6.5s to 7.4s

Sadly, the one script where pre-compilation matters the most is the one
where separating them puts them far away from the usage to not fit on
one screen.


pattern in which case the latency would naturally accumulate.


Ah, I've just seen the docs now

 "The compiled versions of the most recent patterns passed to
  re.compile() and the module-level matching functions are
  cached, so programs that use only a few regular expressions
  at a time needn’t worry about compiling regular expressions."

so with this in mind, I can probably just remove the 'compile' step from
all the scripts in this series. I haven't used it consistently to start
with.



For those regexes only executed on a fraction of lines this is
neligible, but it would be nice to keep them for those that run on every
line.

Jano


question 2) why do we need the '''.* and .*''' parts compared to the original
perl regex? I'll go ahead and assume it's because re.match matches at the
beginning of a string by default, in which case, shouldn't we use re.search
which matches anywhere (that's what perl does by default) instead?


Yeah, I didn't notice the 're.search' function existed & had the semantics
closer to Perl.


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 :|

--
libvir-list mailing list
libvir-list@redhat.com
https://www.redhat.com/mailman/listinfo/libvir-list


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

Re: [libvirt] [PATCH v3 02/22] build-aux: rewrite augest test generator in Python

2019-09-26 Thread Ján Tomko

On Wed, Sep 25, 2019 at 03:17:10PM +0100, Daniel P. Berrangé wrote:

On Wed, Sep 25, 2019 at 03:25:39PM +0200, Ján Tomko wrote:

On Tue, Sep 24, 2019 at 03:58:43PM +0100, Daniel P. Berrangé wrote:
> As part of an goal to eliminate Perl from libvirt build tools,
> rewrite the augeas-gentest.pl tool in Python.
>
> This was a straight conversion, manually going line-by-line to
> change the syntax from Perl to Python. Thus the overall structure
> of the file and approach is the same.
>
> The use of $(AUG_GENTEST) as a dependancy in the makefiles needed

s/dependancy/dependency/

> to be fixed, because this was assumed to be the filename of the
> script, but is in fact a full shell command line.
>

This is the case regardless of the Perl->Python conversion
and can be done upfront to reduce the churn in this patch.
Introduced by commit fb59cf7a5824b9c876737dcbf6aac97c29b1444a

> Signed-off-by: Daniel P. Berrangé 
> ---
> Makefile.am |  2 +-
> build-aux/augeas-gentest.pl | 60 ---
> build-aux/augeas-gentest.py | 72 +
> src/Makefile.am |  3 +-
> src/bhyve/Makefile.inc.am   |  4 +-
> src/interface/Makefile.inc.am   |  2 +-
> src/libxl/Makefile.inc.am   |  4 +-
> src/locking/Makefile.inc.am |  6 +--
> src/logging/Makefile.inc.am |  2 +-
> src/lxc/Makefile.inc.am |  4 +-
> src/network/Makefile.inc.am |  2 +-
> src/node_device/Makefile.inc.am |  2 +-
> src/nwfilter/Makefile.inc.am|  2 +-
> src/qemu/Makefile.inc.am|  4 +-
> src/remote/Makefile.inc.am  |  4 +-
> src/secret/Makefile.inc.am  |  2 +-
> src/storage/Makefile.inc.am |  2 +-
> src/vbox/Makefile.inc.am|  2 +-
> src/vz/Makefile.inc.am  |  2 +-
> 19 files changed, 97 insertions(+), 84 deletions(-)
> delete mode 100755 build-aux/augeas-gentest.pl
> create mode 100755 build-aux/augeas-gentest.py

Since this is a new file with clean history, it might actually deserve
a better location than build-aux and we can leave this directory to
Automake and gnulib to do whatever magic they do there.
Also note that the directory is in .gitignore. (I added the exception
for .pl files back when I added files here)

Would 'scripts' be too vague? Could be a good place to put the helper
scripts for generating QEMU caps files since I never seem to remember
its name and tests/ is growing quite big.


That's a good question. As you see from this series, we've got random
scripts scattered all over the sub-dirs. build-aux/ was in some sense
to avoid polluting the top level dir.

If we create 'scripts/' should we put everything in there, or just
stuff that's related to the top level, and keep everything else in
their current subdirs ?


We put all the driver-specific tests into one tests/ directory, I think
doing it for scripts makes sense too.

Jano




Regards,
Daniel


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

Re: [libvirt] [PATCH v2 5/7] qemu: driver: Move checkpoint-related code to qemu_checkpoint.c

2019-09-26 Thread Eric Blake

On 9/25/19 7:54 AM, Peter Krempa wrote:

Move all extensive functions to a new file so that we don't just pile
everything in the common files. This obviously isn't possible with
straight code movement as we still need stubs in qemu_driver.c

Additionally some functions e.g. for looking up a checkpoint by name
were so short that moving the impl didn't make sense.

Note that in the move the new file also doesn't use
virQEMUMomentReparent but rather an stripped down copy. As I plan to


s/an/a/


split out snapshot code into a separate file the unification doesn't
make sense any more.

Signed-off-by: Peter Krempa 
---
  src/qemu/Makefile.inc.am   |   2 +
  src/qemu/qemu_checkpoint.c | 483 +
  src/qemu/qemu_checkpoint.h |  50 
  src/qemu/qemu_driver.c | 382 +
  4 files changed, 540 insertions(+), 377 deletions(-)
  create mode 100644 src/qemu/qemu_checkpoint.c
  create mode 100644 src/qemu/qemu_checkpoint.h



With the double-free fix you posted in the followup,



+++ b/src/qemu/Makefile.inc.am
@@ -68,6 +68,8 @@ QEMU_DRIVER_SOURCES = \
qemu/qemu_vhost_user.h \
qemu/qemu_vhost_user_gpu.c \
qemu/qemu_vhost_user_gpu.h \
+   qemu/qemu_checkpoint.c \
+   qemu/qemu_checkpoint.h \
$(NULL)


Is it worth keeping this list sorted alphabetically?


+/* Called inside job lock */
+static int
+qemuDomainCheckpointPrepare(virQEMUDriverPtr driver, virCapsPtr caps,


Worth splitting these parameters to separate lines?  (I know you're just 
moving code, and it's my fault they weren't split in my commit...)



+virDomainObjPtr vm,
+virDomainCheckpointDefPtr def)
+{




+
+struct virQEMUCheckpointReparent {
+const char *dir;
+virDomainMomentObjPtr parent;
+virDomainObjPtr vm;
+virCapsPtr caps;
+virDomainXMLOptionPtr xmlopt;
+int err;
+};
+
+
+static int
+qemuCheckpointReparentChildren(void *payload,
+   const void *name ATTRIBUTE_UNUSED,
+   void *data)
+{
+virDomainMomentObjPtr moment = payload;
+struct virQEMUCheckpointReparent  *rep = data;


There's a double space here we could fix.


+int
+qemuCheckpointDelete(virDomainObjPtr vm,
+ virDomainCheckpointPtr checkpoint,
+ unsigned int flags)
+{
+qemuDomainObjPrivatePtr priv = vm->privateData;
+virQEMUDriverPtr driver = priv->driver;
+VIR_AUTOUNREF(virQEMUDriverConfigPtr) cfg = virQEMUDriverGetConfig(driver);
+int ret = -1;
+virDomainMomentObjPtr chk = NULL;
+virQEMUMomentRemove rem;
+struct virQEMUCheckpointReparent rep;


You explained why you unshared virQEMUMomentReparent, but why not 
instead move it to be alongside virQEMUMomentRemove, which is still 
shared?  Yes, I know it's odd that we had two callback structs, split 
between two different files declaring those structs, but rather than 
duplicating things for snapshot vs. checkpoint, keeping the two shared 
structs side-by-side might make more sense.



+++ b/src/qemu/qemu_driver.c



  static virDomainCheckpointPtr
  qemuDomainCheckpointCreateXML(virDomainPtr domain,
const char *xmlDesc,
unsigned int flags)
  {
-virQEMUDriverPtr driver = domain->conn->privateData;
  virDomainObjPtr vm = NULL;




  if (!(vm = qemuDomainObjFromDomain(domain)))
  goto cleanup;

-if (virDomainSnapshotObjListNum(vm->snapshots, NULL, 0) > 0) {
-virReportError(VIR_ERR_OPERATION_UNSUPPORTED, "%s",
-   _("cannot create checkpoint while snapshot exists"));
-goto cleanup;
-}
-
-priv = vm->privateData;
-cfg = virQEMUDriverGetConfig(driver);
-
  if (virDomainCheckpointCreateXMLEnsureACL(domain->conn, vm->def, flags) < 
0)
  goto cleanup;


Didn't you need to fix this separately, for security reasons?

Otherwise, the code motion makes sense.

--
Eric Blake, Principal Software Engineer
Red Hat, Inc.   +1-919-301-3226
Virtualization:  qemu.org | libvirt.org

--
libvir-list mailing list
libvir-list@redhat.com
https://www.redhat.com/mailman/listinfo/libvir-list


Re: [libvirt] [PATCH v3 03/22] build-aux: rewrite po file minimizer in Python

2019-09-26 Thread Daniel P . Berrangé
On Thu, Sep 26, 2019 at 05:34:49PM +0200, Ján Tomko wrote:
> On Thu, Sep 26, 2019 at 02:16:04PM +0100, Daniel P. Berrangé wrote:
> > On Thu, Sep 26, 2019 at 12:39:39PM +0200, Erik Skultety wrote:
> > > On Tue, Sep 24, 2019 at 03:58:44PM +0100, Daniel P. Berrangé wrote:
> > > question 1) what's the benefit of compiling a regex and using it only 
> > > once? Btw
> > > python does cache every pattern passed to re.match (and friends) so 
> > > compilation
> > > IMO hardly ever makes sense unless you're doing 1000s of searches for the 
> > > same
> 
> Some of the scripts here are run on the whole libvirt codebase so that
> is the case here. For example just removing the pre-compilation of
> regexes for comments from the spacing check script bumped the execution
> time from 6.5s to 7.4s
> 
> Sadly, the one script where pre-compilation matters the most is the one
> where separating them puts them far away from the usage to not fit on
> one screen.

I could do a little custom function that caches all regexes

  recache = {}

  def research(regex, line):
global recache
if regex not in recache:
  recache[regex] = re.compile(regex)
return recache[regex].search(line)


then the loop we can do a normal

 research(r'''some regex''', line)

so we can get readability and full caching together. Probably not worth
repeating this trick for every script, but certainly the whitespace
script and a few others probably benefit.

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 :|

--
libvir-list mailing list
libvir-list@redhat.com
https://www.redhat.com/mailman/listinfo/libvir-list

[libvirt] [PATCH 4/9] tests: qemumonitor: Add testing for the 'transaction' command and generators

2019-09-26 Thread Peter Krempa
Validate all the commands against the schema.

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

diff --git a/tests/qemumonitorjsontest.c b/tests/qemumonitorjsontest.c
index d0bbb1f674..8179e802c1 100644
--- a/tests/qemumonitorjsontest.c
+++ b/tests/qemumonitorjsontest.c
@@ -3004,6 +3004,44 @@ testQueryJobs(const void *opaque)
 }


+static int
+testQemuMonitorJSONTransaction(const void *opaque)
+{
+const testGenericData *data = opaque;
+VIR_AUTOPTR(qemuMonitorTest) test = NULL;
+VIR_AUTOPTR(virJSONValue) actions = NULL;
+VIR_AUTOPTR(virJSONValue) mergebitmaps = NULL;
+
+if (!(test = qemuMonitorTestNewSchema(data->xmlopt, data->schema)))
+return -1;
+
+if (!(actions = virJSONValueNewArray()) ||
+!(mergebitmaps = virJSONValueNewArray()))
+return -1;
+
+if (virJSONValueArrayAppendString(mergebitmaps, "mergemap1") < 0 ||
+virJSONValueArrayAppendString(mergebitmaps, "mergemap2") < 0)
+return -1;
+
+if (qemuMonitorTransactionBitmapAdd(actions, "node1", "bitmap1", true, 
true) < 0 ||
+qemuMonitorTransactionBitmapRemove(actions, "node2", "bitmap2") < 0 ||
+qemuMonitorTransactionBitmapEnable(actions, "node3", "bitmap3") < 0 ||
+qemuMonitorTransactionBitmapDisable(actions, "node4", "bitmap4") < 0 ||
+qemuMonitorTransactionBitmapMerge(actions, "node5", "bitmap5", 
) < 0 ||
+qemuMonitorTransactionSnapshotLegacy(actions, "dev6", "path", "qcow2", 
true) < 0 ||
+qemuMonitorTransactionSnapshotBlockdev(actions, "node7", "overlay7") < 
0)
+return -1;
+
+if (qemuMonitorTestAddItem(test, "transaction", "{\"return\":{}}") < 0)
+return -1;
+
+if (qemuMonitorJSONTransaction(qemuMonitorTestGetMonitor(test), ) 
< 0)
+return -1;
+
+return 0;
+}
+
+
 static int
 mymain(void)
 {
@@ -3095,6 +3133,7 @@ mymain(void)
 DO_TEST(CPU);
 DO_TEST(GetNonExistingCPUData);
 DO_TEST(GetIOThreads);
+DO_TEST(Transaction);
 DO_TEST_SIMPLE("qmp_capabilities", qemuMonitorJSONSetCapabilities);
 DO_TEST_SIMPLE("system_powerdown", qemuMonitorJSONSystemPowerdown);
 DO_TEST_SIMPLE("system_reset", qemuMonitorJSONSystemReset);
-- 
2.21.0

--
libvir-list mailing list
libvir-list@redhat.com
https://www.redhat.com/mailman/listinfo/libvir-list


[libvirt] [PATCH 3/9] qemu: monitor: Add transaction generators for snapshot APIs

2019-09-26 Thread Peter Krempa
Unify with other code that generates parameters for the 'transaction'
command.

Signed-off-by: Peter Krempa 
---
 src/qemu/qemu_monitor.c  | 21 +
 src/qemu/qemu_monitor.h  | 11 +++
 src/qemu/qemu_monitor_json.c | 35 +++
 src/qemu/qemu_monitor_json.h | 11 +++
 4 files changed, 78 insertions(+)

diff --git a/src/qemu/qemu_monitor.c b/src/qemu/qemu_monitor.c
index b1499503d4..0f54c5c0e2 100644
--- a/src/qemu/qemu_monitor.c
+++ b/src/qemu/qemu_monitor.c
@@ -4539,3 +4539,24 @@ qemuMonitorTransactionBitmapMerge(virJSONValuePtr 
actions,
 {
 return qemuMonitorJSONTransactionBitmapMerge(actions, node, target, 
sources);
 }
+
+
+int
+qemuMonitorTransactionSnapshotLegacy(virJSONValuePtr actions,
+ const char *device,
+ const char *path,
+ const char *format,
+ bool existing)
+{
+return qemuMonitorJSONTransactionSnapshotLegacy(actions, device, path,
+format, existing);
+}
+
+
+int
+qemuMonitorTransactionSnapshotBlockdev(virJSONValuePtr actions,
+   const char *node,
+   const char *overlay)
+{
+return qemuMonitorJSONTransactionSnapshotBlockdev(actions, node, overlay);
+}
diff --git a/src/qemu/qemu_monitor.h b/src/qemu/qemu_monitor.h
index 4f449f3515..c6f1f3572b 100644
--- a/src/qemu/qemu_monitor.h
+++ b/src/qemu/qemu_monitor.h
@@ -1361,3 +1361,14 @@ qemuMonitorTransactionBitmapMerge(virJSONValuePtr 
actions,
   const char *node,
   const char *target,
   virJSONValuePtr *sources);
+
+int
+qemuMonitorTransactionSnapshotLegacy(virJSONValuePtr actions,
+ const char *device,
+ const char *path,
+ const char *format,
+ bool existing);
+int
+qemuMonitorTransactionSnapshotBlockdev(virJSONValuePtr actions,
+   const char *node,
+   const char *overlay);
diff --git a/src/qemu/qemu_monitor_json.c b/src/qemu/qemu_monitor_json.c
index b1f29e4870..527a658b08 100644
--- a/src/qemu/qemu_monitor_json.c
+++ b/src/qemu/qemu_monitor_json.c
@@ -9100,6 +9100,41 @@ qemuMonitorJSONTransactionBitmapMerge(virJSONValuePtr 
actions,
 }


+int
+qemuMonitorJSONTransactionSnapshotLegacy(virJSONValuePtr actions,
+ const char *device,
+ const char *path,
+ const char *format,
+ bool existing)
+{
+const char *mode = NULL;
+
+if (existing)
+mode = "existing";
+
+return qemuMonitorJSONTransactionAdd(actions,
+ "blockdev-snapshot-sync",
+ "s:device", device,
+ "s:snapshot-file", path,
+ "s:format", format,
+ "S:mode", mode,
+ NULL);
+}
+
+
+int
+qemuMonitorJSONTransactionSnapshotBlockdev(virJSONValuePtr actions,
+   const char *node,
+   const char *overlay)
+{
+return qemuMonitorJSONTransactionAdd(actions,
+ "blockdev-snapshot",
+ "s:node", node,
+ "s:overlay", overlay,
+ NULL);
+}
+
+
 static qemuMonitorJobInfoPtr
 qemuMonitorJSONGetJobInfoOne(virJSONValuePtr data)
 {
diff --git a/src/qemu/qemu_monitor_json.h b/src/qemu/qemu_monitor_json.h
index d5408107be..39a84b3efd 100644
--- a/src/qemu/qemu_monitor_json.h
+++ b/src/qemu/qemu_monitor_json.h
@@ -656,3 +656,14 @@ qemuMonitorJSONTransactionBitmapMerge(virJSONValuePtr 
actions,
   const char *node,
   const char *target,
   virJSONValuePtr *sources);
+
+int
+qemuMonitorJSONTransactionSnapshotLegacy(virJSONValuePtr actions,
+ const char *device,
+ const char *path,
+ const char *format,
+ bool existing);
+int
+qemuMonitorJSONTransactionSnapshotBlockdev(virJSONValuePtr actions,
+   const char *node,
+   const char *overlay);
-- 
2.21.0

--
libvir-list 

[libvirt] [PATCH 8/9] qemu: checkpoint: Fix rollback and access to unlocked 'vm' when deleting checkpoints

2019-09-26 Thread Peter Krempa
Delete/merge bitmaps when deleting checkpoints using a 'transaction' so
that we don't have to deal with halfway-failed scenarios and also fix
access to 'vm' while in the monitor lock.

Signed-off-by: Peter Krempa 
---
 src/qemu/qemu_checkpoint.c | 47 +++---
 1 file changed, 24 insertions(+), 23 deletions(-)

diff --git a/src/qemu/qemu_checkpoint.c b/src/qemu/qemu_checkpoint.c
index 04320b8e39..ff39192b84 100644
--- a/src/qemu/qemu_checkpoint.c
+++ b/src/qemu/qemu_checkpoint.c
@@ -133,11 +133,14 @@ qemuDomainCheckpointDiscard(virQEMUDriverPtr driver,

 if (!metadata_only) {
 qemuDomainObjPrivatePtr priv = vm->privateData;
-bool success = true;
 bool search_parents;
 virDomainCheckpointDefPtr chkdef = virDomainCheckpointObjGetDef(chk);
+int rc;
+VIR_AUTOPTR(virJSONValue) actions = NULL;
+
+if (!(actions = virJSONValueNewArray()))
+return -1;

-qemuDomainObjEnterMonitor(driver, vm);
 parent = virDomainCheckpointFindByName(vm->checkpoints,
chk->def->parent_name);
 for (i = 0; i < chkdef->ndisks; i++) {
@@ -167,31 +170,29 @@ qemuDomainCheckpointDiscard(virQEMUDriverPtr driver,
 continue;
 search_parents = false;

-arr = virJSONValueNewArray();
-if (!arr ||
-virJSONValueArrayAppendString(arr, disk->bitmap) < 0) {
-success = false;
-break;
-}
-if (chk == virDomainCheckpointGetCurrent(vm->checkpoints) 
&&
-qemuMonitorEnableBitmap(priv->mon, node,
-disk2->bitmap) < 0) {
-success = false;
-break;
-}
-if (qemuMonitorMergeBitmaps(priv->mon, node,
-disk2->bitmap, ) < 0) {
-success = false;
-break;
+if (!(arr = virJSONValueNewArray()))
+return -1;
+
+if (virJSONValueArrayAppendString(arr, disk->bitmap) < 0)
+return -1;
+
+if (chk == virDomainCheckpointGetCurrent(vm->checkpoints)) 
{
+if (qemuMonitorTransactionBitmapEnable(actions, node, 
disk2->bitmap) < 0)
+return -1;
 }
+
+if (qemuMonitorTransactionBitmapMerge(actions, node, 
disk2->bitmap, ) < 0)
+return -1;
 }
 }
-if (qemuMonitorDeleteBitmap(priv->mon, node, disk->bitmap) < 0) {
-success = false;
-break;
-}
+
+if (qemuMonitorTransactionBitmapRemove(actions, node, 
disk->bitmap) < 0)
+return -1;
 }
-if (qemuDomainObjExitMonitor(driver, vm) < 0 || !success)
+
+qemuDomainObjEnterMonitor(driver, vm);
+rc = qemuMonitorTransaction(priv->mon, );
+if (qemuDomainObjExitMonitor(driver, vm) < 0 || rc < 0)
 return -1;
 }

-- 
2.21.0

--
libvir-list mailing list
libvir-list@redhat.com
https://www.redhat.com/mailman/listinfo/libvir-list


[libvirt] [PATCH 7/9] qemu: monitor: unexport qemuMonitorJSONTransactionAdd

2019-09-26 Thread Peter Krempa
Now it's not used outside of qemu_monitor_json.c.

Signed-off-by: Peter Krempa 
---
 src/qemu/qemu_monitor_json.c | 2 +-
 src/qemu/qemu_monitor_json.h | 4 
 2 files changed, 1 insertion(+), 5 deletions(-)

diff --git a/src/qemu/qemu_monitor_json.c b/src/qemu/qemu_monitor_json.c
index 527a658b08..0073c863c2 100644
--- a/src/qemu/qemu_monitor_json.c
+++ b/src/qemu/qemu_monitor_json.c
@@ -498,7 +498,7 @@ qemuMonitorJSONHasError(virJSONValuePtr reply,
  *
  * Returns 0 on success and -1 on error.
  */
-int
+static int
 qemuMonitorJSONTransactionAdd(virJSONValuePtr actions,
   const char *cmdname,
   ...)
diff --git a/src/qemu/qemu_monitor_json.h b/src/qemu/qemu_monitor_json.h
index 39a84b3efd..38bed040c1 100644
--- a/src/qemu/qemu_monitor_json.h
+++ b/src/qemu/qemu_monitor_json.h
@@ -28,10 +28,6 @@
 #include "cpu/cpu.h"
 #include "util/virgic.h"

-int qemuMonitorJSONTransactionAdd(virJSONValuePtr actions,
-  const char *cmdname,
-  ...);
-
 int qemuMonitorJSONIOProcessLine(qemuMonitorPtr mon,
  const char *line,
  qemuMonitorMessagePtr msg);
-- 
2.21.0

--
libvir-list mailing list
libvir-list@redhat.com
https://www.redhat.com/mailman/listinfo/libvir-list


[libvirt] [PATCH 2/9] qemu: monitor: Add transaction generators for dirty bitmap APIs

2019-09-26 Thread Peter Krempa
Rather than generating the transaction contents in random places add a
unified set of APIs to generate the contents for a 'transaction' for the
dirty bitmap APIs.

Signed-off-by: Peter Krempa 
---
 src/qemu/qemu_monitor.c  | 48 
 src/qemu/qemu_monitor.h  | 24 
 src/qemu/qemu_monitor_json.c | 71 
 src/qemu/qemu_monitor_json.h | 24 
 4 files changed, 167 insertions(+)

diff --git a/src/qemu/qemu_monitor.c b/src/qemu/qemu_monitor.c
index b6d2936872..b1499503d4 100644
--- a/src/qemu/qemu_monitor.c
+++ b/src/qemu/qemu_monitor.c
@@ -4491,3 +4491,51 @@ qemuMonitorGetJobInfo(qemuMonitorPtr mon,

 return qemuMonitorJSONGetJobInfo(mon, jobs, njobs);
 }
+
+
+int
+qemuMonitorTransactionBitmapAdd(virJSONValuePtr actions,
+const char *node,
+const char *name,
+bool persistent,
+bool disabled)
+{
+return qemuMonitorJSONTransactionBitmapAdd(actions, node, name, 
persistent, disabled);
+}
+
+
+int
+qemuMonitorTransactionBitmapRemove(virJSONValuePtr actions,
+   const char *node,
+   const char *name)
+{
+return qemuMonitorJSONTransactionBitmapRemove(actions, node, name);
+}
+
+
+int
+qemuMonitorTransactionBitmapEnable(virJSONValuePtr actions,
+   const char *node,
+   const char *name)
+{
+return qemuMonitorJSONTransactionBitmapEnable(actions, node, name);
+}
+
+
+int
+qemuMonitorTransactionBitmapDisable(virJSONValuePtr actions,
+const char *node,
+const char *name)
+{
+return qemuMonitorJSONTransactionBitmapDisable(actions, node, name);
+}
+
+
+int
+qemuMonitorTransactionBitmapMerge(virJSONValuePtr actions,
+  const char *node,
+  const char *target,
+  virJSONValuePtr *sources)
+{
+return qemuMonitorJSONTransactionBitmapMerge(actions, node, target, 
sources);
+}
diff --git a/src/qemu/qemu_monitor.h b/src/qemu/qemu_monitor.h
index 8fc11c955e..4f449f3515 100644
--- a/src/qemu/qemu_monitor.h
+++ b/src/qemu/qemu_monitor.h
@@ -1337,3 +1337,27 @@ VIR_DEFINE_AUTOPTR_FUNC(qemuMonitorJobInfo, 
qemuMonitorJobInfoFree);
 int qemuMonitorGetJobInfo(qemuMonitorPtr mon,
   qemuMonitorJobInfoPtr **jobs,
   size_t *njobs);
+
+int
+qemuMonitorTransactionBitmapAdd(virJSONValuePtr actions,
+const char *node,
+const char *name,
+bool persistent,
+bool disabled);
+int
+qemuMonitorTransactionBitmapRemove(virJSONValuePtr actions,
+   const char *node,
+   const char *name);
+int
+qemuMonitorTransactionBitmapEnable(virJSONValuePtr actions,
+   const char *node,
+   const char *name);
+int
+qemuMonitorTransactionBitmapDisable(virJSONValuePtr actions,
+const char *node,
+const char *name);
+int
+qemuMonitorTransactionBitmapMerge(virJSONValuePtr actions,
+  const char *node,
+  const char *target,
+  virJSONValuePtr *sources);
diff --git a/src/qemu/qemu_monitor_json.c b/src/qemu/qemu_monitor_json.c
index cdfaf9785a..b1f29e4870 100644
--- a/src/qemu/qemu_monitor_json.c
+++ b/src/qemu/qemu_monitor_json.c
@@ -9029,6 +9029,77 @@ qemuMonitorJSONDeleteBitmap(qemuMonitorPtr mon,
 }


+int
+qemuMonitorJSONTransactionBitmapAdd(virJSONValuePtr actions,
+const char *node,
+const char *name,
+bool persistent,
+bool disabled)
+{
+return qemuMonitorJSONTransactionAdd(actions,
+ "block-dirty-bitmap-add",
+ "s:node", node,
+ "s:name", name,
+ "b:persistent", persistent,
+ "b:disabled", disabled,
+ NULL);
+}
+
+
+int
+qemuMonitorJSONTransactionBitmapRemove(virJSONValuePtr actions,
+   const char *node,
+   const char *name)
+{
+return qemuMonitorJSONTransactionAdd(actions,
+ "block-dirty-bitmap-remove",
+ "s:node", node,
+ 

[libvirt] [PATCH 0/9] qemu: Refactor transaction actions handling and refactor checkpoint deletion

2019-09-26 Thread Peter Krempa
This should be applied on top of the checkpoints split. Pushing it
requires the interlocking patches for checkpoints being merged as the
bitmap removal QMP command is transactionable only since qemu 4.2. That
is also the reason for the addition of the capabilities of qemu 4.2.

Peter Krempa (9):
  DO NOT PUSH: tests: add qemu capabilities data for qemu 4.2
  qemu: monitor: Add transaction generators for dirty bitmap APIs
  qemu: monitor: Add transaction generators for snapshot APIs
  tests: qemumonitor: Add testing for the 'transaction' command and
generators
  qemu: block: Replace snapshot transaction action generator
  qemu: checkpoint: Replace open-coded transaction action generators
  qemu: monitor: unexport qemuMonitorJSONTransactionAdd
  qemu: checkpoint: Fix rollback and access to unlocked 'vm' when
deleting checkpoints
  qemu: monitor: Remove non-transaction based dirty bitmap APIs

 src/qemu/qemu_block.c |21 +-
 src/qemu/qemu_checkpoint.c|61 +-
 src/qemu/qemu_monitor.c   |   100 +-
 src/qemu/qemu_monitor.h   |54 +-
 src/qemu/qemu_monitor_json.c  |   189 +-
 src/qemu/qemu_monitor_json.h  |52 +-
 .../caps_4.2.0.x86_64.replies | 24758 
 .../caps_4.2.0.x86_64.xml |  1952 ++
 tests/qemumonitorjsontest.c   |80 +-
 9 files changed, 26994 insertions(+), 273 deletions(-)
 create mode 100644 tests/qemucapabilitiesdata/caps_4.2.0.x86_64.replies
 create mode 100644 tests/qemucapabilitiesdata/caps_4.2.0.x86_64.xml

-- 
2.21.0

--
libvir-list mailing list
libvir-list@redhat.com
https://www.redhat.com/mailman/listinfo/libvir-list


[libvirt] [PATCH 6/9] qemu: checkpoint: Replace open-coded transaction action generators

2019-09-26 Thread Peter Krempa
Use the generators provided by the monitor code instead.

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

diff --git a/src/qemu/qemu_checkpoint.c b/src/qemu/qemu_checkpoint.c
index 30d1b6ae3a..04320b8e39 100644
--- a/src/qemu/qemu_checkpoint.c
+++ b/src/qemu/qemu_checkpoint.c
@@ -23,7 +23,6 @@
 #include "qemu_checkpoint.h"
 #include "qemu_capabilities.h"
 #include "qemu_monitor.h"
-#include "qemu_monitor_json.h"
 #include "qemu_domain.h"

 #include "virerror.h"
@@ -306,12 +305,7 @@ qemuDomainCheckpointAddActions(virDomainObjPtr vm,
 if (disk->type != VIR_DOMAIN_CHECKPOINT_TYPE_BITMAP)
 continue;
 node = qemuDomainDiskNodeFormatLookup(vm, disk->name);
-if (qemuMonitorJSONTransactionAdd(actions,
-  "block-dirty-bitmap-add",
-  "s:node", node,
-  "s:name", disk->bitmap,
-  "b:persistent", true,
-  NULL) < 0)
+if (qemuMonitorTransactionBitmapAdd(actions, node, disk->bitmap, true, 
false) < 0)
 return -1;

 /* We only want one active bitmap for a disk along the
@@ -334,11 +328,7 @@ qemuDomainCheckpointAddActions(virDomainObjPtr vm,
 if (STRNEQ(disk->name, disk2->name) ||
 disk2->type != VIR_DOMAIN_CHECKPOINT_TYPE_BITMAP)
 continue;
-if (qemuMonitorJSONTransactionAdd(actions,
-  "block-dirty-bitmap-disable",
-  "s:node", node,
-  "s:name", disk2->bitmap,
-  NULL) < 0)
+if (qemuMonitorTransactionBitmapDisable(actions, node, 
disk2->bitmap) < 0)
 return -1;
 search_parents = false;
 break;
-- 
2.21.0

--
libvir-list mailing list
libvir-list@redhat.com
https://www.redhat.com/mailman/listinfo/libvir-list


[libvirt] [PATCH 5/9] qemu: block: Replace snapshot transaction action generator

2019-09-26 Thread Peter Krempa
Use the new generator residing in the monitor code rather than directly
using qemuMonitorJSONTransactionAdd.

Signed-off-by: Peter Krempa 
---
 src/qemu/qemu_block.c | 21 -
 1 file changed, 4 insertions(+), 17 deletions(-)

diff --git a/src/qemu/qemu_block.c b/src/qemu/qemu_block.c
index 4b5dd30e17..eacb48aa78 100644
--- a/src/qemu/qemu_block.c
+++ b/src/qemu/qemu_block.c
@@ -22,7 +22,6 @@
 #include "qemu_command.h"
 #include "qemu_domain.h"
 #include "qemu_alias.h"
-#include "qemu_monitor_json.h"

 #include "viralloc.h"
 #include "virstring.h"
@@ -1880,15 +1879,7 @@ qemuBlockSnapshotAddLegacy(virJSONValuePtr actions,
 if (qemuGetDriveSourceString(newsrc, NULL, ) < 0)
 return -1;

-if (qemuMonitorJSONTransactionAdd(actions, "blockdev-snapshot-sync",
-  "s:device", device,
-  "s:snapshot-file", source,
-  "s:format", format,
-  "S:mode", reuse ? "existing" : NULL,
-  NULL) < 0)
-return -1;
-
-return 0;
+return qemuMonitorTransactionSnapshotLegacy(actions, device, source, 
format, reuse);
 }


@@ -1897,13 +1888,9 @@ qemuBlockSnapshotAddBlockdev(virJSONValuePtr actions,
  virDomainDiskDefPtr disk,
  virStorageSourcePtr newsrc)
 {
-if (qemuMonitorJSONTransactionAdd(actions, "blockdev-snapshot",
-  "s:node", disk->src->nodeformat,
-  "s:overlay", newsrc->nodeformat,
-  NULL) < 0)
-return -1;
-
-return 0;
+return qemuMonitorTransactionSnapshotBlockdev(actions,
+  disk->src->nodeformat,
+  newsrc->nodeformat);
 }


-- 
2.21.0

--
libvir-list mailing list
libvir-list@redhat.com
https://www.redhat.com/mailman/listinfo/libvir-list


[libvirt] [PATCH v2 13/39] virpci: Introduce and use virPCIDeviceAddressGetIOMMUGroupDev

2019-09-26 Thread Michal Privoznik
Sometimes, we have a PCI address and not fully allocated
virPCIDevice and yet we still want to know its /dev/vfio/N path.
Introduce virPCIDeviceAddressGetIOMMUGroupDev() function exactly
for that.

Signed-off-by: Michal Privoznik 
---
 src/libvirt_private.syms |  1 +
 src/qemu/qemu_domain.c   | 10 +-
 src/util/virpci.c| 15 +++
 src/util/virpci.h|  1 +
 4 files changed, 18 insertions(+), 9 deletions(-)

diff --git a/src/libvirt_private.syms b/src/libvirt_private.syms
index de124eb37b..4b726b3139 100644
--- a/src/libvirt_private.syms
+++ b/src/libvirt_private.syms
@@ -2658,6 +2658,7 @@ virPCIDeviceAddressAsString;
 virPCIDeviceAddressEqual;
 virPCIDeviceAddressFree;
 virPCIDeviceAddressGetIOMMUGroupAddresses;
+virPCIDeviceAddressGetIOMMUGroupDev;
 virPCIDeviceAddressGetIOMMUGroupNum;
 virPCIDeviceAddressGetSysfsFile;
 virPCIDeviceAddressIOMMUGroupIterate;
diff --git a/src/qemu/qemu_domain.c b/src/qemu/qemu_domain.c
index e92c2053c1..f8fe430a7f 100644
--- a/src/qemu/qemu_domain.c
+++ b/src/qemu/qemu_domain.c
@@ -12859,7 +12859,6 @@ qemuDomainGetHostdevPath(virDomainHostdevDefPtr dev,
 virDomainHostdevSubsysSCSIPtr scsisrc = >source.subsys.u.scsi;
 virDomainHostdevSubsysSCSIVHostPtr hostsrc = 
>source.subsys.u.scsi_host;
 virDomainHostdevSubsysMediatedDevPtr mdevsrc = >source.subsys.u.mdev;
-VIR_AUTOPTR(virPCIDevice) pci = NULL;
 VIR_AUTOPTR(virUSBDevice) usb = NULL;
 VIR_AUTOPTR(virSCSIDevice) scsi = NULL;
 VIR_AUTOPTR(virSCSIVHostDevice) host = NULL;
@@ -12871,14 +12870,7 @@ qemuDomainGetHostdevPath(virDomainHostdevDefPtr dev,
 switch ((virDomainHostdevSubsysType)dev->source.subsys.type) {
 case VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_PCI:
 if (pcisrc->backend == VIR_DOMAIN_HOSTDEV_PCI_BACKEND_VFIO) {
-pci = virPCIDeviceNew(pcisrc->addr.domain,
-  pcisrc->addr.bus,
-  pcisrc->addr.slot,
-  pcisrc->addr.function);
-if (!pci)
-return -1;
-
-if (!(tmpPath = virPCIDeviceGetIOMMUGroupDev(pci)))
+if (!(tmpPath = 
virPCIDeviceAddressGetIOMMUGroupDev(>addr)))
 return -1;
 
 perm = VIR_CGROUP_DEVICE_RW;
diff --git a/src/util/virpci.c b/src/util/virpci.c
index ee78151e74..fc620d49ce 100644
--- a/src/util/virpci.c
+++ b/src/util/virpci.c
@@ -1974,6 +1974,21 @@ 
virPCIDeviceAddressGetIOMMUGroupNum(virPCIDeviceAddressPtr addr)
 }
 
 
+char *
+virPCIDeviceAddressGetIOMMUGroupDev(const virPCIDeviceAddress *devAddr)
+{
+VIR_AUTOPTR(virPCIDevice) pci = NULL;
+
+if (!(pci = virPCIDeviceNew(devAddr->domain,
+devAddr->bus,
+devAddr->slot,
+devAddr->function)))
+return NULL;
+
+return virPCIDeviceGetIOMMUGroupDev(pci);
+}
+
+
 /* virPCIDeviceGetIOMMUGroupDev - return the name of the device used
  * to control this PCI device's group (e.g. "/dev/vfio/15")
  */
diff --git a/src/util/virpci.h b/src/util/virpci.h
index dc20f91710..293d10b3ab 100644
--- a/src/util/virpci.h
+++ b/src/util/virpci.h
@@ -193,6 +193,7 @@ int 
virPCIDeviceAddressGetIOMMUGroupAddresses(virPCIDeviceAddressPtr devAddr,
   virPCIDeviceAddressPtr 
**iommuGroupDevices,
   size_t *nIommuGroupDevices);
 int virPCIDeviceAddressGetIOMMUGroupNum(virPCIDeviceAddressPtr addr);
+char *virPCIDeviceAddressGetIOMMUGroupDev(const virPCIDeviceAddress *devAddr);
 char *virPCIDeviceGetIOMMUGroupDev(virPCIDevicePtr dev);
 
 int virPCIDeviceIsAssignable(virPCIDevicePtr dev,
-- 
2.21.0

--
libvir-list mailing list
libvir-list@redhat.com
https://www.redhat.com/mailman/listinfo/libvir-list


[libvirt] [PATCH v2 07/39] qemu: Explicitly add/remove /dev/vfio/vfio to/from NS/CGroups

2019-09-26 Thread Michal Privoznik
In near future, the decision what to do with /dev/vfio/vfio with
respect to domain namespace and CGroup is going to be moved out
of qemuDomainGetHostdevPath() because there will be some other
types of devices than hostdevs that need access to VFIO.

All functions that I'm changing assume that hostdev we are
adding/removing to VM is not in the definition yet (because of
how qemuDomainNeedsVFIO() is written). Fortunately, this
assumption is true.

Signed-off-by: Michal Privoznik 
---
 src/qemu/qemu_cgroup.c | 48 +-
 src/qemu/qemu_domain.c | 36 +++
 2 files changed, 83 insertions(+), 1 deletion(-)

diff --git a/src/qemu/qemu_cgroup.c b/src/qemu/qemu_cgroup.c
index 4d6f0c33cd..f110b49d16 100644
--- a/src/qemu/qemu_cgroup.c
+++ b/src/qemu/qemu_cgroup.c
@@ -25,6 +25,7 @@
 #include "qemu_domain.h"
 #include "qemu_process.h"
 #include "qemu_extdevice.h"
+#include "qemu_hostdev.h"
 #include "vircgroup.h"
 #include "virlog.h"
 #include "viralloc.h"
@@ -360,6 +361,17 @@ qemuTeardownInputCgroup(virDomainObjPtr vm,
 }
 
 
+/**
+ * qemuSetupHostdevCgroup:
+ * vm: domain object
+ * @dev: device to allow
+ *
+ * For given host device @dev allow access to in Cgroups.
+ * Note, @dev must not be in @vm's definition.
+ *
+ * Returns: 0 on success,
+ * -1 otherwise.
+ */
 int
 qemuSetupHostdevCgroup(virDomainObjPtr vm,
virDomainHostdevDefPtr dev)
@@ -386,6 +398,17 @@ qemuSetupHostdevCgroup(virDomainObjPtr vm,
 goto cleanup;
 }
 
+if (qemuHostdevNeedsVFIO(dev) &&
+!qemuDomainNeedsVFIO(vm->def)) {
+VIR_DEBUG("Cgroup allow %s perms=%d", QEMU_DEV_VFIO, 
VIR_CGROUP_DEVICE_RW);
+rv = virCgroupAllowDevicePath(priv->cgroup, QEMU_DEV_VFIO,
+  VIR_CGROUP_DEVICE_RW, false);
+virDomainAuditCgroupPath(vm, priv->cgroup, "allow",
+ QEMU_DEV_VFIO, "rw", rv);
+if (rv < 0)
+goto cleanup;
+}
+
 ret = 0;
 
  cleanup:
@@ -396,9 +419,21 @@ qemuSetupHostdevCgroup(virDomainObjPtr vm,
 return ret;
 }
 
+
+/**
+ * qemuTeardownHostdevCgroup:
+ * @vm: doamin object
+ * @dev: device to tear down
+ *
+ * For given host device @dev deny access to it in CGroups.
+ * Note, @dev must not be in @vm's definition.
+ *
+ * Returns: 0 on success,
+ * -1 otherwise.
+ */
 int
 qemuTeardownHostdevCgroup(virDomainObjPtr vm,
-   virDomainHostdevDefPtr dev)
+  virDomainHostdevDefPtr dev)
 {
 qemuDomainObjPrivatePtr priv = vm->privateData;
 char **path = NULL;
@@ -422,6 +457,17 @@ qemuTeardownHostdevCgroup(virDomainObjPtr vm,
 goto cleanup;
 }
 
+if (qemuHostdevNeedsVFIO(dev) &&
+!qemuDomainNeedsVFIO(vm->def)) {
+VIR_DEBUG("Cgroup deny " QEMU_DEV_VFIO);
+rv = virCgroupDenyDevicePath(priv->cgroup, QEMU_DEV_VFIO,
+ VIR_CGROUP_DEVICE_RWM, false);
+virDomainAuditCgroupPath(vm, priv->cgroup, "deny",
+ QEMU_DEV_VFIO, "rwm", rv);
+if (rv < 0)
+goto cleanup;
+}
+
 ret = 0;
  cleanup:
 for (i = 0; i < npaths; i++)
diff --git a/src/qemu/qemu_domain.c b/src/qemu/qemu_domain.c
index 6502c6191c..02b6e590cd 100644
--- a/src/qemu/qemu_domain.c
+++ b/src/qemu/qemu_domain.c
@@ -13540,6 +13540,10 @@ qemuDomainSetupHostdev(virQEMUDriverConfigPtr cfg 
ATTRIBUTE_UNUSED,
 goto cleanup;
 }
 
+if (qemuHostdevNeedsVFIO(dev) &&
+qemuDomainCreateDevice(QEMU_DEV_VFIO, data, false) < 0)
+goto cleanup;
+
 ret = 0;
  cleanup:
 for (i = 0; i < npaths; i++)
@@ -14576,6 +14580,17 @@ qemuDomainNamespaceTeardownDisk(virDomainObjPtr vm 
ATTRIBUTE_UNUSED,
 }
 
 
+/**
+ * qemuDomainNamespaceSetupHostdev:
+ * @vm: domain object
+ * @hostdev: hostdev to create in @vm's namespace
+ *
+ * For given @hostdev, create its devfs representation (if it has one) in
+ * domain namespace. Note, @hostdev must not be in @vm's definition.
+ *
+ * Returns: 0 on success,
+ * -1 otherwise.
+ */
 int
 qemuDomainNamespaceSetupHostdev(virDomainObjPtr vm,
 virDomainHostdevDefPtr hostdev)
@@ -14590,6 +14605,11 @@ qemuDomainNamespaceSetupHostdev(virDomainObjPtr vm,
 if (qemuDomainNamespaceMknodPaths(vm, (const char **)paths, npaths) < 0)
 goto cleanup;
 
+if (qemuHostdevNeedsVFIO(hostdev) &&
+!qemuDomainNeedsVFIO(vm->def) &&
+qemuDomainNamespaceMknodPath(vm, QEMU_DEV_VFIO) < 0)
+goto cleanup;
+
 ret = 0;
  cleanup:
 for (i = 0; i < npaths; i++)
@@ -14599,6 +14619,17 @@ qemuDomainNamespaceSetupHostdev(virDomainObjPtr vm,
 }
 
 
+/**
+ * qemuDomainNamespaceTeardownHostdev:
+ * @vm: domain object
+ * @hostdev: hostdev to remove in @vm's namespace
+ *
+ * For given @hostdev, remove its devfs representation (if it has one) in
+ * domain namespace. Note, 

[libvirt] [PATCH v2 14/39] virHostdevPreparePCIDevices: Separate out function body

2019-09-26 Thread Michal Privoznik
In near future we will have a list of PCI devices we want to
detach (held in virPCIDeviceListPtr) but we don't have
virDomainHostdevDefPtr. That's okay because
virHostdevPreparePCIDevices() works with virPCIDeviceListPtr
mostly anyway. And in very few places where it needs
virDomainHostdevDefPtr are not interesting for our case.

Signed-off-by: Michal Privoznik 
ACKed-by: Peter Krempa 
---
 src/util/virhostdev.c | 48 +--
 1 file changed, 33 insertions(+), 15 deletions(-)

diff --git a/src/util/virhostdev.c b/src/util/virhostdev.c
index 85812423b5..d2c881bddf 100644
--- a/src/util/virhostdev.c
+++ b/src/util/virhostdev.c
@@ -719,27 +719,22 @@ virHostdevReattachAllPCIDevices(virHostdevManagerPtr mgr,
 }
 }
 
-int
-virHostdevPreparePCIDevices(virHostdevManagerPtr mgr,
-const char *drv_name,
-const char *dom_name,
-const unsigned char *uuid,
-virDomainHostdevDefPtr *hostdevs,
-int nhostdevs,
-unsigned int flags)
+
+static int
+virHostdevPreparePCIDevicesImpl(virHostdevManagerPtr mgr,
+const char *drv_name,
+const char *dom_name,
+const unsigned char *uuid,
+virPCIDeviceListPtr pcidevs,
+virDomainHostdevDefPtr *hostdevs,
+int nhostdevs,
+unsigned int flags)
 {
-VIR_AUTOUNREF(virPCIDeviceListPtr) pcidevs = NULL;
 int last_processed_hostdev_vf = -1;
 size_t i;
 int ret = -1;
 virPCIDeviceAddressPtr devAddr = NULL;
 
-if (!nhostdevs)
-return 0;
-
-if (!(pcidevs = virHostdevGetPCIHostDeviceList(hostdevs, nhostdevs)))
-return -1;
-
 virObjectLock(mgr->activePCIHostdevs);
 virObjectLock(mgr->inactivePCIHostdevs);
 
@@ -989,6 +984,29 @@ virHostdevPreparePCIDevices(virHostdevManagerPtr mgr,
 return ret;
 }
 
+
+int
+virHostdevPreparePCIDevices(virHostdevManagerPtr mgr,
+const char *drv_name,
+const char *dom_name,
+const unsigned char *uuid,
+virDomainHostdevDefPtr *hostdevs,
+int nhostdevs,
+unsigned int flags)
+{
+VIR_AUTOUNREF(virPCIDeviceListPtr) pcidevs = NULL;
+
+if (!nhostdevs)
+return 0;
+
+if (!(pcidevs = virHostdevGetPCIHostDeviceList(hostdevs, nhostdevs)))
+return -1;
+
+return virHostdevPreparePCIDevicesImpl(mgr, drv_name, dom_name, uuid,
+   pcidevs, hostdevs, nhostdevs, 
flags);
+}
+
+
 /* @oldStateDir:
  * For upgrade purpose: see virHostdevRestoreNetConfig
  */
-- 
2.21.0

--
libvir-list mailing list
libvir-list@redhat.com
https://www.redhat.com/mailman/listinfo/libvir-list


[libvirt] [PATCH v2 09/39] qemuDomainGetHostdevPath: Drop @freeTmpPath

2019-09-26 Thread Michal Privoznik
The @freeTmpPath boolean is used to determine if @tmpPath holds
an allocated memory or is a pointer to a constant string and
therefore if it needs to be freed or not when returning from the
function. Well, we can unify the way we set @tmpPath so that it
always holds an allocated memory and thus always must be freed.

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

diff --git a/src/qemu/qemu_domain.c b/src/qemu/qemu_domain.c
index ca6de24e68..c903750fa0 100644
--- a/src/qemu/qemu_domain.c
+++ b/src/qemu/qemu_domain.c
@@ -12871,7 +12871,6 @@ qemuDomainGetHostdevPath(virDomainDefPtr def,
 virSCSIDevicePtr scsi = NULL;
 virSCSIVHostDevicePtr host = NULL;
 char *tmpPath = NULL;
-bool freeTmpPath = false;
 bool includeVFIO = false;
 char **tmpPaths = NULL;
 int *tmpPerms = NULL;
@@ -12894,7 +12893,6 @@ qemuDomainGetHostdevPath(virDomainDefPtr def,
 
 if (!(tmpPath = virPCIDeviceGetIOMMUGroupDev(pci)))
 goto cleanup;
-freeTmpPath = true;
 
 perm = VIR_CGROUP_DEVICE_RW;
 if (teardown) {
@@ -12915,7 +12913,8 @@ qemuDomainGetHostdevPath(virDomainDefPtr def,
 if (!usb)
 goto cleanup;
 
-tmpPath = (char *)virUSBDeviceGetPath(usb);
+if (VIR_STRDUP(tmpPath, virUSBDeviceGetPath(usb)) < 0)
+goto cleanup;
 perm = VIR_CGROUP_DEVICE_RW;
 break;
 
@@ -12936,7 +12935,8 @@ qemuDomainGetHostdevPath(virDomainDefPtr def,
 if (!scsi)
 goto cleanup;
 
-tmpPath = (char *)virSCSIDeviceGetPath(scsi);
+if (VIR_STRDUP(tmpPath, virSCSIDeviceGetPath(scsi)) < 0)
+goto cleanup;
 perm = virSCSIDeviceGetReadonly(scsi) ?
 VIR_CGROUP_DEVICE_READ : VIR_CGROUP_DEVICE_RW;
 }
@@ -12948,7 +12948,8 @@ qemuDomainGetHostdevPath(virDomainDefPtr def,
 if (!(host = virSCSIVHostDeviceNew(hostsrc->wwpn)))
 goto cleanup;
 
-tmpPath = (char *)virSCSIVHostDeviceGetPath(host);
+if (VIR_STRDUP(tmpPath, virSCSIVHostDeviceGetPath(host)) < 0)
+goto cleanup;
 perm = VIR_CGROUP_DEVICE_RW;
 }
 break;
@@ -12958,7 +12959,6 @@ qemuDomainGetHostdevPath(virDomainDefPtr def,
 if (!(tmpPath = 
virMediatedDeviceGetIOMMUGroupDev(mdevsrc->uuidstr)))
 goto cleanup;
 
-freeTmpPath = true;
 includeVFIO = true;
 perm = VIR_CGROUP_DEVICE_RW;
 break;
@@ -13009,8 +13009,7 @@ qemuDomainGetHostdevPath(virDomainDefPtr def,
 virUSBDeviceFree(usb);
 virSCSIDeviceFree(scsi);
 virSCSIVHostDeviceFree(host);
-if (freeTmpPath)
-VIR_FREE(tmpPath);
+VIR_FREE(tmpPath);
 return ret;
 }
 
-- 
2.21.0

--
libvir-list mailing list
libvir-list@redhat.com
https://www.redhat.com/mailman/listinfo/libvir-list


Re: [libvirt] [PATCH v2 1/7] qemu: Move, rename and export qemuDomObjFromDomain

2019-09-26 Thread Ján Tomko

On Wed, Sep 25, 2019 at 02:54:37PM +0200, Peter Krempa wrote:

Move it to qemu_domain.c and rename it to qemuDomainObjFromDomain. This
will allow reusing it after splitting out checkpoint code from
qemu_driver.c.

Signed-off-by: Peter Krempa 
---
src/qemu/qemu_domain.c |  31 +
src/qemu/qemu_domain.h |   1 +
src/qemu/qemu_driver.c | 303 +++--
3 files changed, 169 insertions(+), 166 deletions(-)



Reviewed-by: Ján Tomko 

Jano


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

Re: [libvirt] [PATCH v2 6/7] qemu: domain: Move checkpoint related code to qemu_checkpoint.c

2019-09-26 Thread Eric Blake

On 9/25/19 7:54 AM, Peter Krempa wrote:

Signed-off-by: Peter Krempa 
---
  src/qemu/qemu_checkpoint.c | 185 ++---
  src/qemu/qemu_checkpoint.h |   5 +
  src/qemu/qemu_domain.c | 162 +---
  src/qemu/qemu_domain.h |  15 ---
  4 files changed, 180 insertions(+), 187 deletions(-)



Thanks for splitting the code motion into two patches.

Reviewed-by: Eric Blake 

--
Eric Blake, Principal Software Engineer
Red Hat, Inc.   +1-919-301-3226
Virtualization:  qemu.org | libvirt.org

--
libvir-list mailing list
libvir-list@redhat.com
https://www.redhat.com/mailman/listinfo/libvir-list


Re: [libvirt] [PATCH 1.5/3] conf: use VIR_AUTOPTR as much as possible for virNetworkPortDefPtr

2019-09-26 Thread Laine Stump

On 9/26/19 2:52 AM, Michal Privoznik wrote:

On 9/23/19 3:08 AM, Laine Stump wrote:

Since the VIR_DEFINE_AUTOPTR_FUNC() was added for
virNetworkPortDefPtr, I decided to convert all uses of
virNetworkPortDefPtr that were appropriate to use VIR_AUTOPTR. This 
could be

squashed into patch 1/2, or left separate, or just completely dropped.

Signed-off-by: Laine Stump 
---
  src/conf/domain_conf.c    | 58 ++-
  src/conf/virnetworkobj.c  |  3 +-
  src/conf/virnetworkportdef.c  | 52 +--
  tests/virnetworkportxml2xmltest.c |  3 +-
  4 files changed, 53 insertions(+), 63 deletions(-)

diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c
index d1e7ac84e8..d638c455d0 100644
--- a/src/conf/domain_conf.c
+++ b/src/conf/domain_conf.c
@@ -30565,7 +30565,8 @@ virNetworkPortDefPtr
  virDomainNetDefToNetworkPort(virDomainDefPtr dom,
   virDomainNetDefPtr iface)
  {
-    virNetworkPortDefPtr port;
+    VIR_AUTOPTR(virNetworkPortDef) port = NULL;
+    virNetworkPortDefPtr portret = NULL;


Here and in the rest of the patch you don need to introduce XXXret 
variable, because ...




-    return port;
-
- error:
-    virNetworkPortDefFree(port);
-    return NULL;
+    VIR_STEAL_PTR(portret, port);
+    return portret;


.. you can just use VIR_RETURN_PTR(port);



Ah, I never noticed that macro. Exactly what I wanted :-)





  }



Also, there is one more occurrence of virNetworkPortDefFree() in 
networkPortCreateXML() in src/network/bridge_driver.c. In fact, code 
inspection says that virNetworkPortDef might be leaked there (for 
instance if checks involving @portdef in the middle of the function 
fail), so please squash this in:


diff --git i/src/network/bridge_driver.c w/src/network/bridge_driver.c
index c54be96407..f9ef7eeb6f 100644
--- i/src/network/bridge_driver.c
+++ w/src/network/bridge_driver.c
@@ -5571,7 +5571,7 @@ networkPortCreateXML(virNetworkPtr net,
 virNetworkDriverStatePtr driver = networkGetDriver();
 virNetworkObjPtr obj;
 virNetworkDefPtr def;
-    virNetworkPortDefPtr portdef = NULL;
+    VIR_AUTOPTR(virNetworkPortDef) portdef = NULL;
 virNetworkPortPtr ret = NULL;
 int rc;

@@ -5621,13 +5621,13 @@ networkPortCreateXML(virNetworkPtr net,

 virErrorPreserveLast(_err);
 ignore_value(networkReleasePort(obj, portdef));
-    virNetworkPortDefFree(portdef);
 virErrorRestore(_err);

 goto cleanup;
 }

 ret = virGetNetworkPort(net, portdef->uuid);
+    portdef = NULL;
  cleanup:
 virNetworkObjEndAPI();
 return ret;



I had looked at that one (I used cscope to look at all of them, and for 
some reason had decided it was inappropriate to convert. But your 
suggestion shows that I was just looking at it wrong. So yes, that looks 
like a good idea.



I'll make the changes before pushing.


Thanks!

--
libvir-list mailing list
libvir-list@redhat.com
https://www.redhat.com/mailman/listinfo/libvir-list

Re: [libvirt] [PATCH v3 02/22] build-aux: rewrite augest test generator in Python

2019-09-26 Thread Peter Krempa
On Thu, Sep 26, 2019 at 16:40:54 +0100, Daniel Berrange wrote:
> On Thu, Sep 26, 2019 at 05:35:46PM +0200, Ján Tomko wrote:
> > On Wed, Sep 25, 2019 at 03:17:10PM +0100, Daniel P. Berrangé wrote:
> > > On Wed, Sep 25, 2019 at 03:25:39PM +0200, Ján Tomko wrote:
> > > > On Tue, Sep 24, 2019 at 03:58:43PM +0100, Daniel P. Berrangé wrote:

[...]

> > > If we create 'scripts/' should we put everything in there, or just
> > > stuff that's related to the top level, and keep everything else in
> > > their current subdirs ?
> > 
> > We put all the driver-specific tests into one tests/ directory, I think
> > doing it for scripts makes sense too.
> 
> I'd really like the move all the tests into their respective driver
> directories at some point :-)

I hope you intend to stash them into a 'tests' subdirectory or
something. Otherwise I'll object as the driver directories themselves
are getting too clobbered with non-test stuff already.

--
libvir-list mailing list
libvir-list@redhat.com
https://www.redhat.com/mailman/listinfo/libvir-list


[libvirt] [PATCH 9/9] qemu: monitor: Remove non-transaction based dirty bitmap APIs

2019-09-26 Thread Peter Krempa
We replaced them by use of transaction to simplify possible failure
scenarios.

Signed-off-by: Peter Krempa 
---
 src/qemu/qemu_monitor.c  |  51 ---
 src/qemu/qemu_monitor.h  |  19 --
 src/qemu/qemu_monitor_json.c | 119 ---
 src/qemu/qemu_monitor_json.h |  17 -
 tests/qemumonitorjsontest.c  |  41 
 5 files changed, 247 deletions(-)

diff --git a/src/qemu/qemu_monitor.c b/src/qemu/qemu_monitor.c
index 0f54c5c0e2..135d70084e 100644
--- a/src/qemu/qemu_monitor.c
+++ b/src/qemu/qemu_monitor.c
@@ -4419,57 +4419,6 @@ qemuMonitorGetCurrentMachineInfo(qemuMonitorPtr mon,
 }


-int
-qemuMonitorAddBitmap(qemuMonitorPtr mon,
- const char *node,
- const char *bitmap,
- bool persistent)
-{
-VIR_DEBUG("node=%s bitmap=%s persistent=%d", node, bitmap, persistent);
-
-QEMU_CHECK_MONITOR(mon);
-
-return qemuMonitorJSONAddBitmap(mon, node, bitmap, persistent);
-}
-
-int
-qemuMonitorEnableBitmap(qemuMonitorPtr mon,
-const char *node,
-const char *bitmap)
-{
-VIR_DEBUG("node=%s bitmap=%s", node, bitmap);
-
-QEMU_CHECK_MONITOR(mon);
-
-return qemuMonitorJSONEnableBitmap(mon, node, bitmap);
-}
-
-int
-qemuMonitorMergeBitmaps(qemuMonitorPtr mon,
-const char *node,
-const char *dst,
-virJSONValuePtr *src)
-{
-VIR_DEBUG("node=%s dst=%s", node, dst);
-
-QEMU_CHECK_MONITOR(mon);
-
-return qemuMonitorJSONMergeBitmaps(mon, node, dst, src);
-}
-
-int
-qemuMonitorDeleteBitmap(qemuMonitorPtr mon,
-const char *node,
-const char *bitmap)
-{
-VIR_DEBUG("node=%s bitmap=%s", node, bitmap);
-
-QEMU_CHECK_MONITOR(mon);
-
-return qemuMonitorJSONDeleteBitmap(mon, node, bitmap);
-}
-
-
 void
 qemuMonitorJobInfoFree(qemuMonitorJobInfoPtr job)
 {
diff --git a/src/qemu/qemu_monitor.h b/src/qemu/qemu_monitor.h
index c6f1f3572b..c3b4808ddc 100644
--- a/src/qemu/qemu_monitor.h
+++ b/src/qemu/qemu_monitor.h
@@ -691,25 +691,6 @@ int qemuMonitorSetBalloon(qemuMonitorPtr mon,
   unsigned long long newmem);
 int qemuMonitorSetCPU(qemuMonitorPtr mon, int cpu, bool online);

-int qemuMonitorAddBitmap(qemuMonitorPtr mon,
- const char *node,
- const char *bitmap,
- bool persistent)
-ATTRIBUTE_NONNULL(2) ATTRIBUTE_NONNULL(3);
-int qemuMonitorEnableBitmap(qemuMonitorPtr mon,
-const char *node,
-const char *bitmap)
-ATTRIBUTE_NONNULL(2) ATTRIBUTE_NONNULL(3);
-int qemuMonitorMergeBitmaps(qemuMonitorPtr mon,
-const char *node,
-const char *dst,
-virJSONValuePtr *src)
-ATTRIBUTE_NONNULL(2) ATTRIBUTE_NONNULL(3) ATTRIBUTE_NONNULL(4);
-int qemuMonitorDeleteBitmap(qemuMonitorPtr mon,
-const char *node,
-const char *bitmap)
-ATTRIBUTE_NONNULL(2) ATTRIBUTE_NONNULL(3);
-

 /* XXX should we pass the virDomainDiskDefPtr instead
  * and hide dev_name details inside monitor. Reconsider
diff --git a/src/qemu/qemu_monitor_json.c b/src/qemu/qemu_monitor_json.c
index 0073c863c2..b8ac413eb8 100644
--- a/src/qemu/qemu_monitor_json.c
+++ b/src/qemu/qemu_monitor_json.c
@@ -8910,125 +8910,6 @@ qemuMonitorJSONGetCurrentMachineInfo(qemuMonitorPtr mon,
 }


-int
-qemuMonitorJSONAddBitmap(qemuMonitorPtr mon,
- const char *node,
- const char *bitmap,
- bool persistent)
-{
-int ret = -1;
-virJSONValuePtr cmd;
-virJSONValuePtr reply = NULL;
-
-if (!(cmd = qemuMonitorJSONMakeCommand("block-dirty-bitmap-add",
-   "s:node", node,
-   "s:name", bitmap,
-   "b:persistent", persistent,
-   NULL)))
-return -1;
-
-if (qemuMonitorJSONCommand(mon, cmd, ) < 0)
-goto cleanup;
-
-if (qemuMonitorJSONCheckError(cmd, reply) < 0)
-goto cleanup;
-
-ret = 0;
- cleanup:
-virJSONValueFree(cmd);
-virJSONValueFree(reply);
-return ret;
-}
-
-int
-qemuMonitorJSONEnableBitmap(qemuMonitorPtr mon,
-const char *node,
-const char *bitmap)
-{
-int ret = -1;
-virJSONValuePtr cmd;
-virJSONValuePtr reply = NULL;
-
-if (!(cmd = qemuMonitorJSONMakeCommand("block-dirty-bitmap-enable",
-   "s:node", node,
-   "s:name", bitmap,
-   NULL)))
-return -1;
-
-if (qemuMonitorJSONCommand(mon, cmd, ) < 0)
- 

Re: [libvirt] [PATCH v3 05/22] build-aux: rewrite whitespace checker in Python

2019-09-26 Thread Ján Tomko

On Tue, Sep 24, 2019 at 03:58:46PM +0100, Daniel P. Berrangé wrote:

As part of an goal to eliminate Perl from libvirt build tools,
rewrite the check-spacing.pl tool in Python.

This was a straight conversion, manually going line-by-line to
change the syntax from Perl to Python. Thus the overall structure
of the file and approach is the same.

Signed-off-by: Daniel P. Berrangé 
---
Makefile.am|   2 +-
build-aux/check-spacing.pl | 198 
build-aux/check-spacing.py | 229 +
cfg.mk |   4 +-
4 files changed, 232 insertions(+), 201 deletions(-)
delete mode 100755 build-aux/check-spacing.pl
create mode 100755 build-aux/check-spacing.py

diff --git a/build-aux/check-spacing.py b/build-aux/check-spacing.py
new file mode 100755
index 00..6b9f3ec1ba
--- /dev/null
+++ b/build-aux/check-spacing.py
@@ -0,0 +1,229 @@
+#!/usr/bin/env python
+#
+# Copyright (C) 2012-2019 Red Hat, Inc.
+#
+# check-spacing.pl: Report any usage of 'function (..args..)'
+# Also check for other syntax issues, such as correct use of ';'
+#
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation; either
+# version 2.1 of the License, or (at your option) any later version.
+#
+# This library is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library.  If not, see
+# .
+
+from __future__ import print_function
+
+import re
+import sys
+
+
+def check_whitespace(filename):
+errs = False
+with open(filename, 'r') as fh:
+quotedmetaprog = re.compile(r"""'[";,=]'""")
+quotedstringprog = re.compile(r'''"(?:[^\\\"]|\\.)*"''')
+commentstartprog = re.compile(r'''^(.*)/\*.*$''')
+commentendprog = re.compile(r'''^.*\*/(.*)$''')
+commentprog = re.compile(r'''^(.*)/\*.*\*/(.*)''')
+funcprog = re.compile(r'''(\w+)\s\((?!\*)''')
+keywordprog = re.compile(
+r'''^.*\b(?:if|for|while|switch|return)\(.*$''')
+functypedefprog = re.compile(r'''^.*\(\*\w+\)\s+\(.*$''')
+whitespaceprog1 = re.compile(r'''^.*\s\).*$''')
+whitespaceprog2 = re.compile(r'''^\s+\);?$''')
+whitespaceprog3 = re.compile(r'''^.*\((?!$)\s.*''')
+commasemiprog1 = re.compile(r'''.*\s[;,].*''')
+commasemiprog2 = re.compile(r'''.*\S; ; .*''')
+commasemiprog3 = re.compile(r'''^\s+;''')
+semicolonprog = re.compile(r'''.*;[^\\\n;)].*''')
+commaprog = re.compile(r'''.*,[^ \\\n)}].*''')
+assignprog1 = re.compile(r'''[^ ]\b[!<>&|\-+*\/%\^=]?=''')
+assignprog2 = re.compile(r'''=[^= \\\n]''')
+condstartprog = re.compile(r'''^\s*(if|while|for)\b.*\{$''')
+statementprog = re.compile(r'''^[^;]*;[^;]*$''')
+condendprog = re.compile(r'''^\s*}\s*$''')
+


I think even with descriptive names for the regexes and the Python
rewrite, this script is hard to read and comes too close to be a C
parser.

Also, the execution time goes from 1.5s to 6.5s, which is longer than
all the other checks combined run on my 8-core machine.

Can we get rid of it completely in favor of some proper formatting tool?

I have played with clang-format to try to match our style, the main
problems seem to be:
* pre-processor directives are indented by the same offset as code
 (I see that cppi is specifically intended to add just one space)
* function calls sometimes leave an empty opening parenthesis
* always rewrapping function arguments might create unnecessary churn
* parameters wrapping might not be smart enough, e.g. we like to do
 virReportError(VIR_ERR_CODE, "%s",
_("string"));
 in a lot of places.

On the plus side, we would be able to properly check for spacing after
casts.

Jano


+incomment = False
+# Per-file variables for multiline Curly Bracket (cb_) check
+cb_lineno = 0
+cb_code = ""
+cb_scolon = False
+
+lineno = 0
+for line in fh:
+lineno = lineno + 1
+data = line
+# For temporary modifications
+
+# Kill any quoted , ; = or "
+data = quotedmetaprog.sub("'X'", data)
+
+# Kill any quoted strings
+data = quotedstringprog.sub('"XXX"', data)
+
+if data[0] == '#':
+continue


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

[libvirt] [PATCH v2 03/39] conf: Introduce virDomainDefHasMdevHostdev

2019-09-26 Thread Michal Privoznik
Signed-off-by: Michal Privoznik 
---
 src/conf/domain_conf.c   | 14 ++
 src/conf/domain_conf.h   |  3 +++
 src/libvirt_private.syms |  1 +
 3 files changed, 18 insertions(+)

diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c
index adf8455579..c1769f743b 100644
--- a/src/conf/domain_conf.c
+++ b/src/conf/domain_conf.c
@@ -31558,6 +31558,20 @@ virDomainDefHasVFIOHostdev(const virDomainDef *def)
 }
 
 
+bool
+virDomainDefHasMdevHostdev(const virDomainDef *def)
+{
+size_t i;
+
+for (i = 0; i < def->nhostdevs; i++) {
+if (virHostdevIsMdevDevice(def->hostdevs[i]))
+return true;
+}
+
+return false;
+}
+
+
 /**
  * virDomainGraphicsDefHasOpenGL:
  * @def: domain definition
diff --git a/src/conf/domain_conf.h b/src/conf/domain_conf.h
index 53bdee22fb..bf5d1a154b 100644
--- a/src/conf/domain_conf.h
+++ b/src/conf/domain_conf.h
@@ -3669,6 +3669,9 @@ virDomainDefHasManagedPR(const virDomainDef *def);
 bool
 virDomainDefHasVFIOHostdev(const virDomainDef *def);
 
+bool
+virDomainDefHasMdevHostdev(const virDomainDef *def);
+
 bool
 virDomainGraphicsDefHasOpenGL(const virDomainDef *def);
 
diff --git a/src/libvirt_private.syms b/src/libvirt_private.syms
index ac37aea626..de124eb37b 100644
--- a/src/libvirt_private.syms
+++ b/src/libvirt_private.syms
@@ -294,6 +294,7 @@ virDomainDefGetVcpusMax;
 virDomainDefGetVcpusTopology;
 virDomainDefHasDeviceAddress;
 virDomainDefHasManagedPR;
+virDomainDefHasMdevHostdev;
 virDomainDefHasMemballoon;
 virDomainDefHasMemoryHotplug;
 virDomainDefHasUSB;
-- 
2.21.0

--
libvir-list mailing list
libvir-list@redhat.com
https://www.redhat.com/mailman/listinfo/libvir-list


[libvirt] [PATCH v2 04/39] qemu_hostdev: Introduce qemuHostdevNeedsVFIO()

2019-09-26 Thread Michal Privoznik
There are two types of host devices that require /dev/vfio/vfio
access:

  1) PCI devices with VFIO backend
  2) Mediated devices

Introduce a simple helper that returns true if passed @hostdev
falls in either of the categories.

Signed-off-by: Michal Privoznik 
---
 src/qemu/qemu_hostdev.c | 9 +
 src/qemu/qemu_hostdev.h | 2 ++
 2 files changed, 11 insertions(+)

diff --git a/src/qemu/qemu_hostdev.c b/src/qemu/qemu_hostdev.c
index af41c32679..ebbca817b8 100644
--- a/src/qemu/qemu_hostdev.c
+++ b/src/qemu/qemu_hostdev.c
@@ -118,6 +118,15 @@ qemuHostdevUpdateActiveDomainDevices(virQEMUDriverPtr 
driver,
 return 0;
 }
 
+
+bool
+qemuHostdevNeedsVFIO(const virDomainHostdevDef *hostdev)
+{
+return virHostdevIsVFIODevice(hostdev) ||
+virHostdevIsMdevDevice(hostdev);
+}
+
+
 bool
 qemuHostdevHostSupportsPassthroughVFIO(void)
 {
diff --git a/src/qemu/qemu_hostdev.h b/src/qemu/qemu_hostdev.h
index e99c204961..536069fe8a 100644
--- a/src/qemu/qemu_hostdev.h
+++ b/src/qemu/qemu_hostdev.h
@@ -24,6 +24,8 @@
 #include "qemu_conf.h"
 #include "domain_conf.h"
 
+bool qemuHostdevNeedsVFIO(const virDomainHostdevDef *hostdev);
+
 bool qemuHostdevHostSupportsPassthroughVFIO(void);
 
 int qemuHostdevUpdateActiveMediatedDevices(virQEMUDriverPtr driver,
-- 
2.21.0

--
libvir-list mailing list
libvir-list@redhat.com
https://www.redhat.com/mailman/listinfo/libvir-list


[libvirt] [PATCH v2 11/39] qemuDomainGetHostdevPath: Don't include /dev/vfio/vfio in returned paths

2019-09-26 Thread Michal Privoznik
Now that all callers of qemuDomainGetHostdevPath() handle
/dev/vfio/vfio on their own, we can safely drop handling in this
function. In near future the decision whether domain needs VFIO
file is going to include more device types than just
virDomainHostdev.

Signed-off-by: Michal Privoznik 
---
 src/qemu/qemu_cgroup.c |  52 -
 src/qemu/qemu_domain.c | 100 +
 src/qemu/qemu_domain.h |   9 ++--
 3 files changed, 42 insertions(+), 119 deletions(-)

diff --git a/src/qemu/qemu_cgroup.c b/src/qemu/qemu_cgroup.c
index f110b49d16..e3ea1e30ab 100644
--- a/src/qemu/qemu_cgroup.c
+++ b/src/qemu/qemu_cgroup.c
@@ -377,26 +377,23 @@ qemuSetupHostdevCgroup(virDomainObjPtr vm,
virDomainHostdevDefPtr dev)
 {
 qemuDomainObjPrivatePtr priv = vm->privateData;
-char **path = NULL;
-int *perms = NULL;
-size_t i, npaths = 0;
+VIR_AUTOFREE(char *) path = NULL;
+int perms;
 int rv, ret = -1;
 
 if (!virCgroupHasController(priv->cgroup, VIR_CGROUP_CONTROLLER_DEVICES))
 return 0;
 
-if (qemuDomainGetHostdevPath(NULL, dev, false, , , ) < 0)
+if (qemuDomainGetHostdevPath(dev, , ) < 0)
 goto cleanup;
 
-for (i = 0; i < npaths; i++) {
-VIR_DEBUG("Cgroup allow %s perms=%d", path[i], perms[i]);
-rv = virCgroupAllowDevicePath(priv->cgroup, path[i], perms[i], false);
-virDomainAuditCgroupPath(vm, priv->cgroup, "allow", path[i],
- virCgroupGetDevicePermsString(perms[i]),
- rv);
-if (rv < 0)
-goto cleanup;
-}
+VIR_DEBUG("Cgroup allow %s perms=%d", path, perms);
+rv = virCgroupAllowDevicePath(priv->cgroup, path, perms, false);
+virDomainAuditCgroupPath(vm, priv->cgroup, "allow", path,
+ virCgroupGetDevicePermsString(perms),
+ rv);
+if (rv < 0)
+goto cleanup;
 
 if (qemuHostdevNeedsVFIO(dev) &&
 !qemuDomainNeedsVFIO(vm->def)) {
@@ -412,10 +409,6 @@ qemuSetupHostdevCgroup(virDomainObjPtr vm,
 ret = 0;
 
  cleanup:
-for (i = 0; i < npaths; i++)
-VIR_FREE(path[i]);
-VIR_FREE(path);
-VIR_FREE(perms);
 return ret;
 }
 
@@ -436,26 +429,22 @@ qemuTeardownHostdevCgroup(virDomainObjPtr vm,
   virDomainHostdevDefPtr dev)
 {
 qemuDomainObjPrivatePtr priv = vm->privateData;
-char **path = NULL;
-size_t i, npaths = 0;
+VIR_AUTOFREE(char *) path = NULL;
 int rv, ret = -1;
 
 if (!virCgroupHasController(priv->cgroup, VIR_CGROUP_CONTROLLER_DEVICES))
 return 0;
 
-if (qemuDomainGetHostdevPath(vm->def, dev, true,
- , , NULL) < 0)
+if (qemuDomainGetHostdevPath(dev, , NULL) < 0)
 goto cleanup;
 
-for (i = 0; i < npaths; i++) {
-VIR_DEBUG("Cgroup deny %s", path[i]);
-rv = virCgroupDenyDevicePath(priv->cgroup, path[i],
- VIR_CGROUP_DEVICE_RWM, false);
-virDomainAuditCgroupPath(vm, priv->cgroup,
- "deny", path[i], "rwm", rv);
-if (rv < 0)
-goto cleanup;
-}
+VIR_DEBUG("Cgroup deny %s", path);
+rv = virCgroupDenyDevicePath(priv->cgroup, path,
+ VIR_CGROUP_DEVICE_RWM, false);
+virDomainAuditCgroupPath(vm, priv->cgroup,
+ "deny", path, "rwm", rv);
+if (rv < 0)
+goto cleanup;
 
 if (qemuHostdevNeedsVFIO(dev) &&
 !qemuDomainNeedsVFIO(vm->def)) {
@@ -470,9 +459,6 @@ qemuTeardownHostdevCgroup(virDomainObjPtr vm,
 
 ret = 0;
  cleanup:
-for (i = 0; i < npaths; i++)
-VIR_FREE(path[i]);
-VIR_FREE(path);
 return ret;
 }
 
diff --git a/src/qemu/qemu_domain.c b/src/qemu/qemu_domain.c
index d8d2f72bcc..bfe7838220 100644
--- a/src/qemu/qemu_domain.c
+++ b/src/qemu/qemu_domain.c
@@ -12836,29 +12836,23 @@ qemuDomainNeedsVFIO(const virDomainDef *def)
 
 /**
  * qemuDomainGetHostdevPath:
- * @def: domain definition
  * @dev: host device definition
- * @teardown: true if device will be removed
- * @npaths: number of items in @path and @perms arrays
  * @path: resulting path to @dev
  * @perms: Optional pointer to VIR_CGROUP_DEVICE_* perms
  *
  * For given device @dev fetch its host path and store it at
- * @path. If a device requires other paths to be present/allowed
- * they are stored in the @path array after the actual path.
- * Optionally, caller can get @perms on the path (e.g. rw/ro).
+ * @path. Optionally, caller can get @perms on the path (e.g.
+ * rw/ro).
  *
- * The caller is responsible for freeing the memory.
+ * The caller is responsible for freeing the @path when no longer
+ * needed.
  *
  * Returns 0 on success, -1 otherwise.
  */
 int
-qemuDomainGetHostdevPath(virDomainDefPtr def,
- virDomainHostdevDefPtr dev,
- bool 

[libvirt] [PATCH v2 02/39] virhostdev: Introduce and use virHostdevIsVFIODevice

2019-09-26 Thread Michal Privoznik
In some places we need to check if a hostdev has VFIO backend.
Because of how complicated virDomainHostdevDef structure is, the
check consists of three lines. Move them to a function and
replace all checks with the function call.

Signed-off-by: Michal Privoznik 
---
 src/conf/domain_conf.c   |  5 +
 src/libvirt_private.syms |  1 +
 src/qemu/qemu_cgroup.c   |  4 +---
 src/qemu/qemu_domain.c   | 12 +++-
 src/qemu/qemu_hotplug.c  |  8 +---
 src/util/virhostdev.c| 15 +++
 src/util/virhostdev.h|  3 +++
 7 files changed, 25 insertions(+), 23 deletions(-)

diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c
index c290baf953..adf8455579 100644
--- a/src/conf/domain_conf.c
+++ b/src/conf/domain_conf.c
@@ -31550,10 +31550,7 @@ virDomainDefHasVFIOHostdev(const virDomainDef *def)
 size_t i;
 
 for (i = 0; i < def->nhostdevs; i++) {
-const virDomainHostdevDef *tmp = def->hostdevs[i];
-if (tmp->mode == VIR_DOMAIN_HOSTDEV_MODE_SUBSYS &&
-tmp->source.subsys.type == VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_PCI &&
-tmp->source.subsys.u.pci.backend == 
VIR_DOMAIN_HOSTDEV_PCI_BACKEND_VFIO)
+if (virHostdevIsVFIODevice(def->hostdevs[i]))
 return true;
 }
 
diff --git a/src/libvirt_private.syms b/src/libvirt_private.syms
index 287e63bffa..ac37aea626 100644
--- a/src/libvirt_private.syms
+++ b/src/libvirt_private.syms
@@ -2104,6 +2104,7 @@ virHostCPUStatsAssign;
 virHostdevFindUSBDevice;
 virHostdevIsMdevDevice;
 virHostdevIsSCSIDevice;
+virHostdevIsVFIODevice;
 virHostdevManagerGetDefault;
 virHostdevPCINodeDeviceDetach;
 virHostdevPCINodeDeviceReAttach;
diff --git a/src/qemu/qemu_cgroup.c b/src/qemu/qemu_cgroup.c
index 740a1b33dc..318157dab0 100644
--- a/src/qemu/qemu_cgroup.c
+++ b/src/qemu/qemu_cgroup.c
@@ -413,9 +413,7 @@ qemuTeardownHostdevCgroup(virDomainObjPtr vm,
 if (!virCgroupHasController(priv->cgroup, VIR_CGROUP_CONTROLLER_DEVICES))
 return 0;
 
-if (dev->mode == VIR_DOMAIN_HOSTDEV_MODE_SUBSYS &&
-dev->source.subsys.type == VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_PCI &&
-dev->source.subsys.u.pci.backend == 
VIR_DOMAIN_HOSTDEV_PCI_BACKEND_VFIO &&
+if (virHostdevIsVFIODevice(dev) &&
 qemuDomainGetHostdevPath(vm->def, dev, true,
  , , NULL) < 0)
 goto cleanup;
diff --git a/src/qemu/qemu_domain.c b/src/qemu/qemu_domain.c
index 2aa2164953..824bca89f4 100644
--- a/src/qemu/qemu_domain.c
+++ b/src/qemu/qemu_domain.c
@@ -11871,9 +11871,7 @@ getPPC64MemLockLimitBytes(virDomainDefPtr def)
 for (i = 0; i < def->nhostdevs; i++) {
 virDomainHostdevDefPtr dev = def->hostdevs[i];
 
-if (dev->mode == VIR_DOMAIN_HOSTDEV_MODE_SUBSYS &&
-dev->source.subsys.type == VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_PCI &&
-dev->source.subsys.u.pci.backend == 
VIR_DOMAIN_HOSTDEV_PCI_BACKEND_VFIO) {
+if (virHostdevIsVFIODevice(dev)) {
 usesVFIO = true;
 
 pciAddr = >source.subsys.u.pci.addr;
@@ -12025,12 +12023,8 @@ qemuDomainGetMemLockLimitBytes(virDomainDefPtr def)
  * Note that this may not be valid for all platforms.
  */
 for (i = 0; i < def->nhostdevs; i++) {
-virDomainHostdevSubsysPtr subsys = >hostdevs[i]->source.subsys;
-
-if (def->hostdevs[i]->mode == VIR_DOMAIN_HOSTDEV_MODE_SUBSYS &&
-(subsys->type == VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_MDEV ||
- (subsys->type == VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_PCI &&
-  subsys->u.pci.backend == VIR_DOMAIN_HOSTDEV_PCI_BACKEND_VFIO))) {
+if (virHostdevIsVFIODevice(def->hostdevs[i]) ||
+virHostdevIsMdevDevice(def->hostdevs[i])) {
 memKB = virDomainDefGetMemoryTotal(def) + 1024 * 1024;
 goto done;
 }
diff --git a/src/qemu/qemu_hotplug.c b/src/qemu/qemu_hotplug.c
index e9285f0964..5f92c61aa9 100644
--- a/src/qemu/qemu_hotplug.c
+++ b/src/qemu/qemu_hotplug.c
@@ -4440,16 +4440,10 @@ qemuDomainRemoveHostDevice(virQEMUDriverPtr driver,
 qemuDomainObjPrivatePtr priv = vm->privateData;
 VIR_AUTOFREE(char *) drivealias = NULL;
 VIR_AUTOFREE(char *) objAlias = NULL;
-bool is_vfio = false;
 
 VIR_DEBUG("Removing host device %s from domain %p %s",
   hostdev->info->alias, vm, vm->def->name);
 
-if (hostdev->source.subsys.type == VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_PCI) {
-int backend = hostdev->source.subsys.u.pci.backend;
-is_vfio = backend == VIR_DOMAIN_HOSTDEV_PCI_BACKEND_VFIO;
-}
-
 if (hostdev->source.subsys.type == VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_SCSI) {
 virDomainHostdevSubsysSCSIPtr scsisrc = >source.subsys.u.scsi;
 virDomainHostdevSubsysSCSIiSCSIPtr iscsisrc = >u.iscsi;
@@ -4497,7 +4491,7 @@ qemuDomainRemoveHostDevice(virQEMUDriverPtr driver,
 
 virDomainAuditHostdev(vm, hostdev, "detach", true);
 
-if (!is_vfio &&
+if (!virHostdevIsVFIODevice(hostdev) &&
 

[libvirt] [PATCH v2 01/39] virhostdev: Fix const correctness of virHostdevIs{PCINet, SCSI, Mdev}Device()

2019-09-26 Thread Michal Privoznik
These functions do not change any of the passed hostdevs. They
just read them.

Signed-off-by: Michal Privoznik 
---
 src/util/virhostdev.c | 6 +++---
 src/util/virhostdev.h | 4 ++--
 2 files changed, 5 insertions(+), 5 deletions(-)

diff --git a/src/util/virhostdev.c b/src/util/virhostdev.c
index 41fcab7222..90967b7c7a 100644
--- a/src/util/virhostdev.c
+++ b/src/util/virhostdev.c
@@ -354,7 +354,7 @@ virHostdevNetDevice(virDomainHostdevDefPtr hostdev,
 
 
 static bool
-virHostdevIsPCINetDevice(virDomainHostdevDefPtr hostdev)
+virHostdevIsPCINetDevice(const virDomainHostdevDef *hostdev)
 {
 return hostdev->mode == VIR_DOMAIN_HOSTDEV_MODE_SUBSYS &&
 hostdev->source.subsys.type == VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_PCI &&
@@ -369,7 +369,7 @@ virHostdevIsPCINetDevice(virDomainHostdevDefPtr hostdev)
  * Returns true if @hostdev is a SCSI device, false otherwise.
  */
 bool
-virHostdevIsSCSIDevice(virDomainHostdevDefPtr hostdev)
+virHostdevIsSCSIDevice(const virDomainHostdevDef *hostdev)
 {
 return hostdev->mode == VIR_DOMAIN_HOSTDEV_MODE_SUBSYS &&
 hostdev->source.subsys.type == VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_SCSI;
@@ -383,7 +383,7 @@ virHostdevIsSCSIDevice(virDomainHostdevDefPtr hostdev)
  * Returns true if @hostdev is a Mediated device, false otherwise.
  */
 bool
-virHostdevIsMdevDevice(virDomainHostdevDefPtr hostdev)
+virHostdevIsMdevDevice(const virDomainHostdevDef *hostdev)
 {
 return hostdev->mode == VIR_DOMAIN_HOSTDEV_MODE_SUBSYS &&
 hostdev->source.subsys.type == VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_MDEV;
diff --git a/src/util/virhostdev.h b/src/util/virhostdev.h
index 88501e2743..8d7b8c3284 100644
--- a/src/util/virhostdev.h
+++ b/src/util/virhostdev.h
@@ -185,10 +185,10 @@ virHostdevReAttachDomainDevices(virHostdevManagerPtr mgr,
 const char *oldStateDir)
 ATTRIBUTE_NONNULL(2) ATTRIBUTE_NONNULL(3);
 bool
-virHostdevIsSCSIDevice(virDomainHostdevDefPtr hostdev)
+virHostdevIsSCSIDevice(const virDomainHostdevDef *hostdev)
 ATTRIBUTE_NONNULL(1);
 bool
-virHostdevIsMdevDevice(virDomainHostdevDefPtr hostdev)
+virHostdevIsMdevDevice(const virDomainHostdevDef *hostdev)
 ATTRIBUTE_NONNULL(1);
 
 /* functions used by NodeDevDetach/Reattach/Reset */
-- 
2.21.0

--
libvir-list mailing list
libvir-list@redhat.com
https://www.redhat.com/mailman/listinfo/libvir-list


[libvirt] [PATCH v2 08/39] qemu_domain: Drop few useless checks in qemuDomainGetHostdevPath

2019-09-26 Thread Michal Privoznik
There are three cases where vir*DeviceGetPath() returns a const
string. In these cases, the string is initialized in
corresponding vir*DeviceNew() calls which fail if string couldn't
be allocated. There's no point in checking the second time if the
string is NULL.

Signed-off-by: Michal Privoznik 
---
 src/qemu/qemu_domain.c | 9 +++--
 1 file changed, 3 insertions(+), 6 deletions(-)

diff --git a/src/qemu/qemu_domain.c b/src/qemu/qemu_domain.c
index 02b6e590cd..ca6de24e68 100644
--- a/src/qemu/qemu_domain.c
+++ b/src/qemu/qemu_domain.c
@@ -12915,8 +12915,7 @@ qemuDomainGetHostdevPath(virDomainDefPtr def,
 if (!usb)
 goto cleanup;
 
-if (!(tmpPath = (char *)virUSBDeviceGetPath(usb)))
-goto cleanup;
+tmpPath = (char *)virUSBDeviceGetPath(usb);
 perm = VIR_CGROUP_DEVICE_RW;
 break;
 
@@ -12937,8 +12936,7 @@ qemuDomainGetHostdevPath(virDomainDefPtr def,
 if (!scsi)
 goto cleanup;
 
-if (!(tmpPath = (char *)virSCSIDeviceGetPath(scsi)))
-goto cleanup;
+tmpPath = (char *)virSCSIDeviceGetPath(scsi);
 perm = virSCSIDeviceGetReadonly(scsi) ?
 VIR_CGROUP_DEVICE_READ : VIR_CGROUP_DEVICE_RW;
 }
@@ -12950,8 +12948,7 @@ qemuDomainGetHostdevPath(virDomainDefPtr def,
 if (!(host = virSCSIVHostDeviceNew(hostsrc->wwpn)))
 goto cleanup;
 
-if (!(tmpPath = (char *)virSCSIVHostDeviceGetPath(host)))
-goto cleanup;
+tmpPath = (char *)virSCSIVHostDeviceGetPath(host);
 perm = VIR_CGROUP_DEVICE_RW;
 }
 break;
-- 
2.21.0

--
libvir-list mailing list
libvir-list@redhat.com
https://www.redhat.com/mailman/listinfo/libvir-list


[libvirt] [PATCH v2 00/39] Introduce NVMe support

2019-09-26 Thread Michal Privoznik
v2 of:

https://www.redhat.com/archives/libvir-list/2019-July/msg00675.html

As usual, you can find my patches on my github:

https://github.com/zippy2/libvirt/tree/nvme_v3

https://travis-ci.org/zippy2/libvirt/builds/590033775

(Yeah, my branch is really called _v3 because reasons)

diff to v1:
- A lot. Hopefully all Peter's comments are worked in

Michal Prívozník (39):
  virhostdev: Fix const correctness of
virHostdevIs{PCINet,SCSI,Mdev}Device()
  virhostdev: Introduce and use virHostdevIsVFIODevice
  conf: Introduce virDomainDefHasMdevHostdev
  qemu_hostdev: Introduce qemuHostdevNeedsVFIO()
  qemu: Introduce qemuDomainNeedsVFIO
  qemu_cgroup: Teardown Cgroup for more host device types
  qemu: Explicitly add/remove /dev/vfio/vfio to/from NS/CGroups
  qemu_domain: Drop few useless checks in qemuDomainGetHostdevPath
  qemuDomainGetHostdevPath: Drop @freeTmpPath
  qemuDomainGetHostdevPath: Use more VIR_AUTOFREE/VIR_AUTOPTR
  qemuDomainGetHostdevPath: Don't include /dev/vfio/vfio in returned
paths
  qemu: Drop some 'cleanup' labels
  virpci: Introduce and use virPCIDeviceAddressGetIOMMUGroupDev
  virHostdevPreparePCIDevices: Separate out function body
  virHostdevReAttachPCIDevices: Separate out function body
  virpci: Introduce virPCIDeviceAddressCopy
  qemuMigrationSrcIsSafe: Rework slightly
  schemas: Introduce disk type NVMe
  conf: Format and parse NVMe type disk
  virstoragefile: Introduce virStorageSourceChainHasNVMe
  domain_conf: Introduce virDomainDefHasNVMeDisk
  util: Introduce virNVMeDevice module
  virhostdev: Include virNVMeDevice module
  virpcimock: Introduce NVMe driver and devices
  virhostdevtest: Test virNVMeDevice assignment
  qemu: prepare NVMe devices too
  qemu: Take NVMe disks into account when calculating memlock limit
  qemu: Create NVMe disk in domain namespace
  qemu: Mark NVMe disks as 'need VFIO'
  qemu: Allow NVMe disk in CGroups
  security_selinux: Simplify virSecuritySELinuxSetImageLabelInternal
  virSecuritySELinuxRestoreImageLabelInt: Don't skip non-local storage
  qemu_capabilities: Introduce QEMU_CAPS_DRIVE_NVME
  qemu: Generate command line of NVMe disks
  qemu_monitor_text: Catch IOMMU/VFIO related errors in
qemuMonitorTextAddDrive
  qemu: Don't leak storage perms on failure in
qemuDomainAttachDiskGeneric
  qemu: Allow forcing VFIO when computing memlock limit
  qemu_hotplug: Prepare NVMe disks on hotplug
  virsh: Introduce nvme disk to domblklist

 docs/formatdomain.html.in |  57 ++-
 docs/schemas/domaincommon.rng |  32 ++
 src/conf/domain_conf.c| 129 -
 src/conf/domain_conf.h|   6 +
 src/libvirt_private.syms  |  30 ++
 src/libxl/xen_xl.c|   1 +
 src/qemu/qemu_block.c |  25 +
 src/qemu/qemu_capabilities.c  |   4 +
 src/qemu/qemu_capabilities.h  |   3 +
 src/qemu/qemu_cgroup.c| 216 ++---
 src/qemu/qemu_command.c   |   6 +-
 src/qemu/qemu_domain.c| 409 +---
 src/qemu/qemu_domain.h|  17 +-
 src/qemu/qemu_driver.c|   4 +
 src/qemu/qemu_hostdev.c   |  80 ++-
 src/qemu/qemu_hostdev.h   |  18 +
 src/qemu/qemu_hotplug.c   |  39 +-
 src/qemu/qemu_migration.c |  30 +-
 src/qemu/qemu_monitor_text.c  |   7 +
 src/qemu/qemu_process.c   |   7 +
 src/security/security_apparmor.c  |  33 +-
 src/security/security_dac.c   |  30 ++
 src/security/security_selinux.c   |  82 ++--
 src/util/Makefile.inc.am  |   2 +
 src/util/virhostdev.c | 455 --
 src/util/virhostdev.h |  44 +-
 src/util/virnvme.c| 454 +
 src/util/virnvme.h|  95 
 src/util/virpci.c |  29 ++
 src/util/virpci.h |   5 +
 src/util/virstoragefile.c |  73 +++
 src/util/virstoragefile.h |  19 +
 .../caps_2.12.0.aarch64.xml   |   1 +
 .../caps_2.12.0.ppc64.xml |   1 +
 .../caps_2.12.0.s390x.xml |   1 +
 .../caps_2.12.0.x86_64.xml|   1 +
 .../qemucapabilitiesdata/caps_3.0.0.ppc64.xml |   1 +
 .../caps_3.0.0.riscv32.xml|   1 +
 .../caps_3.0.0.riscv64.xml|   1 +
 .../qemucapabilitiesdata/caps_3.0.0.s390x.xml |   1 +
 .../caps_3.0.0.x86_64.xml |   1 +
 .../qemucapabilitiesdata/caps_3.1.0.ppc64.xml |   1 +
 .../caps_3.1.0.x86_64.xml |   1 +
 .../caps_4.0.0.aarch64.xml|   1 +
 .../qemucapabilitiesdata/caps_4.0.0.ppc64.xml |  

[libvirt] [PATCH v2 12/39] qemu: Drop some 'cleanup' labels

2019-09-26 Thread Michal Privoznik
Previous patches rendered some of 'cleanup' labels needless.
Drop them.

Signed-off-by: Michal Privoznik 
---
 src/qemu/qemu_cgroup.c | 25 ---
 src/qemu/qemu_domain.c | 56 +-
 2 files changed, 32 insertions(+), 49 deletions(-)

diff --git a/src/qemu/qemu_cgroup.c b/src/qemu/qemu_cgroup.c
index e3ea1e30ab..9684bf3662 100644
--- a/src/qemu/qemu_cgroup.c
+++ b/src/qemu/qemu_cgroup.c
@@ -379,13 +379,13 @@ qemuSetupHostdevCgroup(virDomainObjPtr vm,
 qemuDomainObjPrivatePtr priv = vm->privateData;
 VIR_AUTOFREE(char *) path = NULL;
 int perms;
-int rv, ret = -1;
+int rv;
 
 if (!virCgroupHasController(priv->cgroup, VIR_CGROUP_CONTROLLER_DEVICES))
 return 0;
 
 if (qemuDomainGetHostdevPath(dev, , ) < 0)
-goto cleanup;
+return -1;
 
 VIR_DEBUG("Cgroup allow %s perms=%d", path, perms);
 rv = virCgroupAllowDevicePath(priv->cgroup, path, perms, false);
@@ -393,7 +393,7 @@ qemuSetupHostdevCgroup(virDomainObjPtr vm,
  virCgroupGetDevicePermsString(perms),
  rv);
 if (rv < 0)
-goto cleanup;
+return -1;
 
 if (qemuHostdevNeedsVFIO(dev) &&
 !qemuDomainNeedsVFIO(vm->def)) {
@@ -403,13 +403,10 @@ qemuSetupHostdevCgroup(virDomainObjPtr vm,
 virDomainAuditCgroupPath(vm, priv->cgroup, "allow",
  QEMU_DEV_VFIO, "rw", rv);
 if (rv < 0)
-goto cleanup;
+return -1;
 }
 
-ret = 0;
-
- cleanup:
-return ret;
+return 0;
 }
 
 
@@ -430,13 +427,13 @@ qemuTeardownHostdevCgroup(virDomainObjPtr vm,
 {
 qemuDomainObjPrivatePtr priv = vm->privateData;
 VIR_AUTOFREE(char *) path = NULL;
-int rv, ret = -1;
+int rv;
 
 if (!virCgroupHasController(priv->cgroup, VIR_CGROUP_CONTROLLER_DEVICES))
 return 0;
 
 if (qemuDomainGetHostdevPath(dev, , NULL) < 0)
-goto cleanup;
+return -1;
 
 VIR_DEBUG("Cgroup deny %s", path);
 rv = virCgroupDenyDevicePath(priv->cgroup, path,
@@ -444,7 +441,7 @@ qemuTeardownHostdevCgroup(virDomainObjPtr vm,
 virDomainAuditCgroupPath(vm, priv->cgroup,
  "deny", path, "rwm", rv);
 if (rv < 0)
-goto cleanup;
+return -1;
 
 if (qemuHostdevNeedsVFIO(dev) &&
 !qemuDomainNeedsVFIO(vm->def)) {
@@ -454,12 +451,10 @@ qemuTeardownHostdevCgroup(virDomainObjPtr vm,
 virDomainAuditCgroupPath(vm, priv->cgroup, "deny",
  QEMU_DEV_VFIO, "rwm", rv);
 if (rv < 0)
-goto cleanup;
+return -1;
 }
 
-ret = 0;
- cleanup:
-return ret;
+return 0;
 }
 
 
diff --git a/src/qemu/qemu_domain.c b/src/qemu/qemu_domain.c
index bfe7838220..e92c2053c1 100644
--- a/src/qemu/qemu_domain.c
+++ b/src/qemu/qemu_domain.c
@@ -12854,7 +12854,6 @@ qemuDomainGetHostdevPath(virDomainHostdevDefPtr dev,
  char **path,
  int *perms)
 {
-int ret = -1;
 virDomainHostdevSubsysUSBPtr usbsrc = >source.subsys.u.usb;
 virDomainHostdevSubsysPCIPtr pcisrc = >source.subsys.u.pci;
 virDomainHostdevSubsysSCSIPtr scsisrc = >source.subsys.u.scsi;
@@ -12877,10 +12876,10 @@ qemuDomainGetHostdevPath(virDomainHostdevDefPtr dev,
   pcisrc->addr.slot,
   pcisrc->addr.function);
 if (!pci)
-goto cleanup;
+return -1;
 
 if (!(tmpPath = virPCIDeviceGetIOMMUGroupDev(pci)))
-goto cleanup;
+return -1;
 
 perm = VIR_CGROUP_DEVICE_RW;
 }
@@ -12893,10 +12892,10 @@ qemuDomainGetHostdevPath(virDomainHostdevDefPtr dev,
   usbsrc->device,
   NULL);
 if (!usb)
-goto cleanup;
+return -1;
 
 if (VIR_STRDUP(tmpPath, virUSBDeviceGetPath(usb)) < 0)
-goto cleanup;
+return -1;
 perm = VIR_CGROUP_DEVICE_RW;
 break;
 
@@ -12915,10 +12914,10 @@ qemuDomainGetHostdevPath(virDomainHostdevDefPtr dev,
 dev->shareable);
 
 if (!scsi)
-goto cleanup;
+return -1;
 
 if (VIR_STRDUP(tmpPath, virSCSIDeviceGetPath(scsi)) < 0)
-goto cleanup;
+return -1;
 perm = virSCSIDeviceGetReadonly(scsi) ?
 VIR_CGROUP_DEVICE_READ : VIR_CGROUP_DEVICE_RW;
 }
@@ -12928,10 +12927,10 @@ qemuDomainGetHostdevPath(virDomainHostdevDefPtr dev,
 if (hostsrc->protocol ==
 VIR_DOMAIN_HOSTDEV_SUBSYS_SCSI_HOST_PROTOCOL_TYPE_VHOST) {
 if (!(host = virSCSIVHostDeviceNew(hostsrc->wwpn)))

[libvirt] [PATCH v2 05/39] qemu: Introduce qemuDomainNeedsVFIO

2019-09-26 Thread Michal Privoznik
Signed-off-by: Michal Privoznik 
---
 src/qemu/qemu_domain.c | 9 +
 src/qemu/qemu_domain.h | 2 ++
 2 files changed, 11 insertions(+)

diff --git a/src/qemu/qemu_domain.c b/src/qemu/qemu_domain.c
index 824bca89f4..6502c6191c 100644
--- a/src/qemu/qemu_domain.c
+++ b/src/qemu/qemu_domain.c
@@ -29,6 +29,7 @@
 #include "qemu_dbus.h"
 #include "qemu_process.h"
 #include "qemu_capabilities.h"
+#include "qemu_hostdev.h"
 #include "qemu_migration.h"
 #include "qemu_migration_params.h"
 #include "qemu_security.h"
@@ -12825,6 +12826,14 @@ qemuDomainSupportsVideoVga(virDomainVideoDefPtr video,
 }
 
 
+bool
+qemuDomainNeedsVFIO(const virDomainDef *def)
+{
+return virDomainDefHasVFIOHostdev(def) ||
+virDomainDefHasMdevHostdev(def);
+}
+
+
 /**
  * qemuDomainGetHostdevPath:
  * @def: domain definition
diff --git a/src/qemu/qemu_domain.h b/src/qemu/qemu_domain.h
index 6c490bd9d8..8e3917c205 100644
--- a/src/qemu/qemu_domain.h
+++ b/src/qemu/qemu_domain.h
@@ -1084,6 +1084,8 @@ int qemuDomainCheckMonitor(virQEMUDriverPtr driver,
 bool qemuDomainSupportsVideoVga(virDomainVideoDefPtr video,
 virQEMUCapsPtr qemuCaps);
 
+bool qemuDomainNeedsVFIO(const virDomainDef *def);
+
 int qemuDomainGetHostdevPath(virDomainDefPtr def,
  virDomainHostdevDefPtr dev,
  bool teardown,
-- 
2.21.0

--
libvir-list mailing list
libvir-list@redhat.com
https://www.redhat.com/mailman/listinfo/libvir-list


Re: [libvirt] [PATCH v3 02/22] build-aux: rewrite augest test generator in Python

2019-09-26 Thread Daniel P . Berrangé
On Thu, Sep 26, 2019 at 05:58:47PM +0200, Peter Krempa wrote:
> On Thu, Sep 26, 2019 at 16:40:54 +0100, Daniel Berrange wrote:
> > On Thu, Sep 26, 2019 at 05:35:46PM +0200, Ján Tomko wrote:
> > > On Wed, Sep 25, 2019 at 03:17:10PM +0100, Daniel P. Berrangé wrote:
> > > > On Wed, Sep 25, 2019 at 03:25:39PM +0200, Ján Tomko wrote:
> > > > > On Tue, Sep 24, 2019 at 03:58:43PM +0100, Daniel P. Berrangé wrote:
> 
> [...]
> 
> > > > If we create 'scripts/' should we put everything in there, or just
> > > > stuff that's related to the top level, and keep everything else in
> > > > their current subdirs ?
> > > 
> > > We put all the driver-specific tests into one tests/ directory, I think
> > > doing it for scripts makes sense too.
> > 
> > I'd really like the move all the tests into their respective driver
> > directories at some point :-)
> 
> I hope you intend to stash them into a 'tests' subdirectory or
> something. Otherwise I'll object as the driver directories themselves
> are getting too clobbered with non-test stuff already.

I've not thought that far ahead to be honest - its just a random wishlist
item at number 783 on the todo list.

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 :|

--
libvir-list mailing list
libvir-list@redhat.com
https://www.redhat.com/mailman/listinfo/libvir-list

[libvirt] [PATCH v4 07/12] storage_driver.c: use virConnectValidateURIPath()

2019-09-26 Thread Daniel Henrique Barboza
Suggested-by: Cole Robinson 
Signed-off-by: Daniel Henrique Barboza 
---
 src/storage/storage_driver.c | 19 ---
 1 file changed, 4 insertions(+), 15 deletions(-)

diff --git a/src/storage/storage_driver.c b/src/storage/storage_driver.c
index ce10b55ed0..d160ff34fe 100644
--- a/src/storage/storage_driver.c
+++ b/src/storage/storage_driver.c
@@ -411,21 +411,10 @@ storageConnectOpen(virConnectPtr conn,
 return VIR_DRV_OPEN_ERROR;
 }
 
-if (driver->privileged) {
-if (STRNEQ(conn->uri->path, "/system")) {
-virReportError(VIR_ERR_INTERNAL_ERROR,
-   _("unexpected storage URI path '%s', try 
storage:///system"),
-   conn->uri->path);
-return VIR_DRV_OPEN_ERROR;
-}
-} else {
-if (STRNEQ(conn->uri->path, "/session")) {
-virReportError(VIR_ERR_INTERNAL_ERROR,
-   _("unexpected storage URI path '%s', try 
storage:///session"),
-   conn->uri->path);
-return VIR_DRV_OPEN_ERROR;
-}
-}
+if (!virConnectValidateURIPath(conn->uri->path,
+   "storage",
+   driver->privileged))
+return VIR_DRV_OPEN_ERROR;
 
 if (virConnectOpenEnsureACL(conn) < 0)
 return VIR_DRV_OPEN_ERROR;
-- 
2.21.0

--
libvir-list mailing list
libvir-list@redhat.com
https://www.redhat.com/mailman/listinfo/libvir-list


[libvirt] [PATCH v4 05/12] node_device_driver.c: use virConnectValidateURIPath()

2019-09-26 Thread Daniel Henrique Barboza
Suggested-by: Cole Robinson 
Signed-off-by: Daniel Henrique Barboza 
---
 src/node_device/node_device_driver.c | 19 ---
 1 file changed, 4 insertions(+), 15 deletions(-)

diff --git a/src/node_device/node_device_driver.c 
b/src/node_device/node_device_driver.c
index 8fb00d0c86..578489c5be 100644
--- a/src/node_device/node_device_driver.c
+++ b/src/node_device/node_device_driver.c
@@ -58,21 +58,10 @@ nodeConnectOpen(virConnectPtr conn,
 return VIR_DRV_OPEN_ERROR;
 }
 
-if (driver->privileged) {
-if (STRNEQ(conn->uri->path, "/system")) {
-virReportError(VIR_ERR_INTERNAL_ERROR,
-   _("unexpected nodedev URI path '%s', try 
nodedev:///system"),
-   conn->uri->path);
-return VIR_DRV_OPEN_ERROR;
-}
-} else {
-if (STRNEQ(conn->uri->path, "/session")) {
-virReportError(VIR_ERR_INTERNAL_ERROR,
-   _("unexpected nodedev URI path '%s', try 
nodedev:///session"),
-   conn->uri->path);
-return VIR_DRV_OPEN_ERROR;
-}
-}
+if (!virConnectValidateURIPath(conn->uri->path,
+   "nodedev",
+   driver->privileged))
+return VIR_DRV_OPEN_ERROR;
 
 if (virConnectOpenEnsureACL(conn) < 0)
 return VIR_DRV_OPEN_ERROR;
-- 
2.21.0

--
libvir-list mailing list
libvir-list@redhat.com
https://www.redhat.com/mailman/listinfo/libvir-list


[libvirt] [PATCH v4 12/12] tests: add a test for driver.c:virConnectValidateURIPath()

2019-09-26 Thread Daniel Henrique Barboza
Signed-off-by: Daniel Henrique Barboza 
---

I've made this test file to make sure I wasn't messing
up with the logic at patch 8. The idea of having this
test seems okay, but probably I could do it shorter/cleaner.

Feel free to discard it if it's not applicable or
unnecessary. Adding this new file make the whole patch series,
aimed at reduce code repetition and lines of code, add more
lines than before. The irony is real.


 tests/Makefile.am |   7 +-
 tests/virdriverconnvalidatetest.c | 186 ++
 2 files changed, 192 insertions(+), 1 deletion(-)
 create mode 100644 tests/virdriverconnvalidatetest.c

diff --git a/tests/Makefile.am b/tests/Makefile.am
index d88ad7f686..c7f563d24d 100644
--- a/tests/Makefile.am
+++ b/tests/Makefile.am
@@ -433,7 +433,8 @@ test_scripts += $(libvirtd_test_scripts)
 
 test_programs += \
eventtest \
-   virdrivermoduletest
+   virdrivermoduletest \
+   virdriverconnvalidatetest
 else ! WITH_LIBVIRTD
 EXTRA_DIST += $(libvirtd_test_scripts)
 endif ! WITH_LIBVIRTD
@@ -1485,6 +1486,10 @@ if WITH_LIBVIRTD
 virdrivermoduletest_SOURCES = \
virdrivermoduletest.c testutils.h testutils.c
 virdrivermoduletest_LDADD = $(LDADDS)
+
+virdriverconnvalidatetest_SOURCES = \
+   virdriverconnvalidatetest.c testutils.h testutils.c
+virdriverconnvalidatetest_LDADD = $(LDADDS)
 endif WITH_LIBVIRTD
 
 if WITH_LIBVIRTD
diff --git a/tests/virdriverconnvalidatetest.c 
b/tests/virdriverconnvalidatetest.c
new file mode 100644
index 00..599150dc08
--- /dev/null
+++ b/tests/virdriverconnvalidatetest.c
@@ -0,0 +1,186 @@
+/*
+ * Copyright (C) 2019 IBM Corporation
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library.  If not, see
+ * .
+ */
+
+#include 
+
+#include "testutils.h"
+#include "virerror.h"
+#include "viralloc.h"
+#include "virlog.h"
+#include "driver.h"
+
+#define VIR_FROM_THIS VIR_FROM_NONE
+
+VIR_LOG_INIT("tests.driverconnvalidatetest");
+
+struct testDriverConnValidateData {
+const char *uriPath;
+const char *entityName;
+bool privileged;
+bool expectFailure;
+};
+
+
+static int testDriverConnValidate(const void *args)
+{
+const struct testDriverConnValidateData *data = args;
+
+bool ret = virConnectValidateURIPath(data->uriPath,
+ data->entityName,
+ data->privileged);
+if (data->expectFailure)
+ret = !ret;
+
+return ret ? 0 : -1;
+}
+
+
+static int
+mymain(void)
+{
+int ret = 0;
+struct testDriverConnValidateData data;
+
+#define TEST_SUCCESS(name) \
+do  { \
+data.expectFailure = false; \
+if (virTestRun("Test conn URI path validate ok " name, \
+   testDriverConnValidate, ) < 0) \
+ret = -1; \
+} while (0)
+
+#define TEST_FAIL(name) \
+do  { \
+data.expectFailure = true; \
+if (virTestRun("Test conn URI path validate fail " name, \
+   testDriverConnValidate, ) < 0) \
+ret = -1; \
+} while (0)
+
+/* Validation should always succeed with privileged user
+ * and '/system' URI path
+ */
+data.uriPath = "/system";
+data.privileged = true;
+
+data.entityName = "interface";
+TEST_SUCCESS("interface privileged /system");
+
+data.entityName = "network";
+TEST_SUCCESS("network privileged /system");
+
+data.entityName = "nodedev";
+TEST_SUCCESS("nodedev privileged /system");
+
+data.entityName = "secret";
+TEST_SUCCESS("secret privileged /system");
+
+data.entityName = "storage";
+TEST_SUCCESS("storage privileged /system");
+
+data.entityName = "qemu";
+TEST_SUCCESS("qemu privileged /system");
+
+data.entityName = "vbox";
+TEST_SUCCESS("vbox privileged /system");
+
+/* Fail URI path validation for all '/system' path with
+ * unprivileged user
+ */
+data.privileged = false;
+
+data.entityName = "interface";
+TEST_FAIL("interface unprivileged /system");
+
+data.entityName = "network";
+TEST_FAIL("network unprivileged /system");
+
+data.entityName = "nodedev";
+TEST_FAIL("nodedev unprivileged /system");
+
+data.entityName = "secret";
+TEST_FAIL("secret unprivileged /system");
+
+data.entityName = "storage";
+TEST_FAIL("storage unprivileged /system");
+
+  

[libvirt] [PATCH v4 08/12] driver.c: change URI validation to handle QEMU and vbox case

2019-09-26 Thread Daniel Henrique Barboza
The existing QEMU and vbox URI path validation consider
that a privileged user can use both a "/system" and a
"/session" URI. This differs from all the other drivers
that forbids the root user to use "/session" URI.

Let's update virConnectValidateURIPath() to handle these
cases as exceptions, using the already existent 'entityName'
value to handle "QEMU" and "vbox" differently. This allows
us to use the validateURI function in these cases without
changing the existing behavior of other drivers.

Suggested-by: Cole Robinson 
Signed-off-by: Daniel Henrique Barboza 
---
 src/driver.c | 14 +-
 1 file changed, 13 insertions(+), 1 deletion(-)

diff --git a/src/driver.c b/src/driver.c
index 6b75622689..ed2d943ddf 100644
--- a/src/driver.c
+++ b/src/driver.c
@@ -276,7 +276,19 @@ virConnectValidateURIPath(const char *uriPath,
   bool privileged)
 {
 if (privileged) {
-if (STRNEQ(uriPath, "/system")) {
+/* TODO: qemu and vbox drivers allow '/session'
+ * connections as root. This is not ideal, but changing
+ * these drivers to refuse privileged '/session'
+ * connections, like everyone else is already doing, can
+ * break existing applications. Until we decide what to do,
+ * for now we can handle them as exception in this validate
+ * function.
+ */
+bool compatSessionRoot = (STREQ(entityName, "qemu") ||
+  STREQ(entityName, "vbox")) &&
+  STREQ(uriPath, "/session");
+
+if (STRNEQ(uriPath, "/system") && !compatSessionRoot) {
 virReportError(VIR_ERR_INTERNAL_ERROR,
_("unexpected %s URI path '%s', try "
  "%s:///system"),
-- 
2.21.0

--
libvir-list mailing list
libvir-list@redhat.com
https://www.redhat.com/mailman/listinfo/libvir-list


[libvirt] [PATCH v4 11/12] vbox_driver.c: use virConnectValidateURIPath()

2019-09-26 Thread Daniel Henrique Barboza
Suggested-by: Cole Robinson 
Signed-off-by: Daniel Henrique Barboza 
---
 src/vbox/vbox_driver.c | 16 ++--
 1 file changed, 2 insertions(+), 14 deletions(-)

diff --git a/src/vbox/vbox_driver.c b/src/vbox/vbox_driver.c
index 1f31fa28df..d7e80828ab 100644
--- a/src/vbox/vbox_driver.c
+++ b/src/vbox/vbox_driver.c
@@ -58,20 +58,8 @@ static virDrvOpenStatus dummyConnectOpen(virConnectPtr conn,
 
 virCheckFlags(VIR_CONNECT_RO, VIR_DRV_OPEN_ERROR);
 
-if (uid != 0) {
-if (STRNEQ(conn->uri->path, "/session")) {
-virReportError(VIR_ERR_INTERNAL_ERROR,
-   _("unknown driver path '%s' specified (try 
vbox:///session)"), conn->uri->path);
-return VIR_DRV_OPEN_ERROR;
-}
-} else { /* root */
-if (STRNEQ(conn->uri->path, "/system") &&
-STRNEQ(conn->uri->path, "/session")) {
-virReportError(VIR_ERR_INTERNAL_ERROR,
-   _("unknown driver path '%s' specified (try 
vbox:///system)"), conn->uri->path);
-return VIR_DRV_OPEN_ERROR;
-}
-}
+if (!virConnectValidateURIPath(conn->uri->path, "vbox", uid == 0))
+return VIR_DRV_OPEN_ERROR;
 
 virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
_("unable to initialize VirtualBox driver API"));
-- 
2.21.0

--
libvir-list mailing list
libvir-list@redhat.com
https://www.redhat.com/mailman/listinfo/libvir-list


[libvirt] [PATCH v4 04/12] bridge_driver.c: virConnectValidateURIPath()

2019-09-26 Thread Daniel Henrique Barboza
Suggested-by: Cole Robinson 
Signed-off-by: Daniel Henrique Barboza 
---
 src/network/bridge_driver.c | 19 ---
 1 file changed, 4 insertions(+), 15 deletions(-)

diff --git a/src/network/bridge_driver.c b/src/network/bridge_driver.c
index c54be96407..c617bbb58f 100644
--- a/src/network/bridge_driver.c
+++ b/src/network/bridge_driver.c
@@ -938,21 +938,10 @@ networkConnectOpen(virConnectPtr conn,
 return VIR_DRV_OPEN_ERROR;
 }
 
-if (network_driver->privileged) {
-if (STRNEQ(conn->uri->path, "/system")) {
-virReportError(VIR_ERR_INTERNAL_ERROR,
-   _("unexpected network URI path '%s', try 
network:///system"),
-   conn->uri->path);
-return VIR_DRV_OPEN_ERROR;
-}
-} else {
-if (STRNEQ(conn->uri->path, "/session")) {
-virReportError(VIR_ERR_INTERNAL_ERROR,
-   _("unexpected network URI path '%s', try 
network:///session"),
-   conn->uri->path);
-return VIR_DRV_OPEN_ERROR;
-}
-}
+if (!virConnectValidateURIPath(conn->uri->path,
+   "network",
+   network_driver->privileged))
+return VIR_DRV_OPEN_ERROR;
 
 if (virConnectOpenEnsureACL(conn) < 0)
 return VIR_DRV_OPEN_ERROR;
-- 
2.21.0

--
libvir-list mailing list
libvir-list@redhat.com
https://www.redhat.com/mailman/listinfo/libvir-list


[libvirt] [PATCH v4 10/12] vbox_common.c: use virConnectValidateURIPath()

2019-09-26 Thread Daniel Henrique Barboza
Suggested-by: Cole Robinson 
Signed-off-by: Daniel Henrique Barboza 
---
 src/vbox/vbox_common.c | 16 ++--
 1 file changed, 2 insertions(+), 14 deletions(-)

diff --git a/src/vbox/vbox_common.c b/src/vbox/vbox_common.c
index ddabcb80ca..d3b8fb625f 100644
--- a/src/vbox/vbox_common.c
+++ b/src/vbox/vbox_common.c
@@ -517,20 +517,8 @@ vboxConnectOpen(virConnectPtr conn,
 
 virCheckFlags(VIR_CONNECT_RO, VIR_DRV_OPEN_ERROR);
 
-if (uid != 0) {
-if (STRNEQ(conn->uri->path, "/session")) {
-virReportError(VIR_ERR_INTERNAL_ERROR,
-   _("unknown driver path '%s' specified (try 
vbox:///session)"), conn->uri->path);
-return VIR_DRV_OPEN_ERROR;
-}
-} else { /* root */
-if (STRNEQ(conn->uri->path, "/system") &&
-STRNEQ(conn->uri->path, "/session")) {
-virReportError(VIR_ERR_INTERNAL_ERROR,
-   _("unknown driver path '%s' specified (try 
vbox:///system)"), conn->uri->path);
-return VIR_DRV_OPEN_ERROR;
-}
-}
+if (!virConnectValidateURIPath(conn->uri->path, "vbox", uid == 0))
+return VIR_DRV_OPEN_ERROR;
 
 if (!(driver = vboxGetDriverConnection()))
 return VIR_DRV_OPEN_ERROR;
-- 
2.21.0

--
libvir-list mailing list
libvir-list@redhat.com
https://www.redhat.com/mailman/listinfo/libvir-list


Re: [libvirt] [PATCH] domain_conf: Unref video private data in virDomainVideoDefClear()

2019-09-26 Thread Erik Skultety
On Thu, Sep 26, 2019 at 05:01:24PM +0200, Michal Privoznik wrote:
> On 9/26/19 4:42 PM, Erik Skultety wrote:
> > On Thu, Sep 26, 2019 at 04:25:05PM +0200, Michal Privoznik wrote:
> > > The private data for video definition is created in
> > > virDomainVideoDefNew() and we attempt to free it in
> > > virDomainVideoDefFree(). This seems to work, except
> > > the free function calls clear function which zeroes
> > > out the whole structure and thus virObjectUnref()
> > > which is called on private data does nothing.
> > >
> > > 2,568 bytes in 107 blocks are definitely lost in loss record 207 of 213
> > > at 0x4A35476: calloc (vg_replace_malloc.c:752)
> > > by 0x50A6048: virAllocVar (viralloc.c:346)
> > > by 0x513CC5A: virObjectNew (virobject.c:243)
> > > by 0x4DC1DEE: qemuDomainVideoPrivateNew (qemu_domain.c:1337)
> > > by 0x51A6BD6: virDomainVideoDefNew (domain_conf.c:2831)
> > > by 0x51B9F06: virDomainVideoDefParseXML (domain_conf.c:15541)
> > > by 0x51CB761: virDomainDefParseXML (domain_conf.c:21158)
> > > by 0x51C5973: virDomainDefParseNode (domain_conf.c:21708)
> > > by 0x51C583A: virDomainDefParse (domain_conf.c:21663)
> > > by 0x51C58AE: virDomainDefParseFile (domain_conf.c:21688)
> >
> > Impressive that we haven't uncovered it sooner.
>
> That's okay, this was introduced only a few days ago in
> v5.7.0-212-g3dbf3941ad.

Ah, missed the fact that the series touched the object cleanup code as well.

Erik

--
libvir-list mailing list
libvir-list@redhat.com
https://www.redhat.com/mailman/listinfo/libvir-list


Re: [libvirt] [PATCH v3 02/22] build-aux: rewrite augest test generator in Python

2019-09-26 Thread Daniel P . Berrangé
On Thu, Sep 26, 2019 at 05:35:46PM +0200, Ján Tomko wrote:
> On Wed, Sep 25, 2019 at 03:17:10PM +0100, Daniel P. Berrangé wrote:
> > On Wed, Sep 25, 2019 at 03:25:39PM +0200, Ján Tomko wrote:
> > > On Tue, Sep 24, 2019 at 03:58:43PM +0100, Daniel P. Berrangé wrote:
> > > > As part of an goal to eliminate Perl from libvirt build tools,
> > > > rewrite the augeas-gentest.pl tool in Python.
> > > >
> > > > This was a straight conversion, manually going line-by-line to
> > > > change the syntax from Perl to Python. Thus the overall structure
> > > > of the file and approach is the same.
> > > >
> > > > The use of $(AUG_GENTEST) as a dependancy in the makefiles needed
> > > 
> > > s/dependancy/dependency/
> > > 
> > > > to be fixed, because this was assumed to be the filename of the
> > > > script, but is in fact a full shell command line.
> > > >
> > > 
> > > This is the case regardless of the Perl->Python conversion
> > > and can be done upfront to reduce the churn in this patch.
> > > Introduced by commit fb59cf7a5824b9c876737dcbf6aac97c29b1444a
> > > 
> > > > Signed-off-by: Daniel P. Berrangé 
> > > > ---
> > > > Makefile.am |  2 +-
> > > > build-aux/augeas-gentest.pl | 60 ---
> > > > build-aux/augeas-gentest.py | 72 +
> > > > src/Makefile.am |  3 +-
> > > > src/bhyve/Makefile.inc.am   |  4 +-
> > > > src/interface/Makefile.inc.am   |  2 +-
> > > > src/libxl/Makefile.inc.am   |  4 +-
> > > > src/locking/Makefile.inc.am |  6 +--
> > > > src/logging/Makefile.inc.am |  2 +-
> > > > src/lxc/Makefile.inc.am |  4 +-
> > > > src/network/Makefile.inc.am |  2 +-
> > > > src/node_device/Makefile.inc.am |  2 +-
> > > > src/nwfilter/Makefile.inc.am|  2 +-
> > > > src/qemu/Makefile.inc.am|  4 +-
> > > > src/remote/Makefile.inc.am  |  4 +-
> > > > src/secret/Makefile.inc.am  |  2 +-
> > > > src/storage/Makefile.inc.am |  2 +-
> > > > src/vbox/Makefile.inc.am|  2 +-
> > > > src/vz/Makefile.inc.am  |  2 +-
> > > > 19 files changed, 97 insertions(+), 84 deletions(-)
> > > > delete mode 100755 build-aux/augeas-gentest.pl
> > > > create mode 100755 build-aux/augeas-gentest.py
> > > 
> > > Since this is a new file with clean history, it might actually deserve
> > > a better location than build-aux and we can leave this directory to
> > > Automake and gnulib to do whatever magic they do there.
> > > Also note that the directory is in .gitignore. (I added the exception
> > > for .pl files back when I added files here)
> > > 
> > > Would 'scripts' be too vague? Could be a good place to put the helper
> > > scripts for generating QEMU caps files since I never seem to remember
> > > its name and tests/ is growing quite big.
> > 
> > That's a good question. As you see from this series, we've got random
> > scripts scattered all over the sub-dirs. build-aux/ was in some sense
> > to avoid polluting the top level dir.
> > 
> > If we create 'scripts/' should we put everything in there, or just
> > stuff that's related to the top level, and keep everything else in
> > their current subdirs ?
> 
> We put all the driver-specific tests into one tests/ directory, I think
> doing it for scripts makes sense too.

I'd really like the move all the tests into their respective driver
directories at some point :-)

We don't have an enourmous number of scripts though, so having them
all in one place is fine.

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 :|

--
libvir-list mailing list
libvir-list@redhat.com
https://www.redhat.com/mailman/listinfo/libvir-list

[libvirt] [PATCH v2 17/39] qemuMigrationSrcIsSafe: Rework slightly

2019-09-26 Thread Michal Privoznik
There are going to be more disk types that are considered unsafe
with respect to migration. Therefore, move the error reporting
call outside of if() body and rework if-else combo to switch().

Signed-off-by: Michal Privoznik 
---
 src/qemu/qemu_migration.c | 25 -
 1 file changed, 20 insertions(+), 5 deletions(-)

diff --git a/src/qemu/qemu_migration.c b/src/qemu/qemu_migration.c
index a98ec2d55a..693240ed3d 100644
--- a/src/qemu/qemu_migration.c
+++ b/src/qemu/qemu_migration.c
@@ -1239,6 +1239,8 @@ qemuMigrationSrcIsSafe(virDomainDefPtr def,
 for (i = 0; i < def->ndisks; i++) {
 virDomainDiskDefPtr disk = def->disks[i];
 const char *src = virDomainDiskGetSource(disk);
+int actualType = virStorageSourceGetActualType(disk->src);
+bool unsafe = false;
 
 /* Disks without any source (i.e. floppies and CD-ROMs)
  * OR readonly are safe. */
@@ -1252,21 +1254,34 @@ qemuMigrationSrcIsSafe(virDomainDefPtr def,
 continue;
 
 /* However, disks on local FS (e.g. ext4) are not safe. */
-if (virStorageSourceGetActualType(disk->src) == VIR_STORAGE_TYPE_FILE) 
{
+switch ((virStorageType) actualType) {
+case VIR_STORAGE_TYPE_FILE:
 if ((rc = virFileIsSharedFS(src)) < 0) {
 return false;
 } else if (rc == 0) {
-virReportError(VIR_ERR_MIGRATE_UNSAFE, "%s",
-   _("Migration without shared storage is 
unsafe"));
-return false;
+unsafe = true;
 }
 if ((rc = virStorageFileIsClusterFS(src)) < 0)
 return false;
 else if (rc == 1)
 continue;
-} else if (virStorageSourceGetActualType(disk->src) == 
VIR_STORAGE_TYPE_NETWORK) {
+break;
+case VIR_STORAGE_TYPE_NETWORK:
 /* But network disks are safe again. */
 continue;
+
+case VIR_STORAGE_TYPE_NONE:
+case VIR_STORAGE_TYPE_BLOCK:
+case VIR_STORAGE_TYPE_DIR:
+case VIR_STORAGE_TYPE_VOLUME:
+case VIR_STORAGE_TYPE_LAST:
+break;
+}
+
+if (unsafe) {
+virReportError(VIR_ERR_MIGRATE_UNSAFE, "%s",
+   _("Migration without shared storage is unsafe"));
+return false;
 }
 
 /* Our code elsewhere guarantees shared disks are either readonly (in
-- 
2.21.0

--
libvir-list mailing list
libvir-list@redhat.com
https://www.redhat.com/mailman/listinfo/libvir-list


[libvirt] [PATCH v2 18/39] schemas: Introduce disk type NVMe

2019-09-26 Thread Michal Privoznik
There is this class of PCI devices that act like disks: NVMe.
Therefore, they are both PCI devices and disks. While we already
have  (and can assign a NVMe device to a domain
successfully) we don't have disk representation. There are three
problems with PCI assignment in case of a NVMe device:

1) domains with  can't be migrated

2) NVMe device is assigned whole, there's no way to assign only a
   namespace

3) Because hypervisors see  they don't put block layer
   on top of it - users don't get all the fancy features like
   snapshots

NVMe namespaces are way of splitting one continuous NVDIMM memory
into smaller ones, effectively creating smaller NVMe-s (which can
then be partitioned, LVMed, etc.)

Because of all of this the following XML was chosen to model a
NVMe device:

  


  


  

Signed-off-by: Michal Privoznik 
---
 docs/formatdomain.html.in| 57 +++--
 docs/schemas/domaincommon.rng| 32 ++
 tests/qemuxml2argvdata/disk-nvme.xml | 63 
 3 files changed, 149 insertions(+), 3 deletions(-)
 create mode 100644 tests/qemuxml2argvdata/disk-nvme.xml

diff --git a/docs/formatdomain.html.in b/docs/formatdomain.html.in
index 93991aa3d1..ad116ff509 100644
--- a/docs/formatdomain.html.in
+++ b/docs/formatdomain.html.in
@@ -2934,6 +2934,13 @@
 /backingStore
 target dev='vdd' bus='virtio'/
   /disk
+  disk type='nvme' device='disk'
+driver name='qemu' type='raw'/
+source type='pci' managed='yes' namespace='1'
+  address domain='0x' bus='0x01' slot='0x00' function='0x0'/
+/source
+target dev='vde' bus='virtio'/
+  /disk
 /devices
 ...
 
@@ -2947,7 +2954,8 @@
 Valid values are "file", "block",
 "dir" (since 0.7.5),
 "network" (since 0.8.7), or
-"volume" (since 1.0.5)
+"volume" (since 1.0.5), or
+"nvme" (since 5.6.0)
 and refer to the underlying source for the disk.
 Since 0.0.3
 
@@ -3130,6 +3138,43 @@
   Since 1.0.5
   
   
+nvme
+  
+  To specify disk source for NVMe disk the source
+  element has the following attributes:
+  
+type
+The type of address specified in address
+sub-element. Currently, only pci value is
+accepted.
+
+
+managed
+This attribute instructs libvirt to detach NVMe
+controller automatically on domain startup (yes)
+or expect the controller to be detached by system
+administrator (no).
+
+
+namespace
+The namespace ID which should be assigned to the domain.
+According to NVMe standard, namespace numbers start from 1,
+including.
+
+  
+
+  The difference between disk type='nvme'
+  and hostdev/ is that the latter is plain
+  host device assignment with all its limitations (e.g. no live
+  migration), while the former makes hypervisor to run the NVMe
+  disk through hypervisor's block layer thus enabling all
+  features provided by the layer (e.g. snapshots, domain
+  migration, etc.). Moreover, since the NVMe disk is unbinded
+  from its PCI driver, the host kernel storage stack is not
+  involved (compared to passing say /dev/nvme0n1 via
+  disk type='block' and therefore lower
+  latencies can be achieved.
+  
   
 With "file", "block", and "volume", one or more optional
 sub-elements seclabel, described
@@ -3292,11 +3337,17 @@
 initiator IQN needed to access the source via mandatory
 attribute name.
   
+  address
+  For disk of type nvme this element
+specifies the PCI address of the host NVMe
+controller.
+Since 5.6.0
+  
 
 
 
-For a "file" or "volume" disk type which represents a cdrom or floppy
-(the device attribute), it is possible to define
+For a "file" or "volume" disk type which represents a cdrom or
+floppy (the device attribute), it is possible to define
 policy what to do with the disk if the source file is not accessible.
 (NB, startupPolicy is not valid for "volume" disk unless
  the specified storage volume is of "file" type). This is done by the
diff --git a/docs/schemas/domaincommon.rng b/docs/schemas/domaincommon.rng
index 40eb4a2d75..4871a4c4d4 100644
--- a/docs/schemas/domaincommon.rng
+++ b/docs/schemas/domaincommon.rng
@@ -1603,6 +1603,7 @@
   
   
   
+  
 
   
 
@@ -1918,6 +1919,37 @@
 
   
 
+  
+
+  nvme
+

[libvirt] [PATCH v2 15/39] virHostdevReAttachPCIDevices: Separate out function body

2019-09-26 Thread Michal Privoznik
In near future we will have a list of PCI devices we want to
re-attach to the host (held in virPCIDeviceListPtr) but we don't
have virDomainHostdevDefPtr. That's okay because
virHostdevReAttachPCIDevices() works with virPCIDeviceListPtr
mostly anyway. And in very few places where it needs
virDomainHostdevDefPtr are not interesting for our case.

Signed-off-by: Michal Privoznik 
ACKed-by: Peter Krempa 
---
 src/util/virhostdev.c | 58 +++
 1 file changed, 37 insertions(+), 21 deletions(-)

diff --git a/src/util/virhostdev.c b/src/util/virhostdev.c
index d2c881bddf..f0c97ca887 100644
--- a/src/util/virhostdev.c
+++ b/src/util/virhostdev.c
@@ -1007,30 +1007,17 @@ virHostdevPreparePCIDevices(virHostdevManagerPtr mgr,
 }
 
 
-/* @oldStateDir:
- * For upgrade purpose: see virHostdevRestoreNetConfig
- */
-void
-virHostdevReAttachPCIDevices(virHostdevManagerPtr mgr,
- const char *drv_name,
- const char *dom_name,
- virDomainHostdevDefPtr *hostdevs,
- int nhostdevs,
- const char *oldStateDir)
+static void
+virHostdevReAttachPCIDevicesImpl(virHostdevManagerPtr mgr,
+ const char *drv_name,
+ const char *dom_name,
+ virPCIDeviceListPtr pcidevs,
+ virDomainHostdevDefPtr *hostdevs,
+ int nhostdevs,
+ const char *oldStateDir)
 {
-VIR_AUTOUNREF(virPCIDeviceListPtr) pcidevs = NULL;
 size_t i;
 
-if (!nhostdevs)
-return;
-
-if (!(pcidevs = virHostdevGetPCIHostDeviceList(hostdevs, nhostdevs))) {
-VIR_ERROR(_("Failed to allocate PCI device list: %s"),
-  virGetLastErrorMessage());
-virResetLastError();
-return;
-}
-
 virObjectLock(mgr->activePCIHostdevs);
 virObjectLock(mgr->inactivePCIHostdevs);
 
@@ -1126,6 +1113,35 @@ virHostdevReAttachPCIDevices(virHostdevManagerPtr mgr,
 virObjectUnlock(mgr->inactivePCIHostdevs);
 }
 
+
+/* @oldStateDir:
+ * For upgrade purpose: see virHostdevRestoreNetConfig
+ */
+void
+virHostdevReAttachPCIDevices(virHostdevManagerPtr mgr,
+ const char *drv_name,
+ const char *dom_name,
+ virDomainHostdevDefPtr *hostdevs,
+ int nhostdevs,
+ const char *oldStateDir)
+{
+VIR_AUTOUNREF(virPCIDeviceListPtr) pcidevs = NULL;
+
+if (!nhostdevs)
+return;
+
+if (!(pcidevs = virHostdevGetPCIHostDeviceList(hostdevs, nhostdevs))) {
+VIR_ERROR(_("Failed to allocate PCI device list: %s"),
+  virGetLastErrorMessage());
+virResetLastError();
+return;
+}
+
+virHostdevReAttachPCIDevicesImpl(mgr, drv_name, dom_name, pcidevs,
+ hostdevs, nhostdevs, oldStateDir);
+}
+
+
 int
 virHostdevUpdateActivePCIDevices(virHostdevManagerPtr mgr,
  virDomainHostdevDefPtr *hostdevs,
-- 
2.21.0

--
libvir-list mailing list
libvir-list@redhat.com
https://www.redhat.com/mailman/listinfo/libvir-list


[libvirt] [PATCH v2 37/39] qemu: Allow forcing VFIO when computing memlock limit

2019-09-26 Thread Michal Privoznik
With NVMe disks, one can start a blockjob with a NVMe disk
that is not visible in domain XML (at least right away). Usually,
it's fairly easy to override this limitation of
qemuDomainGetMemLockLimitBytes() - for instance for hostdevs we
temporarily add the device to domain def, let the function
calculate the limit and then remove the device. But it's not so
easy with virStorageSourcePtr - in some cases they don't
necessarily are attached to a disk. And even if they are it's
done later in the process and frankly, I find it too complicated
to be able to use the simple trick we use with hostdevs.

Signed-off-by: Michal Privoznik 
---
 src/qemu/qemu_command.c |  2 +-
 src/qemu/qemu_domain.c  | 46 ++---
 src/qemu/qemu_domain.h  |  6 --
 src/qemu/qemu_hotplug.c | 12 +--
 tests/qemumemlocktest.c |  2 +-
 5 files changed, 41 insertions(+), 27 deletions(-)

diff --git a/src/qemu/qemu_command.c b/src/qemu/qemu_command.c
index ad6c1e7e8a..fa2394378a 100644
--- a/src/qemu/qemu_command.c
+++ b/src/qemu/qemu_command.c
@@ -10511,7 +10511,7 @@ qemuBuildCommandLine(virQEMUDriverPtr driver,
 
 /* In some situations, eg. VFIO passthrough, QEMU might need to lock a
  * significant amount of memory, so we need to set the limit accordingly */
-virCommandSetMaxMemLock(cmd, qemuDomainGetMemLockLimitBytes(def));
+virCommandSetMaxMemLock(cmd, qemuDomainGetMemLockLimitBytes(def, false));
 
 if (virQEMUCapsGet(qemuCaps, QEMU_CAPS_MSG_TIMESTAMP) &&
 cfg->logTimestamp)
diff --git a/src/qemu/qemu_domain.c b/src/qemu/qemu_domain.c
index e4e9d4e361..3fe0004cab 100644
--- a/src/qemu/qemu_domain.c
+++ b/src/qemu/qemu_domain.c
@@ -11843,12 +11843,14 @@ ppc64VFIODeviceIsNV2Bridge(const char *device)
 /**
  * getPPC64MemLockLimitBytes:
  * @def: domain definition
+ * @forceVFIO: force VFIO usage
  *
  * A PPC64 helper that calculates the memory locking limit in order for
  * the guest to operate properly.
  */
 static unsigned long long
-getPPC64MemLockLimitBytes(virDomainDefPtr def)
+getPPC64MemLockLimitBytes(virDomainDefPtr def,
+  bool forceVFIO)
 {
 unsigned long long memKB = 0;
 unsigned long long baseLimit = 0;
@@ -11939,7 +11941,7 @@ getPPC64MemLockLimitBytes(virDomainDefPtr def)
 passthroughLimit = maxMemory +
128 * (1ULL<<30) / 512 * nPCIHostBridges +
8192;
-} else if (usesVFIO) {
+} else if (usesVFIO || forceVFIO) {
 /* For regular (non-NVLink2 present) VFIO passthrough, the value
  * of passthroughLimit is:
  *
@@ -11977,16 +11979,20 @@ getPPC64MemLockLimitBytes(virDomainDefPtr def)
 /**
  * qemuDomainGetMemLockLimitBytes:
  * @def: domain definition
+ * @forceVFIO: force VFIO calculation
  *
  * Calculate the memory locking limit that needs to be set in order for
  * the guest to operate properly. The limit depends on a number of factors,
  * including certain configuration options and less immediately apparent ones
  * such as the guest architecture or the use of certain devices.
+ * The @forceVFIO argument can be used to tell this function will use VFIO even
+ * though @def doesn't indicates so right now.
  *
  * Returns: the memory locking limit, or 0 if setting the limit is not needed
  */
 unsigned long long
-qemuDomainGetMemLockLimitBytes(virDomainDefPtr def)
+qemuDomainGetMemLockLimitBytes(virDomainDefPtr def,
+   bool forceVFIO)
 {
 unsigned long long memKB = 0;
 bool usesVFIO = false;
@@ -12007,7 +12013,7 @@ qemuDomainGetMemLockLimitBytes(virDomainDefPtr def)
 return VIR_DOMAIN_MEMORY_PARAM_UNLIMITED;
 
 if (ARCH_IS_PPC64(def->os.arch) && def->virtType == VIR_DOMAIN_VIRT_KVM)
-return getPPC64MemLockLimitBytes(def);
+return getPPC64MemLockLimitBytes(def, forceVFIO);
 
 /* For device passthrough using VFIO the guest memory and MMIO memory
  * regions need to be locked persistent in order to allow DMA.
@@ -12027,18 +12033,20 @@ qemuDomainGetMemLockLimitBytes(virDomainDefPtr def)
  *
  * Note that this may not be valid for all platforms.
  */
-for (i = 0; i < def->nhostdevs; i++) {
-if (virHostdevIsVFIODevice(def->hostdevs[i]) ||
-virHostdevIsMdevDevice(def->hostdevs[i])) {
-usesVFIO = true;
-break;
+if (!forceVFIO) {
+for (i = 0; i < def->nhostdevs; i++) {
+if (virHostdevIsVFIODevice(def->hostdevs[i]) ||
+virHostdevIsMdevDevice(def->hostdevs[i])) {
+usesVFIO = true;
+break;
+}
 }
+
+if (virDomainDefHasNVMeDisk(def))
+usesVFIO = true;
 }
 
-if (virDomainDefHasNVMeDisk(def))
-usesVFIO = true;
-
-if (usesVFIO)
+if (usesVFIO || forceVFIO)
 memKB = virDomainDefGetMemoryTotal(def) + 1024 * 1024;
 
  done:
@@ -12049,9 +12057,12 @@ 

[libvirt] [PATCH v2 25/39] virhostdevtest: Test virNVMeDevice assignment

2019-09-26 Thread Michal Privoznik
Signed-off-by: Michal Privoznik 
ACKed-by: Peter Krempa 
---
 tests/virhostdevtest.c | 97 ++
 1 file changed, 97 insertions(+)

diff --git a/tests/virhostdevtest.c b/tests/virhostdevtest.c
index 46627355c3..fde7f92bc4 100644
--- a/tests/virhostdevtest.c
+++ b/tests/virhostdevtest.c
@@ -48,6 +48,9 @@ VIR_LOG_INIT("tests.hostdevtest");
 # define CHECK_PCI_LIST_COUNT(list, cnt) \
 CHECK_LIST_COUNT(list, cnt, virPCIDeviceListCount)
 
+# define CHECK_NVME_LIST_COUNT(list, cnt) \
+CHECK_LIST_COUNT(list, cnt, virNVMeDeviceListCount)
+
 # define TEST_STATE_DIR abs_builddir "/hostdevmgr"
 static const char *drv_name = "test_driver";
 static const char *dom_name = "test_domain";
@@ -57,6 +60,36 @@ static int nhostdevs = 3;
 static virDomainHostdevDefPtr hostdevs[] = {NULL, NULL, NULL};
 static virPCIDevicePtr dev[] = {NULL, NULL, NULL};
 static virHostdevManagerPtr mgr;
+static const size_t ndisks = 3;
+static virDomainDiskDefPtr disks[] = {NULL, NULL, NULL};
+static const char *diskXML[] = {
+""
+"  "
+"  "
+""
+"  "
+"  "
+"  "
+"",
+
+""
+"  "
+"  "
+""
+"  "
+"  "
+"  "
+"",
+
+""
+"  "
+"  "
+""
+"  "
+"  "
+"  "
+""
+};
 
 static void
 myCleanup(void)
@@ -67,6 +100,9 @@ myCleanup(void)
  virDomainHostdevDefFree(hostdevs[i]);
 }
 
+for (i = 0; i < ndisks; i++)
+virDomainDiskDefFree(disks[i]);
+
 if (mgr) {
 if (!getenv("LIBVIRT_SKIP_CLEANUP"))
 virFileDeleteTree(mgr->stateDir);
@@ -75,6 +111,7 @@ myCleanup(void)
 virObjectUnref(mgr->activeUSBHostdevs);
 virObjectUnref(mgr->inactivePCIHostdevs);
 virObjectUnref(mgr->activeSCSIHostdevs);
+virObjectUnref(mgr->activeNVMeHostdevs);
 VIR_FREE(mgr->stateDir);
 VIR_FREE(mgr);
 }
@@ -107,6 +144,11 @@ myInit(void)
 virPCIDeviceSetStubDriver(dev[i], VIR_PCI_STUB_DRIVER_VFIO);
 }
 
+for (i = 0; i < ndisks; i++) {
+if (!(disks[i] = virDomainDiskDefParse(diskXML[i], NULL, NULL, 0)))
+goto cleanup;
+}
+
 if (VIR_ALLOC(mgr) < 0)
 goto cleanup;
 if ((mgr->activePCIHostdevs = virPCIDeviceListNew()) == NULL)
@@ -117,6 +159,8 @@ myInit(void)
 goto cleanup;
 if ((mgr->activeSCSIHostdevs = virSCSIDeviceListNew()) == NULL)
 goto cleanup;
+if ((mgr->activeNVMeHostdevs = virNVMeDeviceListNew()) == NULL)
+goto cleanup;
 if (VIR_STRDUP(mgr->stateDir, TEST_STATE_DIR) < 0)
 goto cleanup;
 if (virFileMakePath(mgr->stateDir) < 0)
@@ -493,6 +537,58 @@ testVirHostdevOther(const void *opaque ATTRIBUTE_UNUSED)
 return 0;
 }
 
+static int
+testNVMeDiskRoundtrip(const void *opaque ATTRIBUTE_UNUSED)
+{
+int ret = -1;
+
+/* Don't rely on a state that previous test cases might have
+ * left the manager in. Start with a clean slate. */
+virHostdevReAttachPCIDevices(mgr, drv_name, dom_name,
+ hostdevs, nhostdevs, NULL);
+
+CHECK_NVME_LIST_COUNT(mgr->activeNVMeHostdevs, 0);
+CHECK_PCI_LIST_COUNT(mgr->activePCIHostdevs, 0);
+CHECK_PCI_LIST_COUNT(mgr->inactivePCIHostdevs, 0);
+
+/* Firstly, attach all NVMe disks */
+if (virHostdevPrepareNVMeDevices(mgr, drv_name, dom_name, disks, ndisks) < 
0)
+goto cleanup;
+
+CHECK_NVME_LIST_COUNT(mgr->activeNVMeHostdevs, 3);
+CHECK_PCI_LIST_COUNT(mgr->activePCIHostdevs, 2);
+CHECK_PCI_LIST_COUNT(mgr->inactivePCIHostdevs, 0);
+
+/* Now, try to detach the first one. */
+if (virHostdevReAttachNVMeDevices(mgr, drv_name, dom_name, disks, 1) < 0)
+goto cleanup;
+
+CHECK_NVME_LIST_COUNT(mgr->activeNVMeHostdevs, 2);
+CHECK_PCI_LIST_COUNT(mgr->activePCIHostdevs, 2);
+CHECK_PCI_LIST_COUNT(mgr->inactivePCIHostdevs, 0);
+
+/* And the last one */
+if (virHostdevReAttachNVMeDevices(mgr, drv_name, dom_name, [2], 1) < 
0)
+goto cleanup;
+
+CHECK_NVME_LIST_COUNT(mgr->activeNVMeHostdevs, 1);
+CHECK_PCI_LIST_COUNT(mgr->activePCIHostdevs, 1);
+CHECK_PCI_LIST_COUNT(mgr->inactivePCIHostdevs, 0);
+
+/* Finally, detach the middle one */
+if (virHostdevReAttachNVMeDevices(mgr, drv_name, dom_name, [1], 1) < 
0)
+goto cleanup;
+
+CHECK_NVME_LIST_COUNT(mgr->activeNVMeHostdevs, 0);
+CHECK_PCI_LIST_COUNT(mgr->activePCIHostdevs, 0);
+CHECK_PCI_LIST_COUNT(mgr->inactivePCIHostdevs, 0);
+
+ret = 0;
+ cleanup:
+return ret;
+}
+
+
 # define FAKEROOTDIRTEMPLATE abs_builddir "/fakerootdir-XX"
 
 static int
@@ -530,6 +626,7 @@ mymain(void)
 DO_TEST(testVirHostdevRoundtripManaged);
 DO_TEST(testVirHostdevRoundtripMixed);
 DO_TEST(testVirHostdevOther);
+DO_TEST(testNVMeDiskRoundtrip);
 
 myCleanup();
 
-- 
2.21.0

--
libvir-list mailing list
libvir-list@redhat.com
https://www.redhat.com/mailman/listinfo/libvir-list


[libvirt] [PATCH v2 21/39] domain_conf: Introduce virDomainDefHasNVMeDisk

2019-09-26 Thread Michal Privoznik
This function will return true if any of disks (or their backing
chain) for given domain contains an NVMe disk.

Signed-off-by: Michal Privoznik 
ACKed-by: Peter Krempa 
---
 src/conf/domain_conf.c   | 14 ++
 src/conf/domain_conf.h   |  3 +++
 src/libvirt_private.syms |  1 +
 3 files changed, 18 insertions(+)

diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c
index fe540c195e..98ee1f4058 100644
--- a/src/conf/domain_conf.c
+++ b/src/conf/domain_conf.c
@@ -31640,6 +31640,20 @@ virDomainDefHasManagedPR(const virDomainDef *def)
 }
 
 
+bool
+virDomainDefHasNVMeDisk(const virDomainDef *def)
+{
+size_t i;
+
+for (i = 0; i < def->ndisks; i++) {
+if (virStorageSourceChainHasNVMe(def->disks[i]->src))
+return true;
+}
+
+return false;
+}
+
+
 bool
 virDomainDefHasVFIOHostdev(const virDomainDef *def)
 {
diff --git a/src/conf/domain_conf.h b/src/conf/domain_conf.h
index bf5d1a154b..ada2c70a8b 100644
--- a/src/conf/domain_conf.h
+++ b/src/conf/domain_conf.h
@@ -3666,6 +3666,9 @@ virDomainDiskGetDetectZeroesMode(virDomainDiskDiscard 
discard,
 bool
 virDomainDefHasManagedPR(const virDomainDef *def);
 
+bool
+virDomainDefHasNVMeDisk(const virDomainDef *def);
+
 bool
 virDomainDefHasVFIOHostdev(const virDomainDef *def);
 
diff --git a/src/libvirt_private.syms b/src/libvirt_private.syms
index 4e2a74a31b..d383dbe929 100644
--- a/src/libvirt_private.syms
+++ b/src/libvirt_private.syms
@@ -297,6 +297,7 @@ virDomainDefHasManagedPR;
 virDomainDefHasMdevHostdev;
 virDomainDefHasMemballoon;
 virDomainDefHasMemoryHotplug;
+virDomainDefHasNVMeDisk;
 virDomainDefHasUSB;
 virDomainDefHasVcpusOffline;
 virDomainDefHasVFIOHostdev;
-- 
2.21.0

--
libvir-list mailing list
libvir-list@redhat.com
https://www.redhat.com/mailman/listinfo/libvir-list


Re: [libvirt] [PATCH] conf: utility function to update entry in def->nets array

2019-09-26 Thread Laine Stump

On 9/26/19 11:51 AM, Laine Stump wrote:

On 9/26/19 3:28 AM, Michal Privoznik wrote:

On 9/25/19 6:57 PM, Laine Stump wrote:


diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c
index 0753904472..5f63c4f51e 100644
--- a/src/qemu/qemu_driver.c
+++ b/src/qemu/qemu_driver.c
@@ -8786,8 +8786,10 @@ qemuDomainUpdateDeviceConfig(virDomainDefPtr 
vmdef,

   false) < 0)
  return -1;
  -    virDomainNetDefFree(vmdef->nets[pos]);
-    vmdef->nets[pos] = net;
+    if (virDomainNetUpdate(vmdef, pos, net))
+    return -1;
+
+    virDomainNetDefFree(oldDev.data.net);
  dev->data.net = NULL;
  break;



The same code pattern occurrs in lxcDomainUpdateDeviceConfig() so you 
may want to fix it the same way as you're doing here.



Sure. I try to keep changes in sync for all the hypervisors that 
support any particular operation, but sometimes I'm too focused on 
eliminating my specific problem and forget.



... although to be fair, lxc doesn't support  
(or  at all, which is what's 
implied by ).



Still, it doesn't harm anything to use the common function (which 
reduces to just replacing the nets entry


--
libvir-list mailing list
libvir-list@redhat.com
https://www.redhat.com/mailman/listinfo/libvir-list

Re: [libvirt] [PATCH v2 2/7] conf: Drop pointless 'domain' argument from virDomainCheckpointRedefinePrep

2019-09-26 Thread Ján Tomko

On Wed, Sep 25, 2019 at 02:54:38PM +0200, Peter Krempa wrote:

'vm' is passed in which contains the definition which contains the UUID
so we don't need another parameter for this.

Signed-off-by: Peter Krempa 
---
src/conf/checkpoint_conf.c | 7 +++
src/conf/checkpoint_conf.h | 3 +--
src/qemu/qemu_driver.c | 2 +-
src/test/test_driver.c | 2 +-
4 files changed, 6 insertions(+), 8 deletions(-)



Reviewed-by: Ján Tomko 

Jano


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

[libvirt] [PATCH v2 34/39] qemu: Generate command line of NVMe disks

2019-09-26 Thread Michal Privoznik
Now, that we have everything prepared, we can generate command
line for NVMe disks.

Signed-off-by: Michal Privoznik 
---
 src/qemu/qemu_block.c | 25 -
 src/qemu/qemu_command.c   |  3 ++
 src/qemu/qemu_process.c   |  7 +++
 .../disk-nvme.x86_64-latest.args  | 53 +++
 tests/qemuxml2argvtest.c  |  1 +
 5 files changed, 88 insertions(+), 1 deletion(-)
 create mode 100644 tests/qemuxml2argvdata/disk-nvme.x86_64-latest.args

diff --git a/src/qemu/qemu_block.c b/src/qemu/qemu_block.c
index 99b2a4efaa..311f42e52f 100644
--- a/src/qemu/qemu_block.c
+++ b/src/qemu/qemu_block.c
@@ -994,6 +994,25 @@ qemuBlockStorageSourceGetVvfatProps(virStorageSourcePtr 
src,
 }
 
 
+static virJSONValuePtr
+qemuBlockStorageSourceGetNVMeProps(virStorageSourcePtr src)
+{
+const virStorageSourceNVMeDef *nvme = src->nvme;
+VIR_AUTOFREE(char *) pciAddr = NULL;
+virJSONValuePtr ret = NULL;
+
+if (!(pciAddr = virPCIDeviceAddressAsString(>pciAddr)))
+return NULL;
+
+ignore_value(virJSONValueObjectCreate(,
+  "s:driver", "nvme",
+  "s:device", pciAddr,
+  "U:namespace", nvme->namespace,
+  NULL));
+return ret;
+}
+
+
 static int
 qemuBlockStorageSourceGetBlockdevGetCacheProps(virStorageSourcePtr src,
virJSONValuePtr props)
@@ -1076,8 +1095,12 @@ 
qemuBlockStorageSourceGetBackendProps(virStorageSourcePtr src,
 return NULL;
 break;
 
-case VIR_STORAGE_TYPE_VOLUME:
 case VIR_STORAGE_TYPE_NVME:
+if (!(fileprops = qemuBlockStorageSourceGetNVMeProps(src)))
+return NULL;
+break;
+
+case VIR_STORAGE_TYPE_VOLUME:
 case VIR_STORAGE_TYPE_NONE:
 case VIR_STORAGE_TYPE_LAST:
 return NULL;
diff --git a/src/qemu/qemu_command.c b/src/qemu/qemu_command.c
index b2519465ba..ad6c1e7e8a 100644
--- a/src/qemu/qemu_command.c
+++ b/src/qemu/qemu_command.c
@@ -1548,6 +1548,9 @@ qemuDiskSourceNeedsProps(virStorageSourcePtr src,
 src->haveTLS == VIR_TRISTATE_BOOL_YES)
 return true;
 
+if (actualType == VIR_STORAGE_TYPE_NVME)
+return true;
+
 return false;
 }
 
diff --git a/src/qemu/qemu_process.c b/src/qemu/qemu_process.c
index a50cd54393..f20561c07b 100644
--- a/src/qemu/qemu_process.c
+++ b/src/qemu/qemu_process.c
@@ -5390,6 +5390,13 @@ qemuProcessStartValidateDisks(virDomainObjPtr vm,
_("PowerPC pseries machines do not support floppy 
device"));
 return -1;
 }
+
+if (src->type == VIR_STORAGE_TYPE_NVME &&
+!virQEMUCapsGet(qemuCaps, QEMU_CAPS_DRIVE_NVME)) {
+virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
+   _("NVMe disks are not supported with this QEMU 
binary"));
+return -1;
+}
 }
 
 return 0;
diff --git a/tests/qemuxml2argvdata/disk-nvme.x86_64-latest.args 
b/tests/qemuxml2argvdata/disk-nvme.x86_64-latest.args
new file mode 100644
index 00..b0f640b751
--- /dev/null
+++ b/tests/qemuxml2argvdata/disk-nvme.x86_64-latest.args
@@ -0,0 +1,53 @@
+LC_ALL=C \
+PATH=/bin \
+HOME=/tmp/lib/domain--1-QEMUGuest1 \
+USER=test \
+LOGNAME=test \
+XDG_DATA_HOME=/tmp/lib/domain--1-QEMUGuest1/.local/share \
+XDG_CACHE_HOME=/tmp/lib/domain--1-QEMUGuest1/.cache \
+XDG_CONFIG_HOME=/tmp/lib/domain--1-QEMUGuest1/.config \
+QEMU_AUDIO_DRV=none \
+/usr/bin/qemu-system-i686 \
+-name guest=QEMUGuest1,debug-threads=on \
+-S \
+-object secret,id=masterKey0,format=raw,\
+file=/tmp/lib/domain--1-QEMUGuest1/master-key.aes \
+-machine pc,accel=tcg,usb=off,dump-guest-core=off \
+-m 214 \
+-overcommit mem-lock=off \
+-smp 1,sockets=1,cores=1,threads=1 \
+-uuid c7a5fdbd-edaf-9455-926a-d65c16db1809 \
+-display none \
+-no-user-config \
+-nodefaults \
+-chardev socket,id=charmonitor,fd=1729,server,nowait \
+-mon chardev=charmonitor,id=monitor,mode=control \
+-rtc base=utc \
+-no-shutdown \
+-no-acpi \
+-boot strict=on \
+-device piix3-usb-uhci,id=usb,bus=pci.0,addr=0x1.0x2 \
+-device virtio-scsi-pci,id=scsi0,bus=pci.0,addr=0x3 \
+-drive file.driver=nvme,file.device=:01:00.0,file.namespace=1,format=raw,\
+if=none,id=drive-virtio-disk0 \
+-device virtio-blk-pci,scsi=off,bus=pci.0,addr=0x4,drive=drive-virtio-disk0,\
+id=virtio-disk0,bootindex=1 \
+-drive file.driver=nvme,file.device=:01:00.0,file.namespace=2,format=raw,\
+if=none,id=drive-virtio-disk1 \
+-device virtio-blk-pci,scsi=off,bus=pci.0,addr=0x5,drive=drive-virtio-disk1,\
+id=virtio-disk1 \
+-drive file.driver=nvme,file.device=:02:00.0,file.namespace=1,format=raw,\
+if=none,id=drive-virtio-disk2 \
+-device virtio-blk-pci,scsi=off,bus=pci.0,addr=0x6,drive=drive-virtio-disk2,\
+id=virtio-disk2 \
+-object 

[libvirt] [PATCH v2 39/39] virsh: Introduce nvme disk to domblklist

2019-09-26 Thread Michal Privoznik
This is slightly more complicated because NVMe disk source is not
a simple attribute to  element. The format in which the
PCI address and namespace ID are printed is the same as QEMU
accepts them:

  nvme://:XX:XX.X/X

Signed-off-by: Michal Privoznik 
---
 tools/virsh-domain-monitor.c | 31 +--
 1 file changed, 25 insertions(+), 6 deletions(-)

diff --git a/tools/virsh-domain-monitor.c b/tools/virsh-domain-monitor.c
index 0e2c4191d7..f663a87f8f 100644
--- a/tools/virsh-domain-monitor.c
+++ b/tools/virsh-domain-monitor.c
@@ -627,8 +627,8 @@ cmdDomblklist(vshControl *ctl, const vshCmd *cmd)
 for (i = 0; i < ndisks; i++) {
 ctxt->node = disks[i];
 
+type = virXPathString("string(./@type)", ctxt);
 if (details) {
-type = virXPathString("string(./@type)", ctxt);
 device = virXPathString("string(./@device)", ctxt);
 if (!type || !device) {
 vshPrint(ctl, "unable to query block list details");
@@ -641,11 +641,30 @@ cmdDomblklist(vshControl *ctl, const vshCmd *cmd)
 vshError(ctl, "unable to query block list");
 goto cleanup;
 }
-source = virXPathString("string(./source/@file"
-"|./source/@dev"
-"|./source/@dir"
-"|./source/@name"
-"|./source/@volume)", ctxt);
+
+if (STREQ_NULLABLE(type, "nvme")) {
+VIR_AUTOFREE(char *) namespace = NULL;
+virPCIDeviceAddress addr = { 0 };
+xmlNodePtr addrNode = NULL;
+
+if (!(namespace = virXPathString("string(./source/@namespace)", 
ctxt)) ||
+!(addrNode = virXPathNode("./source/address", ctxt)) ||
+virPCIDeviceAddressParseXML(addrNode, ) < 0) {
+vshError(ctl, "Unable to query NVMe disk address");
+goto cleanup;
+}
+
+if (virAsprintf(, "nvme://%04x:%02x:%02x.%d/%s",
+addr.domain, addr.bus, addr.slot, addr.function, 
namespace) < 0)
+goto cleanup;
+} else {
+source = virXPathString("string(./source/@file"
+"|./source/@dev"
+"|./source/@dir"
+"|./source/@name"
+"|./source/@volume)", ctxt);
+}
+
 if (details) {
 if (vshTableRowAppend(table, type, device, target,
   NULLSTR_MINUS(source), NULL) < 0)
-- 
2.21.0

--
libvir-list mailing list
libvir-list@redhat.com
https://www.redhat.com/mailman/listinfo/libvir-list


Re: [libvirt] [PATCH 3/6] qemu_driver: use VIR_AUTOUNREF() with virQEMUDriverConfigPtr 3/3

2019-09-26 Thread Daniel Henrique Barboza




On 9/26/19 6:18 AM, Erik Skultety wrote:

On Wed, Sep 18, 2019 at 11:56:55AM -0300, Daniel Henrique Barboza wrote:

virQEMUDriverConfigPtr can be auto-unref for the great majority
of the uses made in qemu_driver, sparing us a virObjectUnref()
call and sometimes a whole 'cleanup' label.

This patch changes virQEMUDriverConfigPtr declarations to
use VIR_AUTOUNREF(). 'cleanup' labels were deleted when
applicable.

This is the last part of this change. All but one* instance of
virQEMUDriverConfigPtr were changed to use VIR_AUTOUNREF().
'cleanup' labels were deleted when applicable.

* qemuStateInitialize: we can't auto-unref the pointer since we're
initializing the qemu_driver object with it.

Signed-off-by: Daniel Henrique Barboza 
---

I know you focused on virQEMUDriverConfigPtr primarily, but since you're
following up with VIR_AUTOFREE and touching qemu_driver only, I'd like to do a
better job and use VIR_AUTOUNREF at many more places across the file for:

virCapsPtr caps
virConnectPtr conn
qemuDomainSaveCookiePtr cookie
virQEMUCapsPtr qemuCaps
qemuBlockJobDataPtr job
virDomainCapsPtr domCaps
virNetworkPtr network


No problem. Should I squash the first 3 patches of this series into a single
one that will touch only virQEMUDriverConfigPtr and then make one patch
for each pointer type that's changed?


Thanks,


DHB





(there may be a few more...)

Erik


--
libvir-list mailing list
libvir-list@redhat.com
https://www.redhat.com/mailman/listinfo/libvir-list


Re: [libvirt] [PATCH] domain_conf: Unref video private data in virDomainVideoDefClear()

2019-09-26 Thread Erik Skultety
On Thu, Sep 26, 2019 at 04:25:05PM +0200, Michal Privoznik wrote:
> The private data for video definition is created in
> virDomainVideoDefNew() and we attempt to free it in
> virDomainVideoDefFree(). This seems to work, except
> the free function calls clear function which zeroes
> out the whole structure and thus virObjectUnref()
> which is called on private data does nothing.
>
> 2,568 bytes in 107 blocks are definitely lost in loss record 207 of 213
>at 0x4A35476: calloc (vg_replace_malloc.c:752)
>by 0x50A6048: virAllocVar (viralloc.c:346)
>by 0x513CC5A: virObjectNew (virobject.c:243)
>by 0x4DC1DEE: qemuDomainVideoPrivateNew (qemu_domain.c:1337)
>by 0x51A6BD6: virDomainVideoDefNew (domain_conf.c:2831)
>by 0x51B9F06: virDomainVideoDefParseXML (domain_conf.c:15541)
>by 0x51CB761: virDomainDefParseXML (domain_conf.c:21158)
>by 0x51C5973: virDomainDefParseNode (domain_conf.c:21708)
>by 0x51C583A: virDomainDefParse (domain_conf.c:21663)
>by 0x51C58AE: virDomainDefParseFile (domain_conf.c:21688)

Impressive that we haven't uncovered it sooner.

>
> Signed-off-by: Michal Privoznik 
> ---

Reviewed-by: Erik Skultety 

--
libvir-list mailing list
libvir-list@redhat.com
https://www.redhat.com/mailman/listinfo/libvir-list


[libvirt] [PATCH v4 01/12] src/driver.c: add virConnectValidateURIPath()

2019-09-26 Thread Daniel Henrique Barboza
The code to validate the URI path is repeated across several
files. This patch creates a common validation code to be
used across all of them.

Suggested-by: Cole Robinson 
Signed-off-by: Daniel Henrique Barboza 
---
 src/driver.c | 26 ++
 src/driver.h |  4 
 src/libvirt_private.syms |  1 +
 3 files changed, 31 insertions(+)

diff --git a/src/driver.c b/src/driver.c
index 5e8f68f6df..6b75622689 100644
--- a/src/driver.c
+++ b/src/driver.c
@@ -269,3 +269,29 @@ virSetConnectStorage(virConnectPtr conn)
 VIR_DEBUG("Override storage connection with %p", conn);
 return virThreadLocalSet(, conn);
 }
+
+bool
+virConnectValidateURIPath(const char *uriPath,
+  const char *entityName,
+  bool privileged)
+{
+if (privileged) {
+if (STRNEQ(uriPath, "/system")) {
+virReportError(VIR_ERR_INTERNAL_ERROR,
+   _("unexpected %s URI path '%s', try "
+ "%s:///system"),
+   entityName, uriPath, entityName);
+return false;
+}
+} else {
+if (STRNEQ(uriPath, "/session")) {
+virReportError(VIR_ERR_INTERNAL_ERROR,
+   _("unexpected %s URI path '%s', try "
+ "%s:///session"),
+   entityName, uriPath, entityName);
+return false;
+}
+}
+
+return true;
+}
diff --git a/src/driver.h b/src/driver.h
index f7d667a03c..68c0004d86 100644
--- a/src/driver.h
+++ b/src/driver.h
@@ -127,3 +127,7 @@ int virSetConnectNWFilter(virConnectPtr conn);
 int virSetConnectNodeDev(virConnectPtr conn);
 int virSetConnectSecret(virConnectPtr conn);
 int virSetConnectStorage(virConnectPtr conn);
+
+bool virConnectValidateURIPath(const char *uriPath,
+   const char *entityName,
+   bool privileged);
diff --git a/src/libvirt_private.syms b/src/libvirt_private.syms
index 287e63bffa..3668a531a4 100644
--- a/src/libvirt_private.syms
+++ b/src/libvirt_private.syms
@@ -1343,6 +1343,7 @@ virStreamClass;
 
 
 # driver.h
+virConnectValidateURIPath;
 virGetConnectInterface;
 virGetConnectNetwork;
 virGetConnectNodeDev;
-- 
2.21.0

--
libvir-list mailing list
libvir-list@redhat.com
https://www.redhat.com/mailman/listinfo/libvir-list


[libvirt] [PATCH v4 03/12] interface_backend_udev.c: use virConnectValidateURIPath()

2019-09-26 Thread Daniel Henrique Barboza
Suggested-by: Cole Robinson 
Signed-off-by: Daniel Henrique Barboza 
---
 src/interface/interface_backend_udev.c | 19 ---
 1 file changed, 4 insertions(+), 15 deletions(-)

diff --git a/src/interface/interface_backend_udev.c 
b/src/interface/interface_backend_udev.c
index ddc3de5347..1684b8ed83 100644
--- a/src/interface/interface_backend_udev.c
+++ b/src/interface/interface_backend_udev.c
@@ -1250,21 +1250,10 @@ udevConnectOpen(virConnectPtr conn,
 return VIR_DRV_OPEN_ERROR;
 }
 
-if (driver->privileged) {
-if (STRNEQ(conn->uri->path, "/system")) {
-virReportError(VIR_ERR_INTERNAL_ERROR,
-   _("unexpected interface URI path '%s', try 
interface:///system"),
-   conn->uri->path);
-return VIR_DRV_OPEN_ERROR;
-}
-} else {
-if (STRNEQ(conn->uri->path, "/session")) {
-virReportError(VIR_ERR_INTERNAL_ERROR,
-   _("unexpected interface URI path '%s', try 
interface:///session"),
-   conn->uri->path);
-return VIR_DRV_OPEN_ERROR;
-}
-}
+if (!virConnectValidateURIPath(conn->uri->path,
+   "interface",
+   driver->privileged))
+return VIR_DRV_OPEN_ERROR;
 
 if (virConnectOpenEnsureACL(conn) < 0)
 return VIR_DRV_OPEN_ERROR;
-- 
2.21.0

--
libvir-list mailing list
libvir-list@redhat.com
https://www.redhat.com/mailman/listinfo/libvir-list


[libvirt] [PATCH v4 02/12] interface_backend_netcf.c: use virConnectValidateURIPath()

2019-09-26 Thread Daniel Henrique Barboza
Suggested-by: Cole Robinson 
Signed-off-by: Daniel Henrique Barboza 
---
 src/interface/interface_backend_netcf.c | 19 ---
 1 file changed, 4 insertions(+), 15 deletions(-)

diff --git a/src/interface/interface_backend_netcf.c 
b/src/interface/interface_backend_netcf.c
index 9659e9fcf1..5ef8ac33db 100644
--- a/src/interface/interface_backend_netcf.c
+++ b/src/interface/interface_backend_netcf.c
@@ -200,21 +200,10 @@ netcfConnectOpen(virConnectPtr conn,
 return VIR_DRV_OPEN_ERROR;
 }
 
-if (driver->privileged) {
-if (STRNEQ(conn->uri->path, "/system")) {
-virReportError(VIR_ERR_INTERNAL_ERROR,
-   _("unexpected interface URI path '%s', try 
interface:///system"),
-   conn->uri->path);
-return VIR_DRV_OPEN_ERROR;
-}
-} else {
-if (STRNEQ(conn->uri->path, "/session")) {
-virReportError(VIR_ERR_INTERNAL_ERROR,
-   _("unexpected interface URI path '%s', try 
interface:///session"),
-   conn->uri->path);
-return VIR_DRV_OPEN_ERROR;
-}
-}
+if (!virConnectValidateURIPath(conn->uri->path,
+   "interface",
+   driver->privileged))
+return VIR_DRV_OPEN_ERROR;
 
 if (virConnectOpenEnsureACL(conn) < 0)
 return VIR_DRV_OPEN_ERROR;
-- 
2.21.0

--
libvir-list mailing list
libvir-list@redhat.com
https://www.redhat.com/mailman/listinfo/libvir-list


[libvirt] [PATCH v4 00/12] remove repetition of URI path validation

2019-09-26 Thread Daniel Henrique Barboza
This is a code repetition that I crossed a few times, then
I noticed that Cole Robinson suggested a solution for it
in the wiki. Here it is.


changes from v3:
- patch 8: fix the exception logic, move the code formatting
to patch 1
- patch 9: use lowcase 'qemu'
- patch 12: (optional) test case I created to aid in patch 8
logic

changes from v2:
- use a boolean to determine 'QEMU' and 'vbox' case to avoid block
repetition (patch 8)
- avoid 80+ chars lines in all patches

changes from v1:
- handle QEMU and vbox cases separately inside the validation
function

v3: https://www.redhat.com/archives/libvir-list/2019-September/msg01122.html
v2: https://www.redhat.com/archives/libvir-list/2019-September/msg01007.html
v1: https://www.redhat.com/archives/libvir-list/2019-September/msg00983.html

Daniel Henrique Barboza (12):
  src/driver.c: add virConnectValidateURIPath()
  interface_backend_netcf.c: use virConnectValidateURIPath()
  interface_backend_udev.c: use virConnectValidateURIPath()
  bridge_driver.c: virConnectValidateURIPath()
  node_device_driver.c: use virConnectValidateURIPath()
  secret_driver.c: use virConnectValidateURIPath()
  storage_driver.c: use virConnectValidateURIPath()
  driver.c: change URI validation to handle QEMU and vbox case
  qemu_driver.c: use virConnectValidateURIPath()
  vbox_common.c: use virConnectValidateURIPath()
  vbox_driver.c: use virConnectValidateURIPath()
  tests: add a test for driver.c:virConnectValidateURIPath()

 src/driver.c|  38 +
 src/driver.h|   4 +
 src/interface/interface_backend_netcf.c |  19 +--
 src/interface/interface_backend_udev.c  |  19 +--
 src/libvirt_private.syms|   1 +
 src/network/bridge_driver.c |  19 +--
 src/node_device/node_device_driver.c|  19 +--
 src/qemu/qemu_driver.c  |  20 +--
 src/secret/secret_driver.c  |  19 +--
 src/storage/storage_driver.c|  19 +--
 src/vbox/vbox_common.c  |  16 +-
 src/vbox/vbox_driver.c  |  16 +-
 tests/Makefile.am   |   7 +-
 tests/virdriverconnvalidatetest.c   | 186 
 14 files changed, 267 insertions(+), 135 deletions(-)
 create mode 100644 tests/virdriverconnvalidatetest.c

-- 
2.21.0

--
libvir-list mailing list
libvir-list@redhat.com
https://www.redhat.com/mailman/listinfo/libvir-list


[libvirt] [PATCH v4 09/12] qemu_driver.c: use virConnectValidateURIPath()

2019-09-26 Thread Daniel Henrique Barboza
Suggested-by: Cole Robinson 
Signed-off-by: Daniel Henrique Barboza 
---
 src/qemu/qemu_driver.c | 20 
 1 file changed, 4 insertions(+), 16 deletions(-)

diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c
index 0c65414a1a..cf9c06f274 100644
--- a/src/qemu/qemu_driver.c
+++ b/src/qemu/qemu_driver.c
@@ -1295,22 +1295,10 @@ static virDrvOpenStatus qemuConnectOpen(virConnectPtr 
conn,
 return VIR_DRV_OPEN_ERROR;
 }
 
-if (virQEMUDriverIsPrivileged(qemu_driver)) {
-if (STRNEQ(conn->uri->path, "/system") &&
-STRNEQ(conn->uri->path, "/session")) {
-virReportError(VIR_ERR_INTERNAL_ERROR,
-   _("unexpected QEMU URI path '%s', try 
qemu:///system"),
-   conn->uri->path);
-return VIR_DRV_OPEN_ERROR;
-}
-} else {
-if (STRNEQ(conn->uri->path, "/session")) {
-virReportError(VIR_ERR_INTERNAL_ERROR,
-   _("unexpected QEMU URI path '%s', try 
qemu:///session"),
-   conn->uri->path);
-return VIR_DRV_OPEN_ERROR;
-}
-}
+if (!virConnectValidateURIPath(conn->uri->path,
+   "qemu",
+   virQEMUDriverIsPrivileged(qemu_driver)))
+return VIR_DRV_OPEN_ERROR;
 
 if (virConnectOpenEnsureACL(conn) < 0)
 return VIR_DRV_OPEN_ERROR;
-- 
2.21.0

--
libvir-list mailing list
libvir-list@redhat.com
https://www.redhat.com/mailman/listinfo/libvir-list


[libvirt] [PATCH v4 06/12] secret_driver.c: use virConnectValidateURIPath()

2019-09-26 Thread Daniel Henrique Barboza
Suggested-by: Cole Robinson 
Signed-off-by: Daniel Henrique Barboza 
---
 src/secret/secret_driver.c | 19 ---
 1 file changed, 4 insertions(+), 15 deletions(-)

diff --git a/src/secret/secret_driver.c b/src/secret/secret_driver.c
index 7512a51c74..ed3bd3c751 100644
--- a/src/secret/secret_driver.c
+++ b/src/secret/secret_driver.c
@@ -552,21 +552,10 @@ secretConnectOpen(virConnectPtr conn,
 return VIR_DRV_OPEN_ERROR;
 }
 
-if (driver->privileged) {
-if (STRNEQ(conn->uri->path, "/system")) {
-virReportError(VIR_ERR_INTERNAL_ERROR,
-   _("unexpected secret URI path '%s', try 
secret:///system"),
-   conn->uri->path);
-return VIR_DRV_OPEN_ERROR;
-}
-} else {
-if (STRNEQ(conn->uri->path, "/session")) {
-virReportError(VIR_ERR_INTERNAL_ERROR,
-   _("unexpected secret URI path '%s', try 
secret:///session"),
-   conn->uri->path);
-return VIR_DRV_OPEN_ERROR;
-}
-}
+if (!virConnectValidateURIPath(conn->uri->path,
+   "secret",
+   driver->privileged))
+return VIR_DRV_OPEN_ERROR;
 
 if (virConnectOpenEnsureACL(conn) < 0)
 return VIR_DRV_OPEN_ERROR;
-- 
2.21.0

--
libvir-list mailing list
libvir-list@redhat.com
https://www.redhat.com/mailman/listinfo/libvir-list


Re: [libvirt] [PATCH] domain_conf: Unref video private data in virDomainVideoDefClear()

2019-09-26 Thread Michal Privoznik

On 9/26/19 4:42 PM, Erik Skultety wrote:

On Thu, Sep 26, 2019 at 04:25:05PM +0200, Michal Privoznik wrote:

The private data for video definition is created in
virDomainVideoDefNew() and we attempt to free it in
virDomainVideoDefFree(). This seems to work, except
the free function calls clear function which zeroes
out the whole structure and thus virObjectUnref()
which is called on private data does nothing.

2,568 bytes in 107 blocks are definitely lost in loss record 207 of 213
at 0x4A35476: calloc (vg_replace_malloc.c:752)
by 0x50A6048: virAllocVar (viralloc.c:346)
by 0x513CC5A: virObjectNew (virobject.c:243)
by 0x4DC1DEE: qemuDomainVideoPrivateNew (qemu_domain.c:1337)
by 0x51A6BD6: virDomainVideoDefNew (domain_conf.c:2831)
by 0x51B9F06: virDomainVideoDefParseXML (domain_conf.c:15541)
by 0x51CB761: virDomainDefParseXML (domain_conf.c:21158)
by 0x51C5973: virDomainDefParseNode (domain_conf.c:21708)
by 0x51C583A: virDomainDefParse (domain_conf.c:21663)
by 0x51C58AE: virDomainDefParseFile (domain_conf.c:21688)


Impressive that we haven't uncovered it sooner.


That's okay, this was introduced only a few days ago in 
v5.7.0-212-g3dbf3941ad.






Signed-off-by: Michal Privoznik 
---


Reviewed-by: Erik Skultety 



Thanks, pushed now.

Michal

--
libvir-list mailing list
libvir-list@redhat.com
https://www.redhat.com/mailman/listinfo/libvir-list


Re: [libvirt] [PATCH v2 4/7] qemu: driver: Remove misplaced qemuDomainObjEndJob in qemuDomainCheckpointGetXMLDesc

2019-09-26 Thread Eric Blake

On 9/25/19 7:54 AM, Peter Krempa wrote:

The code that gets the job to refresh disk sizes was not merged yet so
remove this artifact.

Signed-off-by: Peter Krempa 
---
  src/qemu/qemu_driver.c | 3 ---
  1 file changed, 3 deletions(-)


Reviewed-by: Eric Blake 



diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c
index ca25814bd1..7da6dbce66 100644
--- a/src/qemu/qemu_driver.c
+++ b/src/qemu/qemu_driver.c
@@ -17535,9 +17535,6 @@ qemuDomainCheckpointGetXMLDesc(virDomainCheckpointPtr 
checkpoint,
  xml = virDomainCheckpointDefFormat(chkdef, driver->caps, driver->xmlopt,
 format_flags);

-if (flags & VIR_DOMAIN_CHECKPOINT_XML_SIZE)
-qemuDomainObjEndJob(driver, vm);
-
   cleanup:
  virDomainObjEndAPI();
  return xml;



--
Eric Blake, Principal Software Engineer
Red Hat, Inc.   +1-919-301-3226
Virtualization:  qemu.org | libvirt.org

--
libvir-list mailing list
libvir-list@redhat.com
https://www.redhat.com/mailman/listinfo/libvir-list


Re: [libvirt] [PATCH v2 5/7] qemu: driver: Move checkpoint-related code to qemu_checkpoint.c

2019-09-26 Thread Peter Krempa
On Thu, Sep 26, 2019 at 10:38:11 -0500, Eric Blake wrote:
> On 9/25/19 7:54 AM, Peter Krempa wrote:
> > Move all extensive functions to a new file so that we don't just pile
> > everything in the common files. This obviously isn't possible with
> > straight code movement as we still need stubs in qemu_driver.c
> > 
> > Additionally some functions e.g. for looking up a checkpoint by name
> > were so short that moving the impl didn't make sense.
> > 
> > Note that in the move the new file also doesn't use
> > virQEMUMomentReparent but rather an stripped down copy. As I plan to
> 
> s/an/a/
> 
> > split out snapshot code into a separate file the unification doesn't
> > make sense any more.
> > 
> > Signed-off-by: Peter Krempa 
> > ---
> >   src/qemu/Makefile.inc.am   |   2 +
> >   src/qemu/qemu_checkpoint.c | 483 +
> >   src/qemu/qemu_checkpoint.h |  50 
> >   src/qemu/qemu_driver.c | 382 +
> >   4 files changed, 540 insertions(+), 377 deletions(-)
> >   create mode 100644 src/qemu/qemu_checkpoint.c
> >   create mode 100644 src/qemu/qemu_checkpoint.h
> > 
> 
> With the double-free fix you posted in the followup,
> 
> 
> > +++ b/src/qemu/Makefile.inc.am
> > @@ -68,6 +68,8 @@ QEMU_DRIVER_SOURCES = \
> > qemu/qemu_vhost_user.h \
> > qemu/qemu_vhost_user_gpu.c \
> > qemu/qemu_vhost_user_gpu.h \
> > +   qemu/qemu_checkpoint.c \
> > +   qemu/qemu_checkpoint.h \
> > $(NULL)
> 
> Is it worth keeping this list sorted alphabetically?
> 
> > +/* Called inside job lock */
> > +static int
> > +qemuDomainCheckpointPrepare(virQEMUDriverPtr driver, virCapsPtr caps,
> 
> Worth splitting these parameters to separate lines?  (I know you're just
> moving code, and it's my fault they weren't split in my commit...)
> 
> > +virDomainObjPtr vm,
> > +virDomainCheckpointDefPtr def)
> > +{
> 
> 
> > +
> > +struct virQEMUCheckpointReparent {
> > +const char *dir;
> > +virDomainMomentObjPtr parent;
> > +virDomainObjPtr vm;
> > +virCapsPtr caps;
> > +virDomainXMLOptionPtr xmlopt;
> > +int err;
> > +};
> > +
> > +
> > +static int
> > +qemuCheckpointReparentChildren(void *payload,
> > +   const void *name ATTRIBUTE_UNUSED,
> > +   void *data)
> > +{
> > +virDomainMomentObjPtr moment = payload;
> > +struct virQEMUCheckpointReparent  *rep = data;
> 
> There's a double space here we could fix.
> 
> > +int
> > +qemuCheckpointDelete(virDomainObjPtr vm,
> > + virDomainCheckpointPtr checkpoint,
> > + unsigned int flags)
> > +{
> > +qemuDomainObjPrivatePtr priv = vm->privateData;
> > +virQEMUDriverPtr driver = priv->driver;
> > +VIR_AUTOUNREF(virQEMUDriverConfigPtr) cfg = 
> > virQEMUDriverGetConfig(driver);
> > +int ret = -1;
> > +virDomainMomentObjPtr chk = NULL;
> > +virQEMUMomentRemove rem;
> > +struct virQEMUCheckpointReparent rep;
> 
> You explained why you unshared virQEMUMomentReparent, but why not instead
> move it to be alongside virQEMUMomentRemove, which is still shared?  Yes, I
> know it's odd that we had two callback structs, split between two different
> files declaring those structs, but rather than duplicating things for
> snapshot vs. checkpoint, keeping the two shared structs side-by-side might
> make more sense.

I plan also to split everything snapshot related out so I thought of
getting completely rid of the code sharing here since it's not
significant.


> 
> > +++ b/src/qemu/qemu_driver.c
> 
> >   static virDomainCheckpointPtr
> >   qemuDomainCheckpointCreateXML(virDomainPtr domain,
> > const char *xmlDesc,
> > unsigned int flags)
> >   {
> > -virQEMUDriverPtr driver = domain->conn->privateData;
> >   virDomainObjPtr vm = NULL;
> 
> > 
> >   if (!(vm = qemuDomainObjFromDomain(domain)))
> >   goto cleanup;
> > 
> > -if (virDomainSnapshotObjListNum(vm->snapshots, NULL, 0) > 0) {
> > -virReportError(VIR_ERR_OPERATION_UNSUPPORTED, "%s",
> > -   _("cannot create checkpoint while snapshot 
> > exists"));
> > -goto cleanup;
> > -}
> > -
> > -priv = vm->privateData;
> > -cfg = virQEMUDriverGetConfig(driver);
> > -
> >   if (virDomainCheckpointCreateXMLEnsureACL(domain->conn, vm->def, 
> > flags) < 0)
> >   goto cleanup;
> 
> Didn't you need to fix this separately, for security reasons?

Oops, I didn't notice this one. I'll post it separately probably just to
have a commit to reference.

--
libvir-list mailing list
libvir-list@redhat.com
https://www.redhat.com/mailman/listinfo/libvir-list


[libvirt] [PATCH v2 20/39] virstoragefile: Introduce virStorageSourceChainHasNVMe

2019-09-26 Thread Michal Privoznik
This function will return true if there's a storage source of
type VIR_STORAGE_TYPE_NVME, or false otherwise.

Signed-off-by: Michal Privoznik 
ACKed-by: Peter Krempa 
---
 src/libvirt_private.syms  |  1 +
 src/util/virstoragefile.c | 14 ++
 src/util/virstoragefile.h |  2 ++
 3 files changed, 17 insertions(+)

diff --git a/src/libvirt_private.syms b/src/libvirt_private.syms
index 91b03afb17..4e2a74a31b 100644
--- a/src/libvirt_private.syms
+++ b/src/libvirt_private.syms
@@ -3024,6 +3024,7 @@ virStoragePRDefIsManaged;
 virStoragePRDefParseXML;
 virStorageSourceBackingStoreClear;
 virStorageSourceChainHasManagedPR;
+virStorageSourceChainHasNVMe;
 virStorageSourceClear;
 virStorageSourceCopy;
 virStorageSourceFindByNodeName;
diff --git a/src/util/virstoragefile.c b/src/util/virstoragefile.c
index 725d68a248..093d2403de 100644
--- a/src/util/virstoragefile.c
+++ b/src/util/virstoragefile.c
@@ -2161,6 +2161,20 @@ virStorageSourceNVMeDefFree(virStorageSourceNVMeDefPtr 
def)
 }
 
 
+bool
+virStorageSourceChainHasNVMe(const virStorageSource *src)
+{
+const virStorageSource *n;
+
+for (n = src; virStorageSourceIsBacking(n); n = n->backingStore) {
+if (n->type == VIR_STORAGE_TYPE_NVME)
+return true;
+}
+
+return false;
+}
+
+
 virSecurityDeviceLabelDefPtr
 virStorageSourceGetSecurityLabelDef(virStorageSourcePtr src,
 const char *model)
diff --git a/src/util/virstoragefile.h b/src/util/virstoragefile.h
index 9e79c7c6ef..306f84b383 100644
--- a/src/util/virstoragefile.h
+++ b/src/util/virstoragefile.h
@@ -433,6 +433,8 @@ virStorageSourceChainHasManagedPR(virStorageSourcePtr src);
 void virStorageSourceNVMeDefFree(virStorageSourceNVMeDefPtr def);
 VIR_DEFINE_AUTOPTR_FUNC(virStorageSourceNVMeDef, virStorageSourceNVMeDefFree);
 
+bool virStorageSourceChainHasNVMe(const virStorageSource *src);
+
 virSecurityDeviceLabelDefPtr
 virStorageSourceGetSecurityLabelDef(virStorageSourcePtr src,
 const char *model);
-- 
2.21.0

--
libvir-list mailing list
libvir-list@redhat.com
https://www.redhat.com/mailman/listinfo/libvir-list


[libvirt] [PATCH v2 22/39] util: Introduce virNVMeDevice module

2019-09-26 Thread Michal Privoznik
This module will be used by virHostdevManager and it's inspired
by virPCIDevice module. They are very similar except instead of
what makes a NVMe device: PCI address AND namespace ID. This
means that a NVMe device can appear in a domain multiple times,
each time with a different namespace.

Signed-off-by: Michal Privoznik 
---
 src/libvirt_private.syms |  18 ++
 src/util/Makefile.inc.am |   2 +
 src/util/virnvme.c   | 454 +++
 src/util/virnvme.h   |  95 
 4 files changed, 569 insertions(+)
 create mode 100644 src/util/virnvme.c
 create mode 100644 src/util/virnvme.h

diff --git a/src/libvirt_private.syms b/src/libvirt_private.syms
index d383dbe929..0c84b347db 100644
--- a/src/libvirt_private.syms
+++ b/src/libvirt_private.syms
@@ -2629,6 +2629,24 @@ virNumaSetPagePoolSize;
 virNumaSetupMemoryPolicy;
 
 
+# util/virnvme.h
+virNVMeDeviceAddressGet;
+virNVMeDeviceCopy;
+virNVMeDeviceFree;
+virNVMeDeviceListAdd;
+virNVMeDeviceListCount;
+virNVMeDeviceListCreateDetachList;
+virNVMeDeviceListDel;
+virNVMeDeviceListGet;
+virNVMeDeviceListLookup;
+virNVMeDeviceListLookupIndex;
+virNVMeDeviceListNew;
+virNVMeDeviceNew;
+virNVMeDeviceUsedByClear;
+virNVMeDeviceUsedByGet;
+virNVMeDeviceUsedBySet;
+
+
 # util/virobject.h
 virClassForObject;
 virClassForObjectLockable;
diff --git a/src/util/Makefile.inc.am b/src/util/Makefile.inc.am
index 482b657a90..7e677b891c 100644
--- a/src/util/Makefile.inc.am
+++ b/src/util/Makefile.inc.am
@@ -145,6 +145,8 @@ UTIL_SOURCES = \
util/virnetlink.h \
util/virnodesuspend.c \
util/virnodesuspend.h \
+   util/virnvme.c \
+   util/virnvme.h \
util/virkmod.c \
util/virkmod.h \
util/virnuma.c \
diff --git a/src/util/virnvme.c b/src/util/virnvme.c
new file mode 100644
index 00..f52955c615
--- /dev/null
+++ b/src/util/virnvme.c
@@ -0,0 +1,454 @@
+/*
+ * virnvme.c: helper APIs for managing NVMe devices
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library.  If not, see
+ * .
+ */
+
+#include 
+
+#include "virnvme.h"
+#include "virobject.h"
+#include "virpci.h"
+#include "viralloc.h"
+#include "virlog.h"
+#include "virstring.h"
+
+VIR_LOG_INIT("util.nvme");
+#define VIR_FROM_THIS VIR_FROM_NONE
+
+struct _virNVMeDevice {
+virPCIDeviceAddress address; /* PCI address of controller */
+unsigned int namespace; /* Namespace ID */
+bool managed;
+
+char *drvname;
+char *domname;
+};
+
+
+struct _virNVMeDeviceList {
+virObjectLockable parent;
+
+size_t count;
+virNVMeDevicePtr *devs;
+};
+
+
+static virClassPtr virNVMeDeviceListClass;
+
+static void virNVMeDeviceListDispose(void *obj);
+
+static int
+virNVMeOnceInit(void)
+{
+if (!VIR_CLASS_NEW(virNVMeDeviceList, virClassForObjectLockable()))
+return -1;
+
+return 0;
+}
+
+VIR_ONCE_GLOBAL_INIT(virNVMe);
+
+
+virNVMeDevicePtr
+virNVMeDeviceNew(const virPCIDeviceAddress *address,
+ unsigned long namespace,
+ bool managed)
+{
+VIR_AUTOPTR(virNVMeDevice) dev = NULL;
+
+if (VIR_ALLOC(dev) < 0)
+return NULL;
+
+virPCIDeviceAddressCopy(>address, address);
+dev->namespace = namespace;
+dev->managed = managed;
+
+VIR_RETURN_PTR(dev);
+}
+
+
+void
+virNVMeDeviceFree(virNVMeDevicePtr dev)
+{
+if (!dev)
+return;
+
+virNVMeDeviceUsedByClear(dev);
+VIR_FREE(dev);
+}
+
+
+virNVMeDevicePtr
+virNVMeDeviceCopy(const virNVMeDevice *dev)
+{
+VIR_AUTOPTR(virNVMeDevice) copy = NULL;
+
+if (VIR_ALLOC(copy) < 0 ||
+VIR_STRDUP(copy->drvname, dev->drvname) < 0 ||
+VIR_STRDUP(copy->domname, dev->domname) < 0)
+return NULL;
+
+virPCIDeviceAddressCopy(>address, >address);
+copy->namespace = dev->namespace;
+copy->managed = dev->managed;
+
+VIR_RETURN_PTR(copy);
+}
+
+
+const virPCIDeviceAddress *
+virNVMeDeviceAddressGet(const virNVMeDevice *dev)
+{
+return >address;
+}
+
+
+void
+virNVMeDeviceUsedByClear(virNVMeDevicePtr dev)
+{
+VIR_FREE(dev->drvname);
+VIR_FREE(dev->domname);
+}
+
+
+void
+virNVMeDeviceUsedByGet(const virNVMeDevice *dev,
+   const char **drv,
+   const char **dom)
+{
+*drv = dev->drvname;
+*dom = dev->domname;
+}
+
+
+int
+virNVMeDeviceUsedBySet(virNVMeDevicePtr dev,
+   const char *drv,

[libvirt] [PATCH v2 19/39] conf: Format and parse NVMe type disk

2019-09-26 Thread Michal Privoznik
To simplify implementation, some restrictions are added. For
instance, an NVMe disk can't go to any bus but virtio and has to
be type of 'disk' and can't have startupPolicy set.

Signed-off-by: Michal Privoznik 
---
 src/conf/domain_conf.c | 96 ++
 src/libvirt_private.syms   |  1 +
 src/libxl/xen_xl.c |  1 +
 src/qemu/qemu_block.c  |  2 +
 src/qemu/qemu_command.c|  1 +
 src/qemu/qemu_driver.c |  4 ++
 src/qemu/qemu_migration.c  |  5 ++
 src/util/virstoragefile.c  | 59 
 src/util/virstoragefile.h  | 17 +
 tests/qemuxml2xmloutdata/disk-nvme.xml |  1 +
 tests/qemuxml2xmltest.c|  1 +
 11 files changed, 188 insertions(+)
 create mode 12 tests/qemuxml2xmloutdata/disk-nvme.xml

diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c
index c1769f743b..fe540c195e 100644
--- a/src/conf/domain_conf.c
+++ b/src/conf/domain_conf.c
@@ -5118,6 +5118,11 @@ virDomainDiskDefPostParse(virDomainDiskDefPtr disk,
 return -1;
 }
 
+if (disk->src->type == VIR_STORAGE_TYPE_NVME) {
+if (disk->src->nvme->managed == VIR_TRISTATE_BOOL_ABSENT)
+disk->src->nvme->managed = VIR_TRISTATE_BOOL_YES;
+}
+
 if (disk->info.type == VIR_DOMAIN_DEVICE_ADDRESS_TYPE_NONE &&
 virDomainDiskDefAssignAddress(xmlopt, disk, def) < 0) {
 return -1;
@@ -9251,6 +9256,76 @@ virDomainDiskSourceNetworkParse(xmlNodePtr node,
 }
 
 
+static int
+virDomainDiskSourceNVMeParse(xmlNodePtr node,
+ xmlXPathContextPtr ctxt,
+ virStorageSourcePtr src)
+{
+VIR_AUTOPTR(virStorageSourceNVMeDef) nvme = NULL;
+VIR_AUTOFREE(char *) type = NULL;
+VIR_AUTOFREE(char *) namespace = NULL;
+VIR_AUTOFREE(char *) managed = NULL;
+xmlNodePtr address;
+
+if (VIR_ALLOC(nvme) < 0)
+return -1;
+
+if (!(type = virXMLPropString(node, "type"))) {
+virReportError(VIR_ERR_XML_ERROR, "%s",
+   _("missing 'type' attribute to disk source"));
+return -1;
+}
+
+if (STRNEQ(type, "pci")) {
+virReportError(VIR_ERR_XML_ERROR,
+   _("unsupported source type '%s'"),
+   type);
+return -1;
+}
+
+if (!(namespace = virXMLPropString(node, "namespace"))) {
+virReportError(VIR_ERR_XML_ERROR, "%s",
+   _("missing 'namespace' attribute to disk source"));
+return -1;
+}
+
+if (virStrToLong_ull(namespace, NULL, 10, >namespace) < 0) {
+virReportError(VIR_ERR_XML_ERROR,
+   _("malformed namespace '%s'"),
+   namespace);
+return -1;
+}
+
+/* NVMe namespaces start from 1 */
+if (nvme->namespace == 0) {
+virReportError(VIR_ERR_XML_ERROR, "%s",
+   _("NVMe namespace can't be zero"));
+return -1;
+}
+
+if ((managed = virXMLPropString(node, "managed"))) {
+if ((nvme->managed = virTristateBoolTypeFromString(managed)) <= 0) {
+virReportError(VIR_ERR_XML_ERROR,
+   _("malformed managed value '%s'"),
+   managed);
+return -1;
+}
+}
+
+if (!(address = virXPathNode("./address", ctxt))) {
+virReportError(VIR_ERR_XML_ERROR, "%s",
+   _("NVMe disk source is missing address"));
+return -1;
+}
+
+if (virPCIDeviceAddressParseXML(address, >pciAddr) < 0)
+return -1;
+
+VIR_STEAL_PTR(src->nvme, nvme);
+return 0;
+}
+
+
 static int
 virDomainDiskSourcePRParse(xmlNodePtr node,
xmlXPathContextPtr ctxt,
@@ -9351,6 +9426,10 @@ virDomainStorageSourceParse(xmlNodePtr node,
 if (virDomainDiskSourcePoolDefParse(node, >srcpool) < 0)
 return -1;
 break;
+case VIR_STORAGE_TYPE_NVME:
+if (virDomainDiskSourceNVMeParse(node, ctxt, src) < 0)
+return -1;
+break;
 case VIR_STORAGE_TYPE_NONE:
 case VIR_STORAGE_TYPE_LAST:
 virReportError(VIR_ERR_INTERNAL_ERROR,
@@ -24088,6 +24167,19 @@ virDomainDiskSourceFormatNetwork(virBufferPtr attrBuf,
 }
 
 
+static void
+virDomainDiskSourceNVMeFormat(virBufferPtr attrBuf,
+  virBufferPtr childBuf,
+  const virStorageSourceNVMeDef *nvme)
+{
+virBufferAddLit(attrBuf, " type='pci'");
+virBufferAsprintf(attrBuf, " managed='%s'",
+  virTristateBoolTypeToString(nvme->managed));
+virBufferAsprintf(attrBuf, " namespace='%llu'", nvme->namespace);
+virPCIDeviceAddressFormat(childBuf, nvme->pciAddr, false);
+}
+
+
 static int
 virDomainDiskSourceFormatPrivateData(virBufferPtr buf,
  virStorageSourcePtr src,
@@ -24174,6 +24266,10 @@ 

[libvirt] [PATCH v2 23/39] virhostdev: Include virNVMeDevice module

2019-09-26 Thread Michal Privoznik
Now that we have virNVMeDevice module (introduced in previous
commit), let's use it int virHostdev to track which NVMe devices
are free to be used by a domain and which are taken.

Signed-off-by: Michal Privoznik 
---
 src/libvirt_private.syms |   5 +
 src/util/virhostdev.c| 332 +++
 src/util/virhostdev.h|  37 +
 3 files changed, 374 insertions(+)

diff --git a/src/libvirt_private.syms b/src/libvirt_private.syms
index 0c84b347db..ae8b41ce30 100644
--- a/src/libvirt_private.syms
+++ b/src/libvirt_private.syms
@@ -2113,18 +2113,23 @@ virHostdevPCINodeDeviceReAttach;
 virHostdevPCINodeDeviceReset;
 virHostdevPrepareDomainDevices;
 virHostdevPrepareMediatedDevices;
+virHostdevPrepareNVMeDevices;
+virHostdevPrepareOneNVMeDevice;
 virHostdevPreparePCIDevices;
 virHostdevPrepareSCSIDevices;
 virHostdevPrepareSCSIVHostDevices;
 virHostdevPrepareUSBDevices;
 virHostdevReAttachDomainDevices;
 virHostdevReAttachMediatedDevices;
+virHostdevReAttachNVMeDevices;
+virHostdevReAttachOneNVMeDevice;
 virHostdevReAttachPCIDevices;
 virHostdevReAttachSCSIDevices;
 virHostdevReAttachSCSIVHostDevices;
 virHostdevReAttachUSBDevices;
 virHostdevUpdateActiveDomainDevices;
 virHostdevUpdateActiveMediatedDevices;
+virHostdevUpdateActiveNVMeDevices;
 virHostdevUpdateActivePCIDevices;
 virHostdevUpdateActiveSCSIDevices;
 virHostdevUpdateActiveUSBDevices;
diff --git a/src/util/virhostdev.c b/src/util/virhostdev.c
index f0c97ca887..9ccf79453c 100644
--- a/src/util/virhostdev.c
+++ b/src/util/virhostdev.c
@@ -138,6 +138,7 @@ virHostdevManagerDispose(void *obj)
 virObjectUnref(hostdevMgr->activeSCSIHostdevs);
 virObjectUnref(hostdevMgr->activeSCSIVHostHostdevs);
 virObjectUnref(hostdevMgr->activeMediatedHostdevs);
+virObjectUnref(hostdevMgr->activeNVMeHostdevs);
 VIR_FREE(hostdevMgr->stateDir);
 }
 
@@ -168,6 +169,9 @@ virHostdevManagerNew(void)
 if (!(hostdevMgr->activeMediatedHostdevs = virMediatedDeviceListNew()))
 return NULL;
 
+if (!(hostdevMgr->activeNVMeHostdevs = virNVMeDeviceListNew()))
+return NULL;
+
 if (privileged) {
 if (VIR_STRDUP(hostdevMgr->stateDir, HOSTDEV_STATE_DIR) < 0)
 return NULL;
@@ -2240,3 +2244,331 @@ 
virHostdevUpdateActiveDomainDevices(virHostdevManagerPtr mgr,
 
 return 0;
 }
+
+
+static int
+virHostdevGetNVMeDeviceList(virNVMeDeviceListPtr nvmeDevices,
+virStorageSourcePtr src,
+const char *drv_name,
+const char *dom_name)
+{
+virStorageSourcePtr n;
+
+for (n = src; virStorageSourceIsBacking(n); n = n->backingStore) {
+VIR_AUTOPTR(virNVMeDevice) dev = NULL;
+const virStorageSourceNVMeDef *srcNVMe = n->nvme;
+
+if (n->type != VIR_STORAGE_TYPE_NVME)
+continue;
+
+if (!(dev = virNVMeDeviceNew(>pciAddr,
+ srcNVMe->namespace,
+ srcNVMe->managed)))
+return -1;
+
+if (virNVMeDeviceUsedBySet(dev, drv_name, dom_name) < 0)
+return -1;
+
+if (virNVMeDeviceListAdd(nvmeDevices, dev) < 0)
+return -1;
+}
+
+return 0;
+}
+
+
+int
+virHostdevPrepareOneNVMeDevice(virHostdevManagerPtr hostdev_mgr,
+   const char *drv_name,
+   const char *dom_name,
+   virStorageSourcePtr src)
+{
+VIR_AUTOUNREF(virNVMeDeviceListPtr) nvmeDevices = NULL;
+VIR_AUTOUNREF(virPCIDeviceListPtr) pciDevices = NULL;
+const unsigned int pciFlags = 0;
+virNVMeDevicePtr temp = NULL;
+size_t i;
+ssize_t lastGoodNVMeIdx = -1;
+int ret = -1;
+
+if (!(nvmeDevices = virNVMeDeviceListNew()))
+return -1;
+
+if (virHostdevGetNVMeDeviceList(nvmeDevices, src, drv_name, dom_name) < 0)
+return -1;
+
+if (virNVMeDeviceListCount(nvmeDevices) == 0)
+return 0;
+
+virObjectLock(hostdev_mgr->activeNVMeHostdevs);
+
+/* Firstly, let's check if all devices are free */
+for (i = 0; i < virNVMeDeviceListCount(nvmeDevices); i++) {
+const virNVMeDevice *dev = virNVMeDeviceListGet(nvmeDevices, i);
+const virPCIDeviceAddress *addr = NULL;
+VIR_AUTOFREE(char *) addrStr = NULL;
+const char *actual_drvname = NULL;
+const char *actual_domname = NULL;
+
+temp = virNVMeDeviceListLookup(hostdev_mgr->activeNVMeHostdevs, dev);
+
+/* Not on the list means not used */
+if (!temp)
+continue;
+
+virNVMeDeviceUsedByGet(temp, _drvname, _domname);
+addr = virNVMeDeviceAddressGet(dev);
+addrStr = virPCIDeviceAddressAsString(addr);
+
+virReportError(VIR_ERR_OPERATION_INVALID,
+   _("NVMe device %s already in use by driver %s domain 
%s"),
+   NULLSTR(addrStr), actual_drvname, actual_domname);
+goto cleanup;

[libvirt] [PATCH v2 16/39] virpci: Introduce virPCIDeviceAddressCopy

2019-09-26 Thread Michal Privoznik
This helper is cleaner than plain memcpy() because one doesn't
have to look into virPCIDeviceAddress struct to see if it
contains any strings / pointers.

Signed-off-by: Michal Privoznik 
ACKed-by: Peter Krempa 
---
 src/libvirt_private.syms |  1 +
 src/util/virpci.c| 14 ++
 src/util/virpci.h|  4 
 3 files changed, 19 insertions(+)

diff --git a/src/libvirt_private.syms b/src/libvirt_private.syms
index 4b726b3139..b3c95495c3 100644
--- a/src/libvirt_private.syms
+++ b/src/libvirt_private.syms
@@ -2655,6 +2655,7 @@ virObjectUnref;
 
 # util/virpci.h
 virPCIDeviceAddressAsString;
+virPCIDeviceAddressCopy;
 virPCIDeviceAddressEqual;
 virPCIDeviceAddressFree;
 virPCIDeviceAddressGetIOMMUGroupAddresses;
diff --git a/src/util/virpci.c b/src/util/virpci.c
index fc620d49ce..9bf081540a 100644
--- a/src/util/virpci.c
+++ b/src/util/virpci.c
@@ -1350,6 +1350,20 @@ virPCIDeviceAddressEqual(const virPCIDeviceAddress 
*addr1,
 return false;
 }
 
+/**
+ * virPCIDeviceAddressCopy:
+ * @dst: where to store address
+ * @src: source address to copy
+ *
+ * Creates a deep copy of given @src address and stores it into
+ * @dst which has to be pre-allocated by caller.
+ */
+void virPCIDeviceAddressCopy(virPCIDeviceAddressPtr dst,
+ const virPCIDeviceAddress *src)
+{
+memcpy(dst, src, sizeof(*src));
+}
+
 char *
 virPCIDeviceAddressAsString(const virPCIDeviceAddress *addr)
 {
diff --git a/src/util/virpci.h b/src/util/virpci.h
index 293d10b3ab..0a89bc9dcf 100644
--- a/src/util/virpci.h
+++ b/src/util/virpci.h
@@ -42,6 +42,7 @@ typedef virZPCIDeviceAddress *virZPCIDeviceAddressPtr;
 struct _virZPCIDeviceAddress {
 unsigned int uid; /* exempt from syntax-check */
 unsigned int fid;
+/* Don't forget to update virPCIDeviceAddressCopy if needed. */
 };
 
 #define VIR_PCI_DEVICE_ADDRESS_FMT "%04x:%02x:%02x.%d"
@@ -54,6 +55,7 @@ struct _virPCIDeviceAddress {
 int multi; /* virTristateSwitch */
 int extFlags; /* enum virPCIDeviceAddressExtensionFlags */
 virZPCIDeviceAddress zpci;
+/* Don't forget to update virPCIDeviceAddressCopy if needed. */
 };
 
 typedef enum {
@@ -234,6 +236,8 @@ bool virPCIDeviceAddressIsEmpty(const virPCIDeviceAddress 
*addr);
 
 bool virPCIDeviceAddressEqual(const virPCIDeviceAddress *addr1,
   const virPCIDeviceAddress *addr2);
+void virPCIDeviceAddressCopy(virPCIDeviceAddressPtr dst,
+ const virPCIDeviceAddress *src);
 
 char *virPCIDeviceAddressAsString(const virPCIDeviceAddress *addr)
   ATTRIBUTE_NONNULL(1);
-- 
2.21.0

--
libvir-list mailing list
libvir-list@redhat.com
https://www.redhat.com/mailman/listinfo/libvir-list


[libvirt] [PATCH v2 26/39] qemu: prepare NVMe devices too

2019-09-26 Thread Michal Privoznik
The qemu driver has its own wrappers around virHostdev module (so
that some arguments are filled in automatically). Extend these to
include NVMe devices too.

Signed-off-by: Michal Privoznik 
ACKed-by: Peter Krempa 
---
 src/qemu/qemu_hostdev.c | 49 ++---
 src/qemu/qemu_hostdev.h | 10 +
 2 files changed, 56 insertions(+), 3 deletions(-)

diff --git a/src/qemu/qemu_hostdev.c b/src/qemu/qemu_hostdev.c
index ebbca817b8..5ab0217858 100644
--- a/src/qemu/qemu_hostdev.c
+++ b/src/qemu/qemu_hostdev.c
@@ -96,13 +96,28 @@ qemuHostdevUpdateActiveMediatedDevices(virQEMUDriverPtr 
driver,
 }
 
 
+int
+qemuHostdevUpdateActiveNVMeDisks(virQEMUDriverPtr driver,
+ virDomainDefPtr def)
+{
+return virHostdevUpdateActiveNVMeDevices(driver->hostdevMgr,
+ QEMU_DRIVER_NAME,
+ def->name,
+ def->disks,
+ def->ndisks);
+}
+
+
 int
 qemuHostdevUpdateActiveDomainDevices(virQEMUDriverPtr driver,
  virDomainDefPtr def)
 {
-if (!def->nhostdevs)
+if (!def->nhostdevs && !def->ndisks)
 return 0;
 
+if (qemuHostdevUpdateActiveNVMeDisks(driver, def) < 0)
+return -1;
+
 if (qemuHostdevUpdateActivePCIDevices(driver, def) < 0)
 return -1;
 
@@ -197,6 +212,17 @@ 
qemuHostdevPreparePCIDevicesCheckSupport(virDomainHostdevDefPtr *hostdevs,
 return true;
 }
 
+int
+qemuHostdevPrepareNVMeDisks(virQEMUDriverPtr driver,
+const char *name,
+virDomainDiskDefPtr *disks,
+size_t ndisks)
+{
+return virHostdevPrepareNVMeDevices(driver->hostdevMgr,
+QEMU_DRIVER_NAME,
+name, disks, ndisks);
+}
+
 int
 qemuHostdevPreparePCIDevices(virQEMUDriverPtr driver,
  const char *name,
@@ -313,9 +339,12 @@ qemuHostdevPrepareDomainDevices(virQEMUDriverPtr driver,
 virQEMUCapsPtr qemuCaps,
 unsigned int flags)
 {
-if (!def->nhostdevs)
+if (!def->nhostdevs && !def->ndisks)
 return 0;
 
+if (qemuHostdevPrepareNVMeDisks(driver, def->name, def->disks, 
def->ndisks) < 0)
+return -1;
+
 if (qemuHostdevPreparePCIDevices(driver, def->name, def->uuid,
  def->hostdevs, def->nhostdevs,
  qemuCaps, flags) < 0)
@@ -340,6 +369,17 @@ qemuHostdevPrepareDomainDevices(virQEMUDriverPtr driver,
 return 0;
 }
 
+void
+qemuHostdevReAttachNVMeDisks(virQEMUDriverPtr driver,
+ const char *name,
+ virDomainDiskDefPtr *disks,
+ size_t ndisks)
+{
+virHostdevReAttachNVMeDevices(driver->hostdevMgr,
+  QEMU_DRIVER_NAME,
+  name, disks, ndisks);
+}
+
 void
 qemuHostdevReAttachPCIDevices(virQEMUDriverPtr driver,
   const char *name,
@@ -419,9 +459,12 @@ void
 qemuHostdevReAttachDomainDevices(virQEMUDriverPtr driver,
  virDomainDefPtr def)
 {
-if (!def->nhostdevs)
+if (!def->nhostdevs && !def->ndisks)
 return;
 
+qemuHostdevReAttachNVMeDisks(driver, def->name, def->disks,
+ def->ndisks);
+
 qemuHostdevReAttachPCIDevices(driver, def->name, def->hostdevs,
   def->nhostdevs);
 
diff --git a/src/qemu/qemu_hostdev.h b/src/qemu/qemu_hostdev.h
index 536069fe8a..735414b6aa 100644
--- a/src/qemu/qemu_hostdev.h
+++ b/src/qemu/qemu_hostdev.h
@@ -28,6 +28,8 @@ bool qemuHostdevNeedsVFIO(const virDomainHostdevDef *hostdev);
 
 bool qemuHostdevHostSupportsPassthroughVFIO(void);
 
+int qemuHostdevUpdateActiveNVMeDisks(virQEMUDriverPtr driver,
+ virDomainDefPtr def);
 int qemuHostdevUpdateActiveMediatedDevices(virQEMUDriverPtr driver,
virDomainDefPtr def);
 int qemuHostdevUpdateActivePCIDevices(virQEMUDriverPtr driver,
@@ -39,6 +41,10 @@ int qemuHostdevUpdateActiveSCSIDevices(virQEMUDriverPtr 
driver,
 int qemuHostdevUpdateActiveDomainDevices(virQEMUDriverPtr driver,
  virDomainDefPtr def);
 
+int qemuHostdevPrepareNVMeDisks(virQEMUDriverPtr driver,
+const char *name,
+virDomainDiskDefPtr *disks,
+size_t ndisks);
 int qemuHostdevPreparePCIDevices(virQEMUDriverPtr driver,
  const char *name,
  const unsigned char *uuid,
@@ -68,6 +74,10 @@ int 

[libvirt] [PATCH v2 27/39] qemu: Take NVMe disks into account when calculating memlock limit

2019-09-26 Thread Michal Privoznik
We have this beautiful function that does crystal ball
divination. The function is named
qemuDomainGetMemLockLimitBytes() and it calculates the upper
limit of how much locked memory is given guest going to need. The
function bases its guess on devices defined for a domain. For
instance, if there is a VFIO hostdev defined then it adds 1GiB to
the guessed maximum. Since NVMe disks are pretty much VFIO
hostdevs (but not quite), we have to do the same sorcery.

Signed-off-by: Michal Privoznik 
ACKed-by: Peter Krempa 
---
 src/qemu/qemu_domain.c | 14 --
 1 file changed, 12 insertions(+), 2 deletions(-)

diff --git a/src/qemu/qemu_domain.c b/src/qemu/qemu_domain.c
index f8fe430a7f..33929ce3a8 100644
--- a/src/qemu/qemu_domain.c
+++ b/src/qemu/qemu_domain.c
@@ -11888,6 +11888,9 @@ getPPC64MemLockLimitBytes(virDomainDefPtr def)
 }
 }
 
+if (virDomainDefHasNVMeDisk(def))
+usesVFIO = true;
+
 memory = virDomainDefGetMemoryTotal(def);
 
 if (def->mem.max_memory)
@@ -11986,6 +11989,7 @@ unsigned long long
 qemuDomainGetMemLockLimitBytes(virDomainDefPtr def)
 {
 unsigned long long memKB = 0;
+bool usesVFIO = false;
 size_t i;
 
 /* prefer the hard limit */
@@ -12026,11 +12030,17 @@ qemuDomainGetMemLockLimitBytes(virDomainDefPtr def)
 for (i = 0; i < def->nhostdevs; i++) {
 if (virHostdevIsVFIODevice(def->hostdevs[i]) ||
 virHostdevIsMdevDevice(def->hostdevs[i])) {
-memKB = virDomainDefGetMemoryTotal(def) + 1024 * 1024;
-goto done;
+usesVFIO = true;
+break;
 }
 }
 
+if (virDomainDefHasNVMeDisk(def))
+usesVFIO = true;
+
+if (usesVFIO)
+memKB = virDomainDefGetMemoryTotal(def) + 1024 * 1024;
+
  done:
 return memKB << 10;
 }
-- 
2.21.0

--
libvir-list mailing list
libvir-list@redhat.com
https://www.redhat.com/mailman/listinfo/libvir-list


[libvirt] [PATCH v2 29/39] qemu: Mark NVMe disks as 'need VFIO'

2019-09-26 Thread Michal Privoznik
There are couple of places where a domain with a VFIO device gets
special treatment: in CGroups when enabling/disabling access to
/dev/vfio/vfio, and when creating/removing nodes in domain mount
namespace. Well, a NVMe disk is a VFIO device too. Fortunately,
we have this qemuDomainNeedsVFIO() function which is the only
place that needs adjustment.

Signed-off-by: Michal Privoznik 
---
 src/qemu/qemu_domain.c | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/src/qemu/qemu_domain.c b/src/qemu/qemu_domain.c
index 9409d8de8d..e4e9d4e361 100644
--- a/src/qemu/qemu_domain.c
+++ b/src/qemu/qemu_domain.c
@@ -12840,7 +12840,8 @@ bool
 qemuDomainNeedsVFIO(const virDomainDef *def)
 {
 return virDomainDefHasVFIOHostdev(def) ||
-virDomainDefHasMdevHostdev(def);
+virDomainDefHasMdevHostdev(def) ||
+virDomainDefHasNVMeDisk(def);
 }
 
 
-- 
2.21.0

--
libvir-list mailing list
libvir-list@redhat.com
https://www.redhat.com/mailman/listinfo/libvir-list


[libvirt] [PATCH v2 24/39] virpcimock: Introduce NVMe driver and devices

2019-09-26 Thread Michal Privoznik
The device configs (which are actually the same one config)
come from a NVMe disk of mine.

Signed-off-by: Michal Privoznik 
ACKed-by: Peter Krempa 
---
 tests/virpcimock.c   |   3 +++
 tests/virpcitestdata/-01-00.0.config | Bin 0 -> 4096 bytes
 tests/virpcitestdata/-02-00.0.config | Bin 0 -> 4096 bytes
 3 files changed, 3 insertions(+)
 create mode 100644 tests/virpcitestdata/-01-00.0.config
 create mode 100644 tests/virpcitestdata/-02-00.0.config

diff --git a/tests/virpcimock.c b/tests/virpcimock.c
index edb558b6ec..c36d3e1371 100644
--- a/tests/virpcimock.c
+++ b/tests/virpcimock.c
@@ -1017,6 +1017,7 @@ init_env(void)
 MAKE_PCI_DRIVER("iwlwifi", 0x8086, 0x0044);
 MAKE_PCI_DRIVER("i915", 0x8086, 0x0046, 0x8086, 0x0047);
 MAKE_PCI_DRIVER("vfio-pci", -1, -1);
+MAKE_PCI_DRIVER("nvme", 0x1cc1, 0x8201);
 
 # define MAKE_PCI_DEVICE(Id, Vendor, Device, IommuGroup, ...) \
 do { \
@@ -1052,6 +1053,8 @@ init_env(void)
 MAKE_PCI_DEVICE("0021:de:1f.1", 0x8086, 0x0047, 13,
 .physfn = "0021:de:1f.0"); /* Virtual Function */
 
+MAKE_PCI_DEVICE(":01:00.0", 0x1cc1, 0x8201, 14, .klass = 0x010802);
+MAKE_PCI_DEVICE(":02:00.0", 0x1cc1, 0x8201, 15, .klass = 0x010802);
 }
 
 
diff --git a/tests/virpcitestdata/-01-00.0.config 
b/tests/virpcitestdata/-01-00.0.config
new file mode 100644
index 
..f92455e2ac5701ce60a51ae19828658b80744399
GIT binary patch
literal 4096
zcmeHIF;Buk6#lMP3WC_80!0h0vM?|ZHYb~)#L>jXKcF*Mr%9L>;{S2-*!p%x

[libvirt] [PATCH v2 28/39] qemu: Create NVMe disk in domain namespace

2019-09-26 Thread Michal Privoznik
If a domain has an NVMe disk configured, then we need to create
/dev/vfio/* paths in domain's namespace so that qemu can open
them.

Signed-off-by: Michal Privoznik 
---
 src/qemu/qemu_domain.c | 69 +++---
 1 file changed, 52 insertions(+), 17 deletions(-)

diff --git a/src/qemu/qemu_domain.c b/src/qemu/qemu_domain.c
index 33929ce3a8..9409d8de8d 100644
--- a/src/qemu/qemu_domain.c
+++ b/src/qemu/qemu_domain.c
@@ -13423,16 +13423,29 @@ qemuDomainSetupDisk(virQEMUDriverConfigPtr cfg 
ATTRIBUTE_UNUSED,
 {
 virStorageSourcePtr next;
 char *dst = NULL;
+bool hasNVMe = false;
 int ret = -1;
 
 for (next = disk->src; virStorageSourceIsBacking(next); next = 
next->backingStore) {
-if (!next->path || !virStorageSourceIsLocalStorage(next)) {
-/* Not creating device. Just continue. */
-continue;
+if (next->type == VIR_STORAGE_TYPE_NVME) {
+VIR_AUTOFREE(char *) nvmePath = NULL;
+
+hasNVMe = true;
+
+if (!(nvmePath = 
virPCIDeviceAddressGetIOMMUGroupDev(>nvme->pciAddr)))
+goto cleanup;
+
+if (qemuDomainCreateDevice(nvmePath, data, false) < 0)
+goto cleanup;
+} else {
+if (!next->path || !virStorageSourceIsLocalStorage(next)) {
+/* Not creating device. Just continue. */
+continue;
+}
+
+if (qemuDomainCreateDevice(next->path, data, false) < 0)
+goto cleanup;
 }
-
-if (qemuDomainCreateDevice(next->path, data, false) < 0)
-goto cleanup;
 }
 
 /* qemu-pr-helper might require access to /dev/mapper/control. */
@@ -13440,6 +13453,10 @@ qemuDomainSetupDisk(virQEMUDriverConfigPtr cfg 
ATTRIBUTE_UNUSED,
 qemuDomainCreateDevice(QEMU_DEVICE_MAPPER_CONTROL_PATH, data, true) < 
0)
 goto cleanup;
 
+if (hasNVMe &&
+qemuDomainCreateDevice(QEMU_DEV_VFIO, data, false) < 0)
+goto cleanup;
+
 ret = 0;
  cleanup:
 VIR_FREE(dst);
@@ -14468,35 +14485,53 @@ qemuDomainNamespaceSetupDisk(virDomainObjPtr vm,
  virStorageSourcePtr src)
 {
 virStorageSourcePtr next;
-const char **paths = NULL;
+char **paths = NULL;
 size_t npaths = 0;
-char *dmPath = NULL;
+bool hasNVMe = false;
+VIR_AUTOFREE(char *) dmPath = NULL;
+VIR_AUTOFREE(char *) vfioPath = NULL;
 int ret = -1;
 
 for (next = src; virStorageSourceIsBacking(next); next = 
next->backingStore) {
-if (virStorageSourceIsEmpty(next) ||
-!virStorageSourceIsLocalStorage(next)) {
-/* Not creating device. Just continue. */
-continue;
+VIR_AUTOFREE(char *) tmpPath = NULL;
+
+if (next->type == VIR_STORAGE_TYPE_NVME) {
+hasNVMe = true;
+
+if (!(tmpPath = 
virPCIDeviceAddressGetIOMMUGroupDev(>nvme->pciAddr)))
+goto cleanup;
+} else {
+if (virStorageSourceIsEmpty(next) ||
+!virStorageSourceIsLocalStorage(next)) {
+/* Not creating device. Just continue. */
+continue;
+}
+
+if (VIR_STRDUP(tmpPath, next->path) < 0)
+goto cleanup;
 }
 
-if (VIR_APPEND_ELEMENT_COPY(paths, npaths, next->path) < 0)
+if (VIR_APPEND_ELEMENT(paths, npaths, tmpPath) < 0)
 goto cleanup;
 }
 
 /* qemu-pr-helper might require access to /dev/mapper/control. */
 if (src->pr &&
 (VIR_STRDUP(dmPath, QEMU_DEVICE_MAPPER_CONTROL_PATH) < 0 ||
- VIR_APPEND_ELEMENT_COPY(paths, npaths, dmPath) < 0))
+ VIR_APPEND_ELEMENT(paths, npaths, dmPath) < 0))
 goto cleanup;
 
-if (qemuDomainNamespaceMknodPaths(vm, paths, npaths) < 0)
+if (hasNVMe &&
+(VIR_STRDUP(vfioPath, QEMU_DEV_VFIO) < 0 ||
+ VIR_APPEND_ELEMENT(paths, npaths, vfioPath) < 0))
+goto cleanup;
+
+if (qemuDomainNamespaceMknodPaths(vm, (const char **) paths, npaths) < 0)
 goto cleanup;
 
 ret = 0;
  cleanup:
-VIR_FREE(dmPath);
-VIR_FREE(paths);
+virStringListFreeCount(paths, npaths);
 return ret;
 }
 
-- 
2.21.0

--
libvir-list mailing list
libvir-list@redhat.com
https://www.redhat.com/mailman/listinfo/libvir-list


Re: [libvirt] [PATCH 1/9] DO NOT PUSH: tests: add qemu capabilities data for qemu 4.2

2019-09-26 Thread Jiri Denemark
On Thu, Sep 26, 2019 at 18:05:14 +0200, Peter Krempa wrote:
> Currently I don't indend to push this as I'm waiting for some qemu
> patches to be merged to allow detection of blockdev.
> 
> This patch is necessary so that qemu's 'transaction' supports also
> deletion of bitmaps which will be introduced in qemu 4.2.
> ---
>  .../caps_4.2.0.x86_64.replies | 24758 
>  .../caps_4.2.0.x86_64.xml |  1952 ++
>  2 files changed, 26710 insertions(+)
>  create mode 100644 tests/qemucapabilitiesdata/caps_4.2.0.x86_64.replies
>  create mode 100644 tests/qemucapabilitiesdata/caps_4.2.0.x86_64.xml

Please push this (ideally with an update to domaincapstest). I need
the 4.2 data for my series which I'm going to send soon.

Thanks.

Reviewed-by: Jiri Denemark 

--
libvir-list mailing list
libvir-list@redhat.com
https://www.redhat.com/mailman/listinfo/libvir-list


Re: [libvirt] [PATCH v2 7/7] qemu: driver: Don't pull in qemu_monitor_json.h directly

2019-09-26 Thread Eric Blake

On 9/25/19 7:54 AM, Peter Krempa wrote:

There's nothing that uses it directly now. Also not allowing direct use
will promote our layering.

Signed-off-by: Peter Krempa 
---
  src/qemu/qemu_driver.c | 1 -
  1 file changed, 1 deletion(-)


Reviewed-by: Eric Blake 



diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c
index 7163216f69..5852df2a53 100644
--- a/src/qemu/qemu_driver.c
+++ b/src/qemu/qemu_driver.c
@@ -47,7 +47,6 @@
  #include "qemu_hostdev.h"
  #include "qemu_hotplug.h"
  #include "qemu_monitor.h"
-#include "qemu_monitor_json.h"
  #include "qemu_process.h"
  #include "qemu_migration.h"
  #include "qemu_migration_params.h"



--
Eric Blake, Principal Software Engineer
Red Hat, Inc.   +1-919-301-3226
Virtualization:  qemu.org | libvirt.org

--
libvir-list mailing list
libvir-list@redhat.com
https://www.redhat.com/mailman/listinfo/libvir-list


[libvirt] [PATCH 1/8] qemu: checkpoint: Refactor cleanup in qemuCheckpointCreateXML

2019-09-26 Thread Peter Krempa
Use VIR_AUTO* helpers and get rid of the 'cleanup' label.

Signed-off-by: Peter Krempa 
---
 src/qemu/qemu_checkpoint.c | 22 +-
 1 file changed, 9 insertions(+), 13 deletions(-)

diff --git a/src/qemu/qemu_checkpoint.c b/src/qemu/qemu_checkpoint.c
index 30d1b6ae3a..4430f69911 100644
--- a/src/qemu/qemu_checkpoint.c
+++ b/src/qemu/qemu_checkpoint.c
@@ -363,9 +363,9 @@ qemuCheckpointCreateXML(virDomainPtr domain,
 bool redefine = flags & VIR_DOMAIN_CHECKPOINT_CREATE_REDEFINE;
 unsigned int parse_flags = 0;
 virDomainMomentObjPtr other = NULL;
-virQEMUDriverConfigPtr cfg = NULL;
-virCapsPtr caps = NULL;
-virJSONValuePtr actions = NULL;
+VIR_AUTOUNREF(virQEMUDriverConfigPtr) cfg = NULL;
+VIR_AUTOUNREF(virCapsPtr) caps = NULL;
+VIR_AUTOPTR(virJSONValue) actions = NULL;
 int ret;
 VIR_AUTOUNREF(virDomainCheckpointDefPtr) def = NULL;

@@ -380,32 +380,32 @@ qemuCheckpointCreateXML(virDomainPtr domain,
 if (virDomainSnapshotObjListNum(vm->snapshots, NULL, 0) > 0) {
 virReportError(VIR_ERR_OPERATION_UNSUPPORTED, "%s",
_("cannot create checkpoint while snapshot exists"));
-goto cleanup;
+return NULL;
 }

 if (!virQEMUCapsGet(priv->qemuCaps, QEMU_CAPS_BITMAP_MERGE)) {
 virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
_("qemu binary lacks persistent bitmaps support"));
-goto cleanup;
+return NULL;
 }

 if (!(caps = virQEMUDriverGetCapabilities(driver, false)))
-goto cleanup;
+return NULL;

 if (!virDomainObjIsActive(vm)) {
 virReportError(VIR_ERR_OPERATION_UNSUPPORTED, "%s",
_("cannot create checkpoint for inactive domain"));
-goto cleanup;
+return NULL;
 }

 if (!(def = virDomainCheckpointDefParseString(xmlDesc, caps, 
driver->xmlopt,
   priv->qemuCaps, 
parse_flags)))
-goto cleanup;
+return NULL;
 /* Unlike snapshots, the RNG schema already ensured a sane filename. */

 /* We are going to modify the domain below. */
 if (qemuDomainObjBeginJob(driver, vm, QEMU_JOB_MODIFY) < 0)
-goto cleanup;
+return NULL;

 if (redefine) {
 if (virDomainCheckpointRedefinePrep(vm, , ,
@@ -484,10 +484,6 @@ qemuCheckpointCreateXML(virDomainPtr domain,

 qemuDomainObjEndJob(driver, vm);

- cleanup:
-virJSONValueFree(actions);
-virObjectUnref(caps);
-virObjectUnref(cfg);
 return checkpoint;
 }

-- 
2.21.0

--
libvir-list mailing list
libvir-list@redhat.com
https://www.redhat.com/mailman/listinfo/libvir-list


[libvirt] [PATCH 2/8] qemu: checkpoint: Remove open-ended TODOs

2019-09-26 Thread Peter Krempa
Once somebody is motivated enough to add the support for the quiesce
flag or offline checkpoint deletion they are welcome to do so but we
don't need to have a reminder.

Signed-off-by: Peter Krempa 
---
 src/qemu/qemu_checkpoint.c | 3 ---
 1 file changed, 3 deletions(-)

diff --git a/src/qemu/qemu_checkpoint.c b/src/qemu/qemu_checkpoint.c
index 4430f69911..59f700e1d3 100644
--- a/src/qemu/qemu_checkpoint.c
+++ b/src/qemu/qemu_checkpoint.c
@@ -370,7 +370,6 @@ qemuCheckpointCreateXML(virDomainPtr domain,
 VIR_AUTOUNREF(virDomainCheckpointDefPtr) def = NULL;

 virCheckFlags(VIR_DOMAIN_CHECKPOINT_CREATE_REDEFINE, NULL);
-/* TODO: VIR_DOMAIN_CHECKPOINT_CREATE_QUIESCE */

 if (redefine) {
 parse_flags |= VIR_DOMAIN_CHECKPOINT_PARSE_REDEFINE;
@@ -570,8 +569,6 @@ qemuCheckpointDelete(virDomainObjPtr vm,
 return -1;

 if (!metadata_only) {
-/* Until qemu-img supports offline bitmap deletion, we are stuck
- * with requiring a running guest */
 if (!virDomainObjIsActive(vm)) {
 virReportError(VIR_ERR_OPERATION_UNSUPPORTED, "%s",
_("cannot delete checkpoint for inactive domain"));
-- 
2.21.0

--
libvir-list mailing list
libvir-list@redhat.com
https://www.redhat.com/mailman/listinfo/libvir-list


[libvirt] [PATCH 0/8] qemu: Lock-out checkpoints until backups are ready

2019-09-26 Thread Peter Krempa
See patch 6/8 for the reasoning.

This series applies on top of the v2 of splitting checkpoints into a
separate file.

Peter Krempa (8):
  qemu: checkpoint: Refactor cleanup in qemuCheckpointCreateXML
  qemu: checkpoint: Remove open-ended TODOs
  qemu: Simplify argument list of qemuDomainBlockPullCommon
  qemu: Don't repeat virDomainObjEndAPI in qemuDomainBlockPull
  qemu: caps: Add capability for incremental backup support
  qemu: checkpoint: Forbid creating checkpoints until we support backups
  qemu: Aggregate interlocking of blockjobs by checkpoints in one place
  qemu: domain: Base block job interlocking on
QEMU_CAPS_INCREMENTAL_BACKUP

 src/qemu/qemu_capabilities.c |  3 +++
 src/qemu/qemu_capabilities.h |  3 +++
 src/qemu/qemu_checkpoint.c   | 42 +-
 src/qemu/qemu_domain.c   | 24 +
 src/qemu/qemu_domain.h   |  4 +++
 src/qemu/qemu_driver.c   | 50 +---
 6 files changed, 70 insertions(+), 56 deletions(-)

-- 
2.21.0

--
libvir-list mailing list
libvir-list@redhat.com
https://www.redhat.com/mailman/listinfo/libvir-list


[libvirt] [PATCH 4/8] qemu: Don't repeat virDomainObjEndAPI in qemuDomainBlockPull

2019-09-26 Thread Peter Krempa
Add a 'cleanup' label and use jumps as we do in other places.

Signed-off-by: Peter Krempa 
---
 src/qemu/qemu_driver.c | 17 ++---
 1 file changed, 10 insertions(+), 7 deletions(-)

diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c
index 71503898e4..3ad1699eb1 100644
--- a/src/qemu/qemu_driver.c
+++ b/src/qemu/qemu_driver.c
@@ -18522,24 +18522,27 @@ qemuDomainBlockPull(virDomainPtr dom, const char 
*path, unsigned long bandwidth,
 unsigned int flags)
 {
 virDomainObjPtr vm;
+int ret = -1;
+
 virCheckFlags(VIR_DOMAIN_BLOCK_PULL_BANDWIDTH_BYTES, -1);

 if (!(vm = qemuDomainObjFromDomain(dom)))
 return -1;

-if (virDomainBlockPullEnsureACL(dom->conn, vm->def) < 0) {
-virDomainObjEndAPI();
-return -1;
-}
+if (virDomainBlockPullEnsureACL(dom->conn, vm->def) < 0)
+goto cleanup;

 if (virDomainListCheckpoints(vm->checkpoints, NULL, dom, NULL, 0) > 0) {
 virReportError(VIR_ERR_OPERATION_UNSUPPORTED, "%s",
_("cannot perform block pull while checkpoint exists"));
-virDomainObjEndAPI();
-return -1;
+goto cleanup;
 }

-return qemuDomainBlockPullCommon(vm, path, NULL, bandwidth, flags);
+ret = qemuDomainBlockPullCommon(vm, path, NULL, bandwidth, flags);
+
+ cleanup:
+virDomainObjEndAPI();
+return ret;
 }


-- 
2.21.0

--
libvir-list mailing list
libvir-list@redhat.com
https://www.redhat.com/mailman/listinfo/libvir-list


[libvirt] [PATCH 7/8] qemu: Aggregate interlocking of blockjobs by checkpoints in one place

2019-09-26 Thread Peter Krempa
Rather than having to fix 5 places once we support the combination add a
function called by all the blockjob/snapshot APIs.

Signed-off-by: Peter Krempa 
---
 src/qemu/qemu_domain.c | 21 +
 src/qemu/qemu_domain.h |  4 
 src/qemu/qemu_driver.c | 25 +
 3 files changed, 30 insertions(+), 20 deletions(-)

diff --git a/src/qemu/qemu_domain.c b/src/qemu/qemu_domain.c
index 19fa5420e7..e8a82fee0b 100644
--- a/src/qemu/qemu_domain.c
+++ b/src/qemu/qemu_domain.c
@@ -15513,3 +15513,24 @@ qemuDomainDefHasManagedPR(virDomainObjPtr vm)

 return jobPR;
 }
+
+
+/**
+ * qemuDomainSupportsCheckpointsBlockjobs:
+ * @vm: domain object
+ *
+ * Checks whether a block job is supported in possible combination with
+ * checkpoints (qcow2 bitmaps). Returns -1 if unsupported and reports an error
+ * 0 in case everything is supported.
+ */
+int
+qemuDomainSupportsCheckpointsBlockjobs(virDomainObjPtr vm)
+{
+if (virDomainListCheckpoints(vm->checkpoints, NULL, NULL, NULL, 0) > 0) {
+virReportError(VIR_ERR_OPERATION_UNSUPPORTED, "%s",
+   _("cannot perform block operations while checkpoint 
exists"));
+return -1;
+}
+
+return 0;
+}
diff --git a/src/qemu/qemu_domain.h b/src/qemu/qemu_domain.h
index f45da882a8..01a54d4265 100644
--- a/src/qemu/qemu_domain.h
+++ b/src/qemu/qemu_domain.h
@@ -1217,3 +1217,7 @@ 
qemuDomainPausedReasonToSuspendedEvent(virDomainPausedReason reason);
 int
 qemuDomainValidateActualNetDef(const virDomainNetDef *net,
virQEMUCapsPtr qemuCaps);
+
+int
+qemuDomainSupportsCheckpointsBlockjobs(virDomainObjPtr vm)
+ATTRIBUTE_RETURN_CHECK;
diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c
index 3ad1699eb1..3847c727cf 100644
--- a/src/qemu/qemu_driver.c
+++ b/src/qemu/qemu_driver.c
@@ -15846,11 +15846,8 @@ qemuDomainSnapshotCreateXML(virDomainPtr domain,
 if (virDomainSnapshotCreateXMLEnsureACL(domain->conn, vm->def, flags) < 0)
 goto cleanup;

-if (virDomainListCheckpoints(vm->checkpoints, NULL, domain, NULL, 0) > 0) {
-virReportError(VIR_ERR_OPERATION_UNSUPPORTED, "%s",
-   _("cannot create snapshot while checkpoint exists"));
+if (qemuDomainSupportsCheckpointsBlockjobs(vm) < 0)
 goto cleanup;
-}

 if (!(caps = virQEMUDriverGetCapabilities(driver, false)))
 goto cleanup;
@@ -18374,11 +18371,8 @@ qemuDomainBlockRebase(virDomainPtr dom, const char 
*path, const char *base,
 if (virDomainBlockRebaseEnsureACL(dom->conn, vm->def) < 0)
 goto cleanup;

-if (virDomainListCheckpoints(vm->checkpoints, NULL, dom, NULL, 0) > 0) {
-virReportError(VIR_ERR_OPERATION_UNSUPPORTED, "%s",
-   _("cannot perform block rebase while checkpoint 
exists"));
+if (qemuDomainSupportsCheckpointsBlockjobs(vm) < 0)
 goto cleanup;
-}

 /* For normal rebase (enhanced blockpull), the common code handles
  * everything, including vm cleanup. */
@@ -18464,11 +18458,8 @@ qemuDomainBlockCopy(virDomainPtr dom, const char 
*disk, const char *destxml,
 if (virDomainBlockCopyEnsureACL(dom->conn, vm->def) < 0)
 goto cleanup;

-if (virDomainListCheckpoints(vm->checkpoints, NULL, dom, NULL, 0) > 0) {
-virReportError(VIR_ERR_OPERATION_UNSUPPORTED, "%s",
-   _("cannot perform block copy while checkpoint exists"));
+if (qemuDomainSupportsCheckpointsBlockjobs(vm) < 0)
 goto cleanup;
-}

 for (i = 0; i < nparams; i++) {
 virTypedParameterPtr param = [i];
@@ -18532,11 +18523,8 @@ qemuDomainBlockPull(virDomainPtr dom, const char 
*path, unsigned long bandwidth,
 if (virDomainBlockPullEnsureACL(dom->conn, vm->def) < 0)
 goto cleanup;

-if (virDomainListCheckpoints(vm->checkpoints, NULL, dom, NULL, 0) > 0) {
-virReportError(VIR_ERR_OPERATION_UNSUPPORTED, "%s",
-   _("cannot perform block pull while checkpoint exists"));
+if (qemuDomainSupportsCheckpointsBlockjobs(vm) < 0)
 goto cleanup;
-}

 ret = qemuDomainBlockPullCommon(vm, path, NULL, bandwidth, flags);

@@ -18591,11 +18579,8 @@ qemuDomainBlockCommit(virDomainPtr dom,
 if (virDomainBlockCommitEnsureACL(dom->conn, vm->def) < 0)
 goto cleanup;

-if (virDomainListCheckpoints(vm->checkpoints, NULL, dom, NULL, 0) > 0) {
-virReportError(VIR_ERR_OPERATION_UNSUPPORTED, "%s",
-   _("cannot perform block commit while checkpoint 
exists"));
+if (qemuDomainSupportsCheckpointsBlockjobs(vm) < 0)
 goto cleanup;
-}

 if (qemuDomainObjBeginJob(driver, vm, QEMU_JOB_MODIFY) < 0)
 goto cleanup;
-- 
2.21.0

--
libvir-list mailing list
libvir-list@redhat.com
https://www.redhat.com/mailman/listinfo/libvir-list


[libvirt] [PATCH 8/8] qemu: domain: Base block job interlocking on QEMU_CAPS_INCREMENTAL_BACKUP

2019-09-26 Thread Peter Krempa
The QEMU_CAPS_INCREMENTAL_BACKUP will be enabled once all bits of the
incremental backup feature work as expected which means also properly
interacting with blockjobs and snapshots.

Thus we can allow blockjobs and snapshots if QEMU_CAPS_INCREMENTAL_BACKUP
is present even when checkpoints exist.

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

diff --git a/src/qemu/qemu_domain.c b/src/qemu/qemu_domain.c
index e8a82fee0b..6d42530db0 100644
--- a/src/qemu/qemu_domain.c
+++ b/src/qemu/qemu_domain.c
@@ -15526,7 +15526,10 @@ qemuDomainDefHasManagedPR(virDomainObjPtr vm)
 int
 qemuDomainSupportsCheckpointsBlockjobs(virDomainObjPtr vm)
 {
-if (virDomainListCheckpoints(vm->checkpoints, NULL, NULL, NULL, 0) > 0) {
+qemuDomainObjPrivatePtr priv = vm->privateData;
+
+if (!virQEMUCapsGet(priv->qemuCaps, QEMU_CAPS_INCREMENTAL_BACKUP) &&
+virDomainListCheckpoints(vm->checkpoints, NULL, NULL, NULL, 0) > 0) {
 virReportError(VIR_ERR_OPERATION_UNSUPPORTED, "%s",
_("cannot perform block operations while checkpoint 
exists"));
 return -1;
-- 
2.21.0

--
libvir-list mailing list
libvir-list@redhat.com
https://www.redhat.com/mailman/listinfo/libvir-list


[libvirt] [PATCH 6/8] qemu: checkpoint: Forbid creating checkpoints until we support backups

2019-09-26 Thread Peter Krempa
Checkpoints by themselves are not very useful for anything else than
testing the few bitmap interactions that are currently implemented.

It's very unlikely that anybody used this feature and thus we can
disable it until we have a more complete implementation ready.

Additionally the code for deleting checkpoints has many broken failure
scenarios which should be fixed first. This will require support of
deleting a bitmap in a qemu 'transaction' which was not released yet.

Curious users obviously can use the qemu namespace in the XML to enable
this for experiments:

  
...

  

  

Signed-off-by: Peter Krempa 
---
 src/qemu/qemu_checkpoint.c | 17 +
 1 file changed, 9 insertions(+), 8 deletions(-)

diff --git a/src/qemu/qemu_checkpoint.c b/src/qemu/qemu_checkpoint.c
index 59f700e1d3..46a10cbeba 100644
--- a/src/qemu/qemu_checkpoint.c
+++ b/src/qemu/qemu_checkpoint.c
@@ -382,9 +382,9 @@ qemuCheckpointCreateXML(virDomainPtr domain,
 return NULL;
 }

-if (!virQEMUCapsGet(priv->qemuCaps, QEMU_CAPS_BITMAP_MERGE)) {
-virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
-   _("qemu binary lacks persistent bitmaps support"));
+if (!virQEMUCapsGet(priv->qemuCaps, QEMU_CAPS_INCREMENTAL_BACKUP)) {
+virReportError(VIR_ERR_OPERATION_UNSUPPORTED, "%s",
+   _("incremental backup is not supported yet"));
 return NULL;
 }

@@ -569,14 +569,15 @@ qemuCheckpointDelete(virDomainObjPtr vm,
 return -1;

 if (!metadata_only) {
-if (!virDomainObjIsActive(vm)) {
+if (!virQEMUCapsGet(priv->qemuCaps, QEMU_CAPS_INCREMENTAL_BACKUP)) {
 virReportError(VIR_ERR_OPERATION_UNSUPPORTED, "%s",
-   _("cannot delete checkpoint for inactive domain"));
+   _("incremental backup is not supported yet"));
 goto endjob;
 }
-if (!virQEMUCapsGet(priv->qemuCaps, QEMU_CAPS_BITMAP_MERGE)) {
-virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
-   _("qemu binary lacks persistent bitmaps support"));
+
+if (!virDomainObjIsActive(vm)) {
+virReportError(VIR_ERR_OPERATION_UNSUPPORTED, "%s",
+   _("cannot delete checkpoint for inactive domain"));
 goto endjob;
 }
 }
-- 
2.21.0

--
libvir-list mailing list
libvir-list@redhat.com
https://www.redhat.com/mailman/listinfo/libvir-list


[libvirt] [PATCH 3/8] qemu: Simplify argument list of qemuDomainBlockPullCommon

2019-09-26 Thread Peter Krempa
Drop the 'driver' argument since it can be extracted from private data
to shorten the argument list.

Signed-off-by: Peter Krempa 
---
 src/qemu/qemu_driver.c | 10 --
 1 file changed, 4 insertions(+), 6 deletions(-)

diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c
index 5852df2a53..71503898e4 100644
--- a/src/qemu/qemu_driver.c
+++ b/src/qemu/qemu_driver.c
@@ -17534,14 +17534,14 @@ qemuDomainBlockPivot(virQEMUDriverPtr driver,
 /* bandwidth in MiB/s per public API. Caller must lock vm beforehand,
  * and not access it afterwards.  */
 static int
-qemuDomainBlockPullCommon(virQEMUDriverPtr driver,
-  virDomainObjPtr vm,
+qemuDomainBlockPullCommon(virDomainObjPtr vm,
   const char *path,
   const char *base,
   unsigned long bandwidth,
   unsigned int flags)
 {
 qemuDomainObjPrivatePtr priv = vm->privateData;
+virQEMUDriverPtr driver = priv->driver;
 const char *device = NULL;
 const char *jobname = NULL;
 virDomainDiskDefPtr disk;
@@ -18355,7 +18355,6 @@ static int
 qemuDomainBlockRebase(virDomainPtr dom, const char *path, const char *base,
   unsigned long bandwidth, unsigned int flags)
 {
-virQEMUDriverPtr driver = dom->conn->privateData;
 virDomainObjPtr vm;
 int ret = -1;
 unsigned long long speed = bandwidth;
@@ -18384,7 +18383,7 @@ qemuDomainBlockRebase(virDomainPtr dom, const char 
*path, const char *base,
 /* For normal rebase (enhanced blockpull), the common code handles
  * everything, including vm cleanup. */
 if (!(flags & VIR_DOMAIN_BLOCK_REBASE_COPY))
-return qemuDomainBlockPullCommon(driver, vm, path, base, bandwidth, 
flags);
+return qemuDomainBlockPullCommon(vm, path, base, bandwidth, flags);

 /* If we got here, we are doing a block copy rebase. */
 if (!(dest = virStorageSourceNew()))
@@ -18540,8 +18539,7 @@ qemuDomainBlockPull(virDomainPtr dom, const char *path, 
unsigned long bandwidth,
 return -1;
 }

-return qemuDomainBlockPullCommon(dom->conn->privateData,
- vm, path, NULL, bandwidth, flags);
+return qemuDomainBlockPullCommon(vm, path, NULL, bandwidth, flags);
 }


-- 
2.21.0

--
libvir-list mailing list
libvir-list@redhat.com
https://www.redhat.com/mailman/listinfo/libvir-list


[libvirt] [PATCH 5/8] qemu: caps: Add capability for incremental backup support

2019-09-26 Thread Peter Krempa
Add a new all-covering capability which will be used to interlock
incremental backup support until all bits are ready.
---
 src/qemu/qemu_capabilities.c | 3 +++
 src/qemu/qemu_capabilities.h | 3 +++
 2 files changed, 6 insertions(+)

diff --git a/src/qemu/qemu_capabilities.c b/src/qemu/qemu_capabilities.c
index 72e070e8ab..2edbb3fdfe 100644
--- a/src/qemu/qemu_capabilities.c
+++ b/src/qemu/qemu_capabilities.c
@@ -540,6 +540,9 @@ VIR_ENUM_IMPL(virQEMUCaps,
   "dbus-vmstate",
   "vhost-user-gpu",
   "vhost-user-vga",
+
+  /* 340 */
+  "incremental-backup",
 );


diff --git a/src/qemu/qemu_capabilities.h b/src/qemu/qemu_capabilities.h
index 137b7161a5..5e990ce01e 100644
--- a/src/qemu/qemu_capabilities.h
+++ b/src/qemu/qemu_capabilities.h
@@ -522,6 +522,9 @@ typedef enum { /* virQEMUCapsFlags grouping marker for 
syntax-check */
 QEMU_CAPS_DEVICE_VHOST_USER_GPU, /* -device vhost-user-gpu */
 QEMU_CAPS_DEVICE_VHOST_USER_VGA, /* -device vhost-user-vga */

+/* 340 */
+QEMU_CAPS_INCREMENTAL_BACKUP, /* incremental backup is supported */
+
 QEMU_CAPS_LAST /* this must always be the last item */
 } virQEMUCapsFlags;

-- 
2.21.0

--
libvir-list mailing list
libvir-list@redhat.com
https://www.redhat.com/mailman/listinfo/libvir-list


Re: [libvirt] [PATCH] conf: utility function to update entry in def->nets array

2019-09-26 Thread Laine Stump

On 9/26/19 3:28 AM, Michal Privoznik wrote:

On 9/25/19 6:57 PM, Laine Stump wrote:


diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c
index 0753904472..5f63c4f51e 100644
--- a/src/qemu/qemu_driver.c
+++ b/src/qemu/qemu_driver.c
@@ -8786,8 +8786,10 @@ qemuDomainUpdateDeviceConfig(virDomainDefPtr 
vmdef,

   false) < 0)
  return -1;
  -    virDomainNetDefFree(vmdef->nets[pos]);
-    vmdef->nets[pos] = net;
+    if (virDomainNetUpdate(vmdef, pos, net))
+    return -1;
+
+    virDomainNetDefFree(oldDev.data.net);
  dev->data.net = NULL;
  break;



The same code pattern occurrs in lxcDomainUpdateDeviceConfig() so you 
may want to fix it the same way as you're doing here.



Sure. I try to keep changes in sync for all the hypervisors that support 
any particular operation, but sometimes I'm too focused on eliminating 
my specific problem and forget.



--
libvir-list mailing list
libvir-list@redhat.com
https://www.redhat.com/mailman/listinfo/libvir-list

[libvirt] [PATCH v2 06/39] qemu_cgroup: Teardown Cgroup for more host device types

2019-09-26 Thread Michal Privoznik
Since its introduction in v1.0.5-rc1-19-g6e13860cb4 the
qemuTeardownHostdevCgroup() does nothing unless the passed
hostdev is a PCI device with VFIO backend. This seems
unnecessary.

Signed-off-by: Michal Privoznik 
---
 src/qemu/qemu_cgroup.c | 8 +---
 1 file changed, 1 insertion(+), 7 deletions(-)

diff --git a/src/qemu/qemu_cgroup.c b/src/qemu/qemu_cgroup.c
index 318157dab0..4d6f0c33cd 100644
--- a/src/qemu/qemu_cgroup.c
+++ b/src/qemu/qemu_cgroup.c
@@ -405,16 +405,10 @@ qemuTeardownHostdevCgroup(virDomainObjPtr vm,
 size_t i, npaths = 0;
 int rv, ret = -1;
 
-/* currently this only does something for PCI devices using vfio
- * for device assignment, but it is called for *all* hostdev
- * devices.
- */
-
 if (!virCgroupHasController(priv->cgroup, VIR_CGROUP_CONTROLLER_DEVICES))
 return 0;
 
-if (virHostdevIsVFIODevice(dev) &&
-qemuDomainGetHostdevPath(vm->def, dev, true,
+if (qemuDomainGetHostdevPath(vm->def, dev, true,
  , , NULL) < 0)
 goto cleanup;
 
-- 
2.21.0

--
libvir-list mailing list
libvir-list@redhat.com
https://www.redhat.com/mailman/listinfo/libvir-list


[libvirt] [PATCH v2 10/39] qemuDomainGetHostdevPath: Use more VIR_AUTOFREE/VIR_AUTOPTR

2019-09-26 Thread Michal Privoznik
There are several variables which could be automatically freed
upon return from the function. I'm not changing @tmpPaths (which
is a string list) because it is going to be removed in next
commit.

Signed-off-by: Michal Privoznik 
---
 src/qemu/qemu_domain.c | 18 ++
 1 file changed, 6 insertions(+), 12 deletions(-)

diff --git a/src/qemu/qemu_domain.c b/src/qemu/qemu_domain.c
index c903750fa0..d8d2f72bcc 100644
--- a/src/qemu/qemu_domain.c
+++ b/src/qemu/qemu_domain.c
@@ -12866,14 +12866,14 @@ qemuDomainGetHostdevPath(virDomainDefPtr def,
 virDomainHostdevSubsysSCSIPtr scsisrc = >source.subsys.u.scsi;
 virDomainHostdevSubsysSCSIVHostPtr hostsrc = 
>source.subsys.u.scsi_host;
 virDomainHostdevSubsysMediatedDevPtr mdevsrc = >source.subsys.u.mdev;
-virPCIDevicePtr pci = NULL;
-virUSBDevicePtr usb = NULL;
-virSCSIDevicePtr scsi = NULL;
-virSCSIVHostDevicePtr host = NULL;
-char *tmpPath = NULL;
+VIR_AUTOPTR(virPCIDevice) pci = NULL;
+VIR_AUTOPTR(virUSBDevice) usb = NULL;
+VIR_AUTOPTR(virSCSIDevice) scsi = NULL;
+VIR_AUTOPTR(virSCSIVHostDevice) host = NULL;
+VIR_AUTOFREE(char *) tmpPath = NULL;
 bool includeVFIO = false;
 char **tmpPaths = NULL;
-int *tmpPerms = NULL;
+VIR_AUTOFREE(int *) tmpPerms = NULL;
 size_t tmpNpaths = 0;
 int perm = 0;
 
@@ -13004,12 +13004,6 @@ qemuDomainGetHostdevPath(virDomainDefPtr def,
 ret = 0;
  cleanup:
 virStringListFreeCount(tmpPaths, tmpNpaths);
-VIR_FREE(tmpPerms);
-virPCIDeviceFree(pci);
-virUSBDeviceFree(usb);
-virSCSIDeviceFree(scsi);
-virSCSIVHostDeviceFree(host);
-VIR_FREE(tmpPath);
 return ret;
 }
 
-- 
2.21.0

--
libvir-list mailing list
libvir-list@redhat.com
https://www.redhat.com/mailman/listinfo/libvir-list


[libvirt] [PATCH v2 32/39] virSecuritySELinuxRestoreImageLabelInt: Don't skip non-local storage

2019-09-26 Thread Michal Privoznik
This function is currently not called for any type of storage
source that is not considered 'local' (as defined by
virStorageSourceIsLocalStorage()). Well, NVMe disks are not
'local' from that point of view and therefore we will need to
call this function more frequently.

Signed-off-by: Michal Privoznik 
---
 src/security/security_apparmor.c | 33 +++---
 src/security/security_dac.c  | 30 
 src/security/security_selinux.c  | 48 +++-
 3 files changed, 94 insertions(+), 17 deletions(-)

diff --git a/src/security/security_apparmor.c b/src/security/security_apparmor.c
index 77eee9410c..580cd72223 100644
--- a/src/security/security_apparmor.c
+++ b/src/security/security_apparmor.c
@@ -803,22 +803,35 @@ AppArmorSetSecurityImageLabel(virSecurityManagerPtr mgr,
 {
 int rc = -1;
 char *profile_name = NULL;
+VIR_AUTOFREE(char *) vfioGroupDev = NULL;
+const char *path = NULL;
 virSecurityLabelDefPtr secdef;
 
-if (!src->path || !virStorageSourceIsLocalStorage(src))
-return 0;
-
 secdef = virDomainDefGetSecurityLabelDef(def, SECURITY_APPARMOR_NAME);
 if (!secdef || !secdef->relabel)
 return 0;
 
 if (secdef->imagelabel) {
-/* if the device doesn't exist, error out */
-if (!virFileExists(src->path)) {
-virReportError(VIR_ERR_INTERNAL_ERROR,
-   _("\'%s\' does not exist"),
-   src->path);
-return -1;
+if (src->type == VIR_STORAGE_TYPE_NVME) {
+const virStorageSourceNVMeDef *nvme = src->nvme;
+
+if (!(vfioGroupDev = 
virPCIDeviceAddressGetIOMMUGroupDev(>pciAddr)))
+return -1;
+
+path = vfioGroupDev;
+} else {
+if (!src->path || !virStorageSourceIsLocalStorage(src))
+return 0;
+
+/* if the device doesn't exist, error out */
+if (!virFileExists(src->path)) {
+virReportError(VIR_ERR_INTERNAL_ERROR,
+   _("\'%s\' does not exist"),
+   src->path);
+return -1;
+}
+
+path = src->path;
 }
 
 if ((profile_name = get_profile_name(def)) == NULL)
@@ -827,7 +840,7 @@ AppArmorSetSecurityImageLabel(virSecurityManagerPtr mgr,
 /* update the profile only if it is loaded */
 if (profile_loaded(secdef->imagelabel) >= 0) {
 if (load_profile(mgr, secdef->imagelabel, def,
- src->path, false) < 0) {
+ path, false) < 0) {
 virReportError(VIR_ERR_INTERNAL_ERROR,
_("cannot update AppArmor profile "
  "\'%s\'"),
diff --git a/src/security/security_dac.c b/src/security/security_dac.c
index 4b4afef18a..42d585500d 100644
--- a/src/security/security_dac.c
+++ b/src/security/security_dac.c
@@ -915,6 +915,19 @@ virSecurityDACSetImageLabelInternal(virSecurityManagerPtr 
mgr,
 return -1;
 }
 
+/* This is not very clean. But so far we don't have NVMe
+ * storage pool backend so that its chownCallback would be
+ * called. And this place looks least offensive. */
+if (src->type == VIR_STORAGE_TYPE_NVME) {
+const virStorageSourceNVMeDef *nvme = src->nvme;
+VIR_AUTOFREE(char *) vfioGroupDev = NULL;
+
+if (!(vfioGroupDev = 
virPCIDeviceAddressGetIOMMUGroupDev(>pciAddr)))
+return -1;
+
+return virSecurityDACSetOwnership(mgr, NULL, vfioGroupDev, user, 
group, false);
+}
+
 /* We can't do restore on shared resources safely. Not even
  * with refcounting implemented in XATTRs because if there
  * was a domain running with the feature turned off the
@@ -1004,6 +1017,23 @@ virSecurityDACRestoreImageLabelInt(virSecurityManagerPtr 
mgr,
 }
 }
 
+/* This is not very clean. But so far we don't have NVMe
+ * storage pool backend so that its chownCallback would be
+ * called. And this place looks least offensive. */
+if (src->type == VIR_STORAGE_TYPE_NVME) {
+const virStorageSourceNVMeDef *nvme = src->nvme;
+VIR_AUTOFREE(char *) vfioGroupDev = NULL;
+
+if (!(vfioGroupDev = 
virPCIDeviceAddressGetIOMMUGroupDev(>pciAddr)))
+return -1;
+
+/* Ideally, we would check if there is not another PCI
+ * device within domain def that is in the same IOMMU
+ * group. But we're not doing that for hostdevs yet. */
+
+return virSecurityDACRestoreFileLabelInternal(mgr, NULL, vfioGroupDev, 
false);
+}
+
 return virSecurityDACRestoreFileLabelInternal(mgr, src, NULL, true);
 }
 
diff --git a/src/security/security_selinux.c b/src/security/security_selinux.c
index 3a00666d26..f439ecec46 100644
--- a/src/security/security_selinux.c
+++ b/src/security/security_selinux.c
@@ -1754,9 +1754,8 @@ 

[libvirt] [PATCH v2 30/39] qemu: Allow NVMe disk in CGroups

2019-09-26 Thread Michal Privoznik
If a domain has an NVMe disk configured, then we need to allow it
on devices CGroup so that qemu can access it. There is one caveat
though - if an NVMe disk is read only we need CGroup to allow
write too. This is because when opening the device, qemu does
couple of ioctl()-s which are considered as write.

Signed-off-by: Michal Privoznik 
---
 src/qemu/qemu_cgroup.c | 101 +
 1 file changed, 72 insertions(+), 29 deletions(-)

diff --git a/src/qemu/qemu_cgroup.c b/src/qemu/qemu_cgroup.c
index 9684bf3662..b9fb0ebca2 100644
--- a/src/qemu/qemu_cgroup.c
+++ b/src/qemu/qemu_cgroup.c
@@ -119,10 +119,30 @@ qemuSetupImageCgroupInternal(virDomainObjPtr vm,
  virStorageSourcePtr src,
  bool forceReadonly)
 {
-if (!src->path || !virStorageSourceIsLocalStorage(src)) {
-VIR_DEBUG("Not updating cgroups for disk path '%s', type: %s",
-  NULLSTR(src->path), virStorageTypeToString(src->type));
-return 0;
+VIR_AUTOFREE(char *) path = NULL;
+bool readonly = src->readonly || forceReadonly;
+
+if (src->type == VIR_STORAGE_TYPE_NVME) {
+/* Even though disk is R/O we can't make it so in
+ * CGroups. QEMU will try to do some ioctl()-s over the
+ * device and such operations are considered R/W by the
+ * kernel */
+readonly = false;
+
+if (!(path = virPCIDeviceAddressGetIOMMUGroupDev(>nvme->pciAddr)))
+return -1;
+
+if (qemuSetupImagePathCgroup(vm, QEMU_DEV_VFIO, false) < 0)
+return -1;
+} else {
+if (!src->path || !virStorageSourceIsLocalStorage(src)) {
+VIR_DEBUG("Not updating cgroups for disk path '%s', type: %s",
+  NULLSTR(src->path), virStorageTypeToString(src->type));
+return 0;
+}
+
+if (VIR_STRDUP(path, src->path) < 0)
+return -1;
 }
 
 if (virStoragePRDefIsManaged(src->pr) &&
@@ -130,7 +150,7 @@ qemuSetupImageCgroupInternal(virDomainObjPtr vm,
 qemuSetupImagePathCgroup(vm, QEMU_DEVICE_MAPPER_CONTROL_PATH, false) < 
0)
 return -1;
 
-return qemuSetupImagePathCgroup(vm, src->path, src->readonly || 
forceReadonly);
+return qemuSetupImagePathCgroup(vm, path, readonly);
 }
 
 
@@ -147,7 +167,10 @@ qemuTeardownImageCgroup(virDomainObjPtr vm,
 virStorageSourcePtr src)
 {
 qemuDomainObjPrivatePtr priv = vm->privateData;
+VIR_AUTOFREE(char *path) = NULL;
 int perms = VIR_CGROUP_DEVICE_RWM;
+bool hasPR = false;
+bool hasNVMe = false;
 size_t i;
 int ret;
 
@@ -155,41 +178,61 @@ qemuTeardownImageCgroup(virDomainObjPtr vm,
 VIR_CGROUP_CONTROLLER_DEVICES))
 return 0;
 
-if (!src->path || !virStorageSourceIsLocalStorage(src)) {
-VIR_DEBUG("Not updating cgroups for disk path '%s', type: %s",
-  NULLSTR(src->path), virStorageTypeToString(src->type));
-return 0;
+for (i = 0; i < vm->def->ndisks; i++) {
+virStorageSourcePtr diskSrc = vm->def->disks[i]->src;
+
+if (src == diskSrc)
+continue;
+
+if (virStoragePRDefIsManaged(diskSrc->pr))
+hasPR = true;
+
+if (virStorageSourceChainHasNVMe(diskSrc))
+hasNVMe = true;
 }
 
-if (virFileExists(QEMU_DEVICE_MAPPER_CONTROL_PATH)) {
-for (i = 0; i < vm->def->ndisks; i++) {
-virStorageSourcePtr diskSrc = vm->def->disks[i]->src;
+if (src->type == VIR_STORAGE_TYPE_NVME) {
+if (!(path = virPCIDeviceAddressGetIOMMUGroupDev(>nvme->pciAddr)))
+return -1;
 
-if (src == diskSrc)
-continue;
-
-if (virStoragePRDefIsManaged(diskSrc->pr))
-break;
-}
-
-if (i == vm->def->ndisks) {
-VIR_DEBUG("Disabling device mapper control");
-ret = virCgroupDenyDevicePath(priv->cgroup,
-  QEMU_DEVICE_MAPPER_CONTROL_PATH,
-  perms, true);
+if (!hasNVMe &&
+!qemuDomainNeedsVFIO(vm->def)) {
+ret = virCgroupDenyDevicePath(priv->cgroup, QEMU_DEV_VFIO, perms, 
true);
 virDomainAuditCgroupPath(vm, priv->cgroup, "deny",
- QEMU_DEVICE_MAPPER_CONTROL_PATH,
+ QEMU_DEV_VFIO,
  virCgroupGetDevicePermsString(perms), 
ret);
 if (ret < 0)
-return ret;
+return -1;
 }
+} else {
+if (!src->path || !virStorageSourceIsLocalStorage(src)) {
+VIR_DEBUG("Not updating cgroups for disk path '%s', type: %s",
+  NULLSTR(src->path), virStorageTypeToString(src->type));
+return 0;
+}
+
+if (VIR_STRDUP(path, src->path) < 0)
+

[libvirt] [PATCH v2 33/39] qemu_capabilities: Introduce QEMU_CAPS_DRIVE_NVME

2019-09-26 Thread Michal Privoznik
This capability tracks if qemu is capable of:

  -drive file.driver=nvme

The feature was added in QEMU's commit of v2.12.0-rc0~104^2~2.

Signed-off-by: Michal Privoznik 
---
 src/qemu/qemu_capabilities.c   | 4 
 src/qemu/qemu_capabilities.h   | 3 +++
 tests/qemucapabilitiesdata/caps_2.12.0.aarch64.xml | 1 +
 tests/qemucapabilitiesdata/caps_2.12.0.ppc64.xml   | 1 +
 tests/qemucapabilitiesdata/caps_2.12.0.s390x.xml   | 1 +
 tests/qemucapabilitiesdata/caps_2.12.0.x86_64.xml  | 1 +
 tests/qemucapabilitiesdata/caps_3.0.0.ppc64.xml| 1 +
 tests/qemucapabilitiesdata/caps_3.0.0.riscv32.xml  | 1 +
 tests/qemucapabilitiesdata/caps_3.0.0.riscv64.xml  | 1 +
 tests/qemucapabilitiesdata/caps_3.0.0.s390x.xml| 1 +
 tests/qemucapabilitiesdata/caps_3.0.0.x86_64.xml   | 1 +
 tests/qemucapabilitiesdata/caps_3.1.0.ppc64.xml| 1 +
 tests/qemucapabilitiesdata/caps_3.1.0.x86_64.xml   | 1 +
 tests/qemucapabilitiesdata/caps_4.0.0.aarch64.xml  | 1 +
 tests/qemucapabilitiesdata/caps_4.0.0.ppc64.xml| 1 +
 tests/qemucapabilitiesdata/caps_4.0.0.riscv32.xml  | 1 +
 tests/qemucapabilitiesdata/caps_4.0.0.riscv64.xml  | 1 +
 tests/qemucapabilitiesdata/caps_4.0.0.s390x.xml| 1 +
 tests/qemucapabilitiesdata/caps_4.0.0.x86_64.xml   | 1 +
 tests/qemucapabilitiesdata/caps_4.1.0.x86_64.xml   | 1 +
 20 files changed, 25 insertions(+)

diff --git a/src/qemu/qemu_capabilities.c b/src/qemu/qemu_capabilities.c
index 72e070e8ab..17ee5e48c8 100644
--- a/src/qemu/qemu_capabilities.c
+++ b/src/qemu/qemu_capabilities.c
@@ -540,6 +540,9 @@ VIR_ENUM_IMPL(virQEMUCaps,
   "dbus-vmstate",
   "vhost-user-gpu",
   "vhost-user-vga",
+
+  /* 340 */
+  "drive-nvme",
 );
 
 
@@ -1287,6 +1290,7 @@ static struct virQEMUCapsStringFlags 
virQEMUCapsQMPSchemaQueries[] = {
 { "query-display-options/ret-type/+egl-headless/rendernode", 
QEMU_CAPS_EGL_HEADLESS_RENDERNODE },
 { "nbd-server-add/arg-type/bitmap", QEMU_CAPS_NBD_BITMAP },
 { "blockdev-add/arg-type/+file/drop-cache", 
QEMU_CAPS_MIGRATION_FILE_DROP_CACHE },
+{ "blockdev-add/arg-type/+nvme", QEMU_CAPS_DRIVE_NVME },
 };
 
 typedef struct _virQEMUCapsObjectTypeProps virQEMUCapsObjectTypeProps;
diff --git a/src/qemu/qemu_capabilities.h b/src/qemu/qemu_capabilities.h
index 137b7161a5..5b6e7174d1 100644
--- a/src/qemu/qemu_capabilities.h
+++ b/src/qemu/qemu_capabilities.h
@@ -522,6 +522,9 @@ typedef enum { /* virQEMUCapsFlags grouping marker for 
syntax-check */
 QEMU_CAPS_DEVICE_VHOST_USER_GPU, /* -device vhost-user-gpu */
 QEMU_CAPS_DEVICE_VHOST_USER_VGA, /* -device vhost-user-vga */
 
+/* 340 */
+QEMU_CAPS_DRIVE_NVME, /* -drive file.driver=nvme */
+
 QEMU_CAPS_LAST /* this must always be the last item */
 } virQEMUCapsFlags;
 
diff --git a/tests/qemucapabilitiesdata/caps_2.12.0.aarch64.xml 
b/tests/qemucapabilitiesdata/caps_2.12.0.aarch64.xml
index 614fd14fb1..ec6479de2a 100644
--- a/tests/qemucapabilitiesdata/caps_2.12.0.aarch64.xml
+++ b/tests/qemucapabilitiesdata/caps_2.12.0.aarch64.xml
@@ -153,6 +153,7 @@
   
   
   
+  
   2012000
   0
   61700807
diff --git a/tests/qemucapabilitiesdata/caps_2.12.0.ppc64.xml 
b/tests/qemucapabilitiesdata/caps_2.12.0.ppc64.xml
index fd9ae0bcb8..d4ed7cea49 100644
--- a/tests/qemucapabilitiesdata/caps_2.12.0.ppc64.xml
+++ b/tests/qemucapabilitiesdata/caps_2.12.0.ppc64.xml
@@ -151,6 +151,7 @@
   
   
   
+  
   2011090
   0
   42900807
diff --git a/tests/qemucapabilitiesdata/caps_2.12.0.s390x.xml 
b/tests/qemucapabilitiesdata/caps_2.12.0.s390x.xml
index 2930381068..91aee9f838 100644
--- a/tests/qemucapabilitiesdata/caps_2.12.0.s390x.xml
+++ b/tests/qemucapabilitiesdata/caps_2.12.0.s390x.xml
@@ -121,6 +121,7 @@
   
   
   
+  
   2012000
   0
   39100807
diff --git a/tests/qemucapabilitiesdata/caps_2.12.0.x86_64.xml 
b/tests/qemucapabilitiesdata/caps_2.12.0.x86_64.xml
index 61b3602c48..96fa7c43c9 100644
--- a/tests/qemucapabilitiesdata/caps_2.12.0.x86_64.xml
+++ b/tests/qemucapabilitiesdata/caps_2.12.0.x86_64.xml
@@ -195,6 +195,7 @@
   
   
   
+  
   2011090
   0
   43100807
diff --git a/tests/qemucapabilitiesdata/caps_3.0.0.ppc64.xml 
b/tests/qemucapabilitiesdata/caps_3.0.0.ppc64.xml
index 61be1df782..7b7d101ee9 100644
--- a/tests/qemucapabilitiesdata/caps_3.0.0.ppc64.xml
+++ b/tests/qemucapabilitiesdata/caps_3.0.0.ppc64.xml
@@ -152,6 +152,7 @@
   
   
   
+  
   2012050
   0
   42900757
diff --git a/tests/qemucapabilitiesdata/caps_3.0.0.riscv32.xml 
b/tests/qemucapabilitiesdata/caps_3.0.0.riscv32.xml
index 865becc179..d50789711a 100644
--- a/tests/qemucapabilitiesdata/caps_3.0.0.riscv32.xml
+++ b/tests/qemucapabilitiesdata/caps_3.0.0.riscv32.xml
@@ -92,6 +92,7 @@
   
   
   
+  
   300
   0
   0
diff --git a/tests/qemucapabilitiesdata/caps_3.0.0.riscv64.xml 
b/tests/qemucapabilitiesdata/caps_3.0.0.riscv64.xml
index eb54aeaff3..06a2e98b90 100644
--- a/tests/qemucapabilitiesdata/caps_3.0.0.riscv64.xml
+++ 

[libvirt] [PATCH v2 31/39] security_selinux: Simplify virSecuritySELinuxSetImageLabelInternal

2019-09-26 Thread Michal Privoznik
This function calls virSecuritySELinuxSetFilecon() or
virSecuritySELinuxSetFileconOptional() from a lot of places.
It works, because in all places we're passing src->path which is
what we wanted. But not anymore. We will want to be able to pass
a different path and thus the function must be reworked a bit.

Signed-off-by: Michal Privoznik 
ACKed-by: Peter Krempa 
---
 src/security/security_selinux.c | 34 -
 1 file changed, 12 insertions(+), 22 deletions(-)

diff --git a/src/security/security_selinux.c b/src/security/security_selinux.c
index e879fa39ab..3a00666d26 100644
--- a/src/security/security_selinux.c
+++ b/src/security/security_selinux.c
@@ -1823,7 +1823,9 @@ 
virSecuritySELinuxSetImageLabelInternal(virSecurityManagerPtr mgr,
 virSecurityDeviceLabelDefPtr disk_seclabel;
 virSecurityDeviceLabelDefPtr parent_seclabel = NULL;
 bool remember;
-int ret;
+const char *path = src->path;
+const char *tcon = NULL;
+int ret = -1;
 
 if (!src->path || !virStorageSourceIsLocalStorage(src))
 return 0;
@@ -1856,40 +1858,28 @@ 
virSecuritySELinuxSetImageLabelInternal(virSecurityManagerPtr mgr,
 if (!disk_seclabel->relabel)
 return 0;
 
-ret = virSecuritySELinuxSetFilecon(mgr, src->path,
-   disk_seclabel->label, remember);
+tcon = disk_seclabel->label;
 } else if (parent_seclabel && (!parent_seclabel->relabel || 
parent_seclabel->label)) {
 if (!parent_seclabel->relabel)
 return 0;
 
-ret = virSecuritySELinuxSetFilecon(mgr, src->path,
-   parent_seclabel->label, remember);
+tcon = parent_seclabel->label;
 } else if (!parent || parent == src) {
 if (src->shared) {
-ret = virSecuritySELinuxSetFilecon(mgr,
-   src->path,
-   data->file_context,
-   remember);
+tcon = data->file_context;
 } else if (src->readonly) {
-ret = virSecuritySELinuxSetFilecon(mgr,
-   src->path,
-   data->content_context,
-   remember);
+tcon = data->content_context;
 } else if (secdef->imagelabel) {
-ret = virSecuritySELinuxSetFilecon(mgr,
-   src->path,
-   secdef->imagelabel,
-   remember);
+tcon = secdef->imagelabel;
 } else {
-ret = 0;
+return 0;
 }
 } else {
-ret = virSecuritySELinuxSetFilecon(mgr,
-   src->path,
-   data->content_context,
-   remember);
+tcon = data->content_context;
 }
 
+ret = virSecuritySELinuxSetFilecon(mgr, path, tcon, remember);
+
 if (ret == 1 && !disk_seclabel) {
 /* If we failed to set a label, but virt_use_nfs let us
  * proceed anyway, then we don't need to relabel later.  */
-- 
2.21.0

--
libvir-list mailing list
libvir-list@redhat.com
https://www.redhat.com/mailman/listinfo/libvir-list


[libvirt] [PATCH v2 38/39] qemu_hotplug: Prepare NVMe disks on hotplug

2019-09-26 Thread Michal Privoznik
Signed-off-by: Michal Privoznik 
---
 src/qemu/qemu_domain.c  | 58 +
 src/qemu/qemu_hostdev.c | 22 
 src/qemu/qemu_hostdev.h |  6 +
 3 files changed, 86 insertions(+)

diff --git a/src/qemu/qemu_domain.c b/src/qemu/qemu_domain.c
index 3fe0004cab..cb94840d5f 100644
--- a/src/qemu/qemu_domain.c
+++ b/src/qemu/qemu_domain.c
@@ -10537,6 +10537,54 @@ typedef enum {
 } qemuDomainStorageSourceAccessFlags;
 
 
+static int
+qemuDomainStorageSourceAccessModifyNVMe(virQEMUDriverPtr driver,
+virDomainObjPtr vm,
+virStorageSourcePtr src,
+bool revoke)
+{
+bool revoke_maxmemlock = false;
+bool revoke_hostdev = false;
+int ret = -1;
+
+if (!virStorageSourceChainHasNVMe(src))
+return 0;
+
+VIR_DEBUG("Modifying access for a NVMe disk src=%p revoke=%d",
+  src, revoke);
+
+if (revoke) {
+revoke_maxmemlock = true;
+revoke_hostdev = true;
+ret = 0;
+goto revoke;
+}
+
+if (qemuDomainAdjustMaxMemLock(vm, true) < 0)
+goto revoke;
+
+revoke_maxmemlock = true;
+
+if (qemuHostdevPrepareOneNVMeDisk(driver, vm->def->name, src) < 0)
+goto revoke;
+
+revoke_hostdev = true;
+
+return 0;
+
+ revoke:
+if (revoke_maxmemlock) {
+if (qemuDomainAdjustMaxMemLock(vm, false) < 0)
+VIR_WARN("Unable to change max memlock limit");
+}
+
+if (revoke_hostdev)
+qemuHostdevReAttachOneNVMeDisk(driver, vm->def->name, src);
+
+return ret;
+}
+
+
 /**
  * qemuDomainStorageSourceAccessModify:
  * @driver: qemu driver struct
@@ -10568,6 +10616,7 @@ qemuDomainStorageSourceAccessModify(virQEMUDriverPtr 
driver,
 bool revoke_cgroup = false;
 bool revoke_label = false;
 bool revoke_namespace = false;
+bool revoke_nvme = false;
 bool revoke_lockspace = false;
 
 VIR_DEBUG("src='%s' readonly=%d force_ro=%d force_rw=%d revoke=%d 
chain=%d",
@@ -10585,6 +10634,7 @@ qemuDomainStorageSourceAccessModify(virQEMUDriverPtr 
driver,
 revoke_cgroup = true;
 revoke_label = true;
 revoke_namespace = true;
+revoke_nvme = true;
 revoke_lockspace = true;
 ret = 0;
 goto revoke;
@@ -10595,6 +10645,11 @@ qemuDomainStorageSourceAccessModify(virQEMUDriverPtr 
driver,
 
 revoke_lockspace = true;
 
+if (qemuDomainStorageSourceAccessModifyNVMe(driver, vm, src, false) < 0)
+goto revoke;
+
+revoke_nvme = true;
+
 /* When modifying access of existing @src namespace does not need update */
 if (!(flags & QEMU_DOMAIN_STORAGE_SOURCE_ACCESS_MODIFY_ACCESS)) {
 if (qemuDomainNamespaceSetupDisk(vm, src) < 0)
@@ -10645,6 +10700,9 @@ qemuDomainStorageSourceAccessModify(virQEMUDriverPtr 
driver,
 VIR_WARN("Unable to remove /dev entry for %s", srcstr);
 }
 
+if (revoke_nvme)
+qemuDomainStorageSourceAccessModifyNVMe(driver, vm, src, true);
+
 if (revoke_lockspace) {
 if (virDomainLockImageDetach(driver->lockManager, vm, src) < 0)
 VIR_WARN("Unable to release lock on %s", srcstr);
diff --git a/src/qemu/qemu_hostdev.c b/src/qemu/qemu_hostdev.c
index 5ab0217858..6ab052724a 100644
--- a/src/qemu/qemu_hostdev.c
+++ b/src/qemu/qemu_hostdev.c
@@ -212,6 +212,17 @@ 
qemuHostdevPreparePCIDevicesCheckSupport(virDomainHostdevDefPtr *hostdevs,
 return true;
 }
 
+int
+qemuHostdevPrepareOneNVMeDisk(virQEMUDriverPtr driver,
+  const char *name,
+  virStorageSourcePtr src)
+{
+return virHostdevPrepareOneNVMeDevice(driver->hostdevMgr,
+  QEMU_DRIVER_NAME,
+  name,
+  src);
+}
+
 int
 qemuHostdevPrepareNVMeDisks(virQEMUDriverPtr driver,
 const char *name,
@@ -369,6 +380,17 @@ qemuHostdevPrepareDomainDevices(virQEMUDriverPtr driver,
 return 0;
 }
 
+void
+qemuHostdevReAttachOneNVMeDisk(virQEMUDriverPtr driver,
+   const char *name,
+   virStorageSourcePtr src)
+{
+virHostdevReAttachOneNVMeDevice(driver->hostdevMgr,
+QEMU_DRIVER_NAME,
+name,
+src);
+}
+
 void
 qemuHostdevReAttachNVMeDisks(virQEMUDriverPtr driver,
  const char *name,
diff --git a/src/qemu/qemu_hostdev.h b/src/qemu/qemu_hostdev.h
index 735414b6aa..23df925529 100644
--- a/src/qemu/qemu_hostdev.h
+++ b/src/qemu/qemu_hostdev.h
@@ -41,6 +41,9 @@ int qemuHostdevUpdateActiveSCSIDevices(virQEMUDriverPtr 
driver,
 int qemuHostdevUpdateActiveDomainDevices(virQEMUDriverPtr driver,
  virDomainDefPtr def);
 
+int 

[libvirt] [PATCH v2 35/39] qemu_monitor_text: Catch IOMMU/VFIO related errors in qemuMonitorTextAddDrive

2019-09-26 Thread Michal Privoznik
Because this is a HMP we're dealing with, there is nothing like
class of reply message, so we have to do some string comparison
to guess if the command fails. Well, with NVMe disks whole new
class of errors comes to play because qemu needs to initialize
IOMMU and VFIO for them. You can see all the messages it may
produce in qemu_vfio_init_pci().

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

diff --git a/src/qemu/qemu_monitor_text.c b/src/qemu/qemu_monitor_text.c
index b1abcacdd0..39445247a0 100644
--- a/src/qemu/qemu_monitor_text.c
+++ b/src/qemu/qemu_monitor_text.c
@@ -76,6 +76,13 @@ int qemuMonitorTextAddDrive(qemuMonitorPtr mon,
 goto cleanup;
 }
 
+if (strstr(reply, "IOMMU") ||
+strstr(reply, "VFIO")) {
+virReportError(VIR_ERR_OPERATION_FAILED, "%s",
+   reply);
+goto cleanup;
+}
+
 ret = 0;
 
  cleanup:
-- 
2.21.0

--
libvir-list mailing list
libvir-list@redhat.com
https://www.redhat.com/mailman/listinfo/libvir-list


  1   2   >