Re: [libvirt] Ability to add arbitrary data to snapshots

2016-01-25 Thread Daniel P. Berrange
On Sat, Jan 23, 2016 at 03:17:43PM +0300, Alexander Burluka wrote:
> Hello!
> 
> Currently our Virtuozzo company is working on some kind of management tool
> for libvirt. We encountered some problems with snapshots while development.
> So I would like to ask community a few questions:
> 1) Would you mind if I extend current libvirt snapshot with ability to add
> arbitrary data (blob or some config files)?
> 2) Would this feature be useful for your users?
> 
> I see it as something like:
> virsh snapshot-create VM1 --blob /path/to/some-file
> virsh snapshot-revert  VM1 
> and /path/to/some-file appeared again.

You don't really explain what you would want libvirt to do with this
data ?

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] Ability to add arbitrary data to snapshots

2016-01-25 Thread Alexander Burluka
Just save this data near main snapshot data (e.g. in 
/var/lib/libvirt/qemu/snapshot//)

and restore it on previous or specified path.

On 01/25/2016 11:46 AM, Daniel P. Berrange wrote:

On Sat, Jan 23, 2016 at 03:17:43PM +0300, Alexander Burluka wrote:

Hello!

Currently our Virtuozzo company is working on some kind of management tool
for libvirt. We encountered some problems with snapshots while development.
So I would like to ask community a few questions:
1) Would you mind if I extend current libvirt snapshot with ability to add
arbitrary data (blob or some config files)?
2) Would this feature be useful for your users?

I see it as something like:
virsh snapshot-create VM1 --blob /path/to/some-file
virsh snapshot-revert  VM1 
and /path/to/some-file appeared again.

You don't really explain what you would want libvirt to do with this
data ?

Regards,
Daniel


--
Regards,
Alexander Burluka

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


[libvirt] [PATCH] qemu: qemuDomainRename and virDomainObjListNumOfDomains ABBA deadlock fix

2016-01-25 Thread Maxim Nestratov
A pretty nasty deadlock occurs while trying to rename a VM in parallel
with virDomainObjListNumOfDomains.
The short description of the problem is as follows:

Thread #1:

qemuDomainRename:
--> aquires domain lock by qemuDomObjFromDomain
   -> waits for domain list lock in any of the listed functions:
  - virDomainObjListFindByName
  - virDomainObjListRenameAddNew
  - virDomainObjListRenameRemove

Thread #2:

virDomainObjListNumOfDomains:
--> aquires domain list lock
   -> waits for domain lock in virDomainObjListCount

The patch establishes a single order of taking locks: driver->domains list
first, then a particular VM. This is done by implementing a set of
virDomainObjListXxxLocked functions working with driver->domains that assume
that list lock is already aquired by calling functions.

Signed-off-by: Maxim Nestratov 
---
 src/conf/virdomainobjlist.c | 74 +
 src/conf/virdomainobjlist.h |  9 ++
 src/libvirt_private.syms|  4 +++
 src/qemu/qemu_driver.c  | 40 +---
 4 files changed, 110 insertions(+), 17 deletions(-)

diff --git a/src/conf/virdomainobjlist.c b/src/conf/virdomainobjlist.c
index 7568f93..89e28a8 100644
--- a/src/conf/virdomainobjlist.c
+++ b/src/conf/virdomainobjlist.c
@@ -132,21 +132,19 @@ virDomainObjPtr 
virDomainObjListFindByID(virDomainObjListPtr doms,
 
 
 static virDomainObjPtr
-virDomainObjListFindByUUIDInternal(virDomainObjListPtr doms,
+virDomainObjListFindByUUIDInternalLocked(virDomainObjListPtr doms,
const unsigned char *uuid,
bool ref)
 {
 char uuidstr[VIR_UUID_STRING_BUFLEN];
 virDomainObjPtr obj;
 
-virObjectLock(doms);
 virUUIDFormat(uuid, uuidstr);
 
 obj = virHashLookup(doms->objs, uuidstr);
-if (ref) {
+if (ref)
 virObjectRef(obj);
-virObjectUnlock(doms);
-}
+
 if (obj) {
 virObjectLock(obj);
 if (obj->removing) {
@@ -156,8 +154,19 @@ virDomainObjListFindByUUIDInternal(virDomainObjListPtr 
doms,
 obj = NULL;
 }
 }
-if (!ref)
-virObjectUnlock(doms);
+return obj;
+}
+
+static virDomainObjPtr
+virDomainObjListFindByUUIDInternal(virDomainObjListPtr doms,
+   const unsigned char *uuid,
+   bool ref)
+{
+virDomainObjPtr obj;
+
+virObjectLock(doms);
+obj = virDomainObjListFindByUUIDInternalLocked(doms, uuid, ref);
+virObjectUnlock(doms);
 return obj;
 }
 
@@ -169,6 +178,13 @@ virDomainObjListFindByUUID(virDomainObjListPtr doms,
 return virDomainObjListFindByUUIDInternal(doms, uuid, false);
 }
 
+virDomainObjPtr
+virDomainObjListFindByUUIDRefLocked(virDomainObjListPtr doms,
+  const unsigned char *uuid)
+{
+return virDomainObjListFindByUUIDInternalLocked(doms, uuid, true);
+}
+
 
 virDomainObjPtr
 virDomainObjListFindByUUIDRef(virDomainObjListPtr doms,
@@ -177,6 +193,23 @@ virDomainObjListFindByUUIDRef(virDomainObjListPtr doms,
 return virDomainObjListFindByUUIDInternal(doms, uuid, true);
 }
 
+virDomainObjPtr virDomainObjListFindByNameLocked(virDomainObjListPtr doms,
+ const char *name)
+{
+virDomainObjPtr obj;
+
+obj = virHashLookup(doms->objsName, name);
+virObjectRef(obj);
+if (obj) {
+virObjectLock(obj);
+if (obj->removing) {
+virObjectUnlock(obj);
+virObjectUnref(obj);
+obj = NULL;
+}
+}
+return obj;
+}
 
 virDomainObjPtr virDomainObjListFindByName(virDomainObjListPtr doms,
const char *name)
@@ -312,14 +345,12 @@ virDomainObjPtr virDomainObjListAdd(virDomainObjListPtr 
doms,
 return ret;
 }
 
-
 int
-virDomainObjListRenameAddNew(virDomainObjListPtr doms,
+virDomainObjListRenameAddNewLocked(virDomainObjListPtr doms,
  virDomainObjPtr vm,
  const char *name)
 {
 int ret = -1;
-virObjectLock(doms);
 
 /* Add new name into the hash table of domain names. */
 if (virHashAddEntry(doms->objsName, name, vm) < 0)
@@ -332,21 +363,38 @@ virDomainObjListRenameAddNew(virDomainObjListPtr doms,
 
 ret = 0;
  cleanup:
+return ret;
+}
+
+int
+virDomainObjListRenameAddNew(virDomainObjListPtr doms,
+ virDomainObjPtr vm,
+ const char *name)
+{
+int ret = -1;
+virObjectLock(doms);
+ret = virDomainObjListRenameAddNewLocked(doms, vm, name);
 virObjectUnlock(doms);
 return ret;
 }
 
+int
+virDomainObjListRenameRemoveLocked(virDomainObjListPtr doms, const char *name)
+{
+virHashRemoveEntry(doms->objsName, name);
+return 0;
+}
 
 int
 virDomainObjListRenameRemove(virDomainObjListPtr doms, const char *name)
 {
+int ret;
 

Re: [libvirt] [PATCH 1/4] vz: Split logic of prlsdkAddDomain() into two functions

2016-01-25 Thread Nikolay Shirokovskiy


On 23.01.2016 11:42, Mikhail Feoktistov wrote:
> Add two functions
> 1. prlsdkNewDomain() creates new empty domain in domains list with the 
> specific uuid.
> 2. prlsdkSetDomainInstance() add data from VM to domain object.
> ---
>  src/vz/vz_sdk.c | 49 +
>  src/vz/vz_sdk.h |  8 
>  2 files changed, 57 insertions(+)
> 
> diff --git a/src/vz/vz_sdk.c b/src/vz/vz_sdk.c
> index b78c413..c705517 100644
> --- a/src/vz/vz_sdk.c
> +++ b/src/vz/vz_sdk.c
> @@ -1509,6 +1509,55 @@ prlsdkUpdateDomain(vzConnPtr privconn, virDomainObjPtr 
> dom)
>  return retdom ? 0 : -1;
>  }
>  
> +int
> +prlsdkSetDomainInstance(vzConnPtr privconn, virDomainObjPtr dom, const 
> unsigned char *uuid)
> +{
> +PRL_HANDLE sdkdom = PRL_INVALID_HANDLE;
> +virDomainObjPtr retdom;
> +
> +sdkdom = prlsdkSdkDomainLookupByUUID(privconn, uuid);
> +if (sdkdom == PRL_INVALID_HANDLE)
> +return -1;
> +
> +retdom = prlsdkLoadDomain(privconn, sdkdom, dom);
> +PrlHandle_Free(sdkdom);
> +return retdom ? 0 : -1;
> +}
I suggest name it prlsdkLoadDomainUUID where use pass uuid instead of handle.
Another option is to just inline it. We use it only once.
> +
> +virDomainObjPtr
> +prlsdkNewDomain(vzConnPtr privconn, char *name, const unsigned char *uuid)
> +{
> +virDomainDefPtr def = NULL;
> +virDomainObjPtr dom = NULL;
> +vzDomObjPtr pdom = NULL;
> +
> +if (!(def = virDomainDefNewFull(name, uuid, -1)))
> +goto error;
> +
> +if (VIR_ALLOC(pdom) < 0)
> +goto error;
> +
> +if (STREQ(privconn->drivername, "vz"))
> +def->virtType = VIR_DOMAIN_VIRT_VZ;
> +else
> +def->virtType = VIR_DOMAIN_VIRT_PARALLELS;
> +
> +if (!(dom = virDomainObjListAdd(privconn->domains, def,
> +privconn->xmlopt,
> +0, NULL)))
> +goto error;
> +
> +dom->privateData = pdom;
> +dom->privateDataFreeFunc = prlsdkDomObjFreePrivate;
> +dom->persistent = 1;
> +return dom;
> +
> + error:
> +virDomainDefFree(def);
> +VIR_FREE(pdom);
> +return NULL;
> +}
> +
>  static int prlsdkSendEvent(vzConnPtr privconn,
> virDomainObjPtr dom,
> virDomainEventType lvEventType,
> diff --git a/src/vz/vz_sdk.h b/src/vz/vz_sdk.h
> index ff6be07..060635e 100644
> --- a/src/vz/vz_sdk.h
> +++ b/src/vz/vz_sdk.h
> @@ -32,6 +32,14 @@ int
>  prlsdkLoadDomains(vzConnPtr privconn);
>  virDomainObjPtr
>  prlsdkAddDomain(vzConnPtr privconn, const unsigned char *uuid);
> +virDomainObjPtr
> +prlsdkNewDomain(vzConnPtr privconn,
> +char *name,
> +const unsigned char *uuid);
> +int
> +prlsdkSetDomainInstance(vzConnPtr privconn,
> +virDomainObjPtr dom,
> +const unsigned char *uuid);
>  int prlsdkUpdateDomain(vzConnPtr privconn, virDomainObjPtr dom);
>  int prlsdkSubscribeToPCSEvents(vzConnPtr privconn);
>  void prlsdkUnsubscribeFromPCSEvents(vzConnPtr privconn);
> 

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


Re: [libvirt] [PATCH 2/4] vz: Remove prlsdkAddDomain() and use new functions

2016-01-25 Thread Nikolay Shirokovskiy
You use 'and' in description like this patch have to distinct purposes. 
Looks like a candidate for splitting.

Say in first patch you use inroduced functions and thus fix a race. By
the way this could be done in one step with introducing the functions.

In second you refactor prlsdkHandleVmAddedEvent. But I don't like the
way you do it much as you get non-cleanup goto in the new version.

On 23.01.2016 11:42, Mikhail Feoktistov wrote:
> Use prlsdkNewDomain() and prlsdkSetDomainInstance() instead of 
> prlsdkAddDomain()
> New algorithm for creating an instance:
> In vzDomainDefineXMLFlags() we add new domain to domain list by calling 
> prlsdkNewDomain()
> and only after that we call CreateVm() to create VM.
> It means that we "reserve" domain object with the specific uuid.
> After creation of new VM we add info from this VM
> to reserved domain object by calling sdkSetDomainInstance().
> 
> In notification handler prlsdkHandleVmAddedEvent() we check
> the existence of a domain and if it doesn't exist we add new domain by calling
> prlsdkLoadDomain().
> ---
>  src/vz/vz_driver.c | 14 --
>  src/vz/vz_sdk.c| 38 +++---
>  src/vz/vz_sdk.h|  2 --
>  3 files changed, 27 insertions(+), 27 deletions(-)
> 
> diff --git a/src/vz/vz_driver.c b/src/vz/vz_driver.c
> index f73f8ef..d1cf8d0 100644
> --- a/src/vz/vz_driver.c
> +++ b/src/vz/vz_driver.c
> @@ -687,6 +687,7 @@ vzDomainDefineXMLFlags(virConnectPtr conn, const char 
> *xml, unsigned int flags)
>  virDomainPtr retdom = NULL;
>  virDomainDefPtr def;
>  virDomainObjPtr olddom = NULL;
> +virDomainObjPtr newdom = NULL;
>  unsigned int parse_flags = VIR_DOMAIN_DEF_PARSE_INACTIVE;
>  
>  virCheckFlags(VIR_DOMAIN_DEFINE_VALIDATE, NULL);
> @@ -702,6 +703,10 @@ vzDomainDefineXMLFlags(virConnectPtr conn, const char 
> *xml, unsigned int flags)
>  olddom = virDomainObjListFindByUUID(privconn->domains, def->uuid);
>  if (olddom == NULL) {
>  virResetLastError();
> +newdom = prlsdkNewDomain(privconn, def->name, def->uuid);
> +if (!newdom)
> +goto cleanup;
> +
>  if (def->os.type == VIR_DOMAIN_OSTYPE_HVM) {
>  if (prlsdkCreateVm(conn, def))
>  goto cleanup;
> @@ -715,8 +720,7 @@ vzDomainDefineXMLFlags(virConnectPtr conn, const char 
> *xml, unsigned int flags)
>  goto cleanup;
>  }
>  
> -olddom = prlsdkAddDomain(privconn, def->uuid);
> -if (!olddom)
> +if (prlsdkSetDomainInstance(privconn, newdom, def->uuid))
>  goto cleanup;
>  } else {
>  int state, reason;
> @@ -757,6 +761,12 @@ vzDomainDefineXMLFlags(virConnectPtr conn, const char 
> *xml, unsigned int flags)
>   cleanup:
>  if (olddom)
>  virObjectUnlock(olddom);
> +if (newdom) {
> +if (!retdom)
> + virDomainObjListRemove(privconn->domains, newdom);
> +else
> + virObjectUnlock(newdom);
> +}
>  virDomainDefFree(def);
>  vzDriverUnlock(privconn);
>  return retdom;
> diff --git a/src/vz/vz_sdk.c b/src/vz/vz_sdk.c
> index c705517..765f5f1 100644
> --- a/src/vz/vz_sdk.c
> +++ b/src/vz/vz_sdk.c
> @@ -1473,27 +1473,6 @@ prlsdkLoadDomains(vzConnPtr privconn)
>  return -1;
>  }
>  
> -virDomainObjPtr
> -prlsdkAddDomain(vzConnPtr privconn, const unsigned char *uuid)
> -{
> -PRL_HANDLE sdkdom = PRL_INVALID_HANDLE;
> -virDomainObjPtr dom;
> -
> -dom = virDomainObjListFindByUUID(privconn->domains, uuid);
> -if (dom) {
> -/* domain is already in the list */
> -return dom;
> -}
> -
> -sdkdom = prlsdkSdkDomainLookupByUUID(privconn, uuid);
> -if (sdkdom == PRL_INVALID_HANDLE)
> -return NULL;
> -
> -dom = prlsdkLoadDomain(privconn, sdkdom, NULL);
> -PrlHandle_Free(sdkdom);
> -return dom;
> -}
> -
>  int
>  prlsdkUpdateDomain(vzConnPtr privconn, virDomainObjPtr dom)
>  {
> @@ -1672,11 +1651,24 @@ prlsdkHandleVmAddedEvent(vzConnPtr privconn,
>   unsigned char *uuid)
>  {
>  virDomainObjPtr dom = NULL;
> +PRL_HANDLE sdkdom = PRL_INVALID_HANDLE;
>  
> -dom = prlsdkAddDomain(privconn, uuid);
> -if (dom == NULL)
> +dom = virDomainObjListFindByUUID(privconn->domains, uuid);
> +if (dom) {
> +/* domain is already in the list */
> +goto send_event;
> +}
> +
> +sdkdom = prlsdkSdkDomainLookupByUUID(privconn, uuid);
> +if (sdkdom == PRL_INVALID_HANDLE)
> +return;
> +
> +dom = prlsdkLoadDomain(privconn, sdkdom, NULL);
> +PrlHandle_Free(sdkdom);
> +if (!dom)
>  return;
>  
> + send_event:
>  prlsdkSendEvent(privconn, dom, VIR_DOMAIN_EVENT_DEFINED,
>  VIR_DOMAIN_EVENT_DEFINED_ADDED);
>  
> diff --git a/src/vz/vz_sdk.h b/src/vz/vz_sdk.h
> index 060635e..19bce88 100644
> --- a/src/vz/vz_sdk.h
> +++ b/src/vz/vz_sdk.h
> @@ -31,8 +31,6 @@ void prlsdkDisconnect(vzConnPtr privc

Re: [libvirt] [PATCH 3/4] vz: remove code duplication from LoadDomain()

2016-01-25 Thread Nikolay Shirokovskiy
prlsdkLoadDomain works in 2 different cases:

1. Called first time for a domain. Then it creates and
initializes it. Then updates it from sdk handle.
2. Called when domain is already in list. In this case it updates domain from 
sdk handle.

I think we could end up in a better series if we split
this function into 2: first is to create and initialize, 
second update domain from sdk handle (load).

On 23.01.2016 11:42, Mikhail Feoktistov wrote:
> Now we create new domain by calling prlsdkNewDomain().
> In LoadDomain() we just load info from vm instance to domain object.
> So remove code to create domain from LoadDomain().
> 
> ---
>  src/vz/vz_sdk.c | 55 +--
>  1 file changed, 17 insertions(+), 38 deletions(-)
> 
> diff --git a/src/vz/vz_sdk.c b/src/vz/vz_sdk.c
> index 765f5f1..d9f2127 100644
> --- a/src/vz/vz_sdk.c
> +++ b/src/vz/vz_sdk.c
> @@ -1260,26 +1260,29 @@ prlsdkLoadDomain(vzConnPtr privconn,
>  PRL_UINT32 ram;
>  PRL_UINT32 envId;
>  PRL_VM_AUTOSTART_OPTION autostart;
> +unsigned char uuid[VIR_UUID_BUFLEN];
> +char *name;
>  
>  virCheckNonNullArgGoto(privconn, error);
>  virCheckNonNullArgGoto(sdkdom, error);
>  
> -if (!(def = virDomainDefNew()))
> +if (prlsdkGetDomainIds(sdkdom, &name, uuid) < 0)
>  goto error;
>  
>  if (!olddom) {
> -if (VIR_ALLOC(pdom) < 0)
> -goto error;
> +dom = prlsdkNewDomain(privconn, name, uuid);
> +def = dom->def;
> +pdom = dom->privateData;
>  } else {
> +if (!(def = virDomainDefNewFull(name, uuid, -1)))
> +goto error;
>  pdom = olddom->privateData;
> +if (STREQ(privconn->drivername, "vz"))
> +def->virtType = VIR_DOMAIN_VIRT_VZ;
> +else
> +def->virtType = VIR_DOMAIN_VIRT_PARALLELS;
>  }
> -
> -if (STREQ(privconn->drivername, "vz"))
> -def->virtType = VIR_DOMAIN_VIRT_VZ;
> -else
> -def->virtType = VIR_DOMAIN_VIRT_PARALLELS;
> -
> -def->id = -1;
> +VIR_FREE(name);
>  
>  /* we will remove this field in the near future, so let's set it
>   * to NULL temporarily */
> @@ -1292,9 +1295,6 @@ prlsdkLoadDomain(vzConnPtr privconn,
>  goto error;
>  }
>  
> -if (prlsdkGetDomainIds(sdkdom, &def->name, def->uuid) < 0)
> -goto error;
> -
>  def->onReboot = VIR_DOMAIN_LIFECYCLE_RESTART;
>  def->onPoweroff = VIR_DOMAIN_LIFECYCLE_DESTROY;
>  def->onCrash = VIR_DOMAIN_LIFECYCLE_CRASH_DESTROY;
> @@ -1369,23 +1369,10 @@ prlsdkLoadDomain(vzConnPtr privconn,
>  }
>  
>  if (olddom) {
> -/* assign new virDomainDef without any checks */
> -/* we can't use virDomainObjAssignDef, because it checks
> - * for state and domain name */
>  dom = olddom;
>  virDomainDefFree(dom->def);
>  dom->def = def;
> -} else {
> -if (!(dom = virDomainObjListAdd(privconn->domains, def,
> -privconn->xmlopt,
> -0, NULL)))
> -goto error;
>  }
> -/* dom is locked here */
> -
> -dom->privateData = pdom;
> -dom->privateDataFreeFunc = prlsdkDomObjFreePrivate;
> -dom->persistent = 1;
>  
>  switch (autostart) {
>  case PAO_VM_START_ON_LOAD:
> @@ -1411,19 +1398,11 @@ prlsdkLoadDomain(vzConnPtr privconn,
>  
>  return dom;
>   error:
> -if (dom && !olddom) {
> -/* Domain isn't persistent means that we haven't yet set
> - * prlsdkDomObjFreePrivate and should call it manually
> - */
> -if (!dom->persistent)
> -prlsdkDomObjFreePrivate(pdom);
> -
> +VIR_FREE(name);
> +if (!olddom && dom)
>  virDomainObjListRemove(privconn->domains, dom);
> -}
> -/* Delete newly allocated def only if we haven't assigned it to domain
> - * Otherwise we will end up with domain having invalid def within it
> - */
> -if (!dom)
> +
> +if (olddom && !dom)
>  virDomainDefFree(def);
>  
>  return NULL;
> 

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


Re: [libvirt] [PATCH v4] qemu: Connect to guest agent iff needed

2016-01-25 Thread Michal Privoznik
On 18.01.2016 11:54, Michal Privoznik wrote:
> https://bugzilla.redhat.com/show_bug.cgi?id=1293351
> 
> Since we already have virtio channel events, we know when guest
> agent within guest has (dis-)connected. Instead of us blindly
> connecting to a socket that no one is listening to, we can just
> follow what qemu-ga does. This has a nice benefit that we don't
> need to 'guest-ping' the agent just to timeout and find out
> nobody is listening.
> 
> The way that this commit is implemented:
> - don't connect in qemuProcessStart directly, defer that to event
>   callback (which already follows the agent).
> - after migration is settled, before we resume vCPUs, ask qemu
>   whether somebody is listening on the socket and if so, connect
>   to it.
> 
> Signed-off-by: Michal Privoznik 
> ---
> 
> diff to v3:
> -Move cap detection into qemuConnectAgent
> 
>  src/qemu/qemu_driver.c| 13 -
>  src/qemu/qemu_migration.c | 12 
>  src/qemu/qemu_process.c   | 24 
>  3 files changed, 48 insertions(+), 1 deletion(-)

ping

Michal

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


Re: [libvirt] [PATCH] virsh: Correctly detect inserted media in change-media command

2016-01-25 Thread Michal Privoznik
On 13.01.2016 17:39, Michal Privoznik wrote:
> https://bugzilla.redhat.com/show_bug.cgi?id=1250331
> 
> It all works like this. The change-media command dumps domain
> XML, finds the corresponding cdrom device we want to change media
> in and returns it in the xmlNodePtr form. This way we don't have
> to bother with keeping all the subelements or attributes that we
> don't care about in the XML that is fed back to libvirt for the
> update API.
> 
> Now, the problem is we try to be clever here and detect if disk
> already has a source (indicated by  subelement).
> However, bare fact that the element is there does not mean disk
> has source. The element has some attributes and only if @file or
> @dev is within them disk has source. Any other attribute is
> meaningless for our purpose now. Make our clever check better.
> 
> Signed-off-by: Michal Privoznik 
> ---
>  tools/virsh-domain.c | 7 ++-
>  1 file changed, 6 insertions(+), 1 deletion(-)

ping

Michal

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


Re: [libvirt] Ability to add arbitrary data to snapshots

2016-01-25 Thread Daniel P. Berrange
On Mon, Jan 25, 2016 at 11:54:55AM +0300, Alexander Burluka wrote:
> Just save this data near main snapshot data (e.g. in
> /var/lib/libvirt/qemu/snapshot//)
> and restore it on previous or specified path.

What sort of data is this - we already have ability to record
arbitrary metadata in the XML, so it is not particularly
attractive to add extra hacks to the snapshot XML for dealing
with extra config data, when it could be just pplaced in the
metadata block. In general I think everything we deal with
should be part of the XML config of the guest, so I don't
much like the suggestion to extend the snapshot APis to pass
through arbitrary opaque blobs.

> On 01/25/2016 11:46 AM, Daniel P. Berrange wrote:
> >On Sat, Jan 23, 2016 at 03:17:43PM +0300, Alexander Burluka wrote:
> >>Hello!
> >>
> >>Currently our Virtuozzo company is working on some kind of management tool
> >>for libvirt. We encountered some problems with snapshots while development.
> >>So I would like to ask community a few questions:
> >>1) Would you mind if I extend current libvirt snapshot with ability to add
> >>arbitrary data (blob or some config files)?
> >>2) Would this feature be useful for your users?
> >>
> >>I see it as something like:
> >>virsh snapshot-create VM1 --blob /path/to/some-file
> >>virsh snapshot-revert  VM1 
> >>and /path/to/some-file appeared again.
> >You don't really explain what you would want libvirt to do with this
> >data ?

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] Ability to add arbitrary data to snapshots

2016-01-25 Thread Alexander Burluka

For example, we want to store suspended state of VM.
I'm aware that some other careless application dealing with libvirt
may erase metadata section and info about additional snapshot data will 
be lost.


On 01/25/2016 02:38 PM, Daniel P. Berrange wrote:

On Mon, Jan 25, 2016 at 11:54:55AM +0300, Alexander Burluka wrote:

Just save this data near main snapshot data (e.g. in
/var/lib/libvirt/qemu/snapshot//)
and restore it on previous or specified path.

What sort of data is this - we already have ability to record
arbitrary metadata in the XML, so it is not particularly
attractive to add extra hacks to the snapshot XML for dealing
with extra config data, when it could be just pplaced in the
metadata block. In general I think everything we deal with
should be part of the XML config of the guest, so I don't
much like the suggestion to extend the snapshot APis to pass
through arbitrary opaque blobs.


On 01/25/2016 11:46 AM, Daniel P. Berrange wrote:

On Sat, Jan 23, 2016 at 03:17:43PM +0300, Alexander Burluka wrote:

Hello!

Currently our Virtuozzo company is working on some kind of management tool
for libvirt. We encountered some problems with snapshots while development.
So I would like to ask community a few questions:
1) Would you mind if I extend current libvirt snapshot with ability to add
arbitrary data (blob or some config files)?
2) Would this feature be useful for your users?

I see it as something like:
virsh snapshot-create VM1 --blob /path/to/some-file
virsh snapshot-revert  VM1 
and /path/to/some-file appeared again.

You don't really explain what you would want libvirt to do with this
data ?

Regards,
Daniel


--
Regards,
Alexander Burluka

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


Re: [libvirt] [PATCHv2] util: keep/use a bitmap of in-use macvtap devices

2016-01-25 Thread Pavel Hrdina
On Fri, Jan 22, 2016 at 12:52:27PM -0500, Laine Stump wrote:
> This patch creates two bitmaps, one for macvlan devicenames and one

s/devicenames/device names/

[...]

> diff --git a/src/util/virnetdevmacvlan.c b/src/util/virnetdevmacvlan.c

[...]

> +/**
> + * virNetDevMacVLanReserveName:
> + *
> + *  @name: already-known name of device
> + *  @quietFail: don't log an error if this name is already in-use
> + *
> + *  Extract the device type and id from a macvtap/macvlan device name
> + *  and mark the appropriate position as in-use in the appropriate
> + *  bitmap.
> + *
> + *  returns 0 on success, -1 on failure, -2 if the name doesn't fit the 
> auto-pattern

Long line, would be nice to wrap it.  And the return 0 isn't true, because
virNetDevMacVLanReserveID() returns ID on success.

> + */
> +int
> +virNetDevMacVLanReserveName(const char *name, bool quietFail)
> +{
> +unsigned int id;
> +unsigned int flags = 0;
> +const char *idstr = NULL;
> +
> +if (virNetDevMacVLanInitialize() < 0)
> +   return -1;
> +
> +if (STRPREFIX(name, MACVTAP_NAME_PREFIX)) {
> +idstr = name + strlen(MACVTAP_NAME_PREFIX);
> +flags |= VIR_NETDEV_MACVLAN_CREATE_WITH_TAP;
> +} else if (STRPREFIX(name, MACVLAN_NAME_PREFIX)) {
> +idstr = name + strlen(MACVLAN_NAME_PREFIX);
> +} else {
> +return -2;
> +}
> +
> +if (virStrToLong_ui(idstr, NULL, 10, &id) < 0) {
> +virReportError(VIR_ERR_INTERNAL_ERROR,
> +   _("couldn't get id value from macvtap device name 
> %s"),
> +   name);
> +return -1;
> +}
> +return virNetDevMacVLanReserveID(id, flags, quietFail, false);
> +}

[...]

>  const char *type = (flags & VIR_NETDEV_MACVLAN_CREATE_WITH_TAP) ?
>  "macvtap" : "macvlan";
> -const char *prefix = (flags & VIR_NETDEV_MACVLAN_CREATE_WITH_TAP) ?
> -MACVTAP_NAME_PREFIX : MACVLAN_NAME_PREFIX;

Maybe use the MACV(TAP|LAN)_NAME_PREFIX instead of the strings for *type.

>  const char *pattern = (flags & VIR_NETDEV_MACVLAN_CREATE_WITH_TAP) ?
>  MACVTAP_NAME_PATTERN : MACVLAN_NAME_PATTERN;
> -int c, rc;
> +int rc, reservedID = -1;
>  char ifname[IFNAMSIZ];
>  int retries, do_retry = 0;
>  uint32_t macvtapMode;
> -const char *cr_ifname = NULL;
> +const char *ifnameCreated = NULL;
>  int ret;
>  int vf = -1;
>  bool vnet_hdr = flags & VIR_NETDEV_MACVLAN_VNET_HDR;

[...]

> +retries = MACVLAN_MAX_ID + 1;
> +while (!ifnameCreated && retries) {
>  virMutexLock(&virNetDevMacVLanCreateMutex);
> -for (c = 0; c < 8192; c++) {
> -snprintf(ifname, sizeof(ifname), pattern, c);
> -if ((ret = virNetDevExists(ifname)) < 0) {
> -virMutexUnlock(&virNetDevMacVLanCreateMutex);
> +reservedID = virNetDevMacVLanReserveID(reservedID, flags, false, 
> true);
> +if (reservedID < 0) {
> +virMutexUnlock(&virNetDevMacVLanCreateMutex);
> +return -1;
> +}
> +snprintf(ifname, sizeof(ifname), pattern, reservedID);

Since you're changing this, snprintf returns -1 in case of error.

ACK with the issues fixed.

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


Re: [libvirt] [PATCH] virsh: Correctly detect inserted media in change-media command

2016-01-25 Thread Pavel Hrdina
On Wed, Jan 13, 2016 at 05:39:10PM +0100, Michal Privoznik wrote:
> https://bugzilla.redhat.com/show_bug.cgi?id=1250331
> 
> It all works like this. The change-media command dumps domain
> XML, finds the corresponding cdrom device we want to change media
> in and returns it in the xmlNodePtr form. This way we don't have
> to bother with keeping all the subelements or attributes that we
> don't care about in the XML that is fed back to libvirt for the
> update API.
> 
> Now, the problem is we try to be clever here and detect if disk
> already has a source (indicated by  subelement).
> However, bare fact that the element is there does not mean disk
> has source. The element has some attributes and only if @file or
> @dev is within them disk has source. Any other attribute is
> meaningless for our purpose now. Make our clever check better.

That's not true, what about disk type='dir|volume|network'?  Those could be also
used as cdrom or floppy.  The patch looks good, but extend it to detect all
possible disk types.

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


Re: [libvirt] Ability to add arbitrary data to snapshots

2016-01-25 Thread Daniel P. Berrange
On Mon, Jan 25, 2016 at 02:55:30PM +0300, Alexander Burluka wrote:
> For example, we want to store suspended state of VM.
> I'm aware that some other careless application dealing with libvirt
> may erase metadata section and info about additional snapshot data will be
> lost.

What do you mean by suspended state of the VM ? Are you referring to
the VM memory & device state ? If so, I think that something that
should be explicitly represented in the API, not a opaque blob.

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] [PATCH] virsh: Correctly detect inserted media in change-media command

2016-01-25 Thread Michal Privoznik
On 25.01.2016 13:45, Pavel Hrdina wrote:
> On Wed, Jan 13, 2016 at 05:39:10PM +0100, Michal Privoznik wrote:
>> https://bugzilla.redhat.com/show_bug.cgi?id=1250331
>>
>> It all works like this. The change-media command dumps domain
>> XML, finds the corresponding cdrom device we want to change media
>> in and returns it in the xmlNodePtr form. This way we don't have
>> to bother with keeping all the subelements or attributes that we
>> don't care about in the XML that is fed back to libvirt for the
>> update API.
>>
>> Now, the problem is we try to be clever here and detect if disk
>> already has a source (indicated by  subelement).
>> However, bare fact that the element is there does not mean disk
>> has source. The element has some attributes and only if @file or
>> @dev is within them disk has source. Any other attribute is
>> meaningless for our purpose now. Make our clever check better.
> 
> That's not true, what about disk type='dir|volume|network'?  Those could be 
> also
> used as cdrom or floppy.  The patch looks good, but extend it to detect all
> possible disk types.
> 

Well, the code doesn't know how to deal with those types anyway. For all
types you've pointed out we will change the disk type to file. So in the
end from a type='dir|volume|network' disk we will create type='file'. I
see no point in producing the following XML then:


  
  ...


But that's a bigger bug to fix. Meanwhile I think we can use my
(incomplete?) fix.

Michal

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


Re: [libvirt] [PATCH] virsh: Correctly detect inserted media in change-media command

2016-01-25 Thread Pavel Hrdina
On Mon, Jan 25, 2016 at 03:21:14PM +0100, Michal Privoznik wrote:
> On 25.01.2016 13:45, Pavel Hrdina wrote:
> > On Wed, Jan 13, 2016 at 05:39:10PM +0100, Michal Privoznik wrote:
> >> https://bugzilla.redhat.com/show_bug.cgi?id=1250331
> >>
> >> It all works like this. The change-media command dumps domain
> >> XML, finds the corresponding cdrom device we want to change media
> >> in and returns it in the xmlNodePtr form. This way we don't have
> >> to bother with keeping all the subelements or attributes that we
> >> don't care about in the XML that is fed back to libvirt for the
> >> update API.
> >>
> >> Now, the problem is we try to be clever here and detect if disk
> >> already has a source (indicated by  subelement).
> >> However, bare fact that the element is there does not mean disk
> >> has source. The element has some attributes and only if @file or
> >> @dev is within them disk has source. Any other attribute is
> >> meaningless for our purpose now. Make our clever check better.
> > 
> > That's not true, what about disk type='dir|volume|network'?  Those could be 
> > also
> > used as cdrom or floppy.  The patch looks good, but extend it to detect all
> > possible disk types.
> > 
> 
> Well, the code doesn't know how to deal with those types anyway. For all
> types you've pointed out we will change the disk type to file. So in the
> end from a type='dir|volume|network' disk we will create type='file'. I
> see no point in producing the following XML then:
> 
> 
>   
>   ...
> 
> 
> But that's a bigger bug to fix. Meanwhile I think we can use my
> (incomplete?) fix.
> 
> Michal

No, I'm not talking about the XML that we will create.  Let's say, that you have
a domain and there is this device:


  
  
  
  
  


Your patch would simply ignore the dir source and assumed that there is no media
inserted and create a new definition.  It would be regression from current
behavior.  It doesn't meter whether the new cdrom would be block or file, you
need to check the existing device and consider all possible source types to
detect whether there is a media inserted or not.

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


Re: [libvirt] [PATCH] virsh: Correctly detect inserted media in change-media command

2016-01-25 Thread Michal Privoznik
On 25.01.2016 15:46, Pavel Hrdina wrote:
> On Mon, Jan 25, 2016 at 03:21:14PM +0100, Michal Privoznik wrote:
>> On 25.01.2016 13:45, Pavel Hrdina wrote:
>>> On Wed, Jan 13, 2016 at 05:39:10PM +0100, Michal Privoznik wrote:
 https://bugzilla.redhat.com/show_bug.cgi?id=1250331

 It all works like this. The change-media command dumps domain
 XML, finds the corresponding cdrom device we want to change media
 in and returns it in the xmlNodePtr form. This way we don't have
 to bother with keeping all the subelements or attributes that we
 don't care about in the XML that is fed back to libvirt for the
 update API.

 Now, the problem is we try to be clever here and detect if disk
 already has a source (indicated by  subelement).
 However, bare fact that the element is there does not mean disk
 has source. The element has some attributes and only if @file or
 @dev is within them disk has source. Any other attribute is
 meaningless for our purpose now. Make our clever check better.
>>>
>>> That's not true, what about disk type='dir|volume|network'?  Those could be 
>>> also
>>> used as cdrom or floppy.  The patch looks good, but extend it to detect all
>>> possible disk types.
>>>
>>
>> Well, the code doesn't know how to deal with those types anyway. For all
>> types you've pointed out we will change the disk type to file. So in the
>> end from a type='dir|volume|network' disk we will create type='file'. I
>> see no point in producing the following XML then:
>>
>> 
>>   
>>   ...
>> 
>>
>> But that's a bigger bug to fix. Meanwhile I think we can use my
>> (incomplete?) fix.
>>
>> Michal
> 
> No, I'm not talking about the XML that we will create.  Let's say, that you 
> have
> a domain and there is this device:
> 
> 
>   
>   
>   
>   
>   
> 
> 
> Your patch would simply ignore the dir source and assumed that there is no 
> media
> inserted and create a new definition.  It would be regression from current
> behavior.  It doesn't meter whether the new cdrom would be block or file, you
> need to check the existing device and consider all possible source types to
> detect whether there is a media inserted or not.
> 

A-ha, now I see the problem. Would squashing this in help?

diff --git a/tools/virsh-domain.c b/tools/virsh-domain.c
index f023e3d..dd41260 100644
--- a/tools/virsh-domain.c
+++ b/tools/virsh-domain.c
@@ -2,8 +2,11 @@ virshUpdateDiskXML(xmlNodePtr disk_node,
 }
 
 if (source) {
-if (!(source_path = virXMLPropString(source, "file")))
-source_path = virXMLPropString(source, "dev");
+if (!(source_path = virXMLPropString(source, "file")) &&
+!(source_path = virXMLPropString(source, "dev")) &&
+!(source_path = virXMLPropString(source, "dir")) &&
+!(source_path = virXMLPropString(source, "pool")))
+source_path = virXMLPropString(source, "name");
 
 if (source_path && type == VIRSH_UPDATE_DISK_XML_INSERT) {
 vshError(NULL, _("The disk device '%s' already has media"), 
target);

Michal

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


Re: [libvirt] [PATCH 22/34] conf: disallow empty cpusets for vcpu pinning when parsing XML

2016-01-25 Thread Peter Krempa
On Mon, Jan 18, 2016 at 12:06:15 -0500, John Ferlan wrote:
> 
> 
> On 01/14/2016 11:27 AM, Peter Krempa wrote:
> > They are disallowed in the pinning API and as default cpuset.
> > 
> > Resolves: https://bugzilla.redhat.com/show_bug.cgi?id=1293241
> > ---
> >  src/conf/domain_conf.c | 6 ++
> >  1 file changed, 6 insertions(+)
> > 
> 
> Is this going to be problematic for a running domain? e.g., would it
> disappear now? I agree with the failure, just worried about the

If you use a bitmap string that ends up empty here, it will be parsed
correctly at first and the internal data would be valid. The saved xml
would not use the "0,^0" string when written to disk, but the bitmap
would format as "". When you attempt to parse such string, the parser
code errors out.

If you open the bugzilla, the situation is described pretty well in
there and the API, as said, does already the check.

So in a way a previously accepted config would be rejected in this case
but nobody used that since it would vanish.

> consequences.  Not that anyone should have done this, but seems to be
> one of those post parse, pre-run type checks since it's been allowed in
> the past.

Peter



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

Re: [libvirt] [PATCH] virsh: Correctly detect inserted media in change-media command

2016-01-25 Thread Pavel Hrdina
On Mon, Jan 25, 2016 at 04:03:44PM +0100, Michal Privoznik wrote:
> On 25.01.2016 15:46, Pavel Hrdina wrote:
> > On Mon, Jan 25, 2016 at 03:21:14PM +0100, Michal Privoznik wrote:
> >> On 25.01.2016 13:45, Pavel Hrdina wrote:
> >>> On Wed, Jan 13, 2016 at 05:39:10PM +0100, Michal Privoznik wrote:
>  https://bugzilla.redhat.com/show_bug.cgi?id=1250331
> 
>  It all works like this. The change-media command dumps domain
>  XML, finds the corresponding cdrom device we want to change media
>  in and returns it in the xmlNodePtr form. This way we don't have
>  to bother with keeping all the subelements or attributes that we
>  don't care about in the XML that is fed back to libvirt for the
>  update API.
> 
>  Now, the problem is we try to be clever here and detect if disk
>  already has a source (indicated by  subelement).
>  However, bare fact that the element is there does not mean disk
>  has source. The element has some attributes and only if @file or
>  @dev is within them disk has source. Any other attribute is
>  meaningless for our purpose now. Make our clever check better.
> >>>
> >>> That's not true, what about disk type='dir|volume|network'?  Those could 
> >>> be also
> >>> used as cdrom or floppy.  The patch looks good, but extend it to detect 
> >>> all
> >>> possible disk types.
> >>>
> >>
> >> Well, the code doesn't know how to deal with those types anyway. For all
> >> types you've pointed out we will change the disk type to file. So in the
> >> end from a type='dir|volume|network' disk we will create type='file'. I
> >> see no point in producing the following XML then:
> >>
> >> 
> >>   
> >>   ...
> >> 
> >>
> >> But that's a bigger bug to fix. Meanwhile I think we can use my
> >> (incomplete?) fix.
> >>
> >> Michal
> > 
> > No, I'm not talking about the XML that we will create.  Let's say, that you 
> > have
> > a domain and there is this device:
> > 
> > 
> >   
> >   
> >   
> >   
> >   
> > 
> > 
> > Your patch would simply ignore the dir source and assumed that there is no 
> > media
> > inserted and create a new definition.  It would be regression from current
> > behavior.  It doesn't meter whether the new cdrom would be block or file, 
> > you
> > need to check the existing device and consider all possible source types to
> > detect whether there is a media inserted or not.
> > 
> 
> A-ha, now I see the problem. Would squashing this in help?
> 
> diff --git a/tools/virsh-domain.c b/tools/virsh-domain.c
> index f023e3d..dd41260 100644
> --- a/tools/virsh-domain.c
> +++ b/tools/virsh-domain.c
> @@ -2,8 +2,11 @@ virshUpdateDiskXML(xmlNodePtr disk_node,
>  }
>  
>  if (source) {
> -if (!(source_path = virXMLPropString(source, "file")))
> -source_path = virXMLPropString(source, "dev");
> +if (!(source_path = virXMLPropString(source, "file")) &&
> +!(source_path = virXMLPropString(source, "dev")) &&
> +!(source_path = virXMLPropString(source, "dir")) &&
> +!(source_path = virXMLPropString(source, "pool")))
> +source_path = virXMLPropString(source, "name");
>  
>  if (source_path && type == VIRSH_UPDATE_DISK_XML_INSERT) {
>  vshError(NULL, _("The disk device '%s' already has media"), 
> target);

ACK with that :)

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


Re: [libvirt] [PATCH 1/2] virt-host-validate: Check those CGroups that we actually use

2016-01-25 Thread Pavel Hrdina
On Mon, Jan 25, 2016 at 08:23:21AM +0100, Michal Privoznik wrote:
> Since the introduction of virt-host-validate tool the set of
> cgroup controllers we use has changed so the tool is checking for
> some cgroups that we don't need (e.g. net_cls, although I doubt
> we have ever used that one) and is not checking for those we
> actually use (e.g. cpuset).
> 
> Signed-off-by: Michal Privoznik 
> ---
>  tools/virt-host-validate-lxc.c  | 16 
>  tools/virt-host-validate-qemu.c | 10 +-
>  2 files changed, 13 insertions(+), 13 deletions(-)

ACK

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


Re: [libvirt] [PATCH 2/2] virt-host-validate: Fix error level for user namespace check

2016-01-25 Thread Pavel Hrdina
On Mon, Jan 25, 2016 at 08:23:22AM +0100, Michal Privoznik wrote:
> >From the code it seems to me that we need user namespace iff

s/>From/From/
s/iff/if/

> configured in domain XML. Otherwise we don't use it at all.
> However our tool is more strict about that. Fix this discrepancy.
> 
> Signed-off-by: Michal Privoznik 
> ---
>  tools/virt-host-validate-lxc.c | 2 +-
>  1 file changed, 1 insertion(+), 1 deletion(-)

ACK

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


Re: [libvirt] [PATCH v2] virsh: improve waiting for block job readiness

2016-01-25 Thread John Ferlan


Since this has been sitting for a bit, I'll poke the bear, but also CC
Peter since he reviewed V1 and had some specific concerns...


On 01/06/2016 10:03 PM, Michael Chapman wrote:
> After a block job hits 100%, we only need to apply a timeout waiting for
> a block job event if exactly one of the BLOCK_JOB or BLOCK_JOB_2
> callbacks were able to be registered.
> 
> If neither callback could be registered, there's clearly no need for a
> timeout.
> 
> If both callbacks were registered, then we're guaranteed to eventually
> get one of the events. The path being used by virsh must be exactly the
> source path or target device in the domain's disk definition, and these
> are the respective strings sent back in these two events.
> 
> Signed-off-by: Michael Chapman 
> ---
> 
> v1 discussion at:
> http://www.redhat.com/archives/libvir-list/2016-January/msg00031.html
> 
> Changes since v1:
> - Fixed bugs in cb_id/cb_id2 conditionals
> - Consistently used break to exit loop, dropped cleanup label
> - Clarified the logic and behaviour in comments
> - Improved commit message
> 
>  tools/virsh-domain.c | 60 
> 
>  1 file changed, 32 insertions(+), 28 deletions(-)
> 
> diff --git a/tools/virsh-domain.c b/tools/virsh-domain.c
> index edbbc34..853416c 100644
> --- a/tools/virsh-domain.c
> +++ b/tools/virsh-domain.c
> @@ -1875,14 +1875,17 @@ virshBlockJobWaitFree(virshBlockJobWaitDataPtr data)
>   * virshBlockJobWait:
>   * @data: private data initialized by virshBlockJobWaitInit
>   *
> - * Waits for the block job to complete. This function prefers to get an event
> - * from libvirt but still has fallback means if the device name can't be 
> matched
> + * Waits for the block job to complete. This function prefers to wait for a
> + * matching VIR_DOMAIN_EVENT_ID_BLOCK_JOB or VIR_DOMAIN_EVENT_ID_BLOCK_JOB_2
> + * event from libvirt, however it has a fallback mode should either of these

nit: It's usually "...; however, ..."

> + * events not be available.
>   *
> - * This function returns values from the virConnectDomainEventBlockJobStatus 
> enum
> - * or -1 in case of a internal error. Fallback states if a block job vanishes
> - * without triggering the event is VIR_DOMAIN_BLOCK_JOB_COMPLETED. For two 
> phase
> - * jobs after the retry count for waiting for the event expires is
> - * VIR_DOMAIN_BLOCK_JOB_READY.
> + * This function returns values from the virConnectDomainEventBlockJobStatus
> + * enum or -1 in case of a internal error.

nit: "...of an internal..."  (usage of an instead of a)

> + *
> + * If the fallback mode is activated the returned event is
> + * VIR_DOMAIN_BLOCK_JOB_COMPLETED if the block job vanishes, or

nit: "...block job vanishes or..."  (no need for a comma)

> + * VIR_DOMAIN_BLOCK_JOB_READY if the block job reaches 100%.
>   */
>  static int
>  virshBlockJobWait(virshBlockJobWaitDataPtr data)
> @@ -1932,28 +1935,32 @@ virshBlockJobWait(virshBlockJobWaitDataPtr data)
>  
>  if (result < 0) {
>  vshError(data->ctl, _("failed to query job for disk %s"), 
> data->dev);
> -goto cleanup;
> +break;

Usage of 'goto' is a libvirt coding convention, even though perhaps not
a convention of all programming styles. I think use of goto here should
be kept (here and other places that follow in this function).

If you feel strongly about usage of break vs. goto, then this should be
a two patch series - the first to convert "goto" usage into "break"
usage and the second to resolve the issue of continuing with the timeout
logic even if both callbacks could not be registered.

>  }
>  
> -/* if we've got an event for the device we are waiting for we can end
> - * the waiting loop */
> +/* If either callback could be registered and we've got an event, we 
> can
> + * can end the waiting loop */
>  if ((data->cb_id >= 0 || data->cb_id2 >= 0) && data->status != -1) {
>  ret = data->status;
> -goto cleanup;
> +break;
>  }
>  
> -/* since virsh can't guarantee that the path provided by the user 
> will
> - * later be matched in the event we will need to keep the fallback
> - * approach and claim success if the block job finishes or vanishes. 
> */
> -if (result == 0)
> -break;
> +/* Fallback behaviour is only needed if one or both callbacks could 
> not
> + * be registered */
> +if (data->cb_id < 0 || data->cb_id2 < 0) {
> +/* If the block job vanishes, synthesize a COMPLETED event */
> +if (result == 0) {
> +ret = VIR_DOMAIN_BLOCK_JOB_COMPLETED;
> +break;
> +}
>  
> -/* for two-phase jobs we will try to wait in the synchronized phase
> - * for event arrival since 100% completion doesn't necessarily mean 
> that
> - * the block job has finished and can be terminated with succ

[libvirt] [PATCH v2 7/9] hostdev: Update comments

2016-01-25 Thread Andrea Bolognani
Some of the comments are no longer accurate after the recent changes,
others have been expanded and hopefully improved.

The initial summary of the operations has been removed so that two
separate edits are not needed when making changes.
---
 src/util/virhostdev.c | 68 +++
 1 file changed, 30 insertions(+), 38 deletions(-)

diff --git a/src/util/virhostdev.c b/src/util/virhostdev.c
index ab17547..0892dbf 100644
--- a/src/util/virhostdev.c
+++ b/src/util/virhostdev.c
@@ -675,11 +675,10 @@ virHostdevPreparePCIDevices(virHostdevManagerPtr 
hostdev_mgr,
  * must be reset before being marked as active.
  */
 
-/* Loop 1: validate that non-managed device isn't in use, eg
- * by checking that device is either un-bound, or bound
- * to pci-stub.ko
- */
+/* Detaching devices from the host involves several steps; each of them
+ * is described at length below */
 
+/* Step 1: perform safety checks, eg. ensure the devices are assignable */
 for (i = 0; i < virPCIDeviceListCount(pcidevs); i++) {
 virPCIDevicePtr dev = virPCIDeviceListGet(pcidevs, i);
 bool strict_acs_check = !!(flags & VIR_HOSTDEV_STRICT_ACS_CHECK);
@@ -710,7 +709,8 @@ virHostdevPreparePCIDevices(virHostdevManagerPtr 
hostdev_mgr,
 }
 }
 
-/* Loop 2: detach managed devices (i.e. bind to appropriate stub driver) */
+/* Step 2: detach managed devices (i.e. bind to appropriate stub driver).
+ * detachPCIDevices() will also mark devices as inactive */
 for (i = 0; i < virPCIDeviceListCount(pcidevs); i++) {
 virPCIDevicePtr dev = virPCIDeviceListGet(pcidevs, i);
 
@@ -718,11 +718,10 @@ virHostdevPreparePCIDevices(virHostdevManagerPtr 
hostdev_mgr,
 goto reattachdevs;
 }
 
-/* At this point, all devices are attached to the stub driver and have
+/* At this point, devices are attached to the stub driver and have
  * been marked as inactive */
 
-/* Loop 3: Now that all the PCI hostdevs have been detached, we
- * can safely reset them */
+/* Step 3: perform a PCI reset on all devices */
 for (i = 0; i < virPCIDeviceListCount(pcidevs); i++) {
 virPCIDevicePtr dev = virPCIDeviceListGet(pcidevs, i);
 
@@ -732,8 +731,7 @@ virHostdevPreparePCIDevices(virHostdevManagerPtr 
hostdev_mgr,
 goto reattachdevs;
 }
 
-/* Loop 4: For SRIOV network devices, Now that we have detached the
- * the network device, set the netdev config */
+/* Step 4: set the netdev config for SRIOV network devices */
 for (i = 0; i < nhostdevs; i++) {
  virDomainHostdevDefPtr hostdev = hostdevs[i];
  if (!virHostdevIsPCINetDevice(hostdev))
@@ -762,9 +760,7 @@ virHostdevPreparePCIDevices(virHostdevManagerPtr 
hostdev_mgr,
 goto inactivedevs;
 }
 
-/* Loop 7: Now set the used_by_domain of the device in
- * activePCIHostdevs as domain name.
- */
+/* Step 6: set driver and domain information */
 for (i = 0; i < virPCIDeviceListCount(pcidevs); i++) {
 virPCIDevicePtr dev, activeDev;
 
@@ -777,7 +773,7 @@ virHostdevPreparePCIDevices(virHostdevManagerPtr 
hostdev_mgr,
 virPCIDeviceSetUsedBy(activeDev, drv_name, dom_name);
 }
 
-/* Loop 8: Now set the original states for hostdev def */
+/* Step 7: set the original states for hostdev def */
 for (i = 0; i < nhostdevs; i++) {
 virPCIDevicePtr dev;
 virPCIDevicePtr pcidev;
@@ -792,10 +788,9 @@ virHostdevPreparePCIDevices(virHostdevManagerPtr 
hostdev_mgr,
 dev = virPCIDeviceNew(pcisrc->addr.domain, pcisrc->addr.bus,
   pcisrc->addr.slot, pcisrc->addr.function);
 
-/* original states "unbind_from_stub", "remove_slot",
- * "reprobe" were already set by pciDettachDevice in
- * loop 2.
- */
+/* original states for "unbind_from_stub", "remove_slot" and
+ * "reprobe" (used when reattaching) were already set by
+ * detachPCIDevices() in a previous step */
 VIR_DEBUG("Saving network configuration of PCI device %s",
   virPCIDeviceGetName(dev));
 if ((pcidev = virPCIDeviceListFind(pcidevs, dev))) {
@@ -875,16 +870,11 @@ virHostdevReAttachPCIDevices(virHostdevManagerPtr 
hostdev_mgr,
 goto cleanup;
 }
 
-/* Loop through the assigned devices 4 times: 1) delete them all from
- * activePCIHostdevs, 2) restore network config of SRIOV netdevs, 3) Do a
- * PCI reset on each device, 4) reattach the devices to their host drivers
- * (managed) or add them to inactivePCIHostdevs (!managed).
- */
+/* Reattaching devices to the host involves several steps; each of them
+ * is described at length below */
 
-/*
- * Loop 1: verify that each device in the hostdevs list really was in use
- * by this domain, and remove them all from the activePCIHostdevs list.
- */
+/* Ste

[libvirt] [PATCH v2 4/9] hostdev: Add virHostdevOnlyDetachPCIDevice()

2016-01-25 Thread Andrea Bolognani
This function mirrors virHostdevOnlyDetachPCIDevice().

The handling of active and inactive devices is updated and made more
explicit, which means virHostdevPreparePCIDevices() has to be
updated as well.
---
 src/util/virhostdev.c | 87 ---
 1 file changed, 61 insertions(+), 26 deletions(-)

diff --git a/src/util/virhostdev.c b/src/util/virhostdev.c
index f40d636..6f14574 100644
--- a/src/util/virhostdev.c
+++ b/src/util/virhostdev.c
@@ -594,6 +594,56 @@ virHostdevOnlyReattachPCIDevice(virHostdevManagerPtr mgr,
 return ret;
 }
 
+/**
+ * virHostdevOnlyDetachPCIDevice:
+ * @mgr: hostdev manager
+ * @pci: PCI device to be detached
+ * @skipUnmanaged: whether to skip unmanaged devices
+ *
+ * Detach a PCI device from the host.
+ *
+ * This function only performs the base detach steps that are required
+ * regardless of whether the device is being attached to a domain or
+ * is simply being detached from the host for later use.
+ *
+ * The PCI related parts of @mgr (inactivePCIHostdevs, activePCIHostdevs)
+ * must have been locked beforehand using virObjectLock().
+ *
+ * Returns: 0 on success, <0 on failure
+ */
+static int
+virHostdevOnlyDetachPCIDevice(virHostdevManagerPtr mgr,
+  virPCIDevicePtr pci,
+  bool skipUnmanaged)
+{
+int ret = -1;
+
+/* Skip unmanaged devices if asked to do so */
+if (!virPCIDeviceGetManaged(pci) && skipUnmanaged) {
+VIR_DEBUG("Not detaching unmanaged PCI device %s",
+  virPCIDeviceGetName(pci));
+ret = 0;
+goto out;
+}
+
+VIR_DEBUG("Detaching PCI device %s", virPCIDeviceGetName(pci));
+if (virPCIDeviceDetach(pci,
+   mgr->activePCIHostdevs,
+   mgr->inactivePCIHostdevs) < 0) {
+virErrorPtr err = virGetLastError();
+VIR_ERROR(_("Failed to detach PCI device %s: %s"),
+  virPCIDeviceGetName(pci),
+  err ? err->message : _("unknown error"));
+virResetError(err);
+goto out;
+}
+
+ret = 0;
+
+ out:
+return ret;
+}
+
 int
 virHostdevPreparePCIDevices(virHostdevManagerPtr hostdev_mgr,
 const char *drv_name,
@@ -664,17 +714,8 @@ virHostdevPreparePCIDevices(virHostdevManagerPtr 
hostdev_mgr,
 for (i = 0; i < virPCIDeviceListCount(pcidevs); i++) {
 virPCIDevicePtr dev = virPCIDeviceListGet(pcidevs, i);
 
-if (virPCIDeviceGetManaged(dev)) {
-VIR_DEBUG("Detaching managed PCI device %s",
-  virPCIDeviceGetName(dev));
-if (virPCIDeviceDetach(dev,
-   hostdev_mgr->activePCIHostdevs,
-   hostdev_mgr->inactivePCIHostdevs) < 0)
-goto reattachdevs;
-} else {
-VIR_DEBUG("Not detaching unmanaged PCI device %s",
-  virPCIDeviceGetName(dev));
-}
+if (virHostdevOnlyDetachPCIDevice(hostdev_mgr, dev, true) < 0)
+goto reattachdevs;
 }
 
 /* At this point, all devices are attached to the stub driver and have
@@ -704,23 +745,21 @@ virHostdevPreparePCIDevices(virHostdevManagerPtr 
hostdev_mgr,
  last_processed_hostdev_vf = i;
 }
 
-/* Loop 5: Now mark all the devices as active */
+/* Step 5: move all devices from the inactive list to the active list */
 for (i = 0; i < virPCIDeviceListCount(pcidevs); i++) {
 virPCIDevicePtr dev = virPCIDeviceListGet(pcidevs, i);
+virPCIDevicePtr actual;
 
-VIR_DEBUG("Adding PCI device %s to active list",
+VIR_DEBUG("Removing PCI device %s from inactive list",
   virPCIDeviceGetName(dev));
-if (virPCIDeviceListAdd(hostdev_mgr->activePCIHostdevs, dev) < 0)
+if (!(actual = virPCIDeviceListSteal(hostdev_mgr->inactivePCIHostdevs,
+ dev)))
 goto inactivedevs;
-}
-
-/* Loop 6: Now remove the devices from inactive list. */
-for (i = 0; i < virPCIDeviceListCount(pcidevs); i++) {
-virPCIDevicePtr dev = virPCIDeviceListGet(pcidevs, i);
 
-VIR_DEBUG("Removing PCI device %s from inactive list",
-  virPCIDeviceGetName(dev));
-virPCIDeviceListDel(hostdev_mgr->inactivePCIHostdevs, dev);
+VIR_DEBUG("Adding PCI device %s to active list",
+  virPCIDeviceGetName(actual));
+if (virPCIDeviceListAdd(hostdev_mgr->activePCIHostdevs, actual) < 0)
+goto inactivedevs;
 }
 
 /* Loop 7: Now set the used_by_domain of the device in
@@ -771,10 +810,6 @@ virHostdevPreparePCIDevices(virHostdevManagerPtr 
hostdev_mgr,
 virPCIDeviceFree(dev);
 }
 
-/* Loop 9: Now steal all the devices from pcidevs */
-while (virPCIDeviceListCount(pcidevs) > 0)
-virPCIDeviceListStealIndex(pcidevs, 0);
-
 ret = 0;
 goto

[libvirt] [PATCH v2 3/9] hostdev: Use common reattach code in virHostdevPCINodeDeviceReAttach()

2016-01-25 Thread Andrea Bolognani
This ensures the behavior for reattach is consistent, no matter how it
was triggered (eg. 'virsh nodedev-reattach', 'virsh detach-device' or
shutdown of a domain that is configured to use hostdevs).
---
 src/util/virhostdev.c | 33 ++---
 1 file changed, 30 insertions(+), 3 deletions(-)

diff --git a/src/util/virhostdev.c b/src/util/virhostdev.c
index 586937e..f40d636 100644
--- a/src/util/virhostdev.c
+++ b/src/util/virhostdev.c
@@ -1637,10 +1637,24 @@ virHostdevPCINodeDeviceDetach(virHostdevManagerPtr 
hostdev_mgr,
 return ret;
 }
 
+/**
+ * virHostdevPCINodeDeviceReAttach:
+ * @hostdev_mgr: hostdev manager
+ * @pci: PCI device
+ *
+ * Reattach a specific PCI device to the host.
+ *
+ * This function makes sure the device is not in use before reattaching it
+ * to the host; if the device has already been reattached to the host, the
+ * operation is considered successful.
+ *
+ * Returns: 0 on success, <0 on failure
+ */
 int
 virHostdevPCINodeDeviceReAttach(virHostdevManagerPtr hostdev_mgr,
 virPCIDevicePtr pci)
 {
+virPCIDevicePtr actual;
 struct virHostdevIsPCINodeDeviceUsedData data = {hostdev_mgr, NULL,
  false};
 int ret = -1;
@@ -1651,10 +1665,23 @@ virHostdevPCINodeDeviceReAttach(virHostdevManagerPtr 
hostdev_mgr,
 if (virHostdevIsPCINodeDeviceUsed(virPCIDeviceGetAddress(pci), &data))
 goto out;
 
-virPCIDeviceReattachInit(pci);
+/* We want this function to be idempotent, so if the device has already
+ * been removed from the inactive list (and is not active either, as
+ * per the check above) just return right away. We also need to retrieve
+ * the actual device from the inactive list because that's the one that
+ * contains state information such as the stub driver */
+if (!(actual = virPCIDeviceListFind(hostdev_mgr->inactivePCIHostdevs,
+pci))) {
+VIR_DEBUG("PCI device %s is already attached to the host",
+  virPCIDeviceGetName(pci));
+ret = 0;
+goto out;
+}
 
-if (virPCIDeviceReattach(pci, hostdev_mgr->activePCIHostdevs,
- hostdev_mgr->inactivePCIHostdevs) < 0)
+/* Reattach the device. We don't want to skip unmanaged devices in
+ * this case, because the user explicitly asked for the device to
+ * be reattached to the host driver */
+if (virHostdevOnlyReattachPCIDevice(hostdev_mgr, actual, false) < 0)
 goto out;
 
 ret = 0;
-- 
2.5.0

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


[libvirt] [PATCH v2 1/9] hostdev: Add virHostdevOnlyReattachPCIDevice()

2016-01-25 Thread Andrea Bolognani
This function replaces virHostdevReattachPCIDevice() and, unlike it,
does not perform list manipulation, leaving it to the calling function.

This means virHostdevReAttachPCIDevices() had to be updated to cope
with the updated requirements.
---
 src/util/virhostdev.c | 136 +-
 1 file changed, 90 insertions(+), 46 deletions(-)

diff --git a/src/util/virhostdev.c b/src/util/virhostdev.c
index f31ad41..66629b4 100644
--- a/src/util/virhostdev.c
+++ b/src/util/virhostdev.c
@@ -526,6 +526,74 @@ virHostdevNetConfigRestore(virDomainHostdevDefPtr hostdev,
 return ret;
 }
 
+/**
+ * virHostdevOnlyReattachPCIDevice:
+ * @mgr: hostdev manager
+ * @pci: PCI device to be reattached
+ * @skipUnmanaged: whether to skip unmanaged devices
+ *
+ * Reattach a PCI device to the host.
+ *
+ * This function only performs the base reattach steps that are required
+ * regardless of whether the device is being detached from a domain or
+ * had been simply detached from the host earlier.
+ *
+ * @pci must have already been marked as inactive, and the PCI related
+ * parts of @mgr (inactivePCIHostdevs, activePCIHostdevs) must have been
+ * locked beforehand using virObjectLock().
+ *
+ * Returns: 0 on success, <0 on failure
+ */
+static int
+virHostdevOnlyReattachPCIDevice(virHostdevManagerPtr mgr,
+virPCIDevicePtr pci,
+bool skipUnmanaged)
+{
+virPCIDevicePtr actual;
+int ret = -1;
+
+/* Retrieve the actual device from the inactive list */
+if (!(actual = virPCIDeviceListFind(mgr->inactivePCIHostdevs, pci))) {
+VIR_DEBUG("PCI device %s is not marked as inactive",
+  virPCIDeviceGetName(pci));
+goto out;
+}
+
+/* Skip unmanaged devices if asked to do so */
+if (!virPCIDeviceGetManaged(actual) && skipUnmanaged) {
+VIR_DEBUG("Not reattaching unmanaged PCI device %s",
+  virPCIDeviceGetName(actual));
+ret = 0;
+goto out;
+}
+
+/* Wait for device cleanup if it is qemu/kvm */
+if (virPCIDeviceGetStubDriver(actual) == VIR_PCI_STUB_DRIVER_KVM) {
+int retries = 100;
+while (virPCIDeviceWaitForCleanup(actual, "kvm_assigned_device")
+   && retries) {
+usleep(100*1000);
+retries--;
+}
+}
+
+VIR_DEBUG("Reattaching PCI device %s", virPCIDeviceGetName(actual));
+if (virPCIDeviceReattach(actual, mgr->activePCIHostdevs,
+ mgr->inactivePCIHostdevs) < 0) {
+virErrorPtr err = virGetLastError();
+VIR_ERROR(_("Failed to reattach PCI device %s: %s"),
+  virPCIDeviceGetName(actual),
+  err ? err->message : _("unknown error"));
+virResetError(err);
+goto out;
+}
+
+ret = 0;
+
+ out:
+return ret;
+}
+
 int
 virHostdevPreparePCIDevices(virHostdevManagerPtr hostdev_mgr,
 const char *drv_name,
@@ -753,45 +821,6 @@ virHostdevPreparePCIDevices(virHostdevManagerPtr 
hostdev_mgr,
 return ret;
 }
 
-/*
- * Pre-condition: inactivePCIHostdevs & activePCIHostdevs
- * are locked
- */
-static void
-virHostdevReattachPCIDevice(virPCIDevicePtr dev, virHostdevManagerPtr mgr)
-{
-/* If the device is not managed and was attached to guest
- * successfully, it must have been inactive.
- */
-if (!virPCIDeviceGetManaged(dev)) {
-VIR_DEBUG("Adding unmanaged PCI device %s to inactive list",
-  virPCIDeviceGetName(dev));
-if (virPCIDeviceListAdd(mgr->inactivePCIHostdevs, dev) < 0)
-virPCIDeviceFree(dev);
-return;
-}
-
-/* Wait for device cleanup if it is qemu/kvm */
-if (virPCIDeviceGetStubDriver(dev) == VIR_PCI_STUB_DRIVER_KVM) {
-int retries = 100;
-while (virPCIDeviceWaitForCleanup(dev, "kvm_assigned_device")
-   && retries) {
-usleep(100*1000);
-retries--;
-}
-}
-
-VIR_DEBUG("Reattaching PCI device %s", virPCIDeviceGetName(dev));
-if (virPCIDeviceReattach(dev, mgr->activePCIHostdevs,
- mgr->inactivePCIHostdevs) < 0) {
-virErrorPtr err = virGetLastError();
-VIR_ERROR(_("Failed to re-attach PCI device: %s"),
-  err ? err->message : _("unknown error"));
-virResetError(err);
-}
-virPCIDeviceFree(dev);
-}
-
 /* @oldStateDir:
  * For upgrade purpose: see virHostdevNetConfigRestore
  */
@@ -803,7 +832,7 @@ virHostdevReAttachPCIDevices(virHostdevManagerPtr 
hostdev_mgr,
  int nhostdevs,
  const char *oldStateDir)
 {
-virPCIDeviceListPtr pcidevs;
+virPCIDeviceListPtr pcidevs = NULL;
 size_t i;
 
 if (!nhostdevs)
@@ -848,11 +877,25 @@ virHostdevReAttachPCIDevices(virHostdevManagerPtr 
hostdev_mgr,
 continue;
 }
 }
+   

[libvirt] [PATCH v2 8/9] pci: Phase out virPCIDeviceReattachInit()

2016-01-25 Thread Andrea Bolognani
The name is confusing, and the only use left is in a test case.
---
 src/libvirt_private.syms | 1 -
 src/util/virpci.c| 8 
 src/util/virpci.h| 1 -
 tests/virpcitest.c   | 5 -
 4 files changed, 4 insertions(+), 11 deletions(-)

diff --git a/src/libvirt_private.syms b/src/libvirt_private.syms
index 6d221de..3f3dbe9 100644
--- a/src/libvirt_private.syms
+++ b/src/libvirt_private.syms
@@ -1991,7 +1991,6 @@ virPCIDeviceListSteal;
 virPCIDeviceListStealIndex;
 virPCIDeviceNew;
 virPCIDeviceReattach;
-virPCIDeviceReattachInit;
 virPCIDeviceReset;
 virPCIDeviceSetManaged;
 virPCIDeviceSetRemoveSlot;
diff --git a/src/util/virpci.c b/src/util/virpci.c
index 505c1f3..f56dbe6 100644
--- a/src/util/virpci.c
+++ b/src/util/virpci.c
@@ -1771,14 +1771,6 @@ virPCIDeviceGetUsedBy(virPCIDevicePtr dev,
 *dom_name = dev->used_by_domname;
 }
 
-void virPCIDeviceReattachInit(virPCIDevicePtr pci)
-{
-pci->unbind_from_stub = true;
-pci->remove_slot = true;
-pci->reprobe = true;
-}
-
-
 virPCIDeviceListPtr
 virPCIDeviceListNew(void)
 {
diff --git a/src/util/virpci.h b/src/util/virpci.h
index d1ac942..0debd7b 100644
--- a/src/util/virpci.h
+++ b/src/util/virpci.h
@@ -119,7 +119,6 @@ void virPCIDeviceSetRemoveSlot(virPCIDevice *dev,
 unsigned int virPCIDeviceGetReprobe(virPCIDevicePtr dev);
 void virPCIDeviceSetReprobe(virPCIDevice *dev,
 bool reprobe);
-void virPCIDeviceReattachInit(virPCIDevice *dev);
 
 
 virPCIDeviceListPtr virPCIDeviceListNew(void);
diff --git a/tests/virpcitest.c b/tests/virpcitest.c
index fb0c970..6dceef2 100644
--- a/tests/virpcitest.c
+++ b/tests/virpcitest.c
@@ -301,7 +301,10 @@ testVirPCIDeviceReattachSingle(const void *opaque)
 if (!dev)
 goto cleanup;
 
-virPCIDeviceReattachInit(dev);
+virPCIDeviceSetUnbindFromStub(dev, true);
+virPCIDeviceSetRemoveSlot(dev, true);
+virPCIDeviceSetReprobe(dev, true);
+
 if (virPCIDeviceReattach(dev, NULL, NULL) < 0)
 goto cleanup;
 
-- 
2.5.0

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


[libvirt] [PATCH v2 6/9] hostdev: Minor style adjustments

2016-01-25 Thread Andrea Bolognani
Mostly labels names and whitespace.

No functional changes.
---
 src/util/virhostdev.c | 23 ++-
 1 file changed, 14 insertions(+), 9 deletions(-)

diff --git a/src/util/virhostdev.c b/src/util/virhostdev.c
index 5ded1e9..ab17547 100644
--- a/src/util/virhostdev.c
+++ b/src/util/virhostdev.c
@@ -838,9 +838,10 @@ virHostdevPreparePCIDevices(virHostdevManagerPtr 
hostdev_mgr,
 }
 
  cleanup:
+virObjectUnref(pcidevs);
 virObjectUnlock(hostdev_mgr->activePCIHostdevs);
 virObjectUnlock(hostdev_mgr->inactivePCIHostdevs);
-virObjectUnref(pcidevs);
+
 return ret;
 }
 
@@ -1671,7 +1672,7 @@ virHostdevPCINodeDeviceDetach(virHostdevManagerPtr 
hostdev_mgr,
 virObjectLock(hostdev_mgr->inactivePCIHostdevs);
 
 if (virHostdevIsPCINodeDeviceUsed(virPCIDeviceGetAddress(pci), &data))
-goto out;
+goto cleanup;
 
 /* We want this function to be idempotent, so if the device has already
  * been added to the inactive list (and is not active, as per the check
@@ -1680,19 +1681,21 @@ virHostdevPCINodeDeviceDetach(virHostdevManagerPtr 
hostdev_mgr,
 VIR_DEBUG("PCI device %s is already detached from the host",
   virPCIDeviceGetName(pci));
 ret = 0;
-goto out;
+goto cleanup;
 }
 
 /* Detach the device. We don't want to skip unmanaged devices in
  * this case, because the user explicitly asked for the device to
  * be detached from the host driver */
 if (virHostdevOnlyDetachPCIDevice(hostdev_mgr, pci, false) < 0)
-goto out;
+goto cleanup;
 
 ret = 0;
- out:
+
+ cleanup:
 virObjectUnlock(hostdev_mgr->inactivePCIHostdevs);
 virObjectUnlock(hostdev_mgr->activePCIHostdevs);
+
 return ret;
 }
 
@@ -1722,7 +1725,7 @@ virHostdevPCINodeDeviceReAttach(virHostdevManagerPtr 
hostdev_mgr,
 virObjectLock(hostdev_mgr->inactivePCIHostdevs);
 
 if (virHostdevIsPCINodeDeviceUsed(virPCIDeviceGetAddress(pci), &data))
-goto out;
+goto cleanup;
 
 /* We want this function to be idempotent, so if the device has already
  * been removed from the inactive list (and is not active either, as
@@ -1734,19 +1737,21 @@ virHostdevPCINodeDeviceReAttach(virHostdevManagerPtr 
hostdev_mgr,
 VIR_DEBUG("PCI device %s is already attached to the host",
   virPCIDeviceGetName(pci));
 ret = 0;
-goto out;
+goto cleanup;
 }
 
 /* Reattach the device. We don't want to skip unmanaged devices in
  * this case, because the user explicitly asked for the device to
  * be reattached to the host driver */
 if (virHostdevOnlyReattachPCIDevice(hostdev_mgr, actual, false) < 0)
-goto out;
+goto cleanup;
 
 ret = 0;
- out:
+
+ cleanup:
 virObjectUnlock(hostdev_mgr->inactivePCIHostdevs);
 virObjectUnlock(hostdev_mgr->activePCIHostdevs);
+
 return ret;
 }
 
-- 
2.5.0

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


[libvirt] [PATCH v2 9/9] pci: Add debug messages when unbinding from stub driver

2016-01-25 Thread Andrea Bolognani
Unbinding a PCI device from the stub driver can require several steps,
and it can be useful for debugging to be able to trace which of these
steps are performed and which are skipped for each device.
---
 src/util/virpci.c | 22 ++
 1 file changed, 18 insertions(+), 4 deletions(-)

diff --git a/src/util/virpci.c b/src/util/virpci.c
index f56dbe6..51a3f88 100644
--- a/src/util/virpci.c
+++ b/src/util/virpci.c
@@ -1106,26 +1106,37 @@ virPCIDeviceUnbindFromStub(virPCIDevicePtr dev)
 
 if (!driver) {
 /* The device is not bound to any driver and we are almost done. */
+VIR_DEBUG("PCI device %s is not bound to any driver", dev->name);
 goto reprobe;
 }
 
-if (!dev->unbind_from_stub)
+if (!dev->unbind_from_stub) {
+VIR_DEBUG("Unbind from stub skipped for PCI device %s", dev->name);
 goto remove_slot;
+}
 
 /* If the device isn't bound to a known stub, skip the unbind. */
 if (virPCIStubDriverTypeFromString(driver) < 0 ||
-virPCIStubDriverTypeFromString(driver) == VIR_PCI_STUB_DRIVER_NONE)
+virPCIStubDriverTypeFromString(driver) == VIR_PCI_STUB_DRIVER_NONE) {
+VIR_DEBUG("Unbind from stub skipped for PCI device %s because of "
+  "unknown stub driver", dev->name);
 goto remove_slot;
+}
 
-VIR_DEBUG("Found stub driver %s", driver);
+VIR_DEBUG("Found stub driver %s for PCI device %s", driver, dev->name);
+VIR_DEBUG("Unbinding PCI device %s", dev->name);
 
 if (virPCIDeviceUnbind(dev) < 0)
 goto cleanup;
 dev->unbind_from_stub = false;
 
  remove_slot:
-if (!dev->remove_slot)
+if (!dev->remove_slot) {
+VIR_DEBUG("Slot removal skipped for PCI device %s", dev->name);
 goto reprobe;
+}
+
+VIR_DEBUG("Removing slot for PCI device %s", dev->name);
 
 /* Xen's pciback.ko wants you to use remove_slot on the specific device */
 if (!(path = virPCIDriverFile(driver, "remove_slot")))
@@ -1141,10 +1152,13 @@ virPCIDeviceUnbindFromStub(virPCIDevicePtr dev)
 
  reprobe:
 if (!dev->reprobe) {
+VIR_DEBUG("Reprobe skipped for PCI device %s", dev->name);
 result = 0;
 goto cleanup;
 }
 
+VIR_DEBUG("Reprobing for PCI device %s", dev->name);
+
 /* Trigger a re-probe of the device is not in the stub's dynamic
  * ID table. If the stub is available, but 'remove_id' isn't
  * available, then re-probing would just cause the device to be
-- 
2.5.0

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


[libvirt] [PATCH v2 0/9] PCI hostdev refactoring

2016-01-25 Thread Andrea Bolognani
Changes in v2:

  * Internal functions operate on a single device, don't pass
around device lists for no reason

  * Use virHostdev prefix for internal functions

  * Split off style adjustments and comments updated to separate
patches

See the cover letter for v1[1] for details about the series.

Cheers.


[1] https://www.redhat.com/archives/libvir-list/2016-January/msg00835.html

Andrea Bolognani (9):
  hostdev: Add virHostdevOnlyReattachPCIDevice()
  hostdev: Use common reattach code to rollback prepare errors
  hostdev: Use common reattach code in virHostdevPCINodeDeviceReAttach()
  hostdev: Add virHostdevOnlyDetachPCIDevice()
  hostdev: Use common detach code in virHostdevPCINodeDeviceDetach()
  hostdev: Minor style adjustments
  hostdev: Update comments
  pci: Phase out virPCIDeviceReattachInit()
  pci: Add debug messages when unbinding from stub driver

 src/libvirt_private.syms |   1 -
 src/util/virhostdev.c| 385 ++-
 src/util/virpci.c|  30 ++--
 src/util/virpci.h|   1 -
 tests/virpcitest.c   |   5 +-
 5 files changed, 272 insertions(+), 150 deletions(-)

-- 
2.5.0

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


[libvirt] [PATCH v2 2/9] hostdev: Use common reattach code to rollback prepare errors

2016-01-25 Thread Andrea Bolognani
---
 src/util/virhostdev.c | 14 +-
 1 file changed, 1 insertion(+), 13 deletions(-)

diff --git a/src/util/virhostdev.c b/src/util/virhostdev.c
index 66629b4..586937e 100644
--- a/src/util/virhostdev.c
+++ b/src/util/virhostdev.c
@@ -799,19 +799,7 @@ virHostdevPreparePCIDevices(virHostdevManagerPtr 
hostdev_mgr,
 for (i = 0; i < virPCIDeviceListCount(pcidevs); i++) {
 virPCIDevicePtr dev = virPCIDeviceListGet(pcidevs, i);
 
-if (virPCIDeviceGetManaged(dev)) {
-/* NB: This doesn't actually re-bind to original driver, just
- * unbinds from the stub driver
- */
-VIR_DEBUG("Reattaching managed PCI device %s",
-  virPCIDeviceGetName(dev));
-ignore_value(virPCIDeviceReattach(dev,
-  hostdev_mgr->activePCIHostdevs,
-  
hostdev_mgr->inactivePCIHostdevs));
-} else {
-VIR_DEBUG("Not reattaching unmanaged PCI device %s",
-  virPCIDeviceGetName(dev));
-}
+ignore_value(virHostdevOnlyReattachPCIDevice(hostdev_mgr, dev, true));
 }
 
  cleanup:
-- 
2.5.0

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


[libvirt] [PATCH v2 5/9] hostdev: Use common detach code in virHostdevPCINodeDeviceDetach()

2016-01-25 Thread Andrea Bolognani
This ensures the behavior for detach is consistent, no matter how it
was triggered (eg. 'virsh nodedev-detach', 'virsh attach-device' or
startup of a domain that is configured to use hostdevs).
---
 src/util/virhostdev.c | 28 ++--
 1 file changed, 26 insertions(+), 2 deletions(-)

diff --git a/src/util/virhostdev.c b/src/util/virhostdev.c
index 6f14574..5ded1e9 100644
--- a/src/util/virhostdev.c
+++ b/src/util/virhostdev.c
@@ -1646,6 +1646,19 @@ virHostdevReAttachSCSIDevices(virHostdevManagerPtr 
hostdev_mgr,
 virObjectUnlock(hostdev_mgr->activeSCSIHostdevs);
 }
 
+/**
+ * virHostdevPCINodeDeviceDetach:
+ * @hostdev_mgr: hostdev manager
+ * @pci: PCI device
+ *
+ * Detach a specific PCI device from the host.
+ *
+ * This function makes sure the device is not in use before detaching it
+ * from the host; if the device has already been detached from the host,
+ * the operation is considered successful.
+ *
+ * Returns: 0 on success, <0 on failure
+ */
 int
 virHostdevPCINodeDeviceDetach(virHostdevManagerPtr hostdev_mgr,
   virPCIDevicePtr pci)
@@ -1660,11 +1673,22 @@ virHostdevPCINodeDeviceDetach(virHostdevManagerPtr 
hostdev_mgr,
 if (virHostdevIsPCINodeDeviceUsed(virPCIDeviceGetAddress(pci), &data))
 goto out;
 
-if (virPCIDeviceDetach(pci, hostdev_mgr->activePCIHostdevs,
-   hostdev_mgr->inactivePCIHostdevs) < 0) {
+/* We want this function to be idempotent, so if the device has already
+ * been added to the inactive list (and is not active, as per the check
+ * above) just return right away */
+if (virPCIDeviceListFind(hostdev_mgr->inactivePCIHostdevs, pci)) {
+VIR_DEBUG("PCI device %s is already detached from the host",
+  virPCIDeviceGetName(pci));
+ret = 0;
 goto out;
 }
 
+/* Detach the device. We don't want to skip unmanaged devices in
+ * this case, because the user explicitly asked for the device to
+ * be detached from the host driver */
+if (virHostdevOnlyDetachPCIDevice(hostdev_mgr, pci, false) < 0)
+goto out;
+
 ret = 0;
  out:
 virObjectUnlock(hostdev_mgr->inactivePCIHostdevs);
-- 
2.5.0

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


[libvirt] Call for mentors and project ideas for Google Summer of Code 2016

2016-01-25 Thread Stefan Hajnoczi
The QEMU wiki page for Google Summer of Code 2016 is now available here:

http://qemu-project.org/Google_Summer_of_Code_2016

QEMU will apply for Google Summer of Code 2016 (https://g.co/gsoc/).
If QEMU is accepted there will be funding for students to work on
12-week full-time open source projects remotely from May to August
2016.  QEMU provides a mentor for each student who gives advice and
evaluates their progress.

If you have a project idea, especially if you are a regular
contributor to QEMU and are willing to mentor this summer, please go
to this wiki page and fill out the project idea template:

http://qemu-project.org/Google_Summer_of_Code_2016

The project ideas list is part of the application so that QEMU can
participate in GSoC.  It's useful to have your project ideas on the
wiki by February 8th 2016.

If you have any questions about project ideas or QEMU applying to
GSoC, please reply to this thread.

Thanks,
Stefan

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


Re: [libvirt] [PATCH 2/2] virt-host-validate: Fix error level for user namespace check

2016-01-25 Thread Andrea Bolognani
On Mon, 2016-01-25 at 16:40 +0100, Pavel Hrdina wrote:
> On Mon, Jan 25, 2016 at 08:23:22AM +0100, Michal Privoznik wrote:
> > > From the code it seems to me that we need user namespace iff
> 
> s/>From/From/

This is fun. The leading ">" is an artifact of escaping, to prevent
(poorly written?) MUAs from mistaking a line starting with "From" in
the body for the From: header.

You would think 'git format-patch', and most importantly 'git am',
would be clever enough to take this into account, but alas they
don't and just pass the commit message through.

> s/iff/if/

Not a typo: "iff" is shortand for "if and only if", and by doing a
quick search in the git log you'll find that there are quite a few
previous instances. Mostly introduced by Michal :)

Cheers.

-- 
Andrea Bolognani
Software Engineer - Virtualization Team

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

Re: [libvirt] [PATCH 1/2] storage: zfs: enable on Linux

2016-01-25 Thread John Ferlan


On 01/02/2016 09:25 PM, Roman Bogorodskiy wrote:
> ZFS-on-Linux implementation of ZFS starting with version 0.6.4
> contains all the features we use, so there's no reason to limit
> libvirt ZFS storage backend to FreeBSD only.
> 
> There's still one difference between these implementations: ZFS on
> FreeBSD requires to set 'volmode' option to 'dev' when creating
> volumes, while ZFS-on-Linux does not need that.
> 
> Handle it by checking if 'volmode' option is needed by parsing usage
> information of the 'zfs get' command.
> ---
>  configure.ac  |  8 --
>  src/storage/storage_backend_zfs.c | 51 
> +--
>  2 files changed, 49 insertions(+), 10 deletions(-)
> 

Caveat - I know very little about zfs, FreeBSD...  But it's languishing
so...

> diff --git a/configure.ac b/configure.ac
> index a566f5b..d768341 100644
> --- a/configure.ac
> +++ b/configure.ac
> @@ -2005,14 +2005,6 @@ if test "$with_storage_gluster" = "yes"; then
>  fi
>  AM_CONDITIONAL([WITH_STORAGE_GLUSTER], [test "$with_storage_gluster" = 
> "yes"])
>  
> -if test "$with_storage_zfs" = "check"; then
> -with_storage_zfs=$with_freebsd
> -fi
> -
> -if test "$with_storage_zfs" = "yes" && test "$with_freebsd" = "no"; then
> -AC_MSG_ERROR([The ZFS storage driver can be enabled on FreeBSD only.])
> -fi
> -
>  if test "$with_storage_zfs" = "yes" ||
> test "$with_storage_zfs" = "check"; then
>AC_PATH_PROG([ZFS], [zfs], [], [$PATH:/sbin:/usr/sbin])

So it would seem this hunk and patch 2 would be more related.  That is
the virsh WITH_STORAGE_ZFS. The order of the patches is up to you.


> diff --git a/src/storage/storage_backend_zfs.c 
> b/src/storage/storage_backend_zfs.c
> index cb2662a..6bf7963 100644
> --- a/src/storage/storage_backend_zfs.c
> +++ b/src/storage/storage_backend_zfs.c
> @@ -39,6 +39,47 @@ VIR_LOG_INIT("storage.storage_backend_zfs");
>   *   for size, show just a number instead of 2G etc
>   */
>  
> +/**
> + * virStorageBackendZFSVolModeNeeded:
> + *
> + * Checks if it's necessary to specify 'volmode' (i.e. that
> + * we're working with BSD ZFS implementation).
> + *
> + * Returns 1 if 'volmode' is need, 0 if not needed, -1 on error
> + */

Does volmode only exist in/on one environment? FreeBSD?

> +static int
> +virStorageBackendZFSVolModeNeeded(void)
> +{
> +virCommandPtr cmd = NULL;
> +int ret = -1, exit = -1;
> +char *error = NULL;
> +
> +/* 'zfs get' without arguments prints out
> + * usage information to stderr, including
> + * list of supported options, and exits with
> + * exit code 2
> + */
> +cmd = virCommandNewArgList(ZFS, "get", NULL);
> +virCommandAddEnvString(cmd, "LC_ALL=C");
> +virCommandSetErrorBuffer(cmd, &error);

Why isn't this something like zfs get volmode $target? (examples that
google returns are tank/).  And I would assume $target would
be pool->def->source.name & vol->name (from the caller).

It would seem that all that's being checking is whether the variable
exists "somewhere" (in "some" $target) as opposed to the specific one.

Also from what I read volmode can have many settings.

> +
> +ret = virCommandRun(cmd, &exit);
> +if ((ret < 0) || (exit != 2)) {
> +VIR_WARN("Command 'zfs get' either failed "
> + "to run or exited with unexpected status");
> +goto cleanup;
> +}
> +
> +if (strstr(error, " volmode "))
> +ret = 1;
> +else
> +ret = 0;
> +
> + cleanup:
> +virCommandFree(cmd);
> +VIR_FREE(error);
> +return ret;
> +}
>  
>  static int
>  virStorageBackendZFSCheckPool(virStoragePoolObjPtr pool ATTRIBUTE_UNUSED,
> @@ -258,6 +299,7 @@ virStorageBackendZFSCreateVol(virConnectPtr conn 
> ATTRIBUTE_UNUSED,
>  {
>  virCommandPtr cmd = NULL;
>  int ret = -1;
> +int volmode_needed = -1;
>  
>  vol->type = VIR_STORAGE_VOL_BLOCK;
>  
> @@ -273,6 +315,9 @@ virStorageBackendZFSCreateVol(virConnectPtr conn 
> ATTRIBUTE_UNUSED,
>  if (VIR_STRDUP(vol->key, vol->target.path) < 0)
>  goto cleanup;
>  
> +volmode_needed = virStorageBackendZFSVolModeNeeded();
> +if (volmode_needed < 0)
> +goto cleanup;
>  /**
>   * $ zfs create -o volmode=dev -V 10240K test/volname
>   *
> @@ -281,8 +326,10 @@ virStorageBackendZFSCreateVol(virConnectPtr conn 
> ATTRIBUTE_UNUSED,
>   *   will lookup vfs.zfs.vol.mode sysctl value
>   * -V -- tells to create a volume with the specified size
>   */
> -cmd = virCommandNewArgList(ZFS, "create", "-o", "volmode=dev",
> -   "-V", NULL);
> +cmd = virCommandNewArgList(ZFS, "create", NULL);

Why not just encase this in

#if WITH_FREEBSD
virCommandAddArgList(cmd, "-o", "volmode=dev", NULL);
#endif

Although perhaps there's some that may not like that approach... It just
seems 'safer' than a get command which searches the output for the
parameter being present. Who knows what implica

Re: [libvirt] [PATCH 1/2] storage: zfs: enable on Linux

2016-01-25 Thread Roman Bogorodskiy
  John Ferlan wrote:

> 
> 
> On 01/02/2016 09:25 PM, Roman Bogorodskiy wrote:
> > ZFS-on-Linux implementation of ZFS starting with version 0.6.4
> > contains all the features we use, so there's no reason to limit
> > libvirt ZFS storage backend to FreeBSD only.
> > 
> > There's still one difference between these implementations: ZFS on
> > FreeBSD requires to set 'volmode' option to 'dev' when creating
> > volumes, while ZFS-on-Linux does not need that.
> > 
> > Handle it by checking if 'volmode' option is needed by parsing usage
> > information of the 'zfs get' command.
> > ---
> >  configure.ac  |  8 --
> >  src/storage/storage_backend_zfs.c | 51 
> > +--
> >  2 files changed, 49 insertions(+), 10 deletions(-)
> > 
> 
> Caveat - I know very little about zfs, FreeBSD...  But it's languishing
> so...

Heh. Thanks for stepping in! :)

> > diff --git a/configure.ac b/configure.ac
> > index a566f5b..d768341 100644
> > --- a/configure.ac
> > +++ b/configure.ac
> > @@ -2005,14 +2005,6 @@ if test "$with_storage_gluster" = "yes"; then
> >  fi
> >  AM_CONDITIONAL([WITH_STORAGE_GLUSTER], [test "$with_storage_gluster" = 
> > "yes"])
> >  
> > -if test "$with_storage_zfs" = "check"; then
> > -with_storage_zfs=$with_freebsd
> > -fi
> > -
> > -if test "$with_storage_zfs" = "yes" && test "$with_freebsd" = "no"; then
> > -AC_MSG_ERROR([The ZFS storage driver can be enabled on FreeBSD only.])
> > -fi
> > -
> >  if test "$with_storage_zfs" = "yes" ||
> > test "$with_storage_zfs" = "check"; then
> >AC_PATH_PROG([ZFS], [zfs], [], [$PATH:/sbin:/usr/sbin])
> 
> So it would seem this hunk and patch 2 would be more related.  That is
> the virsh WITH_STORAGE_ZFS. The order of the patches is up to you.

Actually, these two patches are unrelated. I should have been added the
virsh part when I added ZFS driver in the first place, but I forgot
about it at that time.

I remembered about it when I was testing my configure.ac changes on
Linux and saw that virsh -V output does not change.

> > diff --git a/src/storage/storage_backend_zfs.c 
> > b/src/storage/storage_backend_zfs.c
> > index cb2662a..6bf7963 100644
> > --- a/src/storage/storage_backend_zfs.c
> > +++ b/src/storage/storage_backend_zfs.c
> > @@ -39,6 +39,47 @@ VIR_LOG_INIT("storage.storage_backend_zfs");
> >   *   for size, show just a number instead of 2G etc
> >   */
> >  
> > +/**
> > + * virStorageBackendZFSVolModeNeeded:
> > + *
> > + * Checks if it's necessary to specify 'volmode' (i.e. that
> > + * we're working with BSD ZFS implementation).
> > + *
> > + * Returns 1 if 'volmode' is need, 0 if not needed, -1 on error
> > + */
> 
> Does volmode only exist in/on one environment? FreeBSD?
> 
> > +static int
> > +virStorageBackendZFSVolModeNeeded(void)
> > +{
> > +virCommandPtr cmd = NULL;
> > +int ret = -1, exit = -1;
> > +char *error = NULL;
> > +
> > +/* 'zfs get' without arguments prints out
> > + * usage information to stderr, including
> > + * list of supported options, and exits with
> > + * exit code 2
> > + */
> > +cmd = virCommandNewArgList(ZFS, "get", NULL);
> > +virCommandAddEnvString(cmd, "LC_ALL=C");
> > +virCommandSetErrorBuffer(cmd, &error);
> 
> Why isn't this something like zfs get volmode $target? (examples that
> google returns are tank/).  And I would assume $target would
> be pool->def->source.name & vol->name (from the caller).
> 
> It would seem that all that's being checking is whether the variable
> exists "somewhere" (in "some" $target) as opposed to the specific one.

No, the goal is to check if "volmode" option is supported by the ZFS
implementation we're using. So we don't need any specific information,
just parse usage/help information that 'zfs get' prints out.

In other words, 'zfs get' does not try to receive any information about
the actual pools, volumes etc, its output is always same.

> Also from what I read volmode can have many settings.

Yeah, though if it's available, we always set it to 'dev', and if it's
not available, we just don't care. No need to worry about other possible
settings.

> > +
> > +ret = virCommandRun(cmd, &exit);
> > +if ((ret < 0) || (exit != 2)) {
> > +VIR_WARN("Command 'zfs get' either failed "
> > + "to run or exited with unexpected status");
> > +goto cleanup;
> > +}
> > +
> > +if (strstr(error, " volmode "))
> > +ret = 1;
> > +else
> > +ret = 0;
> > +
> > + cleanup:
> > +virCommandFree(cmd);
> > +VIR_FREE(error);
> > +return ret;
> > +}
> >  
> >  static int
> >  virStorageBackendZFSCheckPool(virStoragePoolObjPtr pool ATTRIBUTE_UNUSED,
> > @@ -258,6 +299,7 @@ virStorageBackendZFSCreateVol(virConnectPtr conn 
> > ATTRIBUTE_UNUSED,
> >  {
> >  virCommandPtr cmd = NULL;
> >  int ret = -1;
> > +int volmode_needed = -1;
> >  
> >  vol->type = VIR_STORAGE_VOL_BLOCK;
> >  
> > @@ -273,6 +315,9 @@ 

Re: [libvirt] [PATCHv2] util: keep/use a bitmap of in-use macvtap devices

2016-01-25 Thread Laine Stump

On 01/25/2016 07:16 AM, Pavel Hrdina wrote:

On Fri, Jan 22, 2016 at 12:52:27PM -0500, Laine Stump wrote:

This patch creates two bitmaps, one for macvlan devicenames and one

s/devicenames/device names/

[...]


Done.




diff --git a/src/util/virnetdevmacvlan.c b/src/util/virnetdevmacvlan.c

[...]


+/**
+ * virNetDevMacVLanReserveName:
+ *
+ *  @name: already-known name of device
+ *  @quietFail: don't log an error if this name is already in-use
+ *
+ *  Extract the device type and id from a macvtap/macvlan device name
+ *  and mark the appropriate position as in-use in the appropriate
+ *  bitmap.
+ *
+ *  returns 0 on success, -1 on failure, -2 if the name doesn't fit the 
auto-pattern

Long line, would be nice to wrap it.  And the return 0 isn't true, because
virNetDevMacVLanReserveID() returns ID on success.


The danger of documenting the function when it's initially written, 
rather than doing it as an afterthought after everything is wrapped up :-).






+ */
+int
+virNetDevMacVLanReserveName(const char *name, bool quietFail)
+{
+unsigned int id;
+unsigned int flags = 0;
+const char *idstr = NULL;
+
+if (virNetDevMacVLanInitialize() < 0)
+   return -1;
+
+if (STRPREFIX(name, MACVTAP_NAME_PREFIX)) {
+idstr = name + strlen(MACVTAP_NAME_PREFIX);
+flags |= VIR_NETDEV_MACVLAN_CREATE_WITH_TAP;
+} else if (STRPREFIX(name, MACVLAN_NAME_PREFIX)) {
+idstr = name + strlen(MACVLAN_NAME_PREFIX);
+} else {
+return -2;
+}
+
+if (virStrToLong_ui(idstr, NULL, 10, &id) < 0) {
+virReportError(VIR_ERR_INTERNAL_ERROR,
+   _("couldn't get id value from macvtap device name %s"),
+   name);
+return -1;
+}
+return virNetDevMacVLanReserveID(id, flags, quietFail, false);
+}

[...]


  const char *type = (flags & VIR_NETDEV_MACVLAN_CREATE_WITH_TAP) ?
  "macvtap" : "macvlan";
-const char *prefix = (flags & VIR_NETDEV_MACVLAN_CREATE_WITH_TAP) ?
-MACVTAP_NAME_PREFIX : MACVLAN_NAME_PREFIX;

Maybe use the MACV(TAP|LAN)_NAME_PREFIX instead of the strings for *type.



Yeah, I wonder why it wasn't like that from the beginning (and for that 
matter why they had a separate char* for prefix and type even though 
they were identical. Maybe they were anticipating the day when libvirt 
might change the names it uses for the devices? Dunno. Anyway, I've 
changed it as you suggest.






  const char *pattern = (flags & VIR_NETDEV_MACVLAN_CREATE_WITH_TAP) ?
  MACVTAP_NAME_PATTERN : MACVLAN_NAME_PATTERN;
-int c, rc;
+int rc, reservedID = -1;
  char ifname[IFNAMSIZ];
  int retries, do_retry = 0;
  uint32_t macvtapMode;
-const char *cr_ifname = NULL;
+const char *ifnameCreated = NULL;
  int ret;
  int vf = -1;
  bool vnet_hdr = flags & VIR_NETDEV_MACVLAN_VNET_HDR;

[...]


+retries = MACVLAN_MAX_ID + 1;
+while (!ifnameCreated && retries) {
  virMutexLock(&virNetDevMacVLanCreateMutex);
-for (c = 0; c < 8192; c++) {
-snprintf(ifname, sizeof(ifname), pattern, c);
-if ((ret = virNetDevExists(ifname)) < 0) {
-virMutexUnlock(&virNetDevMacVLanCreateMutex);
+reservedID = virNetDevMacVLanReserveID(reservedID, flags, false, true);
+if (reservedID < 0) {
+virMutexUnlock(&virNetDevMacVLanCreateMutex);
+return -1;
+}
+snprintf(ifname, sizeof(ifname), pattern, reservedID);

Since you're changing this, snprintf returns -1 in case of error.


Well, the man page says -1 is returned by the *printf functions "if an 
output error is encountered", which would include an I/O error (moot for 
snprintf() since it doesn't do any I/O) or a bad format string (but 
we're calling it with a literal format string that only includes a 
single %d, so it is known to be good). Checking the returned length is 
pointless too, since by definition the longest possible result of 
macvtap%d where the %d is guaranteed between 0 and 8192 is 
"macvtap8192", which is 12 characters - safely below the limit of 
IFNAMSIZ (16).




ACK with the issues fixed.



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


[libvirt] [PATCH] virsh: fix cpu-stats command output format issue

2016-01-25 Thread Luyao Huang
After commit 57177f1, the cpu-stats command format change to:

CPU0:
cpu_time 14401.507878990 seconds
vcpu_time14378732785511

vcpu_time is not user friendly. After this patch, it will
change back:
CPU0:
cpu_time 14401.507878990 seconds
vcpu_time14378.732785511 seconds

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

Signed-off-by: Luyao Huang 
---
 tools/virsh-domain.c | 1 +
 1 file changed, 1 insertion(+)

diff --git a/tools/virsh-domain.c b/tools/virsh-domain.c
index 1089a4d..c2146d2 100644
--- a/tools/virsh-domain.c
+++ b/tools/virsh-domain.c
@@ -7243,6 +7243,7 @@ vshCPUStatsPrintField(vshControl *ctl,
 {
 vshPrint(ctl, "\t%-12s ", param->field);
 if ((STREQ(param->field, VIR_DOMAIN_CPU_STATS_CPUTIME) ||
+ STREQ(param->field, VIR_DOMAIN_CPU_STATS_VCPUTIME) ||
  STREQ(param->field, VIR_DOMAIN_CPU_STATS_USERTIME) ||
  STREQ(param->field, VIR_DOMAIN_CPU_STATS_SYSTEMTIME)) &&
 param->type == VIR_TYPED_PARAM_ULLONG) {
-- 
1.8.3.1

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


[libvirt] [PATCH] libxl: support assignment from a pool of SRIOV VFs

2016-01-25 Thread Chunyan Liu
Add codes to support creating domain with network defition of assigning
SRIOV VF from a pool. And fix hot plug and unplug SRIOV VF under this
kind of network defition.

Signed-off-by: Chunyan Liu 
---
 src/libxl/libxl_conf.c   |  5 +++--
 src/libxl/libxl_domain.c | 48 +++-
 src/libxl/libxl_driver.c | 12 
 tests/Makefile.am|  3 +++
 4 files changed, 65 insertions(+), 3 deletions(-)

diff --git a/src/libxl/libxl_conf.c b/src/libxl/libxl_conf.c
index 6320421..f50c68a 100644
--- a/src/libxl/libxl_conf.c
+++ b/src/libxl/libxl_conf.c
@@ -1260,7 +1260,8 @@ libxlMakeNicList(virDomainDefPtr def,  
libxl_domain_config *d_config)
 return -1;
 
 for (i = 0; i < nnics; i++) {
-if (l_nics[i]->type == VIR_DOMAIN_NET_TYPE_HOSTDEV)
+if (l_nics[i]->type == VIR_DOMAIN_NET_TYPE_HOSTDEV ||
+l_nics[i]->data.network.actual->type == 
VIR_DOMAIN_NET_TYPE_HOSTDEV)
 continue;
 
 if (libxlMakeNic(def, l_nics[i], &x_nics[nvnics]))
@@ -1278,7 +1279,7 @@ libxlMakeNicList(virDomainDefPtr def,  
libxl_domain_config *d_config)
 
 VIR_SHRINK_N(x_nics, nnics, nnics - nvnics);
 d_config->nics = x_nics;
-d_config->num_nics = nnics;
+d_config->num_nics = nvnics;
 
 return 0;
 
diff --git a/src/libxl/libxl_domain.c b/src/libxl/libxl_domain.c
index cf5c9f6..9bf7a5a 100644
--- a/src/libxl/libxl_domain.c
+++ b/src/libxl/libxl_domain.c
@@ -35,6 +35,7 @@
 #include "virstring.h"
 #include "virtime.h"
 #include "locking/domain_lock.h"
+#include "network/bridge_driver.h"
 
 #define VIR_FROM_THIS VIR_FROM_LIBXL
 
@@ -314,7 +315,7 @@ libxlDomainDeviceDefPostParse(virDomainDeviceDefPtr dev,
 virDomainHostdevSubsysPCIPtr pcisrc;
 
 if (dev->type == VIR_DOMAIN_DEVICE_NET)
-hostdev = &(dev->data.net)->data.hostdev.def;
+hostdev = &dev->data.net->data.hostdev.def;
 else
 hostdev = dev->data.hostdev;
 pcisrc = &hostdev->source.subsys.u.pci;
@@ -916,6 +917,48 @@ libxlConsoleCallback(libxl_ctx *ctx, libxl_event *ev, void 
*for_callback)
 libxl_event_free(ctx, ev);
 }
 
+static int
+libxlNetworkPrepareDevices(virDomainDefPtr def)
+{
+int ret = -1;
+size_t i;
+
+for (i = 0; i < def->nnets; i++) {
+virDomainNetDefPtr net = def->nets[i];
+int actualType;
+
+/* If appropriate, grab a physical device from the configured
+ * network's pool of devices, or resolve bridge device name
+ * to the one defined in the network definition.
+ */
+if (networkAllocateActualDevice(def, net) < 0)
+goto cleanup;
+
+actualType = virDomainNetGetActualType(net);
+if (actualType == VIR_DOMAIN_NET_TYPE_HOSTDEV &&
+net->type == VIR_DOMAIN_NET_TYPE_NETWORK) {
+/* Each type='hostdev' network device must also have a
+ * corresponding entry in the hostdevs array. For netdevs
+ * that are hardcoded as type='hostdev', this is already
+ * done by the parser, but for those allocated from a
+ * network / determined at runtime, we need to do it
+ * separately.
+ */
+virDomainHostdevDefPtr hostdev = virDomainNetGetActualHostdev(net);
+virDomainHostdevSubsysPCIPtr pcisrc = 
&hostdev->source.subsys.u.pci;
+
+if (hostdev->mode == VIR_DOMAIN_HOSTDEV_MODE_SUBSYS &&
+hostdev->source.subsys.type == 
VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_PCI)
+pcisrc->backend = VIR_DOMAIN_HOSTDEV_PCI_BACKEND_XEN;
+
+if (virDomainHostdevInsert(def, hostdev) < 0)
+goto cleanup;
+}
+}
+ret = 0;
+ cleanup:
+return ret;
+}
 
 /*
  * Start a domain through libxenlight.
@@ -992,6 +1035,9 @@ libxlDomainStart(libxlDriverPrivatePtr driver, 
virDomainObjPtr vm,
 vm, true) < 0)
 goto cleanup;
 
+if (libxlNetworkPrepareDevices(vm->def) < 0)
+goto cleanup;
+
 if (libxlBuildDomainConfig(driver->reservedGraphicsPorts, vm->def,
cfg->ctx, &d_config) < 0)
 goto cleanup;
diff --git a/src/libxl/libxl_driver.c b/src/libxl/libxl_driver.c
index 4a9134e..6aca042 100644
--- a/src/libxl/libxl_driver.c
+++ b/src/libxl/libxl_driver.c
@@ -3047,6 +3047,12 @@ libxlDomainAttachHostPCIDevice(libxlDriverPrivatePtr 
driver,
 
 libxl_device_pci_init(&pcidev);
 
+/* For those allocated from a network pool/ determined at runtime, it's
+ * not handled by libxlDomainDeviceDefPostParse as hostdev, we need to
+ * set backend correctly.
+ */
+pcisrc->backend = VIR_DOMAIN_HOSTDEV_PCI_BACKEND_XEN;
+
 if (virDomainHostdevFind(vm->def, hostdev, &found) >= 0) {
 virReportError(VIR_ERR_OPERATION_FAILED,
_("target pci device %.4x:%.2x:%.2x.%.1x already 
exists"),
@@ -3388,6 +3394,12 @@ libxlDomainDetachHostPCIDev