[libvirt] libvirt-2.0.0 build error (hidden symbol libvirt_event_poll_update_handle_semaphore)

2017-06-22 Thread longguang.yue
Hi, all:
i back port a patch which make qemu depends on util directory.
so i correct its dependency  by applying a patch.  but another error occur.
the patch is :
--- libvirt-2.0.0/src/Makefile.am   2016-06-27 22:12:20.523191076 +0800
+++ libvirt-2.0.0-ok/src/Makefile.am2017-06-22 12:25:17.51200 +0800
@@ -1362,6 +1362,7 @@
-I$(srcdir)/access \
-I$(srcdir)/conf \
-I$(srcdir)/secret \
+   -I$(srcdir)/util \
$(AM_CFLAGS)
 libvirt_driver_qemu_impl_la_LDFLAGS = $(AM_LDFLAGS)
 libvirt_driver_qemu_impl_la_LIBADD = $(CAPNG_LIBS) \
@@ -1369,6 +1370,7 @@
$(LIBNL_LIBS) \
$(LIBXML_LIBS) \
libvirt_secret.la \
+   libvirt_util.la \
$(NULL)
 libvirt_driver_qemu_impl_la_SOURCES = $(QEMU_DRIVER_SOURCES)






-


BUILD ERROR:


  CCLD qemucapsprobe
/bin/ld: .libs/qemucapsprobe: hidden symbol 
`libvirt_event_poll_update_handle_semaphore' in ../src/libvirt_probes.o is 
referenced by DSO
/bin/ld: final link failed: Bad value
collect2: error: ld returned 1 exit status
make[1]: *** [qemucapsprobe] Error 1
make[1]: Leaving directory `/root/libvirt-2.0/BUILD/libvirt-2.0.0/tests'
make: *** [check-am] Error 2
+ cat test-suite.log
cat: test-suite.log: No such file or directory
+ true
+ exit 1
error: Bad exit status from /var/tmp/rpm-tmp.ZVbGSv (%check)




RPM build errors:
Bad exit status from /var/tmp/rpm-tmp.ZVbGSv (%check) 


-




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

Re: [libvirt] [PATCH RFC 1/2] Resctrl: Add new xml element to support cache tune

2017-06-22 Thread Eli Qiao


On Thursday, 22 June 2017 at 8:41 PM, Martin Kletzander wrote:

> I missed this. Ye, you're right, thanks for showing that with a use
> case. We could then require only the cache_id and automatically fill
> in level and type. Migration (or rather any start) should then fail if
> that cache_id doesn't correspond to the level and type requested. I
> still can't find a reason for 'id', though.

I agree that id, level is useless, but also type is required, the case is when
host’s enabled CDP like this:

  


  


the cachetune need to be defined as:







Thought?

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

[libvirt] [PATCH] leasetime support for

2017-06-22 Thread aruiz
From: Alberto Ruiz 

Fixes #913446

This patch addresses a few problems found by the initial reviews:

* leaseTimeUnit RNG type renamed to timeUnit
* virNetworkDHCPDefGetLeaseTime() renamed to virNetworkDHCPLeaseTimeParseXML()
* consistent use of braces in if-else-if
* use %lu instead of PRId64
* use 0 as infinite lease
* add a leasetime_defined field to struct _virNetworkIPDef to describe whether 
the value was set in the xml configuration or not
* use uint32_t for the leasetime instead of int64_t
* fail on all invalid leasetime values
* squash all patches into one

---
 docs/schemas/basictypes.rng|  16 +++
 docs/schemas/network.rng   |   8 ++
 src/conf/network_conf.c|  93 +++-
 src/conf/network_conf.h|   5 +-
 src/libvirt_private.syms   |   1 +
 src/network/bridge_driver.c| 119 -
 src/network/bridge_driver.h|   1 +
 src/util/virdnsmasq.c  | 106 +++---
 src/util/virdnsmasq.h  |   2 +
 .../dhcp6-nat-network.hostsfile|   7 ++
 tests/networkxml2confdata/dhcp6-network.hostsfile  |   5 +
 .../dhcp6host-routed-network.hostsfile |   7 ++
 tests/networkxml2confdata/leasetime-days.conf  |  18 
 tests/networkxml2confdata/leasetime-days.xml   |  18 
 tests/networkxml2confdata/leasetime-hours.conf |  18 
 tests/networkxml2confdata/leasetime-hours.xml  |  18 
 tests/networkxml2confdata/leasetime-infinite.conf  |  18 
 tests/networkxml2confdata/leasetime-infinite.xml   |  18 
 tests/networkxml2confdata/leasetime-minutes.conf   |  18 
 tests/networkxml2confdata/leasetime-minutes.xml|  18 
 tests/networkxml2confdata/leasetime-seconds.conf   |  18 
 tests/networkxml2confdata/leasetime-seconds.xml|  18 
 tests/networkxml2confdata/leasetime.conf   |  18 
 tests/networkxml2confdata/leasetime.xml|  18 
 .../nat-network-dns-srv-record-minimal.hostsfile   |   2 +
 .../nat-network-dns-srv-record.hostsfile   |   2 +
 .../nat-network-dns-txt-record.hostsfile   |   2 +
 .../nat-network-name-with-quotes.hostsfile |   2 +
 tests/networkxml2confdata/nat-network.hostsfile|   2 +
 .../networkxml2confdata/ptr-domains-auto.hostsfile |   2 +
 tests/networkxml2conftest.c|  45 ++--
 31 files changed, 571 insertions(+), 72 deletions(-)
 create mode 100644 tests/networkxml2confdata/dhcp6-nat-network.hostsfile
 create mode 100644 tests/networkxml2confdata/dhcp6-network.hostsfile
 create mode 100644 tests/networkxml2confdata/dhcp6host-routed-network.hostsfile
 create mode 100644 tests/networkxml2confdata/leasetime-days.conf
 create mode 100644 tests/networkxml2confdata/leasetime-days.xml
 create mode 100644 tests/networkxml2confdata/leasetime-hours.conf
 create mode 100644 tests/networkxml2confdata/leasetime-hours.xml
 create mode 100644 tests/networkxml2confdata/leasetime-infinite.conf
 create mode 100644 tests/networkxml2confdata/leasetime-infinite.xml
 create mode 100644 tests/networkxml2confdata/leasetime-minutes.conf
 create mode 100644 tests/networkxml2confdata/leasetime-minutes.xml
 create mode 100644 tests/networkxml2confdata/leasetime-seconds.conf
 create mode 100644 tests/networkxml2confdata/leasetime-seconds.xml
 create mode 100644 tests/networkxml2confdata/leasetime.conf
 create mode 100644 tests/networkxml2confdata/leasetime.xml
 create mode 100644 
tests/networkxml2confdata/nat-network-dns-srv-record-minimal.hostsfile
 create mode 100644 
tests/networkxml2confdata/nat-network-dns-srv-record.hostsfile
 create mode 100644 
tests/networkxml2confdata/nat-network-dns-txt-record.hostsfile
 create mode 100644 
tests/networkxml2confdata/nat-network-name-with-quotes.hostsfile
 create mode 100644 tests/networkxml2confdata/nat-network.hostsfile
 create mode 100644 tests/networkxml2confdata/ptr-domains-auto.hostsfile

diff --git a/docs/schemas/basictypes.rng b/docs/schemas/basictypes.rng
index 1ea667cdf..9db19c7f0 100644
--- a/docs/schemas/basictypes.rng
+++ b/docs/schemas/basictypes.rng
@@ -564,4 +564,20 @@
 
   
 
+  
+
+  seconds
+  minutes
+  hours
+  days
+
+  
+
+  
+
+  -1
+  4294967295
+
+  
+
 
diff --git a/docs/schemas/network.rng b/docs/schemas/network.rng
index 1048dabf3..a0d878e4a 100644
--- a/docs/schemas/network.rng
+++ b/docs/schemas/network.rng
@@ -357,6 +357,14 @@
 
 
+
+  
+
+  
+
+
+  
+
   
 
   
diff --git a/src/conf/network_conf.c b/src/conf/network_conf.c
index 3ebf67ff5..8431ee806 

Re: [libvirt] [PATCH 1/3] leasetime support for globally

2017-06-22 Thread Alberto Ruiz
2017-06-22 21:47 GMT+01:00 Laine Stump :
> On 06/22/2017 12:21 PM, Alberto Ruiz wrote:
>> Hello Laine,
>>
>> 2017-06-21 17:30 GMT+01:00 Laine Stump > >:
>>
>> On 06/21/2017 03:27 AM, Peter Krempa wrote:
>> > On Tue, Jun 20, 2017 at 19:00:43 +0100, ar...@gnome.org 
>>  wrote:
>> >> From: Alberto Ruiz >
>> >
>> > Missing commit message.
>>
>> And when composing the commit message, it's useful to include links to
>> the associated BZ.
>>
>>   https://bugzilla.redhat.com/show_bug.cgi?id=913446
>> 
>>
>> Also, I recall there being quite a lot of discussion in email (and
>> possibly IRC) about the fact that people *think* they want a
>> configurable lease time because they think that will eliminate cases of
>> a DHCP lease being lost while a domain is paused. It was pointed out
>> that lengthening the lease will *not* eliminate that problem (it just
>> makes it happen less often).
>>
>> As an alternate (and better) solution to the problem of lost leases, we
>> then added the "dhcp-authoritative" option to dnsmasq (commit
>> 4ac20b3ae4), which allows clients to re-acquire the same IP as they had
>> for an expired lease (as long as it hasn't been acquired by someone else
>> in the meantime, which is apparently unlikely unless all the other
>> addresses in the pool are already assigned).
>>
>> I'm not saying this to discourage the idea of making leasetime
>> configurable (I think we'd already agreed that it was reasonable to do
>> so, but there were two competing patches posted, and neither of them was
>> really push-ready), but just to make sure that nobody is disappointed if
>> the results don't lead to the behavior they're hoping for.
>>
>>
>> My main motivation _was_ the loss of IP addresses after reboot on GNOME
>> Boxes.
>>
>> However, given that I've written the patches already and some people
>> might find this useful, I'm okay with going ahead and get them ready for
>> approval.
>>
>>
>> >
>> >>
>> >> ---
>> >>  docs/schemas/basictypes.rng   | 16 +
>> >>  docs/schemas/network.rng  |  8 +++
>> >>  src/conf/network_conf.c   | 78
>> ++-
>> >>  src/conf/network_conf.h   |  3 +-
>> >>  src/network/bridge_driver.c   | 49
>> +-
>> >>  tests/networkxml2confdata/leasetime-days.conf | 17 +
>> >>  tests/networkxml2confdata/leasetime-days.xml  | 18 ++
>> >>  tests/networkxml2confdata/leasetime-hours.conf| 17 +
>> >>  tests/networkxml2confdata/leasetime-hours.xml | 18 ++
>> >>  tests/networkxml2confdata/leasetime-infinite.conf | 17 +
>> >>  tests/networkxml2confdata/leasetime-infinite.xml  | 18 ++
>> >>  tests/networkxml2confdata/leasetime-minutes.conf  | 17 +
>> >>  tests/networkxml2confdata/leasetime-minutes.xml   | 18 ++
>> >>  tests/networkxml2confdata/leasetime-seconds.conf  | 17 +
>> >>  tests/networkxml2confdata/leasetime-seconds.xml   | 18 ++
>> >>  tests/networkxml2confdata/leasetime.conf  | 17 +
>> >>  tests/networkxml2confdata/leasetime.xml   | 18 ++
>> >>  tests/networkxml2conftest.c   |  7 ++
>> >>  18 files changed, 368 insertions(+), 3 deletions(-)
>> >>  create mode 100644 tests/networkxml2confdata/leasetime-days.conf
>> >>  create mode 100644 tests/networkxml2confdata/leasetime-days.xml
>> >>  create mode 100644 tests/networkxml2confdata/leasetime-hours.conf
>> >>  create mode 100644 tests/networkxml2confdata/leasetime-hours.xml
>> >>  create mode 100644 tests/networkxml2confdata/leasetime-infinite.conf
>> >>  create mode 100644 tests/networkxml2confdata/leasetime-infinite.xml
>> >>  create mode 100644 tests/networkxml2confdata/leasetime-minutes.conf
>> >>  create mode 100644 tests/networkxml2confdata/leasetime-minutes.xml
>> >>  create mode 100644 tests/networkxml2confdata/leasetime-seconds.conf
>> >>  create mode 100644 tests/networkxml2confdata/leasetime-seconds.xml
>> >>  create mode 100644 tests/networkxml2confdata/leasetime.conf
>> >>  create mode 100644 tests/networkxml2confdata/leasetime.xml
>> >>
>> >> diff --git a/docs/schemas/basictypes.rng
>> b/docs/schemas/basictypes.rng
>> >> index 1b4f980e7..8a76c235a 100644
>> >> --- a/docs/schemas/basictypes.rng
>> >> +++ b/docs/schemas/basictypes.rng
>> >> @@ -518,4 +518,20 @@
>> >>  
>> >>
>> >>
>> >> +  
>> >> +
>> >> +  seconds
>> >> +  minutes
>> >> +  hours
>> >> +  days
>> >> +
>> >> 

Re: [libvirt] [PATCH 1/3] leasetime support for globally

2017-06-22 Thread Alberto Ruiz
2017-06-22 22:05 GMT+01:00 Laine Stump :
>
> On 06/22/2017 01:12 PM, Alberto Ruiz wrote:
> >
> >
> > 2017-06-21 17:30 GMT+01:00 Laine Stump  > >:
> >
> > On 06/21/2017 03:27 AM, Peter Krempa wrote:
> > > On Tue, Jun 20, 2017 at 19:00:43 +0100, ar...@gnome.org 
> >  wrote:
> > >> From: Alberto Ruiz >
> > >
> > >> +
> > >> +if (result > UINT32_MAX) {
> > >> +virReportError(VIR_ERR_XML_ERROR,
> > >> +   _(" value cannot be greater than 
> > the equivalent of %" PRIo32 " seconds : %" PRId64),
> >
> > We don't use gnulib's "PRIxxx" macros anywhere else in libvirt. Better
> > to "go with the flow" and just use "%d" instead for consistency (or make
> > a case for changing them elsewhere :-)
>
> (Is it possible for you to change the "quotation" character in your
> email client so that when you inline quote the original in a reply, it
> has "> " at the beginning of the line rather than " "? Using blanks
> as the quotation character makes it more likely to confuse who wrote
> which parts (especially when everything isn't starting in column 1))

I'll try to reply using plain text (using gmail here)

> > I knew I added this for something:
> >
> > This is the error I get when I just use "%d":
> >
> > conf/network_conf.c: In function 'virNetworkDHCPLeaseTimeParseXML':
> > conf/network_conf.c:575:26: error: format '%d' expects argument of type
> > 'int', but argument 8 has type 'int64_t {aka long int}' [-Werror=format=]
> > _(" value cannot be greater than the
> > equivalent of %d seconds : %d"),
> >
> > If you can think of any alternative that complies with libvirt's code
> > consistency let me know.
>
> Looking through the other struct definitions that are filled in from
> XML, we don't use any types that directly specify the number of bits.
> Instead we use int, long, and long long (sometimes with unsigned,
> sometimes without).
>
> On x86_64, long and long long are both 64 bits. I think I would just use
> "unsigned long" (assuming you agree to not use "-1" as a special value),
> then use %lu for the formatting string.

I'm actually switching to use uint32_t so %lu should work now, will
give it a try.

-- 
Cheers,
Alberto Ruiz

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


Re: [libvirt] [PATCH] util: Force reading of meta data to get encryption capacity value

2017-06-22 Thread John Ferlan
ping?

Tks,

John

(too bad this missed an internal RHEL deadline... )


On 06/15/2017 03:31 PM, John Ferlan wrote:
> https://bugzilla.redhat.com/show_bug.cgi?id=1371892
> 
> As it turns out the volume create, build, and refresh path was not peeking
> at the meta data, so immediately after a create operation the value displayed
> for capacity was still incorrect. However, if a pool refresh was done the
> correct value was fetched as a result of a meta data peek.
> 
> The reason is it seems historically if the file type is RAW then peeking
> at the file just took the physical value for the capacity. However, since
> we know if it's an encrypted file, then peeking at the meta data will be
> required in order to get a true capacity value.
> 
> So check for encryption in the source and if present, use the meta data
> in order to fill in the capacity value and set the payload_offset.
> 
> Signed-off-by: John Ferlan 
> ---
>  src/util/virstoragefile.c | 11 +++
>  1 file changed, 7 insertions(+), 4 deletions(-)
> 
> diff --git a/src/util/virstoragefile.c b/src/util/virstoragefile.c
> index e82a7fb..11c3625 100644
> --- a/src/util/virstoragefile.c
> +++ b/src/util/virstoragefile.c
> @@ -3446,13 +3446,16 @@ virStorageSourceUpdateCapacity(virStorageSourcePtr 
> src,
>  src->format = format;
>  }
>  
> -if (format == VIR_STORAGE_FILE_RAW)
> +if (format == VIR_STORAGE_FILE_RAW && !src->encryption) {
>  src->capacity = src->physical;
> -else if ((meta = virStorageFileGetMetadataFromBuf(src->path, buf,
> -  len, format, NULL)))
> +} else if ((meta = virStorageFileGetMetadataFromBuf(src->path, buf,
> +len, format, NULL))) 
> {
>  src->capacity = meta->capacity ? meta->capacity : src->physical;
> -else
> +if (src->encryption && meta->encryption)
> +src->encryption->payload_offset = 
> meta->encryption->payload_offset;
> +} else {
>  goto cleanup;
> +}
>  
>  if (src->encryption && src->encryption->payload_offset != -1)
>  src->capacity -= src->encryption->payload_offset * 512;
> 

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


Re: [libvirt] [PATCH 0/8] More virsecretobj changes to prepare for common object

2017-06-22 Thread John Ferlan

ping^2 ?

Tks,

John

Would help especially since I could post more for the recently posted
virObject adjustment...

On 06/14/2017 09:29 PM, John Ferlan wrote:
> ping?
> 
> A bit involved, but encompasses a few things I have found or made more
> common in other vir*obj's
> 
> Tks,
> 
> John
> 
> On 06/03/2017 09:27 AM, John Ferlan wrote:
>> A couple I forgot from earlier series, but a few things found since then
>> along with some clarifications to make the ObjAdd processing a bit more
>> like I've found for nwfilter, nodedev, and interface as well as making
>> the ObjListRemove processing a bit clearer and more consistent.
>>
>> Along with the other series and the virObject v2 adjustments - this brings
>> everything close enough to start sending the patches that will tie all this
>> stuff together to create/use a common object model.
>>
>>
>> John Ferlan (8):
>>   secret: Whitespace modification for secret_driver
>>   secret: Alter FindByUUID to expect the formatted uuidstr
>>   secret: Rename variable in virSecretObjListAdd
>>   secret: Clean up virSecretObjListAdd processing
>>   secret: Remove need for local configFile and base64File in ObjectAdd
>>   secret: Have virSecretObjNew consume newdef
>>   secret: Properly handle @def after virSecretObjAdd in driver
>>   secret: Handle object list removal and deletion properly
>>
>>  src/conf/virsecretobj.c| 125 
>> +
>>  src/conf/virsecretobj.h|   2 +-
>>  src/secret/secret_driver.c |  50 --
>>  3 files changed, 94 insertions(+), 83 deletions(-)
>>
> 
> --
> libvir-list mailing list
> libvir-list@redhat.com
> https://www.redhat.com/mailman/listinfo/libvir-list
> 

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


Re: [libvirt] [PATCH v4] virsh: add [--domain DOMAIN] option to domxml-to-native DOMAIN COMMAND

2017-06-22 Thread John Ferlan

[...]


>>>
>>> There was no change, it is an additional variable, the original one is
>>> below.  The number of differences would be the same, I believe.
>>>
>>
>> If edit the file and change "xml" to "xmlFile" and change the 3 changed
>> xml variable references things work... Like I said, nit, IDC if it's
>> changed or not...
>>
> 
> My bad, I misread that, you're right.

In order to "close" on this, if a squash the attach patch does that work
for everyone?

John
>From a37d80c22f2ac1f89e45d3178f16ec964de9f960 Mon Sep 17 00:00:00 2001
From: John Ferlan 
Date: Thu, 22 Jun 2017 18:20:37 -0400
Subject: [PATCH] merge?

Signed-off-by: John Ferlan 
---
 tools/virsh-domain.c | 10 +-
 tools/virsh.pod  | 17 +++--
 2 files changed, 16 insertions(+), 11 deletions(-)

diff --git a/tools/virsh-domain.c b/tools/virsh-domain.c
index 7b46987..5311a57 100644
--- a/tools/virsh-domain.c
+++ b/tools/virsh-domain.c
@@ -9873,15 +9873,15 @@ cmdDomXMLToNative(vshControl *ctl, const vshCmd *cmd)
 {
 bool ret = false;
 const char *format = NULL;
-const char *xml = NULL;
-char *xmlData = NULL;
+const char *xmlFile = NULL;
 char *configData = NULL;
+char *xmlData = NULL;
 unsigned int flags = 0;
 virshControlPtr priv = ctl->privData;
 virDomainPtr dom = NULL;
 
 if (vshCommandOptStringReq(ctl, cmd, "format", ) < 0 ||
-vshCommandOptStringReq(ctl, cmd, "xml", ) < 0)
+vshCommandOptStringReq(ctl, cmd, "xml", ) < 0)
 return false;
 
 VSH_EXCLUSIVE_OPTIONS("domain", "xml");
@@ -9892,8 +9892,8 @@ cmdDomXMLToNative(vshControl *ctl, const vshCmd *cmd)
 
 if (dom) {
 xmlData = virDomainGetXMLDesc(dom, flags);
-} else if (xml) {
-if (virFileReadAll(xml, VSH_MAX_XML_FILE, ) < 0)
+} else if (xmlFile) {
+if (virFileReadAll(xmlFile, VSH_MAX_XML_FILE, ) < 0)
 goto cleanup;
 } else {
 vshError(ctl, "%s", _("need either domain or domain XML"));
diff --git a/tools/virsh.pod b/tools/virsh.pod
index d77b336..43d6f0c 100644
--- a/tools/virsh.pod
+++ b/tools/virsh.pod
@@ -1441,13 +1441,18 @@ I argument may be B, B, or B. For
 LXC hypervisor, the I argument must be B.
 
 =item B I
-{ I<--domain> I | [I<--xml>] I }
+{ [I<--xml>] I | I<--domain> I }
 
-Convert the file I in domain XML format or existing domain to the
-native guest configuration format named by I. For QEMU/KVM hypervisor,
-the I argument must be B. For Xen hypervisor, the
-I argument may be B, B, or B. For
-LXC hypervisor, the I argument must be B.
+Convert the file I into domain XML format or convert an existing
+I<--domain> to the native guest configuration format named by I.
+The I and I<--domain> arguments are mutually exclusive.
+
+For the QEMU/KVM hypervisor, the I argument must be B.
+
+For the Xen hypervisor, the I argument may be B, B,
+or B.
+
+For the LXC hypervisor, the I argument must be B.
 
 =item B I I [I<--bypass-cache>]
 { [I<--live>] | [I<--crash>] | [I<--reset>] } [I<--verbose>] [I<--memory-only>]
-- 
2.9.4

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

[libvirt] [PATCH] events: Avoid double free possibility on remote call failure

2017-06-22 Thread John Ferlan
If a remote call fails during event registration (more than likely from
a network failure or remote libvirtd restart timed just right), then when
calling the virObjectEventStateDeregisterID we don't want to call the
registered @freecb function because that breaks our contract that we
would only call it after succesfully returning.  If the @freecb routine
were called, it could result in a double free from properly coded
applications that free their opaque data on failure to register, as seen
in the following details:

Program terminated with signal 6, Aborted.
#0  0x7fc45cba15d7 in raise
#1  0x7fc45cba2cc8 in abort
#2  0x7fc45cbe12f7 in __libc_message
#3  0x7fc45cbe86d3 in _int_free
#4  0x7fc45d8d292c in PyDict_Fini
#5  0x7fc45d94f46a in Py_Finalize
#6  0x7fc45d960735 in Py_Main
#7  0x7fc45cb8daf5 in __libc_start_main
#8  0x00400721 in _start

The double dereference of 'pyobj_cbData' is triggered in the following way:

(1) libvirt_virConnectDomainEventRegisterAny is invoked.
(2) the event is successfully added to the event callback list
(virDomainEventStateRegisterClient in
remoteConnectDomainEventRegisterAny returns 1 which means ok).
(3) when function remoteConnectDomainEventRegisterAny is hit,
network connection disconnected coincidently (or libvirtd is
restarted) in the context of function 'call' then the connection
is lost and the function 'call' failed, the branch
virObjectEventStateDeregisterID is therefore taken.
(4) 'pyobj_conn' is dereferenced the 1st time in
libvirt_virConnectDomainEventFreeFunc.
(5) 'pyobj_cbData' (refered to pyobj_conn) is dereferenced the
 2nd time in libvirt_virConnectDomainEventRegisterAny.
(6) the double free error is triggered.

Resolve this by adding an @inhibitFreeCb boolean in order to avoid calling
freecb in virObjectEventStateDeregisterID for any remote call failure in
a remoteConnect*EventRegister* API. For remoteConnect*EventDeregister* calls,
the passed value would be false indicating they should run the freecb if it
exists.

Patch based on the investigation and initial patch posted by:
fangying .

Signed-off-by: John Ferlan 
---
  Initial patch found at:

  https://www.redhat.com/archives/libvir-list/2017-June/msg00039.html

  based on feedback from Daniel Berrange to a previous posting:

  https://www.redhat.com/archives/libvir-list/2017-May/msg01089.html

  Since no new patch was posted, I posted my idea from review for
  consideration.

 src/bhyve/bhyve_driver.c |  2 +-
 src/conf/domain_event.c  |  2 +-
 src/conf/object_event.c  | 23 +--
 src/conf/object_event.h  |  3 ++-
 src/libxl/libxl_driver.c |  2 +-
 src/lxc/lxc_driver.c |  2 +-
 src/network/bridge_driver.c  |  2 +-
 src/node_device/node_device_driver.c |  2 +-
 src/qemu/qemu_driver.c   |  4 ++--
 src/remote/remote_driver.c   | 32 
 src/secret/secret_driver.c   |  2 +-
 src/storage/storage_driver.c |  2 +-
 src/test/test_driver.c   |  8 
 src/uml/uml_driver.c |  2 +-
 src/vz/vz_driver.c   |  2 +-
 src/xen/xen_driver.c |  2 +-
 16 files changed, 52 insertions(+), 40 deletions(-)

diff --git a/src/bhyve/bhyve_driver.c b/src/bhyve/bhyve_driver.c
index ed2221a..6722dc4 100644
--- a/src/bhyve/bhyve_driver.c
+++ b/src/bhyve/bhyve_driver.c
@@ -1503,7 +1503,7 @@ bhyveConnectDomainEventDeregisterAny(virConnectPtr conn,
 
 if (virObjectEventStateDeregisterID(conn,
 privconn->domainEventState,
-callbackID) < 0)
+callbackID, false) < 0)
 return -1;
 
 return 0;
diff --git a/src/conf/domain_event.c b/src/conf/domain_event.c
index 6e471d7..ff4c602 100644
--- a/src/conf/domain_event.c
+++ b/src/conf/domain_event.c
@@ -2301,7 +2301,7 @@ virDomainEventStateDeregister(virConnectPtr conn,
NULL);
 if (callbackID < 0)
 return -1;
-return virObjectEventStateDeregisterID(conn, state, callbackID);
+return virObjectEventStateDeregisterID(conn, state, callbackID, false);
 }
 
 
diff --git a/src/conf/object_event.c b/src/conf/object_event.c
index e5f942f..5e944af 100644
--- a/src/conf/object_event.c
+++ b/src/conf/object_event.c
@@ -234,13 +234,15 @@ virObjectEventCallbackListCount(virConnectPtr conn,
  * @conn: pointer to the connection
  * @cbList: the list
  * @callback: the callback to remove
+ * @inhibitFreeCb: Inhibit calling the freecb
  *
  * Internal function to remove a callback from a virObjectEventCallbackListPtr
  */
 static int
 

Re: [libvirt] RFC: Creating mediated devices with libvirt

2017-06-22 Thread John Ferlan


On 06/14/2017 06:06 PM, Erik Skultety wrote:
> Hi all,
> 
> so there's been an off-list discussion about finally implementing creation of
> mediated devices with libvirt and it's more than desired to get as many 
> opinions
> on that as possible, so please do share your ideas. This did come up already 
> as
> part of some older threads ([1] for example), so this will be a respin of the
> discussions. Long story short, we decided to put device creation off and focus
> on the introduction of the framework as such first and build upon that later,
> i.e. now.
> 
> [1] https://www.redhat.com/archives/libvir-list/2017-February/msg00177.html
> 
> 
> PART 1: NODEDEV-DRIVER
> 
> 
> API-wise, device creation through the nodedev driver should be pretty
> straightforward and without any issues, since virNodeDevCreateXML takes an XML
> and does support flags. Looking at the current device XML:
> 
> 
>   mdev_0cce8709_0640_46ef_bd14_962c7f73cc6f
>   
> /sys/devices/pci:00/.../0cce8709-0640-46ef-bd14-962c7f73cc6f
>   pci__03_00_0
>   
> vfio_mdev
>   
>   
> 
> 
> UUID 
>   
> 
> 
> We can ignore ,, elements, since these are useless
> during creation. We also cannot use  since we don't support arbitrary
> names and we also can't rely on users providing a name in correct form which 
> we
> would need to further parse in order to get the UUID.
> So since the only thing missing to successfully use create an mdev using XML 
> is
> the UUID (if user doesn't want it to be generated automatically), how about
> having a  subelement under  just like PCIs have  and
> friends, USBs have  & , interfaces have  to uniquely
> identify the device even if the name itself is unique.
> Removal of a device should work as well, although we might want to
> consider creating a *Flags version of the API.


Has any thought been put towards creating an mdev pool modeled after the
Storage Pool? Similar to how vHBA's are created from a Storage Pool XML
definition.

That way XML could be defined to keep track of a lot of different things
that you may need and would require only starting the pool in order to
access.

Placed "appropriately" - the mdev's could already be available by the
time node device state initialization occurs too since the pool would
conceivably been created/defined using data from the physical device and
the calls to create the virtual devices would have occurred. Much easier
to add logic to a new driver/pool mgmt to handle whatever considerations
there are than adding logic into the existing node device driver.

Of course if there's only ever going to be a 1-to-1 relationship between
whatever the mdev parent is and an mdev child, then it's probably
overkill to go with a pool model; however, I was under the impression
that an mdev parent could have many mdev children with various different
configuration options depending on multiple factors.

Thus:


  Happy
  UUID
  

...
  
...


where the parent is then "found" in node device via "mdev_%s",  XML that would define specific
"formats" that could be used and made active/inactive. A bit different
than  XML which is output only based on what's found in the
storage pool source.

My recollection of the whole frame work is not up to par with the latest
information, but I recall there being multiple different ways to have
"something" defined that could then be used by the guest based on one
parent mdev. What those things are were a combination of what the mdev
could support and there could be 1 or many depending on the resultant vGPU.

Maybe we need a virtual white board to help describe the things ;-)

If you wait long enough or perhaps if review pace would pick up, maybe
creating a new driver and vir*obj infrastructure will be easier with a
common virObject instance. Oh and this has a "uuid" and "name" for
searches, so fits nicely.

> 
> =
> PART 2: DOMAIN XML & DEVICE AUTO-CREATION, NO POLICY INVOLVED!
> =
> 
> There were some doubts about auto-creation mentioned in [1], although they
> weren't specified further. So hopefully, we'll get further in the discussion
> this time.
> 
>>From my perspective there are two main reasons/benefits to that:
> 
> 1) Convenience
> For apps like virt-manager, user will want to add a host device transparently,
> "hey libvirt, I want an mdev assigned to my VM, can you do that". Even for
> higher management apps, like oVirt, even they might not care about the parent
> device at all times and considering that they would need to enumerate the
> parents, pick one, create the device XML and pass it to the nodedev driver, 
> IMHO
> it would actually be easier and faster to just do it directly through sysfs,
> bypassing libvirt once again

Using "pool" methodology borrows on existing storage technology except
applying it to 

Re: [libvirt] [PATCH 1/3] leasetime support for globally

2017-06-22 Thread Laine Stump
On 06/22/2017 01:12 PM, Alberto Ruiz wrote:
> 
> 
> 2017-06-21 17:30 GMT+01:00 Laine Stump  >:
> 
> On 06/21/2017 03:27 AM, Peter Krempa wrote:
> > On Tue, Jun 20, 2017 at 19:00:43 +0100, ar...@gnome.org 
>  wrote:
> >> From: Alberto Ruiz >
> >
> >> +
> >> +if (result > UINT32_MAX) {
> >> +virReportError(VIR_ERR_XML_ERROR,
> >> +   _(" value cannot be greater than 
> the equivalent of %" PRIo32 " seconds : %" PRId64),
> 
> We don't use gnulib's "PRIxxx" macros anywhere else in libvirt. Better
> to "go with the flow" and just use "%d" instead for consistency (or make
> a case for changing them elsewhere :-)

(Is it possible for you to change the "quotation" character in your
email client so that when you inline quote the original in a reply, it
has "> " at the beginning of the line rather than " "? Using blanks
as the quotation character makes it more likely to confuse who wrote
which parts (especially when everything isn't starting in column 1))

> 
> 
> I knew I added this for something:
> 
> This is the error I get when I just use "%d":
> 
> conf/network_conf.c: In function 'virNetworkDHCPLeaseTimeParseXML':
> conf/network_conf.c:575:26: error: format '%d' expects argument of type
> 'int', but argument 8 has type 'int64_t {aka long int}' [-Werror=format=]
> _(" value cannot be greater than the
> equivalent of %d seconds : %d"),
> 
> If you can think of any alternative that complies with libvirt's code
> consistency let me know.

Looking through the other struct definitions that are filled in from
XML, we don't use any types that directly specify the number of bits.
Instead we use int, long, and long long (sometimes with unsigned,
sometimes without).

On x86_64, long and long long are both 64 bits. I think I would just use
"unsigned long" (assuming you agree to not use "-1" as a special value),
then use %lu for the formatting string.

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


Re: [libvirt] RFC: Creating mediated devices with libvirt

2017-06-22 Thread John Ferlan


On 06/22/2017 11:52 AM, Pavel Hrdina wrote:
> On Thu, Jun 22, 2017 at 09:28:57AM -0600, Alex Williamson wrote:
>> On Thu, 22 Jun 2017 17:14:48 +0200
>> Erik Skultety  wrote:
>>
>>> [...]
>
> ^this is the thing we constantly keep discussing as everyone has a 
> slightly
> different angle of view - libvirt does not implement any kind of policy,
> therefore the only "configuration" would be the PCI parent placement - 
> you say
> what to do and we do it, no logic in it, that's it. Now, I don't 
> understand
> taking care of the guesswork for the user in the simplest manner possible 
> as
> policy rather as a mere convenience, be it just for developers and 
> testers, but
> even that might apparently be perceived as a policy and therefore 
> unacceptable.
>
> I still stand by idea of having auto-creation as unfortunately, I sort of 
> still
> fail to understand what the negative implications of having it are - is 
> that it
> would get just unnecessarily too complex to maintain in the future that 
> we would
> regret it or that we'd get a huge amount of follow-up requests for 
> extending the
> feature or is it just that simply the interpretation of auto-create == 
> policy?  

 The increasing complexity of the qemu driver is a significant concern with
 adding policy based logic to the code. THinking about this though, if we
 provide the inactive node device feature, then we can avoid essentially
 all new code and complexity QEMU driver, and still support auto-create.

 ie, in the domain XML we just continue to have the exact same XML that
 we already have today for mdevs, but with a single new attribute
 autocreate=yes|no

   
 >>> autocreate="yes">
 
 
>>>
>>> So, just for clarification of the concept, the device with ^this UUID will 
>>> have
>>> had to be defined by the nodedev API by the time we start to edit the domain
>>> XML in this manner in which case the only thing the autocreate=yes would do 
>>> is
>>> to actually create the mdev according to the nodedev config, right? 
>>> Continuing
>>> with that thought, if UUID doesn't refer to any of the inactive configs it 
>>> will
>>> be an error I suppose? What about the fact that only one vgpu type can live 
>>> on
>>> the GPU? even if you can successfully identify a device using the UUID in 
>>> this
>>> way, you'll still face the problem, that other types might be currently
>>> occupying the GPU and need to be torn down first, will this be automated as
>>> well in what you suggest? I assume not.
>>>
 
 
   

 In the QEMU driver, then the only change required is

if (def->autocreate)
virNodeDeviceCreate(dev)  
>>>
>>> Aha, so if a device gets torn down on shutdown, we won't face the problem 
>>> with
>>> some other devices being active, all of them will have to be in the inactive
>>> state because they got torn down during the last shutdown - that would work.
>>
>>
>> I'm not familiar with how inactive devices would be defined in the
>> nodedev API, would someone mind explaining or providing an example
>> please?  I don't understand where the metadata is stored that describes
>> the what and where of a given UUID.  Thanks,
> 
> It would basically copy what we do for domains.  Currently there is
> virNodeDeviceCreateXML() which takes the XML definitions and creates a
> new active node device and virNodeDeviceDestroy() which takes as
> argument an object of existing active node device.

FWIW: (Just in case someone doesn't know yet...) The only current
CreateXML consumer is for NPIV/vHBA devices. As I've pointed out before
I see a lot of similarities w/ mdev because they both have a dependency
on "something else" in order for proper creation. NPIV/vHBA requires an
HBA (scsi_hostN) that has a sysfs structure with a vport_create function
to create the vHBA. The HBA scsi_hostN is instantiated during
udevEnumerateDevices processing while the vHBA scsi_hostM is created
during udevEventHandleCallback.

The CreateXML provides an essentially 'transient' model to describe
a(the) vHBA device(s). After host reboot, one would have to run virsh
nodedev-create file.xml in order to recreate their vHBA.

In order to create more permanent vHBA's, it's possible to define a
storage pool that would create the vHBA when the storage pool is
started. So while there's no DefineXML support, there is a model that
does provide a mechanism to have persistence without needing to have a
DefineXML for node devices.

> 
> We would extend the functionality with new APIs:
> 
>   - virNodeDeviceCreate() which would take as argument an object of
> existing inactive node device.
> 
>   - virNodeDeviceDefineXML() would define the node device as inactive.
> 
> With the virNodeDeviceDefineXML() you would create a list of predefined
> inactive 

Re: [libvirt] [PATCH v3 0/2] Adding locale support for virStrToDouble().

2017-06-22 Thread Julio Faracco
Twos question related to this topic:
1. Is virstringtest missing some important tests from virstring.c? I'm
not seeing vir{StrToDouble|DoubleToStr}...
2. Should locale be considered during the test phase too?

2017-06-22 8:23 GMT-03:00 Martin Kletzander :
> On Thu, Jun 22, 2017 at 01:12:44PM +0200, Peter Krempa wrote:
>>
>> On Thu, Jun 22, 2017 at 11:30:06 +0200, Martin Kletzander wrote:
>>>
>>> On Wed, Jun 21, 2017 at 02:08:27PM -0300, Julio Faracco wrote:
>>> > The commits add locale support for virStrToDouble() due to differences
>>> > between
>>> > the mantissa separator in different languages. For example, kernel
>>> > always uses
>>> > dot to separate mantissa. An user who is using pt_BR locale (for
>>> > example) uses
>>> > comma as a separator. So, this user will have problems to parse a
>>> > kernel
>>> > settings using strtod() function.
>>> >
>>> > One of commits move the virDoubleToStr() to virstring.* to share locale
>>> > global variables. Joining the two functions makes more sense.
>>> >
>>>
>>> Reviewed-by: Martin Kletzander 
>>>
>>> I'll push it in a minute.  Thanks for the patches and patience!
>>
>>
>> Since this broke build and will require fixing. I'd prefer that the
>> code to set and revert the locale will be wrapped into a function rather
>> than scattering conditionally compiled code through the code base.
>
>
> I'm working on that, but either we need more functions to add
> conditionally, or just remove the conditionally compiled code from just
> one of those two functions.  I'll post a fix in a while that fixes and
> cleans up more stuff, so we'll see and can talk on that patch.

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


Re: [libvirt] [PATCH 1/3] leasetime support for globally

2017-06-22 Thread Laine Stump
On 06/22/2017 12:21 PM, Alberto Ruiz wrote:
> Hello Laine,
> 
> 2017-06-21 17:30 GMT+01:00 Laine Stump  >:
> 
> On 06/21/2017 03:27 AM, Peter Krempa wrote:
> > On Tue, Jun 20, 2017 at 19:00:43 +0100, ar...@gnome.org 
>  wrote:
> >> From: Alberto Ruiz >
> >
> > Missing commit message.
> 
> And when composing the commit message, it's useful to include links to
> the associated BZ.
> 
>   https://bugzilla.redhat.com/show_bug.cgi?id=913446
> 
> 
> Also, I recall there being quite a lot of discussion in email (and
> possibly IRC) about the fact that people *think* they want a
> configurable lease time because they think that will eliminate cases of
> a DHCP lease being lost while a domain is paused. It was pointed out
> that lengthening the lease will *not* eliminate that problem (it just
> makes it happen less often).
> 
> As an alternate (and better) solution to the problem of lost leases, we
> then added the "dhcp-authoritative" option to dnsmasq (commit
> 4ac20b3ae4), which allows clients to re-acquire the same IP as they had
> for an expired lease (as long as it hasn't been acquired by someone else
> in the meantime, which is apparently unlikely unless all the other
> addresses in the pool are already assigned).
> 
> I'm not saying this to discourage the idea of making leasetime
> configurable (I think we'd already agreed that it was reasonable to do
> so, but there were two competing patches posted, and neither of them was
> really push-ready), but just to make sure that nobody is disappointed if
> the results don't lead to the behavior they're hoping for.
> 
> 
> My main motivation _was_ the loss of IP addresses after reboot on GNOME
> Boxes.
> 
> However, given that I've written the patches already and some people
> might find this useful, I'm okay with going ahead and get them ready for
> approval.
>  
> 
> >
> >>
> >> ---
> >>  docs/schemas/basictypes.rng   | 16 +
> >>  docs/schemas/network.rng  |  8 +++
> >>  src/conf/network_conf.c   | 78
> ++-
> >>  src/conf/network_conf.h   |  3 +-
> >>  src/network/bridge_driver.c   | 49
> +-
> >>  tests/networkxml2confdata/leasetime-days.conf | 17 +
> >>  tests/networkxml2confdata/leasetime-days.xml  | 18 ++
> >>  tests/networkxml2confdata/leasetime-hours.conf| 17 +
> >>  tests/networkxml2confdata/leasetime-hours.xml | 18 ++
> >>  tests/networkxml2confdata/leasetime-infinite.conf | 17 +
> >>  tests/networkxml2confdata/leasetime-infinite.xml  | 18 ++
> >>  tests/networkxml2confdata/leasetime-minutes.conf  | 17 +
> >>  tests/networkxml2confdata/leasetime-minutes.xml   | 18 ++
> >>  tests/networkxml2confdata/leasetime-seconds.conf  | 17 +
> >>  tests/networkxml2confdata/leasetime-seconds.xml   | 18 ++
> >>  tests/networkxml2confdata/leasetime.conf  | 17 +
> >>  tests/networkxml2confdata/leasetime.xml   | 18 ++
> >>  tests/networkxml2conftest.c   |  7 ++
> >>  18 files changed, 368 insertions(+), 3 deletions(-)
> >>  create mode 100644 tests/networkxml2confdata/leasetime-days.conf
> >>  create mode 100644 tests/networkxml2confdata/leasetime-days.xml
> >>  create mode 100644 tests/networkxml2confdata/leasetime-hours.conf
> >>  create mode 100644 tests/networkxml2confdata/leasetime-hours.xml
> >>  create mode 100644 tests/networkxml2confdata/leasetime-infinite.conf
> >>  create mode 100644 tests/networkxml2confdata/leasetime-infinite.xml
> >>  create mode 100644 tests/networkxml2confdata/leasetime-minutes.conf
> >>  create mode 100644 tests/networkxml2confdata/leasetime-minutes.xml
> >>  create mode 100644 tests/networkxml2confdata/leasetime-seconds.conf
> >>  create mode 100644 tests/networkxml2confdata/leasetime-seconds.xml
> >>  create mode 100644 tests/networkxml2confdata/leasetime.conf
> >>  create mode 100644 tests/networkxml2confdata/leasetime.xml
> >>
> >> diff --git a/docs/schemas/basictypes.rng
> b/docs/schemas/basictypes.rng
> >> index 1b4f980e7..8a76c235a 100644
> >> --- a/docs/schemas/basictypes.rng
> >> +++ b/docs/schemas/basictypes.rng
> >> @@ -518,4 +518,20 @@
> >>  
> >>
> >>
> >> +  
> >> +
> >> +  seconds
> >> +  minutes
> >> +  hours
> >> +  days
> >> +
> >> +  
> 
> Maybe call this "timeUnit" in case some other attribute in the future
> needs it?
> 
> 
> sounds good to me. noted
>  
> 
> 
> 

Re: [libvirt] [PATCH v2] qemu: Remove duplicated code in qemuBuildSerialChrDeviceStr()

2017-06-22 Thread Laine Stump
On 06/22/2017 06:08 AM, Andrea Bolognani wrote:
> The call to qemuBuildDeviceAddressStr() happens no matter
> what, so we can move it to the outer possible scope inside
> the function.
> 
> We can also move the call to virBufferAsprintf() after all
> the checks have been performed, where it makes more sense.
> 
> Signed-off-by: Andrea Bolognani 
> ---
>  src/qemu/qemu_command.c | 22 +++---
>  1 file changed, 7 insertions(+), 15 deletions(-)
> 
> diff --git a/src/qemu/qemu_command.c b/src/qemu/qemu_command.c
> index c53ab97..5118541 100644
> --- a/src/qemu/qemu_command.c
> +++ b/src/qemu/qemu_command.c
> @@ -10292,14 +10292,8 @@ qemuBuildSerialChrDeviceStr(char **deviceStr,
>  serial->info.type == VIR_DOMAIN_DEVICE_ADDRESS_TYPE_SPAPRVIO) {
>  virBufferAsprintf(, "spapr-vty,chardev=char%s",
>serial->info.alias);
> -if (qemuBuildDeviceAddressStr(, def, >info, 
> qemuCaps) < 0)
> -goto error;
>  }
>  } else {
> -virBufferAsprintf(, "%s,chardev=char%s,id=%s",
> -  
> virDomainChrSerialTargetTypeToString(serial->targetType),
> -  serial->info.alias, serial->info.alias);
> -
>  switch (serial->targetType) {
>  case VIR_DOMAIN_CHR_SERIAL_TARGET_TYPE_USB:
>  if (!virQEMUCapsGet(qemuCaps, QEMU_CAPS_DEVICE_USB_SERIAL)) {
> @@ -10314,9 +10308,6 @@ qemuBuildSerialChrDeviceStr(char **deviceStr,
> _("usb-serial requires address of usb type"));
>  goto error;
>  }
> -
> -if (qemuBuildDeviceAddressStr(, def, >info, 
> qemuCaps) < 0)
> -goto error;
>  break;
>  
>  case VIR_DOMAIN_CHR_SERIAL_TARGET_TYPE_ISA:
> @@ -10326,9 +10317,6 @@ qemuBuildSerialChrDeviceStr(char **deviceStr,
> _("isa-serial requires address of isa type"));
>  goto error;
>  }
> -
> -if (qemuBuildDeviceAddressStr(, def, >info, 
> qemuCaps) < 0)
> -goto error;
>  break;
>  
>  case VIR_DOMAIN_CHR_SERIAL_TARGET_TYPE_PCI:
> @@ -10344,13 +10332,17 @@ qemuBuildSerialChrDeviceStr(char **deviceStr,
> _("pci-serial requires address of pci type"));
>  goto error;
>  }
> -
> -if (qemuBuildDeviceAddressStr(, def, >info, 
> qemuCaps) < 0)
> -goto error;
>  break;
>  }
> +
> +virBufferAsprintf(, "%s,chardev=char%s,id=%s",
> +  
> virDomainChrSerialTargetTypeToString(serial->targetType),
> +  serial->info.alias, serial->info.alias);
>  }
>  
> +if (qemuBuildDeviceAddressStr(, def, >info, qemuCaps) < 0)
> +goto error;
> +

I haven't looked at the caller of qemuBuildSerialChrDeviceStr() with a
fine-toothed comb, but this patch does change the code a bit. In
particular, previously if qemuDomainIsPSeries(def) was true, but either
one of these was false:

 serial->deviceType == VIR_DOMAIN_CHR_DEVICE_TYPE_SERIAL
 serial->info.type == VIR_DOMAIN_DEVICE_ADDRESS_TYPE_SPAPRVIO

then it would return an empty string in *deviceStr. But now it will
instead return an address string, without the
"spapr-vty,chardev=charBLAH" at the beginning. So can we guarantee that
the above two conditions are always true for PSeries?

I guess in both the "before" and "after" cases, the result would be a
failure (with before, we would end up with a "-device" with nothing
following it, and now we would have "-device" with an address string but
none of the preceding stuff describing the address).

(Similarly, before this patch, if serial->targetType wasn't one of
VIR_DOMAIN_CHR_SERIAL_TARGET_TYPE(USB|ISA|PCI) then *deviceStr would
contain "(null),chardev=charBLAH,id=BLAH" with no address, but now it
will have an address as well as the nonsensical preamble. (yes, I'm
being ridiculous in this case :-P))

In the end, ACK to your patch  since you haven't made the behavior any
worse (and have eliminated a bunch of duplicated code, but I do think
that either the checks on deviceType and info.type should be removed as
pointless, or that they should trigger a failure directly rather than
just creating a bad commandline.

>  if (virBufferCheckError() < 0)
>  goto error;
>  
> 

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


[libvirt] [libvirt-php PATCH 1/7] move macros to header file.

2017-06-22 Thread Dawid Zamirski
So that PHP version handling wrappers are all in one place
---
 src/libvirt-php.c | 88 ---
 src/libvirt-php.h | 79 +
 2 files changed, 79 insertions(+), 88 deletions(-)

diff --git a/src/libvirt-php.c b/src/libvirt-php.c
index c2ab0da..ece98d6 100644
--- a/src/libvirt-php.c
+++ b/src/libvirt-php.c
@@ -45,94 +45,6 @@ const char *features[] = { NULL };
 const char *features_binaries[] = { NULL };
 #endif
 
-#if PHP_MAJOR_VERSION >= 7
-typedef size_t strsize_t;
-
-
-#define VIRT_FETCH_RESOURCE(_state, _type, _zval, _name, _le) \
-if ((_state = (_type)zend_fetch_resource(Z_RES_P(*_zval), _name, _le)) == 
NULL) { \
-RETURN_FALSE; \
-}
-
-#define VIRT_RETVAL_STRING(_str)\
-RETVAL_STRING(_str)
-#define VIRT_RETVAL_STRINGL(_str, _len) \
-RETVAL_STRINGL(_str, _len)
-#define VIRT_RETURN_STRING(_str)\
-RETURN_STRING(_str)
-#define VIRT_RETURN_STRINGL(_str, _len) \
-RETURN_STRINGL(_str, _len)
-#define VIRT_ZVAL_STRINGL(_zv, _str, _len)  \
-ZVAL_STRINGL(_zv, _str, _len)
-#define VIRT_ADD_INDEX_STRING(_arg, _idx, _str)  \
-add_index_string(_arg, _idx, _str)
-#define VIRT_ADD_NEXT_INDEX_STRING(_arg, _str)  \
-add_next_index_string(_arg, _str)
-#define VIRT_ADD_ASSOC_STRING(_arg, _key, _str) \
-add_assoc_string(_arg, _key, _str)
-#define VIRT_ADD_ASSOC_STRING_EX(_arg, _key, _key_len, _value) \
-add_assoc_string_ex(_arg, _key, _key_len, _value)
-
-#define VIRT_FOREACH(_ht, _pos, _zv) \
-for (zend_hash_internal_pointer_reset_ex(_ht, &_pos); \
- (_zv = zend_hash_get_current_data_ex(_ht, &_pos)) != NULL; \
- zend_hash_move_forward_ex(_ht, &_pos)) \
-
-#define VIRT_FOREACH_END(_dummy)
-
-#define VIRT_HASH_CURRENT_KEY_INFO(_ht, _pos, _idx, _info) \
-do { \
-zend_string *tmp_key_info; \
-_info.type = zend_hash_get_current_key_ex(_ht, _key_info, &_idx, 
&_pos); \
-_info.name = ZSTR_VAL(tmp_key_info); \
-_info.length = ZSTR_LEN(tmp_key_info); \
-} while(0)
-
-#else /* PHP_MAJOR_VERSION < 7 */
-typedef int strsize_t;
-typedef long zend_long;
-typedef unsigned long zend_ulong;
-
-#define VIRT_FETCH_RESOURCE(_state, _type, _zval, _name, _le) \
-ZEND_FETCH_RESOURCE(_state, _type, _zval, -1, _name, _le);
-
-#define VIRT_RETVAL_STRING(_str)\
-RETVAL_STRING(_str, 1)
-#define VIRT_RETVAL_STRINGL(_str, _len) \
-RETVAL_STRINGL(_str, _len, 1)
-#define VIRT_RETURN_STRING(_str)\
-RETURN_STRING(_str, 1)
-#define VIRT_RETURN_STRINGL(_str, _len) \
-RETURN_STRINGL(_str, _len, 1)
-#define VIRT_ZVAL_STRINGL(_zv, _str, _len)  \
-ZVAL_STRINGL(_zv, _str, _len, 1)
-#define VIRT_ADD_INDEX_STRING(_arg, _idx, _str)  \
-add_index_string(_arg, _idx, _str, 1)
-#define VIRT_ADD_NEXT_INDEX_STRING(_arg, _str)  \
-add_next_index_string(_arg, _str, 1)
-#define VIRT_ADD_ASSOC_STRING(_arg, _key, _str) \
-add_assoc_string(_arg, _key, _str, 1)
-#define VIRT_ADD_ASSOC_STRING_EX(_arg, _key, _key_len, _value) \
-add_assoc_string_ex(_arg, _key, _key_len, _value, 1)
-
-#define VIRT_FOREACH(_ht, _pos, _zv) \
-{ \
-zval **pzv = &_zv; \
-for (zend_hash_internal_pointer_reset_ex(_ht, &_pos); \
- zend_hash_get_current_data_ex(_ht, (void **) , &_pos) == SUCCESS; 
\
- zend_hash_move_forward_ex(_ht, &_pos)) { \
-_zv = *pzv;
-
-#define VIRT_FOREACH_END(_dummy) \
-}}
-
-#define VIRT_HASH_CURRENT_KEY_INFO(_ht, _pos, _idx, _info) \
-do { \
-_info.type = zend_hash_get_current_key_ex(_ht, &_info.name, &_info.length, 
&_idx, 0, &_pos); \
-} while(0)
-
-#endif /* PHP_MAJOR_VERSION < 7 */
-
 /* ZEND thread safe per request globals definition */
 int le_libvirt_connection;
 int le_libvirt_domain;
diff --git a/src/libvirt-php.h b/src/libvirt-php.h
index f9dec09..d25fa94 100644
--- a/src/libvirt-php.h
+++ b/src/libvirt-php.h
@@ -121,10 +121,89 @@ typedef uint64_t arch_uint;
 
 #if PHP_MAJOR_VERSION >= 7
 typedef size_t strsize_t;
+
+#define VIRT_FETCH_RESOURCE(_state, _type, _zval, _name, _le) \
+if ((_state = (_type)zend_fetch_resource(Z_RES_P(*_zval), _name, _le)) == 
NULL) { \
+RETURN_FALSE; \
+}
+
+#define VIRT_RETVAL_STRING(_str)\
+RETVAL_STRING(_str)
+#define VIRT_RETVAL_STRINGL(_str, _len) \
+RETVAL_STRINGL(_str, _len)
+#define VIRT_RETURN_STRING(_str)\
+RETURN_STRING(_str)
+#define VIRT_RETURN_STRINGL(_str, _len) \
+RETURN_STRINGL(_str, _len)
+#define VIRT_ZVAL_STRINGL(_zv, _str, _len)  \
+ZVAL_STRINGL(_zv, _str, _len)
+#define VIRT_ADD_INDEX_STRING(_arg, _idx, _str)  \
+add_index_string(_arg, _idx, _str)
+#define VIRT_ADD_NEXT_INDEX_STRING(_arg, _str)  \
+add_next_index_string(_arg, _str)
+#define VIRT_ADD_ASSOC_STRING(_arg, _key, _str) \
+add_assoc_string(_arg, _key, _str)
+#define VIRT_ADD_ASSOC_STRING_EX(_arg, _key, _key_len, _value) \
+add_assoc_string_ex(_arg, _key, _key_len, _value)
+
+#define VIRT_FOREACH(_ht, _pos, 

[libvirt] [libvirt-php PATCH 2/7] add wrappers for PHP resource handling.

2017-06-22 Thread Dawid Zamirski
There were quite a few places in code that were using preprocessor
directives to handle differences in dealing with resources between PHP
versions which can be dealt with by using typdefs and macros.
---
 src/libvirt-php.h | 27 +++
 1 file changed, 27 insertions(+)

diff --git a/src/libvirt-php.h b/src/libvirt-php.h
index d25fa94..0422661 100644
--- a/src/libvirt-php.h
+++ b/src/libvirt-php.h
@@ -121,6 +121,19 @@ typedef uint64_t arch_uint;
 
 #if PHP_MAJOR_VERSION >= 7
 typedef size_t strsize_t;
+typedef zend_resource virt_resource;
+
+#define VIRT_RETURN_RESOURCE(_resource) \
+RETVAL_RES(_resource)
+
+#define VIRT_REGISTER_RESOURCE(_resource, _le_resource)  \
+VIRT_RETURN_RESOURCE(zend_register_resource(_resource, _le_resource))
+
+#define VIRT_REGISTER_LIST_RESOURCE(_name) do { \
+zval zret; \
+ZVAL_RES(, zend_register_resource(res_##_name, le_libvirt_##_name)); \
+add_next_index_zval(return_value, ); \
+} while(0)
 
 #define VIRT_FETCH_RESOURCE(_state, _type, _zval, _name, _le) \
 if ((_state = (_type)zend_fetch_resource(Z_RES_P(*_zval), _name, _le)) == 
NULL) { \
@@ -165,6 +178,20 @@ typedef size_t strsize_t;
 typedef int strsize_t;
 typedef long zend_long;
 typedef unsigned long zend_ulong;
+typedef zend_rsrc_list_entry virt_resource;
+
+#define VIRT_RETURN_RESOURCE(_resource) \
+RETVAL_RESOURCE((long) _resource)
+
+#define VIRT_REGISTER_RESOURCE(_resource, _le_resource) \
+ZEND_REGISTER_RESOURCE(return_value, _resource, _le_resource)
+
+#define VIRT_REGISTER_LIST_RESOURCE(_name) do { \
+zval *zret; \
+ALLOC_INIT_ZVAL(zret); \
+ZEND_REGISTER_RESOURCE(zret, res_##_name, le_libvirt_##_name); \
+add_next_index_zval(return_value, zret); \
+} while(0)
 
 #define VIRT_FETCH_RESOURCE(_state, _type, _zval, _name, _le) \
 ZEND_FETCH_RESOURCE(_state, _type, _zval, -1, _name, _le);
-- 
2.13.0

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


[libvirt] [libvirt-php PATCH 0/7] add bindings for NWFilter APIs

2017-06-22 Thread Dawid Zamirski
Hello,

This series adds support for libvirt's virNWFilter* APIs. Since it
introduces new resource type, I took the opportunity to cleanup the
driver code a little:

* in patches 1-3: added macros to take care of the differences in how
  PHP5 and PHP7 handle resource types.
* in patch 4: libvirt_doman_get_connect was segfaulting when called
  multiple times because it was not bumping reference count on the
  resource it was returning to the calling code.
* in patch 5: added a macro to take care of the differences in how PHP5
  and PHP7 initialize arrays.
* patches 6 and 7: implement the missing binding to NWFilter APIs.


Dawid Zamirski (7):
  move macros to header file.
  add wrappers for PHP resource handling.
  update code to use resource handling macros
  fix libvirt_doman_get_connect implementation.
  add and use VIRT_ARRAY_INIT macro
  add nwfilter resource type
  implement NWFilter API bindings.

 src/libvirt-php.c | 923 +++---
 src/libvirt-php.h | 150 -
 2 files changed, 672 insertions(+), 401 deletions(-)

-- 
2.13.0

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


[libvirt] [libvirt-php PATCH 6/7] add nwfilter resource type

2017-06-22 Thread Dawid Zamirski
---
 src/libvirt-php.c | 61 +--
 src/libvirt-php.h |  7 +++
 2 files changed, 66 insertions(+), 2 deletions(-)

diff --git a/src/libvirt-php.c b/src/libvirt-php.c
index 7784450..535d321 100644
--- a/src/libvirt-php.c
+++ b/src/libvirt-php.c
@@ -54,6 +54,7 @@ int le_libvirt_network;
 int le_libvirt_nodedev;
 int le_libvirt_stream;
 int le_libvirt_snapshot;
+int le_libvirt_nwfilter;
 
 ZEND_BEGIN_ARG_INFO_EX(arginfo_libvirt_connect, 0, 0, 0)
 ZEND_ARG_INFO(0, url)
@@ -823,6 +824,8 @@ translate_counter_type(int type)
 return "storage volume";
 case INT_RESOURCE_SNAPSHOT:
 return "snapshot";
+case INT_RESOURCE_NWFILTER:
+return "nwfilter";
 }
 
 return "unknown";
@@ -1226,6 +1229,17 @@ void free_resource(int type, void *mem TSRMLS_DC)
 resource_change_counter(INT_RESOURCE_SNAPSHOT, NULL, 
(virDomainSnapshotPtr)mem, 0 TSRMLS_CC);
 }
 }
+
+if (type == INT_RESOURCE_NWFILTER) {
+rv = virNWFilterFree((virNWFilterPtr) mem);
+if (rv != 0) {
+DPRINTF("%s: virNWFilterFree(%p) returned %d (%s)\n", 
__FUNCTION__, (virNWFilterPtr) mem, rv, LIBVIRT_G(last_error));
+php_error_docref(NULL TSRMLS_CC, E_WARNING, "virDomainSnapshotFree 
failed with %i on destructor: %s", rv, LIBVIRT_G(last_error));
+} else {
+DPRINTF("%s: virNWFilterFree(%p) completed successfully\n", 
__FUNCTION__, (virNWFilterPtr) mem);
+resource_change_counter(INT_RESOURCE_NWFILTER, NULL, 
(virNWFilterPtr) mem, 0 TSRMLS_CC);
+}
+}
 }
 
 /*
@@ -1570,7 +1584,7 @@ static void php_libvirt_snapshot_dtor(virt_resource *rsrc 
TSRMLS_DC)
 rv = virDomainSnapshotFree(snapshot->snapshot);
 if (rv != 0) {
 DPRINTF("%s: virDomainSnapshotFree(%p) returned %d\n", 
__FUNCTION__, snapshot->snapshot, rv);
-php_error_docref(NULL TSRMLS_CC, E_WARNING, "virStorageVolFree 
failed with %i on destructor: %s", rv, LIBVIRT_G(last_error));
+php_error_docref(NULL TSRMLS_CC, E_WARNING, 
"virDomainSnapshotFree failed with %i on destructor: %s", rv, 
LIBVIRT_G(last_error));
 } else {
 DPRINTF("%s: virDomainSnapshotFree(%p) completed 
successfully\n", __FUNCTION__, snapshot->snapshot);
 resource_change_counter(INT_RESOURCE_SNAPSHOT, 
snapshot->domain->conn->conn, snapshot->snapshot, 0 TSRMLS_CC);
@@ -1581,6 +1595,34 @@ static void php_libvirt_snapshot_dtor(virt_resource 
*rsrc TSRMLS_DC)
 }
 }
 
+/* Destructor for nwfilter resource */
+static void php_libvirt_nwfilter_dtor(virt_resource *rsrc)
+{
+php_libvirt_nwfilter *nwfilter = (php_libvirt_nwfilter *) rsrc->ptr;
+int rv = 0;
+
+if (nwfilter != NULL) {
+if (nwfilter->nwfilter != NULL) {
+if (!check_resource_allocation(NULL, INT_RESOURCE_NWFILTER, 
nwfilter->nwfilter TSRMLS_CC)) {
+nwfilter->nwfilter = NULL;
+efree(nwfilter);
+
+return;
+}
+rv = virNWFilterFree(nwfilter->nwfilter);
+if (rv != 0) {
+DPRINTF("%s: virNWFilterFree(%p) returned %d\n", __FUNCTION__, 
nwfilter->nwfilter, rv);
+php_error_docref(NULL TSRMLS_CC, E_WARNING, "virNWFilterFree 
failed with %i on destructor: %s", rv, LIBVIRT_G(last_error));
+} else {
+DPRINTF("%s: virNWFilterFee(%p) completed successfully\n", 
__FUNCTION__, nwfilter->nwfilter);
+resource_change_counter(INT_RESOURCE_NWFILTER, 
nwfilter->conn->conn, nwfilter->nwfilter, 0 TSRMLS_CC);
+}
+nwfilter->nwfilter = NULL;
+}
+efree(nwfilter);
+}
+}
+
 /* ZEND Module inicialization function */
 PHP_MINIT_FUNCTION(libvirt)
 {
@@ -1593,6 +1635,7 @@ PHP_MINIT_FUNCTION(libvirt)
 le_libvirt_network = 
zend_register_list_destructors_ex(php_libvirt_network_dtor, NULL, 
PHP_LIBVIRT_NETWORK_RES_NAME, module_number);
 le_libvirt_nodedev = 
zend_register_list_destructors_ex(php_libvirt_nodedev_dtor, NULL, 
PHP_LIBVIRT_NODEDEV_RES_NAME, module_number);
 le_libvirt_snapshot = 
zend_register_list_destructors_ex(php_libvirt_snapshot_dtor, NULL, 
PHP_LIBVIRT_SNAPSHOT_RES_NAME, module_number);
+le_libvirt_nwfilter = 
zend_register_list_destructors_ex(php_libvirt_nwfilter_dtor, NULL, 
PHP_LIBVIRT_NWFILTER_RES_NAME, module_number);
 
 ZEND_INIT_MODULE_GLOBALS(libvirt, php_libvirt_init_globals, NULL);
 
@@ -1994,7 +2037,21 @@ PHP_MSHUTDOWN_FUNCTION(libvirt)
 VIRT_FETCH_RESOURCE(snapshot, php_libvirt_snapshot*, , 
PHP_LIBVIRT_SNAPSHOT_RES_NAME, le_libvirt_snapshot);\
 if ((snapshot == NULL) || (snapshot->snapshot == NULL))
 \
 RETURN_FALSE;  
 \
-} while (0)

[libvirt] [libvirt-php PATCH 5/7] add and use VIRT_ARRAY_INIT macro

2017-06-22 Thread Dawid Zamirski
This macro handles differences in array initialization between PHP7 and
older.
---
 src/libvirt-php.c | 96 ---
 src/libvirt-php.h | 11 +++
 2 files changed, 24 insertions(+), 83 deletions(-)

diff --git a/src/libvirt-php.c b/src/libvirt-php.c
index 89b17bb..7784450 100644
--- a/src/libvirt-php.c
+++ b/src/libvirt-php.c
@@ -2265,11 +2265,8 @@ PHP_FUNCTION(libvirt_node_get_cpu_stats)
 
 array_init(return_value);
 for (i = 0; i < 2; i++) {
-#if PHP_MAJOR_VERSION >= 7
-zval *arr, zarr;
-#else
 zval *arr;
-#endif
+
 if (i > 0)
 #ifdef EXTWIN
 Sleep(1000);
@@ -2282,12 +2279,7 @@ PHP_FUNCTION(libvirt_node_get_cpu_stats)
 RETURN_FALSE;
 }
 
-#if PHP_MAJOR_VERSION >= 7
-arr = 
-#else
-ALLOC_INIT_ZVAL(arr);
-#endif
-array_init(arr);
+VIRT_ARRAY_INIT(arr);
 
 for (j = 0; j < nparams; j++) {
 DPRINTF("%s: Field %s has value of %llu\n", __FUNCTION__, 
params[j].field, params[j].value);
@@ -2333,11 +2325,7 @@ PHP_FUNCTION(libvirt_node_get_cpu_stats_for_each_cpu)
 int done = 0;
 int i, j, numCpus;
 time_t startTime = 0;
-#if PHP_MAJOR_VERSION >= 7
-zval *time_array, ztime_array;
-#else
 zval *time_array;
-#endif
 
 GET_CONNECTION_FROM_ARGS("r|l", , );
 
@@ -2366,33 +2354,18 @@ PHP_FUNCTION(libvirt_node_get_cpu_stats_for_each_cpu)
 iter = 0;
 done = 0;
 while (!done) {
-#if PHP_MAJOR_VERSION >= 7
-zval *arr, zarr;
-arr = 
-#else
 zval *arr;
-ALLOC_INIT_ZVAL(arr);
-#endif
+VIRT_ARRAY_INIT(arr);
 
-array_init(arr);
 for (i = 0; i < numCpus; i++) {
-#if PHP_MAJOR_VERSION >= 7
-zval *arr2, zarr2;
-#else
 zval *arr2;
-#endif
 
 if (virNodeGetCPUStats(conn->conn, i, params, , 0) != 0) {
 set_error("Unable to get node cpu stats" TSRMLS_CC);
 RETURN_FALSE;
 }
 
-#if PHP_MAJOR_VERSION >= 7
-arr2 = 
-#else
-ALLOC_INIT_ZVAL(arr2);
-#endif
-array_init(arr2);
+VIRT_ARRAY_INIT(arr2);
 
 for (j = 0; j < nparams; j++)
 add_assoc_long(arr2, params[j].field, params[j].value);
@@ -2416,13 +2389,7 @@ PHP_FUNCTION(libvirt_node_get_cpu_stats_for_each_cpu)
 iter++;
 }
 
-#if PHP_MAJOR_VERSION >= 7
-time_array = _array;
-#else
-ALLOC_INIT_ZVAL(time_array);
-#endif
-array_init(time_array);
-
+VIRT_ARRAY_INIT(time_array);
 add_assoc_long(time_array, "start", startTime);
 add_assoc_long(time_array, "finish", time(NULL));
 add_assoc_long(time_array, "duration", time(NULL) - startTime);
@@ -2539,28 +2506,15 @@ PHP_FUNCTION(libvirt_connect_get_machine_types)
 snprintf(tmp, sizeof(tmp), 
"//capabilities/guest/arch[@name=\"%s\"]/domain/@type", ret[i]);
 char **ret2 = get_array_from_xpath(caps, tmp, );
 if (ret2 != NULL) {
-#if PHP_MAJOR_VERSION >= 7
-zval *arr2, zarr2;
-arr2 = 
-#else
 zval *arr2;
-ALLOC_INIT_ZVAL(arr2);
-#endif
-array_init(arr2);
+VIRT_ARRAY_INIT(arr2);
 
 for (j = 0; j < num2; j++) {
 int num3, k;
 char tmp2[1024] = { 0 };
-
-/* Common */
-#if PHP_MAJOR_VERSION >= 7
-zval *arr3, zarr3;
-arr3 = 
-#else
 zval *arr3;
-ALLOC_INIT_ZVAL(arr3);
-#endif
-array_init(arr3);
+
+VIRT_ARRAY_INIT(arr3);
 
 snprintf(tmp2, sizeof(tmp2), 
"//capabilities/guest/arch[@name=\"%s\"]/machine",
  ret[i]);
@@ -2582,15 +2536,8 @@ PHP_FUNCTION(libvirt_connect_get_machine_types)
 if (numTmp == NULL) {
 VIRT_ADD_ASSOC_STRING(arr2, key, ret3[k]);
 } else {
-#if PHP_MAJOR_VERSION >= 7
-zval *arr4, zarr4;
-arr4 = 
-#else
 zval *arr4;
-ALLOC_INIT_ZVAL(arr4);
-#endif
-array_init(arr4);
-
+VIRT_ARRAY_INIT(arr4);
 VIRT_ADD_ASSOC_STRING(arr4, "name", ret3[k]);
 VIRT_ADD_ASSOC_STRING(arr4, "maxCpus", numTmp);
 
@@ -2622,14 +2569,8 @@ PHP_FUNCTION(libvirt_connect_get_machine_types)
 if (numTmp == NULL) {
 VIRT_ADD_ASSOC_STRING(arr3, key, ret3[k]);
 } else {
-#if PHP_MAJOR_VERSION >= 7
-zval *arr4, zarr4;
-arr4 = 
-#else
 zval *arr4;

[libvirt] [libvirt-php PATCH 4/7] fix libvirt_doman_get_connect implementation.

2017-06-22 Thread Dawid Zamirski
This function must bump refcount of the returned resource because it
just returns the one that was registered with libvirt_connect call,
otherwise it would sefgault if calling code called this function more
than once and the return of the first call would be GCd before the 2nd
call.
---
 src/libvirt-php.c | 18 ++
 src/libvirt-php.h | 14 +-
 2 files changed, 15 insertions(+), 17 deletions(-)

diff --git a/src/libvirt-php.c b/src/libvirt-php.c
index 73466f1..89b17bb 100644
--- a/src/libvirt-php.c
+++ b/src/libvirt-php.c
@@ -2177,13 +2177,8 @@ PHP_FUNCTION(libvirt_connect)
 resource_change_counter(INT_RESOURCE_CONNECTION, NULL, conn->conn, 1 
TSRMLS_CC);
 DPRINTF("%s: Connection to %s established, returning %p\n", PHPFUNC, url, 
conn->conn);
 
-#if PHP_MAJOR_VERSION >= 7
-conn->resource_id = zend_register_resource(conn, le_libvirt_connection);
-ZVAL_RES(return_value, conn->resource_id);
-#else
-ZEND_REGISTER_RESOURCE(return_value, conn, le_libvirt_connection);
-conn->resource_id = Z_LVAL_P(return_value);
-#endif
+VIRT_REGISTER_RESOURCE(conn, le_libvirt_connection);
+conn->resource = VIRT_RESOURCE_HANDLE(return_value);
 }
 
 /*
@@ -7216,11 +7211,10 @@ PHP_FUNCTION(libvirt_domain_get_connect)
 conn = domain->conn;
 if (conn->conn == NULL)
 RETURN_FALSE;
-#if PHP_MAJOR_VERSION >= 7
-ZVAL_RES(return_value, conn->resource_id);
-#else
-RETURN_RESOURCE(conn->resource_id);
-#endif
+
+VIRT_RETURN_RESOURCE(conn->resource);
+/* since we're returning already registered resource, bump refcount */
+Z_ADDREF_P(return_value);
 }
 
 /*
diff --git a/src/libvirt-php.h b/src/libvirt-php.h
index 0422661..ed6a8bc 100644
--- a/src/libvirt-php.h
+++ b/src/libvirt-php.h
@@ -122,6 +122,7 @@ typedef uint64_t arch_uint;
 #if PHP_MAJOR_VERSION >= 7
 typedef size_t strsize_t;
 typedef zend_resource virt_resource;
+typedef virt_resource *virt_resource_handle;
 
 #define VIRT_RETURN_RESOURCE(_resource) \
 RETVAL_RES(_resource)
@@ -135,6 +136,9 @@ typedef zend_resource virt_resource;
 add_next_index_zval(return_value, ); \
 } while(0)
 
+#define VIRT_RESOURCE_HANDLE(_resource) \
+Z_RES_P(_resource)
+
 #define VIRT_FETCH_RESOURCE(_state, _type, _zval, _name, _le) \
 if ((_state = (_type)zend_fetch_resource(Z_RES_P(*_zval), _name, _le)) == 
NULL) { \
 RETURN_FALSE; \
@@ -179,6 +183,7 @@ typedef int strsize_t;
 typedef long zend_long;
 typedef unsigned long zend_ulong;
 typedef zend_rsrc_list_entry virt_resource;
+typedef long virt_resource_handle;
 
 #define VIRT_RETURN_RESOURCE(_resource) \
 RETVAL_RESOURCE((long) _resource)
@@ -193,6 +198,9 @@ typedef zend_rsrc_list_entry virt_resource;
 add_next_index_zval(return_value, zret); \
 } while(0)
 
+#define VIRT_RESOURCE_HANDLE(_resource) \
+Z_LVAL_P(_resource)
+
 #define VIRT_FETCH_RESOURCE(_state, _type, _zval, _name, _le) \
 ZEND_FETCH_RESOURCE(_state, _type, _zval, -1, _name, _le);
 
@@ -298,11 +306,7 @@ typedef struct tVMNetwork {
 /* Libvirt-php types */
 typedef struct _php_libvirt_connection {
 virConnectPtr conn;
-#if PHP_MAJOR_VERSION >= 7
-zend_resource *resource_id;
-#else
-long resource_id;
-#endif
+virt_resource_handle resource;
 } php_libvirt_connection;
 
 typedef struct _php_libvirt_stream {
-- 
2.13.0

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


[libvirt] [libvirt-php PATCH 3/7] update code to use resource handling macros

2017-06-22 Thread Dawid Zamirski
---
 src/libvirt-php.c | 270 --
 1 file changed, 59 insertions(+), 211 deletions(-)

diff --git a/src/libvirt-php.c b/src/libvirt-php.c
index ece98d6..73466f1 100644
--- a/src/libvirt-php.c
+++ b/src/libvirt-php.c
@@ -1368,13 +1368,7 @@ int is_local_connection(virConnectPtr conn)
 }
 
 /* Destructor for connection resource */
-static void php_libvirt_connection_dtor(
-#if PHP_MAJOR_VERSION >= 7
-zend_resource *rsrc
-#else
-zend_rsrc_list_entry *rsrc
-#endif
-TSRMLS_DC)
+static void php_libvirt_connection_dtor(virt_resource *rsrc TSRMLS_DC)
 {
 php_libvirt_connection *conn = (php_libvirt_connection *)rsrc->ptr;
 int rv = 0;
@@ -1398,13 +1392,7 @@ static void php_libvirt_connection_dtor(
 }
 
 /* Destructor for domain resource */
-static void php_libvirt_domain_dtor(
-#if PHP_MAJOR_VERSION >= 7
-zend_resource *rsrc
-#else
-zend_rsrc_list_entry *rsrc
-#endif
-TSRMLS_DC)
+static void php_libvirt_domain_dtor(virt_resource *rsrc TSRMLS_DC)
 {
 php_libvirt_domain *domain = (php_libvirt_domain *)rsrc->ptr;
 int rv = 0;
@@ -1432,13 +1420,7 @@ static void php_libvirt_domain_dtor(
 }
 
 /* Destructor for stream resource */
-static void php_libvirt_stream_dtor(
-#if PHP_MAJOR_VERSION >= 7
-zend_resource *rsrc
-#else
-zend_rsrc_list_entry *rsrc
-#endif
-TSRMLS_DC)
+static void php_libvirt_stream_dtor(virt_resource *rsrc TSRMLS_DC)
 {
 php_libvirt_stream *stream = (php_libvirt_stream *)rsrc->ptr;
 int rv = 0;
@@ -1465,13 +1447,7 @@ static void php_libvirt_stream_dtor(
 }
 
 /* Destructor for storagepool resource */
-static void php_libvirt_storagepool_dtor(
-#if PHP_MAJOR_VERSION >= 7
-zend_resource *rsrc
-#else
-zend_rsrc_list_entry *rsrc
-#endif
-TSRMLS_DC)
+static void php_libvirt_storagepool_dtor(virt_resource *rsrc TSRMLS_DC)
 {
 php_libvirt_storagepool *pool = (php_libvirt_storagepool *)rsrc->ptr;
 int rv = 0;
@@ -1498,13 +1474,7 @@ static void php_libvirt_storagepool_dtor(
 }
 
 /* Destructor for volume resource */
-static void php_libvirt_volume_dtor(
-#if PHP_MAJOR_VERSION >= 7
-zend_resource *rsrc
-#else
-zend_rsrc_list_entry *rsrc
-#endif
-TSRMLS_DC)
+static void php_libvirt_volume_dtor(virt_resource *rsrc TSRMLS_DC)
 {
 php_libvirt_volume *volume = (php_libvirt_volume *)rsrc->ptr;
 int rv = 0;
@@ -1531,13 +1501,7 @@ static void php_libvirt_volume_dtor(
 }
 
 /* Destructor for network resource */
-static void php_libvirt_network_dtor(
-#if PHP_MAJOR_VERSION >= 7
-zend_resource *rsrc
-#else
-zend_rsrc_list_entry *rsrc
-#endif
-TSRMLS_DC)
+static void php_libvirt_network_dtor(virt_resource *rsrc TSRMLS_DC)
 {
 php_libvirt_network *network = (php_libvirt_network *)rsrc->ptr;
 int rv = 0;
@@ -1564,13 +1528,7 @@ static void php_libvirt_network_dtor(
 }
 
 /* Destructor for nodedev resource */
-static void php_libvirt_nodedev_dtor(
-#if PHP_MAJOR_VERSION >= 7
-zend_resource *rsrc
-#else
-zend_rsrc_list_entry *rsrc
-#endif
-TSRMLS_DC)
+static void php_libvirt_nodedev_dtor(virt_resource *rsrc TSRMLS_DC)
 {
 php_libvirt_nodedev *nodedev = (php_libvirt_nodedev *)rsrc->ptr;
 int rv = 0;
@@ -1597,13 +1555,7 @@ static void php_libvirt_nodedev_dtor(
 }
 
 /* Destructor for snapshot resource */
-static void php_libvirt_snapshot_dtor(
-#if PHP_MAJOR_VERSION >= 7
-zend_resource *rsrc
-#else
-zend_rsrc_list_entry *rsrc
-#endif
-TSRMLS_DC)
+static void php_libvirt_snapshot_dtor(virt_resource *rsrc TSRMLS_DC)
 {
 php_libvirt_snapshot *snapshot = (php_libvirt_snapshot *)rsrc->ptr;
 int rv = 0;
@@ -4198,11 +4150,8 @@ PHP_FUNCTION(libvirt_domain_lookup_by_name)
 
 DPRINTF("%s: domain name = '%s', returning %p\n", PHPFUNC, name, 
res_domain->domain);
 resource_change_counter(INT_RESOURCE_DOMAIN, conn->conn, 
res_domain->domain, 1 TSRMLS_CC);
-#if PHP_MAJOR_VERSION >= 7
-ZVAL_RES(return_value, zend_register_resource(res_domain, 
le_libvirt_domain));
-#else
-ZEND_REGISTER_RESOURCE(return_value, res_domain, le_libvirt_domain);
-#endif
+
+VIRT_REGISTER_RESOURCE(res_domain, le_libvirt_domain);
 }
 
 /*
@@ -4236,11 +4185,8 @@ PHP_FUNCTION(libvirt_domain_lookup_by_uuid)
 
 DPRINTF("%s: domain UUID = '%s', returning %p\n", PHPFUNC, uuid, 
res_domain->domain);
 resource_change_counter(INT_RESOURCE_DOMAIN, conn->conn, 
res_domain->domain, 1 TSRMLS_CC);
-#if PHP_MAJOR_VERSION >= 7
-ZVAL_RES(return_value, zend_register_resource(res_domain, 
le_libvirt_domain));
-#else
-ZEND_REGISTER_RESOURCE(return_value, res_domain, le_libvirt_domain);
-#endif
+
+VIRT_REGISTER_RESOURCE(res_domain, le_libvirt_domain);
 }
 
 /*
@@ -4304,11 +4250,8 @@ PHP_FUNCTION(libvirt_domain_lookup_by_uuid_string)
 
 DPRINTF("%s: domain UUID string = '%s', returning %p\n", PHPFUNC, uuid, 
res_domain->domain);
 resource_change_counter(INT_RESOURCE_DOMAIN, conn->conn, 
res_domain->domain, 1 TSRMLS_CC);
-#if 

[libvirt] [libvirt-php PATCH 7/7] implement NWFilter API bindings.

2017-06-22 Thread Dawid Zamirski
adds the following functions:

* libvirt_nwfilter_define_xml
* libvirt_nwfilter_undefine
* libvirt_nwfilter_get_xml_desc
* libvirt_nwfilter_get_name
* libvirt_nwfilter_get_uuid
* libvirt_nwfilter_get_uuid_string
* libvirt_nwfilter_lookup_by_name
* libvirt_nwfilter_lookup_by_uuid
* libvirt_nwfilter_lookup_by_uuid_string
* libvirt_list_nwfilters
* libvirt_list_all_nwfilters
---
 src/libvirt-php.c | 390 ++
 src/libvirt-php.h |  12 ++
 2 files changed, 402 insertions(+)

diff --git a/src/libvirt-php.c b/src/libvirt-php.c
index 535d321..5893742 100644
--- a/src/libvirt-php.c
+++ b/src/libvirt-php.c
@@ -645,6 +645,16 @@ static zend_function_entry libvirt_functions[] = {
 PHP_FE(libvirt_nodedev_capabilities, arginfo_libvirt_conn)
 PHP_FE(libvirt_nodedev_get_xml_desc, arginfo_libvirt_conn_xpath)
 PHP_FE(libvirt_nodedev_get_information,  arginfo_libvirt_conn)
+/* NWFilter functions */
+PHP_FE(libvirt_nwfilter_define_xml,  arginfo_libvirt_conn_xml)
+PHP_FE(libvirt_nwfilter_undefine,arginfo_libvirt_conn)
+PHP_FE(libvirt_nwfilter_get_xml_desc,arginfo_libvirt_conn_xpath)
+PHP_FE(libvirt_nwfilter_get_uuid_string, arginfo_libvirt_conn)
+PHP_FE(libvirt_nwfilter_get_uuid,arginfo_libvirt_conn)
+PHP_FE(libvirt_nwfilter_get_name,arginfo_libvirt_conn)
+PHP_FE(libvirt_nwfilter_lookup_by_name,  arginfo_libvirt_conn_name)
+PHP_FE(libvirt_nwfilter_lookup_by_uuid_string, arginfo_libvirt_conn_uuid)
+PHP_FE(libvirt_nwfilter_lookup_by_uuid,  arginfo_libvirt_conn_uuid)
 /* List functions */
 PHP_FE(libvirt_list_domains, arginfo_libvirt_conn)
 PHP_FE(libvirt_list_domain_snapshots,arginfo_libvirt_conn_optflags)
@@ -659,6 +669,8 @@ static zend_function_entry libvirt_functions[] = {
 PHP_FE(libvirt_list_active_domains,  arginfo_libvirt_conn)
 PHP_FE(libvirt_list_active_domain_ids,   arginfo_libvirt_conn)
 PHP_FE(libvirt_list_inactive_domains,arginfo_libvirt_conn)
+PHP_FE(libvirt_list_all_nwfilters,   arginfo_libvirt_conn)
+PHP_FE(libvirt_list_nwfilters,   arginfo_libvirt_conn)
 /* Version information and common function */
 PHP_FE(libvirt_version,  arginfo_libvirt_opttype)
 PHP_FE(libvirt_check_version,arginfo_libvirt_check_version)
@@ -9074,7 +9086,93 @@ PHP_FUNCTION(libvirt_list_nodedevs)
 efree(names);
 }
 
+
+/*
+ * Function name:   libvirt_list_all_nwfilters
+ * Since version:   0.5.4
+ * Description: Function is used to list nwfilters on the connection
+ * Arguments:   @res [resource]: libvirt connection resource
+ * Returns: libvirt nwfilter resources array for the connection
+ */
+PHP_FUNCTION(libvirt_list_all_nwfilters)
+{
+php_libvirt_nwfilter *res_nwfilter;
+php_libvirt_connection *conn = NULL;
+virNWFilterPtr *filters = NULL;
+virNWFilterPtr nwfilter = NULL;
+zval *zconn;
+int count = -1;
+size_t i = 0;
+
+GET_CONNECTION_FROM_ARGS("r", );
+
+/* in current libvirt version, flags are not used for this, so passing 0 */
+if ((count = virConnectListAllNWFilters(conn->conn, , 0)) < 0)
+RETURN_FALSE;
+
+DPRINTF("%s: Found %d nwfilters\n", PHPFUNC, count);
+
+array_init(return_value);
+
+for (i = 0; i < count; i++) {
+nwfilter = filters[i];
+res_nwfilter = (php_libvirt_nwfilter *) 
emalloc(sizeof(php_libvirt_nwfilter));
+res_nwfilter->nwfilter = nwfilter;
+res_nwfilter->conn = conn;
+
+resource_change_counter(INT_RESOURCE_NWFILTER, conn->conn,
+res_nwfilter->nwfilter, 1 TSRMLS_CC);
+VIRT_REGISTER_LIST_RESOURCE(nwfilter);
+}
+}
+
+/*
+ * Function name:   libvirt_list_nwfilters
+ * Since version:   0.5.4
+ * Description: Function is used to list nwfilters on the connection
+ * Arguments:   @res [resource]: libvirt connection resource
+ * Returns: libvirt nwfilter names array for the connection
+ */
+PHP_FUNCTION(libvirt_list_nwfilters)
+{
+php_libvirt_connection *conn = NULL;
+zval *zconn;
+int count = -1;
+int expectedcount = -1;
+char **names;
+int i, done = 0;
+
+GET_CONNECTION_FROM_ARGS("r", );
+
+array_init(return_value);
+
+if ((expectedcount = virConnectNumOfNWFilters(conn->conn)) < 0)
+RETURN_FALSE;
+
+names = (char **) emalloc(expectedcount * sizeof(char *));
+count = virConnectListNWFilters(conn->conn, names, expectedcount);
+
+if (count != expectedcount || count < 0) {
+efree(names);
+DPRINTF("%s: virConnectListNWFilters returned %d filters, while %d was 
"
+"expected\n", PHPFUNC, count, expectedcount);
+RETURN_FALSE;
+}
+
+for (i = 0; i < count; i++) {
+VIRT_ADD_NEXT_INDEX_STRING(return_value,  names[i]);
+   

[libvirt] [resend PATCH v2 6/7] virsh: Implement managedsave-dumpxml command

2017-06-22 Thread Madhu Pavan

Add a simple virsh command handler which makes use of the new API.

Signed-off-by: Kothapally Madhu Pavan 
---
 tools/virsh-domain.c | 56 
 tools/virsh.pod  |  6 ++
 2 files changed, 62 insertions(+)

diff --git a/tools/virsh-domain.c b/tools/virsh-domain.c
index aadacef..874cf49 100644
--- a/tools/virsh-domain.c
+++ b/tools/virsh-domain.c
@@ -4705,6 +4705,56 @@ cmdManagedSaveRemove(vshControl *ctl, const vshCmd *cmd)
 }

 /*
+ * "managedsave-dumpxml" command
+ */
+static const vshCmdInfo info_managed_save_dumpxml[] = {
+   {.name = "help",
+.data = N_("Domain information of managed save state file in XML")
+   },
+   {.name = "desc",
+.data = N_("Dump XML of domain information for a managed save state file to 
stdout.")
+   },
+   {.name = NULL}
+};
+
+static const vshCmdOptDef opts_managed_save_dumpxml[] = {
+VIRSH_COMMON_OPT_DOMAIN_FULL,
+{.name = "security-info",
+ .type = VSH_OT_BOOL,
+ .help = N_("include security sensitive information in XML dump")
+},
+{.name = NULL}
+};
+
+static bool
+cmdManagedSaveDumpxml(vshControl *ctl, const vshCmd *cmd)
+{
+bool ret = false;
+virDomainPtr dom = NULL;
+unsigned int flags = 0;
+char *xml = NULL;
+
+if (vshCommandOptBool(cmd, "security-info"))
+flags |= VIR_DOMAIN_XML_SECURE;
+
+dom = virshCommandOptDomain(ctl, cmd, NULL);
+if (dom == NULL)
+goto cleanup;
+
+xml = virDomainManagedSaveGetXMLDesc(dom, flags);
+if (!xml)
+goto cleanup;
+
+vshPrint(ctl, "%s", xml);
+ret = true;
+
+ cleanup:
+virshDomainFree(dom);
+VIR_FREE(xml);
+return ret;
+}
+
+/*
  * "managedsave-define" command
  */
 static const vshCmdInfo info_managed_save_define[] = {
@@ -13862,6 +13912,12 @@ const vshCmdDef domManagementCmds[] = {
  .info = info_managedsaveremove,
  .flags = 0
 },
+{.name = "managedsave-dumpxml",
+ .handler = cmdManagedSaveDumpxml,
+ .opts = opts_managed_save_dumpxml,
+ .info = info_managed_save_dumpxml,
+ .flags = 0
+},
 {.name = "managedsave-define",
  .handler = cmdManagedSaveDefine,
  .opts = opts_managed_save_define,
diff --git a/tools/virsh.pod b/tools/virsh.pod
index 46b4d72..e93460e 100644
--- a/tools/virsh.pod
+++ b/tools/virsh.pod
@@ -1638,6 +1638,12 @@ running or paused state.  Normally, this command does 
not alter the
 recorded state; passing either the I<--running> or I<--paused> flag
 will allow overriding which state the B should use.

+=item B I [I<--security-info>]
+
+Extract the domain XML that was in effect at the time the saved state
+file I was created with the B command.  Using
+I<--security-info> will also include security sensitive information.
+
 =item B [I]

 Provide the maximum number of virtual CPUs supported for a guest VM on
--
1.8.3.1

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


[libvirt] [resend PATCH v2 7/7] virsh: Implement managedsave-edit command

2017-06-22 Thread Madhu Pavan

Add a simple virsh command handler which makes use of the new API.

Signed-off-by: Kothapally Madhu Pavan 
---
 tools/virsh-domain.c | 72 
 tools/virsh.pod  | 21 +++
 2 files changed, 93 insertions(+)

diff --git a/tools/virsh-domain.c b/tools/virsh-domain.c
index 874cf49..12721e7 100644
--- a/tools/virsh-domain.c
+++ b/tools/virsh-domain.c
@@ -4705,6 +4705,72 @@ cmdManagedSaveRemove(vshControl *ctl, const vshCmd *cmd)
 }

 /*
+ * "managedsave-edit" command
+ */
+static const vshCmdInfo info_managed_save_edit[] = {
+   {.name = "help",
+.data = N_("edit XML for a domain's managed save state file")
+   },
+   {.name = "desc",
+.data = N_("Edit the domain XML associated with the managed save state 
file")
+   },
+   {.name = NULL}
+};
+
+static const vshCmdOptDef opts_managed_save_edit[] = {
+VIRSH_COMMON_OPT_DOMAIN_FULL,
+{.name = "running",
+ .type = VSH_OT_BOOL,
+ .help = N_("set domain to be running on start")
+},
+{.name = "paused",
+ .type = VSH_OT_BOOL,
+ .help = N_("set domain to be paused on start")
+},
+{.name = NULL}
+};
+
+static bool
+cmdManagedSaveEdit(vshControl *ctl, const vshCmd *cmd)
+{
+bool ret = false;
+virDomainPtr dom = NULL;
+unsigned int getxml_flags = VIR_DOMAIN_XML_SECURE;
+unsigned int define_flags = 0;
+
+if (vshCommandOptBool(cmd, "running"))
+define_flags |= VIR_DOMAIN_SAVE_RUNNING;
+if (vshCommandOptBool(cmd, "paused"))
+define_flags |= VIR_DOMAIN_SAVE_PAUSED;
+
+VSH_EXCLUSIVE_OPTIONS("running", "paused");
+
+dom = virshCommandOptDomain(ctl, cmd, NULL);
+if (dom == NULL)
+goto cleanup;
+
+#define EDIT_GET_XML virDomainManagedSaveGetXMLDesc(dom, getxml_flags)
+#define EDIT_NOT_CHANGED   
   \
+do {   
   \
+vshPrintExtra(ctl, _("Managed save image of domain %s XML configuration 
" \
+ "not changed.\n"), virDomainGetName(dom));
   \
+ret = true;
   \
+goto edit_cleanup; 
   \
+} while (0)
+#define EDIT_DEFINE \
+(virDomainManagedSaveDefineXML(dom, doc_edited, define_flags) == 0)
+#include "virsh-edit.c"
+
+vshPrintExtra(ctl, _("Managed save image of Domain %s XML configuration 
edited.\n"),
+  virDomainGetName(dom));
+ret = true;
+
+ cleanup:
+virshDomainFree(dom);
+return ret;
+}
+
+/*
  * "managedsave-dumpxml" command
  */
 static const vshCmdInfo info_managed_save_dumpxml[] = {
@@ -13912,6 +13978,12 @@ const vshCmdDef domManagementCmds[] = {
  .info = info_managedsaveremove,
  .flags = 0
 },
+{.name = "managedsave-edit",
+ .handler = cmdManagedSaveEdit,
+ .opts = opts_managed_save_edit,
+ .info = info_managed_save_edit,
+ .flags = 0
+},
 {.name = "managedsave-dumpxml",
  .handler = cmdManagedSaveDumpxml,
  .opts = opts_managed_save_dumpxml,
diff --git a/tools/virsh.pod b/tools/virsh.pod
index e93460e..639391a 100644
--- a/tools/virsh.pod
+++ b/tools/virsh.pod
@@ -1644,6 +1644,27 @@ Extract the domain XML that was in effect at the time 
the saved state
 file I was created with the B command.  Using
 I<--security-info> will also include security sensitive information.

+=item B I [{I<--running> | I<--paused>}]
+
+Edit the XML configuration associated with a saved state file of a
+I was created by the B command.
+
+The managed save image records whether the domain should be started to a
+running or paused state.  Normally, this command does not alter the
+recorded state; passing either the I<--running> or I<--paused> flag
+will allow overriding which state the B should use.
+
+This is equivalent to:
+
+ virsh managedsave-dumpxml domain-name > state-file.xml
+ vi state-file.xml (or make changes with your other text editor)
+ virsh managedsave-define domain-name state-file-xml
+
+except that it does some error checking.
+
+The editor used can be supplied by the C<$VISUAL> or C<$EDITOR> environment
+variables, and defaults to C.
+
 =item B [I]

 Provide the maximum number of virtual CPUs supported for a guest VM on
--
1.8.3.1

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


[libvirt] [resend PATCH v2 5/7] virsh: Implement managedsave-define command

2017-06-22 Thread Madhu Pavan

Add a simple virsh command handler which makes use of the new API.

Signed-off-by: Kothapally Madhu Pavan 
---
 tools/virsh-domain.c | 79 
 tools/virsh.pod  | 14 ++
 2 files changed, 93 insertions(+)

diff --git a/tools/virsh-domain.c b/tools/virsh-domain.c
index 91bdb58..aadacef 100644
--- a/tools/virsh-domain.c
+++ b/tools/virsh-domain.c
@@ -4705,6 +4705,79 @@ cmdManagedSaveRemove(vshControl *ctl, const vshCmd *cmd)
 }

 /*
+ * "managedsave-define" command
+ */
+static const vshCmdInfo info_managed_save_define[] = {
+{.name = "help",
+ .data = N_("redefine the XML for a domain's managed save state file")
+},
+{.name = "desc",
+ .data = N_("Replace the domain XML associated with a managed save state 
file")
+},
+{.name = NULL}
+};
+
+static const vshCmdOptDef opts_managed_save_define[] = {
+VIRSH_COMMON_OPT_DOMAIN_FULL,
+{.name = "xml",
+ .type = VSH_OT_DATA,
+ .flags = VSH_OFLAG_REQ,
+ .help = N_("filename containing updated XML for the target")
+},
+{.name = "running",
+ .type = VSH_OT_BOOL,
+ .help = N_("set domain to be running on start")
+},
+{.name = "paused",
+ .type = VSH_OT_BOOL,
+ .help = N_("set domain to be paused on start")
+},
+{.name = NULL}
+};
+
+static bool
+cmdManagedSaveDefine(vshControl *ctl, const vshCmd *cmd)
+{
+bool ret = false;
+virDomainPtr dom = NULL;
+const char *xmlfile = NULL;
+char *xml = NULL;
+unsigned int flags = 0;
+
+if (vshCommandOptBool(cmd, "running"))
+flags |= VIR_DOMAIN_SAVE_RUNNING;
+if (vshCommandOptBool(cmd, "paused"))
+flags |= VIR_DOMAIN_SAVE_PAUSED;
+
+VSH_EXCLUSIVE_OPTIONS("running", "paused");
+
+if (vshCommandOptStringReq(ctl, cmd, "xml", ) < 0)
+return false;
+
+if (virFileReadAll(xmlfile, VSH_MAX_XML_FILE, ) < 0)
+return false;
+
+dom = virshCommandOptDomain(ctl, cmd, NULL);
+if (dom == NULL)
+goto cleanup;
+
+if (virDomainManagedSaveDefineXML(dom, xml, flags) < 0) {
+vshError(ctl, _("Failed to update %s XML configuration"),
+virDomainGetName(dom));
+goto cleanup;
+}
+
+vshPrintExtra(ctl, _("Managed save state file of domain %s updated.\n"),
+ virDomainGetName(dom));
+ret = true;
+
+ cleanup:
+virshDomainFree(dom);
+VIR_FREE(xml);
+return ret;
+}
+
+/*
  * "schedinfo" command
  */
 static const vshCmdInfo info_schedinfo[] = {
@@ -13789,6 +13862,12 @@ const vshCmdDef domManagementCmds[] = {
  .info = info_managedsaveremove,
  .flags = 0
 },
+{.name = "managedsave-define",
+ .handler = cmdManagedSaveDefine,
+ .opts = opts_managed_save_define,
+ .info = info_managed_save_define,
+ .flags = 0
+},
 {.name = "memtune",
  .handler = cmdMemtune,
  .opts = opts_memtune,
diff --git a/tools/virsh.pod b/tools/virsh.pod
index c5bf168..46b4d72 100644
--- a/tools/virsh.pod
+++ b/tools/virsh.pod
@@ -1624,6 +1624,20 @@ has any managed save image.
 Remove the B state file for a domain, if it exists.  This
 ensures the domain will do a full boot the next time it is started.

+=item B I I [{I<--running> | I<--paused>}]
+
+Update the domain XML that will be used when I is later
+started. The I argument must be a file name containing
+the alternative XML, with changes only in the host-specific portions of
+the domain XML. For example, it can be used to account for file naming
+differences resulting from creating disk snapshots of underlying storage
+after the guest was saved.
+
+The managed save image records whether the domain should be started to a
+running or paused state.  Normally, this command does not alter the
+recorded state; passing either the I<--running> or I<--paused> flag
+will allow overriding which state the B should use.
+
 =item B [I]

 Provide the maximum number of virtual CPUs supported for a guest VM on
--
1.8.3.1

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


[libvirt] [resend PATCH v2 4/7] qemu: Implement qemuDomainManagedSaveDefineXML

2017-06-22 Thread Madhu Pavan

This commit adds qemu driver implementation to edit xml
configuration of managed save state file of a domain.

Signed-off-by: Kothapally Madhu Pavan 
---
 src/qemu/qemu_driver.c | 41 +
 1 file changed, 41 insertions(+)

diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c
index 5b21cf7..93c62a1 100644
--- a/src/qemu/qemu_driver.c
+++ b/src/qemu/qemu_driver.c
@@ -6843,6 +6843,46 @@ qemuDomainManagedSaveGetXMLDesc(virDomainPtr dom, 
unsigned int flags)
 return ret;
 }

+static int
+qemuDomainManagedSaveDefineXML(virDomainPtr dom, const char *dxml,
+   unsigned int flags)
+{
+virQEMUDriverPtr driver = dom->conn->privateData;
+virConnectPtr conn = dom->conn;
+virDomainObjPtr vm;
+char *path = NULL;
+int ret;
+
+if (!(vm = qemuDomObjFromDomain(dom)))
+return -1;
+
+path = qemuDomainManagedSavePath(driver, vm);
+virDomainObjEndAPI();
+
+if (!path)
+goto error;
+
+if (!virFileExists(path)) {
+virReportError(VIR_ERR_OPERATION_INVALID,
+   "%s",_("domain doesnot have managed save image"));
+goto error;
+}
+
+ret = qemuDomainSaveImageDefineXML(conn, path, dxml, flags);
+
+VIR_FREE(path);
+
+if (ret < 0)
+goto error;
+
+return ret;
+
+ error:
+VIR_FREE(path);
+virDispatchError(conn);
+return -1;
+}
+
 /* Return 0 on success, 1 if incomplete saved image was silently unlinked,
  * and -1 on failure with error raised.  */
 static int
@@ -20856,6 +20896,7 @@ static virHypervisorDriver qemuHypervisorDriver = {
 .domainHasManagedSaveImage = qemuDomainHasManagedSaveImage, /* 0.8.0 */
 .domainManagedSaveRemove = qemuDomainManagedSaveRemove, /* 0.8.0 */
 .domainManagedSaveGetXMLDesc = qemuDomainManagedSaveGetXMLDesc, /* 3.5.0 */
+.domainManagedSaveDefineXML = qemuDomainManagedSaveDefineXML, /* 3.5.0 */
 .domainSnapshotCreateXML = qemuDomainSnapshotCreateXML, /* 0.8.0 */
 .domainSnapshotGetXMLDesc = qemuDomainSnapshotGetXMLDesc, /* 0.8.0 */
 .domainSnapshotNum = qemuDomainSnapshotNum, /* 0.8.0 */
--
1.8.3.1

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


[libvirt] [resend PATCH v2 2/7] lib: Add API to edit domain's managed save state xml configuration

2017-06-22 Thread Madhu Pavan

Similar to domainSaveImageDefineXML this commit adds domainManagedSaveDefineXML
API which allows to edit domain's managed save state xml configuration.

Signed-off-by: Kothapally Madhu Pavan 
---
 include/libvirt/libvirt-domain.h |  4 +++
 src/driver-hypervisor.h  |  6 +
 src/libvirt-domain.c | 58 
 src/libvirt_public.syms  |  1 +
 src/remote/remote_driver.c   |  1 +
 src/remote/remote_protocol.x | 16 ++-
 src/remote_protocol-structs  |  8 +-
 7 files changed, 92 insertions(+), 2 deletions(-)

diff --git a/include/libvirt/libvirt-domain.h b/include/libvirt/libvirt-domain.h
index 56ab5d7..53bebf1 100644
--- a/include/libvirt/libvirt-domain.h
+++ b/include/libvirt/libvirt-domain.h
@@ -1211,6 +1211,10 @@ int
virDomainManagedSaveRemove(virDomainPtr dom,
   unsigned int flags);
 char * virDomainManagedSaveGetXMLDesc(virDomainPtr domain,
   unsigned int flags);
+intvirDomainManagedSaveDefineXML(virDomainPtr domain,
+ const char *dxml,
+ unsigned int flags);
+

 /*
  * Domain core dump
diff --git a/src/driver-hypervisor.h b/src/driver-hypervisor.h
index 598fc06..0a4181e 100644
--- a/src/driver-hypervisor.h
+++ b/src/driver-hypervisor.h
@@ -749,6 +749,11 @@ typedef char *
 (*virDrvDomainManagedSaveGetXMLDesc)(virDomainPtr domain,
  unsigned int flags);

+typedef int
+(*virDrvDomainManagedSaveDefineXML)(virDomainPtr domain,
+const char *dxml,
+unsigned int flags);
+
 typedef virDomainSnapshotPtr
 (*virDrvDomainSnapshotCreateXML)(virDomainPtr domain,
  const char *xmlDesc,
@@ -1427,6 +1432,7 @@ struct _virHypervisorDriver {
 virDrvDomainHasManagedSaveImage domainHasManagedSaveImage;
 virDrvDomainManagedSaveRemove domainManagedSaveRemove;
 virDrvDomainManagedSaveGetXMLDesc domainManagedSaveGetXMLDesc;
+virDrvDomainManagedSaveDefineXML domainManagedSaveDefineXML;
 virDrvDomainSnapshotCreateXML domainSnapshotCreateXML;
 virDrvDomainSnapshotGetXMLDesc domainSnapshotGetXMLDesc;
 virDrvDomainSnapshotNum domainSnapshotNum;
diff --git a/src/libvirt-domain.c b/src/libvirt-domain.c
index b67f8fd..fc5f4ed 100644
--- a/src/libvirt-domain.c
+++ b/src/libvirt-domain.c
@@ -9353,6 +9353,64 @@ virDomainManagedSaveGetXMLDesc(virDomainPtr domain, 
unsigned int flags)


 /**
+ * virDomainManagedSaveDefineXML:
+ * @domain: a domain object
+ * @dxml: XML config for adjusting guest xml used on restore
+ * @flags: bitwise-OR of virDomainSaveRestoreFlags
+ *
+ * This updates the definition of a domain stored in a saved state
+ * file. @domain is used to extract the saved state file location.
+ *
+ * @dxml can be used to alter host-specific portions of the domain XML
+ * that will be used on the next start of the domain. For example, it is
+ * possible to alter the backing filename that is associated with a
+ * disk device, to match renaming done as part of backing up the disk
+ * device while the domain is stopped.
+ *
+ * Normally, the saved state file will remember whether the domain was
+ * running or paused, and restore defaults to the same state.
+ * Specifying VIR_DOMAIN_SAVE_RUNNING or VIR_DOMAIN_SAVE_PAUSED in
+ * @flags will override the default saved into the file; omitting both
+ * leaves the file's default unchanged.  These two flags are mutually
+ * exclusive.
+ *
+ * Returns 0 in case of success and -1 in case of failure.
+ */
+int
+virDomainManagedSaveDefineXML(virDomainPtr domain, const char *dxml,
+  unsigned int flags)
+{
+virConnectPtr conn;
+
+VIR_DOMAIN_DEBUG(domain, "flags=%x", flags);
+
+virResetLastError();
+
+VIR_EXCLUSIVE_FLAGS_GOTO(VIR_DOMAIN_SAVE_RUNNING,
+ VIR_DOMAIN_SAVE_PAUSED,
+ error);
+
+virCheckDomainReturn(domain, -1);
+conn = domain->conn;
+
+if (conn->driver->domainManagedSaveDefineXML) {
+int ret;
+ret = conn->driver->domainManagedSaveDefineXML(domain, dxml, flags);
+
+if (ret < 0)
+goto error;
+return ret;
+}
+
+virReportUnsupportedError();
+
+ error:
+virDispatchError(domain->conn);
+return -1;
+}
+
+
+/**
  * virDomainOpenConsole:
  * @dom: a domain object
  * @dev_name: the console, serial or parallel port device alias, or NULL
diff --git a/src/libvirt_public.syms b/src/libvirt_public.syms
index acba9ea..8c33c6b 100644
--- a/src/libvirt_public.syms
+++ b/src/libvirt_public.syms
@@ -771,6 +771,7 @@ LIBVIRT_3.4.0 {
 LIBVIRT_3.5.0 {
 global:
 virDomainManagedSaveGetXMLDesc;
+  

[libvirt] [resend PATCH v2 3/7] qemu: Implement qemuDomainManagedSaveGetXMLDesc

2017-06-22 Thread Madhu Pavan

This commit adds qemu driver implementation to get xml description
for managed save state domain.

Signed-off-by: Kothapally Madhu Pavan 
---
 src/qemu/qemu_driver.c | 46 ++
 1 file changed, 46 insertions(+)

diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c
index e91663c..5b21cf7 100644
--- a/src/qemu/qemu_driver.c
+++ b/src/qemu/qemu_driver.c
@@ -6798,6 +6798,51 @@ qemuDomainSaveImageDefineXML(virConnectPtr conn, const 
char *path,
 return ret;
 }

+static char *
+qemuDomainManagedSaveGetXMLDesc(virDomainPtr dom, unsigned int flags)
+{
+virQEMUDriverPtr driver = dom->conn->privateData;
+virDomainObjPtr vm;
+char *path = NULL;
+char *ret = NULL;
+virDomainDefPtr def = NULL;
+int fd = -1;
+virQEMUSaveDataPtr data = NULL;
+
+/* We only take subset of virDomainDefFormat flags.  */
+virCheckFlags(VIR_DOMAIN_XML_SECURE, NULL);
+
+if (!(vm = qemuDomObjFromDomain(dom)))
+return ret;
+
+path = qemuDomainManagedSavePath(driver, vm);
+
+if (!path)
+goto cleanup;
+
+if (!virFileExists(path)) {
+virReportError(VIR_ERR_OPERATION_INVALID,
+   "%s",_("domain doesnot have managed save image"));
+goto cleanup;
+}
+
+fd = qemuDomainSaveImageOpen(driver, path, , ,
+ false, NULL, false, false);
+if (fd < 0)
+goto cleanup;
+if (virDomainManagedSaveGetXMLDescEnsureACL(dom->conn, def, flags) < 0)
+goto cleanup;
+ret = qemuDomainDefFormatXML(driver, def, flags);
+
+ cleanup:
+virQEMUSaveDataFree(data);
+virDomainDefFree(def);
+VIR_FORCE_CLOSE(fd);
+virDomainObjEndAPI();
+VIR_FREE(path);
+return ret;
+}
+
 /* Return 0 on success, 1 if incomplete saved image was silently unlinked,
  * and -1 on failure with error raised.  */
 static int
@@ -20810,6 +20855,7 @@ static virHypervisorDriver qemuHypervisorDriver = {
 .domainManagedSave = qemuDomainManagedSave, /* 0.8.0 */
 .domainHasManagedSaveImage = qemuDomainHasManagedSaveImage, /* 0.8.0 */
 .domainManagedSaveRemove = qemuDomainManagedSaveRemove, /* 0.8.0 */
+.domainManagedSaveGetXMLDesc = qemuDomainManagedSaveGetXMLDesc, /* 3.5.0 */
 .domainSnapshotCreateXML = qemuDomainSnapshotCreateXML, /* 0.8.0 */
 .domainSnapshotGetXMLDesc = qemuDomainSnapshotGetXMLDesc, /* 0.8.0 */
 .domainSnapshotNum = qemuDomainSnapshotNum, /* 0.8.0 */
--
1.8.3.1

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


[libvirt] [resend PATCH v2 1/7] lib: Add API to dump xml configuration of managed save state domain

2017-06-22 Thread Madhu Pavan

Similar to domainSaveImageGetXMLDesc this commit adds 
domainManagedSaveGetXMLDesc
API which allows to get the xml of managed save state domain.

Signed-off-by: Kothapally Madhu Pavan 
---
 include/libvirt/libvirt-domain.h |  2 ++
 src/driver-hypervisor.h  |  5 
 src/libvirt-domain.c | 49 
 src/libvirt_public.syms  |  5 
 src/remote/remote_driver.c   |  1 +
 src/remote/remote_protocol.x | 19 ++--
 src/remote_protocol-structs  |  8 +++
 7 files changed, 87 insertions(+), 2 deletions(-)

diff --git a/include/libvirt/libvirt-domain.h b/include/libvirt/libvirt-domain.h
index 45f939a..56ab5d7 100644
--- a/include/libvirt/libvirt-domain.h
+++ b/include/libvirt/libvirt-domain.h
@@ -1209,6 +1209,8 @@ int
virDomainHasManagedSaveImage(virDomainPtr dom,
 unsigned int flags);
 intvirDomainManagedSaveRemove(virDomainPtr dom,
   unsigned int flags);
+char * virDomainManagedSaveGetXMLDesc(virDomainPtr domain,
+  unsigned int flags);

 /*
  * Domain core dump
diff --git a/src/driver-hypervisor.h b/src/driver-hypervisor.h
index 3053d7a..598fc06 100644
--- a/src/driver-hypervisor.h
+++ b/src/driver-hypervisor.h
@@ -745,6 +745,10 @@ typedef int
 (*virDrvDomainManagedSaveRemove)(virDomainPtr domain,
  unsigned int flags);

+typedef char *
+(*virDrvDomainManagedSaveGetXMLDesc)(virDomainPtr domain,
+ unsigned int flags);
+
 typedef virDomainSnapshotPtr
 (*virDrvDomainSnapshotCreateXML)(virDomainPtr domain,
  const char *xmlDesc,
@@ -1422,6 +1426,7 @@ struct _virHypervisorDriver {
 virDrvDomainManagedSave domainManagedSave;
 virDrvDomainHasManagedSaveImage domainHasManagedSaveImage;
 virDrvDomainManagedSaveRemove domainManagedSaveRemove;
+virDrvDomainManagedSaveGetXMLDesc domainManagedSaveGetXMLDesc;
 virDrvDomainSnapshotCreateXML domainSnapshotCreateXML;
 virDrvDomainSnapshotGetXMLDesc domainSnapshotGetXMLDesc;
 virDrvDomainSnapshotNum domainSnapshotNum;
diff --git a/src/libvirt-domain.c b/src/libvirt-domain.c
index 9bda3c2..b67f8fd 100644
--- a/src/libvirt-domain.c
+++ b/src/libvirt-domain.c
@@ -9302,6 +9302,55 @@ virDomainManagedSaveRemove(virDomainPtr dom, unsigned 
int flags)
 }


+/**
+ * virDomainManagedSaveGetXMLDesc:
+ * @domain: a domain object
+ * @flags: bitwise-OR of subset of virDomainXMLFlags
+ *
+ * This method will extract the XML description of the managed save
+ * state file of a domain.
+ *
+ * No security-sensitive data will be included unless @flags contains
+ * VIR_DOMAIN_XML_SECURE; this flag is rejected on read-only
+ * connections.  For this API, @flags should not contain either
+ * VIR_DOMAIN_XML_INACTIVE or VIR_DOMAIN_XML_UPDATE_CPU.
+ *
+ * Returns a 0 terminated UTF-8 encoded XML instance, or NULL in case of
+ * error.  The caller must free() the returned value.
+ */
+char *
+virDomainManagedSaveGetXMLDesc(virDomainPtr domain, unsigned int flags)
+{
+virConnectPtr conn;
+
+VIR_DOMAIN_DEBUG(domain, "flags=%x", flags);
+
+virResetLastError();
+
+virCheckDomainReturn(domain, NULL);
+conn = domain->conn;
+
+if ((conn->flags & VIR_CONNECT_RO) && (flags & VIR_DOMAIN_XML_SECURE)) {
+virReportError(VIR_ERR_OPERATION_DENIED, "%s",
+   _("virDomainManagedSaveGetXMLDesc with secure flag"));
+goto error;
+}
+
+if (conn->driver->domainManagedSaveGetXMLDesc) {
+char *ret;
+ret = conn->driver->domainManagedSaveGetXMLDesc(domain, flags);
+if (!ret)
+goto error;
+return ret;
+}
+
+virReportUnsupportedError();
+
+ error:
+virDispatchError(domain->conn);
+return NULL;
+}
+

 /**
  * virDomainOpenConsole:
diff --git a/src/libvirt_public.syms b/src/libvirt_public.syms
index fac77fb..acba9ea 100644
--- a/src/libvirt_public.syms
+++ b/src/libvirt_public.syms
@@ -768,4 +768,9 @@ LIBVIRT_3.4.0 {
 virStreamSparseSendAll;
 } LIBVIRT_3.1.0;

+LIBVIRT_3.5.0 {
+global:
+virDomainManagedSaveGetXMLDesc;
+} LIBVIRT_3.4.0;
+
 #  define new API here using predicted next version number 
diff --git a/src/remote/remote_driver.c b/src/remote/remote_driver.c
index b452e8b..5b11147 100644
--- a/src/remote/remote_driver.c
+++ b/src/remote/remote_driver.c
@@ -8410,6 +8410,7 @@ static virHypervisorDriver hypervisor_driver = {
 .domainManagedSave = remoteDomainManagedSave, /* 0.8.0 */
 .domainHasManagedSaveImage = remoteDomainHasManagedSaveImage, /* 0.8.0 */
 .domainManagedSaveRemove = remoteDomainManagedSaveRemove, /* 0.8.0 */
+.domainManagedSaveGetXMLDesc = remoteDomainManagedSaveGetXMLDesc, /* 3.5.0 
*/
 

[libvirt] [resend PATCH v2 0/7] Add new APIs to edit xml configuration of managed save state of a domain

2017-06-22 Thread Madhu Pavan

managedsave command offloads the user from managing the save state file.
It does not need the user to specify saved state file location, all it takes
is domain name to identify. This makes it much more comfortable to use in
emergency where immediate shutdowm is needed. But it doesn't provide a way
to edit XML description of the save state file without user going through an
extra effort to search manually where the file actually exists.

The series aims to overcome the above constraints by adding new APIs and
commands to seemlessly edit the managed save state XML description using
just the domain name. The Patches mainly make use of the save-image-edit
code flow only to simplify the above use case.

This patch set provides capability to Dump and Edit the XML configuration
associated with a saved state file of a domain which was created by the
managedsave command.

The new command carry the similar options as the save-image- commands
to change the running state as to paused state or running on start.

This is equivalent to:

 virsh managedsave-dumpxml domain-name > state-file.xml
 vi state-file.xml (or make changes with your other text editor)
 virsh managedsave-define domain-name state-file-xml

or you can simply use:

 virsh managedsave-edit domain-name

It's always better when we get more.

Changes since v1:
- qemu implementation called directly rather than going through
  driver pointer in qemuDomainManagedSaveDefineXML.
- check whether the managed save state file exists and report a
  error if it doesn't.

Kothapally Madhu Pavan (7):
  lib: Add API to dump xml configuration of managed save state domain
  lib: Add API to edit domain's managed save state xml configuration
  qemu: Implement qemuDomainManagedSaveGetXMLDesc
  qemu: Implement qemuDomainManagedSaveDefineXML
  virsh: Implement managedsave-define command
  virsh: Implement managedsave-dumpxml command
  virsh: Implement managedsave-edit command

 include/libvirt/libvirt-domain.h |   6 ++
 src/driver-hypervisor.h  |  11 +++
 src/libvirt-domain.c | 107 
 src/libvirt_public.syms  |   6 ++
 src/qemu/qemu_driver.c   |  87 
 src/remote/remote_driver.c   |   2 +
 src/remote/remote_protocol.x |  31 +-
 src/remote_protocol-structs  |  14 +++
 tools/virsh-domain.c | 207 +++
 tools/virsh.pod  |  41 
 10 files changed, 511 insertions(+), 1 deletion(-)

--
1.8.3.1

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


Re: [libvirt] [PATCH 1/3] leasetime support for globally

2017-06-22 Thread Alberto Ruiz
2017-06-21 17:30 GMT+01:00 Laine Stump :

> On 06/21/2017 03:27 AM, Peter Krempa wrote:
> > On Tue, Jun 20, 2017 at 19:00:43 +0100, ar...@gnome.org wrote:
> >> From: Alberto Ruiz 
> >
> > Missing commit message.
>
> And when composing the commit message, it's useful to include links to
> the associated BZ.
>
>   https://bugzilla.redhat.com/show_bug.cgi?id=913446
>
> Also, I recall there being quite a lot of discussion in email (and
> possibly IRC) about the fact that people *think* they want a
> configurable lease time because they think that will eliminate cases of
> a DHCP lease being lost while a domain is paused. It was pointed out
> that lengthening the lease will *not* eliminate that problem (it just
> makes it happen less often).
>
> As an alternate (and better) solution to the problem of lost leases, we
> then added the "dhcp-authoritative" option to dnsmasq (commit
> 4ac20b3ae4), which allows clients to re-acquire the same IP as they had
> for an expired lease (as long as it hasn't been acquired by someone else
> in the meantime, which is apparently unlikely unless all the other
> addresses in the pool are already assigned).
>
> I'm not saying this to discourage the idea of making leasetime
> configurable (I think we'd already agreed that it was reasonable to do
> so, but there were two competing patches posted, and neither of them was
> really push-ready), but just to make sure that nobody is disappointed if
> the results don't lead to the behavior they're hoping for.
>
>
> >
> >>
> >> ---
> >>  docs/schemas/basictypes.rng   | 16 +
> >>  docs/schemas/network.rng  |  8 +++
> >>  src/conf/network_conf.c   | 78
> ++-
> >>  src/conf/network_conf.h   |  3 +-
> >>  src/network/bridge_driver.c   | 49 +-
> >>  tests/networkxml2confdata/leasetime-days.conf | 17 +
> >>  tests/networkxml2confdata/leasetime-days.xml  | 18 ++
> >>  tests/networkxml2confdata/leasetime-hours.conf| 17 +
> >>  tests/networkxml2confdata/leasetime-hours.xml | 18 ++
> >>  tests/networkxml2confdata/leasetime-infinite.conf | 17 +
> >>  tests/networkxml2confdata/leasetime-infinite.xml  | 18 ++
> >>  tests/networkxml2confdata/leasetime-minutes.conf  | 17 +
> >>  tests/networkxml2confdata/leasetime-minutes.xml   | 18 ++
> >>  tests/networkxml2confdata/leasetime-seconds.conf  | 17 +
> >>  tests/networkxml2confdata/leasetime-seconds.xml   | 18 ++
> >>  tests/networkxml2confdata/leasetime.conf  | 17 +
> >>  tests/networkxml2confdata/leasetime.xml   | 18 ++
> >>  tests/networkxml2conftest.c   |  7 ++
> >>  18 files changed, 368 insertions(+), 3 deletions(-)
> >>  create mode 100644 tests/networkxml2confdata/leasetime-days.conf
> >>  create mode 100644 tests/networkxml2confdata/leasetime-days.xml
> >>  create mode 100644 tests/networkxml2confdata/leasetime-hours.conf
> >>  create mode 100644 tests/networkxml2confdata/leasetime-hours.xml
> >>  create mode 100644 tests/networkxml2confdata/leasetime-infinite.conf
> >>  create mode 100644 tests/networkxml2confdata/leasetime-infinite.xml
> >>  create mode 100644 tests/networkxml2confdata/leasetime-minutes.conf
> >>  create mode 100644 tests/networkxml2confdata/leasetime-minutes.xml
> >>  create mode 100644 tests/networkxml2confdata/leasetime-seconds.conf
> >>  create mode 100644 tests/networkxml2confdata/leasetime-seconds.xml
> >>  create mode 100644 tests/networkxml2confdata/leasetime.conf
> >>  create mode 100644 tests/networkxml2confdata/leasetime.xml
> >>
> >> diff --git a/docs/schemas/basictypes.rng b/docs/schemas/basictypes.rng
> >> index 1b4f980e7..8a76c235a 100644
> >> --- a/docs/schemas/basictypes.rng
> >> +++ b/docs/schemas/basictypes.rng
> >> @@ -518,4 +518,20 @@
> >>  
> >>
> >>
> >> +  
> >> +
> >> +  seconds
> >> +  minutes
> >> +  hours
> >> +  days
> >> +
> >> +  
>
> Maybe call this "timeUnit" in case some other attribute in the future
> needs it?
>
> >> +
> >> +  
> >> +
> >> +  -1
> >> +  4294967295
> >> +
> >> +  
> >> +
> >>  
> >> diff --git a/docs/schemas/network.rng b/docs/schemas/network.rng
> >> index 1a18e64b2..4b8056ab6 100644
> >> --- a/docs/schemas/network.rng
> >> +++ b/docs/schemas/network.rng
> >> @@ -340,6 +340,14 @@
> >>
> >>
> >> +
> >> +  
> >> +
> >> +   name="leaseTimeUnit"/>
> >
> > This does not follow the XML style used everywhere else.
> >
> >> +
> >> +
> >> +  
> >> +
> >>  
> >>
> >>   name="ipAddr"/>
> >> diff --git a/src/conf/network_conf.c b/src/conf/network_conf.c
> >> index aa397768c..6f051493f 

Re: [libvirt] [PATCH 1/3] leasetime support for globally

2017-06-22 Thread Alberto Ruiz
2017-06-21 17:30 GMT+01:00 Laine Stump :

> On 06/21/2017 03:27 AM, Peter Krempa wrote:
> > On Tue, Jun 20, 2017 at 19:00:43 +0100, ar...@gnome.org wrote:
> >> From: Alberto Ruiz 
> >
> > Missing commit message.
>
> And when composing the commit message, it's useful to include links to
> the associated BZ.
>
>   https://bugzilla.redhat.com/show_bug.cgi?id=913446
>
> Also, I recall there being quite a lot of discussion in email (and
> possibly IRC) about the fact that people *think* they want a
> configurable lease time because they think that will eliminate cases of
> a DHCP lease being lost while a domain is paused. It was pointed out
> that lengthening the lease will *not* eliminate that problem (it just
> makes it happen less often).
>
> As an alternate (and better) solution to the problem of lost leases, we
> then added the "dhcp-authoritative" option to dnsmasq (commit
> 4ac20b3ae4), which allows clients to re-acquire the same IP as they had
> for an expired lease (as long as it hasn't been acquired by someone else
> in the meantime, which is apparently unlikely unless all the other
> addresses in the pool are already assigned).
>
> I'm not saying this to discourage the idea of making leasetime
> configurable (I think we'd already agreed that it was reasonable to do
> so, but there were two competing patches posted, and neither of them was
> really push-ready), but just to make sure that nobody is disappointed if
> the results don't lead to the behavior they're hoping for.
>
>
> >
> >>
> >> ---
> >>  docs/schemas/basictypes.rng   | 16 +
> >>  docs/schemas/network.rng  |  8 +++
> >>  src/conf/network_conf.c   | 78
> ++-
> >>  src/conf/network_conf.h   |  3 +-
> >>  src/network/bridge_driver.c   | 49 +-
> >>  tests/networkxml2confdata/leasetime-days.conf | 17 +
> >>  tests/networkxml2confdata/leasetime-days.xml  | 18 ++
> >>  tests/networkxml2confdata/leasetime-hours.conf| 17 +
> >>  tests/networkxml2confdata/leasetime-hours.xml | 18 ++
> >>  tests/networkxml2confdata/leasetime-infinite.conf | 17 +
> >>  tests/networkxml2confdata/leasetime-infinite.xml  | 18 ++
> >>  tests/networkxml2confdata/leasetime-minutes.conf  | 17 +
> >>  tests/networkxml2confdata/leasetime-minutes.xml   | 18 ++
> >>  tests/networkxml2confdata/leasetime-seconds.conf  | 17 +
> >>  tests/networkxml2confdata/leasetime-seconds.xml   | 18 ++
> >>  tests/networkxml2confdata/leasetime.conf  | 17 +
> >>  tests/networkxml2confdata/leasetime.xml   | 18 ++
> >>  tests/networkxml2conftest.c   |  7 ++
> >>  18 files changed, 368 insertions(+), 3 deletions(-)
> >>  create mode 100644 tests/networkxml2confdata/leasetime-days.conf
> >>  create mode 100644 tests/networkxml2confdata/leasetime-days.xml
> >>  create mode 100644 tests/networkxml2confdata/leasetime-hours.conf
> >>  create mode 100644 tests/networkxml2confdata/leasetime-hours.xml
> >>  create mode 100644 tests/networkxml2confdata/leasetime-infinite.conf
> >>  create mode 100644 tests/networkxml2confdata/leasetime-infinite.xml
> >>  create mode 100644 tests/networkxml2confdata/leasetime-minutes.conf
> >>  create mode 100644 tests/networkxml2confdata/leasetime-minutes.xml
> >>  create mode 100644 tests/networkxml2confdata/leasetime-seconds.conf
> >>  create mode 100644 tests/networkxml2confdata/leasetime-seconds.xml
> >>  create mode 100644 tests/networkxml2confdata/leasetime.conf
> >>  create mode 100644 tests/networkxml2confdata/leasetime.xml
> >>
> >> diff --git a/docs/schemas/basictypes.rng b/docs/schemas/basictypes.rng
> >> index 1b4f980e7..8a76c235a 100644
> >> --- a/docs/schemas/basictypes.rng
> >> +++ b/docs/schemas/basictypes.rng
> >> @@ -518,4 +518,20 @@
> >>  
> >>
> >>
> >> +  
> >> +
> >> +  seconds
> >> +  minutes
> >> +  hours
> >> +  days
> >> +
> >> +  
>
> Maybe call this "timeUnit" in case some other attribute in the future
> needs it?
>
> >> +
> >> +  
> >> +
> >> +  -1
> >> +  4294967295
> >> +
> >> +  
> >> +
> >>  
> >> diff --git a/docs/schemas/network.rng b/docs/schemas/network.rng
> >> index 1a18e64b2..4b8056ab6 100644
> >> --- a/docs/schemas/network.rng
> >> +++ b/docs/schemas/network.rng
> >> @@ -340,6 +340,14 @@
> >>
> >>
> >> +
> >> +  
> >> +
> >> +   name="leaseTimeUnit"/>
> >
> > This does not follow the XML style used everywhere else.
> >
> >> +
> >> +
> >> +  
> >> +
> >>  
> >>
> >>   name="ipAddr"/>
> >> diff --git a/src/conf/network_conf.c b/src/conf/network_conf.c
> >> index aa397768c..6f051493f 

Re: [libvirt] RFC: Creating mediated devices with libvirt

2017-06-22 Thread Daniel P. Berrange
On Thu, Jun 22, 2017 at 12:33:16PM -0400, Laine Stump wrote:
> On 06/22/2017 11:28 AM, Alex Williamson wrote:
> > On Thu, 22 Jun 2017 17:14:48 +0200
> > Erik Skultety  wrote:
> > 
> >> [...]
> 
>  ^this is the thing we constantly keep discussing as everyone has a 
>  slightly
>  different angle of view - libvirt does not implement any kind of policy,
>  therefore the only "configuration" would be the PCI parent placement - 
>  you say
>  what to do and we do it, no logic in it, that's it. Now, I don't 
>  understand
>  taking care of the guesswork for the user in the simplest manner 
>  possible as
>  policy rather as a mere convenience, be it just for developers and 
>  testers, but
>  even that might apparently be perceived as a policy and therefore 
>  unacceptable.
> 
>  I still stand by idea of having auto-creation as unfortunately, I sort 
>  of still
>  fail to understand what the negative implications of having it are - is 
>  that it
>  would get just unnecessarily too complex to maintain in the future that 
>  we would
>  regret it or that we'd get a huge amount of follow-up requests for 
>  extending the
>  feature or is it just that simply the interpretation of auto-create == 
>  policy?  
> >>>
> >>> The increasing complexity of the qemu driver is a significant concern with
> >>> adding policy based logic to the code. THinking about this though, if we
> >>> provide the inactive node device feature, then we can avoid essentially
> >>> all new code and complexity QEMU driver, and still support auto-create.
> >>>
> >>> ie, in the domain XML we just continue to have the exact same XML that
> >>> we already have today for mdevs, but with a single new attribute
> >>> autocreate=yes|no
> >>>
> >>>   
> >>>  >>> autocreate="yes">
> >>> 
> >>> 
> >>
> >> So, just for clarification of the concept, the device with ^this UUID will 
> >> have
> >> had to be defined by the nodedev API by the time we start to edit the 
> >> domain
> >> XML in this manner in which case the only thing the autocreate=yes would 
> >> do is
> >> to actually create the mdev according to the nodedev config, right? 
> >> Continuing
> >> with that thought, if UUID doesn't refer to any of the inactive configs it 
> >> will
> >> be an error I suppose? What about the fact that only one vgpu type can 
> >> live on
> >> the GPU? even if you can successfully identify a device using the UUID in 
> >> this
> >> way, you'll still face the problem, that other types might be currently
> >> occupying the GPU and need to be torn down first, will this be automated as
> >> well in what you suggest? I assume not.
> >>
> >>> 
> >>> 
> >>>   
> >>>
> >>> In the QEMU driver, then the only change required is
> >>>
> >>>if (def->autocreate)
> >>>virNodeDeviceCreate(dev)  
> >>
> >> Aha, so if a device gets torn down on shutdown, we won't face the problem 
> >> with
> >> some other devices being active, all of them will have to be in the 
> >> inactive
> >> state because they got torn down during the last shutdown - that would 
> >> work.
> > 
> > 
> > I'm not familiar with how inactive devices would be defined in the
> > nodedev API, would someone mind explaining or providing an example
> > please?  I don't understand where the metadata is stored that describes
> > the what and where of a given UUID.  Thanks,
> 
> You don't understand it because it doesn't exist yet :-)
> 
> The idea is essentially the same that we've talked about, except that
> all the information about parent PCI address, desired type of child, and
> anything else (is there anything else?) is stored in some
> not-yet-specified persistent node device config rather than directly in
> the domain XML. Maybe something like:
> 
>   
> BobLobLaw
> 
>   
> 
> 
>   
> 
> I haven't thought about how it would show the difference between active
> and inactive - didn't get enough coffee today and I have a headache.

The XML doesn't need to show the difference between active & inactive.

That distinction is something you filter on when querying the list
of devices. We'd want to add  a virNodeDeviceIsActive() API like
we have for other objects too, so you can query it afterwards too.


> ... okay, another "shower thought" is coming in... One deficiency of
> this comes to mind - since the domain config references the device by
> uuid, and an existing child device's uuid can't be changed, the unique
> uuid used by a particular domain must be defined on all of the hosts
> that the domain might be moved to. And since other domains can't share
> that uuid (unless you're 100% sure they'll never be active at the same
> time), you won't be able to implement the alternate idea of "pre-create
> all the devices, then assign them to domains as needed"; instead, you'll
> be forced to use the "create-on-demand" model.

You can still 

Re: [libvirt] RFC: Creating mediated devices with libvirt

2017-06-22 Thread Laine Stump
On 06/22/2017 12:15 PM, Daniel P. Berrange wrote:
> On Thu, Jun 22, 2017 at 05:14:48PM +0200, Erik Skultety wrote:
>> [...]

 ^this is the thing we constantly keep discussing as everyone has a slightly
 different angle of view - libvirt does not implement any kind of policy,
 therefore the only "configuration" would be the PCI parent placement - you 
 say
 what to do and we do it, no logic in it, that's it. Now, I don't understand
 taking care of the guesswork for the user in the simplest manner possible 
 as
 policy rather as a mere convenience, be it just for developers and 
 testers, but
 even that might apparently be perceived as a policy and therefore 
 unacceptable.

 I still stand by idea of having auto-creation as unfortunately, I sort of 
 still
 fail to understand what the negative implications of having it are - is 
 that it
 would get just unnecessarily too complex to maintain in the future that we 
 would
 regret it or that we'd get a huge amount of follow-up requests for 
 extending the
 feature or is it just that simply the interpretation of auto-create == 
 policy?
>>>
>>> The increasing complexity of the qemu driver is a significant concern with
>>> adding policy based logic to the code. THinking about this though, if we
>>> provide the inactive node device feature, then we can avoid essentially
>>> all new code and complexity QEMU driver, and still support auto-create.
>>>
>>> ie, in the domain XML we just continue to have the exact same XML that
>>> we already have today for mdevs, but with a single new attribute
>>> autocreate=yes|no
>>>
>>>   
>>> 
>>> 
>>>   
>>
>> So, just for clarification of the concept, the device with ^this UUID will 
>> have
>> had to be defined by the nodedev API by the time we start to edit the domain
>> XML in this manner in which case the only thing the autocreate=yes would do 
>> is
>> to actually create the mdev according to the nodedev config, right? 
>> Continuing
>> with that thought, if UUID doesn't refer to any of the inactive configs it 
>> will
>> be an error I suppose? What about the fact that only one vgpu type can live 
>> on
>> the GPU? even if you can successfully identify a device using the UUID in 
>> this
>> way, you'll still face the problem, that other types might be currently
>> occupying the GPU and need to be torn down first, will this be automated as
>> well in what you suggest? I assume not.
> 
> Technically we shouldn't need the node device to exist at the time we
> define the XML - only at the time we start the guest, does the node
> device have to exist. eg same way you list a virtual network as the
> source of a guest NIC, but that virtual network doesn't have to actually
> have been defined & started until the guest starts.
> 
> If there are constraints that a pGPU can only support a certain combination
> of vGPUs at any single point in time, doesn't the kernel already  enforce
> that when you try to create the vGPU in sysfs. IOW, we merely need to try
> to create the vGPU, and if the kernel mdev driver doesn't allow you to mix
> that with the other vGPUs that already exist, then we'd just report an
> error from virNodeDeviceCreate, and that'd get propagated back as the
> error for the virDomainCreate call.
> 
>>
>>> 
>>> 
>>>   
>>>
>>> In the QEMU driver, then the only change required is
>>>
>>>if (def->autocreate)
>>>virNodeDeviceCreate(dev)
>>
>> Aha, so if a device gets torn down on shutdown, we won't face the problem 
>> with
>> some other devices being active, all of them will have to be in the inactive
>> state because they got torn down during the last shutdown - that would work.
> 
> I'm not sure what the relationship with other active devices is relevant
> here. The virNodeDevicePtr we're accesing here is a single vGPU - if other
> running guests have further vGPUs on the same pGPU, that's not really
> relevant. Each vGPU is created/deleted as required.

I think he's talking about devices that were previously used by other
domains that are no longer active. Since they're also automatically
destroyed, they're not a problem.

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


Re: [libvirt] RFC: Creating mediated devices with libvirt

2017-06-22 Thread Laine Stump
On 06/22/2017 11:28 AM, Alex Williamson wrote:
> On Thu, 22 Jun 2017 17:14:48 +0200
> Erik Skultety  wrote:
> 
>> [...]

 ^this is the thing we constantly keep discussing as everyone has a slightly
 different angle of view - libvirt does not implement any kind of policy,
 therefore the only "configuration" would be the PCI parent placement - you 
 say
 what to do and we do it, no logic in it, that's it. Now, I don't understand
 taking care of the guesswork for the user in the simplest manner possible 
 as
 policy rather as a mere convenience, be it just for developers and 
 testers, but
 even that might apparently be perceived as a policy and therefore 
 unacceptable.

 I still stand by idea of having auto-creation as unfortunately, I sort of 
 still
 fail to understand what the negative implications of having it are - is 
 that it
 would get just unnecessarily too complex to maintain in the future that we 
 would
 regret it or that we'd get a huge amount of follow-up requests for 
 extending the
 feature or is it just that simply the interpretation of auto-create == 
 policy?  
>>>
>>> The increasing complexity of the qemu driver is a significant concern with
>>> adding policy based logic to the code. THinking about this though, if we
>>> provide the inactive node device feature, then we can avoid essentially
>>> all new code and complexity QEMU driver, and still support auto-create.
>>>
>>> ie, in the domain XML we just continue to have the exact same XML that
>>> we already have today for mdevs, but with a single new attribute
>>> autocreate=yes|no
>>>
>>>   
>>> 
>>> 
>>> 
>>
>> So, just for clarification of the concept, the device with ^this UUID will 
>> have
>> had to be defined by the nodedev API by the time we start to edit the domain
>> XML in this manner in which case the only thing the autocreate=yes would do 
>> is
>> to actually create the mdev according to the nodedev config, right? 
>> Continuing
>> with that thought, if UUID doesn't refer to any of the inactive configs it 
>> will
>> be an error I suppose? What about the fact that only one vgpu type can live 
>> on
>> the GPU? even if you can successfully identify a device using the UUID in 
>> this
>> way, you'll still face the problem, that other types might be currently
>> occupying the GPU and need to be torn down first, will this be automated as
>> well in what you suggest? I assume not.
>>
>>> 
>>> 
>>>   
>>>
>>> In the QEMU driver, then the only change required is
>>>
>>>if (def->autocreate)
>>>virNodeDeviceCreate(dev)  
>>
>> Aha, so if a device gets torn down on shutdown, we won't face the problem 
>> with
>> some other devices being active, all of them will have to be in the inactive
>> state because they got torn down during the last shutdown - that would work.
> 
> 
> I'm not familiar with how inactive devices would be defined in the
> nodedev API, would someone mind explaining or providing an example
> please?  I don't understand where the metadata is stored that describes
> the what and where of a given UUID.  Thanks,

You don't understand it because it doesn't exist yet :-)

The idea is essentially the same that we've talked about, except that
all the information about parent PCI address, desired type of child, and
anything else (is there anything else?) is stored in some
not-yet-specified persistent node device config rather than directly in
the domain XML. Maybe something like:

  
BobLobLaw

  


  

I haven't thought about how it would show the difference between active
and inactive - didn't get enough coffee today and I have a headache.

The advantage of this is that it uncouples the  specifics of the child
device from the domain XML - the only thing in the domain XML is the
uuid. So a device config with that uuid would need to exist on every
host where you wanted to run a particular guest, but the details could
be different, yet you wouldn't need to edit the domain XML. This is a
similar concept to the idea of creating libvirt networks that are just
an indirect pointer to a bridge device (which may have a different name
on each host) or to an SRIOV PF (yeah, I know Dan doesn't like that
feature, but I find it very useful, and unobtrusive if management
chooses not to use it).

So from your point of view (I'm talking to Alex here), implementing it
this way would mean that you would need to create the child device
definitions in the nodedev driver once (and possibly/hopefully the uuid
of the devices would be autogenerated, same as we do for uuids in other
parts of libvirt config), then copy that uuid to the domain config one
time. But after doing that once, you would be able to start and stop
domains and the host without any extra action. You could also define
different nodedevices that used the same parent for different child
types, and reference them 

[libvirt] [PATCH 4/8] qemuDomainCreateDeviceRecursive: Fail on unsupported file type

2017-06-22 Thread Michal Privoznik
Currently, we silently assume that file we are creating in the
namespace is either a link or a device (character or block one).
This is not always the case. Therefore instead of doing something
wrong, claim about unsupported file type.

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

diff --git a/src/qemu/qemu_domain.c b/src/qemu/qemu_domain.c
index 286d60761..e6fb041de 100644
--- a/src/qemu/qemu_domain.c
+++ b/src/qemu/qemu_domain.c
@@ -7707,6 +7707,7 @@ qemuDomainCreateDeviceRecursive(const char *device,
 struct stat sb;
 int ret = -1;
 bool isLink = false;
+bool isDev = false;
 bool create = false;
 #ifdef WITH_SELINUX
 char *tcon = NULL;
@@ -7729,6 +7730,7 @@ qemuDomainCreateDeviceRecursive(const char *device,
 }
 
 isLink = S_ISLNK(sb.st_mode);
+isDev = S_ISCHR(sb.st_mode) || S_ISBLK(sb.st_mode);
 
 /* Here, @device might be whatever path in the system. We
  * should create the path in the namespace iff it's "/dev"
@@ -7828,7 +7830,7 @@ qemuDomainCreateDeviceRecursive(const char *device,
 if (qemuDomainCreateDeviceRecursive(target, data,
 allow_noent, ttl - 1) < 0)
 goto cleanup;
-} else {
+} else if (isDev) {
 if (create &&
 mknod(devicePath, sb.st_mode, sb.st_rdev) < 0) {
 if (errno == EEXIST) {
@@ -7850,6 +7852,11 @@ qemuDomainCreateDeviceRecursive(const char *device,
  devicePath);
 goto cleanup;
 }
+} else {
+virReportError(VIR_ERR_OPERATION_UNSUPPORTED,
+   _("unsupported device type %s %o"),
+   device, (int) sb.st_mode);
+goto cleanup;
 }
 
 if (!create) {
-- 
2.13.0

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


[libvirt] [PATCH 2/8] qemuDomainBuildNamespace: Handle special file mount points

2017-06-22 Thread Michal Privoznik
https://bugzilla.redhat.com/show_bug.cgi?id=1459592

In 290a00e41d I've tried to fix the process of building a
qemu namespace when dealing with file mount points. What I
haven't realized then is that we might be dealing not with just
regular files but also special files (like sockets). Indeed, try
the following:

1) socat unix-listen:/tmp/soket stdio
2) touch /dev/socket
3) mount --bind /tmp/socket /dev/socket
4) virsh start anyDomain

Problem with my previous approach is that I wasn't creating the
temporary location (where mount points under /dev are moved) for
anything but directories and regular files.

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

diff --git a/src/qemu/qemu_domain.c b/src/qemu/qemu_domain.c
index 8e7404da6..212717c80 100644
--- a/src/qemu/qemu_domain.c
+++ b/src/qemu/qemu_domain.c
@@ -8356,9 +8356,11 @@ qemuDomainBuildNamespace(virQEMUDriverConfigPtr cfg,
 goto cleanup;
 }
 
-/* At this point, devMountsPath is either a regular file or a 
directory. */
+/* At this point, devMountsPath is either:
+ * a file (regular or special), or
+ * a directory. */
 if ((S_ISDIR(sb.st_mode) && virFileMakePath(devMountsSavePath[i]) < 0) 
||
-(S_ISREG(sb.st_mode) && virFileTouch(devMountsSavePath[i], 
sb.st_mode) < 0)) {
+(!S_ISDIR(sb.st_mode) && virFileTouch(devMountsSavePath[i], 
sb.st_mode) < 0)) {
 virReportSystemError(errno,
  _("Failed to create %s"),
  devMountsSavePath[i]);
-- 
2.13.0

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


[libvirt] [PATCH 1/8] conf: Rename and expose virDomainChrSourceDefPath

2017-06-22 Thread Michal Privoznik
It comes very handy to have source path for chardevs. We already
have such function: virDomainAuditChardevPath() but it's static
and has name not suitable for exposing.

Signed-off-by: Michal Privoznik 
---
 src/conf/domain_audit.c  | 44 ++--
 src/conf/domain_conf.c   | 33 +
 src/conf/domain_conf.h   |  2 ++
 src/libvirt_private.syms |  1 +
 4 files changed, 42 insertions(+), 38 deletions(-)

diff --git a/src/conf/domain_audit.c b/src/conf/domain_audit.c
index 1e667af73..484420a21 100644
--- a/src/conf/domain_audit.c
+++ b/src/conf/domain_audit.c
@@ -68,38 +68,6 @@ virDomainAuditGetRdev(const char *path ATTRIBUTE_UNUSED)
 #endif
 
 
-static const char *
-virDomainAuditChardevPath(virDomainChrSourceDefPtr chr)
-{
-if (!chr)
-return NULL;
-
-switch ((virDomainChrType) chr->type) {
-case VIR_DOMAIN_CHR_TYPE_PTY:
-case VIR_DOMAIN_CHR_TYPE_DEV:
-case VIR_DOMAIN_CHR_TYPE_FILE:
-case VIR_DOMAIN_CHR_TYPE_PIPE:
-case VIR_DOMAIN_CHR_TYPE_NMDM:
-return chr->data.file.path;
-
-case VIR_DOMAIN_CHR_TYPE_UNIX:
-return chr->data.nix.path;
-
-case VIR_DOMAIN_CHR_TYPE_TCP:
-case VIR_DOMAIN_CHR_TYPE_UDP:
-case VIR_DOMAIN_CHR_TYPE_NULL:
-case VIR_DOMAIN_CHR_TYPE_VC:
-case VIR_DOMAIN_CHR_TYPE_STDIO:
-case VIR_DOMAIN_CHR_TYPE_SPICEVMC:
-case VIR_DOMAIN_CHR_TYPE_SPICEPORT:
-case VIR_DOMAIN_CHR_TYPE_LAST:
-return NULL;
-}
-
-return NULL;
-}
-
-
 static void
 virDomainAuditGenericDev(virDomainObjPtr vm,
  const char *type,
@@ -178,8 +146,8 @@ virDomainAuditChardev(virDomainObjPtr vm,
 newsrc = newDef->source;
 
 virDomainAuditGenericDev(vm, "chardev",
- virDomainAuditChardevPath(oldsrc),
- virDomainAuditChardevPath(newsrc),
+ virDomainChrSourceDefPath(oldsrc),
+ virDomainChrSourceDefPath(newsrc),
  reason, success);
 }
 
@@ -218,7 +186,7 @@ virDomainAuditSmartcard(virDomainObjPtr vm,
 
 case VIR_DOMAIN_SMARTCARD_TYPE_PASSTHROUGH:
 virDomainAuditGenericDev(vm, "smartcard", NULL,
- 
virDomainAuditChardevPath(def->data.passthru),
+ 
virDomainChrSourceDefPath(def->data.passthru),
  reason, success);
 break;
 
@@ -264,7 +232,7 @@ virDomainAuditRNG(virDomainObjPtr vm,
 break;
 
 case VIR_DOMAIN_RNG_BACKEND_EGD:
-newsrcpath = virDomainAuditChardevPath(newDef->source.chardev);
+newsrcpath = virDomainChrSourceDefPath(newDef->source.chardev);
 break;
 
 case VIR_DOMAIN_RNG_BACKEND_LAST:
@@ -279,7 +247,7 @@ virDomainAuditRNG(virDomainObjPtr vm,
 break;
 
 case VIR_DOMAIN_RNG_BACKEND_EGD:
-oldsrcpath = virDomainAuditChardevPath(oldDef->source.chardev);
+oldsrcpath = virDomainChrSourceDefPath(oldDef->source.chardev);
 break;
 
 case VIR_DOMAIN_RNG_BACKEND_LAST:
@@ -982,7 +950,7 @@ virDomainAuditShmem(virDomainObjPtr vm,
 {
 char uuidstr[VIR_UUID_STRING_BUFLEN];
 char *vmname = virAuditEncode("vm", vm->def->name);
-const char *srcpath = virDomainAuditChardevPath(>server.chr);
+const char *srcpath = virDomainChrSourceDefPath(>server.chr);
 const char *virt = virDomainVirtTypeToString(vm->def->virtType);
 char *shmpath = NULL;
 
diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c
index 0409c62ef..2cbe96b6e 100644
--- a/src/conf/domain_conf.c
+++ b/src/conf/domain_conf.c
@@ -2034,6 +2034,39 @@ virDomainNetDefFree(virDomainNetDefPtr def)
 VIR_FREE(def);
 }
 
+
+const char *
+virDomainChrSourceDefPath(virDomainChrSourceDefPtr chr)
+{
+if (!chr)
+return NULL;
+
+switch ((virDomainChrType) chr->type) {
+case VIR_DOMAIN_CHR_TYPE_PTY:
+case VIR_DOMAIN_CHR_TYPE_DEV:
+case VIR_DOMAIN_CHR_TYPE_FILE:
+case VIR_DOMAIN_CHR_TYPE_PIPE:
+case VIR_DOMAIN_CHR_TYPE_NMDM:
+return chr->data.file.path;
+
+case VIR_DOMAIN_CHR_TYPE_UNIX:
+return chr->data.nix.path;
+
+case VIR_DOMAIN_CHR_TYPE_TCP:
+case VIR_DOMAIN_CHR_TYPE_UDP:
+case VIR_DOMAIN_CHR_TYPE_NULL:
+case VIR_DOMAIN_CHR_TYPE_VC:
+case VIR_DOMAIN_CHR_TYPE_STDIO:
+case VIR_DOMAIN_CHR_TYPE_SPICEVMC:
+case VIR_DOMAIN_CHR_TYPE_SPICEPORT:
+case VIR_DOMAIN_CHR_TYPE_LAST:
+return NULL;
+}
+
+return NULL;
+}
+
+
 void ATTRIBUTE_NONNULL(1)
 virDomainChrSourceDefClear(virDomainChrSourceDefPtr def)
 {
diff --git a/src/conf/domain_conf.h b/src/conf/domain_conf.h
index 6d9ee9787..51b830917 100644
--- a/src/conf/domain_conf.h
+++ b/src/conf/domain_conf.h
@@ -3256,6 +3256,8 @@ int virDomainDefFindDevice(virDomainDefPtr def,

Re: [libvirt] [PATCH 1/3] leasetime support for globally

2017-06-22 Thread Alberto Ruiz
Hello Laine,

2017-06-21 17:30 GMT+01:00 Laine Stump :

> On 06/21/2017 03:27 AM, Peter Krempa wrote:
> > On Tue, Jun 20, 2017 at 19:00:43 +0100, ar...@gnome.org wrote:
> >> From: Alberto Ruiz 
> >
> > Missing commit message.
>
> And when composing the commit message, it's useful to include links to
> the associated BZ.
>
>   https://bugzilla.redhat.com/show_bug.cgi?id=913446
>
> Also, I recall there being quite a lot of discussion in email (and
> possibly IRC) about the fact that people *think* they want a
> configurable lease time because they think that will eliminate cases of
> a DHCP lease being lost while a domain is paused. It was pointed out
> that lengthening the lease will *not* eliminate that problem (it just
> makes it happen less often).
>
> As an alternate (and better) solution to the problem of lost leases, we
> then added the "dhcp-authoritative" option to dnsmasq (commit
> 4ac20b3ae4), which allows clients to re-acquire the same IP as they had
> for an expired lease (as long as it hasn't been acquired by someone else
> in the meantime, which is apparently unlikely unless all the other
> addresses in the pool are already assigned).
>
> I'm not saying this to discourage the idea of making leasetime
> configurable (I think we'd already agreed that it was reasonable to do
> so, but there were two competing patches posted, and neither of them was
> really push-ready), but just to make sure that nobody is disappointed if
> the results don't lead to the behavior they're hoping for.
>

My main motivation _was_ the loss of IP addresses after reboot on GNOME
Boxes.

However, given that I've written the patches already and some people might
find this useful, I'm okay with going ahead and get them ready for approval.


> >
> >>
> >> ---
> >>  docs/schemas/basictypes.rng   | 16 +
> >>  docs/schemas/network.rng  |  8 +++
> >>  src/conf/network_conf.c   | 78
> ++-
> >>  src/conf/network_conf.h   |  3 +-
> >>  src/network/bridge_driver.c   | 49 +-
> >>  tests/networkxml2confdata/leasetime-days.conf | 17 +
> >>  tests/networkxml2confdata/leasetime-days.xml  | 18 ++
> >>  tests/networkxml2confdata/leasetime-hours.conf| 17 +
> >>  tests/networkxml2confdata/leasetime-hours.xml | 18 ++
> >>  tests/networkxml2confdata/leasetime-infinite.conf | 17 +
> >>  tests/networkxml2confdata/leasetime-infinite.xml  | 18 ++
> >>  tests/networkxml2confdata/leasetime-minutes.conf  | 17 +
> >>  tests/networkxml2confdata/leasetime-minutes.xml   | 18 ++
> >>  tests/networkxml2confdata/leasetime-seconds.conf  | 17 +
> >>  tests/networkxml2confdata/leasetime-seconds.xml   | 18 ++
> >>  tests/networkxml2confdata/leasetime.conf  | 17 +
> >>  tests/networkxml2confdata/leasetime.xml   | 18 ++
> >>  tests/networkxml2conftest.c   |  7 ++
> >>  18 files changed, 368 insertions(+), 3 deletions(-)
> >>  create mode 100644 tests/networkxml2confdata/leasetime-days.conf
> >>  create mode 100644 tests/networkxml2confdata/leasetime-days.xml
> >>  create mode 100644 tests/networkxml2confdata/leasetime-hours.conf
> >>  create mode 100644 tests/networkxml2confdata/leasetime-hours.xml
> >>  create mode 100644 tests/networkxml2confdata/leasetime-infinite.conf
> >>  create mode 100644 tests/networkxml2confdata/leasetime-infinite.xml
> >>  create mode 100644 tests/networkxml2confdata/leasetime-minutes.conf
> >>  create mode 100644 tests/networkxml2confdata/leasetime-minutes.xml
> >>  create mode 100644 tests/networkxml2confdata/leasetime-seconds.conf
> >>  create mode 100644 tests/networkxml2confdata/leasetime-seconds.xml
> >>  create mode 100644 tests/networkxml2confdata/leasetime.conf
> >>  create mode 100644 tests/networkxml2confdata/leasetime.xml
> >>
> >> diff --git a/docs/schemas/basictypes.rng b/docs/schemas/basictypes.rng
> >> index 1b4f980e7..8a76c235a 100644
> >> --- a/docs/schemas/basictypes.rng
> >> +++ b/docs/schemas/basictypes.rng
> >> @@ -518,4 +518,20 @@
> >>  
> >>
> >>
> >> +  
> >> +
> >> +  seconds
> >> +  minutes
> >> +  hours
> >> +  days
> >> +
> >> +  
>
> Maybe call this "timeUnit" in case some other attribute in the future
> needs it?
>

sounds good to me. noted


>
> >> +
> >> +  
> >> +
> >> +  -1
> >> +  4294967295
> >> +
> >> +  
> >> +
> >>  
> >> diff --git a/docs/schemas/network.rng b/docs/schemas/network.rng
> >> index 1a18e64b2..4b8056ab6 100644
> >> --- a/docs/schemas/network.rng
> >> +++ b/docs/schemas/network.rng
> >> @@ -340,6 +340,14 @@
> >>
> >>
> >> +
> >> +  
> >> +
> >> +   name="leaseTimeUnit"/>
> >
> > This does not follow the XML style used everywhere else.
>

I'm not sure I 

[libvirt] [PATCH 8/8] qemu ns: Create chardev backends more frequently

2017-06-22 Thread Michal Privoznik
Currently, the only type of chardev that we create the backend
for in the namespace is type='dev'. This is not enough, other
backends might have files under /dev too. For instance channels
might have a unix socket under /dev (well, bind mounted under
/dev from a different place).

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

diff --git a/src/qemu/qemu_domain.c b/src/qemu/qemu_domain.c
index 51779c535..65eec26dd 100644
--- a/src/qemu/qemu_domain.c
+++ b/src/qemu/qemu_domain.c
@@ -7732,7 +7732,7 @@ qemuDomainCreateDeviceRecursive(const char *device,
 
 isLink = S_ISLNK(sb.st_mode);
 isDev = S_ISCHR(sb.st_mode) || S_ISBLK(sb.st_mode);
-isReg = S_ISREG(sb.st_mode);
+isReg = S_ISREG(sb.st_mode) || S_ISFIFO(sb.st_mode) || 
S_ISSOCK(sb.st_mode);
 
 /* Here, @device might be whatever path in the system. We
  * should create the path in the namespace iff it's "/dev"
@@ -8129,11 +8129,17 @@ qemuDomainSetupChardev(virDomainDefPtr def 
ATTRIBUTE_UNUSED,
void *opaque)
 {
 const struct qemuDomainCreateDeviceData *data = opaque;
+const char *path = NULL;
 
-if (dev->source->type != VIR_DOMAIN_CHR_TYPE_DEV)
+if (!(path = virDomainChrSourceDefPath(dev->source)))
 return 0;
 
-return qemuDomainCreateDevice(dev->source->data.file.path, data, false);
+/* Socket created by qemu. It doesn't exist upfront. */
+if (dev->source->type == VIR_DOMAIN_CHR_TYPE_UNIX &&
+dev->source->data.nix.listen)
+return 0;
+
+return qemuDomainCreateDevice(path, data, true);
 }
 
 
@@ -8531,7 +8537,7 @@ qemuDomainAttachDeviceMknodHelper(pid_t pid 
ATTRIBUTE_UNUSED,
 bool delDevice = false;
 bool isLink = S_ISLNK(data->sb.st_mode);
 bool isDev = S_ISCHR(data->sb.st_mode) || S_ISBLK(data->sb.st_mode);
-bool isReg = S_ISREG(data->sb.st_mode);
+bool isReg = S_ISREG(data->sb.st_mode) || S_ISFIFO(data->sb.st_mode) || 
S_ISSOCK(data->sb.st_mode);
 
 qemuSecurityPostFork(data->driver->securityManager);
 
@@ -8576,7 +8582,7 @@ qemuDomainAttachDeviceMknodHelper(pid_t pid 
ATTRIBUTE_UNUSED,
  * as its backing chain. This might however clash here.
  * Therefore do the cleanup here. */
 if (umount(data->file) < 0 &&
-errno != ENOENT) {
+errno != ENOENT && errno != EINVAL) {
 virReportSystemError(errno,
  _("Unable to umount %s"),
  data->file);
@@ -8685,7 +8691,7 @@ qemuDomainAttachDeviceMknodRecursive(virQEMUDriverPtr 
driver,
 }
 
 isLink = S_ISLNK(data.sb.st_mode);
-isReg = S_ISREG(data.sb.st_mode);
+isReg = S_ISREG(data.sb.st_mode) || S_ISFIFO(data.sb.st_mode) || 
S_ISSOCK(data.sb.st_mode);
 
 if (isReg && STRPREFIX(file, DEVPREFIX)) {
 cfg = virQEMUDriverGetConfig(driver);
@@ -9077,10 +9083,13 @@ qemuDomainNamespaceSetupChardev(virQEMUDriverPtr driver,
 if (!qemuDomainNamespaceEnabled(vm, QEMU_DOMAIN_NS_MOUNT))
 return 0;
 
-if (chr->source->type != VIR_DOMAIN_CHR_TYPE_DEV)
+if (!(path = virDomainChrSourceDefPath(chr->source)))
 return 0;
 
-path = chr->source->data.file.path;
+/* Socket created by qemu. It doesn't exist upfront. */
+if (chr->source->type == VIR_DOMAIN_CHR_TYPE_UNIX &&
+chr->source->data.nix.listen)
+return 0;
 
 cfg = virQEMUDriverGetConfig(driver);
 if (qemuDomainGetPreservedMounts(cfg, vm,
-- 
2.13.0

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


Re: [libvirt] RFC: Creating mediated devices with libvirt

2017-06-22 Thread Daniel P. Berrange
On Thu, Jun 22, 2017 at 05:14:48PM +0200, Erik Skultety wrote:
> [...]
> > >
> > > ^this is the thing we constantly keep discussing as everyone has a 
> > > slightly
> > > different angle of view - libvirt does not implement any kind of policy,
> > > therefore the only "configuration" would be the PCI parent placement - 
> > > you say
> > > what to do and we do it, no logic in it, that's it. Now, I don't 
> > > understand
> > > taking care of the guesswork for the user in the simplest manner possible 
> > > as
> > > policy rather as a mere convenience, be it just for developers and 
> > > testers, but
> > > even that might apparently be perceived as a policy and therefore 
> > > unacceptable.
> > >
> > > I still stand by idea of having auto-creation as unfortunately, I sort of 
> > > still
> > > fail to understand what the negative implications of having it are - is 
> > > that it
> > > would get just unnecessarily too complex to maintain in the future that 
> > > we would
> > > regret it or that we'd get a huge amount of follow-up requests for 
> > > extending the
> > > feature or is it just that simply the interpretation of auto-create == 
> > > policy?
> >
> > The increasing complexity of the qemu driver is a significant concern with
> > adding policy based logic to the code. THinking about this though, if we
> > provide the inactive node device feature, then we can avoid essentially
> > all new code and complexity QEMU driver, and still support auto-create.
> >
> > ie, in the domain XML we just continue to have the exact same XML that
> > we already have today for mdevs, but with a single new attribute
> > autocreate=yes|no
> >
> >   
> > 
> > 
> >   
> 
> So, just for clarification of the concept, the device with ^this UUID will 
> have
> had to be defined by the nodedev API by the time we start to edit the domain
> XML in this manner in which case the only thing the autocreate=yes would do is
> to actually create the mdev according to the nodedev config, right? Continuing
> with that thought, if UUID doesn't refer to any of the inactive configs it 
> will
> be an error I suppose? What about the fact that only one vgpu type can live on
> the GPU? even if you can successfully identify a device using the UUID in this
> way, you'll still face the problem, that other types might be currently
> occupying the GPU and need to be torn down first, will this be automated as
> well in what you suggest? I assume not.

Technically we shouldn't need the node device to exist at the time we
define the XML - only at the time we start the guest, does the node
device have to exist. eg same way you list a virtual network as the
source of a guest NIC, but that virtual network doesn't have to actually
have been defined & started until the guest starts.

If there are constraints that a pGPU can only support a certain combination
of vGPUs at any single point in time, doesn't the kernel already  enforce
that when you try to create the vGPU in sysfs. IOW, we merely need to try
to create the vGPU, and if the kernel mdev driver doesn't allow you to mix
that with the other vGPUs that already exist, then we'd just report an
error from virNodeDeviceCreate, and that'd get propagated back as the
error for the virDomainCreate call.

> 
> > 
> > 
> >   
> >
> > In the QEMU driver, then the only change required is
> >
> >if (def->autocreate)
> >virNodeDeviceCreate(dev)
> 
> Aha, so if a device gets torn down on shutdown, we won't face the problem with
> some other devices being active, all of them will have to be in the inactive
> state because they got torn down during the last shutdown - that would work.

I'm not sure what the relationship with other active devices is relevant
here. The virNodeDevicePtr we're accesing here is a single vGPU - if other
running guests have further vGPUs on the same pGPU, that's not really
relevant. Each vGPU is created/deleted as required.

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 5/8] qemuDomainAttachDeviceMknodHelper: Fail on unsupported file type

2017-06-22 Thread Michal Privoznik
Currently, we silently assume that file we are creating in the
namespace is either a link or a device (character or block one).
This is not always the case. Therefore instead of doing something
wrong, claim about unsupported file type.

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

diff --git a/src/qemu/qemu_domain.c b/src/qemu/qemu_domain.c
index e6fb041de..977b5c089 100644
--- a/src/qemu/qemu_domain.c
+++ b/src/qemu/qemu_domain.c
@@ -8518,6 +8518,7 @@ qemuDomainAttachDeviceMknodHelper(pid_t pid 
ATTRIBUTE_UNUSED,
 int ret = -1;
 bool delDevice = false;
 bool isLink = S_ISLNK(data->sb.st_mode);
+bool isDev = S_ISCHR(data->sb.st_mode) || S_ISBLK(data->sb.st_mode);
 
 qemuSecurityPostFork(data->driver->securityManager);
 
@@ -8539,7 +8540,7 @@ qemuDomainAttachDeviceMknodHelper(pid_t pid 
ATTRIBUTE_UNUSED,
 } else {
 delDevice = true;
 }
-} else {
+} else if (isDev) {
 VIR_DEBUG("Creating dev %s (%d,%d)",
   data->file, major(data->sb.st_rdev), 
minor(data->sb.st_rdev));
 if (mknod(data->file, data->sb.st_mode, data->sb.st_rdev) < 0) {
@@ -8556,6 +8557,11 @@ qemuDomainAttachDeviceMknodHelper(pid_t pid 
ATTRIBUTE_UNUSED,
 } else {
 delDevice = true;
 }
+} else {
+virReportError(VIR_ERR_OPERATION_UNSUPPORTED,
+   _("unsupported device type %s %o"),
+   data->file, (int) data->sb.st_mode);
+goto cleanup;
 }
 
 if (lchown(data->file, data->sb.st_uid, data->sb.st_gid) < 0) {
-- 
2.13.0

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


[libvirt] [PATCH 6/8] qemuDomainCreateDeviceRecursive: Support file mount points

2017-06-22 Thread Michal Privoznik
https://bugzilla.redhat.com/show_bug.cgi?id=1462060

When building a qemu namespace we might be dealing with bare
regular files. Files that live under /dev. For instance
/dev/my_awesome_disk:

  



  

  # qemu-img create -f qcow2 /dev/my_awesome_disk 10M

So far we were mknod()-ing them which is
obviously wrong. We need to touch the file and bind mount it to
the original:

1) touch /var/run/libvirt/qemu/fedora.dev/my_awesome_disk
2) mount --bind /dev/my_awesome_disk 
/var/run/libvirt/qemu/fedora.dev/my_awesome_disk

Later, when the new /dev is built and replaces original /dev the
file is going to live at expected location.

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

diff --git a/src/qemu/qemu_domain.c b/src/qemu/qemu_domain.c
index 977b5c089..6d7c218a2 100644
--- a/src/qemu/qemu_domain.c
+++ b/src/qemu/qemu_domain.c
@@ -7708,6 +7708,7 @@ qemuDomainCreateDeviceRecursive(const char *device,
 int ret = -1;
 bool isLink = false;
 bool isDev = false;
+bool isReg = false;
 bool create = false;
 #ifdef WITH_SELINUX
 char *tcon = NULL;
@@ -7731,6 +7732,7 @@ qemuDomainCreateDeviceRecursive(const char *device,
 
 isLink = S_ISLNK(sb.st_mode);
 isDev = S_ISCHR(sb.st_mode) || S_ISBLK(sb.st_mode);
+isReg = S_ISREG(sb.st_mode);
 
 /* Here, @device might be whatever path in the system. We
  * should create the path in the namespace iff it's "/dev"
@@ -7842,16 +7844,12 @@ qemuDomainCreateDeviceRecursive(const char *device,
 }
 goto cleanup;
 }
-
-/* Set the file permissions again: mknod() is affected by the
- * current umask, and as such might not have set them correctly */
+} else if (isReg) {
 if (create &&
-chmod(devicePath, sb.st_mode) < 0) {
-virReportSystemError(errno,
- _("Failed to set permissions for device %s"),
- devicePath);
+virFileTouch(devicePath, sb.st_mode) < 0)
 goto cleanup;
-}
+/* Just create the file here so that code below sets
+ * proper owner and mode. Bind mount only after that. */
 } else {
 virReportError(VIR_ERR_OPERATION_UNSUPPORTED,
_("unsupported device type %s %o"),
@@ -7871,6 +7869,15 @@ qemuDomainCreateDeviceRecursive(const char *device,
 goto cleanup;
 }
 
+/* Symlinks don't have mode */
+if (!isLink &&
+chmod(devicePath, sb.st_mode) < 0) {
+virReportSystemError(errno,
+ _("Failed to set permissions for device %s"),
+ devicePath);
+goto cleanup;
+}
+
 /* Symlinks don't have ACLs. */
 if (!isLink &&
 virFileCopyACLs(device, devicePath) < 0 &&
@@ -7903,6 +7910,11 @@ qemuDomainCreateDeviceRecursive(const char *device,
 }
 #endif
 
+/* Finish mount process started earlier. */
+if (isReg &&
+virFileBindMountDevice(device, devicePath) < 0)
+goto cleanup;
+
 ret = 0;
  cleanup:
 VIR_FREE(target);
-- 
2.13.0

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


[libvirt] [PATCH 7/8] qemuDomainAttachDeviceMknodRecursive: Support file mount points

2017-06-22 Thread Michal Privoznik
https://bugzilla.redhat.com/show_bug.cgi?id=1462060

Just like in the previous commit, when attaching a file based
device which has its source living under /dev (that is not a
device rather than a regular file), calling mknod() is no help.
We need to:

1) bind mount device to some temporary location
2) enter the namespace
3) move the mount point to desired place
4) umount it in the parent namespace from the temporary location

At the same time, the check in qemuDomainNamespaceSetupDisk makes
no longer sense. Therefore remove it.

Signed-off-by: Michal Privoznik 
---
 src/qemu/qemu_domain.c | 59 --
 1 file changed, 48 insertions(+), 11 deletions(-)

diff --git a/src/qemu/qemu_domain.c b/src/qemu/qemu_domain.c
index 6d7c218a2..51779c535 100644
--- a/src/qemu/qemu_domain.c
+++ b/src/qemu/qemu_domain.c
@@ -8531,6 +8531,7 @@ qemuDomainAttachDeviceMknodHelper(pid_t pid 
ATTRIBUTE_UNUSED,
 bool delDevice = false;
 bool isLink = S_ISLNK(data->sb.st_mode);
 bool isDev = S_ISCHR(data->sb.st_mode) || S_ISBLK(data->sb.st_mode);
+bool isReg = S_ISREG(data->sb.st_mode);
 
 qemuSecurityPostFork(data->driver->securityManager);
 
@@ -8569,6 +8570,23 @@ qemuDomainAttachDeviceMknodHelper(pid_t pid 
ATTRIBUTE_UNUSED,
 } else {
 delDevice = true;
 }
+} else if (isReg) {
+/* We are not cleaning up disks on virDomainDetachDevice
+ * because disk might be still in use by different disk
+ * as its backing chain. This might however clash here.
+ * Therefore do the cleanup here. */
+if (umount(data->file) < 0 &&
+errno != ENOENT) {
+virReportSystemError(errno,
+ _("Unable to umount %s"),
+ data->file);
+goto cleanup;
+}
+if (virFileTouch(data->file, data->sb.st_mode) < 0)
+goto cleanup;
+delDevice = true;
+/* Just create the file here so that code below sets
+ * proper owner and mode. Move the mount only after that. */
 } else {
 virReportError(VIR_ERR_OPERATION_UNSUPPORTED,
_("unsupported device type %s %o"),
@@ -8583,6 +8601,15 @@ qemuDomainAttachDeviceMknodHelper(pid_t pid 
ATTRIBUTE_UNUSED,
 goto cleanup;
 }
 
+/* Symlinks don't have mode */
+if (!isLink &&
+chmod(data->file, data->sb.st_mode) < 0) {
+virReportSystemError(errno,
+ _("Failed to set permissions for device %s"),
+ data->file);
+goto cleanup;
+}
+
 /* Symlinks don't have ACLs. */
 if (!isLink &&
 virFileSetACLs(data->file, data->acl) < 0 &&
@@ -8606,6 +8633,11 @@ qemuDomainAttachDeviceMknodHelper(pid_t pid 
ATTRIBUTE_UNUSED,
 }
 #endif
 
+/* Finish mount process started earlier. */
+if (isReg &&
+virFileMoveMount(data->target, data->file) < 0)
+goto cleanup;
+
 ret = 0;
  cleanup:
 if (ret < 0 && delDevice)
@@ -8626,10 +8658,12 @@ qemuDomainAttachDeviceMknodRecursive(virQEMUDriverPtr 
driver,
  size_t ndevMountsPath,
  unsigned int ttl)
 {
+virQEMUDriverConfigPtr cfg = NULL;
 struct qemuDomainAttachDeviceMknodData data;
 int ret = -1;
 char *target = NULL;
 bool isLink;
+bool isReg;
 
 if (!ttl) {
 virReportSystemError(ELOOP,
@@ -8651,8 +8685,18 @@ qemuDomainAttachDeviceMknodRecursive(virQEMUDriverPtr 
driver,
 }
 
 isLink = S_ISLNK(data.sb.st_mode);
+isReg = S_ISREG(data.sb.st_mode);
 
-if (isLink) {
+if (isReg && STRPREFIX(file, DEVPREFIX)) {
+cfg = virQEMUDriverGetConfig(driver);
+if (!(target = qemuDomainGetPreservedMountPath(cfg, vm, file)))
+goto cleanup;
+
+if (virFileBindMountDevice(file, target) < 0)
+goto cleanup;
+
+data.target = target;
+} else if (isLink) {
 if (virFileReadLink(file, ) < 0) {
 virReportSystemError(errno,
  _("unable to resolve symlink %s"),
@@ -8739,7 +8783,10 @@ qemuDomainAttachDeviceMknodRecursive(virQEMUDriverPtr 
driver,
 freecon(data.tcon);
 #endif
 virFileFreeACLs();
+if (isReg && target)
+umount(target);
 VIR_FREE(target);
+virObjectUnref(cfg);
 return ret;
 }
 
@@ -8817,7 +8864,6 @@ qemuDomainNamespaceSetupDisk(virQEMUDriverPtr driver,
 char **devMountsPath = NULL;
 size_t ndevMountsPath = 0;
 virStorageSourcePtr next;
-struct stat sb;
 int ret = -1;
 
 if (!qemuDomainNamespaceEnabled(vm, QEMU_DOMAIN_NS_MOUNT))
@@ -8836,15 +8882,6 @@ qemuDomainNamespaceSetupDisk(virQEMUDriverPtr driver,
 continue;
 }
 
-if (stat(next->path, ) < 0) {
-virReportSystemError(errno,
- 

[libvirt] [PATCH 3/8] qemu: Move preserved mount points path generation into a separate function

2017-06-22 Thread Michal Privoznik
This function is going to be used on other places, so
instead of copying code we can just call the function.

Signed-off-by: Michal Privoznik 
---
 src/qemu/qemu_domain.c | 59 ++
 1 file changed, 36 insertions(+), 23 deletions(-)

diff --git a/src/qemu/qemu_domain.c b/src/qemu/qemu_domain.c
index 212717c80..286d60761 100644
--- a/src/qemu/qemu_domain.c
+++ b/src/qemu/qemu_domain.c
@@ -7572,6 +7572,41 @@ qemuDomainGetHostdevPath(virDomainDefPtr def,
 }
 
 
+static char *
+qemuDomainGetPreservedMountPath(virQEMUDriverConfigPtr cfg,
+virDomainObjPtr vm,
+const char *mount)
+{
+char *path = NULL;
+char *tmp;
+const char *suffix = mount + strlen(DEVPREFIX);
+size_t off;
+
+if (STREQ(mount, "/dev"))
+suffix = "dev";
+
+if (virAsprintf(, "%s/%s.%s",
+cfg->stateDir, vm->def->name, suffix) < 0)
+return NULL;
+
+/* Now consider that @mount is "/dev/blah/blah2".
+ * @suffix then points to "blah/blah2". However, caller
+ * expects all the @paths to be the same depth. The
+ * caller doesn't always do `mkdir -p` but sometimes bare
+ * `touch`. Therefore fix all the suffixes. */
+off = strlen(path) - strlen(suffix);
+
+tmp = path + off;
+while (*tmp) {
+if (*tmp == '/')
+*tmp = '.';
+tmp++;
+}
+
+return path;
+}
+
+
 /**
  * qemuDomainGetPreservedMounts:
  *
@@ -7628,30 +7663,8 @@ qemuDomainGetPreservedMounts(virQEMUDriverConfigPtr cfg,
 goto error;
 
 for (i = 0; i < nmounts; i++) {
-char *tmp;
-const char *suffix = mounts[i] + strlen(DEVPREFIX);
-size_t off;
-
-if (STREQ(mounts[i], "/dev"))
-suffix = "dev";
-
-if (virAsprintf([i], "%s/%s.%s",
-cfg->stateDir, vm->def->name, suffix) < 0)
+if (!(paths[i] = qemuDomainGetPreservedMountPath(cfg, vm, mounts[i])))
 goto error;
-
-/* Now consider that mounts[i] is "/dev/blah/blah2".
- * @suffix then points to "blah/blah2". However, caller
- * expects all the @paths to be the same depth. The
- * caller doesn't always do `mkdir -p` but sometimes bare
- * `touch`. Therefore fix all the suffixes. */
-off = strlen(paths[i]) - strlen(suffix);
-
-tmp = paths[i] + off;
-while (*tmp) {
-if (*tmp == '/')
-*tmp = '.';
-tmp++;
-}
 }
 
 if (devPath)
-- 
2.13.0

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


[libvirt] [PATCH 0/8] Yet another round of qemu namespace fixes

2017-06-22 Thread Michal Privoznik
I've encountered couple of problems while playing with the namespaces. For the
first issue (2/8) I've got a confirmation from openstack guys that it fixes
their issue.

Michal Privoznik (8):
  conf: Rename and expose virDomainChrSourceDefPath
  qemuDomainBuildNamespace: Handle special file mount points
  qemu: Move preserved mount points path generation into a separate
function
  qemuDomainCreateDeviceRecursive: Fail on unsupported file type
  qemuDomainAttachDeviceMknodHelper: Fail on unsupported file type
  qemuDomainCreateDeviceRecursive: Support file mount points
  qemuDomainAttachDeviceMknodRecursive: Support file mount points
  qemu ns: Create chardev backends more frequently

 src/conf/domain_audit.c  |  44 ++-
 src/conf/domain_conf.c   |  33 +
 src/conf/domain_conf.h   |   2 +
 src/libvirt_private.syms |   1 +
 src/qemu/qemu_domain.c   | 186 ++-
 5 files changed, 178 insertions(+), 88 deletions(-)

-- 
2.13.0

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


[libvirt] [PATCH v3 01/16] util: Generate a common internal only error print

2017-06-22 Thread John Ferlan
If virObjectIsClass fails "internally" to virobject.c, create a macro to
generate the VIR_WARN describing what the problem is. Also improve the
checks and message a bit to indicate which was the failure - whether the
obj was NULL or just not the right class

Signed-off-by: John Ferlan 
---
 src/util/virobject.c | 16 +++-
 1 file changed, 11 insertions(+), 5 deletions(-)

diff --git a/src/util/virobject.c b/src/util/virobject.c
index 34805d3..ff9385b 100644
--- a/src/util/virobject.c
+++ b/src/util/virobject.c
@@ -47,6 +47,16 @@ struct _virClass {
 virObjectDisposeCallback dispose;
 };
 
+#define VIR_OBJECT_USAGE_PRINT_WARNING(anyobj, objclass)\
+do {\
+virObjectPtr obj = anyobj;  \
+if (!obj)   \
+VIR_WARN("Object cannot be NULL");  \
+else\
+VIR_WARN("Object %p (%s) is not a %s instance", \
+  anyobj, obj->klass->name, #objclass); \
+} while (0)
+
 static virClassPtr virObjectClass;
 static virClassPtr virObjectLockableClass;
 
@@ -312,14 +322,10 @@ virObjectRef(void *anyobj)
 static virObjectLockablePtr
 virObjectGetLockableObj(void *anyobj)
 {
-virObjectPtr obj;
-
 if (virObjectIsClass(anyobj, virObjectLockableClass))
 return anyobj;
 
-obj = anyobj;
-VIR_WARN("Object %p (%s) is not a virObjectLockable instance",
-  anyobj, obj ? obj->klass->name : "(unknown)");
+VIR_OBJECT_USAGE_PRINT_WARNING(anyobj, virObjectLockableClass);
 
 return NULL;
 }
-- 
2.9.4

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


Re: [libvirt] RFC: Creating mediated devices with libvirt

2017-06-22 Thread Pavel Hrdina
On Thu, Jun 22, 2017 at 09:28:57AM -0600, Alex Williamson wrote:
> On Thu, 22 Jun 2017 17:14:48 +0200
> Erik Skultety  wrote:
> 
> > [...]
> > > >
> > > > ^this is the thing we constantly keep discussing as everyone has a 
> > > > slightly
> > > > different angle of view - libvirt does not implement any kind of policy,
> > > > therefore the only "configuration" would be the PCI parent placement - 
> > > > you say
> > > > what to do and we do it, no logic in it, that's it. Now, I don't 
> > > > understand
> > > > taking care of the guesswork for the user in the simplest manner 
> > > > possible as
> > > > policy rather as a mere convenience, be it just for developers and 
> > > > testers, but
> > > > even that might apparently be perceived as a policy and therefore 
> > > > unacceptable.
> > > >
> > > > I still stand by idea of having auto-creation as unfortunately, I sort 
> > > > of still
> > > > fail to understand what the negative implications of having it are - is 
> > > > that it
> > > > would get just unnecessarily too complex to maintain in the future that 
> > > > we would
> > > > regret it or that we'd get a huge amount of follow-up requests for 
> > > > extending the
> > > > feature or is it just that simply the interpretation of auto-create == 
> > > > policy?  
> > >
> > > The increasing complexity of the qemu driver is a significant concern with
> > > adding policy based logic to the code. THinking about this though, if we
> > > provide the inactive node device feature, then we can avoid essentially
> > > all new code and complexity QEMU driver, and still support auto-create.
> > >
> > > ie, in the domain XML we just continue to have the exact same XML that
> > > we already have today for mdevs, but with a single new attribute
> > > autocreate=yes|no
> > >
> > >   
> > >  > > autocreate="yes">
> > > 
> > > 
> > 
> > So, just for clarification of the concept, the device with ^this UUID will 
> > have
> > had to be defined by the nodedev API by the time we start to edit the domain
> > XML in this manner in which case the only thing the autocreate=yes would do 
> > is
> > to actually create the mdev according to the nodedev config, right? 
> > Continuing
> > with that thought, if UUID doesn't refer to any of the inactive configs it 
> > will
> > be an error I suppose? What about the fact that only one vgpu type can live 
> > on
> > the GPU? even if you can successfully identify a device using the UUID in 
> > this
> > way, you'll still face the problem, that other types might be currently
> > occupying the GPU and need to be torn down first, will this be automated as
> > well in what you suggest? I assume not.
> > 
> > > 
> > > 
> > >   
> > >
> > > In the QEMU driver, then the only change required is
> > >
> > >if (def->autocreate)
> > >virNodeDeviceCreate(dev)  
> > 
> > Aha, so if a device gets torn down on shutdown, we won't face the problem 
> > with
> > some other devices being active, all of them will have to be in the inactive
> > state because they got torn down during the last shutdown - that would work.
> 
> 
> I'm not familiar with how inactive devices would be defined in the
> nodedev API, would someone mind explaining or providing an example
> please?  I don't understand where the metadata is stored that describes
> the what and where of a given UUID.  Thanks,

It would basically copy what we do for domains.  Currently there is
virNodeDeviceCreateXML() which takes the XML definitions and creates a
new active node device and virNodeDeviceDestroy() which takes as
argument an object of existing active node device.

We would extend the functionality with new APIs:

  - virNodeDeviceCreate() which would take as argument an object of
existing inactive node device.

  - virNodeDeviceDefineXML() would define the node device as inactive.

With the virNodeDeviceDefineXML() you would create a list of predefined
inactive devices which could be obtained by
virConnectListAllNodeDevices() for example.

Internally we would store XML files the same way as we do for domains,
somewhere in "/etc/libvirt/..." and like with domains the APIs would
work with these files.

In virsh terms there would be similar analogy to the domain commands:

"virsh nodedev-start" could simply map to virNodeDeviceCreate() and
would work like "virsh start" for domains and "virsh nodedev-define"
woudl map to virNodeDeviceDefineXML() and work the same way as
"virsh define".  You could simply list the predefined mdev devices
using "virsh nodedev-list", get UUID of existing mdev device and use it
in a domain.

In virt-manager there could be new type of hostdev device where you
could select on of existing mdev devices from a drop-down list where
virt-manager would show nice user-friendly descriptions of the mdev
devices but under the hood it would put the UUID in the domain XML.

Pavel

> 
> Alex
> 
> --
> libvir-list mailing list
> libvir-list@redhat.com
> 

Re: [libvirt] RFC: Creating mediated devices with libvirt

2017-06-22 Thread Alex Williamson
On Thu, 22 Jun 2017 17:14:48 +0200
Erik Skultety  wrote:

> [...]
> > >
> > > ^this is the thing we constantly keep discussing as everyone has a 
> > > slightly
> > > different angle of view - libvirt does not implement any kind of policy,
> > > therefore the only "configuration" would be the PCI parent placement - 
> > > you say
> > > what to do and we do it, no logic in it, that's it. Now, I don't 
> > > understand
> > > taking care of the guesswork for the user in the simplest manner possible 
> > > as
> > > policy rather as a mere convenience, be it just for developers and 
> > > testers, but
> > > even that might apparently be perceived as a policy and therefore 
> > > unacceptable.
> > >
> > > I still stand by idea of having auto-creation as unfortunately, I sort of 
> > > still
> > > fail to understand what the negative implications of having it are - is 
> > > that it
> > > would get just unnecessarily too complex to maintain in the future that 
> > > we would
> > > regret it or that we'd get a huge amount of follow-up requests for 
> > > extending the
> > > feature or is it just that simply the interpretation of auto-create == 
> > > policy?  
> >
> > The increasing complexity of the qemu driver is a significant concern with
> > adding policy based logic to the code. THinking about this though, if we
> > provide the inactive node device feature, then we can avoid essentially
> > all new code and complexity QEMU driver, and still support auto-create.
> >
> > ie, in the domain XML we just continue to have the exact same XML that
> > we already have today for mdevs, but with a single new attribute
> > autocreate=yes|no
> >
> >   
> > 
> > 
> > 
> 
> So, just for clarification of the concept, the device with ^this UUID will 
> have
> had to be defined by the nodedev API by the time we start to edit the domain
> XML in this manner in which case the only thing the autocreate=yes would do is
> to actually create the mdev according to the nodedev config, right? Continuing
> with that thought, if UUID doesn't refer to any of the inactive configs it 
> will
> be an error I suppose? What about the fact that only one vgpu type can live on
> the GPU? even if you can successfully identify a device using the UUID in this
> way, you'll still face the problem, that other types might be currently
> occupying the GPU and need to be torn down first, will this be automated as
> well in what you suggest? I assume not.
> 
> > 
> > 
> >   
> >
> > In the QEMU driver, then the only change required is
> >
> >if (def->autocreate)
> >virNodeDeviceCreate(dev)  
> 
> Aha, so if a device gets torn down on shutdown, we won't face the problem with
> some other devices being active, all of them will have to be in the inactive
> state because they got torn down during the last shutdown - that would work.


I'm not familiar with how inactive devices would be defined in the
nodedev API, would someone mind explaining or providing an example
please?  I don't understand where the metadata is stored that describes
the what and where of a given UUID.  Thanks,

Alex

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


Re: [libvirt] [RFC PATCH v1 4/4] xlconfigtest: add tests for numa cell sibling distances

2017-06-22 Thread Joao Martins
On 06/12/2017 07:54 PM, Wim Ten Have wrote:
> From: Wim ten Have 
> 
> Test a bidirectional xen-xl domxml to and from native for numa
> support administration as brought under this patch series.
> 
> Signed-off-by: Wim ten Have 
> ---
>  .../test-fullvirt-vnuma-nodistances.cfg| 26 +++
>  .../test-fullvirt-vnuma-nodistances.xml| 54 +++
>  tests/xlconfigdata/test-fullvirt-vnuma.cfg | 26 +++
>  tests/xlconfigdata/test-fullvirt-vnuma.xml | 81 
> ++
>  tests/xlconfigtest.c   |  4 ++
>  5 files changed, 191 insertions(+)
>  create mode 100644 tests/xlconfigdata/test-fullvirt-vnuma-nodistances.cfg
>  create mode 100644 tests/xlconfigdata/test-fullvirt-vnuma-nodistances.xml
>  create mode 100644 tests/xlconfigdata/test-fullvirt-vnuma.cfg
>  create mode 100644 tests/xlconfigdata/test-fullvirt-vnuma.xml
> 
> diff --git a/tests/xlconfigdata/test-fullvirt-vnuma-nodistances.cfg 
> b/tests/xlconfigdata/test-fullvirt-vnuma-nodistances.cfg
> new file mode 100644
> index 000..9871f21
> --- /dev/null
> +++ b/tests/xlconfigdata/test-fullvirt-vnuma-nodistances.cfg
> @@ -0,0 +1,26 @@
> +name = "XenGuest2"
> +uuid = "c7a5fdb2-cdaf-9455-926a-d65c16db1809"
> +maxmem = 8192
> +memory = 8192
> +vcpus = 8
> +pae = 1
> +acpi = 1
> +apic = 1
> +viridian = 0
> +rtc_timeoffset = 0
> +localtime = 0
> +on_poweroff = "destroy"
> +on_reboot = "restart"
> +on_crash = "restart"
> +device_model = "/usr/lib/xen/bin/qemu-system-i386"
> +sdl = 0
> +vnc = 1
> +vncunused = 1
> +vnclisten = "127.0.0.1"
> +vif = [ "mac=00:16:3e:66:92:9c,bridge=xenbr1,script=vif-bridge,model=e1000" ]
> +parallel = "none"
> +serial = "none"
> +builder = "hvm"
> +boot = "d"
> +vnuma = [ [ "pnode=0", "size=2048", "vcpus=0-1", "vdistances=10,21,21,21" ], 
> [ "pnode=1", "size=2048", "vcpus=2-3", "vdistances=21,10,21,21" ], [ 
> "pnode=2", "size=2048", "vcpus=4-5", "vdistances=21,21,10,21" ], [ "pnode=3", 
> "size=2048", "vcpus=6-7", "vdistances=21,21,21,10" ] ]
> +disk = [ 
> "format=raw,vdev=hda,access=rw,backendtype=phy,target=/dev/HostVG/XenGuest2" ]
> diff --git a/tests/xlconfigdata/test-fullvirt-vnuma-nodistances.xml 
> b/tests/xlconfigdata/test-fullvirt-vnuma-nodistances.xml
> new file mode 100644
> index 000..a576881
> --- /dev/null
> +++ b/tests/xlconfigdata/test-fullvirt-vnuma-nodistances.xml
> @@ -0,0 +1,54 @@
> +
> +  XenGuest2
> +  c7a5fdb2-cdaf-9455-926a-d65c16db1809
> +  8388608
> +  8388608
> +  8
> +  
> +hvm
> +/usr/lib/xen/boot/hvmloader
> +
> +  
> +  
> +
> +
> +
> +  
> +  
> +

We don't set/support topology info then it shouldn't be in the xml. Therefore
the test with nodistances will fail right? In that case  should be
removed then.

Albeit the other test doesn't have  element which is good :)

> +
> +  
> +  
> +  
> +  
> +
> +  
> +  
> +  destroy
> +  restart
> +  restart
> +  
> +/usr/lib/xen/bin/qemu-system-i386
> +
> +  
> +  
> +  
> +  
> +
> +
> +
> +  
> +  
> +  
> +  
> +
> +
> +
> +
> +  
> +
> +
> +  
> +
> +  
> +
> diff --git a/tests/xlconfigdata/test-fullvirt-vnuma.cfg 
> b/tests/xlconfigdata/test-fullvirt-vnuma.cfg
> new file mode 100644
> index 000..91e233a
> --- /dev/null
> +++ b/tests/xlconfigdata/test-fullvirt-vnuma.cfg
> @@ -0,0 +1,26 @@
> +name = "XenGuest2"
> +uuid = "c7a5fdb2-cdaf-9455-926a-d65c16db1809"
> +maxmem = 8192
> +memory = 8192
> +vcpus = 8
> +pae = 1
> +acpi = 1
> +apic = 1
> +viridian = 0
> +rtc_timeoffset = 0
> +localtime = 0
> +on_poweroff = "destroy"
> +on_reboot = "restart"
> +on_crash = "restart"
> +device_model = "/usr/lib/xen/bin/qemu-system-i386"
> +sdl = 0
> +vnc = 1
> +vncunused = 1
> +vnclisten = "127.0.0.1"
> +vif = [ "mac=00:16:3e:66:92:9c,bridge=xenbr1,script=vif-bridge,model=e1000" ]
> +parallel = "none"
> +serial = "none"
> +builder = "hvm"
> +boot = "d"
> +vnuma = [ [ "pnode=0", "size=2048", "vcpus=0-1", "vdistances=10,21,31,41" ], 
> [ "pnode=1", "size=2048", "vcpus=2-3", "vdistances=21,10,21,31" ], [ 
> "pnode=2", "size=2048", "vcpus=4-5", "vdistances=31,21,10,21" ], [ "pnode=3", 
> "size=2048", "vcpus=6-7", "vdistances=41,31,21,10" ] ]
> +disk = [ 
> "format=raw,vdev=hda,access=rw,backendtype=phy,target=/dev/HostVG/XenGuest2" ]
> diff --git a/tests/xlconfigdata/test-fullvirt-vnuma.xml 
> b/tests/xlconfigdata/test-fullvirt-vnuma.xml
> new file mode 100644
> index 000..5368b0d
> --- /dev/null
> +++ b/tests/xlconfigdata/test-fullvirt-vnuma.xml
> @@ -0,0 +1,81 @@
> +
> +  XenGuest2
> +  c7a5fdb2-cdaf-9455-926a-d65c16db1809
> +  8388608
> +  8388608
> +  8
> +  
> +hvm
> +/usr/lib/xen/boot/hvmloader
> +
> +  
> +  
> +
> +
> +
> +  
> +  
> +
> +  
> +
> +  
> +  
> +  
> +  
> +
> +  
> +  
> +   

Re: [libvirt] RFC: Creating mediated devices with libvirt

2017-06-22 Thread Erik Skultety
[...]
> >
> > ^this is the thing we constantly keep discussing as everyone has a slightly
> > different angle of view - libvirt does not implement any kind of policy,
> > therefore the only "configuration" would be the PCI parent placement - you 
> > say
> > what to do and we do it, no logic in it, that's it. Now, I don't understand
> > taking care of the guesswork for the user in the simplest manner possible as
> > policy rather as a mere convenience, be it just for developers and testers, 
> > but
> > even that might apparently be perceived as a policy and therefore 
> > unacceptable.
> >
> > I still stand by idea of having auto-creation as unfortunately, I sort of 
> > still
> > fail to understand what the negative implications of having it are - is 
> > that it
> > would get just unnecessarily too complex to maintain in the future that we 
> > would
> > regret it or that we'd get a huge amount of follow-up requests for 
> > extending the
> > feature or is it just that simply the interpretation of auto-create == 
> > policy?
>
> The increasing complexity of the qemu driver is a significant concern with
> adding policy based logic to the code. THinking about this though, if we
> provide the inactive node device feature, then we can avoid essentially
> all new code and complexity QEMU driver, and still support auto-create.
>
> ie, in the domain XML we just continue to have the exact same XML that
> we already have today for mdevs, but with a single new attribute
> autocreate=yes|no
>
>   
> 
> 
>   

So, just for clarification of the concept, the device with ^this UUID will have
had to be defined by the nodedev API by the time we start to edit the domain
XML in this manner in which case the only thing the autocreate=yes would do is
to actually create the mdev according to the nodedev config, right? Continuing
with that thought, if UUID doesn't refer to any of the inactive configs it will
be an error I suppose? What about the fact that only one vgpu type can live on
the GPU? even if you can successfully identify a device using the UUID in this
way, you'll still face the problem, that other types might be currently
occupying the GPU and need to be torn down first, will this be automated as
well in what you suggest? I assume not.

> 
> 
>   
>
> In the QEMU driver, then the only change required is
>
>if (def->autocreate)
>virNodeDeviceCreate(dev)

Aha, so if a device gets torn down on shutdown, we won't face the problem with
some other devices being active, all of them will have to be in the inactive
state because they got torn down during the last shutdown - that would work.

Erik

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


Re: [libvirt] RFC: Creating mediated devices with libvirt

2017-06-22 Thread Daniel P. Berrange
On Thu, Jun 22, 2017 at 10:41:13AM +0200, Martin Polednik wrote:
> On 16/06/17 18:14 +0100, Daniel P. Berrange wrote:
> > On Fri, Jun 16, 2017 at 06:11:17PM +0100, Daniel P. Berrange wrote:
> > > On Fri, Jun 16, 2017 at 11:02:55AM -0600, Alex Williamson wrote:
> > > > On Fri, 16 Jun 2017 11:32:04 -0400
> > > > Laine Stump  wrote:
> > > >
> > > > > On 06/15/2017 02:42 PM, Alex Williamson wrote:
> > > > > > On Thu, 15 Jun 2017 09:33:01 +0100
> > > > > > "Daniel P. Berrange"  wrote:
> > > > > >
> > > > > >> On Thu, Jun 15, 2017 at 12:06:43AM +0200, Erik Skultety wrote:
> > > > > >>> Hi all,
> > > > > >>>
> > > > > >>> so there's been an off-list discussion about finally implementing 
> > > > > >>> creation of
> > > > > >>> mediated devices with libvirt and it's more than desired to get 
> > > > > >>> as many opinions
> > > > > >>> on that as possible, so please do share your ideas. This did come 
> > > > > >>> up already as
> > > > > >>> part of some older threads ([1] for example), so this will be a 
> > > > > >>> respin of the
> > > > > >>> discussions. Long story short, we decided to put device creation 
> > > > > >>> off and focus
> > > > > >>> on the introduction of the framework as such first and build upon 
> > > > > >>> that later,
> > > > > >>> i.e. now.
> > > > > >>>
> > > > > >>> [1] 
> > > > > >>> https://www.redhat.com/archives/libvir-list/2017-February/msg00177.html
> > > > > >>>
> > > > > >>> 
> > > > > >>> PART 1: NODEDEV-DRIVER
> > > > > >>> 
> > > > > >>>
> > > > > >>> API-wise, device creation through the nodedev driver should be 
> > > > > >>> pretty
> > > > > >>> straightforward and without any issues, since virNodeDevCreateXML 
> > > > > >>> takes an XML
> > > > > >>> and does support flags. Looking at the current device XML:
> > > > > >>>
> > > > > >>> 
> > > > > >>>   mdev_0cce8709_0640_46ef_bd14_962c7f73cc6f
> > > > > >>>   
> > > > > >>> /sys/devices/pci:00/.../0cce8709-0640-46ef-bd14-962c7f73cc6f
> > > > > >>>   pci__03_00_0
> > > > > >>>   
> > > > > >>> vfio_mdev
> > > > > >>>   
> > > > > >>>   
> > > > > >>> 
> > > > > >>> 
> > > > > >>> UUID 
> > > > > >>>   
> > > > > >>> 
> > > > > >>>
> > > > > >>> We can ignore ,, elements, since these 
> > > > > >>> are useless
> > > > > >>> during creation. We also cannot use  since we don't support 
> > > > > >>> arbitrary
> > > > > >>> names and we also can't rely on users providing a name in correct 
> > > > > >>> form which we
> > > > > >>> would need to further parse in order to get the UUID.
> > > > > >>> So since the only thing missing to successfully use create an 
> > > > > >>> mdev using XML is
> > > > > >>> the UUID (if user doesn't want it to be generated automatically), 
> > > > > >>> how about
> > > > > >>> having a  subelement under  just like PCIs have 
> > > > > >>>  and
> > > > > >>> friends, USBs have  & , interfaces have  to 
> > > > > >>> uniquely
> > > > > >>> identify the device even if the name itself is unique.
> > > > > >>> Removal of a device should work as well, although we might want to
> > > > > >>> consider creating a *Flags version of the API.
> > > > > >>>
> > > > > >>> =
> > > > > >>> PART 2: DOMAIN XML & DEVICE AUTO-CREATION, NO POLICY INVOLVED!
> > > > > >>> =
> > > > > >>>
> > > > > >>> There were some doubts about auto-creation mentioned in [1], 
> > > > > >>> although they
> > > > > >>> weren't specified further. So hopefully, we'll get further in the 
> > > > > >>> discussion
> > > > > >>> this time.
> > > > > >>>
> > > > > >>> From my perspective there are two main reasons/benefits to that:
> > > > > >>>
> > > > > >>> 1) Convenience
> > > > > >>> For apps like virt-manager, user will want to add a host device 
> > > > > >>> transparently,
> > > > > >>> "hey libvirt, I want an mdev assigned to my VM, can you do that". 
> > > > > >>> Even for
> > > > > >>> higher management apps, like oVirt, even they might not care 
> > > > > >>> about the parent
> > > > > >>> device at all times and considering that they would need to 
> > > > > >>> enumerate the
> > > > > >>> parents, pick one, create the device XML and pass it to the 
> > > > > >>> nodedev driver, IMHO
> > > > > >>> it would actually  be easier and faster to just do it directly 
> > > > > >>> through sysfs,
> > > > > >>> bypassing libvirt once again
> > > > > >>
> > > > > >> The convenience only works if the policy we've provided in libvirt 
> > > > > >> actually
> > > > > >> matches the policy the application wants. I think it is quite 
> > > > > >> likely that with
> > > > > >> cloud the mdevs will be created out of band from the domain 
> > > > > >> startup process.
> > > > > >> It is possible the app will just have a fixed set of mdevs 
> > > > > >> pre-created when
> > > > > >> 

Re: [libvirt] RFC: Creating mediated devices with libvirt

2017-06-22 Thread Daniel P. Berrange
On Thu, Jun 22, 2017 at 02:05:26PM +0200, Erik Skultety wrote:
> On Thu, Jun 22, 2017 at 10:41:13AM +0200, Martin Polednik wrote:
> > On 16/06/17 18:14 +0100, Daniel P. Berrange wrote:
> > > On Fri, Jun 16, 2017 at 06:11:17PM +0100, Daniel P. Berrange wrote:
> > > >
> > > > I'm fine with libvirt having APIs in the node device APIs to enable
> > > > create/delete with libvirt, as well as using managed=yes in the same
> > > > manner that we do for regular PCI devices (the bind/unbind to vfio
> > > > or pci-back)
> > >
> > > Oh, and we really need to fix the big missing feature in the node
> > > device APIs of persistent, inactive configs. eg we should be able
> > > to record XML configs of mdevs (and npiv devices too), in /etc/libvirt
> > > so they persist across reboots, and can be setup for auto-start on
> > > boot too.
> >
> > That doesn't help mdev in any way though. It doesn't make sense to
> > generate new UUID for given VM at each start. So in case of
> 
> What statement does this^^ refer to? Why would you generate a new UUID for a 
> VM
> at each start, you'd generate it only once and then store it, the same way as
> domain UUIDs work.
> 
> > single host, the persistent file is redundant to the domain XML (as
> > long as uuid+parent is in the xml) and in case of cluster we'd have to
> 
> Right now you don't have any info about the parent device in the domain XML 
> and
> such data would only exist in the XML if we all agreed on auto-creating mdevs,
> in which case persistent configs in nodedev would be unnecessary and 
> vice-versa.
> 
> > copy all possible VM mdev definitions to all the hosts.
> 
> ^For mdev configs, you might be better off with creating them explicitly than
> copying configs, simply because given the information the XML has, you might
> conflict with UUIDs between hosts, so you'd have to take care for that. 
> Parents
> have different PCI addresses that most probably wouldn't match across hosts, 
> so
> from automation point of view, I think writing a stub recreating the whole set
> of devices/configs might actually be easier than copying & handling them
> (solely because the 2 things left - after the ones I mentioned - in the XML 
> are
> the vgpu type and IOMMU group number which AFAIK cannot be requested 
> explicitly).

Yep, separately the mdev config from the domain config is a significant
benefit as it makes the domain config independant of the particular device
you've attached to which can vary across hosts.

> > The idea works nicely if you had such definitions accessible in the
> > cluster and could define a group of devices (gpu+soundcard, single
> > mdev, single vf, ...) that would later be assigned to a VM (let's hope
> > kubevirt can get there).
> >
> > As for automatic creation, I think it's on the "nice to have" level.
> > So far libvirt is close to useless when working with mdevs as all the
> > data is in the same sysfs place where create/delete endpoints are - as
> > mentioned earlier, we can just get the data and do everything directly
> > from there instead of dealing with XML and bunch of new API calls.
> > Having at least some *configurable* auto create policy might add some
> 
> ^this is the thing we constantly keep discussing as everyone has a slightly
> different angle of view - libvirt does not implement any kind of policy,
> therefore the only "configuration" would be the PCI parent placement - you say
> what to do and we do it, no logic in it, that's it. Now, I don't understand
> taking care of the guesswork for the user in the simplest manner possible as
> policy rather as a mere convenience, be it just for developers and testers, 
> but
> even that might apparently be perceived as a policy and therefore 
> unacceptable.
> 
> I still stand by idea of having auto-creation as unfortunately, I sort of 
> still
> fail to understand what the negative implications of having it are - is that 
> it
> would get just unnecessarily too complex to maintain in the future that we 
> would
> regret it or that we'd get a huge amount of follow-up requests for extending 
> the
> feature or is it just that simply the interpretation of auto-create == policy?

The increasing complexity of the qemu driver is a significant concern with
adding policy based logic to the code. THinking about this though, if we
provide the inactive node device feature, then we can avoid essentially
all new code and complexity QEMU driver, and still support auto-create.

ie, in the domain XML we just continue to have the exact same XML that
we already have today for mdevs, but with a single new attribute
autocreate=yes|no

  


  


  

In the QEMU driver, then the only change required is

   if (def->autocreate)
   virNodeDeviceCreate(dev)

and the opposite in shutdown. This avoids pulling all the node device
XML schema into the domain XML schema too which is something I dislike
about the previous proposals too.

The inactive node device concept is also more broadly useful 

[libvirt] [PATCH v3 11/16] util: Introduce virObjectLookupHashFind

2017-06-22 Thread John Ferlan
This API will use the virHashLookup in order to find the object in
the requested hash table (via @useUUID) by the specified @key. It is
up to the caller to know which table (UUID or Name) to find the data
by @key and handle the error or NULL return.

Signed-off-by: John Ferlan 
---
 src/libvirt_private.syms |  1 +
 src/util/virobject.c | 25 +
 src/util/virobject.h |  5 +
 3 files changed, 31 insertions(+)

diff --git a/src/libvirt_private.syms b/src/libvirt_private.syms
index de986e5..68961e7 100644
--- a/src/libvirt_private.syms
+++ b/src/libvirt_private.syms
@@ -2287,6 +2287,7 @@ virObjectListFreeCount;
 virObjectLock;
 virObjectLockableNew;
 virObjectLookupHashAdd;
+virObjectLookupHashFind;
 virObjectLookupHashGetName;
 virObjectLookupHashGetUUID;
 virObjectLookupHashNew;
diff --git a/src/util/virobject.c b/src/util/virobject.c
index 9443dda..01922b3 100644
--- a/src/util/virobject.c
+++ b/src/util/virobject.c
@@ -853,6 +853,31 @@ virObjectLookupHashGetUUID(void *anyobj)
 
 
 /**
+ * virObjectLookupHashFind:
+ * @tableobj: poolable hash table pointer find data
+ * @useUUID: boolean to use objsUUID
+ * @key: Key to use for lookup
+ *
+ * Returns a pointer to the entry or NULL on failure
+ */
+virObjectLookupKeysPtr
+virObjectLookupHashFind(void *tableobj,
+bool useUUID,
+const char *key)
+{
+virObjectLookupHashPtr hashObj = virObjectGetLookupHashObj(tableobj);
+
+if (!hashObj) {
+virReportError(VIR_ERR_INTERNAL_ERROR,
+   ("tableobj=%p is not a lookup hash object"), tableobj);
+return NULL;
+}
+
+return virHashLookup(useUUID ? hashObj->objsUUID : hashObj->objsName, key);
+}
+
+
+/**
  * virObjectLookupHashGetName
  * @anyobj: Pointer to a LookupHash object
  *
diff --git a/src/util/virobject.h b/src/util/virobject.h
index 422c81e..ed99540 100644
--- a/src/util/virobject.h
+++ b/src/util/virobject.h
@@ -187,6 +187,11 @@ void
 virObjectLookupHashRemove(void *tableobj,
   virObjectLookupKeysPtr obj);
 
+virObjectLookupKeysPtr
+virObjectLookupHashFind(void *tableobj,
+bool useUUID,
+const char *key);
+
 virHashTablePtr
 virObjectLookupHashGetUUID(void *anyobj);
 
-- 
2.9.4

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


[libvirt] [PATCH v3 09/16] util: Introduce virObjectLoookupHashGet{UUID|Name}

2017-06-22 Thread John Ferlan
Add a pair of accessor API's for the object elements which will return
the requested key value from the object to the caller.

It is up to the caller to check the returned key value and error if the
return value is NULL.

Signed-off-by: John Ferlan 
---
 src/libvirt_private.syms |  2 ++
 src/util/virobject.c | 48 
 src/util/virobject.h |  6 ++
 3 files changed, 56 insertions(+)

diff --git a/src/libvirt_private.syms b/src/libvirt_private.syms
index 655a8f8..28244ab 100644
--- a/src/libvirt_private.syms
+++ b/src/libvirt_private.syms
@@ -2286,6 +2286,8 @@ virObjectListFree;
 virObjectListFreeCount;
 virObjectLock;
 virObjectLockableNew;
+virObjectLookupHashGetName;
+virObjectLookupHashGetUUID;
 virObjectLookupHashNew;
 virObjectLookupKeysGetName;
 virObjectLookupKeysGetUUID;
diff --git a/src/util/virobject.c b/src/util/virobject.c
index 79f1fe9..949a93d 100644
--- a/src/util/virobject.c
+++ b/src/util/virobject.c
@@ -514,6 +514,18 @@ virObjectGetLookupKeysObj(void *anyobj)
 }
 
 
+static virObjectLookupHashPtr
+virObjectGetLookupHashObj(void *anyobj)
+{
+if (virObjectIsClass(anyobj, virObjectLookupHashClass))
+return anyobj;
+
+VIR_OBJECT_USAGE_PRINT_WARNING(anyobj, virObjectLookupHashClass);
+
+return NULL;
+}
+
+
 /**
  * virObjectLock:
  * @anyobj: any instance of virObjectLockablePtr
@@ -740,3 +752,39 @@ virObjectLookupKeysGetName(void *anyobj)
 
 return obj->name;
 }
+
+
+/**
+ * virObjectLookupHashGetUUID
+ * @anyobj: Pointer to a LookupHash object
+ *
+ * Returns: Pointer to the UUID Hash Table or NULL on failure
+ */
+virHashTablePtr
+virObjectLookupHashGetUUID(void *anyobj)
+{
+virObjectLookupHashPtr obj = virObjectGetLookupHashObj(anyobj);
+
+if (!obj)
+return NULL;
+
+return obj->objsUUID;
+}
+
+
+/**
+ * virObjectLookupHashGetName
+ * @anyobj: Pointer to a LookupHash object
+ *
+ * Returns: Pointer to the Name Hash Table or NULL on failure
+ */
+virHashTablePtr
+virObjectLookupHashGetName(void *anyobj)
+{
+virObjectLookupHashPtr obj = virObjectGetLookupHashObj(anyobj);
+
+if (!obj)
+return NULL;
+
+return obj->objsName;
+}
diff --git a/src/util/virobject.h b/src/util/virobject.h
index 3c45182..7da680a 100644
--- a/src/util/virobject.h
+++ b/src/util/virobject.h
@@ -179,4 +179,10 @@ virObjectLookupKeysGetUUID(void *anyobj);
 const char *
 virObjectLookupKeysGetName(void *anyobj);
 
+virHashTablePtr
+virObjectLookupHashGetUUID(void *anyobj);
+
+virHashTablePtr
+virObjectLookupHashGetName(void *anyobj);
+
 #endif /* __VIR_OBJECT_H */
-- 
2.9.4

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


[libvirt] [PATCH v3 02/16] util: Add safety net of checks to ensure valid object

2017-06-22 Thread John Ferlan
The virObject logic "assumes" that whatever is passed to its API's
would be some sort of virObjectPtr; however, if it is not then some
really bad things can happen.

So far there's been only virObject{Ref|Unref}, virObject{Lock|Unlock},
and virObjectIsClass and the virObject and virObjectLockable class
consumers have been well behaved and code well tested. Soon there will
be more consumers and one such consumer tripped over this during testing
by passing a virHashTablePtr to virObjectIsClass which ends up calling
virClassIsDerivedFrom using "obj->klass", which wasn't really a klass
object causing one of those bad things to happen.

To avoid the future possibility that a non virObject class memory was
passed to some virObject* API, this patch adds two new checks - one
to validate that the object has the 0xCAFE value in obj->->u.s.magic
and the other to ensure obj->u.s.magic doesn't "wrap" some day to
0xCAFF if we ever get that many object classes. The check is also
moved before the name VIR_STRDUP to avoid the extra VIR_FREE that would
be required on the failure path.

It is still left up to the caller to handle the failed API calls just
as it would be if it passed a NULL opaque pointer anyobj.

Signed-off-by: John Ferlan 
---
 src/util/virobject.c | 26 +++---
 1 file changed, 19 insertions(+), 7 deletions(-)

diff --git a/src/util/virobject.c b/src/util/virobject.c
index ff9385b..443718b 100644
--- a/src/util/virobject.c
+++ b/src/util/virobject.c
@@ -47,14 +47,21 @@ struct _virClass {
 virObjectDisposeCallback dispose;
 };
 
+#define VIR_OBJECT_NOTVALID(obj) (!obj || ((obj->u.s.magic & 0xCAFE) != 
0xCAFE))
+
 #define VIR_OBJECT_USAGE_PRINT_WARNING(anyobj, objclass)\
 do {\
 virObjectPtr obj = anyobj;  \
-if (!obj)   \
-VIR_WARN("Object cannot be NULL");  \
-else\
+if (VIR_OBJECT_NOTVALID(obj)) { \
+if (!obj)   \
+VIR_WARN("Object cannot be NULL");  \
+else\
+VIR_WARN("Object %p has a bad magic number %X", \
+ obj, obj->u.s.magic);  \
+} else {\
 VIR_WARN("Object %p (%s) is not a %s instance", \
   anyobj, obj->klass->name, #objclass); \
+}   \
 } while (0)
 
 static virClassPtr virObjectClass;
@@ -153,9 +160,14 @@ virClassNew(virClassPtr parent,
 goto error;
 
 klass->parent = parent;
+klass->magic = virAtomicIntInc();
+if (klass->magic > 0xCAFE) {
+virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
+   _("too many object classes defined"));
+goto error;
+}
 if (VIR_STRDUP(klass->name, name) < 0)
 goto error;
-klass->magic = virAtomicIntInc();
 klass->objectSize = objectSize;
 klass->dispose = dispose;
 
@@ -272,7 +284,7 @@ virObjectUnref(void *anyobj)
 {
 virObjectPtr obj = anyobj;
 
-if (!obj)
+if (VIR_OBJECT_NOTVALID(obj))
 return false;
 
 bool lastRef = virAtomicIntDecAndTest(>u.s.refs);
@@ -311,7 +323,7 @@ virObjectRef(void *anyobj)
 {
 virObjectPtr obj = anyobj;
 
-if (!obj)
+if (VIR_OBJECT_NOTVALID(obj))
 return NULL;
 virAtomicIntInc(>u.s.refs);
 PROBE(OBJECT_REF, "obj=%p", obj);
@@ -389,7 +401,7 @@ virObjectIsClass(void *anyobj,
  virClassPtr klass)
 {
 virObjectPtr obj = anyobj;
-if (!obj)
+if (VIR_OBJECT_NOTVALID(obj))
 return false;
 
 return virClassIsDerivedFrom(obj->klass, klass);
-- 
2.9.4

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


[libvirt] [PATCH v3 05/16] interface: Use virObjectLookupKeys

2017-06-22 Thread John Ferlan
Use the virObjectLookupKeys rather than virObjectLockable.

Signed-off-by: John Ferlan 
---
 src/conf/virinterfaceobj.c | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

diff --git a/src/conf/virinterfaceobj.c b/src/conf/virinterfaceobj.c
index 106f232..243ff33 100644
--- a/src/conf/virinterfaceobj.c
+++ b/src/conf/virinterfaceobj.c
@@ -33,7 +33,7 @@
 VIR_LOG_INIT("conf.virinterfaceobj");
 
 struct _virInterfaceObj {
-virObjectLockable parent;
+virObjectLookupKeys parent;
 
 bool active;   /* true if interface is active (up) */
 virInterfaceDefPtr def; /* The interface definition */
@@ -52,7 +52,7 @@ static void virInterfaceObjDispose(void *obj);
 static int
 virInterfaceObjOnceInit(void)
 {
-if (!(virInterfaceObjClass = virClassNew(virClassForObjectLockable(),
+if (!(virInterfaceObjClass = virClassNew(virClassForObjectLookupKeys(),
  "virInterfaceObj",
  sizeof(virInterfaceObj),
  virInterfaceObjDispose)))
@@ -81,7 +81,7 @@ virInterfaceObjNew(virInterfaceDefPtr def)
 if (virInterfaceObjInitialize() < 0)
 return NULL;
 
-if (!(obj = virObjectLockableNew(virInterfaceObjClass)))
+if (!(obj = virObjectLookupKeysNew(virInterfaceObjClass, NULL, def->name)))
 return NULL;
 
 virObjectLock(obj);
-- 
2.9.4

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


[libvirt] [PATCH v3 14/16] util: Introduce virObjectLookupHashClone

2017-06-22 Thread John Ferlan
A convenience API that will utilize the virHashForEach API for a specified
LookupHash in order to create a clone/copy. Primary consumer is the interface
driver which has a desire to save off a copy of it's @Name LookupHash table
in order to possible restore it if something goes wrong during processing.
The callback function's primary purpose is to copy anything within the
local LookupKeys into the target.

Signed-off-by: John Ferlan 
---
 src/libvirt_private.syms |  1 +
 src/util/virobject.c | 79 
 src/util/virobject.h | 10 ++
 3 files changed, 90 insertions(+)

diff --git a/src/libvirt_private.syms b/src/libvirt_private.syms
index 2c4296a..41638f6 100644
--- a/src/libvirt_private.syms
+++ b/src/libvirt_private.syms
@@ -2287,6 +2287,7 @@ virObjectListFreeCount;
 virObjectLock;
 virObjectLockableNew;
 virObjectLookupHashAdd;
+virObjectLookupHashClone;
 virObjectLookupHashFind;
 virObjectLookupHashForEach;
 virObjectLookupHashGetName;
diff --git a/src/util/virobject.c b/src/util/virobject.c
index 60bc5b5..9182a2e 100644
--- a/src/util/virobject.c
+++ b/src/util/virobject.c
@@ -992,3 +992,82 @@ virObjectLookupHashSearch(void *tableobj,
 
 return obj;
 }
+
+
+struct cloneData {
+virObjectLookupHashCloneCallback callback;
+virObjectLookupHashPtr dst;
+bool error;
+};
+
+/*
+ * Take the provided virHashForEach element and call the driver @cb function
+ * with the input @dstTable and the source element from the @srcTable in order
+ * to perform the copy - tracking success/failure using the error boolean.
+ * Once there's a failure, no future copy/clone will occur.
+ *
+ * The @cb function can expect the @srcTable object to be locked upon entry.
+ *
+ * Returns 0 to the virHashForEach on success, -1 on failure.
+ */
+static int
+cloneCallback(void *payload,
+  const void *name ATTRIBUTE_UNUSED,
+  void *opaque)
+{
+virObjectLookupKeysPtr obj = payload;
+struct cloneData *data = opaque;
+
+if (data->error)
+return 0;
+
+virObjectLock(obj);
+
+if (data->callback(data->dst, obj) < 0)
+data->error = true;
+
+virObjectUnlock(obj);
+
+if (data->error)
+return -1;
+
+return 0;
+}
+
+/**
+ * virObjectLookupHashClone
+ * @srcTable: source poolable hash table pointer to clone from
+ * @dstTable: destination poolable hash table pointer to clone to
+ * @useUUID: Use the objsUUID for clone (or objsName)
+ * @cb: callback function from driver code to handle the clone
+ *
+ * The clone function is designed to traverse each @srcTable hash element
+ * and call the driver specific @cb function with the element from the
+ * @srcTable in order to clone into the @dstTable. If @useUUID is true,
+ * then clone the objsUUID table; otherwise, clone the objsName table.
+ *
+ * Return 0 on success, -1 on failure
+ */
+int
+virObjectLookupHashClone(void *srcTable,
+ void *dstTable,
+ bool useUUID,
+ virObjectLookupHashCloneCallback cb)
+{
+virObjectLookupHashPtr src = virObjectGetLookupHashObj(srcTable);
+virObjectLookupHashPtr dst = virObjectGetLookupHashObj(dstTable);
+struct cloneData data = { .callback = cb, .dst = dst, .error = false };
+
+if (!src || !dst)
+return -1;
+
+virObjectLock(src);
+virHashForEach(useUUID ? src->objsUUID : src->objsName,
+   cloneCallback, );
+virObjectUnlock(src);
+
+if (data.error)
+return -1;
+
+return 0;
+}
diff --git a/src/util/virobject.h b/src/util/virobject.h
index 7e58e34..350929d 100644
--- a/src/util/virobject.h
+++ b/src/util/virobject.h
@@ -224,4 +224,14 @@ virObjectLookupHashSearch(void *tableobj,
   virHashSearcher callback,
   void *opaque);
 
+typedef int (*virObjectLookupHashCloneCallback)(void *dstTable,
+   void *srcElem);
+int
+virObjectLookupHashClone(void *srcTable,
+ void *dstTable,
+ bool useUUID,
+ virObjectLookupHashCloneCallback cb)
+ATTRIBUTE_NONNULL(4);
+
+
 #endif /* __VIR_OBJECT_H */
-- 
2.9.4

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


[libvirt] [PATCH v3 13/16] util: Introduce virObjectLookupHashSearch

2017-06-22 Thread John Ferlan
A common object API wrapper to use the virHashSearch API to search the
specified LookupHash for specific data defined in the @opaque parameter.
Once data is found, the search would end and the LookupKeys object that
is represented is returned locked with it's reference count incremented.

It is up to the caller to unlock and lower the refcnt once done with the
object and of course handle a NULL return indicating no object found.

Signed-off-by: John Ferlan 
---
 src/libvirt_private.syms |  1 +
 src/util/virobject.c | 38 ++
 src/util/virobject.h |  6 ++
 3 files changed, 45 insertions(+)

diff --git a/src/libvirt_private.syms b/src/libvirt_private.syms
index f783fec..2c4296a 100644
--- a/src/libvirt_private.syms
+++ b/src/libvirt_private.syms
@@ -2293,6 +2293,7 @@ virObjectLookupHashGetName;
 virObjectLookupHashGetUUID;
 virObjectLookupHashNew;
 virObjectLookupHashRemove;
+virObjectLookupHashSearch;
 virObjectLookupKeysGetName;
 virObjectLookupKeysGetUUID;
 virObjectLookupKeysIsActive;
diff --git a/src/util/virobject.c b/src/util/virobject.c
index 8a994f5..60bc5b5 100644
--- a/src/util/virobject.c
+++ b/src/util/virobject.c
@@ -954,3 +954,41 @@ virObjectLookupHashForEach(void *tableobj,
 }
 return -1;
 }
+
+
+/**
+ * virObjectLookupHashSearchName
+ * @tableobj: poolable hash table pointer to search
+ * @useUUID: boolean to use objsUUID
+ * @callback: callback function to handle the object specific checks
+ * @opaque: callback data
+ *
+ * Search the objsName hash table calling the specified @callback routine
+ * with an object and @opaque data in order to determine whether the searched
+ * object is represented by the @opaque data.
+ *
+ * Returns locked/refcnt incremented object on success, NULL on failure
+ */
+virObjectLookupKeysPtr
+virObjectLookupHashSearch(void *tableobj,
+  bool useUUID,
+  virHashSearcher callback,
+  void *opaque)
+{
+virObjectLookupHashPtr tableObj = virObjectGetLookupHashObj(tableobj);
+virObjectLookupKeysPtr obj;
+
+if (!tableObj)
+return NULL;
+
+virObjectLock(tableObj);
+obj = virHashSearch(useUUID ? tableObj->objsUUID : tableObj->objsName,
+callback, opaque);
+virObjectRef(obj);
+virObjectUnlock(tableObj);
+
+if (obj)
+virObjectLock(obj);
+
+return obj;
+}
diff --git a/src/util/virobject.h b/src/util/virobject.h
index 926c9d3..7e58e34 100644
--- a/src/util/virobject.h
+++ b/src/util/virobject.h
@@ -218,4 +218,10 @@ virObjectLookupHashForEach(void *tableobj,
virHashIterator callback,
virObjectLookupHashForEachDataPtr data);
 
+virObjectLookupKeysPtr
+virObjectLookupHashSearch(void *tableobj,
+  bool useUUID,
+  virHashSearcher callback,
+  void *opaque);
+
 #endif /* __VIR_OBJECT_H */
-- 
2.9.4

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


[libvirt] [PATCH v3 16/16] test: Clean up test driver Interface interactions

2017-06-22 Thread John Ferlan
Now that we have self locking hash table for Interface object lookups,
there's no need to take the test driver lock in order to "lock" between
the various API's, so remove the Lock/Unlock logic accordingly.

Add a virInterfaceObjListFree during testDriverFree for the backupIfaces
"just in case". Also use the VIR_STEAL_PTR rather than inline the code.

Finally alter a couple of "if ((obj = function()) == NULL" to use the
more standard "if (!(obj = function()))" syntax.

Signed-off-by: John Ferlan 
---
 src/test/test_driver.c | 55 --
 1 file changed, 13 insertions(+), 42 deletions(-)

diff --git a/src/test/test_driver.c b/src/test/test_driver.c
index 11e7fd8..ff2077c 100644
--- a/src/test/test_driver.c
+++ b/src/test/test_driver.c
@@ -155,6 +155,7 @@ testDriverFree(testDriverPtr driver)
 virNodeDeviceObjListFree(>devs);
 virObjectUnref(driver->networks);
 virInterfaceObjListFree(driver->ifaces);
+virInterfaceObjListFree(driver->backupIfaces);
 virStoragePoolObjListFree(>pools);
 virObjectUnref(driver->eventState);
 virMutexUnlock(>lock);
@@ -3630,11 +3631,7 @@ testInterfaceObjFindByName(testDriverPtr privconn,
 {
 virInterfaceObjPtr obj;
 
-testDriverLock(privconn);
-obj = virInterfaceObjListFindByName(privconn->ifaces, name);
-testDriverUnlock(privconn);
-
-if (!obj)
+if (!(obj = virInterfaceObjListFindByName(privconn->ifaces, name)))
 virReportError(VIR_ERR_NO_INTERFACE,
_("no interface with matching name '%s'"),
name);
@@ -3647,12 +3644,8 @@ static int
 testConnectNumOfInterfaces(virConnectPtr conn)
 {
 testDriverPtr privconn = conn->privateData;
-int ninterfaces;
 
-testDriverLock(privconn);
-ninterfaces = virInterfaceObjListNumOfInterfaces(privconn->ifaces, true);
-testDriverUnlock(privconn);
-return ninterfaces;
+return virInterfaceObjListNumOfInterfaces(privconn->ifaces, true);
 }
 
 
@@ -3662,14 +3655,8 @@ testConnectListInterfaces(virConnectPtr conn,
   int maxnames)
 {
 testDriverPtr privconn = conn->privateData;
-int nnames;
 
-testDriverLock(privconn);
-nnames = virInterfaceObjListGetNames(privconn->ifaces, true,
- names, maxnames);
-testDriverUnlock(privconn);
-
-return nnames;
+return virInterfaceObjListGetNames(privconn->ifaces, true, names, 
maxnames);
 }
 
 
@@ -3677,12 +3664,8 @@ static int
 testConnectNumOfDefinedInterfaces(virConnectPtr conn)
 {
 testDriverPtr privconn = conn->privateData;
-int ninterfaces;
 
-testDriverLock(privconn);
-ninterfaces = virInterfaceObjListNumOfInterfaces(privconn->ifaces, false);
-testDriverUnlock(privconn);
-return ninterfaces;
+return virInterfaceObjListNumOfInterfaces(privconn->ifaces, false);
 }
 
 
@@ -3692,14 +3675,8 @@ testConnectListDefinedInterfaces(virConnectPtr conn,
  int maxnames)
 {
 testDriverPtr privconn = conn->privateData;
-int nnames;
 
-testDriverLock(privconn);
-nnames = virInterfaceObjListGetNames(privconn->ifaces, false,
- names, maxnames);
-testDriverUnlock(privconn);
-
-return nnames;
+return virInterfaceObjListGetNames(privconn->ifaces, false, names, 
maxnames);
 }
 
 
@@ -3732,12 +3709,8 @@ testInterfaceLookupByMACString(virConnectPtr conn,
 char *ifacenames[] = { NULL, NULL };
 virInterfacePtr ret = NULL;
 
-testDriverLock(privconn);
-ifacect = virInterfaceObjListFindByMACString(privconn->ifaces, mac,
- ifacenames, 2);
-testDriverUnlock(privconn);
-
-if (ifacect == 0) {
+if ((ifacect = virInterfaceObjListFindByMACString(privconn->ifaces, mac,
+  ifacenames, 2)) == 0) {
 virReportError(VIR_ERR_NO_INTERFACE,
_("no interface with matching mac '%s'"), mac);
 goto cleanup;
@@ -3821,6 +3794,7 @@ testInterfaceChangeCommit(virConnectPtr conn,
 }
 
 virInterfaceObjListFree(privconn->backupIfaces);
+privconn->backupIfaces = NULL;
 privconn->transaction_running = false;
 
 ret = 0;
@@ -3851,8 +3825,7 @@ testInterfaceChangeRollback(virConnectPtr conn,
 }
 
 virInterfaceObjListFree(privconn->ifaces);
-privconn->ifaces = privconn->backupIfaces;
-privconn->backupIfaces = NULL;
+VIR_STEAL_PTR(privconn->ifaces, privconn->backupIfaces);
 
 privconn->transaction_running = false;
 
@@ -3899,11 +3872,10 @@ testInterfaceDefineXML(virConnectPtr conn,
 
 virCheckFlags(0, NULL);
 
-testDriverLock(privconn);
-if ((def = virInterfaceDefParseString(xmlStr)) == NULL)
-goto cleanup;
+if (!(def = virInterfaceDefParseString(xmlStr)))
+return NULL;
 
-if ((obj = 

[libvirt] [PATCH v3 07/16] interface: Use virObjectLookupKeys*Active

2017-06-22 Thread John Ferlan
Use the @active definition of the virObjectLookupKeys

Signed-off-by: John Ferlan 
---
 src/conf/virinterfaceobj.c | 5 ++---
 1 file changed, 2 insertions(+), 3 deletions(-)

diff --git a/src/conf/virinterfaceobj.c b/src/conf/virinterfaceobj.c
index 243ff33..69a716b 100644
--- a/src/conf/virinterfaceobj.c
+++ b/src/conf/virinterfaceobj.c
@@ -35,7 +35,6 @@ VIR_LOG_INIT("conf.virinterfaceobj");
 struct _virInterfaceObj {
 virObjectLookupKeys parent;
 
-bool active;   /* true if interface is active (up) */
 virInterfaceDefPtr def; /* The interface definition */
 };
 
@@ -113,7 +112,7 @@ virInterfaceObjGetDef(virInterfaceObjPtr obj)
 bool
 virInterfaceObjIsActive(virInterfaceObjPtr obj)
 {
-return obj->active;
+return virObjectLookupKeysIsActive(obj);
 }
 
 
@@ -121,7 +120,7 @@ void
 virInterfaceObjSetActive(virInterfaceObjPtr obj,
  bool active)
 {
-obj->active = active;
+virObjectLookupKeysSetActive(obj, active);
 }
 
 
-- 
2.9.4

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


[libvirt] [PATCH v3 04/16] util: Introduce virObjectLookupKeysGet{UUID|Name}

2017-06-22 Thread John Ferlan
Add a pair of accessor API's for the object elements which will return
the requested key value from the object to the caller.

It is up to the caller to check the returned key value and error if the
return value is NULL.

Signed-off-by: John Ferlan 
---
 src/libvirt_private.syms |  2 ++
 src/util/virobject.c | 48 
 src/util/virobject.h |  6 ++
 3 files changed, 56 insertions(+)

diff --git a/src/libvirt_private.syms b/src/libvirt_private.syms
index 44d712d..bfc68eb 100644
--- a/src/libvirt_private.syms
+++ b/src/libvirt_private.syms
@@ -2285,6 +2285,8 @@ virObjectListFree;
 virObjectListFreeCount;
 virObjectLock;
 virObjectLockableNew;
+virObjectLookupKeysGetName;
+virObjectLookupKeysGetUUID;
 virObjectLookupKeysNew;
 virObjectNew;
 virObjectRef;
diff --git a/src/util/virobject.c b/src/util/virobject.c
index 6908e8d..862d46b 100644
--- a/src/util/virobject.c
+++ b/src/util/virobject.c
@@ -419,6 +419,18 @@ virObjectGetLockableObj(void *anyobj)
 }
 
 
+static virObjectLookupKeysPtr
+virObjectGetLookupKeysObj(void *anyobj)
+{
+if (virObjectIsClass(anyobj, virObjectLookupKeysClass))
+return anyobj;
+
+VIR_OBJECT_USAGE_PRINT_WARNING(anyobj, virObjectLookupKeysClass);
+
+return NULL;
+}
+
+
 /**
  * virObjectLock:
  * @anyobj: any instance of virObjectLockablePtr
@@ -570,3 +582,39 @@ virObjectListFreeCount(void *list,
 
 VIR_FREE(list);
 }
+
+
+/**
+ * virObjectLookupKeysGetUUID
+ * @anyobj: Pointer to a LookupKeys object
+ *
+ * Returns: Pointer to the object's uuid key value or possibly NULL
+ */
+const char *
+virObjectLookupKeysGetUUID(void *anyobj)
+{
+virObjectLookupKeysPtr obj = virObjectGetLookupKeysObj(anyobj);
+
+if (!obj)
+return NULL;
+
+return obj->uuid;
+}
+
+
+/**
+ * virObjectLookupKeysGetName
+ * @anyobj: Pointer to a LookupKeys object
+ *
+ * Returns: Pointer to the object's name key value or possibly NULL
+ */
+const char *
+virObjectLookupKeysGetName(void *anyobj)
+{
+virObjectLookupKeysPtr obj = virObjectGetLookupKeysObj(anyobj);
+
+if (!obj)
+return NULL;
+
+return obj->name;
+}
diff --git a/src/util/virobject.h b/src/util/virobject.h
index 1cade9d..e77634b 100644
--- a/src/util/virobject.h
+++ b/src/util/virobject.h
@@ -140,4 +140,10 @@ void
 virObjectListFreeCount(void *list,
size_t count);
 
+const char *
+virObjectLookupKeysGetUUID(void *anyobj);
+
+const char *
+virObjectLookupKeysGetName(void *anyobj);
+
 #endif /* __VIR_OBJECT_H */
-- 
2.9.4

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


[libvirt] [PATCH v3 10/16] util: Introduce virObjectLookupHash{Add|Remove}

2017-06-22 Thread John Ferlan
Add a pair of API's to add/remove the LookupKeys object to/from the
LookupHash object. The caller must check return status and handle
failure properly for the Add. The Remove API callers are all void
functions, so only report the problem and ignore the attempt to
remove if for some reason the passed @tableobj is not as expected.

Signed-off-by: John Ferlan 
---
 src/libvirt_private.syms |  2 ++
 src/util/virobject.c | 80 
 src/util/virobject.h |  8 +
 3 files changed, 90 insertions(+)

diff --git a/src/libvirt_private.syms b/src/libvirt_private.syms
index 28244ab..de986e5 100644
--- a/src/libvirt_private.syms
+++ b/src/libvirt_private.syms
@@ -2286,9 +2286,11 @@ virObjectListFree;
 virObjectListFreeCount;
 virObjectLock;
 virObjectLockableNew;
+virObjectLookupHashAdd;
 virObjectLookupHashGetName;
 virObjectLookupHashGetUUID;
 virObjectLookupHashNew;
+virObjectLookupHashRemove;
 virObjectLookupKeysGetName;
 virObjectLookupKeysGetUUID;
 virObjectLookupKeysIsActive;
diff --git a/src/util/virobject.c b/src/util/virobject.c
index 949a93d..9443dda 100644
--- a/src/util/virobject.c
+++ b/src/util/virobject.c
@@ -755,6 +755,86 @@ virObjectLookupKeysGetName(void *anyobj)
 
 
 /**
+ * virObjectLookupHashAdd:
+ * @tableobj: LookupHash object with objsUUID/objsName
+ * @obj: The LookupKeys object to insert in the hash table(s)
+ *
+ * Insert @obj into the hash tables found in @tableobj.
+ *
+ * Returns 0 on success, -1 on failure.
+ */
+int
+virObjectLookupHashAdd(void *tableobj,
+   virObjectLookupKeysPtr obj)
+{
+virObjectLookupHashPtr hashObj = virObjectGetLookupHashObj(tableobj);
+
+if (!hashObj) {
+virReportError(VIR_ERR_INTERNAL_ERROR,
+   _("tableobj=%p is not a lookup hash object"), tableobj);
+return -1;
+}
+
+if (obj->uuid) {
+if (virHashAddEntry(hashObj->objsUUID, obj->uuid, obj) < 0)
+return -1;
+virObjectRef(obj);
+}
+
+if (obj->name) {
+if (virHashAddEntry(hashObj->objsName, obj->name, obj) < 0) {
+virHashRemoveEntry(hashObj->objsUUID, obj->uuid);
+return -1;
+}
+virObjectRef(obj);
+}
+
+return 0;
+}
+
+
+/**
+ * virObjectLookupHashRemove:
+ * @tableobj: LookupHash object with objsUUID/objsName
+ * @obj: The LookupKeys object to remove from the hash table(s)
+ *
+ * Remove @obj from the hash tables found in @tableobj. The common
+ * function to remove an object from a hash table will also cause
+ * the virObjectUnref to be called via virObjectFreeHashData since
+ * the virHashCreate used that as the Free object element argument.
+ *
+ * Even though this is a void, report the error for a bad @tableobj.
+ */
+void
+virObjectLookupHashRemove(void *tableobj,
+  virObjectLookupKeysPtr obj)
+{
+virObjectLookupHashPtr hashObj;
+
+if (!obj)
+return;
+
+if (!(hashObj = virObjectGetLookupHashObj(tableobj))) {
+virReportError(VIR_ERR_INTERNAL_ERROR,
+   _("tableobj=%p is not a lookup hash object"), tableobj);
+return;
+}
+
+virObjectRef(obj);
+virObjectUnlock(obj);
+virObjectLock(tableobj);
+virObjectLock(obj);
+if (obj->uuid)
+virHashRemoveEntry(hashObj->objsUUID, obj->uuid);
+if (obj->name)
+virHashRemoveEntry(hashObj->objsName, obj->name);
+virObjectUnlock(obj);
+virObjectUnref(obj);
+virObjectUnlock(tableobj);
+}
+
+
+/**
  * virObjectLookupHashGetUUID
  * @anyobj: Pointer to a LookupHash object
  *
diff --git a/src/util/virobject.h b/src/util/virobject.h
index 7da680a..422c81e 100644
--- a/src/util/virobject.h
+++ b/src/util/virobject.h
@@ -179,6 +179,14 @@ virObjectLookupKeysGetUUID(void *anyobj);
 const char *
 virObjectLookupKeysGetName(void *anyobj);
 
+int
+virObjectLookupHashAdd(void *tableobj,
+   virObjectLookupKeysPtr obj);
+
+void
+virObjectLookupHashRemove(void *tableobj,
+  virObjectLookupKeysPtr obj);
+
 virHashTablePtr
 virObjectLookupHashGetUUID(void *anyobj);
 
-- 
2.9.4

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


[libvirt] [PATCH v3 12/16] util: Introduce virObjectLookupHashForEach

2017-06-22 Thread John Ferlan
Introduce an API to use the virHashForEach API to go through each element
of a specified LookupHash (via @useUUID) calling a callback with a LookupKey
object entry from the LookupHash in order for it to be processed.

Create a common structure to define the various pieces of data needed by
the callback consumers:

struct _virObjectLookupHashForEachData {
virConnectPtr conn;-> Connect ptr for @aclfilter APIs
void *aclfilter;   -> A pointer to function for ACL calls
bool wantActive;   -> Filter active objs
bool error;-> Set by callback functions for error
const char *matchstr;  -> Filter for specific string in many objs
unsigned int flags;-> @flags argument to for Export calls
int nelems;-> # of elements found and passing filters
void **elems;  -> array of elements
int maxelems;  -> maximum # of elements to collect
};

Upon successful completion, the data.nelems is returned to the caller
and possibly various fields within the structure filled in depending
on the callers need as follows:

vir{Object}NumOf{Elem}
=> Would typically only care about @nelems based on whether
   the caller cares about @wantActive. Can also filter results
   based on the @aclfilter call.

vir{Object}Get{Key}
=> Use the @elems and @maxelems in order to fill in an array
   of char ** strings based on the {Key} filtering data as
   necessary from the @aclfilter and possibly the @matchstr.
   Callers of this function will preallocate the @elems and
   supply the @maxelems value. The @nelems is used to keep track
   of the number of elements.

vir{Object}Export
=> When @maxelems == -1, will cause allocation into data->elems
   of an array sized by the hash table size which will be used by
   the callback function to store addresses of objects specific to
   each {Object} that are typically assocated with virConnectListAll*
   API's from the virGet{Object}() calls. The @flags argument is
   typically used for additional filtering via vir{Object}Match or
   vir{Object}Filter APIs found in various vir*obj modules. Upon
   return from the call, the calling function must then move the
   data->elems into the returned structure.

It is up to the callback function to set @error in the event of an error
during processing resulting in calling the VIR_FREE() for each of the
@nelems already in the array.

When an error occurs, any collection done by the callback functions into
the @elems array is discarded.

Signed-off-by: John Ferlan 
---
 src/libvirt_private.syms |  1 +
 src/util/virobject.c | 61 
 src/util/virobject.h | 20 
 3 files changed, 82 insertions(+)

diff --git a/src/libvirt_private.syms b/src/libvirt_private.syms
index 68961e7..f783fec 100644
--- a/src/libvirt_private.syms
+++ b/src/libvirt_private.syms
@@ -2288,6 +2288,7 @@ virObjectLock;
 virObjectLockableNew;
 virObjectLookupHashAdd;
 virObjectLookupHashFind;
+virObjectLookupHashForEach;
 virObjectLookupHashGetName;
 virObjectLookupHashGetUUID;
 virObjectLookupHashNew;
diff --git a/src/util/virobject.c b/src/util/virobject.c
index 01922b3..8a994f5 100644
--- a/src/util/virobject.c
+++ b/src/util/virobject.c
@@ -893,3 +893,64 @@ virObjectLookupHashGetName(void *anyobj)
 
 return obj->objsName;
 }
+
+
+/**
+ * virObjectLookupHashForEach
+ * @tableobj: poolable hash table pointer to walk through
+ * @useUUID: boolean to use objsUUID
+ * @callback: callback function to handle the object specific checks
+ * @opaque: callback data
+ *
+ * For each element of the objsName hash table make a call into the
+ * callback routine to handle its task
+ *
+ * Returns 0 on success, -1 on failure
+ */
+int
+virObjectLookupHashForEach(void *tableobj,
+   bool useUUID,
+   virHashIterator callback,
+   virObjectLookupHashForEachDataPtr data)
+{
+virObjectLookupHashPtr hashObj = virObjectGetLookupHashObj(tableobj);
+virHashTablePtr tbl;
+
+if (!hashObj)
+return -1;
+
+if (useUUID)
+tbl = hashObj->objsUUID;
+else
+tbl = hashObj->objsName;
+
+if (data->maxelems == -1) {
+if (VIR_ALLOC_N(data->elems, virHashSize(tbl) + 1) < 0)
+return -1;
+}
+
+virObjectLock(hashObj);
+virHashForEach(tbl, callback, data);
+virObjectUnlock(hashObj);
+
+if (data->error)
+goto error;
+
+if (data->maxelems == -1) {
+/* trim the array to the final size */
+ignore_value(VIR_REALLOC_N(data->elems, data->nelems + 1));
+}
+
+return data->nelems;
+
+ error:
+if (data->elems) {
+if (data->maxelems == -1) {
+  

[libvirt] [PATCH v3 15/16] interface: Use virObjectLookupHash

2017-06-22 Thread John Ferlan
Convert the code to use the LookupHash object and APIs rather than the
local forward linked list processing. While this could have been done
function by function (for easier review) - converting to the LookupHash
would have required changes to the Add, Remove, Find, and List functions
anyway in order to properly search hash tables - so rather than piecemeal
those changes only to undo them, just use the object.

Signed-off-by: John Ferlan 
---
 src/conf/virinterfaceobj.c | 321 ++---
 1 file changed, 189 insertions(+), 132 deletions(-)

diff --git a/src/conf/virinterfaceobj.c b/src/conf/virinterfaceobj.c
index 69a716b..053a5e5 100644
--- a/src/conf/virinterfaceobj.c
+++ b/src/conf/virinterfaceobj.c
@@ -39,8 +39,7 @@ struct _virInterfaceObj {
 };
 
 struct _virInterfaceObjList {
-size_t count;
-virInterfaceObjPtr *objs;
+virObjectLookupHash parent;
 };
 
 /* virInterfaceObj manipulation */
@@ -128,11 +127,40 @@ virInterfaceObjSetActive(virInterfaceObjPtr obj,
 virInterfaceObjListPtr
 virInterfaceObjListNew(void)
 {
-virInterfaceObjListPtr interfaces;
+return virObjectLookupHashNew(virClassForObjectLookupHash(), 10);
+}
 
-if (VIR_ALLOC(interfaces) < 0)
-return NULL;
-return interfaces;
+
+static int
+virInterfaceObjListFindByMACStringCallback(void *payload,
+   const void *name ATTRIBUTE_UNUSED,
+   void *opaque)
+{
+virInterfaceObjPtr obj = payload;
+virObjectLookupHashForEachDataPtr data = opaque;
+char **const matches = (char **const)data->elems;
+virInterfaceDefPtr def;
+int ret = -1;
+
+if (data->error)
+return 0;
+
+virObjectLock(obj);
+def = obj->def;
+if (STRCASEEQ(def->mac, data->matchstr)) {
+if (data->nelems < data->maxelems) {
+if (VIR_STRDUP(matches[data->nelems], def->name) < 0) {
+data->error = true;
+goto cleanup;
+}
+data->nelems++;
+}
+}
+ret = 0;
+
+ cleanup:
+virObjectUnlock(obj);
+return ret;
 }
 
 
@@ -142,33 +170,23 @@ virInterfaceObjListFindByMACString(virInterfaceObjListPtr 
interfaces,
char **const matches,
int maxmatches)
 {
-size_t i;
-int matchct = 0;
-
-for (i = 0; i < interfaces->count; i++) {
-virInterfaceObjPtr obj = interfaces->objs[i];
-virInterfaceDefPtr def;
+virObjectLookupHashForEachData data = {
+.error = false, .matchstr = mac, .nelems = 0,
+.elems = (void **)matches, .maxelems = maxmatches };
 
-virObjectLock(obj);
-def = obj->def;
-if (STRCASEEQ(def->mac, mac)) {
-if (matchct < maxmatches) {
-if (VIR_STRDUP(matches[matchct], def->name) < 0) {
-virObjectUnlock(obj);
-goto error;
-}
-matchct++;
-}
-}
-virObjectUnlock(obj);
-}
-return matchct;
+return virObjectLookupHashForEach(interfaces, false,
+  
virInterfaceObjListFindByMACStringCallback,
+  );
+}
 
- error:
-while (--matchct >= 0)
-VIR_FREE(matches[matchct]);
 
-return -1;
+static virInterfaceObjPtr
+virInterfaceObjListFindByNameLocked(virInterfaceObjListPtr interfaces,
+const char *name)
+{
+virObjectLookupKeysPtr obj = virObjectLookupHashFind(interfaces, false,
+ name);
+return virObjectRef((virInterfaceObjPtr)obj);
 }
 
 
@@ -176,74 +194,96 @@ virInterfaceObjPtr
 virInterfaceObjListFindByName(virInterfaceObjListPtr interfaces,
   const char *name)
 {
-size_t i;
-
-for (i = 0; i < interfaces->count; i++) {
-virInterfaceObjPtr obj = interfaces->objs[i];
-virInterfaceDefPtr def;
+virInterfaceObjPtr obj;
 
+virObjectLock(interfaces);
+obj = virInterfaceObjListFindByNameLocked(interfaces, name);
+virObjectUnlock(interfaces);
+if (obj)
 virObjectLock(obj);
-def = obj->def;
-if (STREQ(def->name, name))
-return virObjectRef(obj);
-virObjectUnlock(obj);
-}
 
-return NULL;
+return obj;
 }
 
 
 void
 virInterfaceObjListFree(virInterfaceObjListPtr interfaces)
 {
-size_t i;
+virObjectUnref(interfaces);
+}
+
+
+struct interfaceCloneData {
+const char *primaryKey;
+virInterfaceObjListPtr dest;
+bool error;
+};
+
+static int
+virInterfaceObjListCloneCallback(void *payload,
+ const void *name ATTRIBUTE_UNUSED,
+ void *opaque)
+{
+virInterfaceObjPtr srcobj = payload;
+struct interfaceCloneData *data = opaque;
+int ret = -1;
+

[libvirt] [PATCH v3 08/16] util: Introduce virObjectLookupHash

2017-06-22 Thread John Ferlan
Using the virObjectLockable class as the base and the virObjectLookupKeys
uuid and name from the virObjectLookupKeys, create the virObjectLookupHash
to manage a common mechanism to store objects for a driver via self locking
hash tables.

Each hash table will have :

tableElemsStart -> # of elements to create the initial table
objsUUID-> Hash table for the LookupKeys->UUID
objsName-> Hash table for the LookupKeys->name

A secondary benefit of self locking hash tables is each driver then
does not have to keep a higher level driver lock for interactions with
the object storage since the object itself can manage locking as needed.

Signed-off-by: John Ferlan 
---
 src/libvirt_private.syms |  2 ++
 src/util/virobject.c | 85 +++-
 src/util/virobject.h | 24 ++
 3 files changed, 110 insertions(+), 1 deletion(-)

diff --git a/src/libvirt_private.syms b/src/libvirt_private.syms
index 6a87e6b..655a8f8 100644
--- a/src/libvirt_private.syms
+++ b/src/libvirt_private.syms
@@ -2274,6 +2274,7 @@ virNumaSetupMemoryPolicy;
 # util/virobject.h
 virClassForObject;
 virClassForObjectLockable;
+virClassForObjectLookupHash;
 virClassForObjectLookupKeys;
 virClassIsDerivedFrom;
 virClassName;
@@ -2285,6 +2286,7 @@ virObjectListFree;
 virObjectListFreeCount;
 virObjectLock;
 virObjectLockableNew;
+virObjectLookupHashNew;
 virObjectLookupKeysGetName;
 virObjectLookupKeysGetUUID;
 virObjectLookupKeysIsActive;
diff --git a/src/util/virobject.c b/src/util/virobject.c
index 6e2b222..79f1fe9 100644
--- a/src/util/virobject.c
+++ b/src/util/virobject.c
@@ -67,9 +67,11 @@ struct _virClass {
 static virClassPtr virObjectClass;
 static virClassPtr virObjectLockableClass;
 static virClassPtr virObjectLookupKeysClass;
+static virClassPtr virObjectLookupHashClass;
 
 static void virObjectLockableDispose(void *anyobj);
 static void virObjectLookupKeysDispose(void *anyobj);
+static void virObjectLookupHashDispose(void *anyobj);
 
 static int
 virObjectOnceInit(void)
@@ -92,6 +94,12 @@ virObjectOnceInit(void)
  virObjectLookupKeysDispose)))
 return -1;
 
+if (!(virObjectLookupHashClass = virClassNew(virObjectLockableClass,
+ "virObjectLookupHash",
+ sizeof(virObjectLookupHash),
+ virObjectLookupHashDispose)))
+return -1;
+
 return 0;
 }
 
@@ -144,6 +152,21 @@ virClassForObjectLookupKeys(void)
 
 
 /**
+ * virClassForObjectLookupHash:
+ *
+ * Returns the class instance for the virObjectLookupHash type
+ */
+virClassPtr
+virClassForObjectLookupHash(void)
+{
+if (virObjectInitialize() < 0)
+return NULL;
+
+return virObjectLookupHashClass;
+}
+
+
+/**
  * virClassNew:
  * @parent: the parent class
  * @name: the class name
@@ -344,6 +367,65 @@ virObjectLookupKeysDispose(void *anyobj)
 
 
 /**
+ * virObjectLookupHashNew:
+ * @klass: the klass to check
+ * @tableElemsStart: number of elements initially in the table
+ *
+ * Create a new poolable hash table object for storing hash tables capable
+ * of storing virObjectLookupKeys objects.
+ *
+ * Returns: New object on success, NULL on failure w/ error message set
+ */
+void *
+virObjectLookupHashNew(virClassPtr klass,
+   int tableElemsStart)
+{
+virObjectLookupHashPtr obj;
+
+if (!virClassIsDerivedFrom(klass, virClassForObjectLookupHash())) {
+virReportInvalidArg(klass,
+_("Class %s must derive from virObjectLookupHash"),
+virClassName(klass));
+return NULL;
+}
+
+if (!(obj = virObjectLockableNew(klass)))
+return NULL;
+
+obj->tableElemsStart = tableElemsStart;
+
+if (!(obj->objsUUID = virHashCreate(tableElemsStart,
+virObjectFreeHashData)))
+goto error;
+
+if (!(obj->objsName = virHashCreate(tableElemsStart,
+virObjectFreeHashData)))
+goto error;
+
+VIR_DEBUG("obj=%p, elems=%d objsUUID=%p objsName=%p",
+  obj, tableElemsStart, obj->objsUUID, obj->objsName);
+
+return obj;
+
+ error:
+virObjectUnref(obj);
+return NULL;
+}
+
+
+static void
+virObjectLookupHashDispose(void *anyobj)
+{
+virObjectLookupHashPtr obj = anyobj;
+
+VIR_DEBUG("dispose obj=%p", obj);
+
+virHashFree(obj->objsUUID);
+virHashFree(obj->objsName);
+}
+
+
+/**
  * virObjectUnref:
  * @anyobj: any instance of virObjectPtr
  *
@@ -410,7 +492,8 @@ static virObjectLockablePtr
 virObjectGetLockableObj(void *anyobj)
 {
 if (virObjectIsClass(anyobj, virObjectLockableClass) ||
-virObjectIsClass(anyobj, virObjectLookupKeysClass))
+virObjectIsClass(anyobj, virObjectLookupKeysClass) ||
+virObjectIsClass(anyobj, 

[libvirt] [PATCH v3 03/16] util: Introduce virObjectLookupKeys

2017-06-22 Thread John Ferlan
Add a new virObjectLockable child virObjectLookupKeys which can be used
by various driver/vir*object consumers as the means to describe the lookup
keys @uuid and/or @name.  Either or both keys may be defined/used and it's
left up to the object consumer to utilize the lookup keys as it sees fit.
Eventually, these will be the keys used to insert the object into the
hash table(s) for the driver/vir*object consumer.

Signed-off-by: John Ferlan 
---
 src/libvirt_private.syms |  2 ++
 src/util/virobject.c | 78 +++-
 src/util/virobject.h | 17 +++
 3 files changed, 96 insertions(+), 1 deletion(-)

diff --git a/src/libvirt_private.syms b/src/libvirt_private.syms
index c1e9471..44d712d 100644
--- a/src/libvirt_private.syms
+++ b/src/libvirt_private.syms
@@ -2274,6 +2274,7 @@ virNumaSetupMemoryPolicy;
 # util/virobject.h
 virClassForObject;
 virClassForObjectLockable;
+virClassForObjectLookupKeys;
 virClassIsDerivedFrom;
 virClassName;
 virClassNew;
@@ -2284,6 +2285,7 @@ virObjectListFree;
 virObjectListFreeCount;
 virObjectLock;
 virObjectLockableNew;
+virObjectLookupKeysNew;
 virObjectNew;
 virObjectRef;
 virObjectUnlock;
diff --git a/src/util/virobject.c b/src/util/virobject.c
index 443718b..6908e8d 100644
--- a/src/util/virobject.c
+++ b/src/util/virobject.c
@@ -66,8 +66,10 @@ struct _virClass {
 
 static virClassPtr virObjectClass;
 static virClassPtr virObjectLockableClass;
+static virClassPtr virObjectLookupKeysClass;
 
 static void virObjectLockableDispose(void *anyobj);
+static void virObjectLookupKeysDispose(void *anyobj);
 
 static int
 virObjectOnceInit(void)
@@ -84,6 +86,12 @@ virObjectOnceInit(void)
virObjectLockableDispose)))
 return -1;
 
+if (!(virObjectLookupKeysClass = virClassNew(virObjectLockableClass,
+ "virObjectLookupKeys",
+ sizeof(virObjectLookupKeys),
+ virObjectLookupKeysDispose)))
+return -1;
+
 return 0;
 }
 
@@ -121,6 +129,21 @@ virClassForObjectLockable(void)
 
 
 /**
+ * virClassForObjectLookupKeys:
+ *
+ * Returns the class instance for the virObjectLookupKeys type
+ */
+virClassPtr
+virClassForObjectLookupKeys(void)
+{
+if (virObjectInitialize() < 0)
+return NULL;
+
+return virObjectLookupKeysClass;
+}
+
+
+/**
  * virClassNew:
  * @parent: the parent class
  * @name: the class name
@@ -268,6 +291,58 @@ virObjectLockableDispose(void *anyobj)
 }
 
 
+void *
+virObjectLookupKeysNew(virClassPtr klass,
+   const char *uuid,
+   const char *name)
+{
+virObjectLookupKeysPtr obj;
+
+if (!virClassIsDerivedFrom(klass, virClassForObjectLookupKeys())) {
+virReportInvalidArg(klass,
+_("Class %s must derive from virObjectLookupKeys"),
+virClassName(klass));
+return NULL;
+}
+
+if (!uuid && !name) {
+virReportError(VIR_ERR_INVALID_ARG, "%s",
+   _("no key, either 'uuid' or 'name' must be defined"));
+return NULL;
+}
+
+if (!(obj = virObjectLockableNew(klass)))
+return NULL;
+
+if (VIR_STRDUP(obj->uuid, uuid) < 0)
+goto error;
+
+if (VIR_STRDUP(obj->name, name) < 0)
+goto error;
+
+VIR_DEBUG("obj=%p, uuid=%s name=%s",
+  obj, NULLSTR(obj->uuid), NULLSTR(obj->name));
+
+return obj;
+
+ error:
+virObjectUnref(obj);
+return NULL;
+}
+
+
+static void
+virObjectLookupKeysDispose(void *anyobj)
+{
+virObjectLookupKeysPtr obj = anyobj;
+
+VIR_DEBUG("dispose obj=%p", obj);
+
+VIR_FREE(obj->uuid);
+VIR_FREE(obj->name);
+}
+
+
 /**
  * virObjectUnref:
  * @anyobj: any instance of virObjectPtr
@@ -334,7 +409,8 @@ virObjectRef(void *anyobj)
 static virObjectLockablePtr
 virObjectGetLockableObj(void *anyobj)
 {
-if (virObjectIsClass(anyobj, virObjectLockableClass))
+if (virObjectIsClass(anyobj, virObjectLockableClass) ||
+virObjectIsClass(anyobj, virObjectLookupKeysClass))
 return anyobj;
 
 VIR_OBJECT_USAGE_PRINT_WARNING(anyobj, virObjectLockableClass);
diff --git a/src/util/virobject.h b/src/util/virobject.h
index f4c292b..1cade9d 100644
--- a/src/util/virobject.h
+++ b/src/util/virobject.h
@@ -34,6 +34,9 @@ typedef virObject *virObjectPtr;
 typedef struct _virObjectLockable virObjectLockable;
 typedef virObjectLockable *virObjectLockablePtr;
 
+typedef struct _virObjectLookupKeys virObjectLookupKeys;
+typedef virObjectLookupKeys *virObjectLookupKeysPtr;
+
 typedef void (*virObjectDisposeCallback)(void *obj);
 
 /* Most code should not play with the contents of this struct; however,
@@ -59,9 +62,17 @@ struct _virObjectLockable {
 virMutex lock;
 };
 
+struct _virObjectLookupKeys {
+virObjectLockable parent;
+
+char 

[libvirt] [PATCH v3 06/16] util: Introduce virObjectLookupKeys*Active API's

2017-06-22 Thread John Ferlan
Add a 'bool active' field to the virObjectLookupKeys object and then
virObjectLookupKeysIsActive and virObjectLookupKeysSetActive API's
to manage it.

Signed-off-by: John Ferlan 
---
 src/libvirt_private.syms |  2 ++
 src/util/virobject.c | 39 +++
 src/util/virobject.h |  9 +
 3 files changed, 50 insertions(+)

diff --git a/src/libvirt_private.syms b/src/libvirt_private.syms
index bfc68eb..6a87e6b 100644
--- a/src/libvirt_private.syms
+++ b/src/libvirt_private.syms
@@ -2287,7 +2287,9 @@ virObjectLock;
 virObjectLockableNew;
 virObjectLookupKeysGetName;
 virObjectLookupKeysGetUUID;
+virObjectLookupKeysIsActive;
 virObjectLookupKeysNew;
+virObjectLookupKeysSetActive;
 virObjectNew;
 virObjectRef;
 virObjectUnlock;
diff --git a/src/util/virobject.c b/src/util/virobject.c
index 862d46b..6e2b222 100644
--- a/src/util/virobject.c
+++ b/src/util/virobject.c
@@ -585,6 +585,45 @@ virObjectListFreeCount(void *list,
 
 
 /**
+ * virObjectLookupKeysIsActive
+ * @anyobj: Pointer to a locked LookupKeys object
+ *
+ * Returns: True if object is active, false if not
+ */
+bool
+virObjectLookupKeysIsActive(void *anyobj)
+{
+virObjectLookupKeysPtr obj = virObjectGetLookupKeysObj(anyobj);
+
+if (!obj)
+return false;
+
+return obj->active;
+}
+
+
+/**
+ * virObjectLookupKeysSetActive
+ * @anyobj: Pointer to a locked LookupKeys object
+ * @active: New active setting
+ *
+ * Set the lookup keys active bool value; value not changed if object
+ * is not a lookup keys object
+ */
+void
+virObjectLookupKeysSetActive(void *anyobj,
+ bool active)
+{
+virObjectLookupKeysPtr obj = virObjectGetLookupKeysObj(anyobj);
+
+if (!obj)
+return;
+
+obj->active = active;
+}
+
+
+/**
  * virObjectLookupKeysGetUUID
  * @anyobj: Pointer to a LookupKeys object
  *
diff --git a/src/util/virobject.h b/src/util/virobject.h
index e77634b..9e0ecc1 100644
--- a/src/util/virobject.h
+++ b/src/util/virobject.h
@@ -67,6 +67,8 @@ struct _virObjectLookupKeys {
 
 char *uuid;
 char *name;
+
+bool active;   /* true if object is active */
 };
 
 
@@ -140,6 +142,13 @@ void
 virObjectListFreeCount(void *list,
size_t count);
 
+bool
+virObjectLookupKeysIsActive(void *anyobj);
+
+void
+virObjectLookupKeysSetActive(void *anyobj,
+ bool active);
+
 const char *
 virObjectLookupKeysGetUUID(void *anyobj);
 
-- 
2.9.4

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


[libvirt] [PATCH v3 00/16] virObject adjustments for common object

2017-06-22 Thread John Ferlan
v2: https://www.redhat.com/archives/libvir-list/2017-June/msg00070.html

Pushed the first two patches from v2 since they were ACK'd

Changes in this series...

Fixed a couple of nits from former patch 3 & 4, but since they weren't ACK'd
they're here again, but now as patch 1 & 2.

Patch 3 & 4 are an adjusted version of the former patches 5 & 6. Instead
of going with generic @primaryKey and @secondaryKey names, this patch will
use @uuid and @name for the field names. Additionally instead of using
PoolableHashElement as a name, go with a much shorter LookupKeys. So
far the LookupKeys{UUID|Name} API's (patch 4) aren't used and could be
dropped if it's felt no future API would need them.

Former patches 7 & 8 dealing with the generic @def and @newDef object
were tossed away and the rest of the logic I'd be changing for virObject is
presented as the remaining (new to reviewers) patches 5 -> 16.

The object is named using LookupHash which is a follow-on of the LookupKeys.

If someone has better suggestion for names, then please provide suggestions
rather than just saying I hate the name! It's not my favorite name, but it
does convey what it is and IMO is better than just Element.

The patches also include the Interface object changes to illustrate that the
changes do work. I've run them through the various "interface" tests from the
Avocado VT test suite. I also did something similar for the Secret object in
my private branch, but did not include that since there are 8 patches on list
waiting to be reviewed first.

John Ferlan (16):
  util: Generate a common internal only error print
  util: Add safety net of checks to ensure valid object
  util: Introduce virObjectLookupKeys
  util: Introduce virObjectLookupKeysGet{UUID|Name}
  interface: Use virObjectLookupKeys
  util: Introduce virObjectLookupKeys*Active API's
  interface: Use virObjectLookupKeys*Active
  util: Introduce virObjectLookupHash
  util: Introduce virObjectLoookupHashGet{UUID|Name}
  util: Introduce virObjectLookupHash{Add|Remove}
  util: Introduce virObjectLookupHashFind
  util: Introduce virObjectLookupHashForEach
  util: Introduce virObjectLookupHashSearch
  util: Introduce virObjectLookupHashClone
  interface: Use virObjectLookupHash
  test: Clean up test driver Interface interactions

 src/conf/virinterfaceobj.c | 332 ++--
 src/libvirt_private.syms   |  16 ++
 src/test/test_driver.c |  55 +---
 src/util/virobject.c   | 613 -
 src/util/virobject.h   | 111 
 5 files changed, 938 insertions(+), 189 deletions(-)

-- 
2.9.4

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


Re: [libvirt] [PATCH] util: Extract locale-related fixes into separate functions

2017-06-22 Thread Michal Privoznik
On 06/22/2017 02:36 PM, Martin Kletzander wrote:
> Signed-off-by: Martin Kletzander 
> ---
>  src/util/virstring.c | 96 
> 
>  1 file changed, 60 insertions(+), 36 deletions(-)

Makes sense to me. ACK.

Michal

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


Re: [libvirt] [PATCH] util: Extract locale-related fixes into separate functions

2017-06-22 Thread Peter Krempa
On Thu, Jun 22, 2017 at 14:36:53 +0200, Martin Kletzander wrote:
> Signed-off-by: Martin Kletzander 
> ---
>  src/util/virstring.c | 96 
> 
>  1 file changed, 60 insertions(+), 36 deletions(-)
> 
> diff --git a/src/util/virstring.c b/src/util/virstring.c
> index feea5be05198..6125725364f3 100644
> --- a/src/util/virstring.c
> +++ b/src/util/virstring.c
> @@ -522,6 +522,7 @@ virStrToLong_ullp(char const *s, char **end_ptr, int base,
>  #if HAVE_NEWLOCALE
> 
>  static locale_t virLocale;
> +static locale_t virLocaleOld;

This is not a thread local variable ...

> 
>  static int
>  virLocaleOnceInit(void)
> @@ -533,7 +534,58 @@ virLocaleOnceInit(void)
>  }
> 
>  VIR_ONCE_GLOBAL_INIT(virLocale);
> -#endif
> +
> +static int
> +virLocaleSet(void)
> +{
> +if (virLocaleInitialize() < 0)
> +return -1;
> +virLocaleOld = uselocale(virLocale);

... and this is called multiple times ...

> +return 0;
> +}
> +
> +static void
> +virLocaleRevert(void)
> +{
> +uselocale(virLocaleOld);

... so while this at this moment will behave correctly, since
virLocaleOld will only be ever set to the same old locale, the general
approach is not correct.


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

[libvirt] [PATCH] virNetDevOpenvswitchInterfaceStats: Be more forgiving when fetching stats

2017-06-22 Thread Michal Privoznik
https://bugzilla.redhat.com/show_bug.cgi?id=1461270

When fetching stats for a vhost-user type of interface, we run
couple of ovs-vsctl commands and parse their output. However, not
all stats exist at all times, for instance "rx_dropped" or
"tx_errors" can be missing. Thing is, we ask for a bulk of
statistics and if one of them is missing an error is reported
instead of returning the rest. Since we ignore errors, we fail to
set statistics. Fix this by asking for each piece alone.

Signed-off-by: Michal Privoznik 
---
 src/util/virnetdevopenvswitch.c | 96 +++--
 1 file changed, 34 insertions(+), 62 deletions(-)

diff --git a/src/util/virnetdevopenvswitch.c b/src/util/virnetdevopenvswitch.c
index 8f7215e06..6848f65b7 100644
--- a/src/util/virnetdevopenvswitch.c
+++ b/src/util/virnetdevopenvswitch.c
@@ -317,14 +317,8 @@ virNetDevOpenvswitchInterfaceStats(const char *ifname,
 {
 virCommandPtr cmd = NULL;
 char *output;
-long long rx_bytes;
-long long rx_packets;
-long long tx_bytes;
-long long tx_packets;
-long long rx_errs;
-long long rx_drop;
-long long tx_errs;
-long long tx_drop;
+char *tmp;
+bool gotStats = false;
 int ret = -1;
 
 /* Just ensure the interface exists in ovs */
@@ -340,67 +334,45 @@ virNetDevOpenvswitchInterfaceStats(const char *ifname,
 goto cleanup;
 }
 
-VIR_FREE(output);
-virCommandFree(cmd);
-
-cmd = virCommandNew(OVSVSCTL);
-virNetDevOpenvswitchAddTimeout(cmd);
-virCommandAddArgList(cmd, "get", "Interface", ifname,
- "statistics:rx_bytes",
- "statistics:rx_packets",
- "statistics:tx_bytes",
- "statistics:tx_packets", NULL);
-virCommandSetOutputBuffer(cmd, );
-
-if (virCommandRun(cmd, NULL) < 0) {
-virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
-   _("Interface doesn't have statistics"));
-goto cleanup;
-}
+#define GET_STAT(name, member)  \
+do {\
+VIR_FREE(output);   \
+virCommandFree(cmd);\
+cmd = virCommandNew(OVSVSCTL);  \
+virNetDevOpenvswitchAddTimeout(cmd);\
+virCommandAddArgList(cmd, "get", "Interface", ifname,   \
+ "statistics:" name, NULL); \
+virCommandSetOutputBuffer(cmd, );\
+if (virCommandRun(cmd, NULL) < 0) { \
+stats->member = -1; \
+} else {\
+if (virStrToLong_ll(output, , 10, >member) < 0 ||\
+*tmp != '\n') { \
+virReportError(VIR_ERR_INTERNAL_ERROR, "%s",\
+   _("Fail to parse ovs-vsctl output"));\
+goto cleanup;   \
+}   \
+gotStats = true;\
+}   \
+} while (0)
 
 /* The TX/RX fields appear to be swapped here
  * because this is the host view. */
-if (sscanf(output, "%lld\n%lld\n%lld\n%lld\n",
-   _bytes, _packets, _bytes, _packets) != 4) {
-virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
-   _("Fail to parse ovs-vsctl output"));
-goto cleanup;
-}
+GET_STAT("rx_bytes", tx_bytes);
+GET_STAT("rx_packets", tx_packets);
+GET_STAT("rx_errors", tx_errs);
+GET_STAT("rx_dropped", tx_drop);
+GET_STAT("tx_bytes", rx_bytes);
+GET_STAT("tx_packets", rx_packets);
+GET_STAT("tx_errors", rx_errs);
+GET_STAT("tx_dropped", rx_drop);
 
-stats->rx_bytes = rx_bytes;
-stats->rx_packets = rx_packets;
-stats->tx_bytes = tx_bytes;
-stats->tx_packets = tx_packets;
-
-VIR_FREE(output);
-virCommandFree(cmd);
-
-cmd = virCommandNew(OVSVSCTL);
-virNetDevOpenvswitchAddTimeout(cmd);
-virCommandAddArgList(cmd, "get", "Interface", ifname,
- "statistics:rx_errors",
- "statistics:rx_dropped",
- "statistics:tx_errors",
- "statistics:tx_dropped", NULL);
-virCommandSetOutputBuffer(cmd, );
-if (virCommandRun(cmd, NULL) < 0) {
-/* This interface don't have errors or dropped, so set them to 0 */
-

Re: [libvirt] RFC: Creating mediated devices with libvirt

2017-06-22 Thread Martin Polednik

On 22/06/17 14:05 +0200, Erik Skultety wrote:

On Thu, Jun 22, 2017 at 10:41:13AM +0200, Martin Polednik wrote:

On 16/06/17 18:14 +0100, Daniel P. Berrange wrote:
> On Fri, Jun 16, 2017 at 06:11:17PM +0100, Daniel P. Berrange wrote:
> > On Fri, Jun 16, 2017 at 11:02:55AM -0600, Alex Williamson wrote:
> > > On Fri, 16 Jun 2017 11:32:04 -0400
> > > Laine Stump  wrote:
> > >
> > > > On 06/15/2017 02:42 PM, Alex Williamson wrote:
> > > > > On Thu, 15 Jun 2017 09:33:01 +0100
> > > > > "Daniel P. Berrange"  wrote:
> > > > >
> > > > >> On Thu, Jun 15, 2017 at 12:06:43AM +0200, Erik Skultety wrote:
> > > > >>> Hi all,
> > > > >>>
> > > > >>> so there's been an off-list discussion about finally implementing 
creation of
> > > > >>> mediated devices with libvirt and it's more than desired to get as 
many opinions
> > > > >>> on that as possible, so please do share your ideas. This did come 
up already as
> > > > >>> part of some older threads ([1] for example), so this will be a 
respin of the
> > > > >>> discussions. Long story short, we decided to put device creation 
off and focus
> > > > >>> on the introduction of the framework as such first and build upon 
that later,
> > > > >>> i.e. now.
> > > > >>>
> > > > >>> [1] 
https://www.redhat.com/archives/libvir-list/2017-February/msg00177.html
> > > > >>>
> > > > >>> 
> > > > >>> PART 1: NODEDEV-DRIVER
> > > > >>> 
> > > > >>>
> > > > >>> API-wise, device creation through the nodedev driver should be 
pretty
> > > > >>> straightforward and without any issues, since virNodeDevCreateXML 
takes an XML
> > > > >>> and does support flags. Looking at the current device XML:
> > > > >>>
> > > > >>> 
> > > > >>>   mdev_0cce8709_0640_46ef_bd14_962c7f73cc6f
> > > > >>>   
/sys/devices/pci:00/.../0cce8709-0640-46ef-bd14-962c7f73cc6f
> > > > >>>   pci__03_00_0
> > > > >>>   
> > > > >>> vfio_mdev
> > > > >>>   
> > > > >>>   
> > > > >>> 
> > > > >>> 
> > > > >>> UUID 
> > > > >>>   
> > > > >>> 
> > > > >>>
> > > > >>> We can ignore ,, elements, since these 
are useless
> > > > >>> during creation. We also cannot use  since we don't support 
arbitrary
> > > > >>> names and we also can't rely on users providing a name in correct 
form which we
> > > > >>> would need to further parse in order to get the UUID.
> > > > >>> So since the only thing missing to successfully use create an mdev 
using XML is
> > > > >>> the UUID (if user doesn't want it to be generated automatically), 
how about
> > > > >>> having a  subelement under  just like PCIs have 
 and
> > > > >>> friends, USBs have  & , interfaces have  to 
uniquely
> > > > >>> identify the device even if the name itself is unique.
> > > > >>> Removal of a device should work as well, although we might want to
> > > > >>> consider creating a *Flags version of the API.
> > > > >>>
> > > > >>> =
> > > > >>> PART 2: DOMAIN XML & DEVICE AUTO-CREATION, NO POLICY INVOLVED!
> > > > >>> =
> > > > >>>
> > > > >>> There were some doubts about auto-creation mentioned in [1], 
although they
> > > > >>> weren't specified further. So hopefully, we'll get further in the 
discussion
> > > > >>> this time.
> > > > >>>
> > > > >>> From my perspective there are two main reasons/benefits to that:
> > > > >>>
> > > > >>> 1) Convenience
> > > > >>> For apps like virt-manager, user will want to add a host device 
transparently,
> > > > >>> "hey libvirt, I want an mdev assigned to my VM, can you do that". 
Even for
> > > > >>> higher management apps, like oVirt, even they might not care about 
the parent
> > > > >>> device at all times and considering that they would need to 
enumerate the
> > > > >>> parents, pick one, create the device XML and pass it to the nodedev 
driver, IMHO
> > > > >>> it would actually   be easier and faster to just do it directly 
through sysfs,
> > > > >>> bypassing libvirt once again
> > > > >>
> > > > >> The convenience only works if the policy we've provided in libvirt 
actually
> > > > >> matches the policy the application wants. I think it is quite likely 
that with
> > > > >> cloud the mdevs will be created out of band from the domain startup 
process.
> > > > >> It is possible the app will just have a fixed set of mdevs 
pre-created when
> > > > >> the host starts up. Or that the mgmt app wants the domain startup 
process to
> > > > >> be a two phase setup, where it first allocates the resources needed, 
and later
> > > > >> then tries to start the guest. This is why I keep saying that 
putting this kind
> > > > >> of "convenient" policy in libvirt is a bad idea - it is essentially 
just putting
> > > > >> a bit of virt-manager code into libvirt - more advanced apps will 
need more
> > > > >> flexibility in this area.
> > > > >>
> > > > >>> 2) 

Re: [libvirt] [PATCH RFC 1/2] Resctrl: Add new xml element to support cache tune

2017-06-22 Thread Martin Kletzander

On Thu, Jun 22, 2017 at 01:24:29PM +0800, Eli Qiao wrote:

hi Martin

It’s really nice of you to help reviewing the mass code. Thanks.

I don’t find a better way to split patch.


On Wednesday, 21 June 2017 at 9:53 PM, Martin Kletzander wrote:


On Mon, Jun 12, 2017 at 05:48:40PM +0800, Eli Qiao wrote:
> This patch adds new xml element to support cache tune as:
>
> 
> ...
>  vcpus='1,2'/>
>


The cache_id automatically implies level and type. Either have one or
the other. I know we talked about this already (maybe multiple times),
but without any clear outcome. For me the sensible thing is to have
level and type as that doesn't need to be changed when moving between
hosts, and if it cannot be migrated, then it's properly checked.


Think about this case, if the VM has numa setting, the VM has multiple vcpu
running across sockets, if we don’t specify cache_id (cache id stand for
on which Socket/Cache), how can we know on which Socket we allocation for the 
VM?



I missed this.  Ye, you're right, thanks for showing that with a use
case.  We could then require only the cache_id and automatically fill
in level and type.  Migration (or rather any start) should then fail if
that cache_id doesn't correspond to the level and type requested.  I
still can't find a reason for 'id', though.


I can image there’s 2 cases:

1. if we don’t specify vcpus, and our host have 2 or more Socket, we have this 
xml define



We allocate 2816 KiB cache on all of the Socket/Cache.

2. if we specify vcpus




We need to make sure we vcpu 1, 2 are mapped to Socket/Cache 0 and 3,4 on 
Socket/Cache 1.
So that vcpus running on Socket/Cache 0 has 2816 KiB cache allocated and vcpus 
running on
Socket/Cache 1 has 5632 KiB cache allocated.

Does it make sense?

…



>
> virDomainCputune cputune;
>
> + virDomainCachetune cachetune;
> +
>


It is part of cputune in the XML, why not here?


Oh yes, I will rethink how to simple the domain cache tune.


> virDomainNumaPtr numa;
> virDomainResourceDefPtr resource;
> virDomainIdMapDef idmap;
> --
> 1.9.1
>
> --
> libvir-list mailing list
> libvir-list@redhat.com (mailto:libvir-list@redhat.com)
> https://www.redhat.com/mailman/listinfo/libvir-list
>


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







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

[libvirt] [PATCH v4 3/6] virStream*All: Call virStreamAbort() more frequently

2017-06-22 Thread Michal Privoznik
Our documentation to all four virStreamRecvAll, virStreamSendAll,
virStreamSparseRecvAll, virStreamSparseSendAll says that if these
functions fail, virStreamAbort() is called. But that is not
necessarily true. For instance all of these functions allocate a
buffer to work with. If the allocation fails, no virStreamAbort()
is called despite -1 being returned. It's the same story with
argument sanity checks and a lot of other checks.

Signed-off-by: Michal Privoznik 
---
 src/libvirt-stream.c | 49 -
 1 file changed, 20 insertions(+), 29 deletions(-)

diff --git a/src/libvirt-stream.c b/src/libvirt-stream.c
index d7a8f5816..bff0a0571 100644
--- a/src/libvirt-stream.c
+++ b/src/libvirt-stream.c
@@ -596,10 +596,8 @@ virStreamSendAll(virStreamPtr stream,
 for (;;) {
 int got, offset = 0;
 got = (handler)(stream, bytes, want, opaque);
-if (got < 0) {
-virStreamAbort(stream);
+if (got < 0)
 goto cleanup;
-}
 if (got == 0)
 break;
 while (offset < got) {
@@ -615,8 +613,10 @@ virStreamSendAll(virStreamPtr stream,
  cleanup:
 VIR_FREE(bytes);
 
-if (ret != 0)
+if (ret != 0) {
+virStreamAbort(stream);
 virDispatchError(stream->conn);
+}
 
 return ret;
 }
@@ -728,21 +728,16 @@ int virStreamSparseSendAll(virStreamPtr stream,
 const unsigned int skipFlags = 0;
 
 if (!dataLen) {
-if (holeHandler(stream, , , opaque) < 0) {
-virStreamAbort(stream);
+if (holeHandler(stream, , , opaque) < 0)
 goto cleanup;
-}
 
 if (!inData && sectionLen) {
-if (virStreamSendHole(stream, sectionLen, skipFlags) < 0) {
-virStreamAbort(stream);
+if (virStreamSendHole(stream, sectionLen, skipFlags) < 0)
 goto cleanup;
-}
 
 if (skipHandler(stream, sectionLen, opaque) < 0) {
 virReportSystemError(errno, "%s",
  _("unable to skip hole"));
-virStreamAbort(stream);
 goto cleanup;
 }
 continue;
@@ -755,10 +750,8 @@ int virStreamSparseSendAll(virStreamPtr stream,
 want = dataLen;
 
 got = (handler)(stream, bytes, want, opaque);
-if (got < 0) {
-virStreamAbort(stream);
+if (got < 0)
 goto cleanup;
-}
 if (got == 0)
 break;
 while (offset < got) {
@@ -775,8 +768,10 @@ int virStreamSparseSendAll(virStreamPtr stream,
  cleanup:
 VIR_FREE(bytes);
 
-if (ret != 0)
+if (ret != 0) {
+virStreamAbort(stream);
 virDispatchError(stream->conn);
+}
 
 return ret;
 }
@@ -857,10 +852,8 @@ virStreamRecvAll(virStreamPtr stream,
 while (offset < got) {
 int done;
 done = (handler)(stream, bytes + offset, got - offset, opaque);
-if (done < 0) {
-virStreamAbort(stream);
+if (done < 0)
 goto cleanup;
-}
 offset += done;
 }
 }
@@ -869,8 +862,10 @@ virStreamRecvAll(virStreamPtr stream,
  cleanup:
 VIR_FREE(bytes);
 
-if (ret != 0)
+if (ret != 0) {
+virStreamAbort(stream);
 virDispatchError(stream->conn);
+}
 
 return ret;
 }
@@ -963,15 +958,11 @@ virStreamSparseRecvAll(virStreamPtr stream,
 
 got = virStreamRecvFlags(stream, bytes, want, flags);
 if (got == -3) {
-if (virStreamRecvHole(stream, , holeFlags) < 0) {
-virStreamAbort(stream);
+if (virStreamRecvHole(stream, , holeFlags) < 0)
 goto cleanup;
-}
 
-if (holeHandler(stream, holeLen, opaque) < 0) {
-virStreamAbort(stream);
+if (holeHandler(stream, holeLen, opaque) < 0)
 goto cleanup;
-}
 continue;
 } else if (got < 0) {
 goto cleanup;
@@ -981,10 +972,8 @@ virStreamSparseRecvAll(virStreamPtr stream,
 while (offset < got) {
 int done;
 done = (handler)(stream, bytes + offset, got - offset, opaque);
-if (done < 0) {
-virStreamAbort(stream);
+if (done < 0)
 goto cleanup;
-}
 offset += done;
 }
 }
@@ -993,8 +982,10 @@ virStreamSparseRecvAll(virStreamPtr stream,
  cleanup:
 VIR_FREE(bytes);
 
-if (ret != 0)
+if (ret != 0) {
+virStreamAbort(stream);
 virDispatchError(stream->conn);
+}
 
 return ret;
 }
-- 
2.13.0

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


[libvirt] [PATCH v4 4/6] virStream*All: Preserve reported error

2017-06-22 Thread Michal Privoznik
If one these four functions fail (virStreamRecvAll,
virStreamSendAll, virStreamSparseRecvAll, virStreamSparseSendAll)
the stream is aborted by calling virStreamAbort(). This is,
however, an public API - therefore the first thing it does is
error reset. At that point any error that caused us to abort
stream in the first place is gone.

Signed-off-by: Michal Privoznik 
---
 src/libvirt-stream.c | 20 
 1 file changed, 20 insertions(+)

diff --git a/src/libvirt-stream.c b/src/libvirt-stream.c
index bff0a0571..1594ed212 100644
--- a/src/libvirt-stream.c
+++ b/src/libvirt-stream.c
@@ -614,7 +614,12 @@ virStreamSendAll(virStreamPtr stream,
 VIR_FREE(bytes);
 
 if (ret != 0) {
+virErrorPtr orig_err = virSaveLastError();
 virStreamAbort(stream);
+if (orig_err) {
+virSetError(orig_err);
+virFreeError(orig_err);
+}
 virDispatchError(stream->conn);
 }
 
@@ -769,7 +774,12 @@ int virStreamSparseSendAll(virStreamPtr stream,
 VIR_FREE(bytes);
 
 if (ret != 0) {
+virErrorPtr orig_err = virSaveLastError();
 virStreamAbort(stream);
+if (orig_err) {
+virSetError(orig_err);
+virFreeError(orig_err);
+}
 virDispatchError(stream->conn);
 }
 
@@ -863,7 +873,12 @@ virStreamRecvAll(virStreamPtr stream,
 VIR_FREE(bytes);
 
 if (ret != 0) {
+virErrorPtr orig_err = virSaveLastError();
 virStreamAbort(stream);
+if (orig_err) {
+virSetError(orig_err);
+virFreeError(orig_err);
+}
 virDispatchError(stream->conn);
 }
 
@@ -983,7 +998,12 @@ virStreamSparseRecvAll(virStreamPtr stream,
 VIR_FREE(bytes);
 
 if (ret != 0) {
+virErrorPtr orig_err = virSaveLastError();
 virStreamAbort(stream);
+if (orig_err) {
+virSetError(orig_err);
+virFreeError(orig_err);
+}
 virDispatchError(stream->conn);
 }
 
-- 
2.13.0

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


[libvirt] [PATCH] util: Extract locale-related fixes into separate functions

2017-06-22 Thread Martin Kletzander
Signed-off-by: Martin Kletzander 
---
 src/util/virstring.c | 96 
 1 file changed, 60 insertions(+), 36 deletions(-)

diff --git a/src/util/virstring.c b/src/util/virstring.c
index feea5be05198..6125725364f3 100644
--- a/src/util/virstring.c
+++ b/src/util/virstring.c
@@ -522,6 +522,7 @@ virStrToLong_ullp(char const *s, char **end_ptr, int base,
 #if HAVE_NEWLOCALE

 static locale_t virLocale;
+static locale_t virLocaleOld;

 static int
 virLocaleOnceInit(void)
@@ -533,7 +534,58 @@ virLocaleOnceInit(void)
 }

 VIR_ONCE_GLOBAL_INIT(virLocale);
-#endif
+
+static int
+virLocaleSet(void)
+{
+if (virLocaleInitialize() < 0)
+return -1;
+virLocaleOld = uselocale(virLocale);
+return 0;
+}
+
+static void
+virLocaleRevert(void)
+{
+uselocale(virLocaleOld);
+}
+
+static void
+virLocaleFixupRadix(char **strp ATTRIBUTE_UNUSED)
+{
+}
+
+#else /* !HAVE_NEWLOCALE */
+
+static int
+virLocaleSet(void)
+{
+return 0;
+}
+
+static void
+virLocaleRevert(void)
+{
+}
+
+static void
+virLocaleFixupRadix(char **strp)
+{
+char *radix, *tmp;
+struct lconv *lc;
+
+lc = localeconv();
+radix = lc->decimal_point;
+tmp = strstr(*strp, radix);
+if (tmp) {
+*tmp = '.';
+if (strlen(radix) > 1)
+memmove(tmp + 1, tmp + strlen(radix), strlen(*strp) - (tmp - 
*strp));
+}
+}
+
+#endif /* !HAVE_NEWLOCALE */
+

 /**
  * virStrToDouble
@@ -552,17 +604,11 @@ virStrToDouble(char const *s,
 int err;

 errno = 0;
-#if HAVE_NEWLOCALE
-locale_t old_loc;
-if (virLocaleInitialize() < 0)
+if (virLocaleSet() < 0)
 return -1;
-
-old_loc = uselocale(virLocale);
-#endif
 val = strtod(s, ); /* exempt from syntax-check */
-#if HAVE_NEWLOCALE
-uselocale(old_loc);
-#endif
+virLocaleRevert();
+
 err = (errno || (!end_ptr && *p) || p == s);
 if (end_ptr)
 *end_ptr = p;
@@ -584,36 +630,14 @@ virDoubleToStr(char **strp, double number)
 {
 int ret = -1;

-#if HAVE_NEWLOCALE
-
-locale_t old_loc;
-
-if (virLocaleInitialize() < 0)
-goto error;
+if (virLocaleSet() < 0)
+return -1;

-old_loc = uselocale(virLocale);
 ret = virAsprintf(strp, "%lf", number);
-uselocale(old_loc);
-
-#else
-
-char *radix, *tmp;
-struct lconv *lc;
-
-if ((ret = virAsprintf(strp, "%lf", number) < 0))
-goto error;

-lc = localeconv();
-radix = lc->decimal_point;
-tmp = strstr(*strp, radix);
-if (tmp) {
-*tmp = '.';
-if (strlen(radix) > 1)
-memmove(tmp + 1, tmp + strlen(radix), strlen(*strp) - (tmp - 
*strp));
-}
+virLocaleRevert();
+virLocaleFixupRadix(strp);

-#endif /* HAVE_NEWLOCALE */
- error:
 return ret;
 }

-- 
2.13.1

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


[libvirt] [PATCH] util: Move locale.h include from virutil to virstring

2017-06-22 Thread Martin Kletzander
Commit 5c54d29aaeb7 forgot to do that when moving the only function
using it and it broke the build on some platforms.

Signed-off-by: Martin Kletzander 
---

Notes:
Pushed under the build-breaker rule

 src/util/virstring.c | 1 +
 src/util/virutil.c   | 1 -
 2 files changed, 1 insertion(+), 1 deletion(-)

diff --git a/src/util/virstring.c b/src/util/virstring.c
index 1bd677723265..feea5be05198 100644
--- a/src/util/virstring.c
+++ b/src/util/virstring.c
@@ -24,6 +24,7 @@
 #include 
 #include 
 #include 
+#include 

 #include "base64.h"
 #include "c-ctype.h"
diff --git a/src/util/virutil.c b/src/util/virutil.c
index d7e01d464268..e4de4caec91d 100644
--- a/src/util/virutil.c
+++ b/src/util/virutil.c
@@ -45,7 +45,6 @@
 #include 
 #include 
 #include 
-#include 

 #if WITH_DEVMAPPER
 # include 
-- 
2.13.1

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


[libvirt] [PATCH v4 6/6] virStream*All: Report error if a callback fails

2017-06-22 Thread Michal Privoznik
All of these four functions (virStreamRecvAll, virStreamSendAll,
virStreamSparseRecvAll, virStreamSparseSendAll) take one or more
callback that handle various aspects of streams. However, if any
of them fails no error is reported therefore caller does not know
what went wrong.

At the same time, we silently presumed callbacks to set errno on
failure. With this change we should document it explicitly as the
error is not properly reported.

Signed-off-by: Michal Privoznik 
---
 include/libvirt/libvirt-stream.h | 17 +-
 src/libvirt-stream.c | 50 +---
 2 files changed, 58 insertions(+), 9 deletions(-)

diff --git a/include/libvirt/libvirt-stream.h b/include/libvirt/libvirt-stream.h
index d18d43140..86f96b158 100644
--- a/include/libvirt/libvirt-stream.h
+++ b/include/libvirt/libvirt-stream.h
@@ -82,7 +82,10 @@ int virStreamRecvHole(virStreamPtr,
  * of bytes. The callback will continue to be
  * invoked until it indicates the end of the source
  * has been reached by returning 0. A return value
- * of -1 at any time will abort the send operation
+ * of -1 at any time will abort the send operation.
+ *
+ * Please note that for more accurate error reporting the
+ * callback should set appropriate errno on failure.
  *
  * Returns the number of bytes filled, 0 upon end
  * of file, or -1 upon error
@@ -119,6 +122,9 @@ int virStreamSendAll(virStreamPtr st,
  * This function should not adjust the current position within
  * the file.
  *
+ * Please note that for more accurate error reporting the
+ * callback should set appropriate errno on failure.
+ *
  * Returns 0 on success,
  *-1 upon error
  */
@@ -142,6 +148,9 @@ typedef int (*virStreamSourceHoleFunc)(virStreamPtr st,
  * processing the hole in the stream source and then return.
  * A return value of -1 at any time will abort the send operation.
  *
+ * Please note that for more accurate error reporting the
+ * callback should set appropriate errno on failure.
+ *
  * Returns 0 on success,
  *-1 upon error.
  */
@@ -176,6 +185,9 @@ int virStreamSparseSendAll(virStreamPtr st,
  * has been reached. A return value of -1 at any time
  * will abort the receive operation
  *
+ * Please note that for more accurate error reporting the
+ * callback should set appropriate errno on failure.
+ *
  * Returns the number of bytes consumed or -1 upon
  * error
  */
@@ -203,6 +215,9 @@ int virStreamRecvAll(virStreamPtr st,
  * hole in the stream target and then return. A return value of
  * -1 at any time will abort the receive operation.
  *
+ * Please note that for more accurate error reporting the
+ * callback should set appropriate errno on failure.
+ *
  * Returns 0 on success,
  *-1 upon error
  */
diff --git a/src/libvirt-stream.c b/src/libvirt-stream.c
index 1594ed212..cf1b2293a 100644
--- a/src/libvirt-stream.c
+++ b/src/libvirt-stream.c
@@ -567,7 +567,7 @@ virStreamInData(virStreamPtr stream,
  *
  * Returns -1 upon any error, with virStreamAbort() already
  * having been called,  so the caller need only call
- * virStreamFree()
+ * virStreamFree().
  */
 int
 virStreamSendAll(virStreamPtr stream,
@@ -595,9 +595,15 @@ virStreamSendAll(virStreamPtr stream,
 
 for (;;) {
 int got, offset = 0;
+
+errno = 0;
 got = (handler)(stream, bytes, want, opaque);
-if (got < 0)
+if (got < 0) {
+if (errno == 0)
+errno = EIO;
+virReportSystemError(errno, "%s", _("send handler failed"));
 goto cleanup;
+}
 if (got == 0)
 break;
 while (offset < got) {
@@ -732,17 +738,24 @@ int virStreamSparseSendAll(virStreamPtr stream,
 size_t want = bufLen;
 const unsigned int skipFlags = 0;
 
+errno = 0;
 if (!dataLen) {
-if (holeHandler(stream, , , opaque) < 0)
+if (holeHandler(stream, , , opaque) < 0) {
+if (errno == 0)
+errno = EIO;
+virReportSystemError(errno, "%s", _("send holeHandler 
failed"));
 goto cleanup;
+}
 
 if (!inData && sectionLen) {
 if (virStreamSendHole(stream, sectionLen, skipFlags) < 0)
 goto cleanup;
 
 if (skipHandler(stream, sectionLen, opaque) < 0) {
+if (errno == 0)
+errno = EIO;
 virReportSystemError(errno, "%s",
- _("unable to skip hole"));
+ _("send skipHandler failed"));
 goto cleanup;
 }
 continue;
@@ -755,8 +768,13 @@ int virStreamSparseSendAll(virStreamPtr stream,
 want = dataLen;
 
 got = (handler)(stream, bytes, want, opaque);
-if (got < 0)
+if (got < 0) {
+if (errno == 0)
+

[libvirt] [PATCH v4 5/6] virFileInData: preserve errno in cleanup path

2017-06-22 Thread Michal Privoznik
Callers might be interested in the original value of errno. Let's
not overwrite it with lseek() done in cleanup path.

Signed-off-by: Michal Privoznik 
---
 src/util/virfile.c | 5 -
 1 file changed, 4 insertions(+), 1 deletion(-)

diff --git a/src/util/virfile.c b/src/util/virfile.c
index d444b32f8..2be64f1db 100644
--- a/src/util/virfile.c
+++ b/src/util/virfile.c
@@ -3900,8 +3900,11 @@ virFileInData(int fd,
 ret = 0;
  cleanup:
 /* At any rate, reposition back to where we started. */
-if (cur != (off_t) -1)
+if (cur != (off_t) -1) {
+int save_errno = errno;
 ignore_value(lseek(fd, cur, SEEK_SET));
+errno = save_errno;
+}
 return ret;
 }
 
-- 
2.13.0

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


[libvirt] [PATCH v4 2/6] fdstream: Report error from the I/O thread

2017-06-22 Thread Michal Privoznik
Problem with our error reporting is that the error object is a
thread local variable. That means if there's an error reported
within the I/O thread it gets logged and everything, but later
when the event loop aborts the stream it doesn't see the original
error. So we are left with some generic error. We can do better
if we copy the error message between the threads.

Signed-off-by: Michal Privoznik 
---
 daemon/stream.c| 18 --
 src/util/virfdstream.c |  9 ++---
 2 files changed, 18 insertions(+), 9 deletions(-)

diff --git a/daemon/stream.c b/daemon/stream.c
index 1d5b50ad7..5077ac8b0 100644
--- a/daemon/stream.c
+++ b/daemon/stream.c
@@ -231,17 +231,23 @@ daemonStreamEvent(virStreamPtr st, int events, void 
*opaque)
 int ret;
 virNetMessagePtr msg;
 virNetMessageError rerr;
+virErrorPtr origErr = virSaveLastError();
 
 memset(, 0, sizeof(rerr));
 stream->closed = true;
 virStreamEventRemoveCallback(stream->st);
 virStreamAbort(stream->st);
-if (events & VIR_STREAM_EVENT_HANGUP)
-virReportError(VIR_ERR_RPC,
-   "%s", _("stream had unexpected termination"));
-else
-virReportError(VIR_ERR_RPC,
-   "%s", _("stream had I/O failure"));
+if (origErr && origErr->code != VIR_ERR_OK) {
+virSetError(origErr);
+virFreeError(origErr);
+} else {
+if (events & VIR_STREAM_EVENT_HANGUP)
+virReportError(VIR_ERR_RPC,
+   "%s", _("stream had unexpected termination"));
+else
+virReportError(VIR_ERR_RPC,
+   "%s", _("stream had I/O failure"));
+}
 
 msg = virNetMessageNew(false);
 if (!msg) {
diff --git a/src/util/virfdstream.c b/src/util/virfdstream.c
index bd2355d17..f54ba15ae 100644
--- a/src/util/virfdstream.c
+++ b/src/util/virfdstream.c
@@ -106,7 +106,7 @@ struct virFDStreamData {
 /* Thread data */
 virThreadPtr thread;
 virCond threadCond;
-int threadErr;
+virErrorPtr threadErr;
 bool threadQuit;
 bool threadAbort;
 bool threadDoRead;
@@ -123,6 +123,7 @@ virFDStreamDataDispose(void *obj)
 virFDStreamDataPtr fdst = obj;
 
 VIR_DEBUG("obj=%p", fdst);
+virFreeError(fdst->threadErr);
 virFDStreamMsgQueueFree(>msg);
 }
 
@@ -312,8 +313,10 @@ static void virFDStreamEvent(int watch ATTRIBUTE_UNUSED,
 return;
 }
 
-if (fdst->threadErr)
+if (fdst->threadErr) {
 events |= VIR_STREAM_EVENT_ERROR;
+virSetError(fdst->threadErr);
+}
 
 cb = fdst->cb;
 cbopaque = fdst->opaque;
@@ -641,7 +644,7 @@ virFDStreamThread(void *opaque)
 return;
 
  error:
-fdst->threadErr = errno;
+fdst->threadErr = virSaveLastError();
 goto cleanup;
 }
 
-- 
2.13.0

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


[libvirt] [PATCH v4 1/6] virfdstream: Check for thread error more frequently

2017-06-22 Thread Michal Privoznik
When the I/O thread quits (e.g. due to an I/O error, lseek()
error, whatever), any subsequent virFDStream API should return
error too. Moreover, when invoking stream event callback, we must
set the VIR_STREAM_EVENT_ERROR flag so that the callback knows
something bad happened.

Signed-off-by: Michal Privoznik 
---
 src/util/virfdstream.c | 19 ---
 1 file changed, 16 insertions(+), 3 deletions(-)

diff --git a/src/util/virfdstream.c b/src/util/virfdstream.c
index ae6f78e01..bd2355d17 100644
--- a/src/util/virfdstream.c
+++ b/src/util/virfdstream.c
@@ -312,6 +312,9 @@ static void virFDStreamEvent(int watch ATTRIBUTE_UNUSED,
 return;
 }
 
+if (fdst->threadErr)
+events |= VIR_STREAM_EVENT_ERROR;
+
 cb = fdst->cb;
 cbopaque = fdst->opaque;
 ff = fdst->ff;
@@ -791,10 +794,10 @@ static int virFDStreamWrite(virStreamPtr st, const char 
*bytes, size_t nbytes)
 if (fdst->thread) {
 char *buf;
 
-if (fdst->threadQuit) {
+if (fdst->threadQuit || fdst->threadErr) {
 virReportSystemError(EBADF, "%s",
  _("cannot write to stream"));
-return -1;
+goto cleanup;
 }
 
 if (VIR_ALLOC(msg) < 0 ||
@@ -870,7 +873,7 @@ static int virFDStreamRead(virStreamPtr st, char *bytes, 
size_t nbytes)
 virFDStreamMsgPtr msg = NULL;
 
 while (!(msg = fdst->msg)) {
-if (fdst->threadQuit) {
+if (fdst->threadQuit || fdst->threadErr) {
 if (nbytes) {
 virReportSystemError(EBADF, "%s",
  _("stream is not open"));
@@ -971,6 +974,13 @@ virFDStreamSendHole(virStreamPtr st,
  * the thread to do the lseek() for us. Under no
  * circumstances we can do the lseek() ourselves here. We
  * might mess up file position for the thread. */
+
+if (fdst->threadQuit || fdst->threadErr) {
+virReportSystemError(EBADF, "%s",
+ _("stream is not open"));
+goto cleanup;
+}
+
 if (fdst->threadDoRead) {
 msg = fdst->msg;
 if (msg->type != VIR_FDSTREAM_MSG_TYPE_HOLE) {
@@ -1025,6 +1035,9 @@ virFDStreamInData(virStreamPtr st,
 if (fdst->thread) {
 virFDStreamMsgPtr msg;
 
+if (fdst->threadErr)
+goto cleanup;
+
 while (!(msg = fdst->msg)) {
 if (fdst->threadQuit) {
 *inData = *length = 0;
-- 
2.13.0

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


[libvirt] [PATCH v4 0/6] Fix error reporting in streams

2017-06-22 Thread Michal Privoznik
v4 of:

https://www.redhat.com/archives/libvir-list/2017-June/msg00190.html

Frankly, nothing much changed since v3, but the discussion on those patches got
very hairy and without any explicit ACKs. So I'm resending to get them :-)

Michal Privoznik (6):
  virfdstream: Check for thread error more frequently
  fdstream: Report error from the I/O thread
  virStream*All: Call virStreamAbort() more frequently
  virStream*All: Preserve reported error
  virFileInData: preserve errno in cleanup path
  virStream*All: Report error if a callback fails

 daemon/stream.c  | 18 ++---
 include/libvirt/libvirt-stream.h | 17 +++-
 src/libvirt-stream.c | 83 +++-
 src/util/virfdstream.c   | 26 ++---
 src/util/virfile.c   |  5 ++-
 5 files changed, 117 insertions(+), 32 deletions(-)

-- 
2.13.0

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


Re: [libvirt] [PATCH] security: Don't skip relabel for all chardevs

2017-06-22 Thread John Ferlan


On 06/22/2017 07:55 AM, Michal Privoznik wrote:
> Our commit e13e8808f9 was way too generic. Currently, virtlogd is
> used only for chardevs type of file and nothing else. True, we
> must not relabel the path in this case, but we have to in all
> other cases. For instance, if you want to have a physical console
> attached to your guest:
> 
> 
>   
>   
> 
> 
> Starting such domain fails because qemu doesn't have access to
> /dev/ttyS0 because we haven't relabelled the path.

It's relabeled in my spell checker ;-)

> 
> Signed-off-by: Michal Privoznik 
> ---
>  src/security/security_dac.c | 8 ++--
>  src/security/security_selinux.c | 8 ++--
>  2 files changed, 12 insertions(+), 4 deletions(-)
> 

 - I guess I was on the right track in my review of :

https://www.redhat.com/archives/libvir-list/2017-June/msg00581.html

but couldn't quite convey enough context over my concern nor truly
follow "all" the various options for chardev's and source usage in the
formatdomain description (a different problem, but suffice to say
confusing at best).

Reviewed-by: John Ferlan 

John

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


Re: [libvirt] RFC: Creating mediated devices with libvirt

2017-06-22 Thread Erik Skultety
On Thu, Jun 22, 2017 at 10:41:13AM +0200, Martin Polednik wrote:
> On 16/06/17 18:14 +0100, Daniel P. Berrange wrote:
> > On Fri, Jun 16, 2017 at 06:11:17PM +0100, Daniel P. Berrange wrote:
> > > On Fri, Jun 16, 2017 at 11:02:55AM -0600, Alex Williamson wrote:
> > > > On Fri, 16 Jun 2017 11:32:04 -0400
> > > > Laine Stump  wrote:
> > > >
> > > > > On 06/15/2017 02:42 PM, Alex Williamson wrote:
> > > > > > On Thu, 15 Jun 2017 09:33:01 +0100
> > > > > > "Daniel P. Berrange"  wrote:
> > > > > >
> > > > > >> On Thu, Jun 15, 2017 at 12:06:43AM +0200, Erik Skultety wrote:
> > > > > >>> Hi all,
> > > > > >>>
> > > > > >>> so there's been an off-list discussion about finally implementing 
> > > > > >>> creation of
> > > > > >>> mediated devices with libvirt and it's more than desired to get 
> > > > > >>> as many opinions
> > > > > >>> on that as possible, so please do share your ideas. This did come 
> > > > > >>> up already as
> > > > > >>> part of some older threads ([1] for example), so this will be a 
> > > > > >>> respin of the
> > > > > >>> discussions. Long story short, we decided to put device creation 
> > > > > >>> off and focus
> > > > > >>> on the introduction of the framework as such first and build upon 
> > > > > >>> that later,
> > > > > >>> i.e. now.
> > > > > >>>
> > > > > >>> [1] 
> > > > > >>> https://www.redhat.com/archives/libvir-list/2017-February/msg00177.html
> > > > > >>>
> > > > > >>> 
> > > > > >>> PART 1: NODEDEV-DRIVER
> > > > > >>> 
> > > > > >>>
> > > > > >>> API-wise, device creation through the nodedev driver should be 
> > > > > >>> pretty
> > > > > >>> straightforward and without any issues, since virNodeDevCreateXML 
> > > > > >>> takes an XML
> > > > > >>> and does support flags. Looking at the current device XML:
> > > > > >>>
> > > > > >>> 
> > > > > >>>   mdev_0cce8709_0640_46ef_bd14_962c7f73cc6f
> > > > > >>>   
> > > > > >>> /sys/devices/pci:00/.../0cce8709-0640-46ef-bd14-962c7f73cc6f
> > > > > >>>   pci__03_00_0
> > > > > >>>   
> > > > > >>> vfio_mdev
> > > > > >>>   
> > > > > >>>   
> > > > > >>> 
> > > > > >>> 
> > > > > >>> UUID 
> > > > > >>>   
> > > > > >>> 
> > > > > >>>
> > > > > >>> We can ignore ,, elements, since these 
> > > > > >>> are useless
> > > > > >>> during creation. We also cannot use  since we don't support 
> > > > > >>> arbitrary
> > > > > >>> names and we also can't rely on users providing a name in correct 
> > > > > >>> form which we
> > > > > >>> would need to further parse in order to get the UUID.
> > > > > >>> So since the only thing missing to successfully use create an 
> > > > > >>> mdev using XML is
> > > > > >>> the UUID (if user doesn't want it to be generated automatically), 
> > > > > >>> how about
> > > > > >>> having a  subelement under  just like PCIs have 
> > > > > >>>  and
> > > > > >>> friends, USBs have  & , interfaces have  to 
> > > > > >>> uniquely
> > > > > >>> identify the device even if the name itself is unique.
> > > > > >>> Removal of a device should work as well, although we might want to
> > > > > >>> consider creating a *Flags version of the API.
> > > > > >>>
> > > > > >>> =
> > > > > >>> PART 2: DOMAIN XML & DEVICE AUTO-CREATION, NO POLICY INVOLVED!
> > > > > >>> =
> > > > > >>>
> > > > > >>> There were some doubts about auto-creation mentioned in [1], 
> > > > > >>> although they
> > > > > >>> weren't specified further. So hopefully, we'll get further in the 
> > > > > >>> discussion
> > > > > >>> this time.
> > > > > >>>
> > > > > >>> From my perspective there are two main reasons/benefits to that:
> > > > > >>>
> > > > > >>> 1) Convenience
> > > > > >>> For apps like virt-manager, user will want to add a host device 
> > > > > >>> transparently,
> > > > > >>> "hey libvirt, I want an mdev assigned to my VM, can you do that". 
> > > > > >>> Even for
> > > > > >>> higher management apps, like oVirt, even they might not care 
> > > > > >>> about the parent
> > > > > >>> device at all times and considering that they would need to 
> > > > > >>> enumerate the
> > > > > >>> parents, pick one, create the device XML and pass it to the 
> > > > > >>> nodedev driver, IMHO
> > > > > >>> it would actually  be easier and faster to just do it directly 
> > > > > >>> through sysfs,
> > > > > >>> bypassing libvirt once again
> > > > > >>
> > > > > >> The convenience only works if the policy we've provided in libvirt 
> > > > > >> actually
> > > > > >> matches the policy the application wants. I think it is quite 
> > > > > >> likely that with
> > > > > >> cloud the mdevs will be created out of band from the domain 
> > > > > >> startup process.
> > > > > >> It is possible the app will just have a fixed set of mdevs 
> > > > > >> pre-created when
> > > > > >> 

[libvirt] [PATCH] security: Don't skip relabel for all chardevs

2017-06-22 Thread Michal Privoznik
Our commit e13e8808f9 was way too generic. Currently, virtlogd is
used only for chardevs type of file and nothing else. True, we
must not relabel the path in this case, but we have to in all
other cases. For instance, if you want to have a physical console
attached to your guest:


  
  


Starting such domain fails because qemu doesn't have access to
/dev/ttyS0 because we haven't relabelled the path.

Signed-off-by: Michal Privoznik 
---
 src/security/security_dac.c | 8 ++--
 src/security/security_selinux.c | 8 ++--
 2 files changed, 12 insertions(+), 4 deletions(-)

diff --git a/src/security/security_dac.c b/src/security/security_dac.c
index 79941f480..ca7a6af6d 100644
--- a/src/security/security_dac.c
+++ b/src/security/security_dac.c
@@ -1179,7 +1179,9 @@ virSecurityDACSetChardevLabel(virSecurityManagerPtr mgr,
 if (chr_seclabel && !chr_seclabel->relabel)
 return 0;
 
-if (!chr_seclabel && chardevStdioLogd)
+if (!chr_seclabel &&
+dev_source->type == VIR_DOMAIN_CHR_TYPE_FILE &&
+chardevStdioLogd)
 return 0;
 
 if (chr_seclabel && chr_seclabel->label) {
@@ -1261,7 +1263,9 @@ virSecurityDACRestoreChardevLabel(virSecurityManagerPtr 
mgr,
 if (chr_seclabel && !chr_seclabel->relabel)
 return 0;
 
-if (!chr_seclabel && chardevStdioLogd)
+if (!chr_seclabel &&
+dev_source->type == VIR_DOMAIN_CHR_TYPE_FILE &&
+chardevStdioLogd)
 return 0;
 
 switch ((virDomainChrType) dev_source->type) {
diff --git a/src/security/security_selinux.c b/src/security/security_selinux.c
index 26137f6d8..2e3082b7a 100644
--- a/src/security/security_selinux.c
+++ b/src/security/security_selinux.c
@@ -2199,7 +2199,9 @@ virSecuritySELinuxSetChardevLabel(virSecurityManagerPtr 
mgr,
 if (chr_seclabel && !chr_seclabel->relabel)
 return 0;
 
-if (!chr_seclabel && chardevStdioLogd)
+if (!chr_seclabel &&
+dev_source->type == VIR_DOMAIN_CHR_TYPE_FILE &&
+chardevStdioLogd)
 return 0;
 
 if (chr_seclabel)
@@ -2274,7 +2276,9 @@ 
virSecuritySELinuxRestoreChardevLabel(virSecurityManagerPtr mgr,
 if (chr_seclabel && !chr_seclabel->relabel)
 return 0;
 
-if (!chr_seclabel && chardevStdioLogd)
+if (!chr_seclabel &&
+dev_source->type == VIR_DOMAIN_CHR_TYPE_FILE &&
+chardevStdioLogd)
 return 0;
 
 switch (dev_source->type) {
-- 
2.13.0

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


Re: [libvirt] [PATCH v3 0/2] Adding locale support for virStrToDouble().

2017-06-22 Thread Martin Kletzander

On Thu, Jun 22, 2017 at 01:12:44PM +0200, Peter Krempa wrote:

On Thu, Jun 22, 2017 at 11:30:06 +0200, Martin Kletzander wrote:

On Wed, Jun 21, 2017 at 02:08:27PM -0300, Julio Faracco wrote:
> The commits add locale support for virStrToDouble() due to differences between
> the mantissa separator in different languages. For example, kernel always uses
> dot to separate mantissa. An user who is using pt_BR locale (for example) uses
> comma as a separator. So, this user will have problems to parse a kernel
> settings using strtod() function.
>
> One of commits move the virDoubleToStr() to virstring.* to share locale
> global variables. Joining the two functions makes more sense.
>

Reviewed-by: Martin Kletzander 

I'll push it in a minute.  Thanks for the patches and patience!


Since this broke build and will require fixing. I'd prefer that the
code to set and revert the locale will be wrapped into a function rather
than scattering conditionally compiled code through the code base.


I'm working on that, but either we need more functions to add
conditionally, or just remove the conditionally compiled code from just
one of those two functions.  I'll post a fix in a while that fixes and
cleans up more stuff, so we'll see and can talk on that patch.


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

Re: [libvirt] [PATCH v3 0/2] Adding locale support for virStrToDouble().

2017-06-22 Thread Peter Krempa
On Thu, Jun 22, 2017 at 11:30:06 +0200, Martin Kletzander wrote:
> On Wed, Jun 21, 2017 at 02:08:27PM -0300, Julio Faracco wrote:
> > The commits add locale support for virStrToDouble() due to differences 
> > between
> > the mantissa separator in different languages. For example, kernel always 
> > uses
> > dot to separate mantissa. An user who is using pt_BR locale (for example) 
> > uses
> > comma as a separator. So, this user will have problems to parse a kernel
> > settings using strtod() function.
> > 
> > One of commits move the virDoubleToStr() to virstring.* to share locale
> > global variables. Joining the two functions makes more sense.
> > 
> 
> Reviewed-by: Martin Kletzander 
> 
> I'll push it in a minute.  Thanks for the patches and patience!

Since this broke build and will require fixing. I'd prefer that the
code to set and revert the locale will be wrapped into a function rather
than scattering conditionally compiled code through the code base.


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

[libvirt] [PATCH v2] qemu: Remove duplicated code in qemuBuildSerialChrDeviceStr()

2017-06-22 Thread Andrea Bolognani
The call to qemuBuildDeviceAddressStr() happens no matter
what, so we can move it to the outer possible scope inside
the function.

We can also move the call to virBufferAsprintf() after all
the checks have been performed, where it makes more sense.

Signed-off-by: Andrea Bolognani 
---
 src/qemu/qemu_command.c | 22 +++---
 1 file changed, 7 insertions(+), 15 deletions(-)

diff --git a/src/qemu/qemu_command.c b/src/qemu/qemu_command.c
index c53ab97..5118541 100644
--- a/src/qemu/qemu_command.c
+++ b/src/qemu/qemu_command.c
@@ -10292,14 +10292,8 @@ qemuBuildSerialChrDeviceStr(char **deviceStr,
 serial->info.type == VIR_DOMAIN_DEVICE_ADDRESS_TYPE_SPAPRVIO) {
 virBufferAsprintf(, "spapr-vty,chardev=char%s",
   serial->info.alias);
-if (qemuBuildDeviceAddressStr(, def, >info, qemuCaps) 
< 0)
-goto error;
 }
 } else {
-virBufferAsprintf(, "%s,chardev=char%s,id=%s",
-  
virDomainChrSerialTargetTypeToString(serial->targetType),
-  serial->info.alias, serial->info.alias);
-
 switch (serial->targetType) {
 case VIR_DOMAIN_CHR_SERIAL_TARGET_TYPE_USB:
 if (!virQEMUCapsGet(qemuCaps, QEMU_CAPS_DEVICE_USB_SERIAL)) {
@@ -10314,9 +10308,6 @@ qemuBuildSerialChrDeviceStr(char **deviceStr,
_("usb-serial requires address of usb type"));
 goto error;
 }
-
-if (qemuBuildDeviceAddressStr(, def, >info, qemuCaps) 
< 0)
-goto error;
 break;
 
 case VIR_DOMAIN_CHR_SERIAL_TARGET_TYPE_ISA:
@@ -10326,9 +10317,6 @@ qemuBuildSerialChrDeviceStr(char **deviceStr,
_("isa-serial requires address of isa type"));
 goto error;
 }
-
-if (qemuBuildDeviceAddressStr(, def, >info, qemuCaps) 
< 0)
-goto error;
 break;
 
 case VIR_DOMAIN_CHR_SERIAL_TARGET_TYPE_PCI:
@@ -10344,13 +10332,17 @@ qemuBuildSerialChrDeviceStr(char **deviceStr,
_("pci-serial requires address of pci type"));
 goto error;
 }
-
-if (qemuBuildDeviceAddressStr(, def, >info, qemuCaps) 
< 0)
-goto error;
 break;
 }
+
+virBufferAsprintf(, "%s,chardev=char%s,id=%s",
+  
virDomainChrSerialTargetTypeToString(serial->targetType),
+  serial->info.alias, serial->info.alias);
 }
 
+if (qemuBuildDeviceAddressStr(, def, >info, qemuCaps) < 0)
+goto error;
+
 if (virBufferCheckError() < 0)
 goto error;
 
-- 
2.7.5

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


Re: [libvirt] [PATCH] qemu: Remove duplicated code in qemuBuildSerialChrDeviceStr()

2017-06-22 Thread Andrea Bolognani
On Thu, 2017-06-22 at 13:55 +0530, Shivaprasad bhat wrote:
> > @@ -10296,10 +10296,6 @@ qemuBuildSerialChrDeviceStr(char **deviceStr,
>  
> We can remove the qemuBuildDeviceAddressStr() from this line too. Like,
> 
> https://paste.fedoraproject.org/paste/D2P1sQT~ElzQ6Ywe5DlIxA

Good point. v2 coming up.

-- 
Andrea Bolognani / Red Hat / Virtualization

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

Re: [libvirt] [PATCH v3 0/2] Adding locale support for virStrToDouble().

2017-06-22 Thread Martin Kletzander

On Wed, Jun 21, 2017 at 02:08:27PM -0300, Julio Faracco wrote:

The commits add locale support for virStrToDouble() due to differences between
the mantissa separator in different languages. For example, kernel always uses
dot to separate mantissa. An user who is using pt_BR locale (for example) uses
comma as a separator. So, this user will have problems to parse a kernel
settings using strtod() function.

One of commits move the virDoubleToStr() to virstring.* to share locale
global variables. Joining the two functions makes more sense.



Reviewed-by: Martin Kletzander 

I'll push it in a minute.  Thanks for the patches and patience!


Julio Faracco (2):
 util: moving virDoubleToStr() from virutil to virstring.
 util: fix locale problem with virStrToDouble().

src/util/virstring.c | 81 
src/util/virstring.h |  3 ++
src/util/virutil.c   | 63 
src/util/virutil.h   |  3 --
4 files changed, 84 insertions(+), 66 deletions(-)

--
2.7.4

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


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

Re: [libvirt] [PATCH RFC 2/2] Resctrl: Add uitls functions to operate sysfs resctrl

2017-06-22 Thread Eli Qiao


On Wednesday, 21 June 2017 at 10:44 PM, Martin Kletzander wrote:

> n 21, 2017 at 02:07:15PM +0800, Eli Qiao wrote:
>  
> You don't need to pass the whole structure of all the data. Can't the
> qemu function just do something like:
>  
> virResctrlLock()
> foreach cachetune:
> region = virResctrlGetFreeRegion(size, type)
> foreach cachetune.vcpu:
> virResctrlSetRegion(vcpu.pid, region)
>  
> Or like with some other tuning, you can have a function that determines
> the region when given vcpu and just call it for all vcpus. You can
> save the regions in the status XML, so that not only users can see it,
> but you can also reference them from that aforementioned function. Or
> you could have saved pairs of id: region, but I think that's not needed.
>  
> That reminds me, unless referred to from somewhere, the cachetune
> doesn't even need the id.
>  
> But basically, you don't need to pass the whole cachetune or any other
> structure. The code is very messy, check your pointers and don't
> compare references to NULLs. Read the diffs after yourself. I know it
> works for you, but the code needs to be readable as well.
>  

Forgive me to spam it again.  

I agree that not to pass whole cachetune , but it seems I need to define new
struct or passing more paramter while setting a cachetune.

1. It’s not just so simple we only get the Region, and setRegion.

We need to consume the llc cache from the “default” group on the host and
then write back it to /sys/fs/resctrl/ and it’s better that we need to compute 
all
the mask at same time because for multiple socket host, if user don’t specify
cache allocation on all sockets, we need to complete the mask by the min bits.

So I don’t think its a good solution to setcachetune in a look.

Better to pass all domain cache tune to virrresctrl and let it calculate it at 
a time
then write it back to /sys/fs/resctrl

2. for region = virResctrlGetFreeRegion(size, type)
if host has multiple sockets, we can not decide which region only be size, type.
Which is to say, we need the cache_id.

3. while doing cache allocation, we need to pass cache control information:

min, granularity, maxAlloc. beyond that , we need cache_id (we can find by 
vcups list)
type, size..



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

Re: [libvirt] RFC: Creating mediated devices with libvirt

2017-06-22 Thread Martin Polednik

On 16/06/17 18:14 +0100, Daniel P. Berrange wrote:

On Fri, Jun 16, 2017 at 06:11:17PM +0100, Daniel P. Berrange wrote:

On Fri, Jun 16, 2017 at 11:02:55AM -0600, Alex Williamson wrote:
> On Fri, 16 Jun 2017 11:32:04 -0400
> Laine Stump  wrote:
>
> > On 06/15/2017 02:42 PM, Alex Williamson wrote:
> > > On Thu, 15 Jun 2017 09:33:01 +0100
> > > "Daniel P. Berrange"  wrote:
> > >
> > >> On Thu, Jun 15, 2017 at 12:06:43AM +0200, Erik Skultety wrote:
> > >>> Hi all,
> > >>>
> > >>> so there's been an off-list discussion about finally implementing 
creation of
> > >>> mediated devices with libvirt and it's more than desired to get as many 
opinions
> > >>> on that as possible, so please do share your ideas. This did come up 
already as
> > >>> part of some older threads ([1] for example), so this will be a respin 
of the
> > >>> discussions. Long story short, we decided to put device creation off 
and focus
> > >>> on the introduction of the framework as such first and build upon that 
later,
> > >>> i.e. now.
> > >>>
> > >>> [1] 
https://www.redhat.com/archives/libvir-list/2017-February/msg00177.html
> > >>>
> > >>> 
> > >>> PART 1: NODEDEV-DRIVER
> > >>> 
> > >>>
> > >>> API-wise, device creation through the nodedev driver should be pretty
> > >>> straightforward and without any issues, since virNodeDevCreateXML takes 
an XML
> > >>> and does support flags. Looking at the current device XML:
> > >>>
> > >>> 
> > >>>   mdev_0cce8709_0640_46ef_bd14_962c7f73cc6f
> > >>>   
/sys/devices/pci:00/.../0cce8709-0640-46ef-bd14-962c7f73cc6f
> > >>>   pci__03_00_0
> > >>>   
> > >>> vfio_mdev
> > >>>   
> > >>>   
> > >>> 
> > >>> 
> > >>> UUID 
> > >>>   
> > >>> 
> > >>>
> > >>> We can ignore ,, elements, since these are 
useless
> > >>> during creation. We also cannot use  since we don't support 
arbitrary
> > >>> names and we also can't rely on users providing a name in correct form 
which we
> > >>> would need to further parse in order to get the UUID.
> > >>> So since the only thing missing to successfully use create an mdev 
using XML is
> > >>> the UUID (if user doesn't want it to be generated automatically), how 
about
> > >>> having a  subelement under  just like PCIs have 
 and
> > >>> friends, USBs have  & , interfaces have  to 
uniquely
> > >>> identify the device even if the name itself is unique.
> > >>> Removal of a device should work as well, although we might want to
> > >>> consider creating a *Flags version of the API.
> > >>>
> > >>> =
> > >>> PART 2: DOMAIN XML & DEVICE AUTO-CREATION, NO POLICY INVOLVED!
> > >>> =
> > >>>
> > >>> There were some doubts about auto-creation mentioned in [1], although 
they
> > >>> weren't specified further. So hopefully, we'll get further in the 
discussion
> > >>> this time.
> > >>>
> > >>> From my perspective there are two main reasons/benefits to that:
> > >>>
> > >>> 1) Convenience
> > >>> For apps like virt-manager, user will want to add a host device 
transparently,
> > >>> "hey libvirt, I want an mdev assigned to my VM, can you do that". Even 
for
> > >>> higher management apps, like oVirt, even they might not care about the 
parent
> > >>> device at all times and considering that they would need to enumerate 
the
> > >>> parents, pick one, create the device XML and pass it to the nodedev 
driver, IMHO
> > >>> it would actually be easier and faster to just do it directly 
through sysfs,
> > >>> bypassing libvirt once again
> > >>
> > >> The convenience only works if the policy we've provided in libvirt 
actually
> > >> matches the policy the application wants. I think it is quite likely 
that with
> > >> cloud the mdevs will be created out of band from the domain startup 
process.
> > >> It is possible the app will just have a fixed set of mdevs pre-created 
when
> > >> the host starts up. Or that the mgmt app wants the domain startup 
process to
> > >> be a two phase setup, where it first allocates the resources needed, and 
later
> > >> then tries to start the guest. This is why I keep saying that putting 
this kind
> > >> of "convenient" policy in libvirt is a bad idea - it is essentially just 
putting
> > >> a bit of virt-manager code into libvirt - more advanced apps will need 
more
> > >> flexibility in this area.
> > >>
> > >>> 2) Future domain migration
> > >>> Suppose now that the mdev backing physical devices support state dump 
and
> > >>> reload. Chances are, that the corresponding mdev doesn't even exist or 
has a
> > >>> different UUID on the destination, so libvirt would do its best to 
handle this
> > >>> before the domain could be resumed.
> > >>
> > >> This is not an unusual scenario - there are already many other parts of 
the
> > >> device backend config that need to 

Re: [libvirt] [PATCH] qemu: Remove duplicated code in qemuBuildSerialChrDeviceStr()

2017-06-22 Thread Shivaprasad bhat
Hi Andrea,


On Thu, Jun 22, 2017 at 11:50 AM, Andrea Bolognani 
wrote:

> The call to qemuBuildDeviceAddressStr() happens no matter
> what, so we can move it outside of the switch. We can also
> move the call to virBufferAsprintf() closer to it to avoid
> having formatting - error checking - more formatting.
>
> Signed-off-by: Andrea Bolognani 
> ---
>  src/qemu/qemu_command.c | 20 +++-
>  1 file changed, 7 insertions(+), 13 deletions(-)
>
> diff --git a/src/qemu/qemu_command.c b/src/qemu/qemu_command.c
> index c53ab97..9bb0163 100644
> --- a/src/qemu/qemu_command.c
> +++ b/src/qemu/qemu_command.c
> @@ -10296,10 +10296,6 @@ qemuBuildSerialChrDeviceStr(char **deviceStr,
>

We can remove the qemuBuildDeviceAddressStr() from this line too. Like,

https://paste.fedoraproject.org/paste/D2P1sQT~ElzQ6Ywe5DlIxA

Thanks,
Shivaprasad

 goto error;

 }
>  } else {
> -virBufferAsprintf(, "%s,chardev=char%s,id=%s",
> -  virDomainChrSerialTargetTypeTo
> String(serial->targetType),
> -  serial->info.alias, serial->info.alias);
> -
>  switch (serial->targetType) {
>  case VIR_DOMAIN_CHR_SERIAL_TARGET_TYPE_USB:
>  if (!virQEMUCapsGet(qemuCaps, QEMU_CAPS_DEVICE_USB_SERIAL)) {
> @@ -10314,9 +10310,6 @@ qemuBuildSerialChrDeviceStr(char **deviceStr,
> _("usb-serial requires address of usb
> type"));
>  goto error;
>  }
> -
> -if (qemuBuildDeviceAddressStr(, def, >info,
> qemuCaps) < 0)
> -goto error;
>  break;
>
>  case VIR_DOMAIN_CHR_SERIAL_TARGET_TYPE_ISA:
> @@ -10326,9 +10319,6 @@ qemuBuildSerialChrDeviceStr(char **deviceStr,
> _("isa-serial requires address of isa
> type"));
>  goto error;
>  }
> -
> -if (qemuBuildDeviceAddressStr(, def, >info,
> qemuCaps) < 0)
> -goto error;
>  break;
>
>  case VIR_DOMAIN_CHR_SERIAL_TARGET_TYPE_PCI:
> @@ -10344,11 +10334,15 @@ qemuBuildSerialChrDeviceStr(char **deviceStr,
> _("pci-serial requires address of pci
> type"));
>  goto error;
>  }
> -
> -if (qemuBuildDeviceAddressStr(, def, >info,
> qemuCaps) < 0)
> -goto error;
>  break;
>  }
> +
> +virBufferAsprintf(, "%s,chardev=char%s,id=%s",
> +  virDomainChrSerialTargetTypeTo
> String(serial->targetType),
> +  serial->info.alias, serial->info.alias);
> +
> +if (qemuBuildDeviceAddressStr(, def, >info,
> qemuCaps) < 0)
> +goto error;
>  }
>
>  if (virBufferCheckError() < 0)
> --
> 2.7.5
>
> --
> libvir-list mailing list
> libvir-list@redhat.com
> https://www.redhat.com/mailman/listinfo/libvir-list
>
--
libvir-list mailing list
libvir-list@redhat.com
https://www.redhat.com/mailman/listinfo/libvir-list

Re: [libvirt] [PATCH] qemu: Support chardevs with ARM virt machines

2017-06-22 Thread Andrea Bolognani
On Wed, 2017-06-07 at 23:13 +0200, Christoffer Dall wrote:
> The function to check if -chardev is supported by QEMU was written a
> long time ago, where adding chardevs did not make sense on the fixed ARM
> platforms.  Since then, we now have a general purpose virt platform,
> which should support plugging in any device over PCIe which is supported
> in a similar fashion on x86.
> 
> Signed-off-by: Christoffer Dall 
> ---
>  src/qemu/qemu_capabilities.c | 5 +
>  1 file changed, 5 insertions(+)
> 
> diff --git a/src/qemu/qemu_capabilities.c b/src/qemu/qemu_capabilities.c
> index 7f22492..1348af7 100644
> --- a/src/qemu/qemu_capabilities.c
> +++ b/src/qemu/qemu_capabilities.c
> @@ -5507,6 +5507,11 @@ virQEMUCapsSupportsChardev(const virDomainDef *def,
>  if ((def->os.arch != VIR_ARCH_ARMV7L) && (def->os.arch != 
>VIR_ARCH_AARCH64))
>  return true;
>  
> +/* The virt machine has a PCIe bus and allows plugging in the same type 
> of
> + * devices as x86 systems do on a PCIe bus. */
> +if (qemuDomainIsVirt(def))
> +return true;
> +
>  /* This may not be true for all ARM machine types, but at least
>   * the only supported non-virtio serial devices of vexpress and versatile
>   * don't have the -chardev property wired up. */

We have two bugs tracking this issue:

  https://bugs.linaro.org/show_bug.cgi?id=2777
  https://bugzilla.redhat.com/show_bug.cgi?id=1435681

You mention in [1] that applying this patch and using a
recent QEMU fixes the problem for you, however I can't
say the same: I still get

  -device isa-serial,chardev=charserial0,id=serial0:
  No 'ISA' bus found for device 'isa-serial'

Would you mind sharing your guest XML and the resulting
QEMU command line?


[1] https://bugs.linaro.org/show_bug.cgi?id=2777#c36
-- 
Andrea Bolognani / Red Hat / Virtualization

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

[libvirt] [PATCH] qemu: Remove duplicated code in qemuBuildSerialChrDeviceStr()

2017-06-22 Thread Andrea Bolognani
The call to qemuBuildDeviceAddressStr() happens no matter
what, so we can move it outside of the switch. We can also
move the call to virBufferAsprintf() closer to it to avoid
having formatting - error checking - more formatting.

Signed-off-by: Andrea Bolognani 
---
 src/qemu/qemu_command.c | 20 +++-
 1 file changed, 7 insertions(+), 13 deletions(-)

diff --git a/src/qemu/qemu_command.c b/src/qemu/qemu_command.c
index c53ab97..9bb0163 100644
--- a/src/qemu/qemu_command.c
+++ b/src/qemu/qemu_command.c
@@ -10296,10 +10296,6 @@ qemuBuildSerialChrDeviceStr(char **deviceStr,
 goto error;
 }
 } else {
-virBufferAsprintf(, "%s,chardev=char%s,id=%s",
-  
virDomainChrSerialTargetTypeToString(serial->targetType),
-  serial->info.alias, serial->info.alias);
-
 switch (serial->targetType) {
 case VIR_DOMAIN_CHR_SERIAL_TARGET_TYPE_USB:
 if (!virQEMUCapsGet(qemuCaps, QEMU_CAPS_DEVICE_USB_SERIAL)) {
@@ -10314,9 +10310,6 @@ qemuBuildSerialChrDeviceStr(char **deviceStr,
_("usb-serial requires address of usb type"));
 goto error;
 }
-
-if (qemuBuildDeviceAddressStr(, def, >info, qemuCaps) 
< 0)
-goto error;
 break;
 
 case VIR_DOMAIN_CHR_SERIAL_TARGET_TYPE_ISA:
@@ -10326,9 +10319,6 @@ qemuBuildSerialChrDeviceStr(char **deviceStr,
_("isa-serial requires address of isa type"));
 goto error;
 }
-
-if (qemuBuildDeviceAddressStr(, def, >info, qemuCaps) 
< 0)
-goto error;
 break;
 
 case VIR_DOMAIN_CHR_SERIAL_TARGET_TYPE_PCI:
@@ -10344,11 +10334,15 @@ qemuBuildSerialChrDeviceStr(char **deviceStr,
_("pci-serial requires address of pci type"));
 goto error;
 }
-
-if (qemuBuildDeviceAddressStr(, def, >info, qemuCaps) 
< 0)
-goto error;
 break;
 }
+
+virBufferAsprintf(, "%s,chardev=char%s,id=%s",
+  
virDomainChrSerialTargetTypeToString(serial->targetType),
+  serial->info.alias, serial->info.alias);
+
+if (qemuBuildDeviceAddressStr(, def, >info, qemuCaps) < 0)
+goto error;
 }
 
 if (virBufferCheckError() < 0)
-- 
2.7.5

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