[libvirt] [PATCH 5/5] nodedev: Protect every access to udev_monitor by locking the driver

2017-07-25 Thread Erik Skultety
Since @udev_monitor isn't immutable within the driver, we need to
protect every access to it by locking the driver, so that no spurious
action changing the pointer while one thread is actively using it might
occur. This patch just takes some precaution measures.

Signed-off-by: Erik Skultety 
---
 src/node_device/node_device_udev.c | 16 
 1 file changed, 12 insertions(+), 4 deletions(-)

diff --git a/src/node_device/node_device_udev.c 
b/src/node_device/node_device_udev.c
index 7ecb330df..0643a5845 100644
--- a/src/node_device/node_device_udev.c
+++ b/src/node_device/node_device_udev.c
@@ -1623,9 +1623,13 @@ udevEventHandleCallback(int watch ATTRIBUTE_UNUSED,
 void *data ATTRIBUTE_UNUSED)
 {
 struct udev_device *device = NULL;
-struct udev_monitor *udev_monitor = DRV_STATE_UDEV_MONITOR(driver);
+struct udev_monitor *udev_monitor = NULL;
 int udev_fd = -1;
 
+nodeDeviceLock();
+if (!(udev_monitor = DRV_STATE_UDEV_MONITOR(driver)))
+goto error;
+
 udev_fd = udev_monitor_get_fd(udev_monitor);
 if (fd != udev_fd) {
 udevPrivate *priv = driver->privateData;
@@ -1640,22 +1644,26 @@ udevEventHandleCallback(int watch ATTRIBUTE_UNUSED,
  * the same error multiple times
  */
 virEventRemoveHandle(priv->watch);
-
-goto cleanup;
+goto error;
 }
 
 device = udev_monitor_receive_device(udev_monitor);
 if (device == NULL) {
 virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
_("udev_monitor_receive_device returned NULL"));
-goto cleanup;
+goto error;
 }
 
+nodeDeviceUnlock();
 udevHandleOneDevice(device);
 
  cleanup:
 udev_device_unref(device);
 return;
+
+ error:
+nodeDeviceUnlock();
+goto cleanup;
 }
 
 
-- 
2.13.3

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


[libvirt] [PATCH 3/5] nodedev: Clear the udev_monitor reference once unref'd

2017-07-25 Thread Erik Skultety
Since we only have one udev_monitor reference throughout libvirt, we
should either clear the pointer we copy around to prevent invalid memory
access once we unref this single reference, or start using reference
counting provided by libudev. This patch follows the former and only
clears the pointer.

Signed-off-by: Erik Skultety 
---
 src/node_device/node_device_udev.c | 1 +
 1 file changed, 1 insertion(+)

diff --git a/src/node_device/node_device_udev.c 
b/src/node_device/node_device_udev.c
index ea10dc3ce..cd19e79c1 100644
--- a/src/node_device/node_device_udev.c
+++ b/src/node_device/node_device_udev.c
@@ -1581,6 +1581,7 @@ nodeStateCleanup(void)
 if (udev_monitor != NULL) {
 udev = udev_monitor_get_udev(udev_monitor);
 udev_monitor_unref(udev_monitor);
+priv->udev_monitor = NULL;
 }
 }
 
-- 
2.13.3

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


[libvirt] [PATCH 1/5] nodedev: mdev: Report an error when virFileResolveLink fails

2017-07-25 Thread Erik Skultety
It might happen that virFileResolveLinkHelper fails on the lstat system
call. virFileResolveLink expects the caller to report an error when it
fails, however this wasn't the case for udevProcessMediatedDevice.

Signed-off-by: Erik Skultety 
---
 src/node_device/node_device_udev.c | 4 +++-
 1 file changed, 3 insertions(+), 1 deletion(-)

diff --git a/src/node_device/node_device_udev.c 
b/src/node_device/node_device_udev.c
index 4762f1969..80c346e96 100644
--- a/src/node_device/node_device_udev.c
+++ b/src/node_device/node_device_udev.c
@@ -1121,8 +1121,10 @@ udevProcessMediatedDevice(struct udev_device *dev,
 if (virAsprintf(&linkpath, "%s/mdev_type", udev_device_get_syspath(dev)) < 
0)
 goto cleanup;
 
-if (virFileResolveLink(linkpath, &canonicalpath) < 0)
+if (virFileResolveLink(linkpath, &canonicalpath) < 0) {
+virReportSystemError(errno, _("failed to resolve '%s'"), linkpath);
 goto cleanup;
+}
 
 if (VIR_STRDUP(data->type, last_component(canonicalpath)) < 0)
 goto cleanup;
-- 
2.13.3

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


[libvirt] [PATCH 4/5] nodedev: Introduce udevHandleOneDevice

2017-07-25 Thread Erik Skultety
Let this new method handle the device object we obtained from the
monitor in order to enhance readability.

Signed-off-by: Erik Skultety 
---
 src/node_device/node_device_udev.c | 31 ++-
 1 file changed, 18 insertions(+), 13 deletions(-)

diff --git a/src/node_device/node_device_udev.c 
b/src/node_device/node_device_udev.c
index cd19e79c1..7ecb330df 100644
--- a/src/node_device/node_device_udev.c
+++ b/src/node_device/node_device_udev.c
@@ -1599,6 +1599,23 @@ nodeStateCleanup(void)
 }
 
 
+static int
+udevHandleOneDevice(struct udev_device *device)
+{
+const char *action = udev_device_get_action(device);
+
+VIR_DEBUG("udev action: '%s'", action);
+
+if (STREQ(action, "add") || STREQ(action, "change"))
+return udevAddOneDevice(device);
+
+if (STREQ(action, "remove"))
+return udevRemoveOneDevice(device);
+
+return 0;
+}
+
+
 static void
 udevEventHandleCallback(int watch ATTRIBUTE_UNUSED,
 int fd,
@@ -1607,7 +1624,6 @@ udevEventHandleCallback(int watch ATTRIBUTE_UNUSED,
 {
 struct udev_device *device = NULL;
 struct udev_monitor *udev_monitor = DRV_STATE_UDEV_MONITOR(driver);
-const char *action = NULL;
 int udev_fd = -1;
 
 udev_fd = udev_monitor_get_fd(udev_monitor);
@@ -1635,18 +1651,7 @@ udevEventHandleCallback(int watch ATTRIBUTE_UNUSED,
 goto cleanup;
 }
 
-action = udev_device_get_action(device);
-VIR_DEBUG("udev action: '%s'", action);
-
-if (STREQ(action, "add") || STREQ(action, "change")) {
-udevAddOneDevice(device);
-goto cleanup;
-}
-
-if (STREQ(action, "remove")) {
-udevRemoveOneDevice(device);
-goto cleanup;
-}
+udevHandleOneDevice(device);
 
  cleanup:
 udev_device_unref(device);
-- 
2.13.3

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


[libvirt] [PATCH 2/5] nodedev: udev: Remove the udevEventHandleCallback on fatal error

2017-07-25 Thread Erik Skultety
So we have a sanity check for the udev monitor fd. Theoretically, it
could happen that the udev monitor fd changes (due to our own wrongdoing,
hence the 'sanity' here) and if that happens it means we are handling an
event from a different entity than we think, thus we should remove the
handle if someone somewhere somehow hits this hypothetical case.

Signed-off-by: Erik Skultety 
---
 src/node_device/node_device_udev.c | 9 +
 1 file changed, 9 insertions(+)

diff --git a/src/node_device/node_device_udev.c 
b/src/node_device/node_device_udev.c
index 80c346e96..ea10dc3ce 100644
--- a/src/node_device/node_device_udev.c
+++ b/src/node_device/node_device_udev.c
@@ -1611,10 +1611,19 @@ udevEventHandleCallback(int watch ATTRIBUTE_UNUSED,
 
 udev_fd = udev_monitor_get_fd(udev_monitor);
 if (fd != udev_fd) {
+udevPrivate *priv = driver->privateData;
+
 virReportError(VIR_ERR_INTERNAL_ERROR,
_("File descriptor returned by udev %d does not "
  "match node device file descriptor %d"),
fd, udev_fd);
+
+/* this is a non-recoverable error, let's remove the handle, so that we
+ * don't get in here again because of some spurious behaviour and 
report
+ * the same error multiple times
+ */
+virEventRemoveHandle(priv->watch);
+
 goto cleanup;
 }
 
-- 
2.13.3

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


[libvirt] [PATCH 0/5] A few fixes and improvements to the nodedev driver

2017-07-25 Thread Erik Skultety
These are just the few I came across when working on another nodedev-related
series.

Erik Skultety (5):
  nodedev: mdev: Report an error when virFileResolveLink fails
  nodedev: udev: Remove the udevEventHandleCallback on fatal error
  nodedev: Clear the udev_monitor reference once unref'd
  nodedev: Introduce udevHandleOneDevice
  nodedev: Protect every access to udev_monitor by locking the driver

 src/node_device/node_device_udev.c | 59 +++---
 1 file changed, 42 insertions(+), 17 deletions(-)

--
2.13.3

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


Re: [libvirt] [PATCH] qemu: we prefer C89 comment styles over C99

2017-07-25 Thread Martin Kletzander

On Tue, Jul 25, 2017 at 11:14:10PM +0200, Pavel Hrdina wrote:

Introduced by commit 'a7bc2c8cfd6f'.

Signed-off-by: Pavel Hrdina 
---

Pushed under trivial rule.

src/qemu/qemu_domain.c | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/src/qemu/qemu_domain.c b/src/qemu/qemu_domain.c
index dcdbfc9701..5c073027db 100644
--- a/src/qemu/qemu_domain.c
+++ b/src/qemu/qemu_domain.c
@@ -7264,7 +7264,8 @@ qemuDomainPrepareChannel(virDomainChrDefPtr channel,
"%s/%s", domainChannelTargetDir,
channel->target.name) < 0)
return -1;
-} else {// Generate a unique name
+} else {
+/* Generate a unique name */


Oh, thanks for catching this.  You could also remove the comment
altogether since the code is pretty self-explanatory, I guess.

Unless you already pushed it, s/we // in $SUBJ.


if (virAsprintf(&channel->source->data.nix.path,
"%s/vioser-%02d-%02d-%02d.sock",
domainChannelTargetDir,
--
2.13.3

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

[libvirt] [PATCH] qemu: we prefer C89 comment styles over C99

2017-07-25 Thread Pavel Hrdina
Introduced by commit 'a7bc2c8cfd6f'.

Signed-off-by: Pavel Hrdina 
---

Pushed under trivial rule.

 src/qemu/qemu_domain.c | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/src/qemu/qemu_domain.c b/src/qemu/qemu_domain.c
index dcdbfc9701..5c073027db 100644
--- a/src/qemu/qemu_domain.c
+++ b/src/qemu/qemu_domain.c
@@ -7264,7 +7264,8 @@ qemuDomainPrepareChannel(virDomainChrDefPtr channel,
 "%s/%s", domainChannelTargetDir,
 channel->target.name) < 0)
 return -1;
-} else {// Generate a unique name
+} else {
+/* Generate a unique name */
 if (virAsprintf(&channel->source->data.nix.path,
 "%s/vioser-%02d-%02d-%02d.sock",
 domainChannelTargetDir,
-- 
2.13.3

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


Re: [libvirt] [PATCH v2] Generate unique socket file

2017-07-25 Thread Pavel Hrdina
On Tue, Jul 25, 2017 at 09:33:50AM -0500, Scott Garfinkle wrote:
> It's possible to have more than one unnamed virtio-serial unix channel.
> We need to generate a unique name for each channel. Currently, we use
> ".../unknown.sock" for all of them. Better practice would be to specify
> an explicit target path name; however, in the absence of that, we need
> uniqueness in the names we generate internally.
> 
> Before the changes we'd get /var/lib/libvirt/qemu/channel/target/unknown.sock
> for each instance of
> 
> 
> 
> 
> 
> Now, we get vioser-00-00-01.sock, vioser-00-00-02.sock, etc.
> 
> Changes from v1: new socket name
> 
> Signed-off-by: Scott Garfinkle 
> 
> ---
>  src/qemu/qemu_domain.c | 24 
> +++---
>  .../qemuxml2argv-channel-virtio-unix.args  |  2 +-
>  2 files changed, 18 insertions(+), 8 deletions(-)
> 
> diff --git a/src/qemu/qemu_domain.c b/src/qemu/qemu_domain.c
> index 78e75f1..7a9958d 100644
> --- a/src/qemu/qemu_domain.c
> +++ b/src/qemu/qemu_domain.c
> @@ -7178,18 +7178,28 @@ int
>  qemuDomainPrepareChannel(virDomainChrDefPtr channel,
>   const char *domainChannelTargetDir)
>  {
> -if (channel->targetType == VIR_DOMAIN_CHR_CHANNEL_TARGET_TYPE_VIRTIO &&
> -channel->source->type == VIR_DOMAIN_CHR_TYPE_UNIX &&
> -!channel->source->data.nix.path) {
> +if (channel->targetType != VIR_DOMAIN_CHR_CHANNEL_TARGET_TYPE_VIRTIO ||
> +channel->source->type != VIR_DOMAIN_CHR_TYPE_UNIX ||
> +channel->source->data.nix.path)
> +return 0;
> +
> +if (channel->target.name) {
>  if (virAsprintf(&channel->source->data.nix.path,
>  "%s/%s", domainChannelTargetDir,
> -channel->target.name ? channel->target.name
> -: "unknown.sock") < 0)
> +channel->target.name) < 0)
> +return -1;
> +} else {// Generate a unique name

We don't allow this type of comment, since this patch is already pushed,
I'll fix it.

Pavel

> +if (virAsprintf(&channel->source->data.nix.path,
> +"%s/vioser-%02d-%02d-%02d.sock",
> +domainChannelTargetDir,
> +channel->info.addr.vioserial.controller,
> +channel->info.addr.vioserial.bus,
> +channel->info.addr.vioserial.port) < 0)
>  return -1;
> -
> -channel->source->data.nix.listen = true;
>  }
>  
> +channel->source->data.nix.listen = true;
> +
>  return 0;
>  }
>  
> diff --git a/tests/qemuxml2argvdata/qemuxml2argv-channel-virtio-unix.args 
> b/tests/qemuxml2argvdata/qemuxml2argv-channel-virtio-unix.args
> index 2b72965..8e0452a 100644
> --- a/tests/qemuxml2argvdata/qemuxml2argv-channel-virtio-unix.args
> +++ b/tests/qemuxml2argvdata/qemuxml2argv-channel-virtio-unix.args
> @@ -29,7 +29,7 @@ 
> path=/tmp/channel/domain--1-QEMUGuest1/org.qemu.guest_agent.0,server,nowait \
>  -device virtserialport,bus=virtio-serial0.0,nr=1,chardev=charchannel0,\
>  id=channel0,name=org.qemu.guest_agent.0 \
>  -chardev socket,id=charchannel1,\
> -path=/tmp/channel/domain--1-QEMUGuest1/unknown.sock,server,nowait \
> +path=/tmp/channel/domain--1-QEMUGuest1/vioser-00-00-02.sock,server,nowait \
>  -device virtserialport,bus=virtio-serial0.0,nr=2,chardev=charchannel1,\
>  id=channel1 \
>  -chardev socket,id=charchannel2,path=/tmp/channel/domain--1-QEMUGuest1/ble,\
> -- 
> 1.8.3.1
> 
> --
> 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 v2] Generate unique socket file

2017-07-25 Thread Martin Kletzander

On Tue, Jul 25, 2017 at 09:33:50AM -0500, Scott Garfinkle wrote:

It's possible to have more than one unnamed virtio-serial unix channel.
We need to generate a unique name for each channel. Currently, we use
".../unknown.sock" for all of them. Better practice would be to specify
an explicit target path name; however, in the absence of that, we need
uniqueness in the names we generate internally.

Before the changes we'd get /var/lib/libvirt/qemu/channel/target/unknown.sock
for each instance of
   
   
   
   

Now, we get vioser-00-00-01.sock, vioser-00-00-02.sock, etc.

Changes from v1: new socket name

Signed-off-by: Scott Garfinkle 

---
src/qemu/qemu_domain.c | 24 +++---
.../qemuxml2argv-channel-virtio-unix.args  |  2 +-
2 files changed, 18 insertions(+), 8 deletions(-)

diff --git a/src/qemu/qemu_domain.c b/src/qemu/qemu_domain.c
index 78e75f1..7a9958d 100644
--- a/src/qemu/qemu_domain.c
+++ b/src/qemu/qemu_domain.c
@@ -7178,18 +7178,28 @@ int
qemuDomainPrepareChannel(virDomainChrDefPtr channel,
 const char *domainChannelTargetDir)
{
-if (channel->targetType == VIR_DOMAIN_CHR_CHANNEL_TARGET_TYPE_VIRTIO &&
-channel->source->type == VIR_DOMAIN_CHR_TYPE_UNIX &&
-!channel->source->data.nix.path) {
+if (channel->targetType != VIR_DOMAIN_CHR_CHANNEL_TARGET_TYPE_VIRTIO ||
+channel->source->type != VIR_DOMAIN_CHR_TYPE_UNIX ||
+channel->source->data.nix.path)
+return 0;
+


Apart from the indentation right here, it looks fine.  I'll fix this up
and push it in a while.

Reviewed-by: Martin Kletzander 


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

[libvirt] [PATCH v2] Generate unique socket file

2017-07-25 Thread Scott Garfinkle
It's possible to have more than one unnamed virtio-serial unix channel.
We need to generate a unique name for each channel. Currently, we use
".../unknown.sock" for all of them. Better practice would be to specify
an explicit target path name; however, in the absence of that, we need
uniqueness in the names we generate internally.

Before the changes we'd get /var/lib/libvirt/qemu/channel/target/unknown.sock
for each instance of





Now, we get vioser-00-00-01.sock, vioser-00-00-02.sock, etc.

Changes from v1: new socket name

Signed-off-by: Scott Garfinkle 

---
 src/qemu/qemu_domain.c | 24 +++---
 .../qemuxml2argv-channel-virtio-unix.args  |  2 +-
 2 files changed, 18 insertions(+), 8 deletions(-)

diff --git a/src/qemu/qemu_domain.c b/src/qemu/qemu_domain.c
index 78e75f1..7a9958d 100644
--- a/src/qemu/qemu_domain.c
+++ b/src/qemu/qemu_domain.c
@@ -7178,18 +7178,28 @@ int
 qemuDomainPrepareChannel(virDomainChrDefPtr channel,
  const char *domainChannelTargetDir)
 {
-if (channel->targetType == VIR_DOMAIN_CHR_CHANNEL_TARGET_TYPE_VIRTIO &&
-channel->source->type == VIR_DOMAIN_CHR_TYPE_UNIX &&
-!channel->source->data.nix.path) {
+if (channel->targetType != VIR_DOMAIN_CHR_CHANNEL_TARGET_TYPE_VIRTIO ||
+channel->source->type != VIR_DOMAIN_CHR_TYPE_UNIX ||
+channel->source->data.nix.path)
+return 0;
+
+if (channel->target.name) {
 if (virAsprintf(&channel->source->data.nix.path,
 "%s/%s", domainChannelTargetDir,
-channel->target.name ? channel->target.name
-: "unknown.sock") < 0)
+channel->target.name) < 0)
+return -1;
+} else {// Generate a unique name
+if (virAsprintf(&channel->source->data.nix.path,
+"%s/vioser-%02d-%02d-%02d.sock",
+domainChannelTargetDir,
+channel->info.addr.vioserial.controller,
+channel->info.addr.vioserial.bus,
+channel->info.addr.vioserial.port) < 0)
 return -1;
-
-channel->source->data.nix.listen = true;
 }
 
+channel->source->data.nix.listen = true;
+
 return 0;
 }
 
diff --git a/tests/qemuxml2argvdata/qemuxml2argv-channel-virtio-unix.args 
b/tests/qemuxml2argvdata/qemuxml2argv-channel-virtio-unix.args
index 2b72965..8e0452a 100644
--- a/tests/qemuxml2argvdata/qemuxml2argv-channel-virtio-unix.args
+++ b/tests/qemuxml2argvdata/qemuxml2argv-channel-virtio-unix.args
@@ -29,7 +29,7 @@ 
path=/tmp/channel/domain--1-QEMUGuest1/org.qemu.guest_agent.0,server,nowait \
 -device virtserialport,bus=virtio-serial0.0,nr=1,chardev=charchannel0,\
 id=channel0,name=org.qemu.guest_agent.0 \
 -chardev socket,id=charchannel1,\
-path=/tmp/channel/domain--1-QEMUGuest1/unknown.sock,server,nowait \
+path=/tmp/channel/domain--1-QEMUGuest1/vioser-00-00-02.sock,server,nowait \
 -device virtserialport,bus=virtio-serial0.0,nr=2,chardev=charchannel1,\
 id=channel1 \
 -chardev socket,id=charchannel2,path=/tmp/channel/domain--1-QEMUGuest1/ble,\
-- 
1.8.3.1

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


Re: [libvirt] [PATCH glib] Don't set LC_ALL=C during build as that breaks python apps

2017-07-25 Thread Philipp Hahn
Hello,

Am 25.07.2017 um 14:07 schrieb Daniel P. Berrange:
> Setting LC_ALL=C breaks python apps doing I/O on UTF-8 source
> files. In particular this broke glib-mkenums
> 
>   GEN  libvirt-gconfig-enum-types.h
> Traceback (most recent call last):
>   File "/usr/bin/glib-mkenums", line 669, in 
> process_file(fname)
>   File "/usr/bin/glib-mkenums", line 406, in process_file
> line = curfile.readline()
>   File "/usr/lib64/python3.6/encodings/ascii.py", line 26, in decode
> return codecs.ascii_decode(input, self.errors)[0]
> UnicodeDecodeError: 'ascii' codec can't decode byte 0xc3 in position 849: 
> ordinal not in range(128)

What about using "C.UTF-8" instead, which us the same as "C" but with
"UTF-8" encoding?
Maybe ancient RedHat still doesn't know about it ...

Philipp

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


Re: [libvirt] [PATCH 2/3] virobject: Introduce virObjectRWLockable

2017-07-25 Thread John Ferlan

>> With your suggestion, I'd have to change all virObjectLock() in
>> src/conf/virnetworkobj.c to virObjectLockWrite() (all that lock the hash
>> table, not network object itself).
>>
> 
> Obviously I hadn't completely through everything...
> 
> But perhaps this also proves that under the covers we could have just
> converted virObjectLockable to be a virObjectRWLockable without creating
> the new class. Especially since the former patch 1 has been reverted and
> there's no difference between virObjectLockableNew and
> virObjectRWLockableNew other than which class was used to initialize.
> 
> If they were combined and just the new API to perform the RW lock was
> added, then for paths that want to use read locks:
> 
>if (!virObjectLockRead(obj))
>   error and fail
> 
>...
> 
> IOW: At this point in time - what is the purpose of a separate
> virObjectRWLockableClass?
> 
> 

nm: I needed to keep excavating...  Still I think not using overloaded
Lock/Unlock in order to allow new functions to return a failure status
would be better.

John

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


[libvirt] [PATCH v3 2/2] qemu: Default hwclock source for sPAPR to RTC

2017-07-25 Thread Kothapally Madhu Pavan
QEMU fails to launch a sPAPR guest with clock sources other that RTC.
Internally qemu only uses RTC timer for hwclock. This patch reports
the right error message instead of qemu erroring out when any other
timer other than RTC is used.

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

diff --git a/src/qemu/qemu_domain.c b/src/qemu/qemu_domain.c
index e5e4208..b3cfb6c 100644
--- a/src/qemu/qemu_domain.c
+++ b/src/qemu/qemu_domain.c
@@ -3103,6 +3103,14 @@ qemuDomainDefValidate(const virDomainDef *def,
virArchToString(def->os.arch));
 goto cleanup;
 }
+/* /* Only RTC timer is supported as hwclock for sPAPR machines */
+if (ARCH_IS_PPC64(def->os.arch) && timer->name != 
VIR_DOMAIN_TIMER_NAME_RTC) {
+virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
+   _("unsupported clock timer '%s' for %s 
architecture"),
+   
virDomainTimerNameTypeToString(def->clock.timers[i]->name),
+   virArchToString(def->os.arch));
+goto cleanup;
+}
 }
 
 if (def->mem.min_guarantee) {
-- 
1.8.3.1

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


[libvirt] [PATCH] qemu_cgroup: Remove unnecessary virQEMUDriverPtr arguments

2017-07-25 Thread Martin Kletzander
Since commit 2e6ecba1bcac, the pointer to the qemu driver is saved in
domain object's private data and hence does not have to be passed as
yet another parameter if domain object is already one of them.

This is a first (example) patch of this kind of clean up, others will
hopefully follow.

Signed-off-by: Martin Kletzander 
---
 src/qemu/qemu_cgroup.c  | 33 ++---
 src/qemu/qemu_cgroup.h  |  6 ++
 src/qemu/qemu_process.c |  4 ++--
 3 files changed, 18 insertions(+), 25 deletions(-)

diff --git a/src/qemu/qemu_cgroup.c b/src/qemu/qemu_cgroup.c
index 7355527c1cc5..6fc413098ae8 100644
--- a/src/qemu/qemu_cgroup.c
+++ b/src/qemu/qemu_cgroup.c
@@ -604,8 +604,7 @@ qemuTeardownChardevCgroup(virDomainObjPtr vm,
 
 
 static int
-qemuSetupDevicesCgroup(virQEMUDriverPtr driver,
-   virDomainObjPtr vm)
+qemuSetupDevicesCgroup(virDomainObjPtr vm)
 {
 qemuDomainObjPrivatePtr priv = vm->privateData;
 virQEMUDriverConfigPtr cfg = NULL;
@@ -644,7 +643,7 @@ qemuSetupDevicesCgroup(virQEMUDriverPtr driver,
 if (rv < 0)
 goto cleanup;
 
-cfg = virQEMUDriverGetConfig(driver);
+cfg = virQEMUDriverGetConfig(priv->driver);
 deviceACL = cfg->cgroupDeviceACL ?
 (const char *const *)cfg->cgroupDeviceACL :
 defaultDeviceACL;
@@ -769,8 +768,7 @@ qemuSetupCpusetCgroup(virDomainObjPtr vm)
 
 
 static int
-qemuSetupCpuCgroup(virQEMUDriverPtr driver,
-   virDomainObjPtr vm)
+qemuSetupCpuCgroup(virDomainObjPtr vm)
 {
 qemuDomainObjPrivatePtr priv = vm->privateData;
 virObjectEventPtr event = NULL;
@@ -806,7 +804,7 @@ qemuSetupCpuCgroup(virQEMUDriverPtr driver,
 event = virDomainEventTunableNewFromObj(vm, eventParams, 
eventNparams);
 }
 
-qemuDomainEventQueue(driver, event);
+qemuDomainEventQueue(priv->driver, event);
 }
 
 return 0;
@@ -814,16 +812,15 @@ qemuSetupCpuCgroup(virQEMUDriverPtr driver,
 
 
 static int
-qemuInitCgroup(virQEMUDriverPtr driver,
-   virDomainObjPtr vm,
+qemuInitCgroup(virDomainObjPtr vm,
size_t nnicindexes,
int *nicindexes)
 {
 int ret = -1;
 qemuDomainObjPrivatePtr priv = vm->privateData;
-virQEMUDriverConfigPtr cfg = virQEMUDriverGetConfig(driver);
+virQEMUDriverConfigPtr cfg = virQEMUDriverGetConfig(priv->driver);
 
-if (!virQEMUDriverIsPrivileged(driver))
+if (!virQEMUDriverIsPrivileged(priv->driver))
 goto done;
 
 if (!virCgroupAvailable())
@@ -954,14 +951,13 @@ qemuRestoreCgroupState(virDomainObjPtr vm)
 }
 
 int
-qemuConnectCgroup(virQEMUDriverPtr driver,
-  virDomainObjPtr vm)
+qemuConnectCgroup(virDomainObjPtr vm)
 {
-virQEMUDriverConfigPtr cfg = virQEMUDriverGetConfig(driver);
 qemuDomainObjPrivatePtr priv = vm->privateData;
+virQEMUDriverConfigPtr cfg = virQEMUDriverGetConfig(priv->driver);
 int ret = -1;
 
-if (!virQEMUDriverIsPrivileged(driver))
+if (!virQEMUDriverIsPrivileged(priv->driver))
 goto done;
 
 if (!virCgroupAvailable())
@@ -991,8 +987,7 @@ qemuConnectCgroup(virQEMUDriverPtr driver,
 }
 
 int
-qemuSetupCgroup(virQEMUDriverPtr driver,
-virDomainObjPtr vm,
+qemuSetupCgroup(virDomainObjPtr vm,
 size_t nnicindexes,
 int *nicindexes)
 {
@@ -1005,13 +1000,13 @@ qemuSetupCgroup(virQEMUDriverPtr driver,
 return -1;
 }
 
-if (qemuInitCgroup(driver, vm, nnicindexes, nicindexes) < 0)
+if (qemuInitCgroup(vm, nnicindexes, nicindexes) < 0)
 return -1;
 
 if (!priv->cgroup)
 return 0;
 
-if (qemuSetupDevicesCgroup(driver, vm) < 0)
+if (qemuSetupDevicesCgroup(vm) < 0)
 goto cleanup;
 
 if (qemuSetupBlkioCgroup(vm) < 0)
@@ -1020,7 +1015,7 @@ qemuSetupCgroup(virQEMUDriverPtr driver,
 if (qemuSetupMemoryCgroup(vm) < 0)
 goto cleanup;
 
-if (qemuSetupCpuCgroup(driver, vm) < 0)
+if (qemuSetupCpuCgroup(vm) < 0)
 goto cleanup;
 
 if (qemuSetupCpusetCgroup(vm) < 0)
diff --git a/src/qemu/qemu_cgroup.h b/src/qemu/qemu_cgroup.h
index d016ce29d87e..3fc1583612e1 100644
--- a/src/qemu/qemu_cgroup.h
+++ b/src/qemu/qemu_cgroup.h
@@ -55,10 +55,8 @@ int qemuSetupChardevCgroup(virDomainObjPtr vm,
virDomainChrDefPtr dev);
 int qemuTeardownChardevCgroup(virDomainObjPtr vm,
   virDomainChrDefPtr dev);
-int qemuConnectCgroup(virQEMUDriverPtr driver,
-  virDomainObjPtr vm);
-int qemuSetupCgroup(virQEMUDriverPtr driver,
-virDomainObjPtr vm,
+int qemuConnectCgroup(virDomainObjPtr vm);
+int qemuSetupCgroup(virDomainObjPtr vm,
 size_t nnicindexes,
 int *nicindexes);
 int qemuSetupCpusetMems(virDomainObjPtr vm);
diff --git a/src/qemu/qemu_process.c b/src/qemu/qemu_process.c
index 87ab85fdb476..535c16b03705 100644
--- a/src/qemu/qemu_process.c
+++ b/src/q

[libvirt] Plans for next release

2017-07-25 Thread Daniel Veillard
  The end of the month is next week, so if we want to release around
Aug 1st, I think we should enter freeze on Thursday morning, then
I could make rc2 on Saturday and we could have the release on the Tuesday
or Wed.
  Usually this is not the busiest time of the year but if this is a problem
please raise this,

  thanks,

Daniel

-- 
Daniel Veillard  | Red Hat Developers Tools http://developer.redhat.com/
veill...@redhat.com  | libxml Gnome XML XSLT toolkit  http://xmlsoft.org/
http://veillard.com/ | virtualization library  http://libvirt.org/

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


Re: [libvirt] [PATCH 2/3] virobject: Introduce virObjectRWLockable

2017-07-25 Thread John Ferlan


On 07/25/2017 10:25 AM, Michal Privoznik wrote:
> On 07/25/2017 02:13 PM, John Ferlan wrote:
>>
>>
>> On 07/25/2017 03:45 AM, Michal Privoznik wrote:
>>> On 07/24/2017 05:22 PM, John Ferlan wrote:
 [...]

>  /**
>   * virObjectLock:
> - * @anyobj: any instance of virObjectLockablePtr
> + * @anyobj: any instance of virObjectLockable or virObjectRWLockable
>   *
> - * Acquire a lock on @anyobj. The lock must be
> - * released by virObjectUnlock.
> + * Acquire a lock on @anyobj. The lock must be released by
> + * virObjectUnlock. In case the passed object is instance of
> + * virObjectRWLockable a write lock is acquired.
>   *
>   * The caller is expected to have acquired a reference
>   * on the object before locking it (eg virObjectRef).
> @@ -340,31 +382,69 @@ virObjectGetLockableObj(void *anyobj)
>  void
>  virObjectLock(void *anyobj)
>  {
> -virObjectLockablePtr obj = virObjectGetLockableObj(anyobj);
> +if (virObjectIsClass(anyobj, virObjectLockableClass)) {
> +virObjectLockablePtr obj = anyobj;
> +virMutexLock(&obj->lock);
> +} else if (virObjectIsClass(anyobj, virObjectRWLockableClass)) {
> +virObjectRWLockablePtr obj = anyobj;
> +virRWLockWrite(&obj->lock);
> +} else {
> +virObjectPtr obj = anyobj;
> +VIR_WARN("Object %p (%s) is not a virObjectLockable "
> + "nor virObjectRWLockable instance",
> + anyobj, obj ? obj->klass->name : "(unknown)");
> +}
> +}
>  
> -if (!obj)
> -return;
>  
> -virMutexLock(&obj->lock);
> +/**
> + * virObjectLockRead:
> + * @anyobj: any instance of virObjectRWLockablePtr
> + *
> + * Acquire a read lock on @anyobj. The lock must be
> + * released by virObjectUnlock.
> + *
> + * The caller is expected to have acquired a reference
> + * on the object before locking it (eg virObjectRef).
> + * The object must be unlocked before releasing this
> + * reference.
> + */
> +void
> +virObjectLockRead(void *anyobj)
> +{
> +if (virObjectIsClass(anyobj, virObjectRWLockableClass)) {
> +virObjectRWLockablePtr obj = anyobj;
> +virRWLockRead(&obj->lock);
> +} else {
> +virObjectPtr obj = anyobj;
> +VIR_WARN("Object %p (%s) is not a virObjectRWLockable instance",
> + anyobj, obj ? obj->klass->name : "(unknown)");
> +}
>  }
>  

 Hopefully no one "confuses" which object is which or no one starts using
 virObjectLockRead for a virObjectLockable and expects that read lock to
 be in place (or error out) or gasp actually wait for a write lock to
 release the lock as this does not error out.
>>>
>>> This could have already happened if one would pass bare virObject to
>>> virObjectLock().
>>>
>>
>> Consider passing a non virObject (such as what happened during an early
>> change to the code for me - a virHashTablePtr) to virObjectLock...
> 
> Well, that's what happens in C to functions accepting void pointer. In
> this sense yes, we are not true OOP - compiler would catch that you're
> calling a method that is not defined for the class. But since we're
> implementing OOP in runtime, we are able to catch OOP related problem
> only at runtime. I'm not sure it is something we can check for at
> compile time. And I think other C libraries that re-implement OOP (like
> glib) do just the same as us.
> 

Agreed - I cannot think of a way to capture this at compile time, but as
part of that virObject series I did add some code to reduce the chance
of some bad things happening during run time. They don't completely
eliminate the possibility that someone calls virObject{Lock|Unlock}
using an @obj that isn't a virObjectLockable.  But it does protect
against someone using virObject{Ref|Unref} in order to avoid an
virAtomicIntInc or a virAtomicIntDecAndTest on a random @obj field (plus
some worse settings on random fields if for some reason @lastRef is true).

I hadn't come up with a good way to handle virObject{Lock|Unlock}, but
this series jiggled the memory a bit and got me thinking...

>>
>> In any case, we'll have to be more vigilant now to know that only
>> ObjList @obj's for virdomainobjlist can use this new API.
> 
> Why? Maybe I'm misunderstanding what you're saying, but I think that
> network driver, and basically any other driver which uses vir*ObjList
> can use it. And not just lists. Other objects too - e.g. qemuCaps,
> virDomainCaps, etc (I really roughly skimmed through users of
> virObjectLockable).

Ok - wasn't as clear as I should have been... True, as long as the
_vir*ObjList uses virObjectRWLockable and the vir*ObjListNew() uses
virObjectRWLockableNew. Similar for other objects that want to do the
right thing.

I was considering someone that sees virOb

[libvirt] [PATCH v3 1/2] qemu: Restrict usage of hpet and kvm.pit timers by unsupported architectures

2017-07-25 Thread Kothapally Madhu Pavan
hpet and kvm.pit clock timers are specific to x86 architecture and
are not suppose to be used in other architectures. This patch restricts
the usage of hpet and kvm.pit timers in unsupported architectures.

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

diff --git a/src/qemu/qemu_domain.c b/src/qemu/qemu_domain.c
index 2c8c9a7..e5e4208 100644
--- a/src/qemu/qemu_domain.c
+++ b/src/qemu/qemu_domain.c
@@ -3083,12 +3083,28 @@ qemuDomainDefValidate(const virDomainDef *def,
 virQEMUCapsPtr qemuCaps = NULL;
 unsigned int topologycpus;
 int ret = -1;
+size_t i;
 
 if (!(qemuCaps = virQEMUCapsCacheLookup(caps,
 driver->qemuCapsCache,
 def->emulator)))
 goto cleanup;
 
+/* Restrict usage of unsupported clock sources */
+for (i = 0; i < def->clock.ntimers; i++) {
+virDomainTimerDefPtr timer = def->clock.timers[i];
+if ((!(virQEMUCapsGet(qemuCaps, QEMU_CAPS_NO_HPET)) &&
+ (timer->name == VIR_DOMAIN_TIMER_NAME_HPET)) ||
+(!(virQEMUCapsGet(qemuCaps, QEMU_CAPS_NO_KVM_PIT)) &&
+ (timer->name == VIR_DOMAIN_TIMER_NAME_PIT))) {
+virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
+   _("unsupported clock timer '%s' for %s 
architecture"),
+   
virDomainTimerNameTypeToString(def->clock.timers[i]->name),
+   virArchToString(def->os.arch));
+goto cleanup;
+}
+}
+
 if (def->mem.min_guarantee) {
 virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
_("Parameter 'min_guarantee' not supported by QEMU."));
-- 
1.8.3.1

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


Re: [libvirt] [PATCH v3] storage: Disallow usage of the HBA for a fc_host backing

2017-07-25 Thread Erik Skultety
> +/**
> + * @name: Name from a wwnn/wwpn lookup
> + *
> + * Validate that the @name fetched from the wwnn/wwpn is a vHBA
> + * and not an HBA as that should be a configuration error. It's only
> + * possible to use an existing wwnn/wwpn of a vHBA because that's
> + * what someone would have created using the node device create via XML
> + * functionality. Using the HBA "just because" it has a wwnn/wwpn and
> + * the characteristics of a vHBA is just not valid
> + *
> + * Returns true if the @name is OK, false on error
> + */
> +static bool
> +checkName(const char *name)
> +{
> +unsigned int host_num;
> +
> +if (virSCSIHostGetNumber(name, &host_num) &&

I expressed my doubts about ^this if it fails...I was wrong, if that fails,
we've got other problems, IOW virVHBAGetHostByWWN always must feed us a valid
name, since it's fetching it from the filesystem, so we should not have any
problem parsing it, thus extracting @host_num from it.

So, I'm sorry I didn't see it right away, ACK.

Erik

> +virVHBAIsVportCapable(NULL, host_num))
> +return true;
> +
> +virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
> +   _("the wwnn/wwpn for '%s' are assigned to an HBA"), name);
> +return false;
> +}
> +
> +
>  /*
>   * Using the host# name found via wwnn/wwpn lookup in the fc_host
>   * sysfs tree to get the parent 'scsi_host#' to ensure it matches.
> @@ -288,6 +315,9 @@ createVport(virConnectPtr conn,
>   * this pool and we don't have to create the vHBA
>   */
>  if ((name = virVHBAGetHostByWWN(NULL, fchost->wwnn, fchost->wwpn))) {
> +if (!(checkName(name)))
> +goto cleanup;
> +
>  /* If a parent was provided, let's make sure the 'name' we've
>   * retrieved has the same parent. If not this will cause failure. */
>  if (!fchost->parent || checkParent(conn, name, fchost->parent))
> --
> 2.9.4
>
> --
> 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


[libvirt] [PATCH v3 0/2] Restrict usage of unsupported clock timers

2017-07-25 Thread Kothapally Madhu Pavan
hpet and kvm.pit clock timers are specific to x86 architecture and
are not to be used by unsuported architectures. Similarly sPAPR
guests only allow RTC timer. This patchset will restrict the usage
of unsupported clock timers.

Kothapally Madhu Pavan (2):
  qemu: Restrict usage of hpet and kvm.pit timers by unsupported
architectures
  qemu: Default hwclock source for sPAPR to RTC

 src/qemu/qemu_domain.c | 24 
 1 file changed, 24 insertions(+)

-- 
1.8.3.1

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


Re: [libvirt] [PATCH v2] storage: Disallow usage of the HBA for a fc_host backing

2017-07-25 Thread Erik Skultety
> One would hope it doesn't fail...

Even if it does, virSCSIHostGetNumber does report an error already.

>
> Your suggestions make checkName much cleaner:
>
> if (virSCSIHostGetNumber(name, &host_num) &&
> virVHBAIsVportCapable(NULL, host_num))
> return true;
>

if virSCSIHostGetNumber fails, it will report an error on its own but you'll
also format the one below which wouldn't be true, because at that point you
still don't know whether wwnn/wwpn refer to either an HBA or a vHBA

> virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
>_("the wwnn/wwpn for '%s' are assigned to an HBA"),
> name);
> return false;
>
> and only add :
>
> if (!(checkName(name)))
> goto cleanup
>
> to the createVport
>
> The @name to @scsi_host_name can return to checkParent.  I retest and

I'm fine with ^this change.

Erik

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


Re: [libvirt] [PATCH 2/3] virobject: Introduce virObjectRWLockable

2017-07-25 Thread Michal Privoznik
On 07/25/2017 04:25 PM, Michal Privoznik wrote:
> 
> Moreover, now I can do the following and the code still works:
> 
> diff --git i/src/conf/virnetworkobj.c w/src/conf/virnetworkobj.c
> index ccde72e72..4fe13fc40 100644
> --- i/src/conf/virnetworkobj.c
> +++ w/src/conf/virnetworkobj.c
> @@ -60 +60 @@ virNetworkObjOnceInit(void)
> -if (!(virNetworkObjListClass = virClassNew(virClassForObjectLockable(),
> +if (!(virNetworkObjListClass = virClassNew(virClassForObjectRWLockable(),
> diff --git i/src/conf/virnetworkobj.h w/src/conf/virnetworkobj.h
> index 8090c2e24..ee4a939f2 100644
> --- i/src/conf/virnetworkobj.h
> +++ w/src/conf/virnetworkobj.h
> @@ -30 +30 @@ struct _virNetworkObj {
> -virObjectLockable parent;
> +virObjectRWLockable parent;
> 

Hit 'Send' too soon. This should have been:

diff --git i/src/conf/virnetworkobj.c w/src/conf/virnetworkobj.c
index ccde72e72..82be62832 100644
--- i/src/conf/virnetworkobj.c
+++ w/src/conf/virnetworkobj.c
@@ -41 +41 @@ struct _virNetworkObjList {
-virObjectLockable parent;
+virObjectRWLockable parent;
@@ -60 +60 @@ virNetworkObjOnceInit(void)
-if (!(virNetworkObjListClass = virClassNew(virClassForObjectLockable(),
+if (!(virNetworkObjListClass = virClassNew(virClassForObjectRWLockable(),


Obviously, rewriting virNetworkObj to use RW locks is gonna require some more 
work.

Michal

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


Re: [libvirt] [PATCH 2/3] virobject: Introduce virObjectRWLockable

2017-07-25 Thread Michal Privoznik
On 07/25/2017 02:13 PM, John Ferlan wrote:
> 
> 
> On 07/25/2017 03:45 AM, Michal Privoznik wrote:
>> On 07/24/2017 05:22 PM, John Ferlan wrote:
>>> [...]
>>>
  /**
   * virObjectLock:
 - * @anyobj: any instance of virObjectLockablePtr
 + * @anyobj: any instance of virObjectLockable or virObjectRWLockable
   *
 - * Acquire a lock on @anyobj. The lock must be
 - * released by virObjectUnlock.
 + * Acquire a lock on @anyobj. The lock must be released by
 + * virObjectUnlock. In case the passed object is instance of
 + * virObjectRWLockable a write lock is acquired.
   *
   * The caller is expected to have acquired a reference
   * on the object before locking it (eg virObjectRef).
 @@ -340,31 +382,69 @@ virObjectGetLockableObj(void *anyobj)
  void
  virObjectLock(void *anyobj)
  {
 -virObjectLockablePtr obj = virObjectGetLockableObj(anyobj);
 +if (virObjectIsClass(anyobj, virObjectLockableClass)) {
 +virObjectLockablePtr obj = anyobj;
 +virMutexLock(&obj->lock);
 +} else if (virObjectIsClass(anyobj, virObjectRWLockableClass)) {
 +virObjectRWLockablePtr obj = anyobj;
 +virRWLockWrite(&obj->lock);
 +} else {
 +virObjectPtr obj = anyobj;
 +VIR_WARN("Object %p (%s) is not a virObjectLockable "
 + "nor virObjectRWLockable instance",
 + anyobj, obj ? obj->klass->name : "(unknown)");
 +}
 +}
  
 -if (!obj)
 -return;
  
 -virMutexLock(&obj->lock);
 +/**
 + * virObjectLockRead:
 + * @anyobj: any instance of virObjectRWLockablePtr
 + *
 + * Acquire a read lock on @anyobj. The lock must be
 + * released by virObjectUnlock.
 + *
 + * The caller is expected to have acquired a reference
 + * on the object before locking it (eg virObjectRef).
 + * The object must be unlocked before releasing this
 + * reference.
 + */
 +void
 +virObjectLockRead(void *anyobj)
 +{
 +if (virObjectIsClass(anyobj, virObjectRWLockableClass)) {
 +virObjectRWLockablePtr obj = anyobj;
 +virRWLockRead(&obj->lock);
 +} else {
 +virObjectPtr obj = anyobj;
 +VIR_WARN("Object %p (%s) is not a virObjectRWLockable instance",
 + anyobj, obj ? obj->klass->name : "(unknown)");
 +}
  }
  
>>>
>>> Hopefully no one "confuses" which object is which or no one starts using
>>> virObjectLockRead for a virObjectLockable and expects that read lock to
>>> be in place (or error out) or gasp actually wait for a write lock to
>>> release the lock as this does not error out.
>>
>> This could have already happened if one would pass bare virObject to
>> virObjectLock().
>>
> 
> Consider passing a non virObject (such as what happened during an early
> change to the code for me - a virHashTablePtr) to virObjectLock...

Well, that's what happens in C to functions accepting void pointer. In
this sense yes, we are not true OOP - compiler would catch that you're
calling a method that is not defined for the class. But since we're
implementing OOP in runtime, we are able to catch OOP related problem
only at runtime. I'm not sure it is something we can check for at
compile time. And I think other C libraries that re-implement OOP (like
glib) do just the same as us.

> 
> In any case, we'll have to be more vigilant now to know that only
> ObjList @obj's for virdomainobjlist can use this new API.

Why? Maybe I'm misunderstanding what you're saying, but I think that
network driver, and basically any other driver which uses vir*ObjList
can use it. And not just lists. Other objects too - e.g. qemuCaps,
virDomainCaps, etc (I really roughly skimmed through users of
virObjectLockable).

And @obj's are untouched with this change, aren't they? I feel like
we're not on the same page here. My change just allowed two threads to
look up domains at the same time. It doesn't affect domains in any way.

> Longer term
> I'll adjust to use them.
> 
>>>
>>> This is a danger in the long term assumption of having a void function
>>> that has callers that can make the assumption that upon return the Lock
>>> really was taken.
>>
>> Well, I agree that this is one more thing to be cautious about, but no
>> more than making sure object passed to virObjectLock() is virObjectLockable.
>>
> 
> There are some ugly ways to handle this including using some kind of
> macro for virObjectLock that would force an abort of some sort. We have
> been "fortunate" to have well behaved and reviewed code, but with two
> lock API's now it's just one of those things to keep track of for reviews.

I don't find this change that frightening, but I agree that bare
VIR_WARN() we have might not be enough. There are plenty ways where
malicious pointers can be passed to virObject* APIs, and especially
virObjectLock(). Wors

[libvirt] [PATCH v3] storage: Disallow usage of the HBA for a fc_host backing

2017-07-25 Thread John Ferlan
Disallow providing the wwnn/wwpn of the HBA in the adapter XML:

  

This should be considered a configuration error since a vHBA
would not be created. In order to use the HBA as the backing the
following XML should be used:

  

So add a check prior to the checkParent call to validate that
the provided wwnn/wwpn resolves to a vHBA and not an HBA.

Signed-off-by: John Ferlan 
---

 v2: https://www.redhat.com/archives/libvir-list/2017-July/msg01019.html

 Changes since v2, from review, simplify logic even more.


 docs/formatstorage.html.in | 27 +++
 src/storage/storage_backend_scsi.c | 30 ++
 2 files changed, 45 insertions(+), 12 deletions(-)

diff --git a/docs/formatstorage.html.in b/docs/formatstorage.html.in
index 4946ddf..27578e8 100644
--- a/docs/formatstorage.html.in
+++ b/docs/formatstorage.html.in
@@ -207,18 +207,21 @@
 
 
   wwnn and wwpn
-  The "World Wide Node Name" (wwnn) and "World Wide
-Port Name" (wwpn) are used by the "fc_host" adapter
-to uniquely identify the device in the Fibre Channel storage fabric
-(the device can be either a HBA or vHBA). Both wwnn and wwpn should
-be specified. Use the command 'virsh nodedev-dumpxml' to determine
-how to set the values for the wwnn/wwpn of a (v)HBA. The wwnn and
-wwpn have very specific numerical format requirements based on the
-hypervisor being used, thus care should be taken if you decide to
-generate your own to follow the standards; otherwise, the pool
-will fail to start with an opaque error message indicating failure
-to write to the vport_create file during vport create/delete due
-to "No such file or directory".
+  The required "World Wide Node Name" (wwnn) and
+"World Wide Port Name" (wwpn) are used by the
+"fc_host" adapter to uniquely identify the vHBA device in the
+Fibre Channel storage fabric. If the vHBA device already exists
+as a Node Device, then libvirt will use it; otherwise, the vHBA
+will be created using the provided values. It is considered a
+configuration error use the values from the HBA as those would
+be for a "scsi_host" type pool instead. The
+wwnn and wwpn have very specific
+format requirements based on the hypervisor being used, thus
+care should be taken if you decide to generate your own to
+follow the standards; otherwise, the pool will fail to start
+with an opaque error message indicating failure to write to
+the vport_create file during vport create/delete due to
+"No such file or directory".
 Since 1.0.4
   
 
diff --git a/src/storage/storage_backend_scsi.c 
b/src/storage/storage_backend_scsi.c
index af12889..575e6a6 100644
--- a/src/storage/storage_backend_scsi.c
+++ b/src/storage/storage_backend_scsi.c
@@ -211,6 +211,33 @@ getAdapterName(virStorageAdapterPtr adapter)
 }
 
 
+/**
+ * @name: Name from a wwnn/wwpn lookup
+ *
+ * Validate that the @name fetched from the wwnn/wwpn is a vHBA
+ * and not an HBA as that should be a configuration error. It's only
+ * possible to use an existing wwnn/wwpn of a vHBA because that's
+ * what someone would have created using the node device create via XML
+ * functionality. Using the HBA "just because" it has a wwnn/wwpn and
+ * the characteristics of a vHBA is just not valid
+ *
+ * Returns true if the @name is OK, false on error
+ */
+static bool
+checkName(const char *name)
+{
+unsigned int host_num;
+
+if (virSCSIHostGetNumber(name, &host_num) &&
+virVHBAIsVportCapable(NULL, host_num))
+return true;
+
+virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
+   _("the wwnn/wwpn for '%s' are assigned to an HBA"), name);
+return false;
+}
+
+
 /*
  * Using the host# name found via wwnn/wwpn lookup in the fc_host
  * sysfs tree to get the parent 'scsi_host#' to ensure it matches.
@@ -288,6 +315,9 @@ createVport(virConnectPtr conn,
  * this pool and we don't have to create the vHBA
  */
 if ((name = virVHBAGetHostByWWN(NULL, fchost->wwnn, fchost->wwpn))) {
+if (!(checkName(name)))
+goto cleanup;
+
 /* If a parent was provided, let's make sure the 'name' we've
  * retrieved has the same parent. If not this will cause failure. */
 if (!fchost->parent || checkParent(conn, name, fchost->parent))
-- 
2.9.4

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


Re: [libvirt] [PATCH v2] storage: Disallow usage of the HBA for a fc_host backing

2017-07-25 Thread John Ferlan


On 07/25/2017 08:49 AM, Erik Skultety wrote:
> On Tue, Jul 25, 2017 at 07:36:48AM -0400, John Ferlan wrote:
>>
>>
>> On 07/25/2017 03:45 AM, Erik Skultety wrote:
 +/**
 + * @name: Name from a wwnn/wwpn lookup
 + *
 + * Validate that the @name fetched from the wwnn/wwpn is a vHBA and not
 + * an HBA as that should be a configuration error. It's only possible to
 + * use an existing wwnn/wwpn of a vHBA because that's what someone would
 + * have created using the node device create functionality. Using the
 + * HBA "just because" it has a wwnn/wwpn and the characteristics of a
 + * vHBA is just not valid
 + *
 + * Returns the @scsi_host_name to be used or NULL on errror
> 
> s/errror/error
> 
> ...
> 

OK

 @@ -275,6 +316,7 @@ createVport(virConnectPtr conn,
  virStorageAdapterFCHostPtr fchost)
  {
  char *name = NULL;
 +char *scsi_host_name = NULL;
  virStoragePoolFCRefreshInfoPtr cbdata = NULL;
  virThread thread;
  int ret = -1;
 @@ -288,6 +330,9 @@ createVport(virConnectPtr conn,
   * this pool and we don't have to create the vHBA
   */
  if ((name = virVHBAGetHostByWWN(NULL, fchost->wwnn, fchost->wwpn))) {
 +if (!(scsi_host_name = checkName(name)))
 +goto cleanup;
>>>
>>> Ok, so I learn from my mistakes, do you plan on building upon this in the
>>> foreseeable future with a follow-up series you haven't sent yet, but have 
>>> on a
>>> local branch? Because if not, I don't really see a point in returning a 
>>> string
>>> which only gets free'd on the function exit - checkName should probably 
>>> become
>>> something like "isVHBA" and return boolean. And even if you do have a 
>>> follow-up
>>> on a local branch, I still think that converting the return value should be
>>> part of that series, solely because until then, @scsi_host_name wouldn't 
>>> have
>>> any meaning.
>>>
>>> Erik
>>>
>>
>> No this is it - I want to stop thinking about NPIV for a while... I
>> returned the 'scsi_host_name' string because in my mind I had passed it
>> to checkParent, but apparently I didn't do that, sigh.
>>
>> Does that make more sense now?
> 
> Indeed, to be honest I missed the connection between name and scsi_host_name
> and thought, yeah ok makes sense (probably have seen quite a lot NPIV lately
> myself)now that I see it a bit more clearly, it still left me wondering if
> it wouldn't make more sense to move the scsi_host_name formatting part to
> createVport (you free it here after all) right after you pass @name to

That's fine...

> checkName/isVHBA (whatever we settle on):
> - you don't need to format it prior to your checkName, since backwards
>   compatibility takes care of eating "hostX" nicely
> - you also don't need to report any error when virSCSIHostGetNumber fails,
>   since one gets formatted already and it didn't bring much value

One would hope it doesn't fail...

Your suggestions make checkName much cleaner:

if (virSCSIHostGetNumber(name, &host_num) &&
virVHBAIsVportCapable(NULL, host_num))
return true;

virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
   _("the wwnn/wwpn for '%s' are assigned to an HBA"),
name);
return false;

and only add :

if (!(checkName(name)))
goto cleanup

to the createVport

The @name to @scsi_host_name can return to checkParent.  I retest and
repost shortly.

Tks -

John

> 
> -> then, right after that call you actually format the "scsi_" name since you
> really need it to traverse the list of devices and find the parent in
> checkParent.
> 
> Erik
> 
>>
>> John

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


Re: [libvirt] [PATCH 2/4] qemu: Save qemu driver in qemuDomainObjPrivateData

2017-07-25 Thread Michal Privoznik
On 07/25/2017 03:48 PM, Martin Kletzander wrote:
> On Tue, Jul 25, 2017 at 03:20:48PM +0200, Michal Privoznik wrote:
>> On 07/24/2017 04:09 PM, Martin Kletzander wrote:
>>> This way we can finally make it static and not use any externs anywhere.
>>>
>>> Signed-off-by: Martin Kletzander 
>>> ---
>>>  src/qemu/qemu_domain.c  | 3 ++-
>>>  src/qemu/qemu_domain.h  | 2 ++
>>>  src/qemu/qemu_driver.c  | 2 +-
>>>  src/qemu/qemu_process.c | 5 +
>>>  4 files changed, 6 insertions(+), 6 deletions(-)
>>>
>>> diff --git a/src/qemu/qemu_domain.c b/src/qemu/qemu_domain.c
>>> index f1e144d92b64..0b7c45280321 100644
>>> --- a/src/qemu/qemu_domain.c
>>> +++ b/src/qemu/qemu_domain.c
>>> @@ -1662,7 +1662,7 @@ qemuDomainClearPrivatePaths(virDomainObjPtr vm)
>>>
>>>
>>>  static void *
>>> -qemuDomainObjPrivateAlloc(void *opaque ATTRIBUTE_UNUSED)
>>> +qemuDomainObjPrivateAlloc(void *opaque)
>>>  {
>>>  qemuDomainObjPrivatePtr priv;
>>>
>>> @@ -1679,6 +1679,7 @@ qemuDomainObjPrivateAlloc(void *opaque
>>> ATTRIBUTE_UNUSED)
>>>  goto error;
>>>
>>>  priv->migMaxBandwidth = QEMU_DOMAIN_MIG_BANDWIDTH_MAX;
>>> +priv->driver = opaque;
>>>
>>>  return priv;
>>>
>>> diff --git a/src/qemu/qemu_domain.h b/src/qemu/qemu_domain.h
>>> index 365b23c96167..71567af034f5 100644
>>> --- a/src/qemu/qemu_domain.h
>>> +++ b/src/qemu/qemu_domain.h
>>> @@ -217,6 +217,8 @@ struct _qemuDomainSecretInfo {
>>>  typedef struct _qemuDomainObjPrivate qemuDomainObjPrivate;
>>>  typedef qemuDomainObjPrivate *qemuDomainObjPrivatePtr;
>>>  struct _qemuDomainObjPrivate {
>>> +virQEMUDriverPtr driver;
>>> +
>>>  struct qemuDomainJobObj job;
>>>
>>>  virBitmapPtr namespaces;
>>> diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c
>>> index 6568def156f4..9c54571cf078 100644
>>> --- a/src/qemu/qemu_driver.c
>>> +++ b/src/qemu/qemu_driver.c
>>> @@ -159,7 +159,7 @@ static int qemuGetDHCPInterfaces(virDomainPtr dom,
>>>   virDomainObjPtr vm,
>>>   virDomainInterfacePtr **ifaces);
>>>
>>> -virQEMUDriverPtr qemu_driver = NULL;
>>> +static virQEMUDriverPtr qemu_driver;
>>>
>>>
>>>  static void
>>> diff --git a/src/qemu/qemu_process.c b/src/qemu/qemu_process.c
>>> index 525521aaf0ca..757f5d95e0b7 100644
>>> --- a/src/qemu/qemu_process.c
>>> +++ b/src/qemu/qemu_process.c
>>> @@ -120,9 +120,6 @@ qemuProcessRemoveDomainStatus(virQEMUDriverPtr
>>> driver,
>>>  }
>>>
>>>
>>> -/* XXX figure out how to remove this */
>>> -extern virQEMUDriverPtr qemu_driver;
>>> -
>>>  /*
>>>   * This is a callback registered with a qemuAgentPtr instance,
>>>   * and to be invoked when the agent console hits an end of file
>>> @@ -518,9 +515,9 @@ qemuProcessHandleReset(qemuMonitorPtr mon
>>> ATTRIBUTE_UNUSED,
>>>  static void
>>>  qemuProcessFakeReboot(void *opaque)
>>>  {
>>> -virQEMUDriverPtr driver = qemu_driver;
>>>  virDomainObjPtr vm = opaque;
>>>  qemuDomainObjPrivatePtr priv = vm->privateData;
>>> +virQEMUDriverPtr driver = priv->driver;
>>
>> Well, storing driver in private data looks like overkill for this
>> purpose. qemuProcessFakeReboot() runs in a thread (which explains weird
>> function arguments). But in order to pass qemu driver into this function
>> we can make the function take a struct.
>> On the other hand, it might come handy (even right now) as it enables us
>> to clean up some code where we already have both priv and driver in
>> function arguments. Frankly, I'm torn. So it's up to you whether you
>> want to go this way or the one I'm suggesting.
>>
> 
> I'm perfectly fine with passing the struct and I have no problem with
> changing this that way.  The clean up of qemuProcessFakeReboot is not the
> main purpose of this clean up; it's the last patch and enabling future
> clean ups.  However, I have thought about it and when I pass the struct,
> it will eventually still get removed and it will end up in this form
> during the future clean ups.  In other words, I can pass the struct, but
> it's not needed any more since the driver will be available even without
> that =)
> 
> So I'll stick with this since you left me decide ;)

Right. We don't need both approaches. ACK to this and to 1/4 too then.
Although, let me just point out that it was difficult for me to track
that it is indeed driver that is passed as @opaque to
qemuDomainObjPrivateAlloc(). It isn't visible at the first glance.

Michal

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


Re: [libvirt] [PATCH 2/4] qemu: Save qemu driver in qemuDomainObjPrivateData

2017-07-25 Thread Martin Kletzander

On Tue, Jul 25, 2017 at 03:20:48PM +0200, Michal Privoznik wrote:

On 07/24/2017 04:09 PM, Martin Kletzander wrote:

This way we can finally make it static and not use any externs anywhere.

Signed-off-by: Martin Kletzander 
---
 src/qemu/qemu_domain.c  | 3 ++-
 src/qemu/qemu_domain.h  | 2 ++
 src/qemu/qemu_driver.c  | 2 +-
 src/qemu/qemu_process.c | 5 +
 4 files changed, 6 insertions(+), 6 deletions(-)

diff --git a/src/qemu/qemu_domain.c b/src/qemu/qemu_domain.c
index f1e144d92b64..0b7c45280321 100644
--- a/src/qemu/qemu_domain.c
+++ b/src/qemu/qemu_domain.c
@@ -1662,7 +1662,7 @@ qemuDomainClearPrivatePaths(virDomainObjPtr vm)


 static void *
-qemuDomainObjPrivateAlloc(void *opaque ATTRIBUTE_UNUSED)
+qemuDomainObjPrivateAlloc(void *opaque)
 {
 qemuDomainObjPrivatePtr priv;

@@ -1679,6 +1679,7 @@ qemuDomainObjPrivateAlloc(void *opaque ATTRIBUTE_UNUSED)
 goto error;

 priv->migMaxBandwidth = QEMU_DOMAIN_MIG_BANDWIDTH_MAX;
+priv->driver = opaque;

 return priv;

diff --git a/src/qemu/qemu_domain.h b/src/qemu/qemu_domain.h
index 365b23c96167..71567af034f5 100644
--- a/src/qemu/qemu_domain.h
+++ b/src/qemu/qemu_domain.h
@@ -217,6 +217,8 @@ struct _qemuDomainSecretInfo {
 typedef struct _qemuDomainObjPrivate qemuDomainObjPrivate;
 typedef qemuDomainObjPrivate *qemuDomainObjPrivatePtr;
 struct _qemuDomainObjPrivate {
+virQEMUDriverPtr driver;
+
 struct qemuDomainJobObj job;

 virBitmapPtr namespaces;
diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c
index 6568def156f4..9c54571cf078 100644
--- a/src/qemu/qemu_driver.c
+++ b/src/qemu/qemu_driver.c
@@ -159,7 +159,7 @@ static int qemuGetDHCPInterfaces(virDomainPtr dom,
  virDomainObjPtr vm,
  virDomainInterfacePtr **ifaces);

-virQEMUDriverPtr qemu_driver = NULL;
+static virQEMUDriverPtr qemu_driver;


 static void
diff --git a/src/qemu/qemu_process.c b/src/qemu/qemu_process.c
index 525521aaf0ca..757f5d95e0b7 100644
--- a/src/qemu/qemu_process.c
+++ b/src/qemu/qemu_process.c
@@ -120,9 +120,6 @@ qemuProcessRemoveDomainStatus(virQEMUDriverPtr driver,
 }


-/* XXX figure out how to remove this */
-extern virQEMUDriverPtr qemu_driver;
-
 /*
  * This is a callback registered with a qemuAgentPtr instance,
  * and to be invoked when the agent console hits an end of file
@@ -518,9 +515,9 @@ qemuProcessHandleReset(qemuMonitorPtr mon ATTRIBUTE_UNUSED,
 static void
 qemuProcessFakeReboot(void *opaque)
 {
-virQEMUDriverPtr driver = qemu_driver;
 virDomainObjPtr vm = opaque;
 qemuDomainObjPrivatePtr priv = vm->privateData;
+virQEMUDriverPtr driver = priv->driver;


Well, storing driver in private data looks like overkill for this
purpose. qemuProcessFakeReboot() runs in a thread (which explains weird
function arguments). But in order to pass qemu driver into this function
we can make the function take a struct.
On the other hand, it might come handy (even right now) as it enables us
to clean up some code where we already have both priv and driver in
function arguments. Frankly, I'm torn. So it's up to you whether you
want to go this way or the one I'm suggesting.



I'm perfectly fine with passing the struct and I have no problem with
changing this that way.  The clean up of qemuProcessFakeReboot is not the
main purpose of this clean up; it's the last patch and enabling future
clean ups.  However, I have thought about it and when I pass the struct,
it will eventually still get removed and it will end up in this form
during the future clean ups.  In other words, I can pass the struct, but
it's not needed any more since the driver will be available even without
that =)

So I'll stick with this since you left me decide ;)


Michal


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/3] More virsecretobj changes to prepare for common object

2017-07-25 Thread Pavel Hrdina
On Tue, Jul 25, 2017 at 09:21:52AM -0400, John Ferlan wrote:
> v2: https://www.redhat.com/archives/libvir-list/2017-July/msg00520.html
> 
> Changes in v3:
> 
> Former patch 1, dropped
> Former patch 2, pushed
> Former patch 3, adjusted:
>   -> Use @objDef instead of @objdef
>   -> Handle the if (backup) leak shown during review
> Former patch 4, split
>   -> Patch 3 handles the virsecretobj call to virSecretObjListRemove
>   -> Patch 4 handles the secret_driver calls to virSecretObjListRemove
> 
> John Ferlan (3):
>   secret: Properly handle @def after virSecretObjAdd in driver
>   secret: Fix memory leak in virSecretLoad
>   secret: Handle object list removal and deletion properly

Reviewed-by: Pavel Hrdina 


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

[libvirt] [PATCH v3 3/3] secret: Handle object list removal and deletion properly

2017-07-25 Thread John Ferlan
Rather than rely on virSecretObjEndAPI to make the final virObjectUnref
after the call to virSecretObjListRemove, be more explicit by calling
virObjectUnref and setting @obj to NULL for secretUndefine and in
the error path of secretDefineXML. Calling EndAPI will end up calling
Unlock on an already unlocked object which has indeteriminate results
(usually an ignored error).

The virSecretObjEndAPI will both Unref and Unlock the object; however,
the virSecretObjListRemove would have already Unlock'd the object so
calling Unlock again is incorrect. Once the virSecretObjListRemove
is called all that's left is to Unref our interest since that's the
corrollary to the virSecretObjListAdd which returned our ref interest
plus references for each hash table in which the object resides. In math
terms, after an Add there's 2 refs on the object (1 for the object and
1 for the list). After calling Remove there's just 1 ref on the object.
For the Add callers, calling EndAPI removes the ref for the object and
unlocks it, but since it's in a list the other 1 remains.

Signed-off-by: John Ferlan 
---
 src/secret/secret_driver.c | 4 
 1 file changed, 4 insertions(+)

diff --git a/src/secret/secret_driver.c b/src/secret/secret_driver.c
index 8defa46..d833a86 100644
--- a/src/secret/secret_driver.c
+++ b/src/secret/secret_driver.c
@@ -270,6 +270,8 @@ secretDefineXML(virConnectPtr conn,
 VIR_STEAL_PTR(def, objDef);
 } else {
 virSecretObjListRemove(driver->secrets, obj);
+virObjectUnref(obj);
+obj = NULL;
 }
 
  cleanup:
@@ -410,6 +412,8 @@ secretUndefine(virSecretPtr secret)
 virSecretObjDeleteData(obj);
 
 virSecretObjListRemove(driver->secrets, obj);
+virObjectUnref(obj);
+obj = NULL;
 
 ret = 0;
 
-- 
2.9.4

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


[libvirt] [PATCH v3 2/3] secret: Fix memory leak in virSecretLoad

2017-07-25 Thread John Ferlan
If the virSecretLoadValue fails, the code jumped to cleanup without
setting @ret = obj, thus calling virSecretObjListRemove which only
accounts for the object reference related to adding the object to
the list during virSecretObjListAdd, but does not account for the
reference to the object itself as the return of @ret would be NULL
so the caller wouldn't call virSecretObjEndAPI on the object recently
added thus reducing the refcnt to zero.

This patch will perform the ObjListRemove in the failure path of
virSecretLoadValue and Unref @obj in order to perform clean up
and return @obj as NULL. The @def will be freed as part of the
virObjectUnref.

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

diff --git a/src/conf/virsecretobj.c b/src/conf/virsecretobj.c
index 850fdaf..aa994ba 100644
--- a/src/conf/virsecretobj.c
+++ b/src/conf/virsecretobj.c
@@ -914,7 +914,6 @@ virSecretLoad(virSecretObjListPtr secrets,
 {
 virSecretDefPtr def = NULL;
 virSecretObjPtr obj = NULL;
-virSecretObjPtr ret = NULL;
 
 if (!(def = virSecretDefParseFile(path)))
 goto cleanup;
@@ -926,16 +925,15 @@ virSecretLoad(virSecretObjListPtr secrets,
 goto cleanup;
 def = NULL;
 
-if (virSecretLoadValue(obj) < 0)
-goto cleanup;
-
-ret = obj;
-obj = NULL;
+if (virSecretLoadValue(obj) < 0) {
+virSecretObjListRemove(secrets, obj);
+virObjectUnref(obj);
+obj = NULL;
+}
 
  cleanup:
-virSecretObjListRemove(secrets, obj);
 virSecretDefFree(def);
-return ret;
+return obj;
 }
 
 
-- 
2.9.4

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


[libvirt] [PATCH v3 1/3] secret: Properly handle @def after virSecretObjAdd in driver

2017-07-25 Thread John Ferlan
Since the virSecretObjListAdd technically consumes @def on success,
the secretDefineXML should set @def = NULL immediately and process
the remaining calls using a new @objDef variable. We can use use
VIR_STEAL_PTR since we know the Add function just stores @def in
obj->def.

Because we steal @def into @objDef, if we jump to restore_backup:
and @backup is set, then we need to ensure the @def would be
free'd properly, so we'll steal it back from @objDef. For the other
condition this fixes a double free of @def if the code had jumped to
@backup == NULL thus calling virSecretObjListRemove without setting
@def = NULL. In this case, the subsequent call to DefFree would
succeed and free @def; however, the call to EndAPI would also
call DefFree because the Unref done would be the last one for
the @obj meaning the obj->def would be used to call DefFree,
but it's already been free'd because @def wasn't managed right
within this error path.

Signed-off-by: John Ferlan 
---
 src/secret/secret_driver.c | 27 ++-
 1 file changed, 14 insertions(+), 13 deletions(-)

diff --git a/src/secret/secret_driver.c b/src/secret/secret_driver.c
index 30124b4..8defa46 100644
--- a/src/secret/secret_driver.c
+++ b/src/secret/secret_driver.c
@@ -210,6 +210,7 @@ secretDefineXML(virConnectPtr conn,
 {
 virSecretPtr ret = NULL;
 virSecretObjPtr obj = NULL;
+virSecretDefPtr objDef;
 virSecretDefPtr backup = NULL;
 virSecretDefPtr def;
 virObjectEventPtr event = NULL;
@@ -225,8 +226,9 @@ secretDefineXML(virConnectPtr conn,
 if (!(obj = virSecretObjListAdd(driver->secrets, def,
 driver->configDir, &backup)))
 goto cleanup;
+VIR_STEAL_PTR(objDef, def);
 
-if (!def->isephemeral) {
+if (!objDef->isephemeral) {
 if (backup && backup->isephemeral) {
 if (virSecretObjSaveData(obj) < 0)
 goto restore_backup;
@@ -248,28 +250,27 @@ secretDefineXML(virConnectPtr conn,
 /* Saved successfully - drop old values */
 virSecretDefFree(backup);
 
-event = virSecretEventLifecycleNew(def->uuid,
-   def->usage_type,
-   def->usage_id,
+event = virSecretEventLifecycleNew(objDef->uuid,
+   objDef->usage_type,
+   objDef->usage_id,
VIR_SECRET_EVENT_DEFINED,
0);
 
 ret = virGetSecret(conn,
-   def->uuid,
-   def->usage_type,
-   def->usage_id);
-def = NULL;
+   objDef->uuid,
+   objDef->usage_type,
+   objDef->usage_id);
 goto cleanup;
 
  restore_backup:
 /* If we have a backup, then secret was defined before, so just restore
- * the backup. The current def will be handled below.
- * Otherwise, this is a new secret, thus remove it.
- */
-if (backup)
+ * the backup; otherwise, this is a new secret, thus remove it. */
+if (backup) {
 virSecretObjSetDef(obj, backup);
-else
+VIR_STEAL_PTR(def, objDef);
+} else {
 virSecretObjListRemove(driver->secrets, obj);
+}
 
  cleanup:
 virSecretDefFree(def);
-- 
2.9.4

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


[libvirt] [PATCH v3 0/3] More virsecretobj changes to prepare for common object

2017-07-25 Thread John Ferlan
v2: https://www.redhat.com/archives/libvir-list/2017-July/msg00520.html

Changes in v3:

Former patch 1, dropped
Former patch 2, pushed
Former patch 3, adjusted:
  -> Use @objDef instead of @objdef
  -> Handle the if (backup) leak shown during review
Former patch 4, split
  -> Patch 3 handles the virsecretobj call to virSecretObjListRemove
  -> Patch 4 handles the secret_driver calls to virSecretObjListRemove

John Ferlan (3):
  secret: Properly handle @def after virSecretObjAdd in driver
  secret: Fix memory leak in virSecretLoad
  secret: Handle object list removal and deletion properly

 src/conf/virsecretobj.c| 14 ++
 src/secret/secret_driver.c | 31 ++-
 2 files changed, 24 insertions(+), 21 deletions(-)

-- 
2.9.4

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


Re: [libvirt] [PATCH 2/4] qemu: Save qemu driver in qemuDomainObjPrivateData

2017-07-25 Thread Michal Privoznik
On 07/24/2017 04:09 PM, Martin Kletzander wrote:
> This way we can finally make it static and not use any externs anywhere.
> 
> Signed-off-by: Martin Kletzander 
> ---
>  src/qemu/qemu_domain.c  | 3 ++-
>  src/qemu/qemu_domain.h  | 2 ++
>  src/qemu/qemu_driver.c  | 2 +-
>  src/qemu/qemu_process.c | 5 +
>  4 files changed, 6 insertions(+), 6 deletions(-)
> 
> diff --git a/src/qemu/qemu_domain.c b/src/qemu/qemu_domain.c
> index f1e144d92b64..0b7c45280321 100644
> --- a/src/qemu/qemu_domain.c
> +++ b/src/qemu/qemu_domain.c
> @@ -1662,7 +1662,7 @@ qemuDomainClearPrivatePaths(virDomainObjPtr vm)
>  
>  
>  static void *
> -qemuDomainObjPrivateAlloc(void *opaque ATTRIBUTE_UNUSED)
> +qemuDomainObjPrivateAlloc(void *opaque)
>  {
>  qemuDomainObjPrivatePtr priv;
>  
> @@ -1679,6 +1679,7 @@ qemuDomainObjPrivateAlloc(void *opaque ATTRIBUTE_UNUSED)
>  goto error;
>  
>  priv->migMaxBandwidth = QEMU_DOMAIN_MIG_BANDWIDTH_MAX;
> +priv->driver = opaque;
>  
>  return priv;
>  
> diff --git a/src/qemu/qemu_domain.h b/src/qemu/qemu_domain.h
> index 365b23c96167..71567af034f5 100644
> --- a/src/qemu/qemu_domain.h
> +++ b/src/qemu/qemu_domain.h
> @@ -217,6 +217,8 @@ struct _qemuDomainSecretInfo {
>  typedef struct _qemuDomainObjPrivate qemuDomainObjPrivate;
>  typedef qemuDomainObjPrivate *qemuDomainObjPrivatePtr;
>  struct _qemuDomainObjPrivate {
> +virQEMUDriverPtr driver;
> +
>  struct qemuDomainJobObj job;
>  
>  virBitmapPtr namespaces;
> diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c
> index 6568def156f4..9c54571cf078 100644
> --- a/src/qemu/qemu_driver.c
> +++ b/src/qemu/qemu_driver.c
> @@ -159,7 +159,7 @@ static int qemuGetDHCPInterfaces(virDomainPtr dom,
>   virDomainObjPtr vm,
>   virDomainInterfacePtr **ifaces);
>  
> -virQEMUDriverPtr qemu_driver = NULL;
> +static virQEMUDriverPtr qemu_driver;
>  
>  
>  static void
> diff --git a/src/qemu/qemu_process.c b/src/qemu/qemu_process.c
> index 525521aaf0ca..757f5d95e0b7 100644
> --- a/src/qemu/qemu_process.c
> +++ b/src/qemu/qemu_process.c
> @@ -120,9 +120,6 @@ qemuProcessRemoveDomainStatus(virQEMUDriverPtr driver,
>  }
>  
>  
> -/* XXX figure out how to remove this */
> -extern virQEMUDriverPtr qemu_driver;
> -
>  /*
>   * This is a callback registered with a qemuAgentPtr instance,
>   * and to be invoked when the agent console hits an end of file
> @@ -518,9 +515,9 @@ qemuProcessHandleReset(qemuMonitorPtr mon 
> ATTRIBUTE_UNUSED,
>  static void
>  qemuProcessFakeReboot(void *opaque)
>  {
> -virQEMUDriverPtr driver = qemu_driver;
>  virDomainObjPtr vm = opaque;
>  qemuDomainObjPrivatePtr priv = vm->privateData;
> +virQEMUDriverPtr driver = priv->driver;

Well, storing driver in private data looks like overkill for this
purpose. qemuProcessFakeReboot() runs in a thread (which explains weird
function arguments). But in order to pass qemu driver into this function
we can make the function take a struct.
On the other hand, it might come handy (even right now) as it enables us
to clean up some code where we already have both priv and driver in
function arguments. Frankly, I'm torn. So it's up to you whether you
want to go this way or the one I'm suggesting.

Michal

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


Re: [libvirt] [PATCH 3/4] lxc: Make lxcProcessStop callable even without PID being available

2017-07-25 Thread Michal Privoznik
On 07/24/2017 04:09 PM, Martin Kletzander wrote:
> This way the function can work as a central point of clean-up code and
> we don't have to duplicate code.  And it works similarly to the qemu
> driver.
> 
> Signed-off-by: Martin Kletzander 
> ---
>  src/lxc/lxc_process.c | 32 ++--
>  1 file changed, 2 insertions(+), 30 deletions(-)

ACK

Michal

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


Re: [libvirt] [PATCH 4/4] Move machineName generation from virsystemd into domain_conf

2017-07-25 Thread Michal Privoznik
On 07/24/2017 04:09 PM, Martin Kletzander wrote:
> It is more related to a domain as we might use it even when there is
> no systemd and it does not use any dbus/systemd functions.  In order
> not to use code from conf/ in util/ pass machineName in cgroups code
> as a parameter.  That also fixes a leak of machineName in the lxc
> driver and cleans up and de-duplicates some code.
> 
> Signed-off-by: Martin Kletzander 
> ---
>  src/conf/domain_conf.c   | 62 
> 
>  src/conf/domain_conf.h   |  5 
>  src/libvirt_private.syms |  2 +-
>  src/lxc/lxc_cgroup.c |  5 +---
>  src/lxc/lxc_domain.c | 19 +++
>  src/lxc/lxc_domain.h |  3 +++
>  src/lxc/lxc_process.c| 25 +--
>  src/qemu/qemu_cgroup.c   | 24 ---
>  src/qemu/qemu_domain.c   | 21 
>  src/qemu/qemu_domain.h   |  3 +++
>  src/qemu/qemu_process.c  |  6 +
>  src/util/vircgroup.c | 15 
>  src/util/vircgroup.h | 14 +--
>  src/util/virsystemd.c| 62 
> 
>  src/util/virsystemd.h|  5 
>  tests/virsystemdtest.c   |  4 ++--
>  16 files changed, 153 insertions(+), 122 deletions(-)

ACK

Michal

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


Re: [libvirt] [PATCH v2 3/4] secret: Properly handle @def after virSecretObjAdd in driver

2017-07-25 Thread Pavel Hrdina
On Tue, Jul 25, 2017 at 08:37:23AM -0400, John Ferlan wrote:
> 
> 
> On 07/25/2017 08:21 AM, Pavel Hrdina wrote:
> > On Tue, Jul 25, 2017 at 01:36:20PM +0200, Pavel Hrdina wrote:
> >> On Fri, Jul 14, 2017 at 10:04:41AM -0400, John Ferlan wrote:
> >>> Since the virSecretObjListAdd technically consumes @def on success,
> >>> the secretDefineXML should set @def = NULL immediately and process
> >>> the remaining calls using a new @objdef variable. We can use use
> >>> VIR_STEAL_PTR since we know the Add function just stores @def in
> >>> obj->def.
> >>>
> >>> This fixes a possible double free of @def if the code jumps to
> >>> restore_backup: and calls virSecretObjListRemove without setting
> >>> def = NULL. In this case, the subsequent call to DefFree would
> >>> succeed and free @def; however, the call to EndAPI would also
> >>> call DefFree because the Unref done would be the last one for
> >>> the @obj meaning the obj->def would be used to call DefFree,
> >>> but it's already been free'd because @def wasn't managed right
> >>> within this error path.
> >>>
> >>> Signed-off-by: John Ferlan 
> >>> ---
> >>>  src/secret/secret_driver.c | 19 ++-
> >>>  1 file changed, 10 insertions(+), 9 deletions(-)
> >>>
> >>> diff --git a/src/secret/secret_driver.c b/src/secret/secret_driver.c
> >>> index 30124b4..77351d8 100644
> >>> --- a/src/secret/secret_driver.c
> >>> +++ b/src/secret/secret_driver.c
> >>> @@ -210,6 +210,7 @@ secretDefineXML(virConnectPtr conn,
> >>>  {
> >>>  virSecretPtr ret = NULL;
> >>>  virSecretObjPtr obj = NULL;
> >>> +virSecretDefPtr objdef;
> >>
> >> s/objdef/objDef/
> >>
> >> Reviewed-by: Pavel Hrdina 
> > 
> > Actually this patch introduces a memory leak in case we restore the
> > @backup definition.
> > 
> > virSecretObjListAdd() adds the @def into @obj and sets the old def
> > into @backup, so far good.
> > 
> > VIR_STEAL_PTR(objdef, def) leaves the @def == NULL, still good
> > 
> > But if we in any point jump to "restore_backup" after the VIR_STEAL_PTR
> > and the @backup != NULL we simply changes the @obj->def back to @backup
> > and the new def is only in @objdef which is not freed anywhere.
> 
> I went through this in the previous review, but for the opposite
> condition where backup == NULL (repeated for ease)
> 
> Without the stealing of objdef, when return from the Add function we
> have "refcnt=2" and "lock=true".
> 
> For some reason we jump to restore_backup and call ObjListRemove which
> returns and the object refcnt=1 and lock=false.
> 
> We fall into cleanup:
> 
> Call virSecretDefFree(def) where @def != NULL, so it free's it
> Call virSecretObjEndAPI(&obj) which calls Unref, setting R=0 and calling
> virSecretDefFree(obj->def)... But wait, we already did that because we
> allowed the DefFree(def) to free something it didn't own.
> 
> 
> > 
> > Possible fix is to set @def = NULL after the virSecretObjListRemove()
> > in restore_backup:
> > 
> > ...
> > } else {
> > virSecretObjListRemove(driver->secrets, obj);
> > virObjectUnref(obj);
> > obj = NULL;
> > def = NULL;
> > }
> > ...
> > 
> 
> The other fix to the leak you point out is:
> 
> if (backup) {
> virSecretObjSetDef(obj, backup);
> def = objdef;
> } else {
> virSecretObjListRemove(driver->secrets, obj);
> }

That works for me, but still I would like to use objDef.

Pavel


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

Re: [libvirt] [PATCH v2] storage: Disallow usage of the HBA for a fc_host backing

2017-07-25 Thread Erik Skultety
On Tue, Jul 25, 2017 at 07:36:48AM -0400, John Ferlan wrote:
>
>
> On 07/25/2017 03:45 AM, Erik Skultety wrote:
> >> +/**
> >> + * @name: Name from a wwnn/wwpn lookup
> >> + *
> >> + * Validate that the @name fetched from the wwnn/wwpn is a vHBA and not
> >> + * an HBA as that should be a configuration error. It's only possible to
> >> + * use an existing wwnn/wwpn of a vHBA because that's what someone would
> >> + * have created using the node device create functionality. Using the
> >> + * HBA "just because" it has a wwnn/wwpn and the characteristics of a
> >> + * vHBA is just not valid
> >> + *
> >> + * Returns the @scsi_host_name to be used or NULL on errror

s/errror/error

...

> >> @@ -275,6 +316,7 @@ createVport(virConnectPtr conn,
> >>  virStorageAdapterFCHostPtr fchost)
> >>  {
> >>  char *name = NULL;
> >> +char *scsi_host_name = NULL;
> >>  virStoragePoolFCRefreshInfoPtr cbdata = NULL;
> >>  virThread thread;
> >>  int ret = -1;
> >> @@ -288,6 +330,9 @@ createVport(virConnectPtr conn,
> >>   * this pool and we don't have to create the vHBA
> >>   */
> >>  if ((name = virVHBAGetHostByWWN(NULL, fchost->wwnn, fchost->wwpn))) {
> >> +if (!(scsi_host_name = checkName(name)))
> >> +goto cleanup;
> >
> > Ok, so I learn from my mistakes, do you plan on building upon this in the
> > foreseeable future with a follow-up series you haven't sent yet, but have 
> > on a
> > local branch? Because if not, I don't really see a point in returning a 
> > string
> > which only gets free'd on the function exit - checkName should probably 
> > become
> > something like "isVHBA" and return boolean. And even if you do have a 
> > follow-up
> > on a local branch, I still think that converting the return value should be
> > part of that series, solely because until then, @scsi_host_name wouldn't 
> > have
> > any meaning.
> >
> > Erik
> >
>
> No this is it - I want to stop thinking about NPIV for a while... I
> returned the 'scsi_host_name' string because in my mind I had passed it
> to checkParent, but apparently I didn't do that, sigh.
>
> Does that make more sense now?

Indeed, to be honest I missed the connection between name and scsi_host_name
and thought, yeah ok makes sense (probably have seen quite a lot NPIV lately
myself)now that I see it a bit more clearly, it still left me wondering if
it wouldn't make more sense to move the scsi_host_name formatting part to
createVport (you free it here after all) right after you pass @name to
checkName/isVHBA (whatever we settle on):
- you don't need to format it prior to your checkName, since backwards
  compatibility takes care of eating "hostX" nicely
- you also don't need to report any error when virSCSIHostGetNumber fails,
  since one gets formatted already and it didn't bring much value

-> then, right after that call you actually format the "scsi_" name since you
really need it to traverse the list of devices and find the parent in
checkParent.

Erik

>
> John

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


Re: [libvirt] [PATCH v2 3/4] secret: Properly handle @def after virSecretObjAdd in driver

2017-07-25 Thread John Ferlan


On 07/25/2017 08:21 AM, Pavel Hrdina wrote:
> On Tue, Jul 25, 2017 at 01:36:20PM +0200, Pavel Hrdina wrote:
>> On Fri, Jul 14, 2017 at 10:04:41AM -0400, John Ferlan wrote:
>>> Since the virSecretObjListAdd technically consumes @def on success,
>>> the secretDefineXML should set @def = NULL immediately and process
>>> the remaining calls using a new @objdef variable. We can use use
>>> VIR_STEAL_PTR since we know the Add function just stores @def in
>>> obj->def.
>>>
>>> This fixes a possible double free of @def if the code jumps to
>>> restore_backup: and calls virSecretObjListRemove without setting
>>> def = NULL. In this case, the subsequent call to DefFree would
>>> succeed and free @def; however, the call to EndAPI would also
>>> call DefFree because the Unref done would be the last one for
>>> the @obj meaning the obj->def would be used to call DefFree,
>>> but it's already been free'd because @def wasn't managed right
>>> within this error path.
>>>
>>> Signed-off-by: John Ferlan 
>>> ---
>>>  src/secret/secret_driver.c | 19 ++-
>>>  1 file changed, 10 insertions(+), 9 deletions(-)
>>>
>>> diff --git a/src/secret/secret_driver.c b/src/secret/secret_driver.c
>>> index 30124b4..77351d8 100644
>>> --- a/src/secret/secret_driver.c
>>> +++ b/src/secret/secret_driver.c
>>> @@ -210,6 +210,7 @@ secretDefineXML(virConnectPtr conn,
>>>  {
>>>  virSecretPtr ret = NULL;
>>>  virSecretObjPtr obj = NULL;
>>> +virSecretDefPtr objdef;
>>
>> s/objdef/objDef/
>>
>> Reviewed-by: Pavel Hrdina 
> 
> Actually this patch introduces a memory leak in case we restore the
> @backup definition.
> 
> virSecretObjListAdd() adds the @def into @obj and sets the old def
> into @backup, so far good.
> 
> VIR_STEAL_PTR(objdef, def) leaves the @def == NULL, still good
> 
> But if we in any point jump to "restore_backup" after the VIR_STEAL_PTR
> and the @backup != NULL we simply changes the @obj->def back to @backup
> and the new def is only in @objdef which is not freed anywhere.

I went through this in the previous review, but for the opposite
condition where backup == NULL (repeated for ease)

Without the stealing of objdef, when return from the Add function we
have "refcnt=2" and "lock=true".

For some reason we jump to restore_backup and call ObjListRemove which
returns and the object refcnt=1 and lock=false.

We fall into cleanup:

Call virSecretDefFree(def) where @def != NULL, so it free's it
Call virSecretObjEndAPI(&obj) which calls Unref, setting R=0 and calling
virSecretDefFree(obj->def)... But wait, we already did that because we
allowed the DefFree(def) to free something it didn't own.


> 
> Possible fix is to set @def = NULL after the virSecretObjListRemove()
> in restore_backup:
> 
> ...
> } else {
> virSecretObjListRemove(driver->secrets, obj);
> virObjectUnref(obj);
> obj = NULL;
> def = NULL;
> }
> ...
> 

The other fix to the leak you point out is:

if (backup) {
virSecretObjSetDef(obj, backup);
def = objdef;
} else {
virSecretObjListRemove(driver->secrets, obj);
}

> and there is no need to have yet another @objdef.

Unless you want the other condition of having two free's of @def

> 
> Pavel
> 

John

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


Re: [libvirt] [PATCH v2 3/4] secret: Properly handle @def after virSecretObjAdd in driver

2017-07-25 Thread Pavel Hrdina
On Tue, Jul 25, 2017 at 08:23:04AM -0400, John Ferlan wrote:
> 
> 
> On 07/25/2017 07:36 AM, Pavel Hrdina wrote:
> > On Fri, Jul 14, 2017 at 10:04:41AM -0400, John Ferlan wrote:
> >> Since the virSecretObjListAdd technically consumes @def on success,
> >> the secretDefineXML should set @def = NULL immediately and process
> >> the remaining calls using a new @objdef variable. We can use use
> >> VIR_STEAL_PTR since we know the Add function just stores @def in
> >> obj->def.
> >>
> >> This fixes a possible double free of @def if the code jumps to
> >> restore_backup: and calls virSecretObjListRemove without setting
> >> def = NULL. In this case, the subsequent call to DefFree would
> >> succeed and free @def; however, the call to EndAPI would also
> >> call DefFree because the Unref done would be the last one for
> >> the @obj meaning the obj->def would be used to call DefFree,
> >> but it's already been free'd because @def wasn't managed right
> >> within this error path.
> >>
> >> Signed-off-by: John Ferlan 
> >> ---
> >>  src/secret/secret_driver.c | 19 ++-
> >>  1 file changed, 10 insertions(+), 9 deletions(-)
> >>
> >> diff --git a/src/secret/secret_driver.c b/src/secret/secret_driver.c
> >> index 30124b4..77351d8 100644
> >> --- a/src/secret/secret_driver.c
> >> +++ b/src/secret/secret_driver.c
> >> @@ -210,6 +210,7 @@ secretDefineXML(virConnectPtr conn,
> >>  {
> >>  virSecretPtr ret = NULL;
> >>  virSecretObjPtr obj = NULL;
> >> +virSecretDefPtr objdef;
> > 
> > s/objdef/objDef/
> 
> Why?  I've been using objdef in general and not the camel case one

Well, the naming convention is usually a camelCase or snake_case.
In that case other usages of objdef are not correct as well.  Yes in
this case it's easy to distinguish the two parts on the variable name,
but I still thing that camelCase is the preferred form.

Pavel

> 
> John
> > 
> > Reviewed-by: Pavel Hrdina 
> > 


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

Re: [libvirt] [PATCH v2 3/4] secret: Properly handle @def after virSecretObjAdd in driver

2017-07-25 Thread John Ferlan


On 07/25/2017 07:36 AM, Pavel Hrdina wrote:
> On Fri, Jul 14, 2017 at 10:04:41AM -0400, John Ferlan wrote:
>> Since the virSecretObjListAdd technically consumes @def on success,
>> the secretDefineXML should set @def = NULL immediately and process
>> the remaining calls using a new @objdef variable. We can use use
>> VIR_STEAL_PTR since we know the Add function just stores @def in
>> obj->def.
>>
>> This fixes a possible double free of @def if the code jumps to
>> restore_backup: and calls virSecretObjListRemove without setting
>> def = NULL. In this case, the subsequent call to DefFree would
>> succeed and free @def; however, the call to EndAPI would also
>> call DefFree because the Unref done would be the last one for
>> the @obj meaning the obj->def would be used to call DefFree,
>> but it's already been free'd because @def wasn't managed right
>> within this error path.
>>
>> Signed-off-by: John Ferlan 
>> ---
>>  src/secret/secret_driver.c | 19 ++-
>>  1 file changed, 10 insertions(+), 9 deletions(-)
>>
>> diff --git a/src/secret/secret_driver.c b/src/secret/secret_driver.c
>> index 30124b4..77351d8 100644
>> --- a/src/secret/secret_driver.c
>> +++ b/src/secret/secret_driver.c
>> @@ -210,6 +210,7 @@ secretDefineXML(virConnectPtr conn,
>>  {
>>  virSecretPtr ret = NULL;
>>  virSecretObjPtr obj = NULL;
>> +virSecretDefPtr objdef;
> 
> s/objdef/objDef/

Why?  I've been using objdef in general and not the camel case one

John
> 
> Reviewed-by: Pavel Hrdina 
> 

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


Re: [libvirt] [PATCH v2 3/4] secret: Properly handle @def after virSecretObjAdd in driver

2017-07-25 Thread Pavel Hrdina
On Tue, Jul 25, 2017 at 01:36:20PM +0200, Pavel Hrdina wrote:
> On Fri, Jul 14, 2017 at 10:04:41AM -0400, John Ferlan wrote:
> > Since the virSecretObjListAdd technically consumes @def on success,
> > the secretDefineXML should set @def = NULL immediately and process
> > the remaining calls using a new @objdef variable. We can use use
> > VIR_STEAL_PTR since we know the Add function just stores @def in
> > obj->def.
> > 
> > This fixes a possible double free of @def if the code jumps to
> > restore_backup: and calls virSecretObjListRemove without setting
> > def = NULL. In this case, the subsequent call to DefFree would
> > succeed and free @def; however, the call to EndAPI would also
> > call DefFree because the Unref done would be the last one for
> > the @obj meaning the obj->def would be used to call DefFree,
> > but it's already been free'd because @def wasn't managed right
> > within this error path.
> > 
> > Signed-off-by: John Ferlan 
> > ---
> >  src/secret/secret_driver.c | 19 ++-
> >  1 file changed, 10 insertions(+), 9 deletions(-)
> > 
> > diff --git a/src/secret/secret_driver.c b/src/secret/secret_driver.c
> > index 30124b4..77351d8 100644
> > --- a/src/secret/secret_driver.c
> > +++ b/src/secret/secret_driver.c
> > @@ -210,6 +210,7 @@ secretDefineXML(virConnectPtr conn,
> >  {
> >  virSecretPtr ret = NULL;
> >  virSecretObjPtr obj = NULL;
> > +virSecretDefPtr objdef;
> 
> s/objdef/objDef/
> 
> Reviewed-by: Pavel Hrdina 

Actually this patch introduces a memory leak in case we restore the
@backup definition.

virSecretObjListAdd() adds the @def into @obj and sets the old def
into @backup, so far good.

VIR_STEAL_PTR(objdef, def) leaves the @def == NULL, still good

But if we in any point jump to "restore_backup" after the VIR_STEAL_PTR
and the @backup != NULL we simply changes the @obj->def back to @backup
and the new def is only in @objdef which is not freed anywhere.

Possible fix is to set @def = NULL after the virSecretObjListRemove()
in restore_backup:

...
} else {
virSecretObjListRemove(driver->secrets, obj);
virObjectUnref(obj);
obj = NULL;
def = NULL;
}
...

and there is no need to have yet another @objdef.

Pavel


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

Re: [libvirt] [PATCH v2 1/4] secret: Clean up virSecretObjListAdd processing

2017-07-25 Thread John Ferlan


On 07/25/2017 07:21 AM, Pavel Hrdina wrote:
> On Fri, Jul 14, 2017 at 10:04:39AM -0400, John Ferlan wrote:
>> Make use of an error: label to handle the failure and need to call
>> virSecretObjEndAPI for the object to set it to NULL for return.
>>
>> Signed-off-by: John Ferlan 
>> ---
>>  src/conf/virsecretobj.c | 22 +++---
>>  1 file changed, 11 insertions(+), 11 deletions(-)
>>
>> diff --git a/src/conf/virsecretobj.c b/src/conf/virsecretobj.c
>> index e3bcbe5..bedcdbd 100644
>> --- a/src/conf/virsecretobj.c
>> +++ b/src/conf/virsecretobj.c
>> @@ -333,7 +333,6 @@ virSecretObjListAdd(virSecretObjListPtr secrets,
>>  {
>>  virSecretObjPtr obj;
>>  virSecretDefPtr objdef;
>> -virSecretObjPtr ret = NULL;
>>  char uuidstr[VIR_UUID_STRING_BUFLEN];
>>  char *configFile = NULL, *base64File = NULL;
>>  
>> @@ -354,13 +353,13 @@ virSecretObjListAdd(virSecretObjListPtr secrets,
>> _("a secret with UUID %s is already defined for "
>>   "use with %s"),
>> uuidstr, objdef->usage_id);
>> -goto cleanup;
>> +goto error;
>>  }
>>  
>>  if (objdef->isprivate && !newdef->isprivate) {
>>  virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
>> _("cannot change private flag on existing 
>> secret"));
>> -goto cleanup;
>> +goto error;
>>  }
>>  
>>  if (oldDef)
>> @@ -369,8 +368,9 @@ virSecretObjListAdd(virSecretObjListPtr secrets,
>>  virSecretDefFree(objdef);
>>  obj->def = newdef;
>>  } else {
>> +
>>  /* No existing secret with same UUID,
>> - * try look for matching usage instead */
>> + * try to look for matching usage instead */
>>  if ((obj = virSecretObjListFindByUsageLocked(secrets,
>>   newdef->usage_type,
>>   newdef->usage_id))) {
>> @@ -381,7 +381,7 @@ virSecretObjListAdd(virSecretObjListPtr secrets,
>> _("a secret with UUID %s already defined for "
>>   "use with %s"),
>> uuidstr, newdef->usage_id);
>> -goto cleanup;
>> +goto error;
>>  }
>>  
>>  /* Generate the possible configFile and base64File strings
>> @@ -395,7 +395,7 @@ virSecretObjListAdd(virSecretObjListPtr secrets,
>>  goto cleanup;
>>  
>>  if (virHashAddEntry(secrets->objs, uuidstr, obj) < 0)
>> -goto cleanup;
>> +goto error;
>>  
>>  obj->def = newdef;
>>  VIR_STEAL_PTR(obj->configFile, configFile);
>> @@ -403,15 +403,15 @@ virSecretObjListAdd(virSecretObjListPtr secrets,
>>  virObjectRef(obj);
>>  }
>>  
>> -ret = obj;
>> -obj = NULL;
>> -
>>   cleanup:
>> -virSecretObjEndAPI(&obj);
>>  VIR_FREE(configFile);
>>  VIR_FREE(base64File);
>>  virObjectUnlock(secrets);
>> -return ret;
>> +return obj;
>> +
>> + error:
>> +virSecretObjEndAPI(&obj);
>> +goto cleanup;
> 
> I don't see what's wrong with the current code, it's commonly used
> pattern to steal the pointer.  The extra error label would make sense
> if the error path would be more complex, but in this case it doesn't
> add any value.
> 
> Pavel
> 

Fine - I'll drop this one then.

John

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


Re: [libvirt] [PATCH 2/3] virobject: Introduce virObjectRWLockable

2017-07-25 Thread John Ferlan


On 07/25/2017 03:45 AM, Michal Privoznik wrote:
> On 07/24/2017 05:22 PM, John Ferlan wrote:
>> [...]
>>
>>>  /**
>>>   * virObjectLock:
>>> - * @anyobj: any instance of virObjectLockablePtr
>>> + * @anyobj: any instance of virObjectLockable or virObjectRWLockable
>>>   *
>>> - * Acquire a lock on @anyobj. The lock must be
>>> - * released by virObjectUnlock.
>>> + * Acquire a lock on @anyobj. The lock must be released by
>>> + * virObjectUnlock. In case the passed object is instance of
>>> + * virObjectRWLockable a write lock is acquired.
>>>   *
>>>   * The caller is expected to have acquired a reference
>>>   * on the object before locking it (eg virObjectRef).
>>> @@ -340,31 +382,69 @@ virObjectGetLockableObj(void *anyobj)
>>>  void
>>>  virObjectLock(void *anyobj)
>>>  {
>>> -virObjectLockablePtr obj = virObjectGetLockableObj(anyobj);
>>> +if (virObjectIsClass(anyobj, virObjectLockableClass)) {
>>> +virObjectLockablePtr obj = anyobj;
>>> +virMutexLock(&obj->lock);
>>> +} else if (virObjectIsClass(anyobj, virObjectRWLockableClass)) {
>>> +virObjectRWLockablePtr obj = anyobj;
>>> +virRWLockWrite(&obj->lock);
>>> +} else {
>>> +virObjectPtr obj = anyobj;
>>> +VIR_WARN("Object %p (%s) is not a virObjectLockable "
>>> + "nor virObjectRWLockable instance",
>>> + anyobj, obj ? obj->klass->name : "(unknown)");
>>> +}
>>> +}
>>>  
>>> -if (!obj)
>>> -return;
>>>  
>>> -virMutexLock(&obj->lock);
>>> +/**
>>> + * virObjectLockRead:
>>> + * @anyobj: any instance of virObjectRWLockablePtr
>>> + *
>>> + * Acquire a read lock on @anyobj. The lock must be
>>> + * released by virObjectUnlock.
>>> + *
>>> + * The caller is expected to have acquired a reference
>>> + * on the object before locking it (eg virObjectRef).
>>> + * The object must be unlocked before releasing this
>>> + * reference.
>>> + */
>>> +void
>>> +virObjectLockRead(void *anyobj)
>>> +{
>>> +if (virObjectIsClass(anyobj, virObjectRWLockableClass)) {
>>> +virObjectRWLockablePtr obj = anyobj;
>>> +virRWLockRead(&obj->lock);
>>> +} else {
>>> +virObjectPtr obj = anyobj;
>>> +VIR_WARN("Object %p (%s) is not a virObjectRWLockable instance",
>>> + anyobj, obj ? obj->klass->name : "(unknown)");
>>> +}
>>>  }
>>>  
>>
>> Hopefully no one "confuses" which object is which or no one starts using
>> virObjectLockRead for a virObjectLockable and expects that read lock to
>> be in place (or error out) or gasp actually wait for a write lock to
>> release the lock as this does not error out.
> 
> This could have already happened if one would pass bare virObject to
> virObjectLock().
> 

Consider passing a non virObject (such as what happened during an early
change to the code for me - a virHashTablePtr) to virObjectLock...

In any case, we'll have to be more vigilant now to know that only
ObjList @obj's for virdomainobjlist can use this new API. Longer term
I'll adjust to use them.

>>
>> This is a danger in the long term assumption of having a void function
>> that has callers that can make the assumption that upon return the Lock
>> really was taken.
> 
> Well, I agree that this is one more thing to be cautious about, but no
> more than making sure object passed to virObjectLock() is virObjectLockable.
> 

There are some ugly ways to handle this including using some kind of
macro for virObjectLock that would force an abort of some sort. We have
been "fortunate" to have well behaved and reviewed code, but with two
lock API's now it's just one of those things to keep track of for reviews.

>>
>> Perhaps the better way to attack this would have been to create a
>> virObjectLockWrite() function called only from vir*ObjListAdd and
>> vir*ObjListRemove leaving the other virObjectLock()'s in tact and having
>> the virObjectLock() code make the decision over whether to use the
>> virRWLockRead or virMutexLock depending on the object class.
> 
> What's the difference? If virObjectLock() does what you're suggesting
> (what indeed is implemented too), what's the point in having
> virObjectLockWrite()?
> 
> Michal
> 

1. Less code and a lock that could check status... I understand not
wanting to modify 10 callers to check status, but modifying two and thus
making it clearer to the caller that these are "different" might not be
a bad thing.

2. The "default" action being more consumers probably will use the Read
locks (as I believe is the premise/impetus of the series). The
Add/Remove would seemingly be used less and thus the exception. So why
not have the default for ObjList/virObjectRWLockableClass be to have the
virObjectLock use a virRWLockRead instead of virRWLockWrite?


What's done is done - I obviously have ulterior motives to not wanting
virobject to change that much, but I've been considering the downside of
the code that has void functions that really don't return a lock on the
object if the 

[libvirt] [PATCH glib] Don't set LC_ALL=C during build as that breaks python apps

2017-07-25 Thread Daniel P. Berrange
Setting LC_ALL=C breaks python apps doing I/O on UTF-8 source
files. In particular this broke glib-mkenums

  GEN  libvirt-gconfig-enum-types.h
Traceback (most recent call last):
  File "/usr/bin/glib-mkenums", line 669, in 
process_file(fname)
  File "/usr/bin/glib-mkenums", line 406, in process_file
line = curfile.readline()
  File "/usr/lib64/python3.6/encodings/ascii.py", line 26, in decode
return codecs.ascii_decode(input, self.errors)[0]
UnicodeDecodeError: 'ascii' codec can't decode byte 0xc3 in position 849: 
ordinal not in range(128)

Signed-off-by: Daniel P. Berrange 
---

Pushed to fix rawhide build

 maint.mk | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/maint.mk b/maint.mk
index 405c6d0..ef72b4f 100644
--- a/maint.mk
+++ b/maint.mk
@@ -117,8 +117,8 @@ news-check-lines-spec ?= 1,10
 news-check-regexp ?= '^\*.* $(VERSION_REGEXP) \($(today)\)'
 
 # Prevent programs like 'sort' from considering distinct strings to be equal.
-# Doing it here saves us from having to set LC_ALL elsewhere in this file.
-export LC_ALL = C
+# Doing it here saves us from having to set LC_COLLATE elsewhere in this file.
+export LC_COLLATE = C
 
 ## --- ##
 ## Sanity checks.  ##
-- 
2.13.3

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


Re: [libvirt] [PATCH v2 4/4] secret: Handle object list removal and deletion properly

2017-07-25 Thread Pavel Hrdina
On Fri, Jul 14, 2017 at 10:04:42AM -0400, John Ferlan wrote:
> Rather than rely on virSecretObjEndAPI to make the final virObjectUnref
> after the call to virSecretObjListRemove, be more explicit by calling
> virObjectUnref and setting @obj to NULL for secretUndefine and in
> the error path of secretDefineXML. Calling EndAPI will end up calling
> Unlock on an already unlocked object which has indeteriminate results
> (usually an ignored error).
> 
> The virSecretObjEndAPI will both Unref and Unlock the object; however,
> the virSecretObjListRemove would have already Unlock'd the object so
> calling Unlock again is incorrect. Once the virSecretObjListRemove
> is called all that's left is to Unref our interest since that's the
> corrollary to the virSecretObjListAdd which returned our ref interest
> plus references for each hash table in which the object resides. In math
> terms, after an Add there's 2 refs on the object (1 for the object and
> 1 for the list). After calling Remove there's just 1 ref on the object.
> For the Add callers, calling EndAPI removes the ref for the object and
> unlocks it, but since it's in a list the other 1 remains.
> 
> This also fixes a leak during virSecretLoad if the virSecretLoadValue
> fails the code jumps to cleanup without setting @ret = obj, thus calling
> virSecretObjListRemove which only accounts for the object reference
> related to adding the object to the list during virSecretObjListAdd,
> but does not account for the reference to the object itself as the
> return of @ret would be NULL so the caller wouldn't call virSecretObjEndAPI
> on the object recently added thus reducing the refcnt to zero. Thus
> cleaning up the virSecretLoadValue error path to make it clearer what
> needs to be done on failure.
> 
> Signed-off-by: John Ferlan 
> ---
>  src/conf/virsecretobj.c| 14 ++
>  src/secret/secret_driver.c |  9 +++--
>  2 files changed, 13 insertions(+), 10 deletions(-)
> 
> diff --git a/src/conf/virsecretobj.c b/src/conf/virsecretobj.c
> index dd36ce6..0e7675e 100644
> --- a/src/conf/virsecretobj.c
> +++ b/src/conf/virsecretobj.c
> @@ -914,7 +914,6 @@ virSecretLoad(virSecretObjListPtr secrets,
>  {
>  virSecretDefPtr def = NULL;
>  virSecretObjPtr obj = NULL;
> -virSecretObjPtr ret = NULL;
>  
>  if (!(def = virSecretDefParseFile(path)))
>  goto cleanup;
> @@ -926,16 +925,15 @@ virSecretLoad(virSecretObjListPtr secrets,
>  goto cleanup;
>  def = NULL;
>  
> -if (virSecretLoadValue(obj) < 0)
> -goto cleanup;
> -
> -ret = obj;
> -obj = NULL;
> +if (virSecretLoadValue(obj) < 0) {
> +virSecretObjListRemove(secrets, obj);
> +virObjectUnref(obj);
> +obj = NULL;
> +}
>  
>   cleanup:
> -virSecretObjListRemove(secrets, obj);
>  virSecretDefFree(def);
> -return ret;
> +return obj;
>  }

This should be split into two separate patches, the first part that
fixes virSecretLoad() address memory leak and the second part for
secretDefineXML() and secretUndefine() fixes a double unlock.

Pavel

>  
>  
> diff --git a/src/secret/secret_driver.c b/src/secret/secret_driver.c
> index 77351d8..19ba6fd 100644
> --- a/src/secret/secret_driver.c
> +++ b/src/secret/secret_driver.c
> @@ -267,10 +267,13 @@ secretDefineXML(virConnectPtr conn,
>   * the backup. The current def will be Free'd below.
>   * Otherwise, this is a new secret, thus remove it.
>   */
> -if (backup)
> +if (backup) {
>  virSecretObjSetDef(obj, backup);
> -else
> +} else {
>  virSecretObjListRemove(driver->secrets, obj);
> +virObjectUnref(obj);
> +obj = NULL;
> +}
>  
>   cleanup:
>  virSecretDefFree(def);
> @@ -410,6 +413,8 @@ secretUndefine(virSecretPtr secret)
>  virSecretObjDeleteData(obj);
>  
>  virSecretObjListRemove(driver->secrets, obj);
> +virObjectUnref(obj);
> +obj = NULL;
>  
>  ret = 0;
>  
> -- 
> 2.9.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 v2] storage: Disallow usage of the HBA for a fc_host backing

2017-07-25 Thread John Ferlan


On 07/25/2017 03:45 AM, Erik Skultety wrote:
>> +/**
>> + * @name: Name from a wwnn/wwpn lookup
>> + *
>> + * Validate that the @name fetched from the wwnn/wwpn is a vHBA and not
>> + * an HBA as that should be a configuration error. It's only possible to
>> + * use an existing wwnn/wwpn of a vHBA because that's what someone would
>> + * have created using the node device create functionality. Using the
>> + * HBA "just because" it has a wwnn/wwpn and the characteristics of a
>> + * vHBA is just not valid
>> + *
>> + * Returns the @scsi_host_name to be used or NULL on errror
>> + */
>> +static char *
>> +checkName(const char *name)
>> +{
>> +char *scsi_host_name = NULL;
>> +unsigned int host_num;
>> +
>> +if (virAsprintf(&scsi_host_name, "scsi_%s", name) < 0)
>> +return NULL;
>> +
>> +if (virSCSIHostGetNumber(scsi_host_name, &host_num) < 0) {
>> +virReportError(VIR_ERR_INTERNAL_ERROR,
>> +   _("host name '%s' is not properly formatted"),
>> +   name);
>> +goto error;
>> +}
>> +
>> +/* If scsi_host_name is vport capable, then it's an HBA. This is
>> + * a configuration error as the wwnn/wwpn should only be for a vHBA */
>> +if (virVHBAIsVportCapable(NULL, host_num)) {
>> +virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
>> +   _("the wwnn/wwpn for '%s' are assigned to an HBA"),
>> +   scsi_host_name);
>> +goto error;
>> +}
>> +
>> +return scsi_host_name;
>> +
>> + error:
>> +VIR_FREE(scsi_host_name);
>> +return NULL;
>> +}
>> +
> 
> ...
> 
>> @@ -275,6 +316,7 @@ createVport(virConnectPtr conn,
>>  virStorageAdapterFCHostPtr fchost)
>>  {
>>  char *name = NULL;
>> +char *scsi_host_name = NULL;
>>  virStoragePoolFCRefreshInfoPtr cbdata = NULL;
>>  virThread thread;
>>  int ret = -1;
>> @@ -288,6 +330,9 @@ createVport(virConnectPtr conn,
>>   * this pool and we don't have to create the vHBA
>>   */
>>  if ((name = virVHBAGetHostByWWN(NULL, fchost->wwnn, fchost->wwpn))) {
>> +if (!(scsi_host_name = checkName(name)))
>> +goto cleanup;
> 
> Ok, so I learn from my mistakes, do you plan on building upon this in the
> foreseeable future with a follow-up series you haven't sent yet, but have on a
> local branch? Because if not, I don't really see a point in returning a string
> which only gets free'd on the function exit - checkName should probably become
> something like "isVHBA" and return boolean. And even if you do have a 
> follow-up
> on a local branch, I still think that converting the return value should be
> part of that series, solely because until then, @scsi_host_name wouldn't have
> any meaning.
> 
> Erik
> 

No this is it - I want to stop thinking about NPIV for a while... I
returned the 'scsi_host_name' string because in my mind I had passed it
to checkParent, but apparently I didn't do that, sigh.

Does that make more sense now?

John

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


Re: [libvirt] [PATCH v2 3/4] secret: Properly handle @def after virSecretObjAdd in driver

2017-07-25 Thread Pavel Hrdina
On Fri, Jul 14, 2017 at 10:04:41AM -0400, John Ferlan wrote:
> Since the virSecretObjListAdd technically consumes @def on success,
> the secretDefineXML should set @def = NULL immediately and process
> the remaining calls using a new @objdef variable. We can use use
> VIR_STEAL_PTR since we know the Add function just stores @def in
> obj->def.
> 
> This fixes a possible double free of @def if the code jumps to
> restore_backup: and calls virSecretObjListRemove without setting
> def = NULL. In this case, the subsequent call to DefFree would
> succeed and free @def; however, the call to EndAPI would also
> call DefFree because the Unref done would be the last one for
> the @obj meaning the obj->def would be used to call DefFree,
> but it's already been free'd because @def wasn't managed right
> within this error path.
> 
> Signed-off-by: John Ferlan 
> ---
>  src/secret/secret_driver.c | 19 ++-
>  1 file changed, 10 insertions(+), 9 deletions(-)
> 
> diff --git a/src/secret/secret_driver.c b/src/secret/secret_driver.c
> index 30124b4..77351d8 100644
> --- a/src/secret/secret_driver.c
> +++ b/src/secret/secret_driver.c
> @@ -210,6 +210,7 @@ secretDefineXML(virConnectPtr conn,
>  {
>  virSecretPtr ret = NULL;
>  virSecretObjPtr obj = NULL;
> +virSecretDefPtr objdef;

s/objdef/objDef/

Reviewed-by: Pavel Hrdina 


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

Re: [libvirt] [PATCH v2 2/4] secret: Remove need for local configFile and base64File in ObjectAdd

2017-07-25 Thread Pavel Hrdina
On Fri, Jul 14, 2017 at 10:04:40AM -0400, John Ferlan wrote:
> Rather than assign to a local variable, let's just assign directly to the
> object using the error path for cleanup.
> 
> Signed-off-by: John Ferlan 
> ---
>  src/conf/virsecretobj.c | 17 ++---
>  1 file changed, 6 insertions(+), 11 deletions(-)

Reviewed-by: Pavel Hrdina 


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

Re: [libvirt] [PATCH v2 1/4] secret: Clean up virSecretObjListAdd processing

2017-07-25 Thread Pavel Hrdina
On Fri, Jul 14, 2017 at 10:04:39AM -0400, John Ferlan wrote:
> Make use of an error: label to handle the failure and need to call
> virSecretObjEndAPI for the object to set it to NULL for return.
> 
> Signed-off-by: John Ferlan 
> ---
>  src/conf/virsecretobj.c | 22 +++---
>  1 file changed, 11 insertions(+), 11 deletions(-)
> 
> diff --git a/src/conf/virsecretobj.c b/src/conf/virsecretobj.c
> index e3bcbe5..bedcdbd 100644
> --- a/src/conf/virsecretobj.c
> +++ b/src/conf/virsecretobj.c
> @@ -333,7 +333,6 @@ virSecretObjListAdd(virSecretObjListPtr secrets,
>  {
>  virSecretObjPtr obj;
>  virSecretDefPtr objdef;
> -virSecretObjPtr ret = NULL;
>  char uuidstr[VIR_UUID_STRING_BUFLEN];
>  char *configFile = NULL, *base64File = NULL;
>  
> @@ -354,13 +353,13 @@ virSecretObjListAdd(virSecretObjListPtr secrets,
> _("a secret with UUID %s is already defined for "
>   "use with %s"),
> uuidstr, objdef->usage_id);
> -goto cleanup;
> +goto error;
>  }
>  
>  if (objdef->isprivate && !newdef->isprivate) {
>  virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
> _("cannot change private flag on existing 
> secret"));
> -goto cleanup;
> +goto error;
>  }
>  
>  if (oldDef)
> @@ -369,8 +368,9 @@ virSecretObjListAdd(virSecretObjListPtr secrets,
>  virSecretDefFree(objdef);
>  obj->def = newdef;
>  } else {
> +
>  /* No existing secret with same UUID,
> - * try look for matching usage instead */
> + * try to look for matching usage instead */
>  if ((obj = virSecretObjListFindByUsageLocked(secrets,
>   newdef->usage_type,
>   newdef->usage_id))) {
> @@ -381,7 +381,7 @@ virSecretObjListAdd(virSecretObjListPtr secrets,
> _("a secret with UUID %s already defined for "
>   "use with %s"),
> uuidstr, newdef->usage_id);
> -goto cleanup;
> +goto error;
>  }
>  
>  /* Generate the possible configFile and base64File strings
> @@ -395,7 +395,7 @@ virSecretObjListAdd(virSecretObjListPtr secrets,
>  goto cleanup;
>  
>  if (virHashAddEntry(secrets->objs, uuidstr, obj) < 0)
> -goto cleanup;
> +goto error;
>  
>  obj->def = newdef;
>  VIR_STEAL_PTR(obj->configFile, configFile);
> @@ -403,15 +403,15 @@ virSecretObjListAdd(virSecretObjListPtr secrets,
>  virObjectRef(obj);
>  }
>  
> -ret = obj;
> -obj = NULL;
> -
>   cleanup:
> -virSecretObjEndAPI(&obj);
>  VIR_FREE(configFile);
>  VIR_FREE(base64File);
>  virObjectUnlock(secrets);
> -return ret;
> +return obj;
> +
> + error:
> +virSecretObjEndAPI(&obj);
> +goto cleanup;

I don't see what's wrong with the current code, it's commonly used
pattern to steal the pointer.  The extra error label would make sense
if the error path would be more complex, but in this case it doesn't
add any value.

Pavel


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

[libvirt] [PATCH] docs: Add "PCI topology and hotplug" guidelines

2017-07-25 Thread Andrea Bolognani
For all machine types except i440fx, making a guest hotplug
capable requires some sort of planning. Add some information
to help users make educated choices when defining the PCI
topology of guests.

Signed-off-by: Andrea Bolognani 
---
 docs/formatdomain.html.in |   4 +-
 docs/pci-hotplug.html.in  | 164 ++
 2 files changed, 167 insertions(+), 1 deletion(-)
 create mode 100644 docs/pci-hotplug.html.in

diff --git a/docs/formatdomain.html.in b/docs/formatdomain.html.in
index bceddd2..7c4450c 100644
--- a/docs/formatdomain.html.in
+++ b/docs/formatdomain.html.in
@@ -3505,7 +3505,9 @@
   appear more than once, with a group of virtual devices tied to a
   virtual controller.  Normally, libvirt can automatically infer such
   controllers without requiring explicit XML markup, but sometimes
-  it is necessary to provide an explicit controller element.
+  it is necessary to provide an explicit controller element, notably
+  when planning the PCI topology
+  for guests where device hotplug is expected.
 
 
 
diff --git a/docs/pci-hotplug.html.in b/docs/pci-hotplug.html.in
new file mode 100644
index 000..f3d1610
--- /dev/null
+++ b/docs/pci-hotplug.html.in
@@ -0,0 +1,164 @@
+
+http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd";>
+http://www.w3.org/1999/xhtml";>
+  
+PCI topology and hotplug
+
+
+
+
+  Perhaps surprisingly, most libvirt guests support only limited PCI
+  device hotplug out of the box, or even none at all.
+
+
+  The reason for this apparent limitation is the fact that each
+  hotplugged PCI device might require additional PCI controllers to
+  be added to the guest, and libvirt has no way of knowing in advance
+  how many devices will be hotplugged during the guest's lifetime,
+  thus making it impossible to automatically provide the right amount
+  of PCI controllers: any arbitrary number would end up being too big
+  for some users, and too small for others.
+
+
+  Ultimately, the user is the only one who knows how much the guest
+  will need to grow dynamically, so the responsability of planning
+  a suitabile PCI topology in advance falls on them.
+
+
+  This document aims at providing all the information needed to
+  successfully plan the PCI topology of a guest. Note that the
+  details can vary a lot between architectures and even machine
+  types, hence the way it's organized.
+
+
+x86_64 architecture
+
+q35 machine type
+
+
+  This is a PCI Express native machine type. The default PCI topology
+  looks like
+
+
+
+
+
+  
+  
+  
+ + + + and supports hotplugging a single PCI Express device, either + emulated or assigned from the host. + + + Slots on the pcie-root controller do not support + hotplug, so the device will be hotplugged into the + pcie-root-port controller. If you plan to hotplug + more than a single PCI Express device, you should add a suitable + number of pcie-root-port controllers when defining + the guest: for example, add + + + + + + + + + if you expect to hotplug up to three PCI Express devices, + either emulated or assigned from the host. That's all the + information you need to provide: libvirt will fill in the + remaining details automatically. + + + If you expect to hotplug legacy PCI devices, then you will need + specialized controllers, since all those mentioned above are + intended for PCI Express devices only: add + + + + + + + + and you'll be able to hotplug up to 31 legacy PCI devices, + either emulated or assigned from the host. + + +i440fx (pc) machine type + + + This is a legacy PCI native machine type. The default PCI + topology looks like + + + + + + + where each of the 31 slots on the pci-root + controller is hotplug capable and can accept a legacy PCI + device, either emulated or assigned from the guest. + + +ppc64 architecture + +pseries machine type + + + The default PCI topology for the pseries machine + type looks like + + + + + + + + + + The 31 slots on a pci-root controller are all + h

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

2017-07-25 Thread Pavel Hrdina
On Thu, Jun 22, 2017 at 10:02:30AM -0400, John Ferlan wrote:

Let's move the discussion [1] into correct place.

> Still, I must be missing something. Why is it wrong to create a new
> object that would have a specific use? virObjectLockable was created at
> some point in history and then used as a way to provide locking for a
> virObject that only had a @ref. Someone could still create a virObject
> as well and just get @refs. With the new objects based on those two
> objects you get a few more features that allow for add, search, lookup,
> remove.  But you call that wrong, which is confusing to me.

What's wrong, or better wording, what I don't like personally about this
approach is that in order to have features like add, search, lookup,
remove it would require that the object is derived from
virObjectLookupKeys.  The only thing it adds to the simple virObject
is two variables @uuid and @name.

We don't need the virObjectLookupKeys object at all.

For example, current add/remove API is:


 virObjectLookupHashNew 

virObjectLookupHashNew(virClassPtr klass,
   int tableElemsStart);

could be

virObjectListNew(int tableSize,
 bool useName,
 bool useUUID);

or

typedef enum {
VIR_OBJECT_LIST_TABLE_NAME = (1 << 0),
VIR_OBJECT_LIST_TABLE_UUID = (1 << 1),
} virObjectListTableType;

virObjectListNew(int tableSize,
 unsigned int flags);

I don't see why the virObjectLookupHashNew() has to have the @klass
parameter and the @tableElemsStart is not correct, it's not the number
of elements, it's has table size.


 virObjectLookupHash(Add|Remove) 

virObjectLookupHashAdd(void *tableobj,
   virObjectLookupKeysPtr obj);

virObjectLookupHashRemove(void *tableobj,
  virObjectLookupKeysPtr obj);

The only difference without the virObjectLookupKeys object would be
that the API will take two more parameters to give it the @uuid and
@name.

virObjectListAdd(virObjectListPtr listObj,
 void *obj,
 const char *name,
 const char *uuid);

virObjectListRemove(virObjectListPtr listObj,
const char *name,
const char *uuid);

or

virObjectListRemoveByName(virObjectListPtr listObj,
  const char *name);
virObjectListRemoveByUUID(virObjectListPtr listObj,
  const char *uuid);

Yes, at first it may looks worse, but on the other hand it gives you
better flexibility in the way that the object added/removed from the
list doesn't even have to have the exact same variables and it will
work with every object that is derived from virObject.


 virObjectLookupHashFind 

virObjectLookupHashFind(void *tableobj,
bool useUUID,
const char *key);

could be split into two APIs:

virObjectListFindByName(virObjectListPtr listObj,
const char *name);
virObjectListFindByUUID(virObjectListPtr listObj,
const char *UUID);

Which in my opinion is way better than having a single API with a
boolean parameter that switches what type of key it is.


 virObjectLookupHashForEach 

virObjectLookupHashForEach(void *tableobj,
   bool useUUID,
   virHashIterator callback,
   virObjectLookupHashForEachDataPtr data);

could be

virObjectListForEach(virObjectListPtr listObj,
 virHashIterator callback,
 void *callbackData);

There are two things that I don't like.  There is no need to have the
@useUUID because both tables should contain the same objects if both are
used so this can be hidden from the user and the API will simply use one
of the available tables.  The second issue is that this API forces you
to use some predefined data structure and you cannot create your own
specifically tailored for the task that you are about to do.

The @useUUID argument also applies to virObjectLookupHashSearch().




The usage of the virObjectList* APIs could be something like this:

virObjectListPtr
virInterfaceObjListNew(void) {
return virObjectListNew(10, VIR_OBJECT_LIST_TABLE_NAME);
}

static virInterfaceObjPtr
virInterfaceObjListFindByName(virObjectListPtr interfaces,
  const char *name)
{
return virObjectListFindByName(interfaces, name);
}

Pavel


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

Re: [libvirt] [PATCH] Revert "virthread: Introduce virRWLockInitPreferWriter"

2017-07-25 Thread Daniel P. Berrange
On Tue, Jul 25, 2017 at 10:43:50AM +0200, Michal Privoznik wrote:
> This reverts commit 328bd24443d2a345a5832ee48ebba0208f8036ea.
> 
> As it turns out, this is not portable and very Linux & glibc
> specific. Worse, this may lead to not starving writers on Linux
> but everywhere else. Revert this and if the starvation occurs
> resolve it.
> 
> Signed-off-by: Michal Privoznik 

Reviewed-by: Daniel P. Berrange 



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] Revert "virthread: Introduce virRWLockInitPreferWriter"

2017-07-25 Thread Michal Privoznik
This reverts commit 328bd24443d2a345a5832ee48ebba0208f8036ea.

As it turns out, this is not portable and very Linux & glibc
specific. Worse, this may lead to not starving writers on Linux
but everywhere else. Revert this and if the starvation occurs
resolve it.

Signed-off-by: Michal Privoznik 
---
 src/libvirt_private.syms |  1 -
 src/util/virobject.c |  2 +-
 src/util/virthread.c | 35 ---
 src/util/virthread.h |  1 -
 4 files changed, 1 insertion(+), 38 deletions(-)

diff --git a/src/libvirt_private.syms b/src/libvirt_private.syms
index 3cc6f4c6e..d98417678 100644
--- a/src/libvirt_private.syms
+++ b/src/libvirt_private.syms
@@ -2733,7 +2733,6 @@ virMutexUnlock;
 virOnce;
 virRWLockDestroy;
 virRWLockInit;
-virRWLockInitPreferWriter;
 virRWLockRead;
 virRWLockUnlock;
 virRWLockWrite;
diff --git a/src/util/virobject.c b/src/util/virobject.c
index 4236abfef..b1bb378b4 100644
--- a/src/util/virobject.c
+++ b/src/util/virobject.c
@@ -275,7 +275,7 @@ virObjectRWLockableNew(virClassPtr klass)
 if (!(obj = virObjectNew(klass)))
 return NULL;
 
-if (virRWLockInitPreferWriter(&obj->lock) < 0) {
+if (virRWLockInit(&obj->lock) < 0) {
 virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
_("Unable to initialize RW lock"));
 virObjectUnref(obj);
diff --git a/src/util/virthread.c b/src/util/virthread.c
index a8dd72f8b..6c495158f 100644
--- a/src/util/virthread.c
+++ b/src/util/virthread.c
@@ -95,15 +95,6 @@ void virMutexUnlock(virMutexPtr m)
 }
 
 
-/**
- * virRWLockInit:
- * @m: rwlock to init
- *
- * Initializes RW lock using pthread default attributes (which
- * is PTHREAD_RWLOCK_PREFER_READER_NP).
- *
- * Returns 0 on success, -1 otherwise.
- */
 int virRWLockInit(virRWLockPtr m)
 {
 int ret;
@@ -115,32 +106,6 @@ int virRWLockInit(virRWLockPtr m)
 return 0;
 }
 
-
-/**
- * virRWLockInitPreferWriter:
- * @m: rwlock to init
- *
- * Initializes RW lock which prefers writers over readers.
- *
- * Returns 0 on success, -1 otherwise.
- */
-int virRWLockInitPreferWriter(virRWLockPtr m)
-{
-int ret;
-pthread_rwlockattr_t attr;
-
-pthread_rwlockattr_init(&attr);
-pthread_rwlockattr_setkind_np(&attr, 
PTHREAD_RWLOCK_PREFER_WRITER_NONRECURSIVE_NP);
-ret = pthread_rwlock_init(&m->lock, &attr);
-pthread_rwlockattr_destroy(&attr);
-if (ret != 0) {
-errno = ret;
-return -1;
-}
-return 0;
-}
-
-
 void virRWLockDestroy(virRWLockPtr m)
 {
 pthread_rwlock_destroy(&m->lock);
diff --git a/src/util/virthread.h b/src/util/virthread.h
index 18b785af2..e466d9bf0 100644
--- a/src/util/virthread.h
+++ b/src/util/virthread.h
@@ -136,7 +136,6 @@ void virMutexUnlock(virMutexPtr m);
 
 
 int virRWLockInit(virRWLockPtr m) ATTRIBUTE_RETURN_CHECK;
-int virRWLockInitPreferWriter(virRWLockPtr m) ATTRIBUTE_RETURN_CHECK;
 void virRWLockDestroy(virRWLockPtr m);
 
 void virRWLockRead(virRWLockPtr m);
-- 
2.13.0

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


Re: [libvirt] [PATCH 1/3] virthread: Introduce virRWLockInitPreferWriter

2017-07-25 Thread Daniel P. Berrange
On Mon, Jul 24, 2017 at 01:12:59PM -0400, John Ferlan wrote:
> 
> 
> On 07/19/2017 10:31 AM, Michal Privoznik wrote:
> > We already have virRWLockInit. But this uses pthread defaults
> > which prefer reader to initialize the RW lock. This may lead to
> > writer starvation. Therefore we need to have the counterpart that
> > prefers writers. Now, according to the
> > pthread_rwlockattr_setkind_np() man page setting
> > PTHREAD_RWLOCK_PREFER_WRITER_NP attribute is no-op. Therefore we
> > need to use PTHREAD_RWLOCK_PREFER_WRITER_NONRECURSIVE_NP
> > attribute. So much for good enum value names.
> > 
> > Signed-off-by: Michal Privoznik 
> > ---
> >  src/libvirt_private.syms |  1 +
> >  src/util/virthread.c | 35 +++
> >  src/util/virthread.h |  1 +
> >  3 files changed, 37 insertions(+)
> > 
> 
> This has broken the CI build, freebsd is not happy:
> 
> ../../src/util/virthread.c:133:42: error: use of undeclared identifier
> 'PTHREAD_RWLOCK_PREFER_WRITER_NONRECURSIVE_NP'
> pthread_rwlockattr_setkind_np(&attr,
> PTHREAD_RWLOCK_PREFER_WRITER_NONRECURSIVE_NP);
>  ^
> 1 error generated.

It is not just FreeBSD, it also breaks OS-X and Win32.

The suffix '_np' / '_NP' is shorthand for nNon portable" - these
are glibc inventions. IMHO we should not really use this in our
code as if we're going to make assumptions that writers are not
starved as a result, because writers will be starved on any
non-Linux platform.

IOW, I think we need to just revert this.


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


Re: [libvirt] [PATCH] Generate unique socket file

2017-07-25 Thread Martin Kletzander

On Mon, Jul 24, 2017 at 10:34:49AM -0500, s...@us.ibm.com wrote:

From: Scott Garfinkle 



No need to have a cover letter, the information from the cover letter
you sent should instead be here.


It's possible to have more than one unix channel with type=virtio-serial.
We need to generate a unique name for each channel. Currently, we use
"unknown.sock" for all of them.


The reason you get that is because you gave them no target name.  The
right way to do this is to actually give them target names so that you
can differentiate them in the guest nicely.  We might generate some
names for the sockets and let them get just some vportXnY identifiers in
the guest, but I would rather prefer making users name the channels.


---
src/qemu/qemu_domain.c | 23 +++---
.../qemuxml2argv-channel-virtio-unix.args  |  2 +-
2 files changed, 17 insertions(+), 8 deletions(-)

diff --git a/src/qemu/qemu_domain.c b/src/qemu/qemu_domain.c
index 78e75f1..791d4cf 100644
--- a/src/qemu/qemu_domain.c
+++ b/src/qemu/qemu_domain.c
@@ -7178,18 +7178,27 @@ int
qemuDomainPrepareChannel(virDomainChrDefPtr channel,
 const char *domainChannelTargetDir)
{
-if (channel->targetType == VIR_DOMAIN_CHR_CHANNEL_TARGET_TYPE_VIRTIO &&
-channel->source->type == VIR_DOMAIN_CHR_TYPE_UNIX &&
-!channel->source->data.nix.path) {
+if (channel->targetType != VIR_DOMAIN_CHR_CHANNEL_TARGET_TYPE_VIRTIO ||
+channel->source->type != VIR_DOMAIN_CHR_TYPE_UNIX ||
+channel->source->data.nix.path)
+return 0;
+
+if (channel->target.name) {
if (virAsprintf(&channel->source->data.nix.path,
"%s/%s", domainChannelTargetDir,
-channel->target.name ? channel->target.name
-: "unknown.sock") < 0)
+channel->target.name) < 0)
+return -1;
+} else {// Generate a unique name
+if (virAsprintf(&channel->source->data.nix.path,
+"%s/unknown.sock%d%d%d", domainChannelTargetDir,
+channel->info.addr.vioserial.controller,
+channel->info.addr.vioserial.bus,
+channel->info.addr.vioserial.port) < 0)


This needs some separator between the numbers, also in this case I would
rename it to something else than "unknown.sock" and most of all, leave
the '.sock' at the end.


return -1;
-
-channel->source->data.nix.listen = true;
}

+channel->source->data.nix.listen = true;
+
return 0;
}

diff --git a/tests/qemuxml2argvdata/qemuxml2argv-channel-virtio-unix.args 
b/tests/qemuxml2argvdata/qemuxml2argv-channel-virtio-unix.args
index 2b72965..c875a09 100644
--- a/tests/qemuxml2argvdata/qemuxml2argv-channel-virtio-unix.args
+++ b/tests/qemuxml2argvdata/qemuxml2argv-channel-virtio-unix.args
@@ -29,7 +29,7 @@ 
path=/tmp/channel/domain--1-QEMUGuest1/org.qemu.guest_agent.0,server,nowait \
-device virtserialport,bus=virtio-serial0.0,nr=1,chardev=charchannel0,\
id=channel0,name=org.qemu.guest_agent.0 \
-chardev socket,id=charchannel1,\
-path=/tmp/channel/domain--1-QEMUGuest1/unknown.sock,server,nowait \
+path=/tmp/channel/domain--1-QEMUGuest1/unknown.sock002,server,nowait \
-device virtserialport,bus=virtio-serial0.0,nr=2,chardev=charchannel1,\
id=channel1 \
-chardev socket,id=charchannel2,path=/tmp/channel/domain--1-QEMUGuest1/ble,\
--
1.8.3.1

--
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 v4 0/8] Virtio-crypto device support

2017-07-25 Thread Longpeng (Mike)
Ping...

On 2017/7/7 16:07, Longpeng(Mike) wrote:

> As virtio-crypto has been supported in QEMU 2.8 and the frontend
> driver has been merged in linux 4.10, so it's necessary to support
> virtio-crypto in libvirt.
> 
> ---
> Changes since v3:
>   - spilt the capabilities part into a separate patch. [Boris]
>   - include Boris's virtio-crypto ccw support(PATCH 6 & 8). [Boris]
>   - add the missing capabilities in caps_2.9.0.x86_64.xml. [Boris]
>   - fix Indentation and missing virDomainCryptoDefFree. [Marc]
> 
> Changes since v2:
>   - PATCH 1: modify docs as Martin & Boris's suggestion. [Martin & Boris]
>   - PATCH 2: add the missing 'ToString'. [Martin]
>   - PATCH 3: use virAsprintf instead of virBufferAsprintf. [Martin]
>  remove pointless virBufferCheckError. [Martin]
>   - rebase on master. [Longpeng]
> 
> Changes since v1:
>   - split patch [Martin]
>   - rebase on master [Martin]
>   - add docs/tests/schema [Martin]
>   - fix typos [Gonglei]
> 
> ---
> Boris Fiuczynski (2):
>   qemu: virtio-crypto: add ccw support
>   qemu: virtio-crypto: add test for ccw support
> 
> Longpeng(Mike) (6):
>   docs: schema: Add basic documentation for the virtual
>   docs: news: Add virtio-crypto devices
>   conf: Parse virtio-crypto in the domain XML
>   caps: Add qemu capabilities about virtio-crypto
>   qemu: Implement support for 'builtin' backend for virtio-crypto
>   tests: Add testcase for virtio-crypto parsing
> 
>  docs/formatdomain.html.in  |  61 ++
>  docs/news.xml  |  10 +
>  docs/schemas/domaincommon.rng  |  30 +++
>  src/conf/domain_conf.c | 213 
> -
>  src/conf/domain_conf.h |  32 
>  src/libvirt_private.syms   |   5 +
>  src/qemu/qemu_alias.c  |  20 ++
>  src/qemu/qemu_alias.h  |   3 +
>  src/qemu/qemu_capabilities.c   |   6 +
>  src/qemu/qemu_capabilities.h   |   4 +
>  src/qemu/qemu_command.c| 130 +
>  src/qemu/qemu_command.h|   3 +
>  src/qemu/qemu_domain_address.c |  25 +++
>  src/qemu/qemu_driver.c |   6 +
>  src/qemu/qemu_hotplug.c|   1 +
>  tests/qemucapabilitiesdata/caps_2.8.0.s390x.xml|   2 +
>  tests/qemucapabilitiesdata/caps_2.8.0.x86_64.xml   |   2 +
>  tests/qemucapabilitiesdata/caps_2.9.0.x86_64.xml   |   2 +
>  .../qemuxml2argv-virtio-crypto-builtin.xml |  26 +++
>  .../qemuxml2argv-virtio-crypto-ccw.args|  22 +++
>  .../qemuxml2argv-virtio-crypto-ccw.xml |  16 ++
>  .../qemuxml2argv-virtio-crypto.args|  22 +++
>  tests/qemuxml2argvtest.c   |   6 +
>  .../qemuxml2xmlout-virtio-crypto-builtin.xml   |  31 +++
>  tests/qemuxml2xmltest.c|   2 +
>  25 files changed, 679 insertions(+), 1 deletion(-)
>  create mode 100644 
> tests/qemuxml2argvdata/qemuxml2argv-virtio-crypto-builtin.xml
>  create mode 100644 tests/qemuxml2argvdata/qemuxml2argv-virtio-crypto-ccw.args
>  create mode 100644 tests/qemuxml2argvdata/qemuxml2argv-virtio-crypto-ccw.xml
>  create mode 100644 tests/qemuxml2argvdata/qemuxml2argv-virtio-crypto.args
>  create mode 100644 
> tests/qemuxml2xmloutdata/qemuxml2xmlout-virtio-crypto-builtin.xml
> 


-- 
Regards,
Longpeng(Mike)

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


Re: [libvirt] [PATCH 1/3] virthread: Introduce virRWLockInitPreferWriter

2017-07-25 Thread Michal Privoznik
On 07/24/2017 07:12 PM, John Ferlan wrote:
> 
> 
> On 07/19/2017 10:31 AM, Michal Privoznik wrote:
>> We already have virRWLockInit. But this uses pthread defaults
>> which prefer reader to initialize the RW lock. This may lead to
>> writer starvation. Therefore we need to have the counterpart that
>> prefers writers. Now, according to the
>> pthread_rwlockattr_setkind_np() man page setting
>> PTHREAD_RWLOCK_PREFER_WRITER_NP attribute is no-op. Therefore we
>> need to use PTHREAD_RWLOCK_PREFER_WRITER_NONRECURSIVE_NP
>> attribute. So much for good enum value names.
>>
>> Signed-off-by: Michal Privoznik 
>> ---
>>  src/libvirt_private.syms |  1 +
>>  src/util/virthread.c | 35 +++
>>  src/util/virthread.h |  1 +
>>  3 files changed, 37 insertions(+)
>>
> 
> This has broken the CI build, freebsd is not happy:
> 
> ../../src/util/virthread.c:133:42: error: use of undeclared identifier
> 'PTHREAD_RWLOCK_PREFER_WRITER_NONRECURSIVE_NP'
> pthread_rwlockattr_setkind_np(&attr,
> PTHREAD_RWLOCK_PREFER_WRITER_NONRECURSIVE_NP);
>  ^
> 1 error generated.
> 
> 
> John
> 
> You know what my suggestion is ;-)

Actually, I don't. I am trying to search freebsd documentation on
initializing RW locks so that they prefer writers. But no luck so far.
Does anybody here on the list know? Although, for the current usage of
RW locks it's really hard to starve a writer. But if this is going to be
used more broadly it is going to be easier. On the other hand, I just
realized that while one can use mutexes + conditions (like we do for
domain jobs), using RW locks and conditions is not implemented anywhere,
so I will have to come up with some idea.
Long story short, for now we don't care if writer will starve.

Michal

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


Re: [libvirt] [PATCH 2/3] virobject: Introduce virObjectRWLockable

2017-07-25 Thread Michal Privoznik
On 07/24/2017 05:22 PM, John Ferlan wrote:
> [...]
> 
>>  /**
>>   * virObjectLock:
>> - * @anyobj: any instance of virObjectLockablePtr
>> + * @anyobj: any instance of virObjectLockable or virObjectRWLockable
>>   *
>> - * Acquire a lock on @anyobj. The lock must be
>> - * released by virObjectUnlock.
>> + * Acquire a lock on @anyobj. The lock must be released by
>> + * virObjectUnlock. In case the passed object is instance of
>> + * virObjectRWLockable a write lock is acquired.
>>   *
>>   * The caller is expected to have acquired a reference
>>   * on the object before locking it (eg virObjectRef).
>> @@ -340,31 +382,69 @@ virObjectGetLockableObj(void *anyobj)
>>  void
>>  virObjectLock(void *anyobj)
>>  {
>> -virObjectLockablePtr obj = virObjectGetLockableObj(anyobj);
>> +if (virObjectIsClass(anyobj, virObjectLockableClass)) {
>> +virObjectLockablePtr obj = anyobj;
>> +virMutexLock(&obj->lock);
>> +} else if (virObjectIsClass(anyobj, virObjectRWLockableClass)) {
>> +virObjectRWLockablePtr obj = anyobj;
>> +virRWLockWrite(&obj->lock);
>> +} else {
>> +virObjectPtr obj = anyobj;
>> +VIR_WARN("Object %p (%s) is not a virObjectLockable "
>> + "nor virObjectRWLockable instance",
>> + anyobj, obj ? obj->klass->name : "(unknown)");
>> +}
>> +}
>>  
>> -if (!obj)
>> -return;
>>  
>> -virMutexLock(&obj->lock);
>> +/**
>> + * virObjectLockRead:
>> + * @anyobj: any instance of virObjectRWLockablePtr
>> + *
>> + * Acquire a read lock on @anyobj. The lock must be
>> + * released by virObjectUnlock.
>> + *
>> + * The caller is expected to have acquired a reference
>> + * on the object before locking it (eg virObjectRef).
>> + * The object must be unlocked before releasing this
>> + * reference.
>> + */
>> +void
>> +virObjectLockRead(void *anyobj)
>> +{
>> +if (virObjectIsClass(anyobj, virObjectRWLockableClass)) {
>> +virObjectRWLockablePtr obj = anyobj;
>> +virRWLockRead(&obj->lock);
>> +} else {
>> +virObjectPtr obj = anyobj;
>> +VIR_WARN("Object %p (%s) is not a virObjectRWLockable instance",
>> + anyobj, obj ? obj->klass->name : "(unknown)");
>> +}
>>  }
>>  
> 
> Hopefully no one "confuses" which object is which or no one starts using
> virObjectLockRead for a virObjectLockable and expects that read lock to
> be in place (or error out) or gasp actually wait for a write lock to
> release the lock as this does not error out.

This could have already happened if one would pass bare virObject to
virObjectLock().

> 
> This is a danger in the long term assumption of having a void function
> that has callers that can make the assumption that upon return the Lock
> really was taken.

Well, I agree that this is one more thing to be cautious about, but no
more than making sure object passed to virObjectLock() is virObjectLockable.

> 
> Perhaps the better way to attack this would have been to create a
> virObjectLockWrite() function called only from vir*ObjListAdd and
> vir*ObjListRemove leaving the other virObjectLock()'s in tact and having
> the virObjectLock() code make the decision over whether to use the
> virRWLockRead or virMutexLock depending on the object class.

What's the difference? If virObjectLock() does what you're suggesting
(what indeed is implemented too), what's the point in having
virObjectLockWrite()?

Michal

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


Re: [libvirt] [PATCH v2] storage: Disallow usage of the HBA for a fc_host backing

2017-07-25 Thread Erik Skultety
> +/**
> + * @name: Name from a wwnn/wwpn lookup
> + *
> + * Validate that the @name fetched from the wwnn/wwpn is a vHBA and not
> + * an HBA as that should be a configuration error. It's only possible to
> + * use an existing wwnn/wwpn of a vHBA because that's what someone would
> + * have created using the node device create functionality. Using the
> + * HBA "just because" it has a wwnn/wwpn and the characteristics of a
> + * vHBA is just not valid
> + *
> + * Returns the @scsi_host_name to be used or NULL on errror
> + */
> +static char *
> +checkName(const char *name)
> +{
> +char *scsi_host_name = NULL;
> +unsigned int host_num;
> +
> +if (virAsprintf(&scsi_host_name, "scsi_%s", name) < 0)
> +return NULL;
> +
> +if (virSCSIHostGetNumber(scsi_host_name, &host_num) < 0) {
> +virReportError(VIR_ERR_INTERNAL_ERROR,
> +   _("host name '%s' is not properly formatted"),
> +   name);
> +goto error;
> +}
> +
> +/* If scsi_host_name is vport capable, then it's an HBA. This is
> + * a configuration error as the wwnn/wwpn should only be for a vHBA */
> +if (virVHBAIsVportCapable(NULL, host_num)) {
> +virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
> +   _("the wwnn/wwpn for '%s' are assigned to an HBA"),
> +   scsi_host_name);
> +goto error;
> +}
> +
> +return scsi_host_name;
> +
> + error:
> +VIR_FREE(scsi_host_name);
> +return NULL;
> +}
> +

...

> @@ -275,6 +316,7 @@ createVport(virConnectPtr conn,
>  virStorageAdapterFCHostPtr fchost)
>  {
>  char *name = NULL;
> +char *scsi_host_name = NULL;
>  virStoragePoolFCRefreshInfoPtr cbdata = NULL;
>  virThread thread;
>  int ret = -1;
> @@ -288,6 +330,9 @@ createVport(virConnectPtr conn,
>   * this pool and we don't have to create the vHBA
>   */
>  if ((name = virVHBAGetHostByWWN(NULL, fchost->wwnn, fchost->wwpn))) {
> +if (!(scsi_host_name = checkName(name)))
> +goto cleanup;

Ok, so I learn from my mistakes, do you plan on building upon this in the
foreseeable future with a follow-up series you haven't sent yet, but have on a
local branch? Because if not, I don't really see a point in returning a string
which only gets free'd on the function exit - checkName should probably become
something like "isVHBA" and return boolean. And even if you do have a follow-up
on a local branch, I still think that converting the return value should be
part of that series, solely because until then, @scsi_host_name wouldn't have
any meaning.

Erik

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