Re: [libvirt] [PATCH v3 2/2] network: Add code for setting network bandwidth for ethernet interfaces

2014-10-08 Thread Anirban Chakraborty


On 10/8/14, 8:39 PM, "Eric Blake"  wrote:

>On 10/08/2014 04:10 PM, Anirban Chakraborty wrote:
>
>>> Needs rework after my comments on 1/2.  I also wonder if this should
>>> just be folded in to that patch, and/or made into a switch statement
>>> where the compiler forces us to think about any future
>>> VIR_DOMAIN_NET_TYPE_* additions on whether they should return true or
>>> false.
>
>>> bool virNetDevSupportBandwidth(virDomainNetType type)
>>> {
>>>switch (type) {
>>>case VIR_DOMAIN_NET_TYPE_BRIDGE:
>>>case VIR_DOMAIN_NET_TYPE_NETWORK:
>>>case VIR_DOMAIN_NET_TYPE_DIRECT:
>>>case VIR_DOMAIN_NET_TYPE_ETHERNET:
>>>return true;
>>>case VIR_DOMAIN_NET_TYPE_USER:
>>>case VIR_DOMAIN_NET_TYPE_VHOSTUSER:
>>>case VIR_DOMAIN_NET_TYPE_SERVER:
>>>case VIR_DOMAIN_NET_TYPE_CLIENT:
>>>case VIR_DOMAIN_NET_TYPE_MCAST:
>>>case VIR_DOMAIN_NET_TYPE_INTERNAL:
>>>case VIR_DOMAIN_NET_TYPE_HOSTDEV:
>>>case VIR_DOMAIN_NET_TYPE_LAST:
>>>/* cover all enums to appease the compiler */ ;
>>>}
>>>return false;
>>> }
>> 
>> We could have the function defined with a switch, however, instead of
>> listing all the types, I could return false from the default case.
>> 
>> Something like:
>> switch (type) {
>> case VIR_DOMAIN_NET_TYPE_BRIDGE:
>> case VIR_DOMAIN_NET_TYPE_NETWORK:
>> case VIR_DOMAIN_NET_TYPE_DIRECT:
>> case VIR_DOMAIN_NET_TYPE_ETHERNET:
>> return true;
>> 
>> default;
>> return false;
>
>Alas, using a default case means the compiler can no longer tell you
>about missed cases.  I wrote my example to intentionally spell out ALL
>cases without a default, in order to ensure the compiler will loudly
>warn if we add another enum in the future.

I understood the intention. However, I was aiming for a compact code. If
we add additional enums for network type, we should be adding those types
in the above switch provided the new interface type supports bandwidth. I
do not know if we should prevent future coding error by elaborating the
current code. Forgive me, as I do not know the coding convention for
libvirt. If this is the standard practice, I¹ll change the above switch as
per your wish.

Anirban 


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


Re: [libvirt] [Question] capabilities.pidfile is left behind while starting and stopping libvirtd repeatly

2014-10-08 Thread Martin Kletzander

On Wed, Oct 08, 2014 at 04:07:33PM +0800, Wang Rui wrote:

On 2014/10/2 17:55, Martin Kletzander wrote:

On Tue, Sep 30, 2014 at 10:26:21PM +0200, Guido Günther wrote:

On Tue, Sep 30, 2014 at 04:47:14PM +0200, Martin Kletzander wrote:

On Tue, Sep 30, 2014 at 05:34:54PM +0800, Wang Yufei wrote:
>Hi, all
>
>I started and stopped libvirtd service repeatly with high frequency(1 per 
second), and found that the file capabilities.pidfile is left behind, as well as a 
qemu process. If I then restart libvirtd, qemu-kvm will fail to start as it's 
unable to flock capabilities.pidfile's fd.
>

Have you tried current master?  Or at least -rc2?  It should already
be fixed there:

commit 9e159b521dbf18c6da6976e54e29c8553f831eb6
Author: Guido Günther 
Date:   Thu Sep 25 10:30:58 2014 +0200

   qemu: remove capabilities.monitor.sock when done



This one removes the monitor socket, not the pidfile since I didn't
see that one lingering around in my tests.
Cheers,


Oh, sorry for that, my fault.  Well, should the daemon just kill the
process when it's dying in order to release the lock?  If you try
slower, we will properly remove the pidfile, won't we?


Yes, the pidfile will be keep open and locked forever if this qemu process
is alive. And it will be unlink if I shutdown libvitd daemon slower. But
in this condition(started and stopped libvirtd service repeatly with high
frequency) the pidfile is left behind. In fact libvirtd daemon is killed
before qemu-kvm process and pidfile are cleaned up. Is it a problem?



Simple kill(getpid(), SIGTERM) was enough to find out this is exactly
what's happening.  I have a fix prepared for this, but when I tried
checking whether it fixes everything, I realized I can't find any
problem this causes.  And that's strange.  All domain capabilities
were in place even though I cleared them from the cache.

Is there any cause of this problem?  Does something not work then?
I just want to know to test it basically :)

Thanks for finding that out,
Martin


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 1/3] docs, conf, schema: add support for shmem device

2014-10-08 Thread Martin Kletzander

On Wed, Oct 08, 2014 at 06:57:45PM +0200, Maxime Leroy wrote:

Hi Martin,

On Fri, Oct 3, 2014 at 10:45 PM, Martin Kletzander  wrote:

On Thu, Oct 02, 2014 at 09:42:36AM +0200, Michal Privoznik wrote:


On 26.09.2014 12:43, Martin Kletzander wrote:


diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c
index b114737..51bdd31 100644
--- a/src/conf/domain_conf.c
+++ b/src/conf/domain_conf.c




[..]




Nice catch.

Since we are past the release anyway, I'm going to push this in a
while and whoever wants (e.g. Maxime) have the whole release cycle to
test this.



Thanks for pushing/cleaning the shmem patches support (i.e
http://www.redhat.com/archives/libvir-list/2014-August/msg01032.html)

But you did miss the following:

1. the ivshmem server autostart feature: you wanted me to develop it
into the v1. (i.e.
http://www.redhat.com/archives/libvir-list/2014-August/msg01432.html)



Yes, I know.  That was the idea that when the patches are split
logically, it's possible to push one part without waiting for other
one.


2. You did not wait for my tests. Why should I ask you to wait for my tests?
Lucky enough, now I have the results of the tests, everything works fine ;)

I don't understand why it became so urgent to push these patches.



I'm sorry if I disappointed you somehow.  At first I wanted to make it
for the 1.2.9 release, so we might get some upstream and usage from
libvirt users.  Even though I didn't make it, I already had many
reviews and it was easy to fix what people requested.  And because I
had some ACKs and it was after release, there's a whole release cycle
to try out for everyone else if they want (unfortunately they can't
try that with the official release, but have to go with git).

If you doubt that, it already worked.  Thanks to pushing it, Eric
found some typos, Peter found out that there's no ABI stability check
in qemu driver and that's just a start.


Anyway, I am glad that libvirt supports ivshmem.

Since now you pushed these patches, do you plan to provide the ivshmem
autostart feature like you requested previously ?

I'll be glad to review it and to provide feedbacks based on my tests.



I did not plan to, so feel free to continue with that, I'm focusing on
different things now.  But if it's updated in qemu and there's no
progress, I might look into that because it would be nice to have
libvirt supporting the server as well.

Have a nice day,
Martin


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 2/2] network: Add code for setting network bandwidth for ethernet interfaces

2014-10-08 Thread Eric Blake
On 10/08/2014 04:10 PM, Anirban Chakraborty wrote:

>> Needs rework after my comments on 1/2.  I also wonder if this should
>> just be folded in to that patch, and/or made into a switch statement
>> where the compiler forces us to think about any future
>> VIR_DOMAIN_NET_TYPE_* additions on whether they should return true or
>> false.

>> bool virNetDevSupportBandwidth(virDomainNetType type)
>> {
>>switch (type) {
>>case VIR_DOMAIN_NET_TYPE_BRIDGE:
>>case VIR_DOMAIN_NET_TYPE_NETWORK:
>>case VIR_DOMAIN_NET_TYPE_DIRECT:
>>case VIR_DOMAIN_NET_TYPE_ETHERNET:
>>return true;
>>case VIR_DOMAIN_NET_TYPE_USER:
>>case VIR_DOMAIN_NET_TYPE_VHOSTUSER:
>>case VIR_DOMAIN_NET_TYPE_SERVER:
>>case VIR_DOMAIN_NET_TYPE_CLIENT:
>>case VIR_DOMAIN_NET_TYPE_MCAST:
>>case VIR_DOMAIN_NET_TYPE_INTERNAL:
>>case VIR_DOMAIN_NET_TYPE_HOSTDEV:
>>case VIR_DOMAIN_NET_TYPE_LAST:
>>/* cover all enums to appease the compiler */ ;
>>}
>>return false;
>> }
> 
> We could have the function defined with a switch, however, instead of
> listing all the types, I could return false from the default case.
> 
> Something like:
> switch (type) {
> case VIR_DOMAIN_NET_TYPE_BRIDGE:
> case VIR_DOMAIN_NET_TYPE_NETWORK:
> case VIR_DOMAIN_NET_TYPE_DIRECT:
> case VIR_DOMAIN_NET_TYPE_ETHERNET:
> return true;
> 
> default;
> return false;

Alas, using a default case means the compiler can no longer tell you
about missed cases.  I wrote my example to intentionally spell out ALL
cases without a default, in order to ensure the compiler will loudly
warn if we add another enum in the future.

-- 
Eric Blake   eblake redhat com+1-919-301-3266
Libvirt virtualization library http://libvirt.org



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

Re: [libvirt] [PATCH 03/21] Added basic implementation for virConnectGetCapabilities (required Win32_ComputerSystemProduct class)

2014-10-08 Thread Eric Blake
On 10/08/2014 06:33 AM, Yves Vinter wrote:
> From: yvinter 
> 

Long subject line. I'd suggest:

hyperv: add implementation for virConnectGetCapabilities

Done by adding the Win32_ComputerSystemProduct class.

> ---
>  src/hyperv/hyperv_driver.c| 112 
> ++
>  src/hyperv/hyperv_private.h   |   2 +
>  src/hyperv/hyperv_wmi_generator.input |  12 
>  3 files changed, 126 insertions(+)
> 
> diff --git a/src/hyperv/hyperv_driver.c b/src/hyperv/hyperv_driver.c
> index f2017c3..dd56fb0 100644
> --- a/src/hyperv/hyperv_driver.c
> +++ b/src/hyperv/hyperv_driver.c
> @@ -58,12 +58,19 @@ hypervFreePrivate(hypervPrivate **priv)
>  wsmc_release((*priv)->client);
>  }
>  
> +if ((*priv)->caps != NULL)
> +virObjectUnref((*priv)->caps);

Dead 'if'; virObjectUnref(NULL) is safe.


>  
> +/* Forward declaration of hypervCapsInit */
> +static virCapsPtr hypervCapsInit(hypervPrivate *priv);

Why do you need a forward declaration of a static function?  If it's not
recursive, just put the whole function body here (that may mean moving
more than one function, to keep things topologically sorted; if you need
to do code motion of existing functions, do it in a separate patch from
where you add new code, to ease review).

>  
> +/* Retrieves host system UUID  */
> +static int
> +hypervLookupHostSystemBiosUuid(hypervPrivate *priv, unsigned char *uuid)
> +{
> +Win32_ComputerSystemProduct *computerSystem = NULL;
> +virBuffer query = VIR_BUFFER_INITIALIZER;
> +int result = -1;
> +
> +virBufferAddLit(&query, WIN32_COMPUTERSYSTEMPRODUCT_WQL_SELECT);
> +
> +if (hypervGetWin32ComputerSystemProductList(priv, &query, 
> &computerSystem) < 0) {
> +goto cleanup;
> +}
> +
> +if (computerSystem == NULL) {
> +virReportError(VIR_ERR_NO_DOMAIN,

Is VIR_ERR_NO_DOMAIN really the right error to be using here?

> +   _("Unable to get Win32_ComputerSystemProduct"));
> +goto cleanup;
> +}
> +
> +if (virUUIDParse(computerSystem->data->UUID, uuid) < 0) {
> +virReportError(VIR_ERR_INTERNAL_ERROR,
> +   _("Could not parse UUID from string '%s'"),
> +   computerSystem->data->UUID);
> +goto cleanup;
> +}
> +
> +result = 0;
> +
> + cleanup:
> +hypervFreeObject(priv, (hypervObject *)computerSystem);
> +virBufferFreeAndReset(&query);

This virBufferFreeAndReset is not needed if you take my alternate patch
for 1/21.

> +
> +return result;
> +}
> +
> +
> +
> +static virCapsPtr hypervCapsInit(hypervPrivate *priv)

Libvirt style is two blank lines between functions, and function name
starting in column 1 of a line separate from the return type:

static virCapsPtr
hypervCapsInit(hypervPrivate *priv)

> +{
> +virCapsPtr caps = NULL;
> +virCapsGuestPtr guest = NULL;
> +
> +caps = virCapabilitiesNew(VIR_ARCH_X86_64, 1, 1);
> +
> +if (caps == NULL) {
> +virReportOOMError();
> +return NULL;
> +}
> +
> +/* virCapabilitiesSetMacPrefix(caps, (unsigned char[]){ 0x00, 0x0c, 0x29 
> }); */

Might be nice to explain why this is commented out.


> +}
> +
> +
> +
> +static char*

Only need two blank lines.

> +hypervConnectGetCapabilities(virConnectPtr conn)
> +{
> +hypervPrivate *priv = conn->privateData;
> +char *xml = virCapabilitiesFormatXML(priv->caps);

virCapabilitiesFormatXML can only return NULL on error, and it already
outputs a decent error message; also, error is not always due to OOM...

> +
> +if (xml == NULL) {
> +virReportOOMError();

...so this virReportOOMError() is bogus, because it overwrites the
decent message.

> +return NULL;
> +}

Once you realize that, you can simplify this function to:

static char*
hypervConnectGetCapabilities(virConnectPtr conn)
{
hypervPrivate *priv = conn->privateData;
return virCapabilitiesFormatXML(priv->caps);
}


-- 
Eric Blake   eblake redhat com+1-919-301-3266
Libvirt virtualization library http://libvirt.org



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

Re: [libvirt] [PATCH 02/21] Added implementation for virConnectGetVersion (required CIM_DataFile class)

2014-10-08 Thread Eric Blake
On 10/08/2014 06:33 AM, Yves Vinter wrote:
> From: yvinter 
> 
> ---
>  src/hyperv/hyperv_driver.c| 55 
> +++
>  src/hyperv/hyperv_wmi_generator.input | 37 +++
>  src/hyperv/hyperv_wmi_generator.py|  4 +--
>  3 files changed, 94 insertions(+), 2 deletions(-)
> 

Another round of reviews; the .input and .py file look okay to me, but I
spotted more issues in the .c that I didn't point out the first time around.

> +static int
> +hypervConnectGetVersion(virConnectPtr conn, unsigned long *version)
> +{
> +int result = -1;
> +hypervPrivate *priv = conn->privateData;
> +CIM_DataFile  *datafile = NULL;
> +virBuffer query = VIR_BUFFER_INITIALIZER;
> +char *p;
> +

Trailing whitespace. Another thing 'make syntax-check' will flag.

> +virBufferAddLit(&query, " Select * from CIM_DataFile where 
> Name='c:windowssystem32vmms.exe' ");
> +if (hypervGetCIMDataFileList(priv, &query, &datafile) < 0) {
> +goto cleanup;
> +}
> +
> +/* Check the result of convertion */

s/convertion/conversion/

> +if (datafile == NULL) {
> +virReportError(VIR_ERR_INTERNAL_ERROR,
> +   _("Could not lookup %s for domain %s"),
> +   "Msvm_VirtualSystemSettingData",
> +   datafile->data->Version);

Is this error message correct?  That is, is datafile->data->Version the
name of the domain you are referring to in the message?

> +goto cleanup;
> +}
> +
> +/* Delete release number and last digit of build number 1.1.111x. */
> +p = strrchr(datafile->data->Version,'.');
> +if (p == NULL) {
> +virReportError(VIR_ERR_INTERNAL_ERROR,
> +   _("Could not parse version number from '%s'"),
> +   datafile->data->Version);
> +goto cleanup;
> +}
> +p--;
> +*p = '\0';

This is modifying datafile->data in-place.  I hope that's safe (if not,
you'd have to strdup a copy that you can safely manipulate locally).

> +
> +/* Parse Version String to Long */
> +if (virParseVersionString(datafile->data->Version,

The comment is a bit redundant with the name of the function you are
calling.  I'd just omit the comment.


-- 
Eric Blake   eblake redhat com+1-919-301-3266
Libvirt virtualization library http://libvirt.org



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

Re: [libvirt] [PATCH v3 2/3] conf: add check if migration_host is a localhost address

2014-10-08 Thread Chen, Fan
On Wed, 2014-10-08 at 12:33 +0200, Ján Tomko wrote: 
> On 10/07/2014 06:07 AM, Chen Fan wrote:
> >  Signed-off-by: Chen Fan 
> > ---
> >  src/libvirt_private.syms |  1 +
> >  src/qemu/qemu_conf.c | 50 
> > 
> >  src/qemu/qemu_conf.h |  2 ++
> >  src/util/virsocketaddr.c | 24 +++
> >  src/util/virsocketaddr.h |  2 ++
> >  5 files changed, 79 insertions(+)
> > 
> > diff --git a/src/libvirt_private.syms b/src/libvirt_private.syms
> > index 8ab1394..a104bc6 100644
> > --- a/src/libvirt_private.syms
> > +++ b/src/libvirt_private.syms
> > @@ -1911,6 +1911,7 @@ virSocketAddrGetIpPrefix;
> >  virSocketAddrGetPort;
> >  virSocketAddrGetRange;
> >  virSocketAddrIsNetmask;
> > +virSocketAddrIsNumericLocalhost;
> >  virSocketAddrIsPrivate;
> >  virSocketAddrIsWildcard;
> >  virSocketAddrMask;
> > diff --git a/src/qemu/qemu_conf.c b/src/qemu/qemu_conf.c
> > index adc6caf..6b0ac5c 100644
> > --- a/src/qemu/qemu_conf.c
> > +++ b/src/qemu/qemu_conf.c
> > @@ -707,6 +707,15 @@ int virQEMUDriverConfigLoadFile(virQEMUDriverConfigPtr 
> > cfg,
> >  GET_VALUE_LONG("seccomp_sandbox", cfg->seccompSandbox);
> >  
> >  GET_VALUE_STR("migration_host", cfg->migrateHost);
> > +if (cfg->migrateHost &&
> > +qemuCheckLocalhost(cfg->migrateHost)) {
> > +virReportError(VIR_ERR_CONF_SYNTAX,
> > +   _("migration_host must not be the address of"
> > + " the local machine: %s"),
> > +   cfg->migrateHost);
> > +goto cleanup;
> > +}
> > +
> >  GET_VALUE_STR("migration_address", cfg->migrationAddress);
> >  
> >  GET_VALUE_BOOL("log_timestamp", cfg->logTimestamp);
> > @@ -1371,3 +1380,44 @@ qemuGetDefaultHugepath(virHugeTLBFSPtr hugetlbfs,
> >  
> >  return qemuGetHugepagePath(&hugetlbfs[i]);
> >  }
> > +
> > +bool
> > +qemuCheckLocalhost(const char *addrStr)
> > +{
> > +virSocketAddr addr;
> > +char *hostname, *tmp;
> > +bool encloseAddress = false;
> > +int family;
> > +bool ret = true;
> > +
> > +if (VIR_STRDUP(hostname, addrStr) < 0)
> > +return false;
> > +
> > +tmp = hostname;
> > +
> > +if (STRPREFIX(hostname, "[")) {
> > +char *end = strchr(hostname, ']');
> > +if (end) {
> > +*end = '\0';
> > +hostname++;
> > +encloseAddress = true;
> > +}
> > +}
> 
> We don't format the qemu.conf back and we don't need the brackets for
> anything. We can just store the migration host without them in 
> cfg->migrationHost
> 
> > +
> > +if (STRPREFIX(hostname, "localhost"))
> > +goto cleanup;
> > +
> > +family = virSocketAddrNumericFamily(hostname);
> > +if ((family == AF_INET && !encloseAddress) ||
> > +family == AF_INET6) {
> > +if (virSocketAddrParse(&addr, hostname, family) > 0 &&
> > +virSocketAddrIsNumericLocalhost(&addr)) {
> > +goto cleanup;
> > +}
> > +}
> 
> There's no need to check for family upfront.
> 
> > +
> > +ret = false;
> > +cleanup:
> > +VIR_FREE(tmp);
> > +return ret;
> > +}
> > diff --git a/src/qemu/qemu_conf.h b/src/qemu/qemu_conf.h
> > index cb01fb6..c9ce53c 100644
> > --- a/src/qemu/qemu_conf.h
> > +++ b/src/qemu/qemu_conf.h
> > @@ -322,4 +322,6 @@ int qemuTranslateSnapshotDiskSourcePool(virConnectPtr 
> > conn,
> >  char * qemuGetHugepagePath(virHugeTLBFSPtr hugepage);
> >  char * qemuGetDefaultHugepath(virHugeTLBFSPtr hugetlbfs,
> >size_t nhugetlbfs);
> > +
> > +bool qemuCheckLocalhost(const char *addrStr);
> >  #endif /* __QEMUD_CONF_H */
> > diff --git a/src/util/virsocketaddr.c b/src/util/virsocketaddr.c
> > index 7fe7a15..6d36689 100644
> > --- a/src/util/virsocketaddr.c
> > +++ b/src/util/virsocketaddr.c
> > @@ -878,3 +878,27 @@ virSocketAddrNumericFamily(const char *address)
> >  freeaddrinfo(res);
> >  return family;
> >  }
> > +
> > +/**
> > + * virSocketAddrIsNumericLocalhost:
> > + * @address: address to check
> > + *
> > + * Check if passed address is a numeric 'localhost' address.
> > + *
> > + * Returns: true if @address is a numeric 'localhost' address,
> > + *  false otherwise
> > + */
> > +bool
> > +virSocketAddrIsNumericLocalhost(const virSocketAddr *addr)
> 
> I've rewritten this function to take a 'const char *' argument.
> Along with the virStringStripIPv6Brackets function I've sent for review
> separately, this removes the need for a separate qemuCheckLocalhost function
> and it can be inlined.
> 
> > +{
> > +struct in_addr tmp = { .s_addr = htonl(INADDR_LOOPBACK) };
> > +switch (addr->data.stor.ss_family) {
> > +case AF_INET:
> > +return memcmp(&addr->data.inet4.sin_addr.s_addr, &tmp.s_addr,
> > +  sizeof(addr->data.inet4.sin_addr.s_addr)) == 0;
> > +case AF_INET6:
> > +return IN6_IS_ADDR_LOOPBACK(&addr->data.inet6.sin6_addr);
> > +

[libvirt] [PATCH v3 7/7] qemu-attach: Assign device aliases

2014-10-08 Thread John Ferlan
https://bugzilla.redhat.com/show_bug.cgi?id=1141621

As part of attach processing, assign the device aliases by calling
qemuAssignDeviceAliases during qemuDomainQemuAttach once all the devices
are found after the qemuParseCommandLinePid processing.

This will alleviate a symptom that caused a libvirtd crash during an
attempted device detach.

Signed-off-by: John Ferlan 
---
 src/qemu/qemu_driver.c | 3 +++
 1 file changed, 3 insertions(+)

diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c
index 4e2b356..57daa67 100644
--- a/src/qemu/qemu_driver.c
+++ b/src/qemu/qemu_driver.c
@@ -14862,6 +14862,9 @@ static virDomainPtr qemuDomainQemuAttach(virConnectPtr 
conn,
 if (qemuCanonicalizeMachine(def, qemuCaps) < 0)
 goto cleanup;
 
+if (qemuAssignDeviceAliases(def, qemuCaps) < 0)
+goto cleanup;
+
 if (qemuDomainAssignAddresses(def, qemuCaps, NULL) < 0)
 goto cleanup;
 
-- 
1.9.3

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


[libvirt] [PATCH v3 4/7] hotplug: Check for alias in hostdev detach

2014-10-08 Thread John Ferlan
If the QEMU_CAPS_DEVICE is set, then ensure the host device alias has
been properly set before making the calls to detach the device

Signed-off-by: John Ferlan 
---
 src/qemu/qemu_hotplug.c | 7 +++
 1 file changed, 7 insertions(+)

diff --git a/src/qemu/qemu_hotplug.c b/src/qemu/qemu_hotplug.c
index 3e8cdbf..db39948 100644
--- a/src/qemu/qemu_hotplug.c
+++ b/src/qemu/qemu_hotplug.c
@@ -3371,8 +3371,15 @@ qemuDomainDetachThisHostDevice(virQEMUDriverPtr driver,
virDomainObjPtr vm,
virDomainHostdevDefPtr detach)
 {
+qemuDomainObjPrivatePtr priv = vm->privateData;
 int ret = -1;
 
+if (virQEMUCapsGet(priv->qemuCaps, QEMU_CAPS_DEVICE) &&
+!detach->info->alias) {
+if (qemuAssignDeviceHostdevAlias(vm->def, detach, -1) < 0)
+return -1;
+}
+
 switch (detach->source.subsys.type) {
 case VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_PCI:
 ret = qemuDomainDetachHostPCIDevice(driver, vm, detach);
-- 
1.9.3

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


[libvirt] [PATCH v3 1/7] virsh: Adjust the text in man page regarding qemu-attach

2014-10-08 Thread John Ferlan
Slight adjustment to the qemu-attach man page to note device hotplug
and hot unplug may not work and that the environment should be considered
read-only

Signed-off-by: John Ferlan 
---
 tools/virsh.pod | 5 +++--
 1 file changed, 3 insertions(+), 2 deletions(-)

diff --git a/tools/virsh.pod b/tools/virsh.pod
index eae9195..bd17f68 100644
--- a/tools/virsh.pod
+++ b/tools/virsh.pod
@@ -3698,8 +3698,9 @@ using the UNIX driver. Ideally the process will also have 
had the
 
 Not all functions of libvirt are expected to work reliably after
 attaching to an externally launched QEMU process. There may be
-issues with the guest ABI changing upon migration, and hotunplug
-may not work.
+issues with the guest ABI changing upon migration and device hotplug
+or hotunplug may not work. The attached environment should be considered
+primarily read-only.
 
 =item B I { [I<--hmp>] | [I<--pretty>] }
 I...
-- 
1.9.3

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


[libvirt] [PATCH v3 5/7] hotplug: Check for alias in chrdev detach

2014-10-08 Thread John Ferlan
If the QEMU_CAPS_DEVICE is set, then ensure the chr device alias has
been properly set before making the calls to detach the device

Signed-off-by: John Ferlan 
---
 src/qemu/qemu_hotplug.c | 6 ++
 1 file changed, 6 insertions(+)

diff --git a/src/qemu/qemu_hotplug.c b/src/qemu/qemu_hotplug.c
index db39948..f79a37a 100644
--- a/src/qemu/qemu_hotplug.c
+++ b/src/qemu/qemu_hotplug.c
@@ -3696,6 +3696,12 @@ int qemuDomainDetachChrDevice(virQEMUDriverPtr driver,
 return ret;
 }
 
+if (virQEMUCapsGet(priv->qemuCaps, QEMU_CAPS_DEVICE) &&
+!tmpChr->info.alias) {
+if (qemuAssignDeviceChrAlias(vmdef, tmpChr, -1) < 0)
+return ret;
+}
+
 if (qemuBuildChrDeviceStr(&devstr, vm->def, chr, priv->qemuCaps) < 0)
 return ret;
 
-- 
1.9.3

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


[libvirt] [PATCH v3 0/7] hotplug: Fix libvirtd crash on qemu-attached guest

2014-10-08 Thread John Ferlan
v2 is here:

http://www.redhat.com/archives/libvir-list/2014-September/msg01575.html

As Michal pointed out in his review - other devices could have the
same issue - so take care of each of them separately (I already knew
the answer to my last question...)

Totally different approach this time - rather than error out, follow
the example I from the Controller Detach code which will generate an
alias for the device (although it did miss one minor check to see if
it was already set leading to a potential memory leak since the alias
code would overwrite whatever was there).

Note: In a way 1/7 was already ACK'd - I just hadn't separated it yet
for a push and wanted to keep these closer together when/if they were
pushed.

Whether 7/7 is now necessary is debateable - I keep it only for
completeness and environment setup in much the same way the start
code handles aliases.

John Ferlan (7):
  virsh: Adjust the text in man page regarding qemu-attach
  hotplug: Check for alias in controller detach
  hotplug: Check for alias in disk detach
  hotplug: Check for alias in hostdev detach
  hotplug: Check for alias in chrdev detach
  hotplug: Check for alias in net detach
  qemu-attach: Assign device aliases

 src/qemu/qemu_driver.c  |  3 +++
 src/qemu/qemu_hotplug.c | 28 +++-
 tools/virsh.pod |  5 +++--
 3 files changed, 33 insertions(+), 3 deletions(-)

-- 
1.9.3

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


[libvirt] [PATCH v3 6/7] hotplug: Check for alias in net detach

2014-10-08 Thread John Ferlan
https://bugzilla.redhat.com/show_bug.cgi?id=1141621

If the QEMU_CAPS_DEVICE is set, then ensure the host device alias has
been properly set before making the calls to detach the device

Signed-off-by: John Ferlan 
---
 src/qemu/qemu_hotplug.c | 6 ++
 1 file changed, 6 insertions(+)

diff --git a/src/qemu/qemu_hotplug.c b/src/qemu/qemu_hotplug.c
index f79a37a..33241fb 100644
--- a/src/qemu/qemu_hotplug.c
+++ b/src/qemu/qemu_hotplug.c
@@ -3530,6 +3530,12 @@ qemuDomainDetachNetDevice(virQEMUDriverPtr driver,
 }
 }
 
+if (virQEMUCapsGet(priv->qemuCaps, QEMU_CAPS_DEVICE) &&
+!detach->info.alias) {
+if (qemuAssignDeviceNetAlias(vm->def, detach, -1) < 0)
+goto cleanup;
+}
+
 qemuDomainMarkDeviceForRemoval(vm, &detach->info);
 
 qemuDomainObjEnterMonitor(driver, vm);
-- 
1.9.3

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


[libvirt] [PATCH v3 3/7] hotplug: Check for alias in disk detach

2014-10-08 Thread John Ferlan
If the QEMU_CAPS_DEVICE is set, then ensure the disk device alias has
been properly set in prior to making the calls to detach the device.

Signed-off-by: John Ferlan 
---
 src/qemu/qemu_hotplug.c | 6 ++
 1 file changed, 6 insertions(+)

diff --git a/src/qemu/qemu_hotplug.c b/src/qemu/qemu_hotplug.c
index 9c0f6c9..3e8cdbf 100644
--- a/src/qemu/qemu_hotplug.c
+++ b/src/qemu/qemu_hotplug.c
@@ -2998,6 +2998,12 @@ qemuDomainDetachVirtioDiskDevice(virQEMUDriverPtr driver,
 }
 }
 
+if (virQEMUCapsGet(priv->qemuCaps, QEMU_CAPS_DEVICE) &&
+!detach->info.alias) {
+if (qemuAssignDeviceDiskAlias(vm->def, detach, priv->qemuCaps) < 0)
+goto cleanup;
+}
+
 qemuDomainMarkDeviceForRemoval(vm, &detach->info);
 
 qemuDomainObjEnterMonitor(driver, vm);
-- 
1.9.3

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


[libvirt] [PATCH v3 2/7] hotplug: Check for alias in controller detach

2014-10-08 Thread John Ferlan
In qemuDomainDetachControllerDevice if the info.alias already exists
a call to qemuAssignDeviceControllerAlias would overwrite the existing
so avoid this possibility.

Signed-off-by: John Ferlan 
---
 src/qemu/qemu_hotplug.c | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/src/qemu/qemu_hotplug.c b/src/qemu/qemu_hotplug.c
index 1e504ec..9c0f6c9 100644
--- a/src/qemu/qemu_hotplug.c
+++ b/src/qemu/qemu_hotplug.c
@@ -3226,7 +3226,8 @@ int qemuDomainDetachControllerDevice(virQEMUDriverPtr 
driver,
 goto cleanup;
 }
 
-if (virQEMUCapsGet(priv->qemuCaps, QEMU_CAPS_DEVICE)) {
+if (virQEMUCapsGet(priv->qemuCaps, QEMU_CAPS_DEVICE) &&
+!detach->info.alias) {
 if (qemuAssignDeviceControllerAlias(detach) < 0)
 goto cleanup;
 }
-- 
1.9.3

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


Re: [libvirt] [PATCH v3 2/2] network: Add code for setting network bandwidth for ethernet interfaces

2014-10-08 Thread Anirban Chakraborty


On 10/8/14, 2:39 PM, "Eric Blake"  wrote:

>On 10/08/2014 01:59 PM, Anirban Chakraborty wrote:
>> 
>> Signed-off-by: Anirban Chakraborty 
>> ---
>>  src/conf/domain_conf.h | 3 ++-
>>  1 file changed, 2 insertions(+), 1 deletion(-)
>> 
>> diff --git a/src/conf/domain_conf.h b/src/conf/domain_conf.h
>> index f03599e..91da1ec 100644
>> --- a/src/conf/domain_conf.h
>> +++ b/src/conf/domain_conf.h
>> @@ -2852,7 +2852,8 @@ static inline bool virNetDevSupportBandwidth(int
>>type)
>>  {
>>  return ((type == VIR_DOMAIN_NET_TYPE_BRIDGE ||
>>   type == VIR_DOMAIN_NET_TYPE_NETWORK ||
>> - type == VIR_DOMAIN_NET_TYPE_DIRECT) ? true : false);
>> + type == VIR_DOMAIN_NET_TYPE_DIRECT ||
>> + type == VIR_DOMAIN_NET_TYPE_ETHERNET) ? true : false);
>
>Needs rework after my comments on 1/2.  I also wonder if this should
>just be folded in to that patch, and/or made into a switch statement
>where the compiler forces us to think about any future
>VIR_DOMAIN_NET_TYPE_* additions on whether they should return true or
>false.

I will rework the 1/2 patch to fix syntax etc. Initially, I sent a single
patch to keep everything together, however, there was a suggestion to
split it. I decided to split it into two as clearly there are two parts to
this series, one to prepare the code for addition of ethernet interfaces
and the other to add the ethernet type. True, the second patch is very
minimal and I can fold it back into a single patch if everyone agrees to
it.

>
>As in:
>
>bool virNetDevSupportBandwidth(virDomainNetType type)
>{
>switch (type) {
>case VIR_DOMAIN_NET_TYPE_BRIDGE:
>case VIR_DOMAIN_NET_TYPE_NETWORK:
>case VIR_DOMAIN_NET_TYPE_DIRECT:
>case VIR_DOMAIN_NET_TYPE_ETHERNET:
>return true;
>case VIR_DOMAIN_NET_TYPE_USER:
>case VIR_DOMAIN_NET_TYPE_VHOSTUSER:
>case VIR_DOMAIN_NET_TYPE_SERVER:
>case VIR_DOMAIN_NET_TYPE_CLIENT:
>case VIR_DOMAIN_NET_TYPE_MCAST:
>case VIR_DOMAIN_NET_TYPE_INTERNAL:
>case VIR_DOMAIN_NET_TYPE_HOSTDEV:
>case VIR_DOMAIN_NET_TYPE_LAST:
>/* cover all enums to appease the compiler */ ;
>}
>return false;
>}

We could have the function defined with a switch, however, instead of
listing all the types, I could return false from the default case.

Something like:
switch (type) {
case VIR_DOMAIN_NET_TYPE_BRIDGE:
case VIR_DOMAIN_NET_TYPE_NETWORK:
case VIR_DOMAIN_NET_TYPE_DIRECT:
case VIR_DOMAIN_NET_TYPE_ETHERNET:
return true;

default;
return false;
}

Will this work for you?

Thanks.
-Anirban


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


Re: [libvirt] [PATCH 02/21] Added implementation for virConnectGetVersion (required CIM_DataFile class)

2014-10-08 Thread Eric Blake
On 10/08/2014 06:33 AM, Yves Vinter wrote:
> From: yvinter 

Looks like you had identity problems throughout the series. I don't mind
touching up first-time contributions, but it would be nice to get it
right in the future so I don't have to spend time on it.

> 
> ---
>  src/hyperv/hyperv_driver.c| 55 
> +++
>  src/hyperv/hyperv_wmi_generator.input | 37 +++
>  src/hyperv/hyperv_wmi_generator.py|  4 +--
>  3 files changed, 94 insertions(+), 2 deletions(-)
> 
> diff --git a/src/hyperv/hyperv_driver.c b/src/hyperv/hyperv_driver.c
> index 372ff39..f2017c3 100644
> --- a/src/hyperv/hyperv_driver.c
> +++ b/src/hyperv/hyperv_driver.c
> @@ -1232,6 +1232,7 @@ hypervDomainManagedSaveRemove(virDomainPtr domain, 
> unsigned int flags)
>  }
>  
>  
> +
>  #define MATCH(FLAG) (flags & (FLAG))

Why the added blank line?

>  static int
>  hypervConnectListAllDomains(virConnectPtr conn,
> @@ -1366,6 +1367,59 @@ hypervConnectListAllDomains(virConnectPtr conn,
>  
>  
>  
> +static int

Wow, that's a lot of blank lines already there.

> +hypervConnectGetVersion(virConnectPtr conn, unsigned long *version)
> +{
> +int result = -1;
> +hypervPrivate *priv = conn->privateData;
> +CIM_DataFile  *datafile = NULL;

Why the double space?

> +virBuffer query = VIR_BUFFER_INITIALIZER;
> +char *p;
> +
> +virBufferAddLit(&query, " Select * from CIM_DataFile where 
> Name='c:windowssystem32vmms.exe' ");

Is the leading and trailing space really necessary in the string literal?

> +if (hypervGetCIMDataFileList(priv, &query, &datafile) < 0) {
> +goto cleanup;
> +}

Libvirt style says {} are not necessary for one-line bodies (qemu style
would require it, but we're a bit more lenient).

> +
> +/* Check the result of convertion */
> +if (datafile == NULL) {

It's sufficient to write 'if (datafile)' (comparison to NULL is just
extra verbosity); but as that appears to be the prevailing style already
in this file, I'm not going to worry about shortening it.

> +virReportError(VIR_ERR_INTERNAL_ERROR,
> +   _("Could not lookup %s for domain %s"),
> +   "Msvm_VirtualSystemSettingData",
> +   datafile->data->Version);
> +goto cleanup;
> +}
> +
> +/* Delete release number and last digit of build number 1.1.111x. */
> +p = strrchr(datafile->data->Version,'.');

This failed 'make syntax-check' due to a missing space:

  GEN  bracket-spacing-check
src/hyperv/hyperv_driver.c:1381: p =
strrchr(datafile->data->Version,'.');
maint.mk: incorrect whitespace, see HACKING for rules
make: *** [bracket-spacing-check] Error 1

> +if (p == NULL) {
> +virReportError(VIR_ERR_INTERNAL_ERROR,
> +   _("Could not parse version number from '%s'"),
> +   datafile->data->Version);
> +goto cleanup;
> +}
> +p--;
> +*p = '\0';
> +
> +/* Parse Version String to Long */
> +if (virParseVersionString(datafile->data->Version,
> +  version, true) < 0) {
> +virReportError(VIR_ERR_INTERNAL_ERROR,
> +   _("Could not parse version number from '%s'"),
> +   datafile->data->Version);
> +goto cleanup;
> +}
> +
> +result = 0;
> +
> + cleanup:
> +hypervFreeObject(priv, (hypervObject *)datafile);
> +virBufferFreeAndReset(&query);

This line is not necessary if you ACK my v2 of 1/21.

> +
> +return result;
> +}
> +
> +
>  
>  static virDriver hypervDriver = {
>  .no = VIR_DRV_HYPERV,
> @@ -1402,6 +1456,7 @@ static virDriver hypervDriver = {
>  .domainHasManagedSaveImage = hypervDomainHasManagedSaveImage, /* 0.9.5 */
>  .domainManagedSaveRemove = hypervDomainManagedSaveRemove, /* 0.9.5 */
>  .connectIsAlive = hypervConnectIsAlive, /* 0.9.8 */
> +.connectGetVersion = hypervConnectGetVersion, /* 1.2.10 */
>  };

I got through here in my review for now; mostly looks good other than
style.  When I finish the rest of the patch, I may end up just fixing it
myself and pushing.

-- 
Eric Blake   eblake redhat com+1-919-301-3266
Libvirt virtualization library http://libvirt.org



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

Re: [libvirt] [PATCH v3 2/2] network: Add code for setting network bandwidth for ethernet interfaces

2014-10-08 Thread Eric Blake
On 10/08/2014 01:59 PM, Anirban Chakraborty wrote:
> 
> Signed-off-by: Anirban Chakraborty 
> ---
>  src/conf/domain_conf.h | 3 ++-
>  1 file changed, 2 insertions(+), 1 deletion(-)
> 
> diff --git a/src/conf/domain_conf.h b/src/conf/domain_conf.h
> index f03599e..91da1ec 100644
> --- a/src/conf/domain_conf.h
> +++ b/src/conf/domain_conf.h
> @@ -2852,7 +2852,8 @@ static inline bool virNetDevSupportBandwidth(int type)
>  {
>  return ((type == VIR_DOMAIN_NET_TYPE_BRIDGE ||
>   type == VIR_DOMAIN_NET_TYPE_NETWORK ||
> - type == VIR_DOMAIN_NET_TYPE_DIRECT) ? true : false);
> + type == VIR_DOMAIN_NET_TYPE_DIRECT ||
> + type == VIR_DOMAIN_NET_TYPE_ETHERNET) ? true : false);

Needs rework after my comments on 1/2.  I also wonder if this should
just be folded in to that patch, and/or made into a switch statement
where the compiler forces us to think about any future
VIR_DOMAIN_NET_TYPE_* additions on whether they should return true or false.

As in:

bool virNetDevSupportBandwidth(virDomainNetType type)
{
switch (type) {
case VIR_DOMAIN_NET_TYPE_BRIDGE:
case VIR_DOMAIN_NET_TYPE_NETWORK:
case VIR_DOMAIN_NET_TYPE_DIRECT:
case VIR_DOMAIN_NET_TYPE_ETHERNET:
return true;
case VIR_DOMAIN_NET_TYPE_USER:
case VIR_DOMAIN_NET_TYPE_VHOSTUSER:
case VIR_DOMAIN_NET_TYPE_SERVER:
case VIR_DOMAIN_NET_TYPE_CLIENT:
case VIR_DOMAIN_NET_TYPE_MCAST:
case VIR_DOMAIN_NET_TYPE_INTERNAL:
case VIR_DOMAIN_NET_TYPE_HOSTDEV:
case VIR_DOMAIN_NET_TYPE_LAST:
/* cover all enums to appease the compiler */ ;
}
return false;
}

-- 
Eric Blake   eblake redhat com+1-919-301-3266
Libvirt virtualization library http://libvirt.org



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

Re: [libvirt] [PATCH v3 1/2] network: Refactor code to add bandwidth support for ethernet interfaces

2014-10-08 Thread Eric Blake
On 10/08/2014 01:55 PM, Anirban Chakraborty wrote:
> Modified code to set and clear bandwidth cleanly.

[meta-comment - this mail wasn't threaded to the 0/2 cover letter, but
came through as its own top-level thread.  This makes it harder to track
the series]

> 
> Signed-off-by: Anirban Chakraborty 
> ---
>  src/conf/domain_conf.h  |  7 +++
>  src/lxc/lxc_driver.c|  3 +++
>  src/lxc/lxc_process.c   | 18 +-
>  src/qemu/qemu_command.c | 25 +++--
>  src/qemu/qemu_command.h |  2 ++
>  src/qemu/qemu_driver.c  |  3 +++
>  src/qemu/qemu_hotplug.c | 12 
>  src/qemu/qemu_process.c |  3 +++
>  src/util/virnetdevmacvlan.c | 10 --
>  src/util/virnetdevmacvlan.h |  1 -
>  10 files changed, 58 insertions(+), 26 deletions(-)

Style review (I'll leave the content review to someone a bit more
familiar with network code)

> 
> diff --git a/src/conf/domain_conf.h b/src/conf/domain_conf.h
> index afa3da6..f03599e 100644
> --- a/src/conf/domain_conf.h
> +++ b/src/conf/domain_conf.h
> @@ -2848,4 +2848,11 @@ int virDomainObjSetMetadata(virDomainObjPtr vm,
>  bool virDomainDefNeedsPlacementAdvice(virDomainDefPtr def)
>  ATTRIBUTE_NONNULL(1);
> 
> +static inline bool virNetDevSupportBandwidth(int type)
> +{
> +return ((type == VIR_DOMAIN_NET_TYPE_BRIDGE ||
> + type == VIR_DOMAIN_NET_TYPE_NETWORK ||
> + type == VIR_DOMAIN_NET_TYPE_DIRECT) ? true : false);

I think 'return cond ? true : false;' is a waste of source code.  Just
'return cond;'.  Indentation looks awkward; I would have done it:

return (type == VIR_DOMAIN_NET_TYPE_BRIDGE ||
type == VIR_DOMAIN_NET_TYPE_NETWORK ||
type == VIR_DOMAIN_NET_TYPE_DIRECT);

> +};

Spurious semicolon.

-- 
Eric Blake   eblake redhat com+1-919-301-3266
Libvirt virtualization library http://libvirt.org



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

Re: [libvirt] NBD TLS support in QEMU

2014-10-08 Thread Wouter Verhelst
On Thu, Oct 02, 2014 at 03:50:57PM +0200, Wouter Verhelst wrote:
> On Thu, Oct 02, 2014 at 01:00:04PM +0200, Paolo Bonzini wrote:
> > Il 01/10/2014 22:23, Wouter Verhelst ha scritto:
> > > Hi,
> > > 
> > > On Fri, Sep 05, 2014 at 03:26:09PM +0200, Wouter Verhelst wrote:
> > >> Tunneling the entire protocol inside an SSL connection doesn't fix that;
> > >> if an attacker is able to hijack your TCP connections and change flags,
> > >> then this attacker is also able to hijack your TCP connection and
> > >> redirect it to a decrypting/encrypting proxy.
> > >>
> > >> I agree that preventing a possible SSL downgrade attack (and other forms
> > >> of MITM) should be high on the priority list, but "tunnel the whole
> > >> thing in SSL" doesn't do that.
> > > 
> > > So, having given this some thought, I wanted to come up with a spec just
> > > so that we had something we could all agree on. As part of that, I had a
> > > look at qemu-nbd, and noticed that it uses the "oldstyle" handshake
> > > protocol (on port 10809 by default -- ew, please don't do that).
> > 
> > Can you use new-style handshake with a single unnamed export?  Export
> > names are a useless complication for qemu-nbd.
> 
> Not currently, but I don't think you need that. You could have a default
> name, which would be used if no name was otherwise specified. It's not
> much of a stretch to make that name part of the protocol spec, either.

So. I think this makes sense, and as such changed the proto.txt file as
follows:

diff --git a/doc/proto.txt b/doc/proto.txt
index e0a4fb1..990d012 100644
--- a/doc/proto.txt
+++ b/doc/proto.txt
@@ -242,10 +242,13 @@ Option types
 * NBD_OPT_EXPORT_NAME (1)
   Choose the export which the client would like to use, and end option
   haggling. Data: name of the export, free-form UTF8 text (subject to
   limitations by server implementation). If the chosen export does not
   exist, the server closes the connection.
+  A special, "empty", name (i.e., the length field is zero and no name
+  is specified), is reserved for a "default" export, to be used in cases
+  where explicitly specifying an export name makes no sense.
 
 * NBD_OPT_ABORT (2)
   Abort negotiation and close the connection. Optional.
 
 * NBD_OPT_LIST (3)

That is, specify an empty name to specify a default.

Thoughts?

-- 
It is easy to love a country that is famous for chocolate and beer

  -- Barack Obama, speaking in Brussels, Belgium, 2014-03-26

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


Re: [libvirt] [PATCH v2] hotplug: Fix libvirtd crash on qemu-attached guest

2014-10-08 Thread John Ferlan


On 10/08/2014 12:08 PM, Michal Privoznik wrote:
> On 25.09.2014 17:00, John Ferlan wrote:
>> https://bugzilla.redhat.com/show_bug.cgi?id=1141621
>>
>> The crash in this case was because the qemu-attach code did not create
>> aliases for qemu cli args. When the detach-interface code was called
>> it assumed aliases were set resulting in a core when dereferencing the
>> still NULL alias.
>>
>> Adding a call to qemuAssignDeviceAliases() resolves the path for
>> qemu-attach; however, to prevent future issues an additional check
>> for a NULL value is made and an error provided in the deatch path.
>>
>> Add some more verbiage to the virsh man page.
>>
>> Signed-off-by: John Ferlan 
>> ---
>>
>> v1 is here:
>> http://www.redhat.com/archives/libvir-list/2014-September/msg01331.html
>>
>> Changes since v1:
>>   - Add the call to qemuAssignDeviceAliases() in qemuDomainQemuAttach().
>>   - Move the check for NULL alias inside the CAPS_DEVICE check and emit
>> an error rather than trying to remove as an "else" condition.
>>
>>   src/qemu/qemu_driver.c  | 3 +++
>>   src/qemu/qemu_hotplug.c | 7 +++
>>   tools/virsh.pod | 5 +++--
>>   3 files changed, 13 insertions(+), 2 deletions(-)
>>
>> diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c
>> index 117138a..ef4ecd2 100644
>> --- a/src/qemu/qemu_driver.c
>> +++ b/src/qemu/qemu_driver.c
>> @@ -14746,6 +14746,9 @@ static virDomainPtr 
>> qemuDomainQemuAttach(virConnectPtr conn,
>>   if (qemuCanonicalizeMachine(def, qemuCaps) < 0)
>>   goto cleanup;
>>
>> +if (qemuAssignDeviceAliases(def, qemuCaps) < 0)
>> +goto cleanup;
>> +
>>   if (qemuDomainAssignAddresses(def, qemuCaps, NULL) < 0)
>>   goto cleanup;
>>
>> diff --git a/src/qemu/qemu_hotplug.c b/src/qemu/qemu_hotplug.c
>> index d631887..daebe82 100644
>> --- a/src/qemu/qemu_hotplug.c
>> +++ b/src/qemu/qemu_hotplug.c
>> @@ -3521,6 +3521,13 @@ qemuDomainDetachNetDevice(virConnectPtr conn,
>>
>>   qemuDomainObjEnterMonitor(driver, vm);
>>   if (virQEMUCapsGet(priv->qemuCaps, QEMU_CAPS_DEVICE)) {
>> +if (!detach->info.alias) {
>> +virReportError(VIR_ERR_OPERATION_FAILED, "%s",
>> +   _("device alias not found: cannot delete the "
>> + "net device"));
>> +qemuDomainObjExitMonitor(driver, vm);
>> +goto cleanup;
>> +}
> 
> Is there a reason to not check this upfront rather than this late in the 
> process? And I don't think that net devices are the only thing affected 
> here. For instance a virtio disks seems vulnerable too (well, at first 
> glance on the code).
> 

Recall the environment - 'qemu-attach' and the bz... The bz is specific
for network attach/detach, so I wasn't considering disks, controllers,
hostdevs, and chrdevs when first working through this particular
problem. Although based on some follow-up work (more in a bit) I've
learned a bit more!

Note that the check is specific to when the CAPS_DEVICE is set (IOW,
using the newer device naming syntax). In this case, someone used
-net/-net instead of -netdev/-device and the assumption in the code once
we get to this point that the alias would filled in which without the
qemuAssignDeviceAliases in qemuDomainQemuAttach wouldn't be the case.

A side note is that qemuParseCommandLine() which is what qemu-attach
will use when parsing the command line of the pid that's being attached
to doesn't even handle -netdev, but that's a different issue.

Anyway, even though the alias is there "now" the concern was the effect
if some other path called into here without the alias. Since it only
mattered when CAPS_DEVICE was set, that's why the check is where it is.

The question relating to why not in some other caller is valid; however,
not fool proof since none of the qemuDomainDetach* API's in
qemu_hotplug.c are static. Making the check earlier in the caller of all
those API's qemuDomainDetachDeviceLive is possible, but would have to
avoid the check for DEVICE_LEASE since it doesn't use info.alias.

As for disks (and perhaps other devices) - funny you should mention
that... There's another bz (844845) that I have some patches I'm working
on which actually allow a qemu using the 'id="drive-"' to work.
As of now, starting qemu using the "id=" instead of "index=" will not
allow the qemu-attach to succeed. And yes, I do believe given what I now
know about the code, sure the disk, controller, hostdev, and chrdev
paths could all be affected by the assumption of info.alias being set
(although I don't have working examples of such a detachment).

This is the long winded way of noting yes, it's possible; however, the
example or bz doesn't exist.  I can use this opportunity to make those
checks (in much the same manner) if desired though... Also I'd need to
know if there should be a separate patch for each (turning a 1 patch
change into 5 or 6).

John


>>   if (qemuMonitorDelDevice(priv->mon, detach->info.al

Re: [libvirt] [PATCH 2/2] qemu: change macvtap multicast list in response to NIC_RX_FILTER_CHANGED

2014-10-08 Thread Tony Krowiak

On 10/08/2014 03:15 PM, Laine Stump wrote:

On 10/06/2014 05:37 PM, akrow...@linux.vnet.ibm.com wrote:

From: Tony Krowiak 

This patch adds functionality to processNicRxFilterChangedEvent().
The old and new multicast lists are compared and the filters in
the macvtap are programmed to match the guest's filters.

Signed-off-by: Tony Krowiak 
---
  src/qemu/qemu_driver.c |  138 +++
  1 files changed, 114 insertions(+), 24 deletions(-)

diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c
index 4e2b356..7ff9c38 100644
--- a/src/qemu/qemu_driver.c
+++ b/src/qemu/qemu_driver.c
@@ -4147,6 +4147,106 @@ processDeviceDeletedEvent(virQEMUDriverPtr driver,
  
  
  static void

+syncNicRxFilterMacAddr(char *ifname, virNetDevRxFilterPtr guestFilter,
+   virNetDevRxFilterPtr hostFilter)
+{
+char newMacStr[VIR_MAC_STRING_BUFLEN];
+
+if (virMacAddrCmp(&hostFilter->mac, &guestFilter->mac)) {
+virMacAddrFormat(&guestFilter->mac, newMacStr);
+
+/* set new MAC address from guest to associated macvtap device */
+if (virNetDevSetMAC(ifname, &guestFilter->mac)) {
+VIR_WARN("Couldn't set new MAC address %s to device %s "
+ "while responding to NIC_RX_FILTER_CHANGED",
+ newMacStr, ifname);
+} else {
+VIR_DEBUG("device %s MAC address set to %s", ifname, newMacStr);
+}
+}
+}
+
+
+static void
+syncNicRxFilterGuestMulticast(char *ifname, virNetDevRxFilterPtr guestFilter,
+  virNetDevRxFilterPtr hostFilter)
+{
+size_t i, j;
+bool found;
+char macstr[VIR_MAC_STRING_BUFLEN];
+
+for (i = 0; i < guestFilter->multicast.nTable; i++) {
+found = false;
+
+for (j = 0; j < hostFilter->multicast.nTable; j++) {
+if (virMacAddrCmp(&guestFilter->multicast.table[i],
+  &hostFilter->multicast.table[j]) == 0) {
+found = true;
+break;
+}
+}
+
+if (!found) {
+virMacAddrFormat(&guestFilter->multicast.table[i], macstr);
+
+if (virNetDevAddMulti(ifname, &guestFilter->multicast.table[i])) {
+VIR_WARN("Couldn't add new multicast MAC address %s to "
+ "device %s while responding to NIC_RX_FILTER_CHANGED",
+ macstr, ifname);
+} else {
+VIR_DEBUG("Added multicast MAC %s to %s interface",
+  macstr, ifname);
+}
+}
+}
+}
+
+
+static void
+syncNicRxFilterHostMulticast(char *ifname, virNetDevRxFilterPtr guestFilter,
+ virNetDevRxFilterPtr hostFilter)
+{
+size_t i, j;
+bool found;
+char macstr[VIR_MAC_STRING_BUFLEN];
+
+for (i = 0; i < hostFilter->multicast.nTable; i++) {
+found = false;
+
+for (j = 0; j < guestFilter->multicast.nTable; j++) {
+if (virMacAddrCmp(&hostFilter->multicast.table[i],
+  &guestFilter->multicast.table[j]) == 0) {
+found = true;
+break;
+}
+}
+
+if (!found) {
+virMacAddrFormat(&hostFilter->multicast.table[i], macstr);
+
+if (virNetDevDelMulti(ifname, &hostFilter->multicast.table[i])) {
+VIR_WARN("Couldn't delete multicast MAC address %s from "
+ "device %s while responding to NIC_RX_FILTER_CHANGED",
+ macstr, ifname);
+} else {
+VIR_DEBUG("Deleted multicast MAC %s from %s interface",
+  macstr, ifname);
+}
+}
+}
+}
+
+
+static void
+syncNicRxFilterMulticast(char *ifname,
+ virNetDevRxFilterPtr guestFilter,
+ virNetDevRxFilterPtr hostFilter)
+{
+syncNicRxFilterGuestMulticast(ifname, guestFilter, hostFilter);
+syncNicRxFilterHostMulticast(ifname, guestFilter, hostFilter);

Interesting method. I had planned to sort both lists, then do a single
loop that went through the two in parallel, deleting/adding from the
host interface filter at each step as necessary. Yours works, too,
though. :-)

ACK to this patch. I'll push it along with 1/2 once a new eversion of
that patch has gotten ACK.

BTW, once we're programming the multicast filter, do we need to set any
other mode of the macvtap device in order for this to have a positive
impact on performance? Or does multicast simply not work properly
without this patch (I don't use multicast for anything, and don't have
any tests setup to use multicast).
To be honest, the only testing I did was to make sure that if I added or 
deleted a multicast MAC on the guest, that it showed up in the macvtap 
list on the host.  I am not too networking literate and rely on our 
system test team to flesh out those issues.  The next thing on my 

[libvirt] [PATCH v3 2/2] network: Add code for setting network bandwidth for ethernet interfaces

2014-10-08 Thread Anirban Chakraborty

Signed-off-by: Anirban Chakraborty 
---
 src/conf/domain_conf.h | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/src/conf/domain_conf.h b/src/conf/domain_conf.h
index f03599e..91da1ec 100644
--- a/src/conf/domain_conf.h
+++ b/src/conf/domain_conf.h
@@ -2852,7 +2852,8 @@ static inline bool virNetDevSupportBandwidth(int type)
 {
 return ((type == VIR_DOMAIN_NET_TYPE_BRIDGE ||
  type == VIR_DOMAIN_NET_TYPE_NETWORK ||
- type == VIR_DOMAIN_NET_TYPE_DIRECT) ? true : false);
+ type == VIR_DOMAIN_NET_TYPE_DIRECT ||
+ type == VIR_DOMAIN_NET_TYPE_ETHERNET) ? true : false);
 };

 #endif /* __DOMAIN_CONF_H */
-- 
1.9.1

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


[libvirt] [PATCH v3 1/2] network: Refactor code to add bandwidth support for ethernet interfaces

2014-10-08 Thread Anirban Chakraborty
Modified code to set and clear bandwidth cleanly.

Signed-off-by: Anirban Chakraborty 
---
 src/conf/domain_conf.h  |  7 +++
 src/lxc/lxc_driver.c|  3 +++
 src/lxc/lxc_process.c   | 18 +-
 src/qemu/qemu_command.c | 25 +++--
 src/qemu/qemu_command.h |  2 ++
 src/qemu/qemu_driver.c  |  3 +++
 src/qemu/qemu_hotplug.c | 12 
 src/qemu/qemu_process.c |  3 +++
 src/util/virnetdevmacvlan.c | 10 --
 src/util/virnetdevmacvlan.h |  1 -
 10 files changed, 58 insertions(+), 26 deletions(-)

diff --git a/src/conf/domain_conf.h b/src/conf/domain_conf.h
index afa3da6..f03599e 100644
--- a/src/conf/domain_conf.h
+++ b/src/conf/domain_conf.h
@@ -2848,4 +2848,11 @@ int virDomainObjSetMetadata(virDomainObjPtr vm,
 bool virDomainDefNeedsPlacementAdvice(virDomainDefPtr def)
 ATTRIBUTE_NONNULL(1);

+static inline bool virNetDevSupportBandwidth(int type)
+{
+return ((type == VIR_DOMAIN_NET_TYPE_BRIDGE ||
+ type == VIR_DOMAIN_NET_TYPE_NETWORK ||
+ type == VIR_DOMAIN_NET_TYPE_DIRECT) ? true : false);
+};
+
 #endif /* __DOMAIN_CONF_H */
diff --git a/src/lxc/lxc_driver.c b/src/lxc/lxc_driver.c
index b3e506f..a6f1f8a 100644
--- a/src/lxc/lxc_driver.c
+++ b/src/lxc/lxc_driver.c
@@ -72,6 +72,7 @@
 #include "viraccessapicheck.h"
 #include "viraccessapichecklxc.h"
 #include "virhostdev.h"
+#include "qemu/qemu_command.h"

 #define VIR_FROM_THIS VIR_FROM_LXC

@@ -4634,6 +4635,8 @@ lxcDomainDetachDeviceNetLive(virDomainObjPtr vm,

 detach = vm->def->nets[detachidx];

+qemuDomainClearNetBandwidth(vm);
+
 switch (virDomainNetGetActualType(detach)) {
 case VIR_DOMAIN_NET_TYPE_BRIDGE:
 case VIR_DOMAIN_NET_TYPE_NETWORK:
diff --git a/src/lxc/lxc_process.c b/src/lxc/lxc_process.c
index ed30c37..3192011 100644
--- a/src/lxc/lxc_process.c
+++ b/src/lxc/lxc_process.c
@@ -274,11 +274,6 @@ char *virLXCProcessSetupInterfaceBridged(virConnectPtr 
conn,
 if (virNetDevSetOnline(parentVeth, true) < 0)
 goto cleanup;

-if (virNetDevBandwidthSet(net->ifname,
-  virDomainNetGetActualBandwidth(net),
-  false) < 0)
-goto cleanup;
-
 if (net->filter &&
 virDomainConfNWFilterInstantiate(conn, vm->uuid, net) < 0)
 goto cleanup;
@@ -300,6 +295,7 @@ char *virLXCProcessSetupInterfaceDirect(virConnectPtr conn,
 virNetDevBandwidthPtr bw;
 virNetDevVPortProfilePtr prof;
 virLXCDriverConfigPtr cfg = virLXCDriverGetConfig(driver);
+const char *linkdev = virDomainNetGetActualDirectDev(net);

 /* XXX how todo bandwidth controls ?
  * Since the 'net-ifname' is about to be moved to a different
@@ -329,14 +325,13 @@ char *virLXCProcessSetupInterfaceDirect(virConnectPtr 
conn,

 if (virNetDevMacVLanCreateWithVPortProfile(
 net->ifname, &net->mac,
-virDomainNetGetActualDirectDev(net),
+linkdev,
 virDomainNetGetActualDirectMode(net),
 false, def->uuid,
-virDomainNetGetActualVirtPortProfile(net),
+prof,
 &res_ifname,
 VIR_NETDEV_VPORT_PROFILE_OP_CREATE,
-cfg->stateDir,
-virDomainNetGetActualBandwidth(net), 0) < 0)
+cfg->stateDir, 0) < 0)
 goto cleanup;

 ret = res_ifname;
@@ -450,6 +445,11 @@ static int virLXCProcessSetupInterfaces(virConnectPtr conn,
 goto cleanup;
 }

+/* set network bandwidth */
+if (virNetDevBandwidthSet(def->nets[i]->ifname,
+virDomainNetGetActualBandwidth(def->nets[i]), false) < 0)
+   goto cleanup;
+
 (*veths)[(*nveths)-1] = veth;

 /* Make sure all net definitions will have a name in the container */
diff --git a/src/qemu/qemu_command.c b/src/qemu/qemu_command.c
index 8cb0865..3635712 100644
--- a/src/qemu/qemu_command.c
+++ b/src/qemu/qemu_command.c
@@ -191,7 +191,6 @@ qemuPhysIfaceConnect(virDomainDefPtr def,
 virDomainNetGetActualVirtPortProfile(net),
 &res_ifname,
 vmop, cfg->stateDir,
-virDomainNetGetActualBandwidth(net),
 macvlan_create_flags);
 if (rc >= 0) {
 virDomainAuditNetDevice(def, net, res_ifname, true);
@@ -371,11 +370,6 @@ qemuNetworkIfaceConnect(virDomainDefPtr def,
   &net->mac) < 0)
 goto cleanup;

-if (virNetDevBandwidthSet(net->ifname,
-  virDomainNetGetActualBandwidth(net),
-  false) < 0)
-goto cleanup;
-
 if (net->filter &&
 virDomainConfNWFilterInstantiate(conn, def->uuid, net) < 0) {
 goto cleanup;
@@ -7427,6 +7421,13 @@ qemuBuildInterfaceCommandLine(virCommandPtr cmd,
 goto cleanup;
 }

+/* Set Bandwidth */
+if (virNetDevSupportBandwidth(actualType) &&
+   virNetDevBandwidthSet(net->ifname,
+   virDomainNetGetActualBandwidth(net),
+ 

[libvirt] [PATCH v3 0/2] network: Add network bandwidth for ethernet type interfaces

2014-10-08 Thread Anirban Chakraborty
V3:
Addressed issues pointed out in V2
Split into two patches

V2:
Addressed comments raised in review of V1.
Consolidate calls to virNetDevBandwidthSet.
Clear bandwidth settings when the interface is detached or domain
destroyed.

V1:
Ethernet interfaces in libvirt currently do not support bandwidth setting.
For example, following xml file for an interface will not apply these
settings to corresponding qdiscs.

Signed-off-by: Anirban Chakraborty 

Anirban Chakraborty (2):
network: Refactor code to add bandwidth support for ethernet interfaces
network: Add code for setting bandwidth for ethernet interfaces

 src/conf/domain_conf.h  |  8 
 src/lxc/lxc_driver.c|  3 +++
 src/lxc/lxc_process.c   | 18 +-
 src/qemu/qemu_command.c | 25 +++--
 src/qemu/qemu_command.h |  2 ++
 src/qemu/qemu_driver.c  |  3 +++
 src/qemu/qemu_hotplug.c | 12 
 src/qemu/qemu_process.c |  3 +++
 src/util/virnetdevmacvlan.c | 10 --
 src/util/virnetdevmacvlan.h |  1 -
 10 files changed, 59 insertions(+), 26 deletions(-)

-- 
1.9.1

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


Re: [libvirt] [PATCH 2/2] qemu: change macvtap multicast list in response to NIC_RX_FILTER_CHANGED

2014-10-08 Thread Laine Stump
On 10/06/2014 05:37 PM, akrow...@linux.vnet.ibm.com wrote:
> From: Tony Krowiak 
>
> This patch adds functionality to processNicRxFilterChangedEvent().
> The old and new multicast lists are compared and the filters in
> the macvtap are programmed to match the guest's filters.
>
> Signed-off-by: Tony Krowiak 
> ---
>  src/qemu/qemu_driver.c |  138 +++
>  1 files changed, 114 insertions(+), 24 deletions(-)
>
> diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c
> index 4e2b356..7ff9c38 100644
> --- a/src/qemu/qemu_driver.c
> +++ b/src/qemu/qemu_driver.c
> @@ -4147,6 +4147,106 @@ processDeviceDeletedEvent(virQEMUDriverPtr driver,
>  
>  
>  static void
> +syncNicRxFilterMacAddr(char *ifname, virNetDevRxFilterPtr guestFilter,
> +   virNetDevRxFilterPtr hostFilter)
> +{
> +char newMacStr[VIR_MAC_STRING_BUFLEN];
> +
> +if (virMacAddrCmp(&hostFilter->mac, &guestFilter->mac)) {
> +virMacAddrFormat(&guestFilter->mac, newMacStr);
> +
> +/* set new MAC address from guest to associated macvtap device */
> +if (virNetDevSetMAC(ifname, &guestFilter->mac)) {
> +VIR_WARN("Couldn't set new MAC address %s to device %s "
> + "while responding to NIC_RX_FILTER_CHANGED",
> + newMacStr, ifname);
> +} else {
> +VIR_DEBUG("device %s MAC address set to %s", ifname, newMacStr);
> +}
> +}
> +}
> +
> +
> +static void
> +syncNicRxFilterGuestMulticast(char *ifname, virNetDevRxFilterPtr guestFilter,
> +  virNetDevRxFilterPtr hostFilter)
> +{
> +size_t i, j;
> +bool found;
> +char macstr[VIR_MAC_STRING_BUFLEN];
> +
> +for (i = 0; i < guestFilter->multicast.nTable; i++) {
> +found = false;
> +
> +for (j = 0; j < hostFilter->multicast.nTable; j++) {
> +if (virMacAddrCmp(&guestFilter->multicast.table[i],
> +  &hostFilter->multicast.table[j]) == 0) {
> +found = true;
> +break;
> +}
> +}
> +
> +if (!found) {
> +virMacAddrFormat(&guestFilter->multicast.table[i], macstr);
> +
> +if (virNetDevAddMulti(ifname, &guestFilter->multicast.table[i])) 
> {
> +VIR_WARN("Couldn't add new multicast MAC address %s to "
> + "device %s while responding to 
> NIC_RX_FILTER_CHANGED",
> + macstr, ifname);
> +} else {
> +VIR_DEBUG("Added multicast MAC %s to %s interface",
> +  macstr, ifname);
> +}
> +}
> +}
> +}
> +
> +
> +static void
> +syncNicRxFilterHostMulticast(char *ifname, virNetDevRxFilterPtr guestFilter,
> + virNetDevRxFilterPtr hostFilter)
> +{
> +size_t i, j;
> +bool found;
> +char macstr[VIR_MAC_STRING_BUFLEN];
> +
> +for (i = 0; i < hostFilter->multicast.nTable; i++) {
> +found = false;
> +
> +for (j = 0; j < guestFilter->multicast.nTable; j++) {
> +if (virMacAddrCmp(&hostFilter->multicast.table[i],
> +  &guestFilter->multicast.table[j]) == 0) {
> +found = true;
> +break;
> +}
> +}
> +
> +if (!found) {
> +virMacAddrFormat(&hostFilter->multicast.table[i], macstr);
> +
> +if (virNetDevDelMulti(ifname, &hostFilter->multicast.table[i])) {
> +VIR_WARN("Couldn't delete multicast MAC address %s from "
> + "device %s while responding to 
> NIC_RX_FILTER_CHANGED",
> + macstr, ifname);
> +} else {
> +VIR_DEBUG("Deleted multicast MAC %s from %s interface",
> +  macstr, ifname);
> +}
> +}
> +}
> +}
> +
> +
> +static void
> +syncNicRxFilterMulticast(char *ifname,
> + virNetDevRxFilterPtr guestFilter,
> + virNetDevRxFilterPtr hostFilter)
> +{
> +syncNicRxFilterGuestMulticast(ifname, guestFilter, hostFilter);
> +syncNicRxFilterHostMulticast(ifname, guestFilter, hostFilter);

Interesting method. I had planned to sort both lists, then do a single
loop that went through the two in parallel, deleting/adding from the
host interface filter at each step as necessary. Yours works, too,
though. :-)

ACK to this patch. I'll push it along with 1/2 once a new eversion of
that patch has gotten ACK.

BTW, once we're programming the multicast filter, do we need to set any
other mode of the macvtap device in order for this to have a positive
impact on performance? Or does multicast simply not work properly
without this patch (I don't use multicast for anything, and don't have
any tests setup to use multicast).

> +}
> +
> +static void
>  processNicRxFilterChangedEvent(virQEMUDriverPtr driver,
>  

Re: [libvirt] [PATCH 1/2] util: Functions to update host network device's multicast filter

2014-10-08 Thread Laine Stump
On 10/08/2014 01:41 PM, Tony Krowiak wrote:
>> Otherwise it looks okay. As we've discussed, it would be nice to use
>> netlink instead of /proc/net and ioctl(), but that can be added later.
> I agree.  When I originally started working on this, that was my plan,
> however; after spending days trying to understand how to use netlink
> to do retrieve the multicast list, I gave up when I found that
> iproute2 does it by reading the file.  Can you point me to some good,
> detailed netlink documentation?  I've googled for it, looked at code
> examples and experimented by writing code snippets and have not been
> able to figure out how to retrieve the multicast list using netlink. 

No :-( That is a *big* problem with netlink, and I went through the same
journey as you (although probably spent less time, as you sent your
first message when I'd only been looking at it for a day or so).

I *think* there is a libnl cache that can be used to retrieve the
multicast list (look for the libnl-devel mailing list archives for a
message I sent there several days ago, along with a couple of
responses), but it's definitely not as straightforward as reading a file
in /proc.

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


Re: [libvirt] [PATCH 1/2] util: Functions to update host network device's multicast filter

2014-10-08 Thread Tony Krowiak

On 10/08/2014 11:36 AM, Laine Stump wrote:

On 10/06/2014 05:37 PM, akrow...@linux.vnet.ibm.com wrote:

From: Tony Krowiak 

This patch provides the utility functions to needed to synchronize the
changes made to a guest domain network device's multicast filter
with the corresponding macvtap device's filter on the host:

* Get/add/remove multicast MAC addresses
* Get the macvtap device's RX filter list

Signed-off-by: Tony Krowiak 
---
  src/libvirt_private.syms |4 +
  src/util/virmacaddr.c|   37 +
  src/util/virmacaddr.h|4 +
  src/util/virnetdev.c |  360 ++
  src/util/virnetdev.h |   11 ++
  5 files changed, 416 insertions(+), 0 deletions(-)

diff --git a/src/libvirt_private.syms b/src/libvirt_private.syms
index d6265ac..6d06a2c 100644
--- a/src/libvirt_private.syms
+++ b/src/libvirt_private.syms
@@ -1590,13 +1590,16 @@ virMacAddrIsBroadcastRaw;
  virMacAddrIsMulticast;
  virMacAddrIsUnicast;
  virMacAddrParse;
+virMacAddrParseHex;
  virMacAddrSet;
  virMacAddrSetRaw;
  
  
  # util/virnetdev.h

+virNetDevAddMulti;
  virNetDevAddRoute;
  virNetDevClearIPv4Address;
+virNetDevDelMulti;
  virNetDevExists;
  virNetDevGetIndex;
  virNetDevGetIPv4Address;
@@ -1604,6 +1607,7 @@ virNetDevGetLinkInfo;
  virNetDevGetMAC;
  virNetDevGetMTU;
  virNetDevGetPhysicalFunction;
+virNetDevGetRxFilter;
  virNetDevGetVirtualFunctionIndex;
  virNetDevGetVirtualFunctionInfo;
  virNetDevGetVirtualFunctions;
diff --git a/src/util/virmacaddr.c b/src/util/virmacaddr.c
index ebd1182..ae5e5d2 100644
--- a/src/util/virmacaddr.c
+++ b/src/util/virmacaddr.c
@@ -198,6 +198,43 @@ virMacAddrFormat(const virMacAddr *addr,
  return str;
  }
  
+/**

+ * virMacAddrParseHex:
+ * @str: string hexadecimal representation of MAC address, e.g., "F801EFCE3aCB"
+ * @addr: 6-byte MAC address
+ *
+ * Parse the hexadecimal representation of a MAC address
+ *
+ * Return 0 upon success, or -1 in case of error.
+ */
+int
+virMacAddrParseHex(const char* str, virMacAddrPtr addr)
+{
+if (strlen(str) != VIR_MAC_HEXLEN)
+return -1;
+
+size_t iaddr;
+size_t istr;
+
+
+for (istr = 0, iaddr = 0; iaddr < VIR_MAC_BUFLEN; istr += 2, iaddr++) {
+unsigned int hex;
+
+if (sscanf(&str[istr], "%02x", &hex) != 1)
+break;

I'm not keen on sscanf(), but since we're already using it elsewhere,
and the existing virMacAddrParse uses the normally-blacklisted strtoul()
(and using virStrToLong_ui() on pieces of the string would require a
terminating character after each piece), I don't have a ready answer for
an alternative.

Eric, do you have an opinion on this? Is sscanf okay when we want to parse:

  

of hex digits into 6 binary bytes?

See my response to Eric's response.




+
+if (hex > UCHAR_MAX)
+break;
+
+addr->addr[iaddr] = hex;
+}
+
+if (istr == VIR_MAC_HEXLEN)
+return 0;
+
+return -1;
+}
+
  void virMacAddrGenerate(const unsigned char prefix[VIR_MAC_PREFIX_BUFLEN],
  virMacAddrPtr addr)
  {
diff --git a/src/util/virmacaddr.h b/src/util/virmacaddr.h
index 49efc36..72a285a 100644
--- a/src/util/virmacaddr.h
+++ b/src/util/virmacaddr.h
@@ -27,6 +27,7 @@
  # include "internal.h"
  
  # define VIR_MAC_BUFLEN 6

+#define VIR_MAC_HEXLEN (VIR_MAC_BUFLEN * 2)
  # define VIR_MAC_PREFIX_BUFLEN 3
  # define VIR_MAC_STRING_BUFLEN (VIR_MAC_BUFLEN * 3)
  
@@ -50,6 +51,9 @@ void virMacAddrGenerate(const unsigned char prefix[VIR_MAC_PREFIX_BUFLEN],

  virMacAddrPtr addr);
  int virMacAddrParse(const char* str,
  virMacAddrPtr addr) ATTRIBUTE_RETURN_CHECK;
+int virMacAddrParseHex(const char* str,
+   virMacAddrPtr addr)
+ATTRIBUTE_NONNULL(1) ATTRIBUTE_NONNULL(2) ATTRIBUTE_RETURN_CHECK;
  bool virMacAddrIsUnicast(const virMacAddr *addr);
  bool virMacAddrIsMulticast(const virMacAddr *addr);
  bool virMacAddrIsBroadcastRaw(const unsigned char s[VIR_MAC_BUFLEN]);
diff --git a/src/util/virnetdev.c b/src/util/virnetdev.c
index db5623a..5e53f5f 100644
--- a/src/util/virnetdev.c
+++ b/src/util/virnetdev.c
@@ -56,6 +56,33 @@
  
  VIR_LOG_INIT("util.netdev");
  
+# define VIR_MCAST_NAME_LEN (IFNAMSIZ + 1)

+# define VIR_MCAST_INDEX_TOKEN_IDX 0
+# define VIR_MCAST_NAME_TOKEN_IDX 1
+# define VIR_MCAST_USERS_TOKEN_IDX 2
+# define VIR_MCAST_GLOBAL_TOKEN_IDX 3
+# define VIR_MCAST_ADDR_TOKEN_IDX 4
+# define VIR_MCAST_NUM_TOKENS 5
+# define VIR_MCAST_TOKEN_DELIMS " \n"
+# define VIR_MCAST_ADDR_LEN (VIR_MAC_HEXLEN + 1)
+
+typedef struct _virNetDevMcastEntry virNetDevMcastEntry;
+typedef virNetDevMcastEntry *virNetDevMcastEntryPtr;
+struct _virNetDevMcastEntry  {
+int index;
+char name[VIR_MCAST_NAME_LEN];
+int users;
+bool global;
+virMacAddr macaddr;
+};
+
+typedef struct _virNetDevMcast virNetDevMcast;
+typedef virNetDevMcast *virNetDevMcastPtr;
+struct _virNetDevMcast {
+size_t

Re: [libvirt] [PATCH 1/2] util: Functions to update host network device's multicast filter

2014-10-08 Thread Tony Krowiak

On 10/08/2014 12:59 PM, Eric Blake wrote:

On 10/08/2014 09:36 AM, Laine Stump wrote:

On 10/06/2014 05:37 PM, akrow...@linux.vnet.ibm.com wrote:

From: Tony Krowiak 

This patch provides the utility functions to needed to synchronize the
changes made to a guest domain network device's multicast filter
with the corresponding macvtap device's filter on the host:

* Get/add/remove multicast MAC addresses
* Get the macvtap device's RX filter list

Signed-off-by: Tony Krowiak 
---
+/**
+ * virMacAddrParseHex:
+ * @str: string hexadecimal representation of MAC address, e.g., "F801EFCE3aCB"
+ * @addr: 6-byte MAC address
+ *
+ * Parse the hexadecimal representation of a MAC address
+ *
+ * Return 0 upon success, or -1 in case of error.
+ */
+int
+virMacAddrParseHex(const char* str, virMacAddrPtr addr)

Wrong spacing around '*'.

I will fix that.



+{
+if (strlen(str) != VIR_MAC_HEXLEN)
+return -1;
+
+size_t iaddr;
+size_t istr;
+
+
+for (istr = 0, iaddr = 0; iaddr < VIR_MAC_BUFLEN; istr += 2, iaddr++) {
+unsigned int hex;
+
+if (sscanf(&str[istr], "%02x", &hex) != 1)
+break;

I'm not keen on sscanf(), but since we're already using it elsewhere,
and the existing virMacAddrParse uses the normally-blacklisted strtoul()
(and using virStrToLong_ui() on pieces of the string would require a
terminating character after each piece), I don't have a ready answer for
an alternative.

Why not just open-code it?  It's just two input bytes per iteration, and
we already have a helper function that makes it a very short function.
And strspn makes it easy to do input validation before starting the loop:

int
virMacAddrParseHex(const char *str, virMacAddrPtr addr)
{
 size_t i;

 if (strspn(str, "0123456789abcdefABCDEF") != VIR_MAC_HEXLEN ||
 str[VIR_MAC_HEXLEN])
 return -1;

 for (i = 0; i < VIR_MAC_BUFLEN; i++)
 addr->addr[i] = (virHexToBin(str[2 * i]) << 4 |
  virHexToBin(str[2 * i + 1]));
 return 0;
}

Looks good, I'll put that in.




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


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

Re: [libvirt] [PATCH v3 1/3] docs, conf, schema: add support for shmem device

2014-10-08 Thread Michal Privoznik

On 08.10.2014 18:57, Maxime Leroy wrote:

Hi Martin,

On Fri, Oct 3, 2014 at 10:45 PM, Martin Kletzander  wrote:

On Thu, Oct 02, 2014 at 09:42:36AM +0200, Michal Privoznik wrote:


On 26.09.2014 12:43, Martin Kletzander wrote:


diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c
index b114737..51bdd31 100644
--- a/src/conf/domain_conf.c
+++ b/src/conf/domain_conf.c




[..]




Nice catch.

Since we are past the release anyway, I'm going to push this in a
while and whoever wants (e.g. Maxime) have the whole release cycle to
test this.



Thanks for pushing/cleaning the shmem patches support (i.e
http://www.redhat.com/archives/libvir-list/2014-August/msg01032.html)

But you did miss the following:

1. the ivshmem server autostart feature: you wanted me to develop it
into the v1. (i.e.
http://www.redhat.com/archives/libvir-list/2014-August/msg01432.html)

2. You did not wait for my tests. Why should I ask you to wait for my tests?
Lucky enough, now I have the results of the tests, everything works fine ;)

I don't understand why it became so urgent to push these patches.


Well, I'm not intending to speak on Martin's behalf, but my workflow is 
as follows: when developing a new code I create a local branch and put 
the commits there. And as the development goes on, I keep the branch 
rebased onto the current master. However, depending on the complexity of 
the code, rebase conflicts are likely to occur - and that's rather 
unpleasant. So once the patches are ready I'm pushing them nearly ASAP 
for two reasons: to get rid of the rebasing (others may be working in 
the same area in near future too, so I'd spare them having rebase 
conflicts), and to test the feature. As soon as an pubclic API is not 
released, there's still an possibility to revert the patches if they 
turn out to be rubbish.


So I'd say you both (you and Martin) obeyed the process. You've tested 
an upstream code. If it turned out that there's something wrong we could 
just fix it.


Michal

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


Re: [libvirt] [PATCH 1/2] util: Functions to update host network device's multicast filter

2014-10-08 Thread Eric Blake
On 10/08/2014 09:36 AM, Laine Stump wrote:
> On 10/06/2014 05:37 PM, akrow...@linux.vnet.ibm.com wrote:
>> From: Tony Krowiak 
>>
>> This patch provides the utility functions to needed to synchronize the
>> changes made to a guest domain network device's multicast filter
>> with the corresponding macvtap device's filter on the host:
>>
>> * Get/add/remove multicast MAC addresses
>> * Get the macvtap device's RX filter list
>>
>> Signed-off-by: Tony Krowiak 
>> ---

>> +/**
>> + * virMacAddrParseHex:
>> + * @str: string hexadecimal representation of MAC address, e.g., 
>> "F801EFCE3aCB"
>> + * @addr: 6-byte MAC address
>> + *
>> + * Parse the hexadecimal representation of a MAC address
>> + *
>> + * Return 0 upon success, or -1 in case of error.
>> + */
>> +int
>> +virMacAddrParseHex(const char* str, virMacAddrPtr addr)

Wrong spacing around '*'.

>> +{
>> +if (strlen(str) != VIR_MAC_HEXLEN)
>> +return -1;
>> +
>> +size_t iaddr;
>> +size_t istr;
>> +
>> +
>> +for (istr = 0, iaddr = 0; iaddr < VIR_MAC_BUFLEN; istr += 2, iaddr++) {
>> +unsigned int hex;
>> +
>> +if (sscanf(&str[istr], "%02x", &hex) != 1)
>> +break;
> 
> I'm not keen on sscanf(), but since we're already using it elsewhere,
> and the existing virMacAddrParse uses the normally-blacklisted strtoul()
> (and using virStrToLong_ui() on pieces of the string would require a
> terminating character after each piece), I don't have a ready answer for
> an alternative.

Why not just open-code it?  It's just two input bytes per iteration, and
we already have a helper function that makes it a very short function.
And strspn makes it easy to do input validation before starting the loop:

int
virMacAddrParseHex(const char *str, virMacAddrPtr addr)
{
size_t i;

if (strspn(str, "0123456789abcdefABCDEF") != VIR_MAC_HEXLEN ||
str[VIR_MAC_HEXLEN])
return -1;

for (i = 0; i < VIR_MAC_BUFLEN; i++)
addr->addr[i] = (virHexToBin(str[2 * i]) << 4 |
 virHexToBin(str[2 * i + 1]));
return 0;
}

-- 
Eric Blake   eblake redhat com+1-919-301-3266
Libvirt virtualization library http://libvirt.org



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

Re: [libvirt] [PATCH v3 1/3] docs, conf, schema: add support for shmem device

2014-10-08 Thread Maxime Leroy
Hi Martin,

On Fri, Oct 3, 2014 at 10:45 PM, Martin Kletzander  wrote:
> On Thu, Oct 02, 2014 at 09:42:36AM +0200, Michal Privoznik wrote:
>>
>> On 26.09.2014 12:43, Martin Kletzander wrote:
>>>
>>> diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c
>>> index b114737..51bdd31 100644
>>> --- a/src/conf/domain_conf.c
>>> +++ b/src/conf/domain_conf.c
>>
>>
[..]
>>
>
> Nice catch.
>
> Since we are past the release anyway, I'm going to push this in a
> while and whoever wants (e.g. Maxime) have the whole release cycle to
> test this.
>

Thanks for pushing/cleaning the shmem patches support (i.e
http://www.redhat.com/archives/libvir-list/2014-August/msg01032.html)

But you did miss the following:

1. the ivshmem server autostart feature: you wanted me to develop it
into the v1. (i.e.
http://www.redhat.com/archives/libvir-list/2014-August/msg01432.html)

2. You did not wait for my tests. Why should I ask you to wait for my tests?
Lucky enough, now I have the results of the tests, everything works fine ;)

I don't understand why it became so urgent to push these patches.

Anyway, I am glad that libvirt supports ivshmem.

Since now you pushed these patches, do you plan to provide the ivshmem
autostart feature like you requested previously ?

I'll be glad to review it and to provide feedbacks based on my tests.

Maxime

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


Re: [libvirt] [PATCH] security_selinux: Don't relabel /dev/net/tun

2014-10-08 Thread Eric Blake
On 10/08/2014 07:23 AM, Michal Privoznik wrote:

>>> +if (!STRPREFIX(fd_path, "/dev/tap")) {
>>
>> Should this be "/dev/tap.", since...
>>
>>> +VIR_DEBUG("fd=%d points to %s not setting SELinux label",
>>> +  fd, fd_path);
>>> +rc = 0;
>>> +goto cleanup;
>>> +}
>>> +
>>>   if (getContext(mgr, "/dev/tap.*", buf.st_mode, &fcon) < 0) {
>>
>> ...you require a '.' in the context lookup?  Without the '.' in the
>> filter, you would let the (unlikely) name '/dev/tapX' get through.
>>
>> ACK with that tweaked.
>>
>>
> 
> In fact, /dev/tapX is what is created. getContext should be using it too
> as it accepts shell expendable names, not regular expressions. I'm
> adjusting getContext's argument too.

I assume "shell expendable" meant "glob" :)

Oh wow - so you're saying the only reason this even worked is that
getContext was getting lucky and realizing that any file that matches
the stricter glob '/dev/tap.*' also matches the looser glob '/dev/tap*',
and that we were lucky the context rule we were trying to look up was
not written against a tighter glob such as '/dev/tap[0-9]*'.

Yes, you've convinced me that the name really is /dev/tapX and that
removing the spurious '.' in the call to getContext is correct.

-- 
Eric Blake   eblake redhat com+1-919-301-3266
Libvirt virtualization library http://libvirt.org



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

[libvirt] [PATCH v2 1/21] hyperv: avoid query memleaks on failure

2014-10-08 Thread Eric Blake
The function hypervEnumAndPull consumes query on success, but leaked
it on failure.  Rather than having to change all callers (many of
them indirect callers through the generated
hypervGetMsvmComputerSystemList), it was easier to just guarantee
that the buffer is cleaned on return from the function.

Reported by Yves Vinter.

* src/hyperv/hyperv_wmi.c (hypervEnumAndPull): Don't leak query on
failure.

Signed-off-by: Eric Blake 
---
 src/hyperv/hyperv_wmi.c | 37 +
 1 file changed, 21 insertions(+), 16 deletions(-)

diff --git a/src/hyperv/hyperv_wmi.c b/src/hyperv/hyperv_wmi.c
index acb705c..3027601 100644
--- a/src/hyperv/hyperv_wmi.c
+++ b/src/hyperv/hyperv_wmi.c
@@ -2,6 +2,7 @@
  * hyperv_wmi.c: general WMI over WSMAN related functions and structures for
  *   managing Microsoft Hyper-V hosts
  *
+ * Copyright (C) 2014 Red Hat, Inc.
  * Copyright (C) 2011 Matthias Bolte 
  * Copyright (C) 2009 Michael Sievers 
  *
@@ -105,6 +106,7 @@ hyperyVerifyResponse(WsManClient *client, WsXmlDocH 
response,
  * Object
  */

+/* This function guarantees that query is freed, even on failure */
 int
 hypervEnumAndPull(hypervPrivate *priv, virBufferPtr query, const char *root,
   XmlSerializerInfo *serializerInfo, const char *resourceUri,
@@ -123,25 +125,28 @@ hypervEnumAndPull(hypervPrivate *priv, virBufferPtr 
query, const char *root,
 XML_TYPE_PTR data = NULL;
 hypervObject *object;

-if (list == NULL || *list != NULL) {
-virReportError(VIR_ERR_INTERNAL_ERROR, "%s", _("Invalid argument"));
+if (virBufferCheckError(query) < 0) {
+virBufferFreeAndReset(query);
 return -1;
 }
-
-if (virBufferCheckError(query) < 0)
-return -1;
-
-serializerContext = wsmc_get_serialization_context(priv->client);
-
-options = wsmc_options_init();
-
-if (options == NULL) {
-virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
-   _("Could not initialize options"));
-goto cleanup;
-}
-
 query_string = virBufferContentAndReset(query);
+
+if (list == NULL || *list != NULL) {
+virReportError(VIR_ERR_INTERNAL_ERROR, "%s", _("Invalid argument"));
+VIR_FREE(query_string);
+return -1;
+}
+
+serializerContext = wsmc_get_serialization_context(priv->client);
+
+options = wsmc_options_init();
+
+if (options == NULL) {
+virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
+   _("Could not initialize options"));
+goto cleanup;
+}
+
 filter = filter_create_simple(WSM_WQL_FILTER_DIALECT, query_string);

 if (filter == NULL) {
-- 
1.9.3

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


Re: [libvirt] [PATCH 01/21] Added missing virBufferFreeAndReset on the query buffer to free some memory

2014-10-08 Thread Eric Blake
On 10/08/2014 06:33 AM, Yves Vinter wrote:
> From: yvinter 

Your git config is incorrect; your email headers list your full name
'Yves Vinter' but this line means that git is trying to attribute to the
authorship to your username 'yvinter'.  We prefer that the git history
include a full legal name rather than a username abbreviation.

Long subject line; the first line of a commit message should generally
be no more than about 60 characters, so that 'git log --oneline -30'
still fits the information comfortably in an 80-column screen.  Also, it
is nice to include a 'topic:' lead-in.  Ideally, the one-line summary is
the "what", and then the rest of the commit message after a blank line
is the "why".  So I suggest:

hyperv: avoid memory leaks

Add missing virBufferFreeAndReset on query buffers used throughout the
hyperv code.

as well as mention any valgrind testing you did to prove that the leaks
are fixed.

> +++ b/src/hyperv/hyperv_driver.c
> @@ -201,6 +201,7 @@ hypervConnectOpen(virConnectPtr conn, virConnectAuthPtr 
> auth, unsigned int flags
>  VIR_FREE(username);
>  VIR_FREE(password);
>  hypervFreeObject(priv, (hypervObject *)computerSystem);
> +virBufferFreeAndReset(&query);

Hmmm.  query is initialized empty, until it is used in this code a few
lines earlier:


virBufferAddLit(&query, MSVM_COMPUTERSYSTEM_WQL_SELECT);
virBufferAddLit(&query, "where ");
virBufferAddLit(&query, MSVM_COMPUTERSYSTEM_WQL_PHYSICAL);

if (hypervGetMsvmComputerSystemList(priv, &query, &computerSystem) <
0) {
goto cleanup;

but tracing through that code, hypervGetMsvmComputerSystemList in
hyperv_wmi.generated.c calls hypervEnumAndPull in hyperv_wmi.c, which in
turn calls virBufferContentAndReset(query) on the success path, leaving
nothing to clean up here.  Okay, I see where hypervEnumAndPull can
return early without cleaning query; I wonder if it would have been
better to patch THAT function to guarantee that the buffer is always
clean on return, rather than having to patch every single caller.

In fact, after looking through the entire patch, it looks like EVERY
single addition of virBufferFreeAndReset(&query) is only ever useful in
any case where hypervEnumAndPull returns early.

I'm going to reply to this mail with an alternative shorter patch.  I
don't have access to hyperv to test it under an actual valgrind run, but
it compiled for me.  Can you please run it through your test setup to
see if it solves the issues you were initially trying to address?

-- 
Eric Blake   eblake redhat com+1-919-301-3266
Libvirt virtualization library http://libvirt.org



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

Re: [libvirt] [PATCH v2] hotplug: Fix libvirtd crash on qemu-attached guest

2014-10-08 Thread Michal Privoznik

On 25.09.2014 17:00, John Ferlan wrote:

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

The crash in this case was because the qemu-attach code did not create
aliases for qemu cli args. When the detach-interface code was called
it assumed aliases were set resulting in a core when dereferencing the
still NULL alias.

Adding a call to qemuAssignDeviceAliases() resolves the path for
qemu-attach; however, to prevent future issues an additional check
for a NULL value is made and an error provided in the deatch path.

Add some more verbiage to the virsh man page.

Signed-off-by: John Ferlan 
---

v1 is here:
http://www.redhat.com/archives/libvir-list/2014-September/msg01331.html

Changes since v1:
  - Add the call to qemuAssignDeviceAliases() in qemuDomainQemuAttach().
  - Move the check for NULL alias inside the CAPS_DEVICE check and emit
an error rather than trying to remove as an "else" condition.

  src/qemu/qemu_driver.c  | 3 +++
  src/qemu/qemu_hotplug.c | 7 +++
  tools/virsh.pod | 5 +++--
  3 files changed, 13 insertions(+), 2 deletions(-)

diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c
index 117138a..ef4ecd2 100644
--- a/src/qemu/qemu_driver.c
+++ b/src/qemu/qemu_driver.c
@@ -14746,6 +14746,9 @@ static virDomainPtr qemuDomainQemuAttach(virConnectPtr 
conn,
  if (qemuCanonicalizeMachine(def, qemuCaps) < 0)
  goto cleanup;

+if (qemuAssignDeviceAliases(def, qemuCaps) < 0)
+goto cleanup;
+
  if (qemuDomainAssignAddresses(def, qemuCaps, NULL) < 0)
  goto cleanup;

diff --git a/src/qemu/qemu_hotplug.c b/src/qemu/qemu_hotplug.c
index d631887..daebe82 100644
--- a/src/qemu/qemu_hotplug.c
+++ b/src/qemu/qemu_hotplug.c
@@ -3521,6 +3521,13 @@ qemuDomainDetachNetDevice(virConnectPtr conn,

  qemuDomainObjEnterMonitor(driver, vm);
  if (virQEMUCapsGet(priv->qemuCaps, QEMU_CAPS_DEVICE)) {
+if (!detach->info.alias) {
+virReportError(VIR_ERR_OPERATION_FAILED, "%s",
+   _("device alias not found: cannot delete the "
+ "net device"));
+qemuDomainObjExitMonitor(driver, vm);
+goto cleanup;
+}


Is there a reason to not check this upfront rather than this late in the 
process? And I don't think that net devices are the only thing affected 
here. For instance a virtio disks seems vulnerable too (well, at first 
glance on the code).



  if (qemuMonitorDelDevice(priv->mon, detach->info.alias) < 0) {


The other possibility would be to make qemuMonitorDelDevice fail on 
@devalias == NULL.



  qemuDomainObjExitMonitor(driver, vm);
  virDomainAuditNet(vm, detach, NULL, "detach", false);
diff --git a/tools/virsh.pod b/tools/virsh.pod
index eae9195..bd17f68 100644
--- a/tools/virsh.pod
+++ b/tools/virsh.pod
@@ -3698,8 +3698,9 @@ using the UNIX driver. Ideally the process will also have 
had the

  Not all functions of libvirt are expected to work reliably after
  attaching to an externally launched QEMU process. There may be
-issues with the guest ABI changing upon migration, and hotunplug
-may not work.
+issues with the guest ABI changing upon migration and device hotplug
+or hotunplug may not work. The attached environment should be considered
+primarily read-only.

  =item B I { [I<--hmp>] | [I<--pretty>] }
  I...



Michal

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


Re: [libvirt] [PATCHv2] Introduce virStringStripIPv6Brackets

2014-10-08 Thread Eric Blake
On 10/08/2014 04:31 AM, Ján Tomko wrote:
> Helper function to strip the brackets from an IPv6 address.
> Tested by viruritest.
> ---
>  src/libvirt_private.syms |  1 +
>  src/util/virstring.c | 22 ++
>  src/util/virstring.h |  2 ++
>  src/util/viruri.c| 20 
>  tests/virstringtest.c| 49 
> 
>  5 files changed, 78 insertions(+), 16 deletions(-)
> 

>  return virBufferContentAndReset(&buf);
>  }
> +
> +/**

Two blank lines between functions seems to be the prevailing style.


> +len = strlen(str);
> +if (str[0] == '[' && str[len-1] == ']' && strchr(str, ':')) {

Spaces around '-'

ACK with those tweaks

-- 
Eric Blake   eblake redhat com+1-919-301-3266
Libvirt virtualization library http://libvirt.org



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

Re: [libvirt] [PATCH 1/2] util: Functions to update host network device's multicast filter

2014-10-08 Thread Laine Stump
On 10/06/2014 05:37 PM, akrow...@linux.vnet.ibm.com wrote:
> From: Tony Krowiak 
>
> This patch provides the utility functions to needed to synchronize the
> changes made to a guest domain network device's multicast filter
> with the corresponding macvtap device's filter on the host:
>
> * Get/add/remove multicast MAC addresses
> * Get the macvtap device's RX filter list
>
> Signed-off-by: Tony Krowiak 
> ---
>  src/libvirt_private.syms |4 +
>  src/util/virmacaddr.c|   37 +
>  src/util/virmacaddr.h|4 +
>  src/util/virnetdev.c |  360 
> ++
>  src/util/virnetdev.h |   11 ++
>  5 files changed, 416 insertions(+), 0 deletions(-)
>
> diff --git a/src/libvirt_private.syms b/src/libvirt_private.syms
> index d6265ac..6d06a2c 100644
> --- a/src/libvirt_private.syms
> +++ b/src/libvirt_private.syms
> @@ -1590,13 +1590,16 @@ virMacAddrIsBroadcastRaw;
>  virMacAddrIsMulticast;
>  virMacAddrIsUnicast;
>  virMacAddrParse;
> +virMacAddrParseHex;
>  virMacAddrSet;
>  virMacAddrSetRaw;
>  
>  
>  # util/virnetdev.h
> +virNetDevAddMulti;
>  virNetDevAddRoute;
>  virNetDevClearIPv4Address;
> +virNetDevDelMulti;
>  virNetDevExists;
>  virNetDevGetIndex;
>  virNetDevGetIPv4Address;
> @@ -1604,6 +1607,7 @@ virNetDevGetLinkInfo;
>  virNetDevGetMAC;
>  virNetDevGetMTU;
>  virNetDevGetPhysicalFunction;
> +virNetDevGetRxFilter;
>  virNetDevGetVirtualFunctionIndex;
>  virNetDevGetVirtualFunctionInfo;
>  virNetDevGetVirtualFunctions;
> diff --git a/src/util/virmacaddr.c b/src/util/virmacaddr.c
> index ebd1182..ae5e5d2 100644
> --- a/src/util/virmacaddr.c
> +++ b/src/util/virmacaddr.c
> @@ -198,6 +198,43 @@ virMacAddrFormat(const virMacAddr *addr,
>  return str;
>  }
>  
> +/**
> + * virMacAddrParseHex:
> + * @str: string hexadecimal representation of MAC address, e.g., 
> "F801EFCE3aCB"
> + * @addr: 6-byte MAC address
> + *
> + * Parse the hexadecimal representation of a MAC address
> + *
> + * Return 0 upon success, or -1 in case of error.
> + */
> +int
> +virMacAddrParseHex(const char* str, virMacAddrPtr addr)
> +{
> +if (strlen(str) != VIR_MAC_HEXLEN)
> +return -1;
> +
> +size_t iaddr;
> +size_t istr;
> +
> +
> +for (istr = 0, iaddr = 0; iaddr < VIR_MAC_BUFLEN; istr += 2, iaddr++) {
> +unsigned int hex;
> +
> +if (sscanf(&str[istr], "%02x", &hex) != 1)
> +break;

I'm not keen on sscanf(), but since we're already using it elsewhere,
and the existing virMacAddrParse uses the normally-blacklisted strtoul()
(and using virStrToLong_ui() on pieces of the string would require a
terminating character after each piece), I don't have a ready answer for
an alternative.

Eric, do you have an opinion on this? Is sscanf okay when we want to parse:

 

of hex digits into 6 binary bytes?


> +
> +if (hex > UCHAR_MAX)
> +break;
> +
> +addr->addr[iaddr] = hex;
> +}
> +
> +if (istr == VIR_MAC_HEXLEN)
> +return 0;
> +
> +return -1;
> +}
> +
>  void virMacAddrGenerate(const unsigned char prefix[VIR_MAC_PREFIX_BUFLEN],
>  virMacAddrPtr addr)
>  {
> diff --git a/src/util/virmacaddr.h b/src/util/virmacaddr.h
> index 49efc36..72a285a 100644
> --- a/src/util/virmacaddr.h
> +++ b/src/util/virmacaddr.h
> @@ -27,6 +27,7 @@
>  # include "internal.h"
>  
>  # define VIR_MAC_BUFLEN 6
> +#define VIR_MAC_HEXLEN (VIR_MAC_BUFLEN * 2)
>  # define VIR_MAC_PREFIX_BUFLEN 3
>  # define VIR_MAC_STRING_BUFLEN (VIR_MAC_BUFLEN * 3)
>  
> @@ -50,6 +51,9 @@ void virMacAddrGenerate(const unsigned char 
> prefix[VIR_MAC_PREFIX_BUFLEN],
>  virMacAddrPtr addr);
>  int virMacAddrParse(const char* str,
>  virMacAddrPtr addr) ATTRIBUTE_RETURN_CHECK;
> +int virMacAddrParseHex(const char* str,
> +   virMacAddrPtr addr)
> +ATTRIBUTE_NONNULL(1) ATTRIBUTE_NONNULL(2) ATTRIBUTE_RETURN_CHECK;
>  bool virMacAddrIsUnicast(const virMacAddr *addr);
>  bool virMacAddrIsMulticast(const virMacAddr *addr);
>  bool virMacAddrIsBroadcastRaw(const unsigned char s[VIR_MAC_BUFLEN]);
> diff --git a/src/util/virnetdev.c b/src/util/virnetdev.c
> index db5623a..5e53f5f 100644
> --- a/src/util/virnetdev.c
> +++ b/src/util/virnetdev.c
> @@ -56,6 +56,33 @@
>  
>  VIR_LOG_INIT("util.netdev");
>  
> +# define VIR_MCAST_NAME_LEN (IFNAMSIZ + 1)
> +# define VIR_MCAST_INDEX_TOKEN_IDX 0
> +# define VIR_MCAST_NAME_TOKEN_IDX 1
> +# define VIR_MCAST_USERS_TOKEN_IDX 2
> +# define VIR_MCAST_GLOBAL_TOKEN_IDX 3
> +# define VIR_MCAST_ADDR_TOKEN_IDX 4
> +# define VIR_MCAST_NUM_TOKENS 5
> +# define VIR_MCAST_TOKEN_DELIMS " \n"
> +# define VIR_MCAST_ADDR_LEN (VIR_MAC_HEXLEN + 1)
> +
> +typedef struct _virNetDevMcastEntry virNetDevMcastEntry;
> +typedef virNetDevMcastEntry *virNetDevMcastEntryPtr;
> +struct _virNetDevMcastEntry  {
> +int index;
> +char name[VIR_MCAST_NAME_LEN];
> +int users;
> +bool global;
> +v

Re: [libvirt] Implementation of new features for Hyper-V Libvirt driver

2014-10-08 Thread Eric Blake
[the original message got eaten by the moderator queue because of size
violation]

On 12/31/1969 05:00 PM,  wrote:
> Hi all,
> 
> I've just submitted a set of 21 patchs for the implementation of new features 
> in the hyperv libvirt driver.
> For your convenience, I have attached to this email a document giving more 
> details about this delivery.

Rather than sending a 450k pdf describing the changes, just submit the
changes themselves, one email per change.  'git send-email origin
--cover-letter --annotate' can work miracles at giving you a chance to
write a 0/21 cover letter that summarizes the rest of the series, and
then 21 emails at one per patch.  Doing it in this manner will make it
much more likely that your series gets a timely review.


-- 
Eric Blake   eblake redhat com+1-919-301-3266
Libvirt virtualization library http://libvirt.org



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

Re: [libvirt] [PATCH v2 6/8] Implemented post-copy migration logic in qemu

2014-10-08 Thread Cristian Klein
On 07 Oct 2014, at 23:02 , Jiri Denemark  wrote:

> On Tue, Sep 30, 2014 at 16:39:27 +0200, Cristian Klein wrote:
>> Perform phase stops once migration switched to post-copy.
>> Confirm phase waits for post-copy to finish before killing the VM.
>> 
>> Signed-off-by: Cristian Klein 
>> ---
>> src/qemu/qemu_driver.c|  8 
>> src/qemu/qemu_migration.c | 25 ++---
>> 2 files changed, 30 insertions(+), 3 deletions(-)
>> 
>> diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c
>> index e873d45..3fe2216 100644
>> --- a/src/qemu/qemu_driver.c
>> +++ b/src/qemu/qemu_driver.c
>> @@ -10942,6 +10942,14 @@ qemuDomainMigratePrepare2(virConnectPtr dconn,
>> 
>> virCheckFlags(QEMU_MIGRATION_FLAGS, -1);
>> 
>> +if (flags & VIR_MIGRATE_POSTCOPY) {
>> +/* post-copy migration does not work with Sequence v2 */
>> +virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
>> +   _("Post-copy migration requested but not "
>> + "supported by v2 protocol"));
>> +goto cleanup;
>> +}
>> +
> 
> This code should be unreachable. If both source and destination daemons
> support VIR_MIGRATE_POSTCOPY, they support v3 protocol as well. And a
> client new enough to specify VIR_MIGRATE_POSTCOPY will also support v3
> migration protocol. However, it doesn't hurt to check this to be safe.
> 
>> if (flags & VIR_MIGRATE_TUNNELLED) {
>> /* this is a logical error; we never should have gotten here with
>>  * VIR_MIGRATE_TUNNELLED set
>> diff --git a/src/qemu/qemu_migration.c b/src/qemu/qemu_migration.c
>> index 4a36946..436b701 100644
>> --- a/src/qemu/qemu_migration.c
>> +++ b/src/qemu/qemu_migration.c
>> @@ -2039,6 +2039,11 @@ qemuMigrationUpdateJobStatus(virQEMUDriverPtr driver,
>> ret = 0;
>> break;
>> 
>> +case QEMU_MONITOR_MIGRATION_STATUS_POSTCOPY_ACTIVE:
>> +jobInfo->type = VIR_DOMAIN_JOB_PHASE1_COMPLETED;
>> +ret = 0;
>> +break;
>> +
> 
> This will need to be dropped after 5/8 is removed. However, it reminds
> me...
> 
>enum {
>QEMU_MONITOR_MIGRATION_STATUS_INACTIVE,
>QEMU_MONITOR_MIGRATION_STATUS_ACTIVE,
>QEMU_MONITOR_MIGRATION_STATUS_COMPLETED,
>QEMU_MONITOR_MIGRATION_STATUS_ERROR,
>QEMU_MONITOR_MIGRATION_STATUS_CANCELLED,
>QEMU_MONITOR_MIGRATION_STATUS_SETUP,
>QEMU_MONITOR_MIGRATION_STATUS_POSTCOPY_ACTIVE,
> 
>QEMU_MONITOR_MIGRATION_STATUS_LAST
>};
> 
> in qemu_monitor.h needs to be turned into a proper typedef so that
> 
>switch (status.status) {
> 
> line in qemuMigrationUpdateJobStatus may be changed to explicitly
> mention the enum so that the compiler may report a warning whenever we
> add new status but forgot to handle it in this switch.

What about `QEMU_MONITOR_MIGRATION_STATUS_LAST`? Should this be included in a 
switch with an assertion that that code should never be reached?

> Which means the
> new state will need to be handled in the same patch it was introduced,
> i.e, in 3/8.
> 
>> case QEMU_MONITOR_MIGRATION_STATUS_INACTIVE:
>> jobInfo->type = VIR_DOMAIN_JOB_NONE;
>> virReportError(VIR_ERR_OPERATION_FAILED,
>> @@ -2077,6 +2082,7 @@ qemuMigrationWaitForCompletion(virQEMUDriverPtr driver,
>> qemuDomainJobInfoPtr jobInfo = priv->job.current;
>> const char *job;
>> int pauseReason;
>> +bool inPhase2 = (jobInfo->type == VIR_DOMAIN_JOB_PHASE1_COMPLETED);
> 
> I think it would be cleaner to pass this info in a new parameter for
> qemuMigrationWaitForCompletion instead of doing a hidden black magic
> here.

I agree with you, I wasn’t sure about with this way of coding things either. Is 
it okey to ask developers to always create a new intermediate parameter to call 
this function, so as to make its usage easier to read? E.g.,

“””
bool return_on_postcopy_active = false;
rv = qemuMigrationWaitForCompletion(driver, vm,
QEMU_ASYNC_JOB_MIGRATION_OUT,
conn, abort_on_error,
return_on_postcopy_active);
“”" 

> 
>> 
>> switch (priv->job.asyncJob) {
>> case QEMU_ASYNC_JOB_MIGRATION_OUT:
>> @@ -2092,9 +2098,11 @@ qemuMigrationWaitForCompletion(virQEMUDriverPtr 
>> driver,
>> job = _("job");
>> }
>> 
>> -jobInfo->type = VIR_DOMAIN_JOB_UNBOUNDED;
>> +if (!inPhase2)
>> +jobInfo->type = VIR_DOMAIN_JOB_UNBOUNDED;
>> 
>> -while (jobInfo->type == VIR_DOMAIN_JOB_UNBOUNDED) {
>> +while (jobInfo->type == VIR_DOMAIN_JOB_UNBOUNDED ||
>> +   (inPhase2 && jobInfo->type == VIR_DOMAIN_JOB_PHASE1_COMPLETED)) {
> 
> Just use jobInfo->status.status directly.
> 
>> /* Poll every 50ms for progress & to allow cancellation */
>> struct timespec ts = { .tv_sec = 0, .tv_nsec = 50 * 1000 * 1000ull };
>> 
>> @@ -2123,7 +2131,8 @@ qemuMigrationWaitForCompletion(virQEMUDriverPtr driver,
>>

Re: [libvirt] [PATCH v2 5/8] Added job type VIR_DOMAIN_JOB_PHASE1_COMPLETED

2014-10-08 Thread Cristian Klein

On 07 Oct 2014, at 22:08 , Jiri Denemark  wrote:

> On Tue, Sep 30, 2014 at 16:39:26 +0200, Cristian Klein wrote:
>> Some jobs feature several phases. For example, post-copy migration is
>> composed of a first phase, from migration start to switching to
>> post-copy, and a second phase, to migration completion. This
>> job type allows to flag that the job has completed the first phase,
>> but is not yet fully completed.
>> 
>> Signed-off-by: Cristian Klein 
>> ---
>> include/libvirt/libvirt.h.in | 1 +
>> tools/virsh-domain.c | 3 ++-
>> 2 files changed, 3 insertions(+), 1 deletion(-)
>> 
>> diff --git a/include/libvirt/libvirt.h.in b/include/libvirt/libvirt.h.in
>> index 84cd5a4..81044f0 100644
>> --- a/include/libvirt/libvirt.h.in
>> +++ b/include/libvirt/libvirt.h.in
>> @@ -4307,6 +4307,7 @@ typedef enum {
>> VIR_DOMAIN_JOB_COMPLETED = 3, /* Job has finished, but isn't cleaned up 
>> */
>> VIR_DOMAIN_JOB_FAILED= 4, /* Job hit error, but isn't cleaned up */
>> VIR_DOMAIN_JOB_CANCELLED = 5, /* Job was aborted, but isn't cleaned up */
>> +VIR_DOMAIN_JOB_PHASE1_COMPLETED = 6, /* Job completed first phase, 
>> e.g., post-copy activation */
> 
> This is not a job type. If we need to advertise this to libvirt clients,
> we may introduce a new job statistics typed parameter but we should not
> misuse job type. And I'm not entirely convinced we need to advertise
> this. To me it seems the only interested thing is whether a domain is
> still running on the source host or it was already resumed on the
> destination host. And it's easy to get this kind of information via
> existing ways, e.g., listening to domain life cycle events or by
> checking domain's status.

My rationale for introducing this flag was to prevent a future breakage of an 
internal API. I felt like none of the previous flags where accurately 
representing the status of this job after post-copy has started. Sure, I could 
use `job->status.status` in `qemuMigrationWaitForCompletion`, but I was 
concerned that a future `libvirt` addition might not take this subtly into 
account and might break post-copy.

If you think I should go ahead, suppress this job type and use 
`job->status.status` instead, what should I use instead, 
`VIR_DOMAIN_JOB_UNBOUNDED` or `VIR_DOMAIN_JOB_BOUNDED`? To be honest, I’m not 
sure to have completely understood the difference between them, except that 
`VIR_DOMAIN_JOB_BOUNDED` seems to be used to signal that a job is almost 
complete.

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


[libvirt] [PATCH 18/21] Added hypervDomainAttachDisk, internal implementation for disk attachement (required Msvm_ResourceAllocationSettingData and Msvm_AllocationCapabilities classes)

2014-10-08 Thread Yves Vinter
From: yvinter 

---
 src/hyperv/hyperv_driver.c| 377 ++
 src/hyperv/hyperv_wmi_generator.input |  41 
 2 files changed, 418 insertions(+)

diff --git a/src/hyperv/hyperv_driver.c b/src/hyperv/hyperv_driver.c
index f68eaad..cbe4397 100644
--- a/src/hyperv/hyperv_driver.c
+++ b/src/hyperv/hyperv_driver.c
@@ -2424,6 +2424,383 @@ hypervDomainUndefine(virDomainPtr domain)
 
 
 
+/*
+ * Creates the attribute __PATH for the RASD object
+ * The attribute is build like this:
+ *   
\\\root\virtualization:Msvm_ResourceAllocationSettingData.InstanceID=""
+ *   where backslashes in rasdInstanceID are doubled
+ */
+static int
+hypervGetResourceAllocationSettingDataPATH(virDomainPtr domain, char 
*rasdInstanceID, char **__path)
+{
+char uuid_string[VIR_UUID_STRING_BUFLEN];
+hypervPrivate *priv = domain->conn->privateData;
+virBuffer query = VIR_BUFFER_INITIALIZER;
+Msvm_ComputerSystem *computerSystem = NULL;
+char *strTemp = NULL;
+int result = -1, i = 0, j = 0, n = 0;
+
+virUUIDFormat(domain->uuid, uuid_string);
+
+/* Get host name */
+virBufferAsprintf(&query,
+  "associators of "
+  
"{Msvm_ComputerSystem.CreationClassName=\"Msvm_ComputerSystem\","
+  "Name=\"%s\"} "
+  "where AssocClass = Msvm_HostedDependency "
+  "ResultClass = Msvm_ComputerSystem",
+  uuid_string);
+if (hypervGetMsvmComputerSystemList(priv, &query, &computerSystem) < 0) {
+goto cleanup;
+}
+if (computerSystem == NULL) {
+virReportError(VIR_ERR_NO_DOMAIN, _("No domain with UUID %s"), 
uuid_string);
+goto cleanup;
+}
+
+/* Count the number of backslash character */
+strTemp = strchr(rasdInstanceID, '\\');
+while (strTemp != NULL) {
+n++;
+strTemp = strchr(++strTemp, '\\');
+}
+/* Double the blackslashes */
+if (VIR_ALLOC_N(strTemp, strlen(rasdInstanceID) + 1 + n) < 0)
+goto cleanup;
+while (rasdInstanceID[i] != '\0') {
+strTemp[j] = rasdInstanceID[i];
+if (rasdInstanceID[i] == '\\') {
+j++;
+strTemp[j] = '\\';
+}
+i++;
+j++;
+}
+strTemp[j] = '\0';
+
+/* Create the attribute __PATH */
+/* FIXME: *__path allocated with 255 characters (static value) */
+if (VIR_ALLOC_N(*__path, 255) < 0)
+goto cleanup;
+sprintf(*__path, "");
+strcat(*__path, computerSystem->data->ElementName);
+strcat(*__path, 
"\\root\\virtualization:Msvm_ResourceAllocationSettingData.InstanceID=\"");
+strcat(*__path, strTemp);
+strcat(*__path, "\"");
+
+result = 0;
+
+ cleanup:
+VIR_FREE(strTemp);
+hypervFreeObject(priv, (hypervObject *)computerSystem);
+virBufferFreeAndReset(&query);
+
+return result;
+}
+
+
+
+/* hypervDomainAttachDisk
+ * FIXME:
+ *   - added ressources must me removed in case of error
+ *   - allow attaching disks on iSCSI (implemented only on IDE)
+ *   - allow attaching ISO images (on DVD devices)
+ *   - implement associated detach method
+ */
+ATTRIBUTE_UNUSED static int
+hypervDomainAttachDisk(virDomainPtr domain, virDomainDiskDefPtr disk)
+{
+int result = -1, nb_params;
+const char *selector = 
"CreationClassName=Msvm_VirtualSystemManagementService";
+char uuid_string[VIR_UUID_STRING_BUFLEN];
+char *ideRasdPath = NULL, *newDiskDrivePath = NULL;
+char ideControler[2], ideControlerAddr[2];
+hypervPrivate *priv = domain->conn->privateData;
+virBuffer query = VIR_BUFFER_INITIALIZER;
+Msvm_VirtualSystemSettingData *virtualSystemSettingData = NULL;
+Msvm_ResourceAllocationSettingData *resourceAllocationSettingData = NULL;
+Msvm_ResourceAllocationSettingData *resourceAllocationSettingData2 = NULL;
+Msvm_ResourceAllocationSettingData *resourceAllocationSettingData3 = NULL;
+Msvm_ResourceAllocationSettingData *resourceAllocationSettingData4 = NULL;
+Msvm_ResourceAllocationSettingData *ideRasd = NULL;  /* 
resourceAllocationSettingData subtree -> do not disallocate */
+Msvm_ResourceAllocationSettingData *diskRasd = NULL;  /* 
resourceAllocationSettingData2 subtree -> do not disallocate */
+Msvm_ResourceAllocationSettingData *newDiskDrive = NULL;  /* 
resourceAllocationSettingData3 subtree -> do not disallocate */
+Msvm_AllocationCapabilities *allocationCapabilities  = NULL;
+Msvm_AllocationCapabilities *allocationCapabilities2  = NULL;
+invokeXmlParam *params = NULL;
+properties_t *tab_props = NULL;
+eprParam eprparam1, eprparam2;
+embeddedParam embeddedparam1, embeddedparam2;
+
+/* Initialization */
+virUUIDFormat(domain->uuid, uuid_string);
+
+/* Set IDE Controler 0 or 1 and address 0 or 1 */
+if (STREQ(disk->dst, "hda")) {
+sprintf(ideControler, "%d", 0);
+sprintf(ideControlerAddr, "%d", 0);
+}

[libvirt] [PATCH 16/21] Added implementation for virDomainSetVcpus and virDomainSetVcpusFlags

2014-10-08 Thread Yves Vinter
From: yvinter 

---
 src/hyperv/hyperv_driver.c | 118 +
 1 file changed, 118 insertions(+)

diff --git a/src/hyperv/hyperv_driver.c b/src/hyperv/hyperv_driver.c
index a8d679e..ade9db1 100644
--- a/src/hyperv/hyperv_driver.c
+++ b/src/hyperv/hyperv_driver.c
@@ -2237,6 +2237,122 @@ hypervDomainSetMemory(virDomainPtr domain, unsigned 
long memory)
 
 
 
+static int
+hypervDomainSetVcpusFlags(virDomainPtr domain, unsigned int nvcpus,
+  unsigned int flags ATTRIBUTE_UNUSED)
+{
+int result = -1;
+invokeXmlParam *params = NULL;
+char uuid_string[VIR_UUID_STRING_BUFLEN];
+hypervPrivate *priv = domain->conn->privateData;
+properties_t *tab_props = NULL;
+virBuffer query = VIR_BUFFER_INITIALIZER;
+Msvm_VirtualSystemSettingData *virtualSystemSettingData = NULL;
+Msvm_ProcessorSettingData *processorSettingData = NULL;
+eprParam eprparam;
+embeddedParam embeddedparam;
+int nb_params;
+const char *selector = 
"CreationClassName=Msvm_VirtualSystemManagementService";
+char *nvcpus_str = NULL;
+
+/* Convert nvcpus as a string value */
+nvcpus_str = num2str(nvcpus);
+if (nvcpus_str == NULL)
+goto cleanup;
+
+virUUIDFormat(domain->uuid, uuid_string);
+
+VIR_DEBUG("nvcpus=%s, uuid=%s", nvcpus_str, uuid_string);
+
+/* Get Msvm_VirtualSystemSettingData */
+virBufferAsprintf(&query,
+  "associators of "
+  
"{Msvm_ComputerSystem.CreationClassName=\"Msvm_ComputerSystem\","
+  "Name=\"%s\"} "
+  "where AssocClass = Msvm_SettingsDefineState "
+  "ResultClass = Msvm_VirtualSystemSettingData",
+  uuid_string);
+
+if (hypervGetMsvmVirtualSystemSettingDataList(priv, &query, 
&virtualSystemSettingData) < 0)
+goto cleanup;
+
+/* Get Msvm_ProcessorSettingData */
+virBufferFreeAndReset(&query);
+virBufferAsprintf(&query,
+  "associators of "
+  "{Msvm_VirtualSystemSettingData.InstanceID=\"%s\"} "
+  "where AssocClass = 
Msvm_VirtualSystemSettingDataComponent "
+  "ResultClass = Msvm_ProcessorSettingData",
+  virtualSystemSettingData->data->InstanceID);
+
+if (hypervGetMsvmProcessorSettingDataList(priv, &query, 
&processorSettingData) < 0)
+goto cleanup;
+
+if (processorSettingData == NULL) {
+virReportError(VIR_ERR_INTERNAL_ERROR,
+   _("Could not lookup Msvm_ProcessorSettingData for 
domain %s"),
+   virtualSystemSettingData->data->ElementName);
+goto cleanup;
+}
+
+/* Prepare EPR param */
+virBufferFreeAndReset(&query);
+virBufferAddLit(&query, MSVM_COMPUTERSYSTEM_WQL_SELECT);
+virBufferAsprintf(&query, "where Name = \"%s\"",uuid_string);
+eprparam.query = &query;
+eprparam.wmiProviderURI = ROOT_VIRTUALIZATION;
+
+/* Prepare EMBEDDED param */
+embeddedparam.nbProps = 2;
+if (VIR_ALLOC_N(tab_props, embeddedparam.nbProps) < 0)
+goto cleanup;
+(*tab_props).name = "VirtualQuantity";
+(*tab_props).val = nvcpus_str;
+(*(tab_props+1)).name = "InstanceID";
+(*(tab_props+1)).val = processorSettingData->data->InstanceID;
+embeddedparam.instanceName =  "Msvm_ProcessorSettingData";
+embeddedparam.prop_t = tab_props;
+
+/* Create invokeXmlParam */
+nb_params = 2;
+if (VIR_ALLOC_N(params, nb_params) < 0)
+goto cleanup;
+(*params).name = "ComputerSystem";
+(*params).type = EPR_PARAM;
+(*params).param = &eprparam;
+(*(params+1)).name = "ResourceSettingData";
+(*(params+1)).type = EMBEDDED_PARAM;
+(*(params+1)).param = &embeddedparam;
+
+if (hypervInvokeMethod(priv, params, nb_params, 
"ModifyVirtualSystemResources",
+   MSVM_VIRTUALSYSTEMMANAGEMENTSERVICE_RESOURCE_URI, 
selector) < 0) {
+virReportError(VIR_ERR_INTERNAL_ERROR, _("Could not set domain 
vcpus"));
+goto cleanup;
+}
+
+result = 0;
+
+ cleanup:
+VIR_FREE(tab_props);
+VIR_FREE(params);
+VIR_FREE(nvcpus_str);
+hypervFreeObject(priv, (hypervObject *)virtualSystemSettingData);
+hypervFreeObject(priv, (hypervObject *)processorSettingData);
+virBufferFreeAndReset(&query);
+
+return result;
+}
+
+
+
+static int
+hypervDomainSetVcpus(virDomainPtr domain, unsigned int nvcpus)
+{
+return hypervDomainSetVcpusFlags(domain, nvcpus, 0);
+}
+
+
+
 static virDriver hypervDriver = {
 .no = VIR_DRV_HYPERV,
 .name = "Hyper-V",
@@ -2289,6 +2405,8 @@ static virDriver hypervDriver = {
 .domainSetMaxMemory = hypervDomainSetMaxMemory, /* 1.2.10 */
 .domainSetMemory = hypervDomainSetMemory, /* 1.2.10 */
 .domainSetMemoryFlags = hypervDomainSetMemoryFlags, /* 1.2.10 */
+.domainSetVcpus = 

[libvirt] [PATCH 21/21] Added implementation for virDomainDefineXML and virDomainCreateXML

2014-10-08 Thread Yves Vinter
From: yvinter 

---
 src/hyperv/hyperv_driver.c | 142 +
 1 file changed, 142 insertions(+)

diff --git a/src/hyperv/hyperv_driver.c b/src/hyperv/hyperv_driver.c
index 8e0d6b3..83fb605 100644
--- a/src/hyperv/hyperv_driver.c
+++ b/src/hyperv/hyperv_driver.c
@@ -3098,6 +3098,146 @@ hypervDomainAttachDevice(virDomainPtr domain, const 
char *xml)
 
 
 
+static virDomainPtr
+hypervDomainDefineXML(virConnectPtr conn, const char *xml)
+{
+hypervPrivate *priv = conn->privateData;
+virDomainDefPtr def = NULL;
+virDomainPtr domain = NULL;
+invokeXmlParam *params = NULL;
+properties_t *tab_props = NULL;
+embeddedParam embeddedparam;
+int nb_params, i;
+const char *selector = 
"CreationClassName=Msvm_VirtualSystemManagementService";
+char uuid_string[VIR_UUID_STRING_BUFLEN];
+
+/* Parse XML domain description */
+if ((def = virDomainDefParseString(xml, priv->caps, priv->xmlopt,
+   1 << VIR_DOMAIN_VIRT_HYPERV, 
VIR_DOMAIN_XML_INACTIVE)) == NULL) {
+goto cleanup;
+}
+
+/* Create the domain if does not exist */
+if (def->uuid == NULL || (domain = hypervDomainLookupByUUID(conn, 
def->uuid)) == NULL) {
+/* Prepare EMBEDDED param */
+/* Edit only VM name */
+/* FIXME: cannot edit VM UUID */
+embeddedparam.nbProps = 1;
+if (VIR_ALLOC_N(tab_props, embeddedparam.nbProps) < 0)
+goto cleanup;
+(*tab_props).name = "ElementName";
+(*tab_props).val = def->name;
+embeddedparam.instanceName = "Msvm_VirtualSystemGlobalSettingData";
+embeddedparam.prop_t = tab_props;
+
+/* Create invokeXmlParam */
+nb_params = 1;
+if (VIR_ALLOC_N(params, nb_params) < 0)
+goto cleanup;
+(*params).name = "SystemSettingData";
+(*params).type = EMBEDDED_PARAM;
+(*params).param = &embeddedparam;
+
+/* Create VM */
+if (hypervInvokeMethod(priv, params, nb_params, "DefineVirtualSystem",
+   
MSVM_VIRTUALSYSTEMMANAGEMENTSERVICE_RESOURCE_URI, selector) < 0) {
+virReportError(VIR_ERR_INTERNAL_ERROR,
+   _("Could not create new domain %s"), def->name);
+goto cleanup;
+}
+
+/* Get domain pointer */
+domain = hypervDomainLookupByName(conn, def->name);
+
+VIR_DEBUG("Domain created: name=%s, uuid=%s",
+  domain->name, virUUIDFormat(domain->uuid, uuid_string));
+}
+
+/* Set VM maximum memory */
+if (def->mem.max_balloon > 0) {
+if (hypervDomainSetMaxMemory(domain, def->mem.max_balloon) < 0) {
+virReportError(VIR_ERR_INTERNAL_ERROR,
+   _("Could not set VM maximum memory"));
+}
+}
+
+/* Set VM memory */
+if (def->mem.cur_balloon > 0) {
+if (hypervDomainSetMemory(domain, def->mem.cur_balloon) < 0) {
+virReportError(VIR_ERR_INTERNAL_ERROR,
+   _("Could not set VM memory"));
+}
+}
+
+/* Set VM vcpus */
+if (def->vcpus > 0) {
+if (hypervDomainSetVcpus(domain, def->vcpus) < 0) {
+virReportError(VIR_ERR_INTERNAL_ERROR,
+   _("Could not set VM vCPUs"));
+}
+}
+
+/* Attach networks */
+for (i = 0; i < def->nnets; i++) {
+if (hypervDomainAttachNetwork(domain, def->nets[i]) < 0) {
+virReportError(VIR_ERR_INTERNAL_ERROR,
+   _("Could not attach network"));
+}
+}
+
+/* Attach disks */
+for (i = 0; i < def->ndisks; i++) {
+if (hypervDomainAttachDisk(domain, def->disks[i]) < 0) {
+virReportError(VIR_ERR_INTERNAL_ERROR,
+   _("Could not attach disk"));
+}
+}
+
+ cleanup:
+virDomainDefFree(def);
+VIR_FREE(tab_props);
+VIR_FREE(params);
+
+return domain;
+}
+
+
+
+static virDomainPtr
+hypervDomainCreateXML(virConnectPtr conn, const char *xmlDesc, unsigned int 
flags)
+{
+virDomainPtr domain;
+
+virCheckFlags(VIR_DOMAIN_START_PAUSED | VIR_DOMAIN_START_AUTODESTROY, 
NULL);
+
+/* Create the new domain */
+domain = hypervDomainDefineXML(conn, xmlDesc);
+if (domain == NULL)
+return NULL;
+
+/* Start the domain */
+if (hypervInvokeMsvmComputerSystemRequestStateChange(domain, 
MSVM_COMPUTERSYSTEM_REQUESTEDSTATE_ENABLED) < 0) {
+virReportError(VIR_ERR_INTERNAL_ERROR,
+   _("Could not start the domain %s"), domain->name);
+return domain;
+}
+
+/* If the VIR_DOMAIN_START_PAUSED flag is set,
+   the guest domain will be started, but its CPUs will remain paused */
+if (flags & VIR_DOMAIN_START_PAUSED) {
+if (hypervDomainSuspend(domain) < 0) {
+virReportError(VIR_

[libvirt] [PATCH 20/21] Added implementation for virDomainAttachDevice and virDomainAttachDeviceFlags (required xmlopt in private structure)

2014-10-08 Thread Yves Vinter
From: yvinter 

---
 src/hyperv/hyperv_driver.c  | 81 +
 src/hyperv/hyperv_private.h |  2 ++
 2 files changed, 83 insertions(+)

diff --git a/src/hyperv/hyperv_driver.c b/src/hyperv/hyperv_driver.c
index 8b8e612..8e0d6b3 100644
--- a/src/hyperv/hyperv_driver.c
+++ b/src/hyperv/hyperv_driver.c
@@ -62,6 +62,9 @@ hypervFreePrivate(hypervPrivate **priv)
 if ((*priv)->caps != NULL)
 virObjectUnref((*priv)->caps);
 
+if ((*priv)->xmlopt != NULL)
+virObjectUnref((*priv)->xmlopt);
+
 hypervFreeParsedUri(&(*priv)->parsedUri);
 VIR_FREE(*priv);
 }
@@ -206,6 +209,9 @@ hypervConnectOpen(virConnectPtr conn, virConnectAuthPtr 
auth, unsigned int flags
 goto cleanup;
 }
 
+/* Init xmlopt to parse Domain XML */
+priv->xmlopt = virDomainXMLOptionNew(NULL, NULL, NULL);
+
 conn->privateData = priv;
 priv = NULL;
 result = VIR_DRV_OPEN_SUCCESS;
@@ -3019,6 +3025,79 @@ hypervDomainAttachNetwork(virDomainPtr domain, 
virDomainNetDefPtr net)
 
 
 
+static int
+hypervDomainAttachDeviceFlags(virDomainPtr domain, const char *xml,
+  unsigned int flags ATTRIBUTE_UNUSED)
+{
+int result = -1;
+hypervPrivate *priv = domain->conn->privateData;
+virDomainDefPtr def = NULL;
+virDomainDeviceDefPtr dev = NULL;
+char *xmlDomain = NULL;
+
+/* Get domain definition */
+if ((xmlDomain = hypervDomainGetXMLDesc(domain, 0)) == NULL) {
+goto cleanup;
+}
+if ((def = virDomainDefParseString(xmlDomain, priv->caps, priv->xmlopt,
+   1 << VIR_DOMAIN_VIRT_HYPERV, 
VIR_DOMAIN_XML_INACTIVE)) == NULL) {
+goto cleanup;
+}
+
+/* Get domain device definition */
+if ((dev = virDomainDeviceDefParse(xml, def, priv->caps,
+   priv->xmlopt, VIR_DOMAIN_XML_INACTIVE)) 
== NULL) {
+goto cleanup;
+}
+
+switch (dev->type) {
+/* Device = disk */
+case VIR_DOMAIN_DEVICE_DISK:
+if (hypervDomainAttachDisk(domain, dev->data.disk) < 0) {
+virReportError(VIR_ERR_INTERNAL_ERROR,
+   _("Could not attach disk"));
+goto cleanup;
+}
+VIR_DEBUG("Disk attached");
+break;
+
+/* Device = network */
+case VIR_DOMAIN_DEVICE_NET:
+if (hypervDomainAttachNetwork(domain, dev->data.net) < 0) {
+virReportError(VIR_ERR_INTERNAL_ERROR,
+   _("Could not attach network"));
+goto cleanup;
+}
+VIR_DEBUG("Network attached");
+break;
+
+/* Unsupported device type */
+default:
+virReportError(VIR_ERR_INTERNAL_ERROR,
+   _("Device attachment of type %d is not 
implemented"), dev->type);
+goto cleanup;
+}
+
+result = 0;
+
+ cleanup:
+virDomainDefFree(def);
+virDomainDeviceDefFree(dev);
+VIR_FREE(xmlDomain);
+
+return result;
+}
+
+
+
+static int
+hypervDomainAttachDevice(virDomainPtr domain, const char *xml)
+{
+return hypervDomainAttachDeviceFlags(domain, xml, 0);
+}
+
+
+
 static virDriver hypervDriver = {
 .no = VIR_DRV_HYPERV,
 .name = "Hyper-V",
@@ -3075,6 +3154,8 @@ static virDriver hypervDriver = {
 .domainSetVcpusFlags = hypervDomainSetVcpusFlags, /* 1.2.10 */
 .domainUndefine = hypervDomainUndefine, /* 1.2.10 */
 .domainUndefineFlags = hypervDomainUndefineFlags, /* 1.2.10 */
+.domainAttachDevice = hypervDomainAttachDevice, /* 1.2.10 */
+.domainAttachDeviceFlags = hypervDomainAttachDeviceFlags, /* 1.2.10 */
 };
 
 
diff --git a/src/hyperv/hyperv_private.h b/src/hyperv/hyperv_private.h
index d9aa0bd..2dfce6e 100644
--- a/src/hyperv/hyperv_private.h
+++ b/src/hyperv/hyperv_private.h
@@ -27,6 +27,7 @@
 # include "virerror.h"
 # include "hyperv_util.h"
 # include "capabilities.h"
+# include "domain_conf.h"
 # include "openwsman.h"
 
 typedef struct _hypervPrivate hypervPrivate;
@@ -35,6 +36,7 @@ struct _hypervPrivate {
 hypervParsedUri *parsedUri;
 WsManClient *client;
 virCapsPtr caps;
+virDomainXMLOptionPtr xmlopt;
 };
 
 #endif /* __HYPERV_PRIVATE_H__ */
-- 
1.9.1

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


[libvirt] [PATCH 15/21] Added implementation for virDomainSetMemory and virDomainSetMemoryFlags

2014-10-08 Thread Yves Vinter
From: yvinter 

---
 src/hyperv/hyperv_driver.c | 112 +
 1 file changed, 112 insertions(+)

diff --git a/src/hyperv/hyperv_driver.c b/src/hyperv/hyperv_driver.c
index 0618ce1..a8d679e 100644
--- a/src/hyperv/hyperv_driver.c
+++ b/src/hyperv/hyperv_driver.c
@@ -2127,6 +2127,116 @@ hypervDomainSetMaxMemory(virDomainPtr domain, unsigned 
long memory)
 
 
 
+static int
+hypervDomainSetMemoryFlags(virDomainPtr domain, unsigned long memory,
+   unsigned int flags ATTRIBUTE_UNUSED)
+{
+int result = -1, nb_params;
+const char *selector = 
"CreationClassName=Msvm_VirtualSystemManagementService";
+char uuid_string[VIR_UUID_STRING_BUFLEN];
+hypervPrivate *priv = domain->conn->privateData;
+invokeXmlParam *params = NULL;
+properties_t *tab_props = NULL;
+eprParam eprparam;
+embeddedParam embeddedparam;
+virBuffer query = VIR_BUFFER_INITIALIZER;
+Msvm_VirtualSystemSettingData *virtualSystemSettingData = NULL;
+Msvm_MemorySettingData *memorySettingData = NULL;
+unsigned long memory_mb = memory / 1024;   /* Memory converted in MB */
+char *memory_str = NULL;
+
+/* Memory value must be a multiple of 2 MB; round up it accordingly if 
necessary */
+if (memory_mb % 2) memory_mb++;
+
+/* Convert the memory value as a string */
+memory_str = num2str(memory_mb);
+if (memory_str == NULL)
+goto cleanup;
+
+virUUIDFormat(domain->uuid, uuid_string);
+
+VIR_DEBUG("memory=%sMb, uuid=%s", memory_str, uuid_string);
+
+/* Get Msvm_VirtualSystemSettingData */
+virBufferAsprintf(&query,
+  "associators of "
+  
"{Msvm_ComputerSystem.CreationClassName=\"Msvm_ComputerSystem\","
+  "Name=\"%s\"} "
+  "where AssocClass = Msvm_SettingsDefineState "
+  "ResultClass = Msvm_VirtualSystemSettingData",
+  uuid_string);
+if (hypervGetMsvmVirtualSystemSettingDataList(priv, &query, 
&virtualSystemSettingData) < 0)
+goto cleanup;
+
+/* Get Msvm_MemorySettingData */
+virBufferFreeAndReset(&query);
+virBufferAsprintf(&query,
+  "associators of "
+  "{Msvm_VirtualSystemSettingData.InstanceID=\"%s\"} "
+  "where AssocClass = 
Msvm_VirtualSystemSettingDataComponent "
+  "ResultClass = Msvm_MemorySettingData",
+  virtualSystemSettingData->data->InstanceID);
+if (hypervGetMsvmMemorySettingDataList(priv, &query, &memorySettingData) < 
0)
+goto cleanup;
+
+/* Prepare EPR param */
+virBufferFreeAndReset(&query);
+virBufferAddLit(&query, MSVM_COMPUTERSYSTEM_WQL_SELECT);
+virBufferAsprintf(&query, "where Name = \"%s\"",uuid_string);
+eprparam.query = &query;
+eprparam.wmiProviderURI = ROOT_VIRTUALIZATION;
+
+/* Prepare EMBEDDED param */
+embeddedparam.nbProps = 2;
+if (VIR_ALLOC_N(tab_props, embeddedparam.nbProps) < 0)
+goto cleanup;
+(*tab_props).name = "VirtualQuantity";
+(*tab_props).val = memory_str;
+(*(tab_props+1)).name = "InstanceID";
+(*(tab_props+1)).val = memorySettingData->data->InstanceID;
+embeddedparam.instanceName =  "Msvm_MemorySettingData";
+embeddedparam.prop_t = tab_props;
+
+/* Create invokeXmlParam */
+nb_params = 2;
+if (VIR_ALLOC_N(params, nb_params) < 0)
+goto cleanup;
+(*params).name = "ComputerSystem";
+(*params).type = EPR_PARAM;
+(*params).param = &eprparam;
+(*(params+1)).name = "ResourceSettingData";
+(*(params+1)).type = EMBEDDED_PARAM;
+(*(params+1)).param = &embeddedparam;
+
+if (hypervInvokeMethod(priv, params, nb_params, 
"ModifyVirtualSystemResources",
+   MSVM_VIRTUALSYSTEMMANAGEMENTSERVICE_RESOURCE_URI, 
selector) < 0) {
+virReportError(VIR_ERR_INTERNAL_ERROR, _("Could not set domain 
memory"));
+goto cleanup;
+}
+
+result = 0;
+
+ cleanup:
+VIR_FREE(tab_props);
+VIR_FREE(params);
+VIR_FREE(memory_str);
+hypervFreeObject(priv, (hypervObject *)virtualSystemSettingData);
+hypervFreeObject(priv, (hypervObject *)memorySettingData);
+virBufferFreeAndReset(&query);
+
+return result;
+}
+
+
+
+static int
+hypervDomainSetMemory(virDomainPtr domain, unsigned long memory)
+{
+return hypervDomainSetMemoryFlags(domain, memory, 0);
+}
+
+
+
 static virDriver hypervDriver = {
 .no = VIR_DRV_HYPERV,
 .name = "Hyper-V",
@@ -2177,6 +2287,8 @@ static virDriver hypervDriver = {
 .domainSetAutostart = hypervDomainSetAutostart, /* 1.2.10 */
 .domainGetAutostart = hypervDomainGetAutostart, /* 1.2.10 */
 .domainSetMaxMemory = hypervDomainSetMaxMemory, /* 1.2.10 */
+.domainSetMemory = hypervDomainSetMemory, /* 1.2.10 */
+.domainSetMemoryFlags = hypervDomainSetMemoryFlags, /* 1.2.10 

[libvirt] [PATCH 19/21] Added hypervDomainAttachNetwork, internal implementation for network attachement (required Msvm_SwitchPort and Msvm_SyntheticEthernetPortSettingData classes)

2014-10-08 Thread Yves Vinter
From: yvinter 

---
 src/hyperv/hyperv_driver.c| 218 ++
 src/hyperv/hyperv_wmi_generator.input |  87 ++
 2 files changed, 305 insertions(+)

diff --git a/src/hyperv/hyperv_driver.c b/src/hyperv/hyperv_driver.c
index cbe4397..8b8e612 100644
--- a/src/hyperv/hyperv_driver.c
+++ b/src/hyperv/hyperv_driver.c
@@ -2801,6 +2801,224 @@ hypervDomainAttachDisk(virDomainPtr domain, 
virDomainDiskDefPtr disk)
 
 
 
+/*
+ * Create the attribute __PATH for the SwitchPort object.
+ * The attribute is build like this:
+ *   
\\\root\virtualization:Msvm_SwitchPort.CreationClassName="Msvm_SwitchPort",
+ *   Name="",SystemCreationClassName="Msvm_VirtualSwitch",
+ *   SystemName=""
+ */
+static int
+hypervGetSwitchPortPATH(virDomainPtr domain, char *switchPortName, char 
*virtualSwitchSystemName, char **__path)
+{
+char uuid_string[VIR_UUID_STRING_BUFLEN];
+hypervPrivate *priv = domain->conn->privateData;
+virBuffer query = VIR_BUFFER_INITIALIZER;
+Msvm_ComputerSystem *computerSystem = NULL;
+int result = -1;
+
+virUUIDFormat(domain->uuid, uuid_string);
+
+/* Get host name */
+virBufferAsprintf(&query,
+  "associators of "
+  
"{Msvm_ComputerSystem.CreationClassName=\"Msvm_ComputerSystem\","
+  "Name=\"%s\"} "
+  "where AssocClass = Msvm_HostedDependency "
+  "ResultClass = Msvm_ComputerSystem",
+  uuid_string);
+if (hypervGetMsvmComputerSystemList(priv, &query, &computerSystem) < 0) {
+goto cleanup;
+}
+if (computerSystem == NULL) {
+virReportError(VIR_ERR_NO_DOMAIN,
+   _("No domain with UUID %s"), uuid_string);
+goto cleanup;
+}
+
+/* Create the attribute __PATH */
+/* FIXME: *__path is allocated with 512 characters (static value) */
+if (VIR_ALLOC_N(*__path, 512) < 0)
+goto cleanup;
+sprintf(*__path,
+
"%s\\root\\virtualization:Msvm_SwitchPort.CreationClassName=\"Msvm_SwitchPort\","
+
"Name=\"%s\",SystemCreationClassName=\"Msvm_VirtualSwitch\",SystemName=\"%s\"",
+computerSystem->data->ElementName, switchPortName, 
virtualSwitchSystemName);
+
+result = 0;
+
+ cleanup:
+hypervFreeObject(priv, (hypervObject *) computerSystem);
+virBufferFreeAndReset(&query);
+return result;
+}
+
+
+
+/* hypervDomainAttachNetwork
+ * FIXME:
+ *   - implement associated detach method
+ */
+ATTRIBUTE_UNUSED static int
+hypervDomainAttachNetwork(virDomainPtr domain, virDomainNetDefPtr net)
+{
+int result = -1, nb_params;
+const char *selector1 = 
"CreationClassName=Msvm_VirtualSwitchManagementService";
+const char *selector2 = 
"CreationClassName=Msvm_VirtualSystemManagementService";
+char uuid_string[VIR_UUID_STRING_BUFLEN], 
guid_string[VIR_UUID_STRING_BUFLEN];
+unsigned char guid[VIR_UUID_BUFLEN];
+char *virtualSystemIdentifiers = NULL, *switchPortPATH = NULL;
+hypervPrivate *priv = domain->conn->privateData;
+virBuffer query = VIR_BUFFER_INITIALIZER;
+eprParam eprparam1, eprparam2;
+simpleParam simpleparam1, simpleparam2, simpleparam3;
+embeddedParam embeddedparam;
+properties_t *tab_props = NULL;
+invokeXmlParam *params = NULL;
+Msvm_SwitchPort *switchPort = NULL;
+Msvm_VirtualSwitch *virtualSwitch = NULL;
+
+/* Initialization */
+virUUIDFormat(domain->uuid, uuid_string);
+
+VIR_DEBUG("network=%s, uuid=%s", net->data.network.name, uuid_string);
+
+/* Create virtual switch port */
+/* Prepare EPR param 1 */
+virBufferAddLit(&query, MSVM_VIRTUALSWITCH_WQL_SELECT);
+virBufferAsprintf(&query, "where ElementName = \"%s\"", 
net->data.network.name);
+eprparam1.query = &query;
+eprparam1.wmiProviderURI = ROOT_VIRTUALIZATION;
+
+/* Prepare SIMPLE params */
+virUUIDGenerate(guid);
+virUUIDFormat(guid, guid_string);
+simpleparam1.value = guid_string;
+simpleparam2.value = "Dynamic Ethernet Switch Port";
+simpleparam3.value = "";
+
+/* Create invokeXmlParam tab */
+nb_params = 4;
+if (VIR_ALLOC_N(params, nb_params) < 0)
+goto cleanup;
+(*params).name = "VirtualSwitch";
+(*params).type = EPR_PARAM;
+(*params).param = &eprparam1;
+(*(params+1)).name = "Name";
+(*(params+1)).type = SIMPLE_PARAM;
+(*(params+1)).param = &simpleparam1;
+(*(params+2)).name = "FriendlyName";
+(*(params+2)).type = SIMPLE_PARAM;
+(*(params+2)).param = &simpleparam2;
+(*(params+3)).name = "ScopeOfResidence";
+(*(params+3)).type = SIMPLE_PARAM;
+(*(params+3)).param = &simpleparam3;
+
+if (hypervInvokeMethod(priv, params, nb_params, "CreateSwitchPort",
+   MSVM_VIRTUALSWITCHMANAGEMENTSERVICE_RESOURCE_URI, 
selector1) < 0) {
+virReportError(VIR_ERR_INTERNAL_ERROR,
+   

[libvirt] [PATCH 14/21] Added implementation for virDomainSetMaxMemory

2014-10-08 Thread Yves Vinter
From: yvinter 

---
 src/hyperv/hyperv_driver.c | 119 +
 1 file changed, 119 insertions(+)

diff --git a/src/hyperv/hyperv_driver.c b/src/hyperv/hyperv_driver.c
index 5c79c99..0618ce1 100644
--- a/src/hyperv/hyperv_driver.c
+++ b/src/hyperv/hyperv_driver.c
@@ -2009,6 +2009,124 @@ hypervDomainGetAutostart(virDomainPtr domain, int 
*autostart)
 
 
 
+/* Format a number as a string value */
+static char *num2str(unsigned long value)
+{
+int sz;
+char *result;
+
+sz = snprintf (NULL, 0, "%lu", value);
+if (VIR_ALLOC_N(result, sz + 1) < 0) {
+  return NULL;
+}
+
+sprintf(result, "%lu", value);
+return result;
+}
+
+
+
+static int
+hypervDomainSetMaxMemory(virDomainPtr domain, unsigned long memory)
+{
+int result = -1;
+invokeXmlParam *params = NULL;
+char uuid_string[VIR_UUID_STRING_BUFLEN];
+hypervPrivate *priv = domain->conn->privateData;
+properties_t *tab_props = NULL;
+virBuffer query = VIR_BUFFER_INITIALIZER;
+virBuffer query2 = VIR_BUFFER_INITIALIZER;
+Msvm_VirtualSystemSettingData *virtualSystemSettingData = NULL;
+Msvm_MemorySettingData *memorySettingData = NULL;
+eprParam eprparam;
+embeddedParam embeddedparam;
+int nb_params;
+const char *selector = 
"CreationClassName=Msvm_VirtualSystemManagementService";
+unsigned long memory_mb = memory/1024;
+char *memory_str = NULL;
+
+/* Memory value must be a multiple of 2 MB; round up it accordingly if 
necessary */
+if (memory_mb % 2) memory_mb++;
+
+/* Convert the memory value as a string */
+memory_str = num2str(memory_mb);
+if (memory_str == NULL)
+goto cleanup;
+
+virUUIDFormat(domain->uuid, uuid_string);
+
+VIR_DEBUG("memory=%sMb, uuid=%s", memory_str, uuid_string);
+
+/* Prepare EPR param */
+virBufferAddLit(&query, MSVM_COMPUTERSYSTEM_WQL_SELECT);
+virBufferAsprintf(&query, "where Name = \"%s\"",uuid_string);
+eprparam.query = &query;
+eprparam.wmiProviderURI = ROOT_VIRTUALIZATION;
+
+/* Prepare EMBEDDED param 1 */
+/* Get Msvm_VirtualSystemSettingData */
+virBufferAsprintf(&query2,
+  "associators of "
+  
"{Msvm_ComputerSystem.CreationClassName=\"Msvm_ComputerSystem\","
+  "Name=\"%s\"} "
+  "where AssocClass = Msvm_SettingsDefineState "
+  "ResultClass = Msvm_VirtualSystemSettingData",
+  uuid_string);
+
+if (hypervGetMsvmVirtualSystemSettingDataList(priv, &query2, 
&virtualSystemSettingData) < 0)
+goto cleanup;
+
+/* Get Msvm_MemorySettingData */
+virBufferFreeAndReset(&query2);
+virBufferAsprintf(&query2,
+  "associators of "
+  "{Msvm_VirtualSystemSettingData.InstanceID=\"%s\"} "
+  "where AssocClass = 
Msvm_VirtualSystemSettingDataComponent "
+  "ResultClass = Msvm_MemorySettingData",
+  virtualSystemSettingData->data->InstanceID);
+
+if (hypervGetMsvmMemorySettingDataList(priv, &query2, &memorySettingData) 
< 0)
+goto cleanup;
+
+embeddedparam.nbProps = 2;
+if (VIR_ALLOC_N(tab_props, embeddedparam.nbProps) < 0)
+goto cleanup;
+(*tab_props).name = "Limit";
+(*tab_props).val = memory_str;
+(*(tab_props+1)).name = "InstanceID";
+(*(tab_props+1)).val = memorySettingData->data->InstanceID;
+embeddedparam.instanceName =  "Msvm_MemorySettingData";
+embeddedparam.prop_t = tab_props;
+embeddedparam.nbProps = 2;
+
+/* Create invokeXmlParam */
+nb_params = 2;
+if (VIR_ALLOC_N(params, nb_params) < 0)
+goto cleanup;
+(*params).name = "ComputerSystem";
+(*params).type = EPR_PARAM;
+(*params).param = &eprparam;
+(*(params+1)).name = "ResourceSettingData";
+(*(params+1)).type = EMBEDDED_PARAM;
+(*(params+1)).param = &embeddedparam;
+
+result = hypervInvokeMethod(priv, params, nb_params, 
"ModifyVirtualSystemResources",
+ MSVM_VIRTUALSYSTEMMANAGEMENTSERVICE_RESOURCE_URI, 
selector);
+
+ cleanup:
+VIR_FREE(tab_props);
+VIR_FREE(params);
+VIR_FREE(memory_str);
+hypervFreeObject(priv, (hypervObject *)virtualSystemSettingData);
+hypervFreeObject(priv, (hypervObject *)memorySettingData);
+virBufferFreeAndReset(&query);
+virBufferFreeAndReset(&query2);
+
+return result;
+}
+
+
+
 static virDriver hypervDriver = {
 .no = VIR_DRV_HYPERV,
 .name = "Hyper-V",
@@ -2058,6 +2176,7 @@ static virDriver hypervDriver = {
 .domainGetSchedulerType = hypervDomainGetSchedulerType, /* 1.2.10 */
 .domainSetAutostart = hypervDomainSetAutostart, /* 1.2.10 */
 .domainGetAutostart = hypervDomainGetAutostart, /* 1.2.10 */
+.domainSetMaxMemory = hypervDomainSetMaxMemory, /* 1.2.10 */
 };
 
 
-- 
1.9.1

--
libvir-list mailing 

[libvirt] [PATCH 17/21] Added implementation for virDomainUndefine and virDomainUndefineFlags

2014-10-08 Thread Yves Vinter
From: yvinter 

---
 src/hyperv/hyperv_driver.c | 73 ++
 1 file changed, 73 insertions(+)

diff --git a/src/hyperv/hyperv_driver.c b/src/hyperv/hyperv_driver.c
index ade9db1..f68eaad 100644
--- a/src/hyperv/hyperv_driver.c
+++ b/src/hyperv/hyperv_driver.c
@@ -2353,6 +2353,77 @@ hypervDomainSetVcpus(virDomainPtr domain, unsigned int 
nvcpus)
 
 
 
+static int
+hypervDomainUndefineFlags(virDomainPtr domain, unsigned int flags 
ATTRIBUTE_UNUSED)
+{
+int result = -1, nb_params;
+const char *selector = 
"CreationClassName=Msvm_VirtualSystemManagementService";
+char uuid_string[VIR_UUID_STRING_BUFLEN];
+hypervPrivate *priv = domain->conn->privateData;
+invokeXmlParam *params = NULL;
+eprParam eprparam;
+virBuffer query = VIR_BUFFER_INITIALIZER;
+Msvm_ComputerSystem *computerSystem = NULL;
+
+virCheckFlags(0, -1);
+
+virUUIDFormat(domain->uuid, uuid_string);
+
+if (hypervMsvmComputerSystemFromDomain(domain, &computerSystem) < 0) {
+goto cleanup;
+}
+
+/* Shutdown the VM if not disabled */
+if (computerSystem->data->EnabledState != 
MSVM_COMPUTERSYSTEM_ENABLEDSTATE_DISABLED) {
+if (hypervDomainShutdown(domain) < 0) {
+goto cleanup;
+}
+}
+
+/* Deleting the VM */
+
+/* Prepare EPR param */
+virBufferFreeAndReset(&query);
+virBufferAddLit(&query, MSVM_COMPUTERSYSTEM_WQL_SELECT);
+virBufferAsprintf(&query, "where Name = \"%s\"", uuid_string);
+eprparam.query = &query;
+eprparam.wmiProviderURI = ROOT_VIRTUALIZATION;
+
+/* Create invokeXmlParam tab */
+nb_params = 1;
+if (VIR_ALLOC_N(params, nb_params) < 0)
+goto cleanup;
+(*params).name = "ComputerSystem";
+(*params).type = EPR_PARAM;
+(*params).param = &eprparam;
+
+/* Destroy VM */
+if (hypervInvokeMethod(priv, params, nb_params, "DestroyVirtualSystem",
+   MSVM_VIRTUALSYSTEMMANAGEMENTSERVICE_RESOURCE_URI, 
selector) < 0) {
+virReportError(VIR_ERR_INTERNAL_ERROR, "%s", _("Could not delete 
domain"));
+goto cleanup;
+}
+
+result = 0;
+
+ cleanup:
+VIR_FREE(params);
+hypervFreeObject(priv, (hypervObject *) computerSystem);
+virBufferFreeAndReset(&query);
+
+return result;
+}
+
+
+
+static int
+hypervDomainUndefine(virDomainPtr domain)
+{
+return hypervDomainUndefineFlags(domain, 0);
+}
+
+
+
 static virDriver hypervDriver = {
 .no = VIR_DRV_HYPERV,
 .name = "Hyper-V",
@@ -2407,6 +2478,8 @@ static virDriver hypervDriver = {
 .domainSetMemoryFlags = hypervDomainSetMemoryFlags, /* 1.2.10 */
 .domainSetVcpus = hypervDomainSetVcpus, /* 1.2.10 */
 .domainSetVcpusFlags = hypervDomainSetVcpusFlags, /* 1.2.10 */
+.domainUndefine = hypervDomainUndefine, /* 1.2.10 */
+.domainUndefineFlags = hypervDomainUndefineFlags, /* 1.2.10 */
 };
 
 
-- 
1.9.1

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


[libvirt] [PATCH 12/21] Added implementation of hypervInvokeMethod which handles complex parameters (simple, EPR or embedded)

2014-10-08 Thread Yves Vinter
From: yvinter 

---
 src/hyperv/hyperv_wmi.c| 666 +
 src/hyperv/hyperv_wmi.h|  53 +++
 src/hyperv/hyperv_wmi_generator.py |  59 
 src/hyperv/openwsman.h |   4 +
 4 files changed, 782 insertions(+)

diff --git a/src/hyperv/hyperv_wmi.c b/src/hyperv/hyperv_wmi.c
index be84532..61fb540 100644
--- a/src/hyperv/hyperv_wmi.c
+++ b/src/hyperv/hyperv_wmi.c
@@ -22,6 +22,7 @@
  */
 
 #include 
+#include   /* Where struct _WsXmlDoc is defined (necessary to 
dereference WsXmlDocH type) */
 
 #include "internal.h"
 #include "virerror.h"
@@ -32,6 +33,7 @@
 #include "hyperv_private.h"
 #include "hyperv_wmi.h"
 #include "virstring.h"
+#include "hyperv_wmi_cimtypes.generated.h"
 
 #define WS_SERIALIZER_FREE_MEM_WORKS 0
 
@@ -383,6 +385,670 @@ hypervReturnCodeToString(int returnCode)
 
 
 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
+ * hypervInvokeMethod
+ *   Function to invoke WSMAN request with simple, EPR or embedded parameters
+ */
+
+/* Create XML structure */
+static int
+hypervCreateXmlStruct(const char *methodName, const char *classURI,
+  WsXmlDocH *xmlDocRoot, WsXmlNodeH *xmlNodeMethod)
+{
+virBuffer method_buff = VIR_BUFFER_INITIALIZER;
+char *methodNameInput = NULL;
+
+virBufferAsprintf(&method_buff, "%s_INPUT", methodName);
+methodNameInput = virBufferContentAndReset(&method_buff);
+
+if (methodNameInput == NULL) {
+virReportError(VIR_ERR_INTERNAL_ERROR,
+   "%s",
+   _("Could not create Xml Doc"));
+goto cleanup;
+}
+
+*xmlDocRoot = ws_xml_create_doc(NULL, methodNameInput);
+if (*xmlDocRoot == NULL) {
+virReportError(VIR_ERR_INTERNAL_ERROR,
+   "%s",
+   _("Could not create Xml Doc with given parameter 
xmlDocRoot"));
+goto cleanup;
+}
+
+*xmlNodeMethod = xml_parser_get_root(*xmlDocRoot);
+if (*xmlNodeMethod == NULL) {
+virReportError(VIR_ERR_INTERNAL_ERROR,
+   "%s",
+   _("Could not get xmlDocRoot root node"));
+goto cleanup;
+}
+
+/* Add namespace to xmlNodeMethode */
+ws_xml_set_ns(*xmlNodeMethod, classURI, "p");
+
+VIR_FREE(methodNameInput);
+return 0;
+
+ cleanup:
+
+virBufferFreeAndReset(&method_buff);
+VIR_FREE(methodNameInput);
+if (*xmlDocRoot != NULL) {
+ws_xml_destroy_doc(*xmlDocRoot);
+*xmlDocRoot = NULL;
+}
+
+return -1;
+}
+
+
+/* Look for the type of a given property class and specifies if it is an array 
*/
+static int
+hypervGetPropType(const char *className, const char *propName, const char 
**propType, bool *isArray)
+{
+int i, y;
+
+i = 0;
+while (cimClasses[i].name[0] != '\0') {
+if (STREQ(cimClasses[i].name, className)){
+y = 0;
+while (cimClasses[i].cimTypesPtr[y].name[0] != '\0') {
+if (STREQ(cimClasses[i].cimTypesPtr[y].name, propName)){
+*propType = cimClasses[i].cimTypesPtr[y].type;
+*isArray = cimClasses[i].cimTypesPtr[y].isArray;
+return 0;
+}
+y++;
+}
+break;
+}
+i++;
+}
+
+return -1;
+}
+
+
+/* Adding an Simple param node to a parent node given in parameter */
+static int
+hypervAddSimpleParam(const char *paramName, const char* value,
+ const char *classURI, WsXmlNodeH *parentNode)
+{
+int result = -1;
+WsXmlNodeH xmlNodeParam = NULL;
+
+xmlNodeParam = ws_xml_add_child(*parentNode, classURI, paramName, value);
+if (xmlNodeParam == NULL) {
+virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
+   _("Could not create simple param"));
+goto cleanup;
+}
+
+result = 0;
+
+ cleanup:
+return result;
+}
+
+
+/* Adding EPR param node to a parent node given in parameter */
+static int
+hypervAddEprParam(const char *paramName, virBufferPtr query, const char *root,
+  const char *classURI, WsXmlNodeH *parentNode, WsXmlDocH doc, 
hypervPrivate *priv)
+{
+
+int result = -1;
+WsXmlNodeH xmlNodeParam = NULL;
+WsXmlNodeH xmlNodTemp = NULL;
+WsXmlNodeH xmlNodeAdr = NULL;
+WsXmlNodeH xmlNodeRef = NULL;
+xmlNodePtr xmlNodeAdrPtr = NULL;
+xmlNodePtr xmlNodeRefPtr = NULL;
+WsXmlDocH xmlDocResponse = NULL;
+xmlDocPtr docPtr = (xmlDocPtr) doc->parserDoc;
+WsXmlNsH ns = NULL;
+client_opt_t *options = NULL;
+filter_t *filter = NULL;
+char *enumContext = NULL;
+char *query_string = NULL;
+
+/* Request options and filter */
+options = wsmc_options_init();
+
+if (options == NULL) {
+virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
+   _("Could not initialize options"));
+goto

[libvirt] [PATCH 11/21] Added implementation for virConnectNumOfDefinedNetworks and virConnectListDefinedNetworks

2014-10-08 Thread Yves Vinter
From: yvinter 

---
 src/hyperv/hyperv_network_driver.c | 81 ++
 1 file changed, 81 insertions(+)

diff --git a/src/hyperv/hyperv_network_driver.c 
b/src/hyperv/hyperv_network_driver.c
index 84267b7..2063090 100644
--- a/src/hyperv/hyperv_network_driver.c
+++ b/src/hyperv/hyperv_network_driver.c
@@ -228,6 +228,85 @@ hypervConnectListNetworks(virConnectPtr conn, char **const 
names, int maxnames)
 
 
 
+static int
+hypervConnectNumOfDefinedNetworks(virConnectPtr conn)
+{
+int result = -1, count = 0;
+hypervPrivate *priv = conn->privateData;
+virBuffer query = VIR_BUFFER_INITIALIZER;
+Msvm_VirtualSwitch *virtualSwitchList = NULL;
+Msvm_VirtualSwitch *virtualSwitch = NULL;
+
+virBufferAddLit(&query, MSVM_VIRTUALSWITCH_WQL_SELECT);
+virBufferAsprintf(&query, "where HealthState <> %d", 5);
+if (hypervGetMsvmVirtualSwitchList(priv, &query, &virtualSwitchList) < 0) {
+goto cleanup;
+}
+
+for (virtualSwitch = virtualSwitchList; virtualSwitch != NULL;
+ virtualSwitch = virtualSwitch->next) {
+count++;
+}
+
+result = count;
+
+ cleanup:
+hypervFreeObject(priv, (hypervObject *) virtualSwitchList);
+virBufferFreeAndReset(&query);
+
+return result;
+}
+
+
+
+static int
+hypervConnectListDefinedNetworks(virConnectPtr conn, char **const names, int 
maxnames)
+{
+int i, count = 0;
+bool success = false;
+hypervPrivate *priv = conn->privateData;
+virBuffer query = VIR_BUFFER_INITIALIZER;
+Msvm_VirtualSwitch *virtualSwitchList = NULL;
+Msvm_VirtualSwitch *virtualSwitch = NULL;
+
+if (maxnames <= 0)
+return 0;
+
+virBufferAddLit(&query, MSVM_VIRTUALSWITCH_WQL_SELECT);
+virBufferAsprintf(&query, "where HealthState <> %d", 5);
+if (hypervGetMsvmVirtualSwitchList(priv, &query, &virtualSwitchList) < 0) {
+goto cleanup;
+}
+
+for (virtualSwitch = virtualSwitchList; virtualSwitch != NULL;
+ virtualSwitch = virtualSwitch->next) {
+if (VIR_STRDUP(names[count], virtualSwitch->data->ElementName) < 0) {
+goto cleanup;
+}
+count++;
+if (count >= maxnames) {
+break;
+}
+}
+
+success = true;
+
+ cleanup:
+if (!success) {
+for (i = 0; i < count; ++i) {
+VIR_FREE(names[i]);
+}
+count = -1;
+}
+
+hypervFreeObject(priv, (hypervObject *) virtualSwitchList);
+virBufferFreeAndReset(&query);
+
+return count;
+}
+
+
+
 static virNetworkDriver hypervNetworkDriver = {
 .name = "Hyper-V",
 .networkOpen = hypervNetworkOpen, /* 0.9.5 */
@@ -236,6 +315,8 @@ static virNetworkDriver hypervNetworkDriver = {
 .networkGetXMLDesc = hypervNetworkGetXMLDesc, /* 1.2.10 */
 .connectNumOfNetworks = hypervConnectNumOfNetworks, /* 1.2.10 */
 .connectListNetworks = hypervConnectListNetworks, /* 1.2.10 */
+.connectNumOfDefinedNetworks = hypervConnectNumOfDefinedNetworks, /* 
1.2.10 */
+.connectListDefinedNetworks = hypervConnectListDefinedNetworks, /* 1.2.10 
*/
 };
 
 
-- 
1.9.1

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


[libvirt] [PATCH 13/21] Added implementation for virDomainSetAutostart and virDomainGetAutostart (required Msvm_VirtualSystemManagementService and Msvm_VirtualSystemGlobalSettingData classes)

2014-10-08 Thread Yves Vinter
From: yvinter 

---
 src/hyperv/hyperv_driver.c| 103 ++
 src/hyperv/hyperv_wmi.c   |   6 --
 src/hyperv/hyperv_wmi.h   |   7 +++
 src/hyperv/hyperv_wmi_generator.input |  50 +
 4 files changed, 160 insertions(+), 6 deletions(-)

diff --git a/src/hyperv/hyperv_driver.c b/src/hyperv/hyperv_driver.c
index 4074fb0..5c79c99 100644
--- a/src/hyperv/hyperv_driver.c
+++ b/src/hyperv/hyperv_driver.c
@@ -1908,6 +1908,107 @@ hypervDomainGetSchedulerType(virDomainPtr domain 
ATTRIBUTE_UNUSED, int *nparams)
 
 
 
+static int
+hypervDomainSetAutostart(virDomainPtr domain, int autostart)
+{
+int result = -1;
+invokeXmlParam *params = NULL;
+hypervPrivate *priv = domain->conn->privateData;
+virBuffer query = VIR_BUFFER_INITIALIZER;
+virBuffer queryVssd = VIR_BUFFER_INITIALIZER;
+Msvm_VirtualSystemSettingData *virtualSystemSettingData = NULL;
+properties_t *tab_props = NULL;
+eprParam eprparam;
+embeddedParam embeddedparam;
+int nb_params;
+char uuid_string[VIR_UUID_STRING_BUFLEN];
+const char *selector = 
"CreationClassName=Msvm_VirtualSystemManagementService";
+
+virUUIDFormat(domain->uuid, uuid_string);
+
+/* Prepare EPR param */
+virBufferAddLit(&query, MSVM_COMPUTERSYSTEM_WQL_SELECT);
+virBufferAsprintf(&query, "where Name = \"%s\"", uuid_string);
+eprparam.query = &query;
+eprparam.wmiProviderURI = ROOT_VIRTUALIZATION;
+
+/* Prepare EMBEDDED param */
+virBufferAsprintf(&queryVssd,
+  "associators of "
+  
"{Msvm_ComputerSystem.CreationClassName=\"Msvm_ComputerSystem\","
+  "Name=\"%s\"} "
+  "where AssocClass = Msvm_SettingsDefineState "
+  "ResultClass = Msvm_VirtualSystemSettingData",
+  uuid_string);
+
+if (hypervGetMsvmVirtualSystemSettingDataList(priv, &queryVssd, 
&virtualSystemSettingData) < 0)
+goto cleanup;
+
+embeddedparam.nbProps = 2;
+if (VIR_ALLOC_N(tab_props, embeddedparam.nbProps) < 0)
+goto cleanup;
+(*tab_props).name = "AutomaticStartupAction";
+(*tab_props).val = autostart ? "2" : "0";
+(*(tab_props+1)).name = "InstanceID";
+(*(tab_props+1)).val = virtualSystemSettingData->data->InstanceID;
+
+embeddedparam.instanceName =  "Msvm_VirtualSystemGlobalSettingData";
+embeddedparam.prop_t = tab_props;
+
+/* Create invokeXmlParam tab */
+nb_params = 2;
+if (VIR_ALLOC_N(params, nb_params) < 0)
+goto cleanup;
+(*params).name = "ComputerSystem";
+(*params).type = EPR_PARAM;
+(*params).param = &eprparam;
+(*(params+1)).name = "SystemSettingData";
+(*(params+1)).type = EMBEDDED_PARAM;
+(*(params+1)).param = &embeddedparam;
+
+result = hypervInvokeMethod(priv, params, nb_params, "ModifyVirtualSystem",
+ MSVM_VIRTUALSYSTEMMANAGEMENTSERVICE_RESOURCE_URI, 
selector);
+
+ cleanup:
+hypervFreeObject(priv, (hypervObject *) virtualSystemSettingData);
+VIR_FREE(tab_props);
+VIR_FREE(params);
+virBufferFreeAndReset(&query);
+virBufferFreeAndReset(&queryVssd);
+
+return result;
+}
+
+
+
+static int
+hypervDomainGetAutostart(virDomainPtr domain, int *autostart)
+{
+int result = -1;
+char uuid_string[VIR_UUID_STRING_BUFLEN];
+hypervPrivate *priv = domain->conn->privateData;
+virBuffer query = VIR_BUFFER_INITIALIZER;
+Msvm_VirtualSystemGlobalSettingData *vsgsd = NULL;
+
+virUUIDFormat(domain->uuid, uuid_string);
+virBufferAddLit(&query, MSVM_VIRTUALSYSTEMGLOBALSETTINGDATA_WQL_SELECT);
+virBufferAsprintf(&query, "where SystemName = \"%s\"", uuid_string);
+
+if (hypervGetMsvmVirtualSystemGlobalSettingDataList(priv, &query, &vsgsd) 
< 0)
+goto cleanup;
+
+*autostart = vsgsd->data->AutomaticStartupAction;
+result = 0;
+
+ cleanup:
+hypervFreeObject(priv, (hypervObject *) vsgsd);
+virBufferFreeAndReset(&query);
+
+return result;
+}
+
+
+
 static virDriver hypervDriver = {
 .no = VIR_DRV_HYPERV,
 .name = "Hyper-V",
@@ -1955,6 +2056,8 @@ static virDriver hypervDriver = {
 .domainGetSchedulerParametersFlags = 
hypervDomainGetSchedulerParametersFlags, /* 1.2.10 */
 .domainGetSchedulerParameters = hypervDomainGetSchedulerParameters, /* 
1.2.10 */
 .domainGetSchedulerType = hypervDomainGetSchedulerType, /* 1.2.10 */
+.domainSetAutostart = hypervDomainSetAutostart, /* 1.2.10 */
+.domainGetAutostart = hypervDomainGetAutostart, /* 1.2.10 */
 };
 
 
diff --git a/src/hyperv/hyperv_wmi.c b/src/hyperv/hyperv_wmi.c
index 61fb540..f086843 100644
--- a/src/hyperv/hyperv_wmi.c
+++ b/src/hyperv/hyperv_wmi.c
@@ -37,12 +37,6 @@
 
 #define WS_SERIALIZER_FREE_MEM_WORKS 0
 
-#define ROOT_CIMV2 \
-"http://schemas.microsoft.com/wbem/wsman/1/wmi/root/cimv2/*";
-
-#define ROOT_VIRTUA

[libvirt] [PATCH 04/21] Added implementation for virDomainGetVcpus and virConnectGetMaxVcpus (required Win32_PerfRawData_HvStats_HyperVHypervisorVirtualProcessor class)

2014-10-08 Thread Yves Vinter
From: yvinter 

---
 src/hyperv/hyperv_driver.c| 184 ++
 src/hyperv/hyperv_wmi_generator.input | 109 
 2 files changed, 293 insertions(+)

diff --git a/src/hyperv/hyperv_driver.c b/src/hyperv/hyperv_driver.c
index dd56fb0..f734c09 100644
--- a/src/hyperv/hyperv_driver.c
+++ b/src/hyperv/hyperv_driver.c
@@ -1532,6 +1532,186 @@ hypervConnectGetCapabilities(virConnectPtr conn)
 
 
 
+static int
+hypervConnectGetMaxVcpus(virConnectPtr conn, const char *type ATTRIBUTE_UNUSED)
+{
+int result = -1;
+hypervPrivate *priv = conn->privateData;
+virBuffer query = VIR_BUFFER_INITIALIZER;
+Msvm_ProcessorSettingData *processorSettingData = NULL;
+
+/* Get Msvm_ProcessorSettingData maximum definition */
+virBufferAddLit(&query, "SELECT * FROM Msvm_ProcessorSettingData "
+"WHERE InstanceID LIKE 'Microsoft:Definition%Maximum'");
+
+if (hypervGetMsvmProcessorSettingDataList(priv, &query, 
&processorSettingData) < 0) {
+goto cleanup;
+}
+
+if (processorSettingData == NULL) {
+virReportError(VIR_ERR_INTERNAL_ERROR,
+   _("Could not get maximum definition of 
Msvm_ProcessorSettingData"));
+goto cleanup;
+}
+
+result = processorSettingData->data->SocketCount * 
processorSettingData->data->ProcessorsPerSocket;
+
+ cleanup:
+hypervFreeObject(priv, (hypervObject *) processorSettingData);
+virBufferFreeAndReset(&query);
+
+return result;
+}
+
+
+
+static int
+hypervDomainGetVcpusFlags(virDomainPtr domain, unsigned int flags)
+{
+int result = -1;
+char uuid_string[VIR_UUID_STRING_BUFLEN];
+hypervPrivate *priv = domain->conn->privateData;
+Msvm_ComputerSystem *computerSystem = NULL;
+Msvm_ProcessorSettingData *processorSettingData = NULL;
+Msvm_VirtualSystemSettingData *virtualSystemSettingData = NULL;
+virBuffer query = VIR_BUFFER_INITIALIZER;
+
+virCheckFlags(VIR_DOMAIN_VCPU_LIVE | VIR_DOMAIN_VCPU_CONFIG | 
VIR_DOMAIN_VCPU_MAXIMUM, -1);
+
+virUUIDFormat(domain->uuid, uuid_string);
+
+/* Get Msvm_ComputerSystem */
+if (hypervMsvmComputerSystemFromDomain(domain, &computerSystem) < 0) {
+goto cleanup;
+}
+
+/* If @flags includes VIR_DOMAIN_VCPU_LIVE,
+   this will query a running domain (which will fail if domain is not 
active) */
+if (flags & VIR_DOMAIN_VCPU_LIVE) {
+if (computerSystem->data->EnabledState != 
MSVM_COMPUTERSYSTEM_ENABLEDSTATE_ENABLED) {
+virReportError(VIR_ERR_OPERATION_INVALID, "%s", _("Domain is not 
active"));
+goto cleanup;
+}
+}
+
+/* If @flags includes VIR_DOMAIN_VCPU_MAXIMUM, then the maximum virtual 
CPU limit is queried */
+if (flags & VIR_DOMAIN_VCPU_MAXIMUM) {
+result = hypervConnectGetMaxVcpus(domain->conn, NULL);
+goto cleanup;
+}
+
+/* Get Msvm_VirtualSystemSettingData */
+virBufferAsprintf(&query,
+  "associators of "
+  
"{Msvm_ComputerSystem.CreationClassName=\"Msvm_ComputerSystem\","
+  "Name=\"%s\"} "
+  "where AssocClass = Msvm_SettingsDefineState "
+  "ResultClass = Msvm_VirtualSystemSettingData",
+  uuid_string);
+if (hypervGetMsvmVirtualSystemSettingDataList(priv, &query, 
&virtualSystemSettingData) < 0) {
+goto cleanup;
+}
+if (virtualSystemSettingData == NULL) {
+virReportError(VIR_ERR_INTERNAL_ERROR, _("Could not lookup %s for 
domain %s"),
+   "Msvm_VirtualSystemSettingData", 
computerSystem->data->ElementName);
+goto cleanup;
+}
+
+/* Get Msvm_ProcessorSettingData */
+virBufferFreeAndReset(&query);
+virBufferAsprintf(&query,
+  "associators of "
+  "{Msvm_VirtualSystemSettingData.InstanceID=\"%s\"} "
+  "where AssocClass = 
Msvm_VirtualSystemSettingDataComponent "
+  "ResultClass = Msvm_ProcessorSettingData",
+  virtualSystemSettingData->data->InstanceID);
+if (hypervGetMsvmProcessorSettingDataList(priv, &query, 
&processorSettingData) < 0) {
+goto cleanup;
+}
+if (processorSettingData == NULL) {
+virReportError(VIR_ERR_INTERNAL_ERROR, _("Could not lookup %s for 
domain %s"),
+   "Msvm_ProcessorSettingData", 
computerSystem->data->ElementName);
+goto cleanup;
+}
+
+result = processorSettingData->data->VirtualQuantity;
+
+ cleanup:
+hypervFreeObject(priv, (hypervObject *)computerSystem);
+hypervFreeObject(priv, (hypervObject *)virtualSystemSettingData);
+hypervFreeObject(priv, (hypervObject *)processorSettingData);
+virBufferFreeAndReset(&query);
+
+return result;
+}
+
+
+
+static int
+hypervDomainGetMaxVcpus(virDomainPtr dom)
+{
+/* If t

[libvirt] [PATCH 02/21] Added implementation for virConnectGetVersion (required CIM_DataFile class)

2014-10-08 Thread Yves Vinter
From: yvinter 

---
 src/hyperv/hyperv_driver.c| 55 +++
 src/hyperv/hyperv_wmi_generator.input | 37 +++
 src/hyperv/hyperv_wmi_generator.py|  4 +--
 3 files changed, 94 insertions(+), 2 deletions(-)

diff --git a/src/hyperv/hyperv_driver.c b/src/hyperv/hyperv_driver.c
index 372ff39..f2017c3 100644
--- a/src/hyperv/hyperv_driver.c
+++ b/src/hyperv/hyperv_driver.c
@@ -1232,6 +1232,7 @@ hypervDomainManagedSaveRemove(virDomainPtr domain, 
unsigned int flags)
 }
 
 
+
 #define MATCH(FLAG) (flags & (FLAG))
 static int
 hypervConnectListAllDomains(virConnectPtr conn,
@@ -1366,6 +1367,59 @@ hypervConnectListAllDomains(virConnectPtr conn,
 
 
 
+static int
+hypervConnectGetVersion(virConnectPtr conn, unsigned long *version)
+{
+int result = -1;
+hypervPrivate *priv = conn->privateData;
+CIM_DataFile  *datafile = NULL;
+virBuffer query = VIR_BUFFER_INITIALIZER;
+char *p;
+
+virBufferAddLit(&query, " Select * from CIM_DataFile where 
Name='c:windowssystem32vmms.exe' ");
+if (hypervGetCIMDataFileList(priv, &query, &datafile) < 0) {
+goto cleanup;
+}
+
+/* Check the result of convertion */
+if (datafile == NULL) {
+virReportError(VIR_ERR_INTERNAL_ERROR,
+   _("Could not lookup %s for domain %s"),
+   "Msvm_VirtualSystemSettingData",
+   datafile->data->Version);
+goto cleanup;
+}
+
+/* Delete release number and last digit of build number 1.1.111x. */
+p = strrchr(datafile->data->Version,'.');
+if (p == NULL) {
+virReportError(VIR_ERR_INTERNAL_ERROR,
+   _("Could not parse version number from '%s'"),
+   datafile->data->Version);
+goto cleanup;
+}
+p--;
+*p = '\0';
+
+/* Parse Version String to Long */
+if (virParseVersionString(datafile->data->Version,
+  version, true) < 0) {
+virReportError(VIR_ERR_INTERNAL_ERROR,
+   _("Could not parse version number from '%s'"),
+   datafile->data->Version);
+goto cleanup;
+}
+
+result = 0;
+
+ cleanup:
+hypervFreeObject(priv, (hypervObject *)datafile);
+virBufferFreeAndReset(&query);
+
+return result;
+}
+
+
 
 static virDriver hypervDriver = {
 .no = VIR_DRV_HYPERV,
@@ -1402,6 +1456,7 @@ static virDriver hypervDriver = {
 .domainHasManagedSaveImage = hypervDomainHasManagedSaveImage, /* 0.9.5 */
 .domainManagedSaveRemove = hypervDomainManagedSaveRemove, /* 0.9.5 */
 .connectIsAlive = hypervConnectIsAlive, /* 0.9.8 */
+.connectGetVersion = hypervConnectGetVersion, /* 1.2.10 */
 };
 
 
diff --git a/src/hyperv/hyperv_wmi_generator.input 
b/src/hyperv/hyperv_wmi_generator.input
index 97f9dff..6b969df 100644
--- a/src/hyperv/hyperv_wmi_generator.input
+++ b/src/hyperv/hyperv_wmi_generator.input
@@ -296,3 +296,40 @@ class Win32_Processor
 string   Version
 uint32   VoltageCaps
 end
+
+
+class CIM_DataFile
+   uint32   AccessMask
+   boolean  Archive
+   string   Caption
+   boolean  Compressed
+   string   CompressionMethod
+   string   CreationClassName
+   datetime CreationDate
+   string   CSCreationClassName
+   string   CSName
+   string   Description
+   string   Drive
+   string   EightDotThreeFileName
+   boolean  Encrypted
+   string   EncryptionMethod
+   string   Extension
+   string   FileName
+   uint64   FileSize
+   string   FileType
+   string   FSCreationClassName
+   string   FSName
+   boolean  Hidden
+   datetime InstallDate
+   uint64   InUseCount
+   datetime LastAccessed
+   datetime LastModified
+   string   Manufacturer
+   string   Name
+   string   Path
+   boolean  Readable
+   string   Status
+   boolean  System
+   string   Version
+   boolean  Writeable
+end
diff --git a/src/hyperv/hyperv_wmi_generator.py 
b/src/hyperv/hyperv_wmi_generator.py
index f767d54..1011719 100755
--- a/src/hyperv/hyperv_wmi_generator.py
+++ b/src/hyperv/hyperv_wmi_generator.py
@@ -68,7 +68,7 @@ class Class:
 header += "\n"
 header += "#define %s_RESOURCE_URI \\\n" % name_upper
 
-if self.name.startswith("Win32_"):
+if self.name.startswith("Win32_") or 
self.name.startswith("CIM_DataFile"):
 header += "
\"http://schemas.microsoft.com/wbem/wsman/1/wmi/root/cimv2/%s\"\n"; % self.name
 else:
 header += "
\"http://schemas.microsoft.com/wbem/wsman/1/wmi/root/virtualization/%s\"\n"; % 
self.name
@@ -113,7 +113,7 @@ class Class:
   % (self.name.replace("_", ""), self.name)
 source += "{\n"
 
-if self.name.startswith("Win32_"):
+if self.name.startswith("Win32_") or 
self.name.startswith("CIM_DataFile"):

[libvirt] [PATCH 10/21] Added implementation for virConnectNumOfNetworks and virConnectListNetworks

2014-10-08 Thread Yves Vinter
From: yvinter 

---
 src/hyperv/hyperv_network_driver.c | 81 ++
 1 file changed, 81 insertions(+)

diff --git a/src/hyperv/hyperv_network_driver.c 
b/src/hyperv/hyperv_network_driver.c
index ee7c0b3..84267b7 100644
--- a/src/hyperv/hyperv_network_driver.c
+++ b/src/hyperv/hyperv_network_driver.c
@@ -149,12 +149,93 @@ hypervNetworkGetXMLDesc(virNetworkPtr network, unsigned 
int flags)
 
 
 
+static int
+hypervConnectNumOfNetworks(virConnectPtr conn)
+{
+int result = -1, count = 0;
+hypervPrivate *priv = conn->privateData;
+virBuffer query = VIR_BUFFER_INITIALIZER;
+Msvm_VirtualSwitch *virtualSwitchList = NULL;
+Msvm_VirtualSwitch *virtualSwitch = NULL;
+
+virBufferAddLit(&query, MSVM_VIRTUALSWITCH_WQL_SELECT);
+virBufferAsprintf(&query, "where HealthState = %d", 5);
+if (hypervGetMsvmVirtualSwitchList(priv, &query, &virtualSwitchList) < 0) {
+goto cleanup;
+}
+
+for (virtualSwitch = virtualSwitchList; virtualSwitch != NULL;
+ virtualSwitch = virtualSwitch->next) {
+count++;
+}
+
+result = count;
+
+ cleanup:
+hypervFreeObject(priv, (hypervObject *) virtualSwitchList);
+virBufferFreeAndReset(&query);
+
+return result;
+}
+
+
+
+static int
+hypervConnectListNetworks(virConnectPtr conn, char **const names, int maxnames)
+{
+int i, count = 0;
+bool success = false;
+hypervPrivate *priv = conn->privateData;
+virBuffer query = VIR_BUFFER_INITIALIZER;
+Msvm_VirtualSwitch *virtualSwitchList = NULL;
+Msvm_VirtualSwitch *virtualSwitch = NULL;
+
+if (maxnames <= 0)
+return 0;
+
+virBufferAddLit(&query, MSVM_VIRTUALSWITCH_WQL_SELECT);
+virBufferAsprintf(&query, "where HealthState = %d", 5);
+if (hypervGetMsvmVirtualSwitchList(priv, &query, &virtualSwitchList) < 0) {
+goto cleanup;
+}
+
+for (virtualSwitch = virtualSwitchList; virtualSwitch != NULL;
+ virtualSwitch = virtualSwitch->next) {
+if (VIR_STRDUP(names[count], virtualSwitch->data->ElementName) < 0) {
+goto cleanup;
+}
+count++;
+if (count >= maxnames) {
+break;
+}
+}
+
+success = true;
+
+ cleanup:
+if (!success) {
+for (i = 0; i < count; ++i) {
+VIR_FREE(names[i]);
+}
+count = -1;
+}
+
+hypervFreeObject(priv, (hypervObject *) virtualSwitchList);
+virBufferFreeAndReset(&query);
+
+return count;
+}
+
+
+
 static virNetworkDriver hypervNetworkDriver = {
 .name = "Hyper-V",
 .networkOpen = hypervNetworkOpen, /* 0.9.5 */
 .networkClose = hypervNetworkClose, /* 0.9.5 */
 .networkLookupByName = hypervNetworkLookupByName, /* 1.2.10 */
 .networkGetXMLDesc = hypervNetworkGetXMLDesc, /* 1.2.10 */
+.connectNumOfNetworks = hypervConnectNumOfNetworks, /* 1.2.10 */
+.connectListNetworks = hypervConnectListNetworks, /* 1.2.10 */
 };
 
 
-- 
1.9.1

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


[libvirt] [PATCH 09/21] Added implementation for virNetworkGetXMLDesc

2014-10-08 Thread Yves Vinter
From: yvinter 

---
 src/hyperv/hyperv_network_driver.c | 57 ++
 1 file changed, 57 insertions(+)

diff --git a/src/hyperv/hyperv_network_driver.c 
b/src/hyperv/hyperv_network_driver.c
index 22e1144..ee7c0b3 100644
--- a/src/hyperv/hyperv_network_driver.c
+++ b/src/hyperv/hyperv_network_driver.c
@@ -27,8 +27,10 @@
 #include "datatypes.h"
 #include "viralloc.h"
 #include "viruuid.h"
+#include "virstring.h"
 #include "hyperv_network_driver.h"
 #include "hyperv_wmi.h"
+#include "network_conf.h"
 
 #define VIR_FROM_THIS VIR_FROM_HYPERV
 
@@ -93,11 +95,66 @@ hypervNetworkLookupByName(virConnectPtr conn, const char 
*name)
 
 
 
+static char *
+hypervNetworkGetXMLDesc(virNetworkPtr network, unsigned int flags)
+{
+char *xml = NULL;
+char uuid_string[VIR_UUID_STRING_BUFLEN];
+hypervPrivate *priv = network->conn->privateData;
+virNetworkDefPtr def = NULL;
+virBuffer query = VIR_BUFFER_INITIALIZER;
+Msvm_VirtualSwitch *virtualSwitch = NULL;
+
+/* Flags checked by virNetworkDefFormat */
+
+if (VIR_ALLOC(def) < 0) {
+virReportOOMError();
+goto cleanup;
+}
+
+virUUIDFormat(network->uuid, uuid_string);
+
+/* Get Msvm_VirtualSwitch */
+virBufferAddLit(&query, MSVM_VIRTUALSWITCH_WQL_SELECT);
+virBufferAsprintf(&query, "where Name = \"%s\"", uuid_string);
+if (hypervGetMsvmVirtualSwitchList(priv, &query, &virtualSwitch) < 0) {
+goto cleanup;
+}
+if (virtualSwitch == NULL) {
+virReportError(VIR_ERR_NO_NETWORK,
+   _("No network found with UUID %s"), uuid_string);
+goto cleanup;
+}
+
+/* Fill struct */
+if (virUUIDParse(virtualSwitch->data->Name, def->uuid) < 0) {
+virReportError(VIR_ERR_INTERNAL_ERROR,
+   _("Could not parse UUID from string '%s'"),
+   virtualSwitch->data->Name);
+return NULL;
+}
+
+if (VIR_STRDUP(def->name, virtualSwitch->data->ElementName) < 0)
+goto cleanup;
+
+xml = virNetworkDefFormat(def, flags);
+
+ cleanup:
+virNetworkDefFree(def);
+hypervFreeObject(priv, (hypervObject *)virtualSwitch);
+virBufferFreeAndReset(&query);
+
+return xml;
+}
+
+
+
 static virNetworkDriver hypervNetworkDriver = {
 .name = "Hyper-V",
 .networkOpen = hypervNetworkOpen, /* 0.9.5 */
 .networkClose = hypervNetworkClose, /* 0.9.5 */
 .networkLookupByName = hypervNetworkLookupByName, /* 1.2.10 */
+.networkGetXMLDesc = hypervNetworkGetXMLDesc, /* 1.2.10 */
 };
 
 
-- 
1.9.1

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


[libvirt] [PATCH 03/21] Added basic implementation for virConnectGetCapabilities (required Win32_ComputerSystemProduct class)

2014-10-08 Thread Yves Vinter
From: yvinter 

---
 src/hyperv/hyperv_driver.c| 112 ++
 src/hyperv/hyperv_private.h   |   2 +
 src/hyperv/hyperv_wmi_generator.input |  12 
 3 files changed, 126 insertions(+)

diff --git a/src/hyperv/hyperv_driver.c b/src/hyperv/hyperv_driver.c
index f2017c3..dd56fb0 100644
--- a/src/hyperv/hyperv_driver.c
+++ b/src/hyperv/hyperv_driver.c
@@ -58,12 +58,19 @@ hypervFreePrivate(hypervPrivate **priv)
 wsmc_release((*priv)->client);
 }
 
+if ((*priv)->caps != NULL)
+virObjectUnref((*priv)->caps);
+
 hypervFreeParsedUri(&(*priv)->parsedUri);
 VIR_FREE(*priv);
 }
 
 
 
+/* Forward declaration of hypervCapsInit */
+static virCapsPtr hypervCapsInit(hypervPrivate *priv);
+
+
 static virDrvOpenStatus
 hypervConnectOpen(virConnectPtr conn, virConnectAuthPtr auth, unsigned int 
flags)
 {
@@ -192,6 +199,12 @@ hypervConnectOpen(virConnectPtr conn, virConnectAuthPtr 
auth, unsigned int flags
 goto cleanup;
 }
 
+/* Setup capabilities */
+priv->caps = hypervCapsInit(priv);
+if (priv->caps == NULL) {
+goto cleanup;
+}
+
 conn->privateData = priv;
 priv = NULL;
 result = VIR_DRV_OPEN_SUCCESS;
@@ -1420,6 +1433,104 @@ hypervConnectGetVersion(virConnectPtr conn, unsigned 
long *version)
 }
 
 
+/* Retrieves host system UUID  */
+static int
+hypervLookupHostSystemBiosUuid(hypervPrivate *priv, unsigned char *uuid)
+{
+Win32_ComputerSystemProduct *computerSystem = NULL;
+virBuffer query = VIR_BUFFER_INITIALIZER;
+int result = -1;
+
+virBufferAddLit(&query, WIN32_COMPUTERSYSTEMPRODUCT_WQL_SELECT);
+
+if (hypervGetWin32ComputerSystemProductList(priv, &query, &computerSystem) 
< 0) {
+goto cleanup;
+}
+
+if (computerSystem == NULL) {
+virReportError(VIR_ERR_NO_DOMAIN,
+   _("Unable to get Win32_ComputerSystemProduct"));
+goto cleanup;
+}
+
+if (virUUIDParse(computerSystem->data->UUID, uuid) < 0) {
+virReportError(VIR_ERR_INTERNAL_ERROR,
+   _("Could not parse UUID from string '%s'"),
+   computerSystem->data->UUID);
+goto cleanup;
+}
+
+result = 0;
+
+ cleanup:
+hypervFreeObject(priv, (hypervObject *)computerSystem);
+virBufferFreeAndReset(&query);
+
+return result;
+}
+
+
+
+static virCapsPtr hypervCapsInit(hypervPrivate *priv)
+{
+virCapsPtr caps = NULL;
+virCapsGuestPtr guest = NULL;
+
+caps = virCapabilitiesNew(VIR_ARCH_X86_64, 1, 1);
+
+if (caps == NULL) {
+virReportOOMError();
+return NULL;
+}
+
+/* virCapabilitiesSetMacPrefix(caps, (unsigned char[]){ 0x00, 0x0c, 0x29 
}); */
+
+if (hypervLookupHostSystemBiosUuid(priv,caps->host.host_uuid) < 0) {
+goto failure;
+}
+
+/* i686 */
+guest = virCapabilitiesAddGuest(caps, "hvm", VIR_ARCH_I686, NULL, NULL, 0, 
NULL);
+if (guest == NULL) {
+goto failure;
+}
+if (virCapabilitiesAddGuestDomain(guest, "hyperv", NULL, NULL, 0, NULL) == 
NULL) {
+goto failure;
+}
+
+/* x86_64 */
+guest = virCapabilitiesAddGuest(caps, "hvm", VIR_ARCH_X86_64, NULL, NULL, 
0, NULL);
+if (guest == NULL) {
+goto failure;
+}
+if (virCapabilitiesAddGuestDomain(guest, "hyperv", NULL, NULL, 0, NULL) == 
NULL) {
+goto failure;
+}
+
+return caps;
+
+ failure:
+virObjectUnref(caps);
+return NULL;
+}
+
+
+
+static char*
+hypervConnectGetCapabilities(virConnectPtr conn)
+{
+hypervPrivate *priv = conn->privateData;
+char *xml = virCapabilitiesFormatXML(priv->caps);
+
+if (xml == NULL) {
+virReportOOMError();
+return NULL;
+}
+
+return xml;
+}
+
+
 
 static virDriver hypervDriver = {
 .no = VIR_DRV_HYPERV,
@@ -1457,6 +1568,7 @@ static virDriver hypervDriver = {
 .domainManagedSaveRemove = hypervDomainManagedSaveRemove, /* 0.9.5 */
 .connectIsAlive = hypervConnectIsAlive, /* 0.9.8 */
 .connectGetVersion = hypervConnectGetVersion, /* 1.2.10 */
+.connectGetCapabilities = hypervConnectGetCapabilities, /* 1.2.10 */
 };
 
 
diff --git a/src/hyperv/hyperv_private.h b/src/hyperv/hyperv_private.h
index 574bb5f..d9aa0bd 100644
--- a/src/hyperv/hyperv_private.h
+++ b/src/hyperv/hyperv_private.h
@@ -26,6 +26,7 @@
 # include "internal.h"
 # include "virerror.h"
 # include "hyperv_util.h"
+# include "capabilities.h"
 # include "openwsman.h"
 
 typedef struct _hypervPrivate hypervPrivate;
@@ -33,6 +34,7 @@ typedef struct _hypervPrivate hypervPrivate;
 struct _hypervPrivate {
 hypervParsedUri *parsedUri;
 WsManClient *client;
+virCapsPtr caps;
 };
 
 #endif /* __HYPERV_PRIVATE_H__ */
diff --git a/src/hyperv/hyperv_wmi_generator.input 
b/src/hyperv/hyperv_wmi_generator.input
index 6b969df..f1e0c81 100644
--- a/src/hyperv/hyperv_wmi_generator.input
+++ b/src/hyperv/hyperv_wmi_generator.in

[libvirt] [PATCH 05/21] Added implementation for virNodeGetFreeMemory (required Win32_OperatingSystem class)

2014-10-08 Thread Yves Vinter
From: yvinter 

---
 src/hyperv/hyperv_driver.c| 34 ++
 src/hyperv/hyperv_wmi_generator.input | 68 +++
 src/hyperv/hyperv_wmi_generator.py|  1 +
 3 files changed, 103 insertions(+)

diff --git a/src/hyperv/hyperv_driver.c b/src/hyperv/hyperv_driver.c
index f734c09..191c7dd 100644
--- a/src/hyperv/hyperv_driver.c
+++ b/src/hyperv/hyperv_driver.c
@@ -1712,6 +1712,39 @@ hypervDomainGetVcpus(virDomainPtr domain, virVcpuInfoPtr 
info, int maxinfo,
 
 
 
+static unsigned long long
+hypervNodeGetFreeMemory(virConnectPtr conn)
+{
+unsigned long long res = 0;
+hypervPrivate *priv = conn->privateData;
+virBuffer query = VIR_BUFFER_INITIALIZER;
+Win32_OperatingSystem *operatingSystem = NULL;
+
+/* Get Win32_OperatingSystem */
+virBufferAddLit(&query, WIN32_OPERATINGSYSTEM_WQL_SELECT);
+
+if (hypervGetWin32OperatingSystemList(priv, &query, &operatingSystem) < 0) 
{
+goto cleanup;
+}
+
+if (operatingSystem == NULL) {
+virReportError(VIR_ERR_INTERNAL_ERROR,
+   _("Could not get Win32_OperatingSystem"));
+goto cleanup;
+}
+
+/* Return free memory in bytes */
+res = operatingSystem->data->FreePhysicalMemory * 1024;
+
+ cleanup:
+hypervFreeObject(priv, (hypervObject *) operatingSystem);
+virBufferFreeAndReset(&query);
+
+return res;
+}
+
+
+
 static virDriver hypervDriver = {
 .no = VIR_DRV_HYPERV,
 .name = "Hyper-V",
@@ -1753,6 +1786,7 @@ static virDriver hypervDriver = {
 .domainGetMaxVcpus = hypervDomainGetMaxVcpus, /* 1.2.10 */
 .domainGetVcpusFlags = hypervDomainGetVcpusFlags, /* 1.2.10 */
 .domainGetVcpus = hypervDomainGetVcpus, /* 1.2.10 */
+.nodeGetFreeMemory = hypervNodeGetFreeMemory, /* 1.2.10 */
 };
 
 
diff --git a/src/hyperv/hyperv_wmi_generator.input 
b/src/hyperv/hyperv_wmi_generator.input
index 8fb34e4..739be87 100644
--- a/src/hyperv/hyperv_wmi_generator.input
+++ b/src/hyperv/hyperv_wmi_generator.input
@@ -454,3 +454,71 @@ class 
Win32_PerfRawData_HvStats_HyperVHypervisorVirtualProcessor
uint64   VirtualMMUHypercallsPersec
uint64   VirtualProcessorHypercallsPersec
 end
+
+
+class Win32_OperatingSystem
+   string   BootDevice
+   string   BuildNumber
+   string   BuildType
+   string   Caption
+   string   CodeSet
+   string   CountryCode
+   string   CreationClassName
+   string   CSCreationClassName
+   string   CSDVersion
+   string   CSName
+   sint16   CurrentTimeZone
+   boolean  DataExecutionPrevention_Available
+   boolean  DataExecutionPrevention_32BitApplications
+   boolean  DataExecutionPrevention_Drivers
+   uint8DataExecutionPrevention_SupportPolicy
+   boolean  Debug
+   string   Description
+   boolean  Distributed
+   uint32   EncryptionLevel
+   uint8ForegroundApplicationBoost
+   uint64   FreePhysicalMemory
+   uint64   FreeSpaceInPagingFiles
+   uint64   FreeVirtualMemory
+   datetime InstallDate
+   uint32   LargeSystemCache
+   datetime LastBootUpTime
+   datetime LocalDateTime
+   string   Locale
+   string   Manufacturer
+   uint32   MaxNumberOfProcesses
+   uint64   MaxProcessMemorySize
+   string   MUILanguages[]
+   string   Name
+   uint32   NumberOfLicensedUsers
+   uint32   NumberOfProcesses
+   uint32   NumberOfUsers
+   uint32   OperatingSystemSKU
+   string   Organization
+   string   OSArchitecture
+   uint32   OSLanguage
+   uint32   OSProductSuite
+   uint16   OSType
+   string   OtherTypeDescription
+   boolean  PAEEnabled
+   string   PlusProductID
+   string   PlusVersionNumber
+   boolean  PortableOperatingSystem
+   boolean  Primary
+   uint32   ProductType
+   string   RegisteredUser
+   string   SerialNumber
+   uint16   ServicePackMajorVersion
+   uint16   ServicePackMinorVersion
+   uint64   SizeStoredInPagingFiles
+   string   Status
+   uint32   SuiteMask
+   string   SystemDevice
+   string   SystemDirectory
+   string   SystemDrive
+   uint64   TotalSwapSpaceSize
+   uint64   TotalVirtualMemorySize
+   uint64   TotalVisibleMemorySize
+   string   Version
+   string   WindowsDirectory
+end
diff --git a/src/hyperv/hyperv_wmi_generator.py 
b/src/hyperv/hyperv_wmi_generator.py
index 1011719..5010470 100755
--- a/src/hyperv/hyperv_wmi_generator.py
+++ b/src/hyperv/hyperv_wmi_generator.py
@@ -158,6 +158,7 @@ class Property:
"int16": "INT16",
"int32": "INT32",
"int64": "INT64",
+   "sint16"   : "INT16",
"uint8": "UINT8",
"uint16"   : "UINT16",
"uint32"   : "UINT32",
-- 
1.9.1

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

[libvirt] [PATCH 07/21] Added implementation for virDomainGetSchedulerType and virDomainGetSchedulerParameters

2014-10-08 Thread Yves Vinter
From: yvinter 

---
 src/hyperv/hyperv_driver.c | 129 +
 1 file changed, 129 insertions(+)

diff --git a/src/hyperv/hyperv_driver.c b/src/hyperv/hyperv_driver.c
index aadadb1..4074fb0 100644
--- a/src/hyperv/hyperv_driver.c
+++ b/src/hyperv/hyperv_driver.c
@@ -41,6 +41,7 @@
 #include "hyperv_wmi.h"
 #include "openwsman.h"
 #include "virstring.h"
+#include "virtypedparam.h"
 
 #define VIR_FROM_THIS VIR_FROM_HYPERV
 
@@ -1782,6 +1783,131 @@ hypervDomainShutdown(virDomainPtr dom)
 
 
 
+static int
+hypervDomainGetSchedulerParametersFlags(virDomainPtr dom, virTypedParameterPtr 
params,
+int *nparams, unsigned int flags)
+{
+hypervPrivate *priv = dom->conn->privateData;
+Msvm_ComputerSystem *computerSystem = NULL;
+Msvm_ProcessorSettingData *processorSettingData = NULL;
+Msvm_VirtualSystemSettingData *virtualSystemSettingData = NULL;
+char uuid_string[VIR_UUID_STRING_BUFLEN];
+virBuffer query = VIR_BUFFER_INITIALIZER;
+int saved_nparams = 0;
+int result = -1;
+
+virCheckFlags(VIR_DOMAIN_AFFECT_LIVE |VIR_DOMAIN_AFFECT_CONFIG 
|VIR_TYPED_PARAM_STRING_OKAY, -1);
+
+/* We don't return strings, and thus trivially support this flag */
+flags &= ~VIR_TYPED_PARAM_STRING_OKAY;
+
+virUUIDFormat(dom->uuid, uuid_string);
+
+/* Get Msvm_ComputerSystem */
+if (hypervMsvmComputerSystemFromDomain(dom, &computerSystem) < 0) {
+goto cleanup;
+}
+
+/* Get Msvm_VirtualSystemSettingData */
+virBufferAsprintf(&query,
+  "associators of "
+  
"{Msvm_ComputerSystem.CreationClassName=\"Msvm_ComputerSystem\","
+  "Name=\"%s\"} "
+  "where AssocClass = Msvm_SettingsDefineState "
+  "ResultClass = Msvm_VirtualSystemSettingData",
+  uuid_string);
+
+if (hypervGetMsvmVirtualSystemSettingDataList(priv, &query, 
&virtualSystemSettingData) < 0) {
+goto cleanup;
+}
+
+if (virtualSystemSettingData == NULL) {
+virReportError(VIR_ERR_INTERNAL_ERROR,
+   _("Could not lookup %s for domain %s"),
+   "Msvm_VirtualSystemSettingData",
+   computerSystem->data->ElementName);
+goto cleanup;
+}
+
+/* Get Msvm_ProcessorSettingData */
+virBufferAsprintf(&query,
+  "associators of "
+  "{Msvm_VirtualSystemSettingData.InstanceID=\"%s\"} "
+  "where AssocClass = 
Msvm_VirtualSystemSettingDataComponent "
+  "ResultClass = Msvm_ProcessorSettingData",
+  virtualSystemSettingData->data->InstanceID);
+
+if (hypervGetMsvmProcessorSettingDataList(priv, &query, 
&processorSettingData) < 0) {
+goto cleanup;
+}
+
+if (processorSettingData == NULL) {
+virReportError(VIR_ERR_INTERNAL_ERROR, _("Could not lookup %s for 
domain %s"),
+   
"Msvm_ProcessorSettingData",computerSystem->data->ElementName);
+goto cleanup;
+}
+
+if (virTypedParameterAssign(¶ms[0], VIR_DOMAIN_SCHEDULER_LIMIT,
+VIR_TYPED_PARAM_LLONG, 
processorSettingData->data->Limit) < 0)
+goto cleanup;
+saved_nparams++;
+
+if (*nparams > saved_nparams) {
+if 
(virTypedParameterAssign(¶ms[1],VIR_DOMAIN_SCHEDULER_RESERVATION,
+VIR_TYPED_PARAM_LLONG, 
processorSettingData->data->Reservation) < 0)
+goto cleanup;
+saved_nparams++;
+}
+
+if (*nparams > saved_nparams) {
+if (virTypedParameterAssign(¶ms[2],VIR_DOMAIN_SCHEDULER_WEIGHT,
+VIR_TYPED_PARAM_UINT, 
processorSettingData->data->Weight) < 0)
+goto cleanup;
+saved_nparams++;
+}
+
+*nparams = saved_nparams;
+
+result = 0;
+
+ cleanup:
+hypervFreeObject(priv, (hypervObject *)computerSystem);
+hypervFreeObject(priv, (hypervObject *)virtualSystemSettingData);
+hypervFreeObject(priv, (hypervObject *)processorSettingData);
+virBufferFreeAndReset(&query);
+
+return result;
+}
+
+
+
+static int
+hypervDomainGetSchedulerParameters(virDomainPtr dom, virTypedParameterPtr 
params, int *nparams)
+{
+return hypervDomainGetSchedulerParametersFlags(dom, params, nparams, 
VIR_DOMAIN_AFFECT_CURRENT);
+}
+
+
+
+static char*
+hypervDomainGetSchedulerType(virDomainPtr domain ATTRIBUTE_UNUSED, int 
*nparams)
+{
+char *type;
+
+if (VIR_STRDUP(type, "allocation") < 0) {
+virReportOOMError();
+return NULL;
+}
+
+if (nparams != NULL) {
+*nparams = 3; /* reservation, limit, weight */
+}
+
+return type;
+}
+
+
+
 static virDriver hypervDriver = {
 .no = VIR_DRV_HYPERV,
 .name = "Hyper-V",
@@ -1826,6 +1952,9 

[libvirt] [PATCH 01/21] Added missing virBufferFreeAndReset on the query buffer to free some memory

2014-10-08 Thread Yves Vinter
From: yvinter 

---
 src/hyperv/hyperv_driver.c | 13 +
 src/hyperv/hyperv_wmi.c| 15 +++
 2 files changed, 24 insertions(+), 4 deletions(-)

diff --git a/src/hyperv/hyperv_driver.c b/src/hyperv/hyperv_driver.c
index aed9307..372ff39 100644
--- a/src/hyperv/hyperv_driver.c
+++ b/src/hyperv/hyperv_driver.c
@@ -201,6 +201,7 @@ hypervConnectOpen(virConnectPtr conn, virConnectAuthPtr 
auth, unsigned int flags
 VIR_FREE(username);
 VIR_FREE(password);
 hypervFreeObject(priv, (hypervObject *)computerSystem);
+virBufferFreeAndReset(&query);
 
 return result;
 }
@@ -254,6 +255,7 @@ hypervConnectGetHostname(virConnectPtr conn)
 
  cleanup:
 hypervFreeObject(priv, (hypervObject *)computerSystem);
+virBufferFreeAndReset(&query);
 
 return hostname;
 }
@@ -352,6 +354,7 @@ hypervNodeGetInfo(virConnectPtr conn, virNodeInfoPtr info)
  cleanup:
 hypervFreeObject(priv, (hypervObject *)computerSystem);
 hypervFreeObject(priv, (hypervObject *)processorList);
+virBufferFreeAndReset(&query);
 
 return result;
 }
@@ -396,6 +399,7 @@ hypervConnectListDomains(virConnectPtr conn, int *ids, int 
maxids)
 
  cleanup:
 hypervFreeObject(priv, (hypervObject *)computerSystemList);
+virBufferFreeAndReset(&query);
 
 return success ? count : -1;
 }
@@ -432,6 +436,7 @@ hypervConnectNumOfDomains(virConnectPtr conn)
 
  cleanup:
 hypervFreeObject(priv, (hypervObject *)computerSystemList);
+virBufferFreeAndReset(&query);
 
 return success ? count : -1;
 }
@@ -464,6 +469,7 @@ hypervDomainLookupByID(virConnectPtr conn, int id)
 
  cleanup:
 hypervFreeObject(priv, (hypervObject *)computerSystem);
+virBufferFreeAndReset(&query);
 
 return domain;
 }
@@ -500,6 +506,7 @@ hypervDomainLookupByUUID(virConnectPtr conn, const unsigned 
char *uuid)
 
  cleanup:
 hypervFreeObject(priv, (hypervObject *)computerSystem);
+virBufferFreeAndReset(&query);
 
 return domain;
 }
@@ -533,6 +540,7 @@ hypervDomainLookupByName(virConnectPtr conn, const char 
*name)
 
  cleanup:
 hypervFreeObject(priv, (hypervObject *)computerSystem);
+virBufferFreeAndReset(&query);
 
 return domain;
 }
@@ -748,6 +756,7 @@ hypervDomainGetInfo(virDomainPtr domain, virDomainInfoPtr 
info)
 hypervFreeObject(priv, (hypervObject *)virtualSystemSettingData);
 hypervFreeObject(priv, (hypervObject *)processorSettingData);
 hypervFreeObject(priv, (hypervObject *)memorySettingData);
+virBufferFreeAndReset(&query);
 
 return result;
 }
@@ -915,6 +924,7 @@ hypervDomainGetXMLDesc(virDomainPtr domain, unsigned int 
flags)
 hypervFreeObject(priv, (hypervObject *)virtualSystemSettingData);
 hypervFreeObject(priv, (hypervObject *)processorSettingData);
 hypervFreeObject(priv, (hypervObject *)memorySettingData);
+virBufferFreeAndReset(&query);
 
 return xml;
 }
@@ -971,6 +981,7 @@ hypervConnectListDefinedDomains(virConnectPtr conn, char 
**const names, int maxn
 }
 
 hypervFreeObject(priv, (hypervObject *)computerSystemList);
+virBufferFreeAndReset(&query);
 
 return count;
 }
@@ -1007,6 +1018,7 @@ hypervConnectNumOfDefinedDomains(virConnectPtr conn)
 
  cleanup:
 hypervFreeObject(priv, (hypervObject *)computerSystemList);
+virBufferFreeAndReset(&query);
 
 return success ? count : -1;
 }
@@ -1346,6 +1358,7 @@ hypervConnectListAllDomains(virConnectPtr conn,
 }
 
 hypervFreeObject(priv, (hypervObject *)computerSystemList);
+virBufferFreeAndReset(&query);
 
 return ret;
 }
diff --git a/src/hyperv/hyperv_wmi.c b/src/hyperv/hyperv_wmi.c
index acb705c..d93abd9 100644
--- a/src/hyperv/hyperv_wmi.c
+++ b/src/hyperv/hyperv_wmi.c
@@ -526,6 +526,7 @@ 
hypervInvokeMsvmComputerSystemRequestStateChange(virDomainPtr domain,
 VIR_FREE(returnValue);
 VIR_FREE(instanceID);
 hypervFreeObject(priv, (hypervObject *)concreteJob);
+virBufferFreeAndReset(&query);
 
 return result;
 }
@@ -646,13 +647,14 @@ int
 hypervMsvmComputerSystemFromDomain(virDomainPtr domain,
Msvm_ComputerSystem **computerSystem)
 {
+int result = -1;
 hypervPrivate *priv = domain->conn->privateData;
 char uuid_string[VIR_UUID_STRING_BUFLEN];
 virBuffer query = VIR_BUFFER_INITIALIZER;
 
 if (computerSystem == NULL || *computerSystem != NULL) {
 virReportError(VIR_ERR_INTERNAL_ERROR, "%s", _("Invalid argument"));
-return -1;
+goto cleanup;
 }
 
 virUUIDFormat(domain->uuid, uuid_string);
@@ -663,16 +665,21 @@ hypervMsvmComputerSystemFromDomain(virDomainPtr domain,
 virBufferAsprintf(&query, "and Name = \"%s\"", uuid_string);
 
 if (hypervGetMsvmComputerSystemList(priv, &query, computerSystem) < 0) {
-return -1;
+goto cleanup;
 }
 
 if (*computerSystem == NULL) {
 virReportError(VIR_ERR_NO_DOMAIN,
_("No domain with UUID %s"), uuid_string);
-return -1;
+goto c

[libvirt] [PATCH 08/21] Added implementation for virNetworkLookupByName (required Msvm_VirtualSwitch class)

2014-10-08 Thread Yves Vinter
From: yvinter 

---
 src/hyperv/hyperv_network_driver.c| 33 +
 src/hyperv/hyperv_wmi.c   | 27 +++
 src/hyperv/hyperv_wmi.h   |  9 +
 src/hyperv/hyperv_wmi_generator.input | 33 +
 4 files changed, 102 insertions(+)

diff --git a/src/hyperv/hyperv_network_driver.c 
b/src/hyperv/hyperv_network_driver.c
index 6f54f44..22e1144 100644
--- a/src/hyperv/hyperv_network_driver.c
+++ b/src/hyperv/hyperv_network_driver.c
@@ -28,6 +28,7 @@
 #include "viralloc.h"
 #include "viruuid.h"
 #include "hyperv_network_driver.h"
+#include "hyperv_wmi.h"
 
 #define VIR_FROM_THIS VIR_FROM_HYPERV
 
@@ -61,10 +62,42 @@ hypervNetworkClose(virConnectPtr conn)
 
 
 
+static virNetworkPtr
+hypervNetworkLookupByName(virConnectPtr conn, const char *name)
+{
+virNetworkPtr network = NULL;
+hypervPrivate *priv = conn->privateData;
+virBuffer query = VIR_BUFFER_INITIALIZER;
+Msvm_VirtualSwitch *virtualSwitch = NULL;
+
+virBufferAddLit(&query, MSVM_VIRTUALSWITCH_WQL_SELECT);
+virBufferAsprintf(&query, "where Description = \"%s\" and ElementName = 
\"%s\"",
+  "Microsoft Virtual Switch", name);
+if (hypervGetMsvmVirtualSwitchList(priv, &query, &virtualSwitch) < 0) {
+goto cleanup;
+}
+if (virtualSwitch == NULL) {
+virReportError(VIR_ERR_NO_NETWORK,
+   _("No network found with name %s"), name);
+goto cleanup;
+}
+
+hypervMsvmVirtualSwitchToNetwork(conn, virtualSwitch, &network);
+
+ cleanup:
+hypervFreeObject(priv, (hypervObject *) virtualSwitch);
+virBufferFreeAndReset(&query);
+
+return network;
+}
+
+
+
 static virNetworkDriver hypervNetworkDriver = {
 .name = "Hyper-V",
 .networkOpen = hypervNetworkOpen, /* 0.9.5 */
 .networkClose = hypervNetworkClose, /* 0.9.5 */
+.networkLookupByName = hypervNetworkLookupByName, /* 1.2.10 */
 };
 
 
diff --git a/src/hyperv/hyperv_wmi.c b/src/hyperv/hyperv_wmi.c
index d93abd9..be84532 100644
--- a/src/hyperv/hyperv_wmi.c
+++ b/src/hyperv/hyperv_wmi.c
@@ -682,6 +682,33 @@ hypervMsvmComputerSystemFromDomain(virDomainPtr domain,
 return result;
 }
 
+int
+hypervMsvmVirtualSwitchToNetwork(virConnectPtr conn,
+ Msvm_VirtualSwitch *virtualSwitch, 
virNetworkPtr *network)
+{
+unsigned char uuid[VIR_UUID_BUFLEN];
+
+if (network == NULL || *network != NULL) {
+virReportError(VIR_ERR_INTERNAL_ERROR, "%s", _("Invalid argument"));
+return -1;
+}
+
+if (virUUIDParse(virtualSwitch->data->Name, uuid) < 0) {
+virReportError(VIR_ERR_INTERNAL_ERROR,
+   _("Could not parse UUID from string '%s'"),
+   virtualSwitch->data->Name);
+return -1;
+}
+
+*network = virGetNetwork(conn, virtualSwitch->data->ElementName, uuid);
+
+if (*network == NULL) {
+return -1;
+}
+
+return 0;
+}
+
 
 
 #include "hyperv_wmi.generated.c"
diff --git a/src/hyperv/hyperv_wmi.h b/src/hyperv/hyperv_wmi.h
index 5fbbbac..acc4097 100644
--- a/src/hyperv/hyperv_wmi.h
+++ b/src/hyperv/hyperv_wmi.h
@@ -115,6 +115,15 @@ int hypervMsvmComputerSystemFromDomain(virDomainPtr domain,
 
 
 
+/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
+ * Msvm_VirtualSwitch
+ */
+
+int hypervMsvmVirtualSwitchToNetwork(virConnectPtr conn,
+   Msvm_VirtualSwitch *virtualSwitch, virNetworkPtr *network);
+
+
+
 # include "hyperv_wmi.generated.h"
 
 #endif /* __HYPERV_WMI_H__ */
diff --git a/src/hyperv/hyperv_wmi_generator.input 
b/src/hyperv/hyperv_wmi_generator.input
index 739be87..21420d5 100644
--- a/src/hyperv/hyperv_wmi_generator.input
+++ b/src/hyperv/hyperv_wmi_generator.input
@@ -522,3 +522,36 @@ class Win32_OperatingSystem
string   Version
string   WindowsDirectory
 end
+
+
+class Msvm_VirtualSwitch
+   string Caption
+   string Description
+   string ElementName
+   datetime InstallDate
+   uint16 OperationalStatus[]
+   string StatusDescriptions[]
+   string Status
+   uint16 HealthState
+   uint16 EnabledState
+   string OtherEnabledState
+   uint16 RequestedState
+   uint16 EnabledDefault
+   datetime TimeOfLastStateChange
+   string CreationClassName
+   string Name
+   string PrimaryOwnerContact
+   string PrimaryOwnerName
+   string Roles[]
+   string NameFormat
+   string OtherIdentifyingInfo[]
+   string IdentifyingDescriptions[]
+   uint16 Dedicated[]
+   string OtherDedicatedDescriptions[]
+   uint16 ResetCapability
+   uint16 PowerManagementCapabilities[]
+   string ScopeOfResidence
+   uint32 NumLearnableAddresses
+   uint32 MaxVMQOffloads
+   uint32 MaxChimneyOffloads
+end
-- 
1.9.1

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

[libvirt] [PATCH 06/21] Added implementation for virDomainShutdown and virDomainShutdownFlags

2014-10-08 Thread Yves Vinter
From: yvinter 

---
 src/hyperv/hyperv_driver.c | 39 +++
 1 file changed, 39 insertions(+)

diff --git a/src/hyperv/hyperv_driver.c b/src/hyperv/hyperv_driver.c
index 191c7dd..aadadb1 100644
--- a/src/hyperv/hyperv_driver.c
+++ b/src/hyperv/hyperv_driver.c
@@ -1745,6 +1745,43 @@ hypervNodeGetFreeMemory(virConnectPtr conn)
 
 
 
+static int
+hypervDomainShutdownFlags(virDomainPtr domain, unsigned int flags)
+{
+int result = -1;
+hypervPrivate *priv = domain->conn->privateData;
+Msvm_ComputerSystem *computerSystem = NULL;
+bool in_transition = false;
+
+virCheckFlags(0, -1);
+
+if (hypervMsvmComputerSystemFromDomain(domain, &computerSystem) < 0) {
+goto cleanup;
+}
+
+if (!hypervIsMsvmComputerSystemActive(computerSystem, &in_transition) || 
in_transition) {
+virReportError(VIR_ERR_OPERATION_INVALID, "%s",
+   _("Domain is not active or is in state transition"));
+goto cleanup;
+}
+
+result = hypervInvokeMsvmComputerSystemRequestStateChange(domain, 
MSVM_COMPUTERSYSTEM_REQUESTEDSTATE_DISABLED);
+
+ cleanup:
+hypervFreeObject(priv, (hypervObject *) computerSystem);
+return result;
+}
+
+
+
+static int
+hypervDomainShutdown(virDomainPtr dom)
+{
+return hypervDomainShutdownFlags(dom, 0);
+}
+
+
+
 static virDriver hypervDriver = {
 .no = VIR_DRV_HYPERV,
 .name = "Hyper-V",
@@ -1787,6 +1824,8 @@ static virDriver hypervDriver = {
 .domainGetVcpusFlags = hypervDomainGetVcpusFlags, /* 1.2.10 */
 .domainGetVcpus = hypervDomainGetVcpus, /* 1.2.10 */
 .nodeGetFreeMemory = hypervNodeGetFreeMemory, /* 1.2.10 */
+.domainShutdownFlags = hypervDomainShutdownFlags, /* 1.2.10 */
+.domainShutdown = hypervDomainShutdown, /* 1.2.10 */
 };
 
 
-- 
1.9.1

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


Re: [libvirt] [PATCH] security_selinux: Don't relabel /dev/net/tun

2014-10-08 Thread Michal Privoznik

On 07.10.2014 17:19, Eric Blake wrote:

On 10/07/2014 08:53 AM, Michal Privoznik wrote:

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

The code for relabelling the TAP FD is there due to a race. When
libvirt creates a /dev/tapN device it's labeled as
'system_u:object_r:device_t:s0' by default. Later, when
udev/systemd reacts to this device, it's relabelled to the
expected label 'system_u:object_r:tun_tap_device_t:s0'. Hence, we
have a code that relabels the device, to cut the race down. For
more info see ae368ebfcc4.

But the problem is, the relabel function is called on all TUN/TAP
devices. Yes, on /dev/net/tun too. This is however a special kind
of device - other processes uses it too. We shouldn't touch it's
label then.

Ideally, there would an API in SELinux that would label just the
passed FD and not the underlying path. That way, we wouldn't need
to care as we would be not labeling /dev/net/tun but the FD
passed to the domain. Unfortunately, there's no such API so we
have to workaround until then.




+
+if (!STRPREFIX(fd_path, "/dev/tap")) {


Should this be "/dev/tap.", since...


+VIR_DEBUG("fd=%d points to %s not setting SELinux label",
+  fd, fd_path);
+rc = 0;
+goto cleanup;
+}
+
  if (getContext(mgr, "/dev/tap.*", buf.st_mode, &fcon) < 0) {


...you require a '.' in the context lookup?  Without the '.' in the
filter, you would let the (unlikely) name '/dev/tapX' get through.

ACK with that tweaked.




In fact, /dev/tapX is what is created. getContext should be using it too 
as it accepts shell expendable names, not regular expressions. I'm 
adjusting getContext's argument too.


Michal

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


Re: [libvirt] [PATCH v3 2/3] conf: add check if migration_host is a localhost address

2014-10-08 Thread Ján Tomko
On 10/07/2014 06:07 AM, Chen Fan wrote:
>  Signed-off-by: Chen Fan 
> ---
>  src/libvirt_private.syms |  1 +
>  src/qemu/qemu_conf.c | 50 
> 
>  src/qemu/qemu_conf.h |  2 ++
>  src/util/virsocketaddr.c | 24 +++
>  src/util/virsocketaddr.h |  2 ++
>  5 files changed, 79 insertions(+)
> 
> diff --git a/src/libvirt_private.syms b/src/libvirt_private.syms
> index 8ab1394..a104bc6 100644
> --- a/src/libvirt_private.syms
> +++ b/src/libvirt_private.syms
> @@ -1911,6 +1911,7 @@ virSocketAddrGetIpPrefix;
>  virSocketAddrGetPort;
>  virSocketAddrGetRange;
>  virSocketAddrIsNetmask;
> +virSocketAddrIsNumericLocalhost;
>  virSocketAddrIsPrivate;
>  virSocketAddrIsWildcard;
>  virSocketAddrMask;
> diff --git a/src/qemu/qemu_conf.c b/src/qemu/qemu_conf.c
> index adc6caf..6b0ac5c 100644
> --- a/src/qemu/qemu_conf.c
> +++ b/src/qemu/qemu_conf.c
> @@ -707,6 +707,15 @@ int virQEMUDriverConfigLoadFile(virQEMUDriverConfigPtr 
> cfg,
>  GET_VALUE_LONG("seccomp_sandbox", cfg->seccompSandbox);
>  
>  GET_VALUE_STR("migration_host", cfg->migrateHost);
> +if (cfg->migrateHost &&
> +qemuCheckLocalhost(cfg->migrateHost)) {
> +virReportError(VIR_ERR_CONF_SYNTAX,
> +   _("migration_host must not be the address of"
> + " the local machine: %s"),
> +   cfg->migrateHost);
> +goto cleanup;
> +}
> +
>  GET_VALUE_STR("migration_address", cfg->migrationAddress);
>  
>  GET_VALUE_BOOL("log_timestamp", cfg->logTimestamp);
> @@ -1371,3 +1380,44 @@ qemuGetDefaultHugepath(virHugeTLBFSPtr hugetlbfs,
>  
>  return qemuGetHugepagePath(&hugetlbfs[i]);
>  }
> +
> +bool
> +qemuCheckLocalhost(const char *addrStr)
> +{
> +virSocketAddr addr;
> +char *hostname, *tmp;
> +bool encloseAddress = false;
> +int family;
> +bool ret = true;
> +
> +if (VIR_STRDUP(hostname, addrStr) < 0)
> +return false;
> +
> +tmp = hostname;
> +
> +if (STRPREFIX(hostname, "[")) {
> +char *end = strchr(hostname, ']');
> +if (end) {
> +*end = '\0';
> +hostname++;
> +encloseAddress = true;
> +}
> +}

We don't format the qemu.conf back and we don't need the brackets for
anything. We can just store the migration host without them in 
cfg->migrationHost

> +
> +if (STRPREFIX(hostname, "localhost"))
> +goto cleanup;
> +
> +family = virSocketAddrNumericFamily(hostname);
> +if ((family == AF_INET && !encloseAddress) ||
> +family == AF_INET6) {
> +if (virSocketAddrParse(&addr, hostname, family) > 0 &&
> +virSocketAddrIsNumericLocalhost(&addr)) {
> +goto cleanup;
> +}
> +}

There's no need to check for family upfront.

> +
> +ret = false;
> +cleanup:
> +VIR_FREE(tmp);
> +return ret;
> +}
> diff --git a/src/qemu/qemu_conf.h b/src/qemu/qemu_conf.h
> index cb01fb6..c9ce53c 100644
> --- a/src/qemu/qemu_conf.h
> +++ b/src/qemu/qemu_conf.h
> @@ -322,4 +322,6 @@ int qemuTranslateSnapshotDiskSourcePool(virConnectPtr 
> conn,
>  char * qemuGetHugepagePath(virHugeTLBFSPtr hugepage);
>  char * qemuGetDefaultHugepath(virHugeTLBFSPtr hugetlbfs,
>size_t nhugetlbfs);
> +
> +bool qemuCheckLocalhost(const char *addrStr);
>  #endif /* __QEMUD_CONF_H */
> diff --git a/src/util/virsocketaddr.c b/src/util/virsocketaddr.c
> index 7fe7a15..6d36689 100644
> --- a/src/util/virsocketaddr.c
> +++ b/src/util/virsocketaddr.c
> @@ -878,3 +878,27 @@ virSocketAddrNumericFamily(const char *address)
>  freeaddrinfo(res);
>  return family;
>  }
> +
> +/**
> + * virSocketAddrIsNumericLocalhost:
> + * @address: address to check
> + *
> + * Check if passed address is a numeric 'localhost' address.
> + *
> + * Returns: true if @address is a numeric 'localhost' address,
> + *  false otherwise
> + */
> +bool
> +virSocketAddrIsNumericLocalhost(const virSocketAddr *addr)

I've rewritten this function to take a 'const char *' argument.
Along with the virStringStripIPv6Brackets function I've sent for review
separately, this removes the need for a separate qemuCheckLocalhost function
and it can be inlined.

> +{
> +struct in_addr tmp = { .s_addr = htonl(INADDR_LOOPBACK) };
> +switch (addr->data.stor.ss_family) {
> +case AF_INET:
> +return memcmp(&addr->data.inet4.sin_addr.s_addr, &tmp.s_addr,
> +  sizeof(addr->data.inet4.sin_addr.s_addr)) == 0;
> +case AF_INET6:
> +return IN6_IS_ADDR_LOOPBACK(&addr->data.inet6.sin6_addr);
> +}
> +return false;
> +
> +}

The diff I'll squash into this patch before pushing (after
virStringStripIPv6Brackets is sorted out):

--- a/src/qemu/qemu_conf.c
+++ b/src/qemu/qemu_conf.c
@@ -707,8 +707,10 @@ int virQEMUDriverConfigLoadFile(virQEMUDriverConfigPtr cfg,
 GET_VALUE_LONG("seccomp_sandbox", cfg->seccompSandbox);

 GET

Re: [libvirt] [PATCH] Introduce virStringStripIPv6Brackets

2014-10-08 Thread Ján Tomko
On 10/08/2014 11:10 AM, Daniel P. Berrange wrote:
> On Wed, Oct 08, 2014 at 10:46:53AM +0200, Ján Tomko wrote:
>> Helper function to strip the brackets from an IPv6 address.
>> Tested by viruritest.
>> ---
>>  src/libvirt_private.syms |  1 +
>>  src/util/virstring.c | 22 ++
>>  src/util/virstring.h |  2 ++
>>  src/util/viruri.c| 20 
>>  4 files changed, 29 insertions(+), 16 deletions(-)
> 
> Can we have tests in viruritest.c and virstringtest.c too
> 

We already test it on sane inputs in viruritest.

I've added some corner cases to virstringtest in v2.

> 
> Regards,
> Daniel
> 



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

[libvirt] [PATCH v2] qemu: Pass file descriptor when using TPM passthrough

2014-10-08 Thread Stefan Berger
From: Stefan Berger 

Pass the TPM file descriptor to QEMU via command line.
Instead of passing /dev/tpm0 we now pass /dev/fdset/10 and the additional
parameters -add-fd set=10,fd=20.

This addresses the use case when QEMU is started with non-root privileges
and QEMU cannot open /dev/tpm0 for example.

One problem is that for the passing of the file descriptor set to work,
virCommandReorderFDs must not be called on the virCommand. This is prevented
by setting a flag in the virCommandPassFDGetFDIndex that is checked to be
clear when virCommandReorderFDs is run.

Signed-off-by: Stefan Berger 
---
 src/libvirt_private.syms |   1 +
 src/qemu/qemu_command.c  | 132 ---
 src/util/vircommand.c|  33 
 src/util/vircommand.h|   3 ++
 4 files changed, 162 insertions(+), 7 deletions(-)

diff --git a/src/libvirt_private.syms b/src/libvirt_private.syms
index d6265ac..6c697bb 100644
--- a/src/libvirt_private.syms
+++ b/src/libvirt_private.syms
@@ -1158,6 +1158,7 @@ virCommandNewArgList;
 virCommandNewArgs;
 virCommandNonblockingFDs;
 virCommandPassFD;
+virCommandPassFDGetFDIndex;
 virCommandPassListenFDs;
 virCommandRawStatus;
 virCommandRequireHandshake;
diff --git a/src/qemu/qemu_command.c b/src/qemu/qemu_command.c
index 8cb0865..2e030fb 100644
--- a/src/qemu/qemu_command.c
+++ b/src/qemu/qemu_command.c
@@ -157,6 +157,58 @@ VIR_ENUM_IMPL(qemuNumaPolicy, VIR_DOMAIN_NUMATUNE_MEM_LAST,
   "interleave");
 
 /**
+ * qemuVirCommandGetFDSet:
+ * @cmd: the command to modify
+ * @fd: fd to reassign to the child
+ *
+ * Get the parameters for the QEMU -add-fd command line option
+ * for the given file descriptor. The file descriptor must previously
+ * have been 'transferred' in a virCommandPassFD() call.
+ * This function for example returns "set=10,fd=20".
+ */
+static char *
+qemuVirCommandGetFDSet(virCommandPtr cmd, int fd)
+{
+char *result = NULL;
+int idx = virCommandPassFDGetFDIndex(cmd, fd);
+
+if (idx >= 0) {
+ignore_value(virAsprintf(&result, "set=%d,fd=%d", idx, fd) < 0);
+} else {
+virReportError(VIR_ERR_INTERNAL_ERROR,
+   _("file descriptor %d has not been transferred"), fd);
+}
+
+return result;
+}
+
+/**
+ * qemuVirCommandGetDevSet:
+ * @cmd: the command to modify
+ * @fd: fd to reassign to the child
+ *
+ * Get the parameters for the QEMU path= parameter where a file
+ * descriptor is accessed via a file descriptor set, for example
+ * /dev/fdset/10. The file descriptor must previously have been
+ * 'transferred' in a virCommandPassFD() call.
+ */
+static char *
+qemuVirCommandGetDevSet(virCommandPtr cmd, int fd)
+{
+char *result = NULL;
+int idx = virCommandPassFDGetFDIndex(cmd, fd);
+
+if (idx >= 0) {
+ignore_value(virAsprintf(&result, "/dev/fdset/%d", idx) < 0);
+} else {
+virReportError(VIR_ERR_INTERNAL_ERROR,
+   _("file descriptor %d has not been transferred"), fd);
+}
+return result;
+}
+
+
+/**
  * qemuPhysIfaceConnect:
  * @def: the definition of the VM (needed by 802.1Qbh and audit)
  * @driver: pointer to the driver instance
@@ -5869,14 +5921,20 @@ qemuBuildRNGDeviceArgs(virCommandPtr cmd,
 
 
 static char *qemuBuildTPMBackendStr(const virDomainDef *def,
+virCommandPtr cmd,
 virQEMUCapsPtr qemuCaps,
-const char *emulator)
+const char *emulator,
+int *tpmfd, int *cancelfd)
 {
 const virDomainTPMDef *tpm = def->tpm;
 virBuffer buf = VIR_BUFFER_INITIALIZER;
 const char *type = virDomainTPMBackendTypeToString(tpm->type);
-char *cancel_path;
+char *cancel_path = NULL;
 const char *tpmdev;
+char *devset = NULL, *cancel_devset = NULL;
+
+*tpmfd = -1;
+*cancelfd = -1;
 
 virBufferAsprintf(&buf, "%s,id=tpm-%s", type, tpm->info.alias);
 
@@ -5889,11 +5947,47 @@ static char *qemuBuildTPMBackendStr(const virDomainDef 
*def,
 if (!(cancel_path = virTPMCreateCancelPath(tpmdev)))
 goto error;
 
-virBufferAddLit(&buf, ",path=");
-virBufferEscape(&buf, ',', ",", "%s", tpmdev);
+if (virQEMUCapsGet(qemuCaps, QEMU_CAPS_ADD_FD)) {
+*tpmfd = open(tpmdev, O_RDWR);
+if (*tpmfd < 0) {
+virReportError(VIR_ERR_INTERNAL_ERROR,
+   _("Could not open TPM device %s"), tpmdev);
+goto error;
+}
+
+virCommandPassFD(cmd, *tpmfd,
+ VIR_COMMAND_PASS_FD_CLOSE_PARENT);
+devset = qemuVirCommandGetDevSet(cmd, *tpmfd);
+if (devset == NULL)
+goto error;
+
+*cancelfd = open(cancel_path, O_WRONLY);
+if (*cancelfd < 0) {
+virReportError(VIR_ERR_INTERNAL_ERROR,
+   

[libvirt] [PATCHv2] Introduce virStringStripIPv6Brackets

2014-10-08 Thread Ján Tomko
Helper function to strip the brackets from an IPv6 address.
Tested by viruritest.
---
 src/libvirt_private.syms |  1 +
 src/util/virstring.c | 22 ++
 src/util/virstring.h |  2 ++
 src/util/viruri.c| 20 
 tests/virstringtest.c| 49 
 5 files changed, 78 insertions(+), 16 deletions(-)

diff --git a/src/libvirt_private.syms b/src/libvirt_private.syms
index d6265ac..c5397dd 100644
--- a/src/libvirt_private.syms
+++ b/src/libvirt_private.syms
@@ -2004,6 +2004,7 @@ virStringSortCompare;
 virStringSortRevCompare;
 virStringSplit;
 virStringSplitCount;
+virStringStripIPv6Brackets;
 virStrncpy;
 virStrndup;
 virStrToDouble;
diff --git a/src/util/virstring.c b/src/util/virstring.c
index 54c0b6f..0cb7f3f 100644
--- a/src/util/virstring.c
+++ b/src/util/virstring.c
@@ -929,3 +929,25 @@ virStringReplace(const char *haystack,
 
 return virBufferContentAndReset(&buf);
 }
+
+/**
+ * virStringStripIPv6Brackets:
+ * @str: the string to strip
+ *
+ * Modify the string in-place to remove the leading and closing brackets
+ * from an IPv6 address.
+ */
+void
+virStringStripIPv6Brackets(char *str)
+{
+size_t len;
+
+if (!str)
+return;
+
+len = strlen(str);
+if (str[0] == '[' && str[len-1] == ']' && strchr(str, ':')) {
+memmove(&str[0], &str[1], len - 2);
+str[len - 2] = '\0';
+}
+}
diff --git a/src/util/virstring.h b/src/util/virstring.h
index b82ef2a..40ebaeb 100644
--- a/src/util/virstring.h
+++ b/src/util/virstring.h
@@ -268,4 +268,6 @@ char *virStringReplace(const char *haystack,
const char *newneedle)
 ATTRIBUTE_NONNULL(1) ATTRIBUTE_NONNULL(2) ATTRIBUTE_NONNULL(3);
 
+void virStringStripIPv6Brackets(char *str);
+
 #endif /* __VIR_STRING_H__ */
diff --git a/src/util/viruri.c b/src/util/viruri.c
index 23d86c5..6166c37 100644
--- a/src/util/viruri.c
+++ b/src/util/viruri.c
@@ -182,22 +182,10 @@ virURIParse(const char *uri)
 if (VIR_STRDUP(ret->user, xmluri->user) < 0)
 goto error;
 
-/* First check: does it even make sense to jump inside */
-if (ret->server != NULL &&
-ret->server[0] == '[') {
-size_t length = strlen(ret->server);
-
-/* We want to modify the server string only if there are
- * square brackets on both ends and inside there is IPv6
- * address. Otherwise we could make a mistake by modifying
- * something other than an IPv6 address. */
-if (ret->server[length - 1] == ']' && strchr(ret->server, ':')) {
-memmove(&ret->server[0], &ret->server[1], length - 2);
-ret->server[length - 2] = '\0';
-}
-/* Even after such modification, it is completely ok to free
- * the uri with xmlFreeURI() */
-}
+/* Strip square bracket from an IPv6 address.
+ * The function modifies the string in-place. Even after such
+ * modification, it is OK to free the URI with xmlFreeURI. */
+virStringStripIPv6Brackets(ret->server);
 
 if (virURIParseParams(ret) < 0)
 goto error;
diff --git a/tests/virstringtest.c b/tests/virstringtest.c
index 10fad2c..841531f 100644
--- a/tests/virstringtest.c
+++ b/tests/virstringtest.c
@@ -522,6 +522,36 @@ testVirStringFreeListCount(const void *opaque 
ATTRIBUTE_UNUSED)
 }
 
 
+struct testStripIPv6BracketsData {
+const char *string;
+const char *result;
+};
+
+static int testStripIPv6Brackets(const void *args)
+{
+const struct testStripIPv6BracketsData *data = args;
+int ret = -1;
+char *res = NULL;
+
+if (VIR_STRDUP(res, data->string) < 0)
+goto cleanup;
+
+virStringStripIPv6Brackets(res);
+
+if (STRNEQ_NULLABLE(res, data->result)) {
+fprintf(stderr, "Returned '%s', expected '%s'\n",
+NULLSTR(res), NULLSTR(data->result));
+goto cleanup;
+}
+
+ret = 0;
+
+ cleanup:
+VIR_FREE(res);
+return ret;
+}
+
+
 static int
 mymain(void)
 {
@@ -731,6 +761,25 @@ mymain(void)
 NULL) < 0)
 ret = -1;
 
+#define TEST_STRIP_IPV6_BRACKETS(str, res)  \
+do {\
+struct testStripIPv6BracketsData stripData = {  \
+.string = str,  \
+.result = res,  \
+};  \
+if (virtTestRun("Strip brackets from IPv6 " #str,   \
+testStripIPv6Brackets, &stripData) < 0) \
+ret = -1;   \
+} while (0)
+
+TEST_STRIP_IPV6_BRACKETS(NULL, NULL);
+TEST_STRIP_IPV6_BRACKETS("[]", "[]");
+TEST_STRIP_IPV6_BRACKETS("[:]", ":");
+TEST_STRIP_IPV6_BRACKETS("[::1]", "::1");
+TEST_STRIP_IPV6_BRAC

Re: [libvirt] [PATCH] Introduce virStringStripIPv6Brackets

2014-10-08 Thread Daniel P. Berrange
On Wed, Oct 08, 2014 at 10:46:53AM +0200, Ján Tomko wrote:
> Helper function to strip the brackets from an IPv6 address.
> Tested by viruritest.
> ---
>  src/libvirt_private.syms |  1 +
>  src/util/virstring.c | 22 ++
>  src/util/virstring.h |  2 ++
>  src/util/viruri.c| 20 
>  4 files changed, 29 insertions(+), 16 deletions(-)

Can we have tests in viruritest.c and virstringtest.c too


Regards,
Daniel
-- 
|: http://berrange.com  -o-http://www.flickr.com/photos/dberrange/ :|
|: http://libvirt.org  -o- http://virt-manager.org :|
|: http://autobuild.org   -o- http://search.cpan.org/~danberr/ :|
|: http://entangle-photo.org   -o-   http://live.gnome.org/gtk-vnc :|

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

Re: [libvirt] Notes: Non-shared storage live migration w/ active blockcommit

2014-10-08 Thread Kashyap Chamarthy
On Tue, Oct 07, 2014 at 05:35:00PM -0600, Eric Blake wrote:
> On 09/25/2014 08:26 AM, Kashyap Chamarthy wrote:
> > This notes is based on an IRC conversation with Eric Blake, to have
> > efficient non-shared storage live migration. Thought I'd post my notes
> > here before I forget. Please review and spot if there are any
> > inaccuracies.
> > 
> > Procedure
> > -
> > 
> > (1) Starting from disk A, create a snapshot A <- A':
> > 
> > $ virsh snapshot-create-as \
> > --domain f20vm snap1 snap1-desc \
> > --diskspec hda,file=/export/vmimages/A'.qcow2 \
> > --disk-only --atomic
> 
> If you are using this snapshot only for the side-effect of growing the
> chain, you can add --no-metadata here instead of deleting the snapshot
> later when it gets invalidated [1].  Of course, if you pass
> --no-metadata, the snapshot name (snap1) and description (snap1-desc)
> are no longer important.

Right, until proper cleaner revert to external snapshot mechanisms are
in place, I should make a habit of passing '--no-metadata' when creating
external snapshots for the above reason (as I usually do end up deleting
the related libvirt metadata as part of cleanup).

> > 
> > (2) Background copy of A to B:
> > 
> > $ virsh blockcopy \
> > --domain vm1 vda /export/vmimages/B.qcow2 \
> > --wait --verbose --shallow \
> > --finish
> 
> This step is not quite right.  You are asking for a shallow copy of the
> current file for disk 'vda' (that is, A'.qcow2).  But that is NOT the
> same as the base A image.

Oh right, thanks for catching this mistake.

> For this step, libvirt does not yet have an easy way to access the
> contents of a backing chain of a live domain; you CAN use 'virsh
> vol-*' commands to do a background copy from storage pools, but it may
> be easier to just resort to normal file system tools:
> 
> cp /export/vmimages/A.qcow2 /export/vmimages/B.qcow2

Yeah, simple and less commands to type too.

> or even rely on storage-array-specific commands to set up a trivial
> clone with no real time overhead (for example, some iscsi storage arrays
> allow efficient copy-on-write cloning of storage volumes by creating a
> new name that shares the same original contents of A.qcow2 as its
> starting point; and since we are about to delete A.qcow2 later on, we
> never need any actual data copying).
> 
> > 
> > (3) Create an empty B' with backing file B:
> > 
> > $ qemu-img create -f qcow2 -b B.qcow2 \
> > -o backing_fmt=qcow2 B'.qcow2
> > 
> > [or]
> > 
> > $ virsh vol-create-as default B'.qcow2 1G \
> > --format qcow2 \
> > --backing-vol B.qcow2 --backing-vol-format qcow2 
> 
> [side note - we should really teach libvirt to not REQUIRE a size when
> creating an empty wrapper around an existing image]

Filed: https://bugzilla.redhat.com/show_bug.cgi?id=1150411

> > 
> > (4) Do a shallow blockcopy of A' to B':
> > 
> > $ virsh blockcopy \
> > --domain vm1 vda /export/vmimages/B'.qcow2 \
> > --wait --verbose --shallow \
> > --finish
> 
> For this to work, you need to also use the --reuse-external flag

True, I self-corrected in my other response in this thread, but thanks
for noticing.

> to take
> advantage of the backing chain already recorded in B'.qcow2 (without the
> flag, the command will complain that B'.qcow2 already exists if it is a
> regular file; if it is a block device, it will just silently ignore the
> contents of the block device and treat B'.qcow2 as though an absolute
> path to A.qcow2 were its backing file).
> 
> > 
> > (5) Then live shallow commit of B:
> > 
> > $ virsh blockcommit \
> > --domain f20vm vda \
> > --wait --verbose --shallow \
> > --pivot --active --finish
> > Block Commit: [100 %]
> > Successfully pivoted
> 
> With steps 2 and 4 corrected, this indeed shortens the chain back down
> to just B.qcow2.  And once this happens, you no longer need the path to
> A.qcow2 or A'.qcow2; you can also delete B'.qcow2.  But back to the
> point I made earlier at [1]: if this is all you do, then 'virsh
> snapshot-list' will still show 'snap1' as a snapshot that tries to refer
> to A'.qcow2; since you just invalidated that with the copy, you'd need
> to 'virsh snapshot-delete --metadata vm1 snap1' to get rid of the stale
> snapshot (if you don't tweak step 1 to avoid creating that snapshot
> metadata in the first place).

Thanks for this reminder, I'll script this as part of my tests to ensure
it's not missed.

> The NICE part about this whole sequence is that the backing file does
> NOT have to be qcow2, and it is VERY efficient timewise, if you happen
> to have an efficient way to do step 2.  That is, I can go from a
> multi-gigabyte raw file A.img to raw file B.img in less than a second,
> assuming the guest isn't doing much I/O in the meantime, when scripting
> all these steps together, and without any guest downtime.

Thanks again, for your met

Re: [libvirt] [PATCH] Introduce virStringStripIPv6Brackets

2014-10-08 Thread Chen, Hanxiao


> -Original Message-
> From: libvir-list-boun...@redhat.com [mailto:libvir-list-boun...@redhat.com]
> On Behalf Of Ján Tomko
> Sent: Wednesday, October 08, 2014 4:47 PM
> To: libvir-list@redhat.com
> Subject: [libvirt] [PATCH] Introduce virStringStripIPv6Brackets
> 
> Helper function to strip the brackets from an IPv6 address.
> Tested by viruritest.

Reviewed-by: Chen Hanxiao 


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

[libvirt] [PATCH] Introduce virStringStripIPv6Brackets

2014-10-08 Thread Ján Tomko
Helper function to strip the brackets from an IPv6 address.
Tested by viruritest.
---
 src/libvirt_private.syms |  1 +
 src/util/virstring.c | 22 ++
 src/util/virstring.h |  2 ++
 src/util/viruri.c| 20 
 4 files changed, 29 insertions(+), 16 deletions(-)

diff --git a/src/libvirt_private.syms b/src/libvirt_private.syms
index d6265ac..c5397dd 100644
--- a/src/libvirt_private.syms
+++ b/src/libvirt_private.syms
@@ -2004,6 +2004,7 @@ virStringSortCompare;
 virStringSortRevCompare;
 virStringSplit;
 virStringSplitCount;
+virStringStripIPv6Brackets;
 virStrncpy;
 virStrndup;
 virStrToDouble;
diff --git a/src/util/virstring.c b/src/util/virstring.c
index 54c0b6f..0cb7f3f 100644
--- a/src/util/virstring.c
+++ b/src/util/virstring.c
@@ -929,3 +929,25 @@ virStringReplace(const char *haystack,
 
 return virBufferContentAndReset(&buf);
 }
+
+/**
+ * virStringStripIPv6Brackets:
+ * @str: the string to strip
+ *
+ * Modify the string in-place to remove the leading and closing brackets
+ * from an IPv6 address.
+ */
+void
+virStringStripIPv6Brackets(char *str)
+{
+size_t len;
+
+if (!str)
+return;
+
+len = strlen(str);
+if (str[0] == '[' && str[len-1] == ']' && strchr(str, ':')) {
+memmove(&str[0], &str[1], len - 2);
+str[len - 2] = '\0';
+}
+}
diff --git a/src/util/virstring.h b/src/util/virstring.h
index b82ef2a..40ebaeb 100644
--- a/src/util/virstring.h
+++ b/src/util/virstring.h
@@ -268,4 +268,6 @@ char *virStringReplace(const char *haystack,
const char *newneedle)
 ATTRIBUTE_NONNULL(1) ATTRIBUTE_NONNULL(2) ATTRIBUTE_NONNULL(3);
 
+void virStringStripIPv6Brackets(char *str);
+
 #endif /* __VIR_STRING_H__ */
diff --git a/src/util/viruri.c b/src/util/viruri.c
index 23d86c5..6166c37 100644
--- a/src/util/viruri.c
+++ b/src/util/viruri.c
@@ -182,22 +182,10 @@ virURIParse(const char *uri)
 if (VIR_STRDUP(ret->user, xmluri->user) < 0)
 goto error;
 
-/* First check: does it even make sense to jump inside */
-if (ret->server != NULL &&
-ret->server[0] == '[') {
-size_t length = strlen(ret->server);
-
-/* We want to modify the server string only if there are
- * square brackets on both ends and inside there is IPv6
- * address. Otherwise we could make a mistake by modifying
- * something other than an IPv6 address. */
-if (ret->server[length - 1] == ']' && strchr(ret->server, ':')) {
-memmove(&ret->server[0], &ret->server[1], length - 2);
-ret->server[length - 2] = '\0';
-}
-/* Even after such modification, it is completely ok to free
- * the uri with xmlFreeURI() */
-}
+/* Strip square bracket from an IPv6 address.
+ * The function modifies the string in-place. Even after such
+ * modification, it is OK to free the URI with xmlFreeURI. */
+virStringStripIPv6Brackets(ret->server);
 
 if (virURIParseParams(ret) < 0)
 goto error;
-- 
2.0.4

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


Re: [libvirt] [Question] capabilities.pidfile is left behind while starting and stopping libvirtd repeatly

2014-10-08 Thread Wang Rui
On 2014/10/2 17:55, Martin Kletzander wrote:
> On Tue, Sep 30, 2014 at 10:26:21PM +0200, Guido Günther wrote:
>> On Tue, Sep 30, 2014 at 04:47:14PM +0200, Martin Kletzander wrote:
>>> On Tue, Sep 30, 2014 at 05:34:54PM +0800, Wang Yufei wrote:
>>> >Hi, all
>>> >
>>> >I started and stopped libvirtd service repeatly with high frequency(1 per 
>>> >second), and found that the file capabilities.pidfile is left behind, as 
>>> >well as a qemu process. If I then restart libvirtd, qemu-kvm will fail to 
>>> >start as it's unable to flock capabilities.pidfile's fd.
>>> >
>>>
>>> Have you tried current master?  Or at least -rc2?  It should already
>>> be fixed there:
>>>
>>> commit 9e159b521dbf18c6da6976e54e29c8553f831eb6
>>> Author: Guido Günther 
>>> Date:   Thu Sep 25 10:30:58 2014 +0200
>>>
>>>qemu: remove capabilities.monitor.sock when done
>>>
>>
>> This one removes the monitor socket, not the pidfile since I didn't
>> see that one lingering around in my tests.
>> Cheers,
> 
> Oh, sorry for that, my fault.  Well, should the daemon just kill the
> process when it's dying in order to release the lock?  If you try
> slower, we will properly remove the pidfile, won't we?

Yes, the pidfile will be keep open and locked forever if this qemu process
is alive. And it will be unlink if I shutdown libvitd daemon slower. But
in this condition(started and stopped libvirtd service repeatly with high
frequency) the pidfile is left behind. In fact libvirtd daemon is killed
before qemu-kvm process and pidfile are cleaned up. Is it a problem?


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


Re: [libvirt] Features - virDomainOpenConsole

2014-10-08 Thread Matthias Bolte
2014-10-06 19:56 GMT+02:00 Andre Smith :
> Hi,
>
> We urgently need proper virDomainOpenConsole support for both VMware and
> Virtualbox.  Since this is for our own commercial usage, my employer has
> authorized me to find a developer that can do the work quickly and properly
> and to pay them for their efforts.

About which VMware products are you talking here? vSphere/ESX or
Workstation/Player/Fusion?

-- 
Matthias Bolte
http://photron.blogspot.com

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


Re: [libvirt] [PATCH] "pclmuldq" was introduced with Westmere, not Sandy Bridge. This feature is important to get proper performance for aes-128-gcm in openssl, an important cipher for https communica

2014-10-08 Thread Jiri Denemark
On Tue, Oct 07, 2014 at 21:22:12 +0200, Jan-Frode Myklebust wrote:
> 
> Signed-off-by: Jan-Frode Myklebust 
> ---
>  src/cpu/cpu_map.xml |2 +-
>  1 files changed, 1 insertions(+), 1 deletions(-)
> 
> diff --git a/src/cpu/cpu_map.xml b/src/cpu/cpu_map.xml
> index 18c7b0d..94f1458 100644
> --- a/src/cpu/cpu_map.xml
> +++ b/src/cpu/cpu_map.xml
> @@ -488,11 +488,11 @@
>  
>
>
> +  
>  
>  
>  
>
> -  
>
>
>

Technically you are correct and even QEMU added this feature to Westmere
in April 2013. However, our goal is to provide stable virtual hardware
that doesn't change when, e.g., a domain is migrated to another machine
(let's ignore the fact we don't currently enforce such stability for CPU
models/features because of missing functionality in both QEMU and
libvirt). Thus we should not really change existing CPU models. We may
be able to do that in the future depending how (if ever) we solve the
CPU definition probing in QEMU and how libvirt will make use of it to
really enforce stable ABI for guest operating systems.

Moreover, it's trivial to enable the feature in domain XML:


Westmere



That said, I don't think we should take this patch, at least not for
now.

Jirka

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


Re: [libvirt] [PATCH] Fix build with older libcurl

2014-10-08 Thread Matthias Bolte
2014-10-08 9:15 GMT+02:00 Ján Tomko :
> Add ATTRIBUTE_UNUSED marker to the unused timeout_ms option
> in esxVI_MultiCURL_TimerCallback.
>
> Introduced by commit 125007d.
> ---
> Pushed under the build breaker rule.
>
>  src/esx/esx_vi.c | 3 ++-
>  1 file changed, 2 insertions(+), 1 deletion(-)
>
> diff --git a/src/esx/esx_vi.c b/src/esx/esx_vi.c
> index fcd2e70..b00d8e7 100644
> --- a/src/esx/esx_vi.c
> +++ b/src/esx/esx_vi.c
> @@ -711,7 +711,8 @@ esxVI_MultiCURL_SocketCallback(CURL *handle 
> ATTRIBUTE_UNUSED,
>
>  static int
>  esxVI_MultiCURL_TimerCallback(CURLM *handle ATTRIBUTE_UNUSED,
> -  long timeout_ms, void *callback_opaque)
> +  long timeout_ms ATTRIBUTE_UNUSED,
> +  void *callback_opaque)
>  {
>  esxVI_MultiCURL *multi = callback_opaque;

Ah, I probably didn't do final test with libcurl < 7.28.0 yesterday.
Sorry and thanks for fixing this.

-- 
Matthias Bolte
http://photron.blogspot.com

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

[libvirt] [PATCH] Fix build with older libcurl

2014-10-08 Thread Ján Tomko
Add ATTRIBUTE_UNUSED marker to the unused timeout_ms option
in esxVI_MultiCURL_TimerCallback.

Introduced by commit 125007d.
---
Pushed under the build breaker rule.

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

diff --git a/src/esx/esx_vi.c b/src/esx/esx_vi.c
index fcd2e70..b00d8e7 100644
--- a/src/esx/esx_vi.c
+++ b/src/esx/esx_vi.c
@@ -711,7 +711,8 @@ esxVI_MultiCURL_SocketCallback(CURL *handle 
ATTRIBUTE_UNUSED,
 
 static int
 esxVI_MultiCURL_TimerCallback(CURLM *handle ATTRIBUTE_UNUSED,
-  long timeout_ms, void *callback_opaque)
+  long timeout_ms ATTRIBUTE_UNUSED,
+  void *callback_opaque)
 {
 esxVI_MultiCURL *multi = callback_opaque;
 
-- 
2.0.4

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