Re: [libvirt] [PATCH] conf: don't output managed attr for non-pci hostdevs

2019-02-27 Thread Nikolay Shirokovskiy



On 27.02.2019 20:43, John Ferlan wrote:
> 
> 
> On 2/22/19 4:35 AM, Nikolay Shirokovskiy wrote:
>> It is ignored on input for non pci hostdevs as written in docs.
>> I guess it would be better if the attr was disabled to be specified
>> in the first place instead but such behaviour is already documented.
>> At least let's not output it back. This will fix issue when
>> managed appeared on output for non pci hostdevs when it was not
>> specified on input.
>>
>> The tests are fixed by next commands:
>> grep  -lRP 'hostdev.*mode=.subsystem.*type=.(?!pci).*managed' `find tests 
>> -name '*.xml'` > files
>> sed -i.bak -re 's/ managed=.(yes|no).//' `cat files`
>>
> 
> To save yourself some effort in the future...
> 
> VIR_TEST_REGENERATE_OUTPUT=1 tests/qemuxml2xmltest
> VIR_TEST_REGENERATE_OUTPUT=1 tests/xlconfigtest
> VIR_TEST_REGENERATE_OUTPUT=1 tests/qemuargv2xmltest
> 
> Would have got a lot of them...

Thanx, great hint!

> 
>> Signed-off-by: Nikolay Shirokovskiy 
>> ---
>>  src/conf/domain_conf.c |  6 --
>>  tests/qemuargv2xmldata/hostdev-usb-address.xml |  2 +-
>>  tests/qemuxml2argvdata/controller-order.xml|  2 +-
>>  .../disk-hostdev-scsi-address-conflict.xml |  2 +-
>>  .../disk-hostdev-scsi-virtio-iscsi-auth-AES.xml|  2 +-
>>  .../hostdev-scsi-autogen-address.xml   | 22 
>> +++---
>>  tests/qemuxml2argvdata/hostdev-scsi-boot.xml   |  2 +-
>>  tests/qemuxml2argvdata/hostdev-scsi-large-unit.xml |  2 +-
>>  .../hostdev-scsi-lsi-iscsi-auth.xml|  4 ++--
>>  tests/qemuxml2argvdata/hostdev-scsi-lsi-iscsi.xml  |  4 ++--
>>  tests/qemuxml2argvdata/hostdev-scsi-lsi.xml|  2 +-
>>  tests/qemuxml2argvdata/hostdev-scsi-rawio.xml  |  2 +-
>>  tests/qemuxml2argvdata/hostdev-scsi-readonly.xml   |  2 +-
>>  tests/qemuxml2argvdata/hostdev-scsi-sgio.xml   |  2 +-
>>  tests/qemuxml2argvdata/hostdev-scsi-shareable.xml  |  2 +-
>>  .../hostdev-scsi-vhost-scsi-ccw.xml|  2 +-
>>  .../hostdev-scsi-vhost-scsi-pci.xml|  2 +-
>>  .../hostdev-scsi-vhost-scsi-pcie.xml   |  2 +-
>>  .../hostdev-scsi-virtio-iscsi-auth.xml |  4 ++--
>>  .../qemuxml2argvdata/hostdev-scsi-virtio-iscsi.xml |  4 ++--
>>  .../qemuxml2argvdata/hostdev-scsi-virtio-scsi.xml  |  2 +-
>>  .../hostdev-usb-address-device-boot.xml|  2 +-
>>  .../hostdev-usb-address-device.xml |  2 +-
>>  tests/qemuxml2argvdata/hostdev-usb-address.xml |  2 +-
>>  .../hostdevs-drive-address-conflict.xml|  4 ++--
>>  tests/qemuxml2argvdata/name-escape.xml |  2 +-
>>  tests/qemuxml2argvdata/user-aliases-usb.xml|  4 ++--
>>  tests/qemuxml2xmloutdata/hostdev-mdev-display.xml  |  2 +-
>>  .../qemuxml2xmloutdata/hostdev-mdev-precreated.xml |  2 +-
>>  .../hostdev-scsi-autogen-address.xml   | 22 
>> +++---
>>  .../qemuxml2xmloutdata/hostdev-scsi-large-unit.xml |  2 +-
>>  .../hostdev-scsi-lsi-iscsi-auth.xml|  4 ++--
>>  .../qemuxml2xmloutdata/hostdev-scsi-lsi-iscsi.xml  |  4 ++--
>>  tests/qemuxml2xmloutdata/hostdev-scsi-lsi.xml  |  2 +-
>>  tests/qemuxml2xmloutdata/hostdev-scsi-rawio.xml|  2 +-
>>  tests/qemuxml2xmloutdata/hostdev-scsi-readonly.xml |  2 +-
>>  tests/qemuxml2xmloutdata/hostdev-scsi-sgio.xml |  2 +-
>>  .../qemuxml2xmloutdata/hostdev-scsi-shareable.xml  |  2 +-
>>  .../hostdev-scsi-vhost-scsi-ccw.xml|  2 +-
>>  .../hostdev-scsi-vhost-scsi-pci.xml|  2 +-
>>  .../hostdev-scsi-vhost-scsi-pcie.xml   |  2 +-
>>  .../hostdev-scsi-virtio-iscsi-auth.xml |  4 ++--
>>  .../hostdev-scsi-virtio-iscsi.xml  |  4 ++--
>>  .../hostdev-scsi-virtio-scsi.xml   |  2 +-
>>  .../hostdev-subsys-mdev-vfio-ccw.xml   |  2 +-
>>  tests/qemuxml2xmloutdata/hostdev-usb-address.xml   |  2 +-
>>  tests/xlconfigdata/test-usb.xml|  2 +-
>>  47 files changed, 80 insertions(+), 78 deletions(-)
>>
>> diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c
>> index ceeb247..9ff659c 100644
>> --- a/src/conf/domain_conf.c
>> +++ b/src/conf/domain_conf.c
>> @@ -27330,8 +27330,10 @@ virDomainHostdevDefFormat(virBufferPtr buf,
>>  virBufferAsprintf(buf, ">mode, type);
>>  if (def->mode == VIR_DOMAIN_HOSTDEV_MODE_SUBSYS) {
>> -virBufferAsprintf(buf, " managed='%s'",
>> -  def->managed ? "yes" : "no");
>> +if (def->source.subsys.type == VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_PCI) {
>> +virBufferAsprintf(buf, " managed='%s'",
>> +  def->managed ? "yes" : "no");
>> +}
> 
> Do you think perhaps @managed should be changed to a virTristateBool?
> After all the RNG attribute is a virYesNo like other Tristate's.

AFAIU tristate is nice when we have hypervisor-specific default values.
In this case 

Re: [libvirt] [Qemu-devel] Virtio-net control queue handling

2019-02-27 Thread Jason Wang


On 2019/2/28 上午1:39, Nikhil Agarwal wrote:

Hi Stefan,

Thanks for directing question to correct people, yes your understanding is 
correct.

I want virtio-net control virtqueue to be handled by vhost-user-net device 
based backend for vdpa use case where control message would do some 
configuration on actual hw device. Or these changes should to be done in 
libvirt where QMP event are being handled as of now?

Regards
Nikhil



Cc Michael. Several methods for dealing with control virtqueue:

1) using backend specific method. For example, multiqueue control for 
TAP was done in this way, and we plan to support RSS in this way as well 
(through steering eBPF program). But this may not work for the 
privilleged operations.
2) inventing new vhost(user) protocol, convert the vq command to 
vhost(user) command and pass it to vhost(user) backend.

3) extend vhost protocol to deal with control vq like you propose here.
4) notify libvirt using QMP event, we've already supported this if rx 
filter is changed for virtio-net, and let management to deal with the 
changes.
5) implementing or linking vhost backend qemu, then there's no need to 
invent no IPCs


For the case of vDPA, I'm not sure the use case for vDPA through 
vhost-user. Can you describe more about that? To me the best way is 
probably done through mdev and VFIO not userspace path.


Thanks





-Original Message-
From: Stefan Hajnoczi 
Sent: Wednesday, February 27, 2019 8:54 PM
To: Nikhil Agarwal 
Cc: qemu-de...@nongnu.org; jasow...@redhat.com; libvir-list@redhat.com
Subject: Re: [Qemu-devel] Virtio-net control queue handling

On Tue, Feb 26, 2019 at 02:13:43PM +, Nikhil Agarwal wrote:

Is there any option in QEMU to offload virtio device control queue handling to 
backend instead of deciphering and passing to libvirt via QMP? if not, is there 
any interface in libvirt which passes on these message to application or i 
directly use QMP interface from QEMU?

I'm not sure I understand your question.  It could be because of
terminology:

"virtio device control queue" == virtio-net control virtqueue?

"backend" == vhost-user-net device backend?

"message" == QMP event?

I have CCed Jason Wang, QEMU network subsystem maintainer, and the libvirt 
mailing list.

Stefan



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

Re: [libvirt] [PATCH v4 11/20] wip: backup: Parse and output checkpoint XML

2019-02-27 Thread John Ferlan



On 2/25/19 4:06 PM, Eric Blake wrote:
> On 2/12/19 11:23 AM, John Ferlan wrote:
>>
>>
>> On 2/6/19 2:18 PM, Eric Blake wrote:
>>> Work in progress - the checkpoint code is not quite passing
>>> tests (part of that is figuring out the minimal XML that is
>>> still valid as a  element, or just use --no-domain flag).
>>>
>>> Signed-off-by: Eric Blake 
>>> ---
>>>  src/conf/checkpoint_conf.h  |  150 
>>>  src/conf/domain_conf.h  |   11 +-
>>>  po/POTFILES |1 +
>>>  src/conf/Makefile.inc.am|2 +
>>>  src/conf/checkpoint_conf.c  | 1030 +++
>>>  src/conf/domain_conf.c  |7 +-
>>>  src/libvirt_private.syms|   21 +
>>>  tests/Makefile.am   |9 +-
>>>  tests/domaincheckpointxml2xmltest.c |  231 ++
>>>  9 files changed, 1458 insertions(+), 4 deletions(-)
>>>  create mode 100644 src/conf/checkpoint_conf.h
>>>  create mode 100644 src/conf/checkpoint_conf.c
>>>  create mode 100644 tests/domaincheckpointxml2xmltest.c
>>>
>>
>> Starting to lose some steam - seeing wip means I don't want to spend too
>> much time on some algorithms for fear they'll change, but then again I
>> know you're looking for feedback...
> 
> I understand. The 'wip' tags should be gone for v5.
> 
>>
>>> diff --git a/src/conf/checkpoint_conf.h b/src/conf/checkpoint_conf.h
>>> new file mode 100644
>>> index 00..994a8bd083
>>> --- /dev/null
>>> +++ b/src/conf/checkpoint_conf.h
>>> @@ -0,0 +1,150 @@
>>> +/*
>>> + * checkpoint_conf.h: domain checkpoint XML processing
>>> + *
>>> + * Copyright (C) 2006-2019 Red Hat, Inc.
>>> + * Copyright (C) 2006-2008 Daniel P. Berrange
>>
>> This is new, right?  Not a copy of...
> 
> New file, but so heavily copied from snapshot_conf.h that I felt safer
> preserving all existing copyrights.
> 

See src/conf/{vir*obj}.c for some examples, e.g.:

 * virinterfaceobj.c: interface object handling
 *(derived from interface_conf.c)

that's what I ended up doing when splitting apart XML handling from
Object handling code.

> 
>>> +struct _virDomainCheckpointDef {
>>> +/* Public XML.  */
>>> +char *name;
>>> +char *description;
>>> +char *parent;
>>> +long long creationTime; /* in seconds */
>>> +
>>> +size_t ndisks; /* should not exceed dom->ndisks */
>>> +virDomainCheckpointDiskDef *disks;
>>> +
>>> +virDomainDefPtr dom;
>>> +
>>> +/* Internal use.  */
>>> +bool current; /* At most one checkpoint in the list should have this 
>>> set */
>>
>> Typically these are then in the *Obj...
> 
> Copy-and-paste from virDomainSnapshotDef, but my recent work there has
> made me want to reconsider where the current object is tracked.
> 

Yeah, understandable. Like I noted earlier - when I did the work to
split out object code and make it more common, I skipped snapshots for
various reasons, but mostly because I feared that code and wasn't sure
if changing it would cause issues with any blockdev work Peter was
doing. So I want the safer route.

I do think snapshot_conf.c could be split up with virsnapshotobjlist.c
being created, but that's future work.  Maybe something you can consider
for checkpoints though.

> The problem is that the current way we store things on disk is via a
> separate  XML per snapshot, with no other obvious place
> for the internal representation of a  to track which snapshot is
> current.  BUT, as I have just posted patches to add a bulk dump/redefine
> with VIR_DOMAIN_XML_SNAPSHOTS, we COULD just ditch our current
> separate-file storage of snapshots, and instead store the snapshots
> directly with the  (for all new saves; when loading libvirtd,
> we'd still have to keep the code to load from older separate snapshot
> files for back-compat reasons, even if we no longer track separate files
> after the one-time conversion).  And if I make snapshots cleaner like
> that, then checkpoints can just start life with the saner approach,
> rather than being stuck with copying the older one-file-per-checkpoint
> approach that I implemented using copy-and-paste.
> 

Hey, I recognize that explanation!

>>
>>> +};
>>> +
>>> +struct _virDomainCheckpointObj {
>>> +virDomainCheckpointDefPtr def; /* non-NULL except for metaroot */
>>> +
>>> +virDomainCheckpointObjPtr parent; /* non-NULL except for metaroot, 
>>> before
>>> + 
>>> virDomainCheckpointUpdateRelations, or
>>> + after 
>>> virDomainCheckpointDropParent */
>>> +virDomainCheckpointObjPtr sibling; /* NULL if last child of parent */
>>> +size_t nchildren;
>>> +virDomainCheckpointObjPtr first_child; /* NULL if no children */
>>
>> The whole relationship thing is I think overly complex and a bit
>> difficult to follow. Having @sibling and @first_child seems to make the
>> code even more complex. I would think you have a parent and maybe a
>> child. If this is 

[libvirt] Release candidate 2 of libvirt-5.1.0

2019-02-27 Thread Daniel Veillard
  It's there, tagged in git and with signed tarball and rpms at the usual
place:

   ftp://libvirt.org/libvirt/

  Seems to work fin in my limited testing, I didn't hear any complaint
about RC1, and incredibly https://ci.centos.org/view/libvirt/ is still
all green, so this looks good so far, but please check it for defects.

  If everything works fine, I may try to push the GA version on Friday
before taking my flight, otherwise that may be pushed to the week-end.

Please give it some testing,

  thanks,

Daniel

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

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


Re: [libvirt] [PATCH v4 08/20] backup: Introduce virDomainBackup APIs

2019-02-27 Thread John Ferlan


[...]

> 
>>> +++ b/src/libvirt-domain-checkpoint.c
>>> @@ -721,3 +721,205 @@ virDomainCheckpointFree(virDomainCheckpointPtr 
>>> checkpoint)
>>>  virObjectUnref(checkpoint);
>>>  return 0;
>>>  }
>>
>> Dirtying the namespace of libvirt-domain-checkpoint w/ Backup. Why not a
>> separate libvirt-domain-backup - beyond the obvious need to alter more
>> stuff of course.  If kept here would seem to need to alter line #2 way
>> back up at the top to include virDomainBackupPtr API's too.
> 
> Or even place the backup APIs directly in libvirt-domain.c, as they are
> domain-based operations with no separate object being created, and are
> more similar to other job-based APIs like virDomainMigrate().
> 

Yes, makes more sense I think - operating on a domain or domain obj,
then use libvirt-domain.c

> 
>>> + * This operation returns quickly, such that a user can choose to
>>> + * start a backup job between virDomainFSFreeze() and
>>> + * virDomainFSThaw() in order to create the backup while guest I/O is
>>> + * quiesced.
>>> + */
>>> +/* FIXME: Do we need a specific API for listing all current backup
>>> + * jobs (which, at the moment, is at most one job), or is it better to
>>> + * refactor other existing job APIs in libvirt-domain.c to have job-id
>>> + * counterparts along with a generic listing of all jobs (with flags
>>> + * for filtering to specific job types)?
>>> + */
>>
>> Or do we wait until some consumer asks for this? Do you mean
>> GetBlockJobInfo? GetJobStats? GetJobInfo?
>>
>> Is it required for initial implementation?  Not sure I'm expert enough
>> to answer that questions!
> 
> I've already had Nir asking for something; he also requested an ability
> to name jobs (he may use a UUID, but any name would work). My initial
> implementation was hard-coded to always create job id '1' (and what's
> the point of listing something, if the answer is either 'no job running'
> or 'job 1 is running').  But where things get tricky is that if we do
> NOT have an API for listing all jobs (even if there is just one possible
> job in the initial implementation), then it gets much harder to backport
> that API later. So yes, I _do_ need to get this implemented. I haven't
> got it up yet (my v5 posting will probably still have it lacking), but
> if I've missed 5.1, then I have enough time before 5.2 to definitely get
> that API tackled as part of everything else related to incremental backups.
> 

How much of that can be left for the future beyond 5.2. It seems more
requirements keep getting added and we cannot at least get something
going/pushed.

> 
>>> +/**
>>> + * virDomainBackupGetXMLDesc:
>>> + * @domain: a domain object
>>> + * @id: the id of an active backup job previously started with
>>> + *  virDomainBackupBegin()
>>> + * @flags: extra flags; not used yet, so callers should always pass 0
>>> + *
>>> + * In some cases, a user can start a backup job without supplying all
>>> + * details, and rely on libvirt to fill in the rest (for example,
>>
>> s/, and/ and/
>>
>>> + * selecting the port used for an NBD export). This API can then be
>>> + * used to learn what default values were chosen.
>>> + *
>>> + * Returns a NUL-terminated UTF-8 encoded XML instance, or NULL in
>>
>> s/, or/ or/
>>
>>> + * case of error.  The caller must free() the returned value.
>>> + */
>>
>> Do we have the same security concerns as Checkpoint?  IOW: One doesn't
>> necessarily have to use a conn that was used for virDomainBackupBegin or
>> do they?  Should we just check for a non read-only connection (which I
>> assume has implications later in remote.x defs).
> 
> The security concern for CheckpointGetXMLDesc is that the checkpoint XML
> includes a  sub-element, which must NOT expose any passwords in
> the  except on a read-write connection where the _SECURE flag is
> passed.
> 
> In the patches as posted so far, I separated the Checkpoint XML (with
> its  subelement) to be completely distinct from the Backup XML
> (which is very minimal, and just describes the job and perhaps a
>  name but not full XML); thus, there is nothing
> security-related in the output.
> 
> But I also asked the question in the cover letter if I should make
>  be a subelement of , in which case it
> should also be a subelement of a backup job (since both a backup job and
> a snapshot are logical places to atomically create a checkpoint at the
> same time).  And depending on how we answer that, then yes, anything
> that might expose a  sub-subelement (via a 
> sub-element of the backup job) would need the same _SECURE flag.
> 

OMG the cover letter - I wasn't even thinking about that at this point
let alone remember what I may have read ;-)

Not sure what the best answer would be. I can see overlap between the
two, but I really do "fear" there's some pieces of heavy weight in
snapshots that just would be so difficult to link directly as a parent
to a checkpoint.  As a lightweight piece, a checkpoint would be
something that both backup and 

Re: [libvirt] [PATCH v4 07/20] backup: Introduce virDomainCheckpoint APIs

2019-02-27 Thread John Ferlan



On 2/25/19 2:15 PM, Eric Blake wrote:
> On 2/11/19 3:19 PM, John Ferlan wrote:
>>
>>
>> On 2/6/19 2:18 PM, Eric Blake wrote:
>>> Introduce a bunch of new public APIs related to backup checkpoints.
>>> Checkpoints are modeled heavily after virDomainSnapshotPtr (both
>>> represent a point in time of the guest), although a snapshot exists
>>> with the intent of rolling back to that state, while a checkpoint
>>> exists to make it possible to create an incremental backup at a later
>>> time.
>>>
>>> The full list of new API:
>>> virDomainCheckpointCreateXML;
>>> virDomainCheckpointCurrent;
>>> virDomainCheckpointDelete;
>>> virDomainCheckpointFree;
>>> virDomainCheckpointGetConnect;
>>> virDomainCheckpointGetDomain;
>>> virDomainCheckpointGetParent;
>>> virDomainCheckpointGetXMLDesc;
>>> virDomainCheckpointHasMetadata;
>>> virDomainCheckpointIsCurrent;
>>> virDomainCheckpointListChildren;
>>> virDomainCheckpointLookupByName;
>>> virDomainCheckpointRef;
>>> virDomainHasCurrentCheckpoint;
>>> virDomainListCheckpoints;
>>> virDomainCheckpointGetName;
> 
>>
>> After reading and commenting further I came back here and started
>> wondering if we should just name this 'libvirt-domain-backup' since
>> checkpoint is part of backup... Then of course adjust various comments
>> accordingly to indicate checkpoint and backup.
>>
>> Of course there's also something to be said for separating out the
>> domain-backup API's into their own module too.
>>
>> So while you may see comments later about splitting just keep this
>> secondary thought in mind.
> 
> Long-term, I'd like to have both virDomainBackupBegin() and some form of
> virDomainSnapshotCreateXML() be able to kick off the creation of a
> checkpoint object. Object-wise, we have virDomainSnapshotPtr and
> virDomainCheckpointPtr (two distinct objects that are long-term XML
> entities present regardless of what else you do), but no
> virDomainBackupPtr (a backup job is just that - a job, that goes away
> when it is complete).  I'm actually thinking that it is better to have
> virDomainBackupBegin() and friends live directly in libvirt-domain.h,
> alongside other job-like APIs (virDomainMigrate(), virDomainBlockCopy(),
> ...), especially if I fix snapshots to refer to checkpoints.
> 
> So there's that to think about as well when considering where to place
> things.
> 

Makes sense to me to have BackupBegin live in libvirt-domain.h

Seems like merging Snapshot and Checkpoint code can be a "wishlist" type
task.

[...]

>>> @@ -1580,6 +1627,17 @@ struct _virHypervisorDriver {
>>>  virDrvConnectBaselineHypervisorCPU connectBaselineHypervisorCPU;
>>>  virDrvNodeGetSEVInfo nodeGetSEVInfo;
>>>  virDrvDomainGetLaunchSecurityInfo domainGetLaunchSecurityInfo;
>>> +virDrvDomainCheckpointCreateXML domainCheckpointCreateXML;
>>> +virDrvDomainCheckpointGetXMLDesc domainCheckpointGetXMLDesc;
>>> +virDrvDomainListCheckpoints domainListCheckpoints;
>>> +virDrvDomainCheckpointListChildren domainCheckpointListChildren;
>>> +virDrvDomainCheckpointLookupByName domainCheckpointLookupByName;
>>> +virDrvDomainHasCurrentCheckpoint domainHasCurrentCheckpoint;
>>> +virDrvDomainCheckpointGetParent domainCheckpointGetParent;
>>> +virDrvDomainCheckpointCurrent domainCheckpointCurrent;
>>> +virDrvDomainCheckpointIsCurrent domainCheckpointIsCurrent;
>>> +virDrvDomainCheckpointHasMetadata domainCheckpointHasMetadata;
>>> +virDrvDomainCheckpointDelete domainCheckpointDelete;
>>>  };
>>
>> Since we're adding new I think we should be consistent w/ naming
>>
>> virDrvDomainCheckpoint* and domainCheckpoint*
>>
>> DomainListCheckpoints and DomainHasCurrent break the mold, so to speak.
> 
> Here, I'm copying heavily from virDomainSnapshot. The APIs that deal
> directly with a virDomain object (namely, listing how many checkpoints
> belong to the domain, and whether the domain has a current checkpoint)
> are distinct from the APIs that deal with a virDomainCheckpointObject
> (creation, getting XML, looking up children). But you are also right
> that there are some other misleading names
> (virDomainCheckpointLookupByName and virDomainCheckpointCurrent are
> virDomain operations).

More recent changes to the hacking guide have some fairly specific
guidelines about API naming. That's where my thoughts were since this is
to a degree a new API set. But you made good points about consistency
between Snapshots and Checkpoints as children of the Domain. In a way I
see this as similar to how Volumes are a child of StoragePool objects.

When in doubt I fall back to Andrea's epiphany "Naming is hard".
Everyone seems to have an opinion or tweak to your chosen name. In the
long run, for me it's about consistency.

> 
> Here's what snapshots have, and how I differ:
> 
> virDomainSnapshotCreateXML;
> 

Re: [libvirt] [PATCH v4 06/20] backup: Document new XML for backups

2019-02-27 Thread John Ferlan
[...]

I placed reviewing other changes higher over returning to this series to
answer, agree with, provide feedback, etc. on anything that you
responded to. Also, trying to avoid doing too many things at one time.

So I'll just provide some extra thoughts and wait for v5. I think we're
at a point where nickle and diming over minutiae is taking too much time
away from getting something upstream as soon as possible.

>>> +++ b/tests/domaincheckpointxml2xmlout/empty.xml
>>> @@ -0,0 +1,10 @@
>>> +
>>> +  1525889631
>>> +  1525889631
>>> +  
>>> +
>>> +  
>>> +  
>>> +9d37b878-a7cc-9f9a-b78f-49b3abad25a8
>>
>> This looks strange without the name... and the domain type like the
>> sample.xml output has
> 
> Here's part of my reason for still having 'wip' on later patches - the
> snapshot code USED to just take a single UUID, until we released a
> couple of releases later that you can't revert to a domain state unless
> you capture the entire  at the point in time you plan to revert
> to (as hot-plug actions after that time must be rolled back for the
> reversion to be correct).  So the snapshot code has a horrible hack of
> taking either a UUID or a full  sub-element. I don't want to
> repeat that hack in  - I want a full  element every
> time.  But coming up with the absolute minimum  that does not
> make the test balloon into a super-long demonstration while still
> passing the RNG as a valid XML was where I got stuck, especially since
> the user does NOT pass in a  sublement except when using the
> _REDEFINE flag (the rest of the time, the  sublement is computed
> at creation time from the virDomainPtr that is gaining a new checkpoint).
> 

OK - makes sense with the additional details. Whatever you're
considering a minimum could just be added in.

> 
>>> +++ b/tests/domaincheckpointxml2xmlout/sample.xml
>>> @@ -0,0 +1,16 @@
>>> +
>>> +  1525889631
>>> +  Completion of updates after OS install
>>> +  1525889631
>>> +  
>>> +1525111885
>>> +  
>>> +  
>>> +
>>
>> Maybe this one should show the size attribute too...
> 
> No, I want size to be an output-only element, and one you have to pass
> in an additional flag to get (because it requires runtime computation,
> rather than a static output).

Fair enough. It was mostly a well let's cover all the bases type note.

> 
> Oh, and that reminds me of another long-standing yak hair - we
> introduced the ability to validate some of our XML against the RNG, but
> we have not finished wiring it up to all of the APIs that take XML.
> Domain snapshots don't have a validation flag, and hence my
> copy-and-paste code for checkpoints don't have one, but both need one.
> (Otherwise, the presence or absence of an ignored  element won't
> really matter whether the RNG permits or rejects it)
> 

So avoiding domain snapshot code isn't only something I've done then!

John

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


Re: [libvirt] [PATCH v1 00/15] Firmware auto selection

2019-02-27 Thread Kashyap Chamarthy
On Wed, Feb 27, 2019 at 11:04:32AM +0100, Michal Privoznik wrote:
> Libvirt allows specifying firmware for domains for quite some time now.
> However, problem for mgmt applications is that they do not know which
> firmware to chose as all they see are their paths and from that it's
> impossible to tell whether one of them supports say secure boot.
> 
> This problem was addressed by qemu where Lazslo and Daniel created a
> document, specification which describes metadata for each individual
> firmware image. In the description (which itself is a JSON file for easy
> machine parsing) then it's specified whether the firmware it's
> describing supports secureboot, s3/s4 states, it it's bios or efi, and
> so on.
> 
> These patches take advantage of that, and even though the description
> files are not picked up by that many distributions yet, it allows users
> to not care about putting specific firmware path into their domain XML.
> It's as easy as:
> 
>   
> 
>   

Nice, _much_ better than how certain management tools hard-code the path
to firmware binaries :-)

Thanks for working on this patch series.  I'll give them a spin sometime
this or early next week. 

> to have libvirt pick up OVMF image with secure enabled boot (and enabled
> System Management Mode at the same time).
> 
> The metadata specification lives under
> qemu.git/docs/interop/firmware.json and I highly recommend you go and
> read it before reviewing (unless you're Laszlo or Daniel in which case
> you already know what the document says).
> 
> As usual, you can find my patches at my github:
> 
>   https://github.com/zippy2/libvirt/commits/firmware_v1

[...]

-- 
/kashyap

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


Re: [libvirt] [PATCH] snapshot: Improve message for VIR_ERR_INVALID_DOMAIN_SNAPSHOT

2019-02-27 Thread Eric Blake
On 2/25/19 10:49 AM, Daniel P. Berrangé wrote:
> On Mon, Feb 25, 2019 at 10:40:00AM -0600, Eric Blake wrote:
>> For consistency with other error messages, and the fact that
>> the object is always called a virDomainSnapshot rather than
>> a mere virSnapshot, include the word "domain" in the error
>> message.
>>
>> Suggested-by: John Ferlan 
>> Signed-off-by: Eric Blake 
>> ---
>>  src/util/virerror.c | 4 ++--
>>  1 file changed, 2 insertions(+), 2 deletions(-)
> 
> Reviewed-by: Daniel P. Berrangé 

I'm assuming this one is safe for freeze, so I pushed it.

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

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

Re: [libvirt] [PATCH v2 5/7] snapshot: Rework virDomainSnapshotState enum

2019-02-27 Thread Eric Blake
On 2/27/19 2:04 PM, Eric Blake wrote:
> The existing virDomainSnapshotState is a superset of virDomainState,
> adding one more state (disk-snapshot) on top of valid domain states.
> But as written, the enum cannot be used for gcc validation that all
> enum values are covered in a strongly-typed switch condition, because
> the enum does not explicitly include the values it is adding to.
> 
> Copy the style used in qemu_blockjob.h of creating new enum names
> for every inherited value, and update all clients to use the new
> enum names anywhere snapshot state is referenced. Qemu code gains
> a fixme comment about some odd casts (which will be cleaned up in
> separate patches); the rest of the patch is mechanical.
> 
> Signed-off-by: Eric Blake 
> ---

> +/**
> + * This enum has to map all known domain states from the public enum
> + * virDomainState, before adding one additional state possible only
> + * for snapshots.
> + */
>  typedef enum {
> -/* Inherit the VIR_DOMAIN_* states from virDomainState.  */
> -VIR_DOMAIN_DISK_SNAPSHOT = VIR_DOMAIN_LAST,
> -VIR_DOMAIN_SNAPSHOT_STATE_LAST
> +/* Mapped to public enum */
> +VIR_SNAP_STATE_NOSTATE = VIR_DOMAIN_NOSTATE,
> +VIR_SNAP_STATE_RUNNING = VIR_DOMAIN_RUNNING,
> +VIR_SNAP_STATE_BLOCKED = VIR_DOMAIN_BLOCKED,
> +VIR_SNAP_STATE_PAUSED = VIR_DOMAIN_PAUSED,
> +VIR_SNAP_STATE_SHUTDOWN = VIR_DOMAIN_SHUTDOWN,
> +VIR_SNAP_STATE_SHUTOFF = VIR_DOMAIN_SHUTOFF,
> +VIR_SNAP_STATE_CRASHED = VIR_DOMAIN_CRASHED,
> +VIR_SNAP_STATE_PMSUSPENDED = VIR_DOMAIN_PMSUSPENDED,
> +/* Additional enum values local to qemu */

Too much copy-and-paste from qemu_blockjob.h; this comment should
mention 'local to snapshots'

> +VIR_SNAP_STATE_DISK_SNAPSHOT,
> +VIR_SNAP_STATE_LAST
>  } virDomainSnapshotState;
> +verify((int)VIR_SNAP_STATE_DISK_SNAPSHOT == VIR_DOMAIN_LAST);
> 


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

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


[libvirt] [PATCH v2 5/7] snapshot: Rework virDomainSnapshotState enum

2019-02-27 Thread Eric Blake
The existing virDomainSnapshotState is a superset of virDomainState,
adding one more state (disk-snapshot) on top of valid domain states.
But as written, the enum cannot be used for gcc validation that all
enum values are covered in a strongly-typed switch condition, because
the enum does not explicitly include the values it is adding to.

Copy the style used in qemu_blockjob.h of creating new enum names
for every inherited value, and update all clients to use the new
enum names anywhere snapshot state is referenced. Qemu code gains
a fixme comment about some odd casts (which will be cleaned up in
separate patches); the rest of the patch is mechanical.

Signed-off-by: Eric Blake 
---
 src/conf/snapshot_conf.h | 21 ++---
 src/conf/snapshot_conf.c | 28 ++--
 src/qemu/qemu_driver.c   | 27 ---
 src/test/test_driver.c   | 20 ++--
 src/vbox/vbox_common.c   |  4 ++--
 5 files changed, 60 insertions(+), 40 deletions(-)

diff --git a/src/conf/snapshot_conf.h b/src/conf/snapshot_conf.h
index 7a175dfc96..9084f5fb8b 100644
--- a/src/conf/snapshot_conf.h
+++ b/src/conf/snapshot_conf.h
@@ -36,11 +36,26 @@ typedef enum {
 VIR_DOMAIN_SNAPSHOT_LOCATION_LAST
 } virDomainSnapshotLocation;

+/**
+ * This enum has to map all known domain states from the public enum
+ * virDomainState, before adding one additional state possible only
+ * for snapshots.
+ */
 typedef enum {
-/* Inherit the VIR_DOMAIN_* states from virDomainState.  */
-VIR_DOMAIN_DISK_SNAPSHOT = VIR_DOMAIN_LAST,
-VIR_DOMAIN_SNAPSHOT_STATE_LAST
+/* Mapped to public enum */
+VIR_SNAP_STATE_NOSTATE = VIR_DOMAIN_NOSTATE,
+VIR_SNAP_STATE_RUNNING = VIR_DOMAIN_RUNNING,
+VIR_SNAP_STATE_BLOCKED = VIR_DOMAIN_BLOCKED,
+VIR_SNAP_STATE_PAUSED = VIR_DOMAIN_PAUSED,
+VIR_SNAP_STATE_SHUTDOWN = VIR_DOMAIN_SHUTDOWN,
+VIR_SNAP_STATE_SHUTOFF = VIR_DOMAIN_SHUTOFF,
+VIR_SNAP_STATE_CRASHED = VIR_DOMAIN_CRASHED,
+VIR_SNAP_STATE_PMSUSPENDED = VIR_DOMAIN_PMSUSPENDED,
+/* Additional enum values local to qemu */
+VIR_SNAP_STATE_DISK_SNAPSHOT,
+VIR_SNAP_STATE_LAST
 } virDomainSnapshotState;
+verify((int)VIR_SNAP_STATE_DISK_SNAPSHOT == VIR_DOMAIN_LAST);

 /* Stores disk-snapshot information */
 typedef struct _virDomainSnapshotDiskDef virDomainSnapshotDiskDef;
diff --git a/src/conf/snapshot_conf.c b/src/conf/snapshot_conf.c
index 41236d9932..299fc2101b 100644
--- a/src/conf/snapshot_conf.c
+++ b/src/conf/snapshot_conf.c
@@ -58,7 +58,7 @@ VIR_ENUM_IMPL(virDomainSnapshotLocation, 
VIR_DOMAIN_SNAPSHOT_LOCATION_LAST,
 );

 /* virDomainSnapshotState is really virDomainState plus one extra state */
-VIR_ENUM_IMPL(virDomainSnapshotState, VIR_DOMAIN_SNAPSHOT_STATE_LAST,
+VIR_ENUM_IMPL(virDomainSnapshotState, VIR_SNAP_STATE_LAST,
   "nostate",
   "running",
   "blocked",
@@ -257,8 +257,8 @@ virDomainSnapshotDefParse(xmlXPathContextPtr ctxt,
state);
 goto cleanup;
 }
-offline = (def->state == VIR_DOMAIN_SHUTOFF ||
-   def->state == VIR_DOMAIN_DISK_SNAPSHOT);
+offline = (def->state == VIR_SNAP_STATE_SHUTOFF ||
+   def->state == VIR_SNAP_STATE_DISK_SNAPSHOT);

 /* Older snapshots were created with just /, and
  * lack domain/@type.  In that case, leave dom NULL, and
@@ -879,14 +879,14 @@ static int virDomainSnapshotObjListCopyNames(void 
*payload,

 if (data->flags & VIR_DOMAIN_SNAPSHOT_FILTERS_STATUS) {
 if (!(data->flags & VIR_DOMAIN_SNAPSHOT_LIST_INACTIVE) &&
-obj->def->state == VIR_DOMAIN_SHUTOFF)
+obj->def->state == VIR_SNAP_STATE_SHUTOFF)
 return 0;
 if (!(data->flags & VIR_DOMAIN_SNAPSHOT_LIST_DISK_ONLY) &&
-obj->def->state == VIR_DOMAIN_DISK_SNAPSHOT)
+obj->def->state == VIR_SNAP_STATE_DISK_SNAPSHOT)
 return 0;
 if (!(data->flags & VIR_DOMAIN_SNAPSHOT_LIST_ACTIVE) &&
-obj->def->state != VIR_DOMAIN_SHUTOFF &&
-obj->def->state != VIR_DOMAIN_DISK_SNAPSHOT)
+obj->def->state != VIR_SNAP_STATE_SHUTOFF &&
+obj->def->state != VIR_SNAP_STATE_DISK_SNAPSHOT)
 return 0;
 }

@@ -1225,7 +1225,7 @@ virDomainSnapshotRedefinePrep(virDomainPtr domain,
 int align_location = VIR_DOMAIN_SNAPSHOT_LOCATION_INTERNAL;
 bool align_match = true;
 virDomainSnapshotObjPtr other;
-bool external = def->state == VIR_DOMAIN_DISK_SNAPSHOT ||
+bool external = def->state == VIR_SNAP_STATE_DISK_SNAPSHOT ||
 virDomainSnapshotDefIsExternal(def);

 /* Prevent circular chains */
@@ -1282,10 +1282,10 @@ virDomainSnapshotRedefinePrep(virDomainPtr domain,

 other = virDomainSnapshotFindByName(vm->snapshots, def->name);
 if (other) {
-if ((other->def->state == VIR_DOMAIN_RUNNING ||
- other->def->state == VIR_DOMAIN_PAUSED) !=
-

[libvirt] [PATCH v2 6/7] qemu: Use virDomainSnapshotState for switch statements

2019-02-27 Thread Eric Blake
Clean up the previous patch which abused a switch on virDomainState
when contrasted to a variable containing virDomainSnapshotState, by
converting the two affected switch statements to now use the right
enum.  No semantic changes now (the caller to qemuDomainSnapshotValidate
passes in a domain state rather than a snapshot state, so the new
branch is currently unreachable [will change in next patch], while
qemuDomainRevertToSnapshot can't reach the new state because of the
earlier rejection of external images).

Signed-off-by: Eric Blake 
---
 src/qemu/qemu_driver.c | 57 +++---
 1 file changed, 31 insertions(+), 26 deletions(-)

diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c
index 34014ba9c7..06bc1893ad 100644
--- a/src/qemu/qemu_driver.c
+++ b/src/qemu/qemu_driver.c
@@ -15700,27 +15700,35 @@ qemuDomainSnapshotValidate(virDomainSnapshotDefPtr 
def, int state,
 }

 /* allow snapshots only in certain states */
-switch ((virDomainState) state) {
+switch ((virDomainSnapshotState) state) {
 /* valid states */
-case VIR_DOMAIN_RUNNING:
-case VIR_DOMAIN_PAUSED:
-case VIR_DOMAIN_SHUTDOWN:
-case VIR_DOMAIN_SHUTOFF:
-case VIR_DOMAIN_CRASHED:
+case VIR_SNAP_STATE_RUNNING:
+case VIR_SNAP_STATE_PAUSED:
+case VIR_SNAP_STATE_SHUTDOWN:
+case VIR_SNAP_STATE_SHUTOFF:
+case VIR_SNAP_STATE_CRASHED:
 break;

-case VIR_DOMAIN_PMSUSPENDED:
+case VIR_SNAP_STATE_DISK_SNAPSHOT:
+if (!(flags & VIR_DOMAIN_SNAPSHOT_CREATE_REDEFINE)) {
+virReportError(VIR_ERR_INTERNAL_ERROR, _("Invalid domain state 
%s"),
+   virDomainSnapshotStateTypeToString(state));
+return -1;
+}
+break;
+
+case VIR_SNAP_STATE_PMSUSPENDED:
 virReportError(VIR_ERR_OPERATION_UNSUPPORTED, "%s",
_("qemu doesn't support taking snapshots of "
  "PMSUSPENDED guests"));
 return -1;

 /* invalid states */
-case VIR_DOMAIN_NOSTATE:
-case VIR_DOMAIN_BLOCKED: /* invalid state, unused in qemu */
-case VIR_DOMAIN_LAST:
+case VIR_SNAP_STATE_NOSTATE:
+case VIR_SNAP_STATE_BLOCKED: /* invalid state, unused in qemu */
+case VIR_SNAP_STATE_LAST:
 virReportError(VIR_ERR_INTERNAL_ERROR, _("Invalid domain state %s"),
-   virDomainStateTypeToString(state));
+   virDomainSnapshotStateTypeToString(state));
 return -1;
 }
 return 0;
@@ -16487,14 +16495,9 @@ qemuDomainRevertToSnapshot(virDomainSnapshotPtr 
snapshot,

 cookie = (qemuDomainSaveCookiePtr) snap->def->cookie;

-/* FIXME: This cast should be to virDomainSnapshotState, with
- * better handling of VIR_SNAP_STATE_DISK_SNAPSHOT (the only enum
- * value added beyond what virDomainState supports). But for now
- * it doesn't matter, because of the above rejection of revert to
- * external snapshots. */
-switch ((virDomainState) snap->def->state) {
-case VIR_DOMAIN_RUNNING:
-case VIR_DOMAIN_PAUSED:
+switch ((virDomainSnapshotState) snap->def->state) {
+case VIR_SNAP_STATE_RUNNING:
+case VIR_SNAP_STATE_PAUSED:

 start_flags |= VIR_QEMU_PROCESS_START_PAUSED;

@@ -16669,9 +16672,9 @@ qemuDomainRevertToSnapshot(virDomainSnapshotPtr 
snapshot,
 }
 break;

-case VIR_DOMAIN_SHUTDOWN:
-case VIR_DOMAIN_SHUTOFF:
-case VIR_DOMAIN_CRASHED:
+case VIR_SNAP_STATE_SHUTDOWN:
+case VIR_SNAP_STATE_SHUTOFF:
+case VIR_SNAP_STATE_CRASHED:
 /* Transitions 1, 4, 7 */
 /* Newer qemu -loadvm refuses to revert to the state of a snapshot
  * created by qemu-img snapshot -c.  If the domain is running, we
@@ -16728,15 +16731,17 @@ qemuDomainRevertToSnapshot(virDomainSnapshotPtr 
snapshot,
 }
 break;

-case VIR_DOMAIN_PMSUSPENDED:
+case VIR_SNAP_STATE_PMSUSPENDED:
 virReportError(VIR_ERR_OPERATION_UNSUPPORTED, "%s",
_("qemu doesn't support reversion of snapshot taken in "
  "PMSUSPENDED state"));
 goto endjob;

-case VIR_DOMAIN_NOSTATE:
-case VIR_DOMAIN_BLOCKED:
-case VIR_DOMAIN_LAST:
+case VIR_SNAP_STATE_DISK_SNAPSHOT:
+/* Rejected earlier as an external snapshot */
+case VIR_SNAP_STATE_NOSTATE:
+case VIR_SNAP_STATE_BLOCKED:
+case VIR_SNAP_STATE_LAST:
 virReportError(VIR_ERR_INTERNAL_ERROR,
_("Invalid target domain state '%s'. Refusing "
  "snapshot reversion"),
-- 
2.20.1

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


[libvirt] [PATCH variant2 v2 7/7] qemu: Fix snapshot redefine vs. domain state bug

2019-02-27 Thread Eric Blake
The existing qemu snapshot code has a slight bug: if the domain
is currently pmsuspended, you can't use the _REDEFINE flag even
though the current domain state should have no bearing on being
able to recreate metadata state; and conversely, you can use the
_REDEFINE flag to create snapshot metadata claiming to be
pmsuspended as a bypass to the normal restrictions that you can't
create an original qemu snapshot in that state (the restriction
against pmsuspend is specific to qemu, rather than part of the
driver-agnostic snapshot_conf code).

Fix this by checking the snapshot state (when redefining) instead
of the domain state (which is a subset of snapshot states).

Fixes the second problem mentioned in https://bugzilla.redhat.com/1680304

Signed-off-by: Eric Blake 
---
 src/qemu/qemu_driver.c | 7 +--
 1 file changed, 5 insertions(+), 2 deletions(-)

diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c
index 06bc1893ad..18acdd9816 100644
--- a/src/qemu/qemu_driver.c
+++ b/src/qemu/qemu_driver.c
@@ -15674,7 +15674,9 @@ qemuDomainSnapshotCreateActiveExternal(virQEMUDriverPtr 
driver,


 /* Validate that a snapshot object does not violate any qemu-specific
- * constraints. */
+ * constraints. @state is virDomainState if flags implies creation, or
+ * virDomainSnapshotState if flags includes _REDEFINE (the latter
+ * enum is a superset of the former). */
 static int
 qemuDomainSnapshotValidate(virDomainSnapshotDefPtr def, int state,
unsigned int flags)
@@ -15808,7 +15810,8 @@ qemuDomainSnapshotCreateXML(virDomainPtr domain,
 parse_flags)))
 goto cleanup;

-if (qemuDomainSnapshotValidate(def, vm->state.state, flags) < 0)
+if (qemuDomainSnapshotValidate(def, redefine ? def->state : 
vm->state.state,
+   flags) < 0)
 goto cleanup;

 /* reject the VIR_DOMAIN_SNAPSHOT_CREATE_LIVE flag where not supported */
-- 
2.20.1

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


[libvirt] [PATCH v2 2/7] DO NOT MERGE: Revert "qemu: Fix snapshot redefine vs. domain state bug"

2019-02-27 Thread Eric Blake
This reverts commit a6ecf44211ec62786dc1dc6ff30f1c7ea1a18f8b.
---
 src/qemu/qemu_driver.c | 9 ++---
 1 file changed, 2 insertions(+), 7 deletions(-)

diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c
index 36426cd65a..1d5b5f8653 100644
--- a/src/qemu/qemu_driver.c
+++ b/src/qemu/qemu_driver.c
@@ -15693,7 +15693,6 @@ qemuDomainSnapshotCreateXML(virDomainPtr domain,
 virQEMUDriverConfigPtr cfg = NULL;
 virCapsPtr caps = NULL;
 qemuDomainObjPrivatePtr priv;
-virDomainState state;

 virCheckFlags(VIR_DOMAIN_SNAPSHOT_CREATE_REDEFINE |
   VIR_DOMAIN_SNAPSHOT_CREATE_CURRENT |
@@ -15777,11 +15776,7 @@ qemuDomainSnapshotCreateXML(virDomainPtr domain,
 }

 /* allow snapshots only in certain states */
-state = vm->state.state;
-if (redefine)
-state = def->state == VIR_DOMAIN_DISK_SNAPSHOT ? VIR_DOMAIN_SHUTOFF :
-def->state;
-switch (state) {
+switch ((virDomainState) vm->state.state) {
 /* valid states */
 case VIR_DOMAIN_RUNNING:
 case VIR_DOMAIN_PAUSED:
@@ -15801,7 +15796,7 @@ qemuDomainSnapshotCreateXML(virDomainPtr domain,
 case VIR_DOMAIN_BLOCKED: /* invalid state, unused in qemu */
 case VIR_DOMAIN_LAST:
 virReportError(VIR_ERR_INTERNAL_ERROR, _("Invalid domain state %s"),
-   virDomainStateTypeToString(state));
+   virDomainStateTypeToString(vm->state.state));
 goto cleanup;
 }

-- 
2.20.1

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


[libvirt] [PATCH variant1 v2 1/7] qemu: Fix snapshot redefine vs. domain state bug

2019-02-27 Thread Eric Blake
The existing qemu snapshot code has a slight bug: if the domain
is currently pmsuspended, you can't use the _REDEFINE flag even
though the current domain state should have no bearing on being
able to recreate metadata state; and conversely, you can use the
_REDEFINE flag to create snapshot metadata claiming to be
pmsuspended as a bypass to the normal restrictions that you can't
create an original qemu snapshot in that state (the restriction
against pmsuspend is specific to qemu, rather than part of the
driver-agnostic snapshot_conf code).

Fix this by checking the snapshot state (when redefining) instead
of the domain state (which is a subset of snapshot states).

Fixes the second problem mentioned in https://bugzilla.redhat.com/1680304

Signed-off-by: Eric Blake 
---
 src/qemu/qemu_driver.c | 9 +++--
 1 file changed, 7 insertions(+), 2 deletions(-)

diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c
index 1d5b5f8653..36426cd65a 100644
--- a/src/qemu/qemu_driver.c
+++ b/src/qemu/qemu_driver.c
@@ -15693,6 +15693,7 @@ qemuDomainSnapshotCreateXML(virDomainPtr domain,
 virQEMUDriverConfigPtr cfg = NULL;
 virCapsPtr caps = NULL;
 qemuDomainObjPrivatePtr priv;
+virDomainState state;

 virCheckFlags(VIR_DOMAIN_SNAPSHOT_CREATE_REDEFINE |
   VIR_DOMAIN_SNAPSHOT_CREATE_CURRENT |
@@ -15776,7 +15777,11 @@ qemuDomainSnapshotCreateXML(virDomainPtr domain,
 }

 /* allow snapshots only in certain states */
-switch ((virDomainState) vm->state.state) {
+state = vm->state.state;
+if (redefine)
+state = def->state == VIR_DOMAIN_DISK_SNAPSHOT ? VIR_DOMAIN_SHUTOFF :
+def->state;
+switch (state) {
 /* valid states */
 case VIR_DOMAIN_RUNNING:
 case VIR_DOMAIN_PAUSED:
@@ -15796,7 +15801,7 @@ qemuDomainSnapshotCreateXML(virDomainPtr domain,
 case VIR_DOMAIN_BLOCKED: /* invalid state, unused in qemu */
 case VIR_DOMAIN_LAST:
 virReportError(VIR_ERR_INTERNAL_ERROR, _("Invalid domain state %s"),
-   virDomainStateTypeToString(vm->state.state));
+   virDomainStateTypeToString(state));
 goto cleanup;
 }

-- 
2.20.1

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


[libvirt] [PATCH v2 4/7] qemu: Factor out qemuDomainSnapshotValidate() helper

2019-02-27 Thread Eric Blake
Straight code motion, coupled with changing goto into return -1
as needed. This change will be important to later patches adding
bulk redefinition (where each snapshot in a list has to meet the
same constraints), but moving it out now also makes it easier
for a more immediate bug-fix related to which states are being
validated in the next patch.

Signed-off-by: Eric Blake 
---
 src/qemu/qemu_driver.c | 99 +++---
 1 file changed, 55 insertions(+), 44 deletions(-)

diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c
index 4869096273..a8ac9b59ee 100644
--- a/src/qemu/qemu_driver.c
+++ b/src/qemu/qemu_driver.c
@@ -15673,6 +15673,59 @@ 
qemuDomainSnapshotCreateActiveExternal(virQEMUDriverPtr driver,
 }


+/* Validate that a snapshot object does not violate any qemu-specific
+ * constraints. */
+static int
+qemuDomainSnapshotValidate(virDomainSnapshotDefPtr def, int state,
+   unsigned int flags)
+{
+/* reject snapshot names containing slashes or starting with dot as
+ * snapshot definitions are saved in files named by the snapshot name */
+if (!(flags & VIR_DOMAIN_SNAPSHOT_CREATE_NO_METADATA)) {
+if (strchr(def->name, '/')) {
+virReportError(VIR_ERR_XML_DETAIL,
+   _("invalid snapshot name '%s': "
+ "name can't contain '/'"),
+   def->name);
+return -1;
+}
+
+if (def->name[0] == '.') {
+virReportError(VIR_ERR_XML_DETAIL,
+   _("invalid snapshot name '%s': "
+ "name can't start with '.'"),
+   def->name);
+return -1;
+}
+}
+
+/* allow snapshots only in certain states */
+switch ((virDomainState) state) {
+/* valid states */
+case VIR_DOMAIN_RUNNING:
+case VIR_DOMAIN_PAUSED:
+case VIR_DOMAIN_SHUTDOWN:
+case VIR_DOMAIN_SHUTOFF:
+case VIR_DOMAIN_CRASHED:
+break;
+
+case VIR_DOMAIN_PMSUSPENDED:
+virReportError(VIR_ERR_OPERATION_UNSUPPORTED, "%s",
+   _("qemu doesn't support taking snapshots of "
+ "PMSUSPENDED guests"));
+return -1;
+
+/* invalid states */
+case VIR_DOMAIN_NOSTATE:
+case VIR_DOMAIN_BLOCKED: /* invalid state, unused in qemu */
+case VIR_DOMAIN_LAST:
+virReportError(VIR_ERR_INTERNAL_ERROR, _("Invalid domain state %s"),
+   virDomainStateTypeToString(state));
+return -1;
+}
+return 0;
+}
+
 static virDomainSnapshotPtr
 qemuDomainSnapshotCreateXML(virDomainPtr domain,
 const char *xmlDesc,
@@ -15747,25 +15800,8 @@ qemuDomainSnapshotCreateXML(virDomainPtr domain,
 parse_flags)))
 goto cleanup;

-/* reject snapshot names containing slashes or starting with dot as
- * snapshot definitions are saved in files named by the snapshot name */
-if (!(flags & VIR_DOMAIN_SNAPSHOT_CREATE_NO_METADATA)) {
-if (strchr(def->name, '/')) {
-virReportError(VIR_ERR_XML_DETAIL,
-   _("invalid snapshot name '%s': "
- "name can't contain '/'"),
-   def->name);
-goto cleanup;
-}
-
-if (def->name[0] == '.') {
-virReportError(VIR_ERR_XML_DETAIL,
-   _("invalid snapshot name '%s': "
- "name can't start with '.'"),
-   def->name);
-goto cleanup;
-}
-}
+if (qemuDomainSnapshotValidate(def, vm->state.state, flags) < 0)
+goto cleanup;

 /* reject the VIR_DOMAIN_SNAPSHOT_CREATE_LIVE flag where not supported */
 if (flags & VIR_DOMAIN_SNAPSHOT_CREATE_LIVE &&
@@ -15777,31 +15813,6 @@ qemuDomainSnapshotCreateXML(virDomainPtr domain,
 goto cleanup;
 }

-/* allow snapshots only in certain states */
-switch ((virDomainState) vm->state.state) {
-/* valid states */
-case VIR_DOMAIN_RUNNING:
-case VIR_DOMAIN_PAUSED:
-case VIR_DOMAIN_SHUTDOWN:
-case VIR_DOMAIN_SHUTOFF:
-case VIR_DOMAIN_CRASHED:
-break;
-
-case VIR_DOMAIN_PMSUSPENDED:
-virReportError(VIR_ERR_OPERATION_UNSUPPORTED, "%s",
-   _("qemu doesn't support taking snapshots of "
- "PMSUSPENDED guests"));
-goto cleanup;
-
-/* invalid states */
-case VIR_DOMAIN_NOSTATE:
-case VIR_DOMAIN_BLOCKED: /* invalid state, unused in qemu */
-case VIR_DOMAIN_LAST:
-virReportError(VIR_ERR_INTERNAL_ERROR, _("Invalid domain state %s"),
-   virDomainStateTypeToString(vm->state.state));
-goto cleanup;
-}
-
 /* We are going to modify the domain below. Internal snapshots would use
  * a regular job, 

[libvirt] [PATCH v2 3/7] qemu: Refactor check for _LIVE vs. _REDEFINE

2019-02-27 Thread Eric Blake
The current qemu code rejects the combination of the two flags
VIR_DOMAIN_SNAPSHOT_CREATE_LIVE in tandem with
VIR_DOMAIN_SNAPSHOT_CREATE_REDEFINE, but rather late in the cycle
(after the snapshot was already parsed), and with a rather confusing
message (complaining that live snapshots require external storage,
even if the redefined snapshot already declares external storage).
Hoist the rejection message to occur earlier (before parsing any
XML, which also aids upcoming patches that will implement bulk
redefine), and with a more typical error message about mutually
exclusive flags.

Signed-off-by: Eric Blake 
---
 src/qemu/qemu_driver.c | 6 --
 1 file changed, 4 insertions(+), 2 deletions(-)

diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c
index 1d5b5f8653..4869096273 100644
--- a/src/qemu/qemu_driver.c
+++ b/src/qemu/qemu_driver.c
@@ -15707,6 +15707,9 @@ qemuDomainSnapshotCreateXML(virDomainPtr domain,
 VIR_REQUIRE_FLAG_RET(VIR_DOMAIN_SNAPSHOT_CREATE_QUIESCE,
  VIR_DOMAIN_SNAPSHOT_CREATE_DISK_ONLY,
  NULL);
+VIR_EXCLUSIVE_FLAGS_RET(VIR_DOMAIN_SNAPSHOT_CREATE_LIVE,
+VIR_DOMAIN_SNAPSHOT_CREATE_REDEFINE,
+NULL);

 if ((redefine && !(flags & VIR_DOMAIN_SNAPSHOT_CREATE_CURRENT)) ||
 (flags & VIR_DOMAIN_SNAPSHOT_CREATE_NO_METADATA))
@@ -15767,8 +15770,7 @@ qemuDomainSnapshotCreateXML(virDomainPtr domain,
 /* reject the VIR_DOMAIN_SNAPSHOT_CREATE_LIVE flag where not supported */
 if (flags & VIR_DOMAIN_SNAPSHOT_CREATE_LIVE &&
 (!virDomainObjIsActive(vm) ||
- def->memory != VIR_DOMAIN_SNAPSHOT_LOCATION_EXTERNAL ||
- redefine)) {
+ def->memory != VIR_DOMAIN_SNAPSHOT_LOCATION_EXTERNAL)) {
 virReportError(VIR_ERR_OPERATION_UNSUPPORTED, "%s",
_("live snapshot creation is supported only "
  "during full system snapshots"));
-- 
2.20.1

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


[libvirt] [PATCH v2 0/7] fix snapshot --redefine bugs (incremental backup saga)

2019-02-27 Thread Eric Blake
John pointed out that patch 2 of my original bug fix did too
much in one patch. Now that we are in freeze for 5.1, I've
proposed two variants of the same fix: patch 1 is the bare
minimum to fix the bug and nothing else, while patches 3-7
are more in line with my v1 patch at doing other refactoring
work along the way (but now split into multiple logical steps)
that will prove useful for my other pending snapshot improvements
(https://www.redhat.com/archives/libvir-list/2019-February/msg01350.html,
but now 5.2 material).

I'm proposing both variants for comparison, although I already
suspect the answer will be 'use patch 1 for 5.1, then rebase
what remains of patches 3-7 into the other snapshot cleanups
for 5.2'.

variant2 is cleaner than my v1 patch 2/2 in that I no longer have
to use a default: label to hack around gcc's enum sanity checking
within a switch statement, but it required introducing a large
mechanical rename of all use of snapshot state values.

Eric Blake (7):
  qemu: Fix snapshot redefine vs. domain state bug
  Revert "qemu: Fix snapshot redefine vs. domain state bug"
  qemu: Refactor check for _LIVE vs. _REDEFINE
  qemu: Factor out qemuDomainSnapshotValidate() helper
  snapshot: Rework virDomainSnapshotState enum
  qemu: Use virDomainSnapshotState for switch statements
  qemu: Fix snapshot redefine vs. domain state bug

 src/conf/snapshot_conf.h |  21 -
 src/conf/snapshot_conf.c |  28 +++
 src/qemu/qemu_driver.c   | 160 +++
 src/test/test_driver.c   |  20 ++---
 src/vbox/vbox_common.c   |   4 +-
 5 files changed, 137 insertions(+), 96 deletions(-)

-- 
2.20.1

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


[libvirt] [PATCH 2/2] qemu: Allow creating ppc64 guests with graphics and no USB mouse

2019-02-27 Thread Andrea Bolognani
The existing behavior for ppc64 guests is to always add a USB
keyboard and mouse combo if graphics are present; unfortunately,
this means any attempt to use a USB tablet will cause both pointing
devices to show up in the guest, which in turn will result in poor
user experience.

We can't just stop adding the USB mouse or start adding a USB tablet
instead, because existing applications and user might rely on the
current behavior; however, we can avoid adding the USB mouse if a USB
tablet is already present, thus allowing users and applications to
create guests that contain a single pointing device.

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

Signed-off-by: Andrea Bolognani 
---
 src/qemu/qemu_domain.c| 20 +++
 .../ppc64-pseries-graphics.ppc64-latest.args  |  1 -
 2 files changed, 20 insertions(+), 1 deletion(-)

diff --git a/src/qemu/qemu_domain.c b/src/qemu/qemu_domain.c
index 59fe1eb401..915795ab84 100644
--- a/src/qemu/qemu_domain.c
+++ b/src/qemu/qemu_domain.c
@@ -3476,6 +3476,26 @@ qemuDomainDefAddDefaultDevices(virDomainDefPtr def,
 virQEMUCapsGet(qemuCaps, QEMU_CAPS_VIRTIO_S390) && def->memballoon)
 def->memballoon->model = VIR_DOMAIN_MEMBALLOON_MODEL_NONE;
 
+if (addDefaultUSBMouse) {
+bool hasUSBTablet = false;
+size_t j;
+
+for (j = 0; j < def->ninputs; j++) {
+if (def->inputs[j]->type == VIR_DOMAIN_INPUT_TYPE_TABLET &&
+def->inputs[j]->bus == VIR_DOMAIN_INPUT_BUS_USB) {
+hasUSBTablet = true;
+break;
+}
+}
+
+/* Historically, we have automatically added USB keyboard and
+ * mouse to some guests. While the former device is generally
+ * safe to have, adding the latter is undesiderable if a USB
+ * tablet is already present in the guest */
+if (hasUSBTablet)
+addDefaultUSBMouse = false;
+}
+
 if (addDefaultUSBKBD &&
 def->ngraphics > 0 &&
 virDomainDefMaybeAddInput(def,
diff --git a/tests/qemuxml2argvdata/ppc64-pseries-graphics.ppc64-latest.args 
b/tests/qemuxml2argvdata/ppc64-pseries-graphics.ppc64-latest.args
index 1c6c25ed24..b81648f078 100644
--- a/tests/qemuxml2argvdata/ppc64-pseries-graphics.ppc64-latest.args
+++ b/tests/qemuxml2argvdata/ppc64-pseries-graphics.ppc64-latest.args
@@ -37,7 +37,6 @@ addr=0x1 \
 id=channel0,name=org.qemu.guest_agent.0 \
 -device usb-tablet,id=input0,bus=usb.0,port=1 \
 -device usb-kbd,id=input1,bus=usb.0,port=2 \
--device usb-mouse,id=input2,bus=usb.0,port=3 \
 -vnc 127.0.0.1:0 \
 -device VGA,id=video0,vgamem_mb=16,bus=pci.0,addr=0x7 \
 -device virtio-balloon-pci,id=balloon0,bus=pci.0,addr=0x5 \
-- 
2.20.1

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


[libvirt] [PATCH 0/2] qemu: Allow creating ppc64 guests with graphics and no USB mouse

2019-02-27 Thread Andrea Bolognani
See patch 2/2.

Andrea Bolognani (2):
  tests: Add simple guests with graphics to qemuxml2argv
  qemu: Allow creating ppc64 guests with graphics and no USB mouse

 src/qemu/qemu_domain.c| 20 +++
 .../aarch64-virt-graphics.aarch64-latest.args | 59 +++
 .../aarch64-virt-graphics.xml | 50 
 .../ppc64-pseries-graphics.ppc64-latest.args  | 47 +++
 .../ppc64-pseries-graphics.xml| 44 ++
 .../x86_64-pc-graphics.x86_64-latest.args | 51 
 tests/qemuxml2argvdata/x86_64-pc-graphics.xml | 55 +
 .../x86_64-q35-graphics.x86_64-latest.args| 59 +++
 .../qemuxml2argvdata/x86_64-q35-graphics.xml  | 55 +
 tests/qemuxml2argvtest.c  |  6 ++
 10 files changed, 446 insertions(+)
 create mode 100644 
tests/qemuxml2argvdata/aarch64-virt-graphics.aarch64-latest.args
 create mode 100644 tests/qemuxml2argvdata/aarch64-virt-graphics.xml
 create mode 100644 
tests/qemuxml2argvdata/ppc64-pseries-graphics.ppc64-latest.args
 create mode 100644 tests/qemuxml2argvdata/ppc64-pseries-graphics.xml
 create mode 100644 tests/qemuxml2argvdata/x86_64-pc-graphics.x86_64-latest.args
 create mode 100644 tests/qemuxml2argvdata/x86_64-pc-graphics.xml
 create mode 100644 
tests/qemuxml2argvdata/x86_64-q35-graphics.x86_64-latest.args
 create mode 100644 tests/qemuxml2argvdata/x86_64-q35-graphics.xml

-- 
2.20.1

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


[libvirt] [PATCH 1/2] tests: Add simple guests with graphics to qemuxml2argv

2019-02-27 Thread Andrea Bolognani
These are similar to the existing simple headless guests, but
also include a graphical output and some input devices.

Input files were generated by running

  $ virt-install \
--name guest --os-variant fedora29 \
--vcpus 4 --memory 4096 --disk size=5 \
--graphics vnc \
--print-xml

followed by minor tweaks.

Signed-off-by: Andrea Bolognani 
---
 .../aarch64-virt-graphics.aarch64-latest.args | 59 +++
 .../aarch64-virt-graphics.xml | 50 
 .../ppc64-pseries-graphics.ppc64-latest.args  | 48 +++
 .../ppc64-pseries-graphics.xml| 44 ++
 .../x86_64-pc-graphics.x86_64-latest.args | 51 
 tests/qemuxml2argvdata/x86_64-pc-graphics.xml | 55 +
 .../x86_64-q35-graphics.x86_64-latest.args| 59 +++
 .../qemuxml2argvdata/x86_64-q35-graphics.xml  | 55 +
 tests/qemuxml2argvtest.c  |  6 ++
 9 files changed, 427 insertions(+)
 create mode 100644 
tests/qemuxml2argvdata/aarch64-virt-graphics.aarch64-latest.args
 create mode 100644 tests/qemuxml2argvdata/aarch64-virt-graphics.xml
 create mode 100644 
tests/qemuxml2argvdata/ppc64-pseries-graphics.ppc64-latest.args
 create mode 100644 tests/qemuxml2argvdata/ppc64-pseries-graphics.xml
 create mode 100644 tests/qemuxml2argvdata/x86_64-pc-graphics.x86_64-latest.args
 create mode 100644 tests/qemuxml2argvdata/x86_64-pc-graphics.xml
 create mode 100644 
tests/qemuxml2argvdata/x86_64-q35-graphics.x86_64-latest.args
 create mode 100644 tests/qemuxml2argvdata/x86_64-q35-graphics.xml

diff --git a/tests/qemuxml2argvdata/aarch64-virt-graphics.aarch64-latest.args 
b/tests/qemuxml2argvdata/aarch64-virt-graphics.aarch64-latest.args
new file mode 100644
index 00..46111a5f23
--- /dev/null
+++ b/tests/qemuxml2argvdata/aarch64-virt-graphics.aarch64-latest.args
@@ -0,0 +1,59 @@
+LC_ALL=C \
+PATH=/bin \
+HOME=/home/test \
+USER=test \
+LOGNAME=test \
+QEMU_AUDIO_DRV=none \
+/usr/bin/qemu-system-aarch64 \
+-name guest=guest,debug-threads=on \
+-S \
+-object secret,id=masterKey0,format=raw,\
+file=/tmp/lib/domain--1-guest/master-key.aes \
+-machine virt,accel=tcg,usb=off,dump-guest-core=off,gic-version=2 \
+-drive file=/usr/share/AAVMF/AAVMF_CODE.fd,if=pflash,format=raw,unit=0,\
+readonly=on \
+-drive file=/var/lib/libvirt/qemu/nvram/guest_VARS.fd,if=pflash,format=raw,\
+unit=1 \
+-m 4096 \
+-realtime mlock=off \
+-smp 4,sockets=4,cores=1,threads=1 \
+-uuid 33844184-97c0-4cc0-aa7d-206f5803530b \
+-no-user-config \
+-nodefaults \
+-chardev socket,id=charmonitor,fd=1729,server,nowait \
+-mon chardev=charmonitor,id=monitor,mode=control \
+-rtc base=utc \
+-no-shutdown \
+-boot strict=on \
+-device 
pcie-root-port,port=0x8,chassis=1,id=pci.1,bus=pcie.0,multifunction=on,\
+addr=0x1 \
+-device pcie-root-port,port=0x9,chassis=2,id=pci.2,bus=pcie.0,addr=0x1.0x1 \
+-device pcie-root-port,port=0xa,chassis=3,id=pci.3,bus=pcie.0,addr=0x1.0x2 \
+-device pcie-root-port,port=0xb,chassis=4,id=pci.4,bus=pcie.0,addr=0x1.0x3 \
+-device pcie-root-port,port=0xc,chassis=5,id=pci.5,bus=pcie.0,addr=0x1.0x4 \
+-device pcie-root-port,port=0xd,chassis=6,id=pci.6,bus=pcie.0,addr=0x1.0x5 \
+-device pcie-root-port,port=0xe,chassis=7,id=pci.7,bus=pcie.0,addr=0x1.0x6 \
+-device qemu-xhci,p2=15,p3=15,id=usb,bus=pci.2,addr=0x0 \
+-device virtio-scsi-pci,id=scsi0,bus=pci.3,addr=0x0 \
+-device virtio-serial-pci,id=virtio-serial0,bus=pci.4,addr=0x0 \
+-drive file=/var/lib/libvirt/images/guest.qcow2,format=qcow2,if=none,\
+id=drive-scsi0-0-0-0 \
+-device scsi-hd,bus=scsi0.0,channel=0,scsi-id=0,lun=0,drive=drive-scsi0-0-0-0,\
+id=scsi0-0-0-0,bootindex=1 \
+-netdev user,id=hostnet0 \
+-device 
virtio-net-pci,netdev=hostnet0,id=net0,mac=52:54:00:53:45:a5,bus=pci.1,\
+addr=0x0 \
+-chardev pty,id=charserial0 \
+-serial chardev:charserial0 \
+-chardev socket,id=charchannel0,fd=1729,server,nowait \
+-device virtserialport,bus=virtio-serial0.0,nr=1,chardev=charchannel0,\
+id=channel0,name=org.qemu.guest_agent.0 \
+-device usb-tablet,id=input0,bus=usb.0,port=1 \
+-device usb-kbd,id=input1,bus=usb.0,port=2 \
+-vnc 127.0.0.1:0 \
+-device virtio-gpu-pci,id=video0,max_outputs=1,bus=pci.6,addr=0x0 \
+-object rng-random,id=objrng0,filename=/dev/urandom \
+-device virtio-rng-pci,rng=objrng0,id=rng0,bus=pci.5,addr=0x0 \
+-sandbox on,obsolete=deny,elevateprivileges=deny,spawn=deny,\
+resourcecontrol=deny \
+-msg timestamp=on
diff --git a/tests/qemuxml2argvdata/aarch64-virt-graphics.xml 
b/tests/qemuxml2argvdata/aarch64-virt-graphics.xml
new file mode 100644
index 00..95aef91beb
--- /dev/null
+++ b/tests/qemuxml2argvdata/aarch64-virt-graphics.xml
@@ -0,0 +1,50 @@
+
+  guest
+  33844184-97c0-4cc0-aa7d-206f5803530b
+  
+http://libosinfo.org/xmlns/libvirt/domain/1.0;>
+  http://fedoraproject.org/fedora/29"/>
+
+  
+  4194304
+  4194304
+  4
+  
+hvm
+/usr/share/AAVMF/AAVMF_CODE.fd
+/var/lib/libvirt/qemu/nvram/guest_VARS.fd
+

Re: [libvirt] [PATCH v2 11/11] qemu: Implement bulk snapshot operations

2019-02-27 Thread Eric Blake
On 2/27/19 11:27 AM, John Ferlan wrote:
> 
> 
> On 2/23/19 4:24 PM, Eric Blake wrote:
>> Implement the new flags for bulk snapshot dump and redefine. This
>> borrows from ideas in the test driver, but is further complicated
>> by the fact that qemu must write snapshot XML to disk, and thus must
>> do additional validation after the initial parse to ensure the user
>> didn't attempt to rename a snapshot with "../" or similar.
>>
>> Of note: all prior callers of qemuDomainSnapshotDiscardAllMetadata()
>> were at points where it did not matter if vm->current_snapshot and
>> the metaroot in vm->snapshots were left pointing to stale memory,
>> because we were about to delete the entire vm object; but now it is
>> important to reset things properly so that the domain still shows
>> as having no snapshots on failure.
>>
>> Signed-off-by: Eric Blake 
>> ---
>>  src/qemu/qemu_domain.h |  2 +-
>>  src/qemu/qemu_domain.c | 35 +--
>>  src/qemu/qemu_driver.c | 64 --
>>  3 files changed, 89 insertions(+), 12 deletions(-)
>>
> 
> NB: I couldn't get this one to git am -3 apply - I didn't chase the
> conflict though.

My fault for too many patches in flight at once. As I'll be doing a v3
anyways, that one wil be cleaner.

> 
>> diff --git a/src/qemu/qemu_domain.h b/src/qemu/qemu_domain.h
>> index 7c6b50184c..37c9813ec5 100644
>> --- a/src/qemu/qemu_domain.h
>> +++ b/src/qemu/qemu_domain.h
>> @@ -683,7 +683,7 @@ int qemuDomainSnapshotWriteMetadata(virDomainObjPtr vm,
>>  virDomainSnapshotObjPtr snapshot,
>>  virCapsPtr caps,
>>  virDomainXMLOptionPtr xmlopt,
>> -char *snapshotDir);
>> +const char *snapshotDir);
> 
> Theoretically separable.

Yeah, I debated about it. Since you called me on it, I'll make the split.


>> @@ -7881,7 +7884,14 @@ qemuDomainDefFormatBufInternal(virQEMUDriverPtr 
>> driver,
>>  }
>>
>>   format:
>> -ret = virDomainDefFormatInternal(def, caps, NULL, NULL,
>> +if (snapshots && !vm) {
>> +virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
>> +   _("snapshots XML requested but not provided"));
> 
> Error msg is a bit odd - the error is that a snapshot listing was
> desired, but consumer didn't pass the @vm object.

It's a programmer's error, not user-triggerable.  (If we could assert()
or abort(), that's what I'd have done instead).  And really, it is no
snapshots were provided, because it is vm->snapshots that we depend on.

> 
>> +goto cleanup;
>> +}
>> +ret = virDomainDefFormatInternal(def, caps,
>> + snapshots ? vm->snapshots : NULL,
>> + snapshots ? vm->current_snapshot : 
>> NULL,
>>   
>> virDomainDefFormatConvertXMLFlags(flags),
>>   buf, driver->xmlopt);
> 
> Perhaps this one should [be | have been] turned into a
> virDomainDefFormatFull (or whatever new name is chosen if one is
> chosen).  I think it shows the hazards of exposing *Internal to many
> consumers.

It's a ripple effect - I had to decide how many interfaces needed an
additional parameter, even if the caller wouldn't be using it. But your
idea of an auxiliary struct may make it nicer.


>> +/* Return is arbitrary, so use the first root */
>> +snap = virDomainSnapshotFindByName(vm->snapshots, NULL);
> 
> Similar to test driver - this isn't used during cleanup.
> 
> John
> 
>> +snapshot = virGetDomainSnapshot(domain, 
>> snap->first_child->def->name);

Yeah, but it's not leaked, and it let me avoid a long line.

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

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


Re: [libvirt] [Qemu-devel] [PATCH v3 00/10] dirty-bitmaps: deprecate @status field

2019-02-27 Thread no-reply
Patchew URL: https://patchew.org/QEMU/20190223000614.13894-1-js...@redhat.com/



Hi,

This series seems to have some coding style problems. See output below for
more information:

Message-id: 20190223000614.13894-1-js...@redhat.com
Subject: [Qemu-devel] [PATCH v3 00/10] dirty-bitmaps: deprecate @status field
Type: series

=== TEST SCRIPT BEGIN ===
#!/bin/bash
git rev-parse base > /dev/null || exit 0
git config --local diff.renamelimit 0
git config --local diff.renames True
git config --local diff.algorithm histogram
./scripts/checkpatch.pl --mailback base..
=== TEST SCRIPT END ===

Updating 3c8cf5a9c21ff8782164d1def7f44bd888713384
>From https://github.com/patchew-project/qemu
 * [new tag]   
patchew/20190220160628.6555-1-marcandre.lur...@redhat.com -> 
patchew/20190220160628.6555-1-marcandre.lur...@redhat.com
Switched to a new branch 'test'
5615f81566 iotests: add busy/recording bit test to 124
7c4f722b89 blockdev: remove unused paio parameter documentation
30e0427368 block/dirty-bitmaps: move comment block
a29ece1728 block/dirty-bitmaps: unify qmp_locked and user_locked calls
3d0665404c block/dirty-bitmap: explicitly lock bitmaps with successors
d932d4e9c4 nbd: change error checking order for bitmaps
2ee1f03bae block/dirty-bitmap: change semantics of enabled predicate
4fca6cb44e block/dirty-bitmap: remove set/reset assertions against enabled bit
7d032c41b8 block/dirty-bitmaps: rename frozen predicate helper
9d17322444 block/dirty-bitmap: add recording and busy properties

=== OUTPUT BEGIN ===
1/10 Checking commit 9d1732244435 (block/dirty-bitmap: add recording and busy 
properties)
2/10 Checking commit 7d032c41b8ab (block/dirty-bitmaps: rename frozen predicate 
helper)
WARNING: line over 80 characters
#85: FILE: block/dirty-bitmap.c:248:
+error_setg(errp, "Cannot create a successor for a bitmap that is 
in-use "

total: 0 errors, 1 warnings, 122 lines checked

Patch 2/10 has style problems, please review.  If any of these errors
are false positives report them to the maintainer, see
CHECKPATCH in MAINTAINERS.
3/10 Checking commit 4fca6cb44e9b (block/dirty-bitmap: remove set/reset 
assertions against enabled bit)
4/10 Checking commit 2ee1f03baedb (block/dirty-bitmap: change semantics of 
enabled predicate)
5/10 Checking commit d932d4e9c476 (nbd: change error checking order for bitmaps)
6/10 Checking commit 3d0665404c60 (block/dirty-bitmap: explicitly lock bitmaps 
with successors)
7/10 Checking commit a29ece1728f0 (block/dirty-bitmaps: unify qmp_locked and 
user_locked calls)
ERROR: open brace '{' following function declarations go on the next line
#37: FILE: block/dirty-bitmap.c:190:
+bool bdrv_dirty_bitmap_busy(BdrvDirtyBitmap *bitmap) {

total: 1 errors, 0 warnings, 263 lines checked

Patch 7/10 has style problems, please review.  If any of these errors
are false positives report them to the maintainer, see
CHECKPATCH in MAINTAINERS.

8/10 Checking commit 30e042736827 (block/dirty-bitmaps: move comment block)
9/10 Checking commit 7c4f722b8967 (blockdev: remove unused paio parameter 
documentation)
10/10 Checking commit 5615f815663d (iotests: add busy/recording bit test to 124)
=== OUTPUT END ===

Test command exited with code: 1


The full log is available at
http://patchew.org/logs/20190223000614.13894-1-js...@redhat.com/testing.checkpatch/?type=message.
---
Email generated automatically by Patchew [http://patchew.org/].
Please send your feedback to patchew-de...@redhat.com

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


Re: [libvirt] [PATCH v2 10/11] test: Implement bulk snapshot operations

2019-02-27 Thread Eric Blake
On 2/27/19 11:03 AM, John Ferlan wrote:
> 
> 
> On 2/23/19 4:24 PM, Eric Blake wrote:
>> Implement the new flags for bulk snapshot dump and redefine. The
>> bulk of the work is already done by the common code.
>>
>> Since each connection to test:///default restarts at the same
>> canned state, this can easily be tested with:
>>

>> @@ -6337,6 +6340,18 @@ testDomainSnapshotCreateXML(virDomainPtr domain,
>>  goto cleanup;
>>  }
>>
>> +if (flags & VIR_DOMAIN_SNAPSHOT_CREATE_REDEFINE_LIST) {
>> +if (virDomainSnapshotDefParseList(xmlDesc, vm->def->uuid, 
>> vm->snapshots,
>> +  >current_snapshot, 
>> privconn->caps,
>> +  privconn->xmlopt, parse_flags) < 
>> 0)
>> +goto cleanup;
>> +
>> +/* Return is arbitrary, so use the first root */
>> +snap = virDomainSnapshotFindByName(vm->snapshots, NULL);
> 
> Hmm... I don't think @snap is used since cleanup: code filters on
> REDEFINE_LIST, so it would seem this would be leaked then.
> 

snap is a stolen pointer into something residing in vm->snapshots (that
is, the result of virDomainSnapshotFindByName() never leaks, and does
not need explicit cleanup).

> Reviewed-by: John Ferlan 
> 
> John
> 

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

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


Re: [libvirt] [PATCH] conf: don't output managed attr for non-pci hostdevs

2019-02-27 Thread John Ferlan



On 2/22/19 4:35 AM, Nikolay Shirokovskiy wrote:
> It is ignored on input for non pci hostdevs as written in docs.
> I guess it would be better if the attr was disabled to be specified
> in the first place instead but such behaviour is already documented.
> At least let's not output it back. This will fix issue when
> managed appeared on output for non pci hostdevs when it was not
> specified on input.
> 
> The tests are fixed by next commands:
> grep  -lRP 'hostdev.*mode=.subsystem.*type=.(?!pci).*managed' `find tests 
> -name '*.xml'` > files
> sed -i.bak -re 's/ managed=.(yes|no).//' `cat files`
> 

To save yourself some effort in the future...

VIR_TEST_REGENERATE_OUTPUT=1 tests/qemuxml2xmltest
VIR_TEST_REGENERATE_OUTPUT=1 tests/xlconfigtest
VIR_TEST_REGENERATE_OUTPUT=1 tests/qemuargv2xmltest

Would have got a lot of them...

> Signed-off-by: Nikolay Shirokovskiy 
> ---
>  src/conf/domain_conf.c |  6 --
>  tests/qemuargv2xmldata/hostdev-usb-address.xml |  2 +-
>  tests/qemuxml2argvdata/controller-order.xml|  2 +-
>  .../disk-hostdev-scsi-address-conflict.xml |  2 +-
>  .../disk-hostdev-scsi-virtio-iscsi-auth-AES.xml|  2 +-
>  .../hostdev-scsi-autogen-address.xml   | 22 
> +++---
>  tests/qemuxml2argvdata/hostdev-scsi-boot.xml   |  2 +-
>  tests/qemuxml2argvdata/hostdev-scsi-large-unit.xml |  2 +-
>  .../hostdev-scsi-lsi-iscsi-auth.xml|  4 ++--
>  tests/qemuxml2argvdata/hostdev-scsi-lsi-iscsi.xml  |  4 ++--
>  tests/qemuxml2argvdata/hostdev-scsi-lsi.xml|  2 +-
>  tests/qemuxml2argvdata/hostdev-scsi-rawio.xml  |  2 +-
>  tests/qemuxml2argvdata/hostdev-scsi-readonly.xml   |  2 +-
>  tests/qemuxml2argvdata/hostdev-scsi-sgio.xml   |  2 +-
>  tests/qemuxml2argvdata/hostdev-scsi-shareable.xml  |  2 +-
>  .../hostdev-scsi-vhost-scsi-ccw.xml|  2 +-
>  .../hostdev-scsi-vhost-scsi-pci.xml|  2 +-
>  .../hostdev-scsi-vhost-scsi-pcie.xml   |  2 +-
>  .../hostdev-scsi-virtio-iscsi-auth.xml |  4 ++--
>  .../qemuxml2argvdata/hostdev-scsi-virtio-iscsi.xml |  4 ++--
>  .../qemuxml2argvdata/hostdev-scsi-virtio-scsi.xml  |  2 +-
>  .../hostdev-usb-address-device-boot.xml|  2 +-
>  .../hostdev-usb-address-device.xml |  2 +-
>  tests/qemuxml2argvdata/hostdev-usb-address.xml |  2 +-
>  .../hostdevs-drive-address-conflict.xml|  4 ++--
>  tests/qemuxml2argvdata/name-escape.xml |  2 +-
>  tests/qemuxml2argvdata/user-aliases-usb.xml|  4 ++--
>  tests/qemuxml2xmloutdata/hostdev-mdev-display.xml  |  2 +-
>  .../qemuxml2xmloutdata/hostdev-mdev-precreated.xml |  2 +-
>  .../hostdev-scsi-autogen-address.xml   | 22 
> +++---
>  .../qemuxml2xmloutdata/hostdev-scsi-large-unit.xml |  2 +-
>  .../hostdev-scsi-lsi-iscsi-auth.xml|  4 ++--
>  .../qemuxml2xmloutdata/hostdev-scsi-lsi-iscsi.xml  |  4 ++--
>  tests/qemuxml2xmloutdata/hostdev-scsi-lsi.xml  |  2 +-
>  tests/qemuxml2xmloutdata/hostdev-scsi-rawio.xml|  2 +-
>  tests/qemuxml2xmloutdata/hostdev-scsi-readonly.xml |  2 +-
>  tests/qemuxml2xmloutdata/hostdev-scsi-sgio.xml |  2 +-
>  .../qemuxml2xmloutdata/hostdev-scsi-shareable.xml  |  2 +-
>  .../hostdev-scsi-vhost-scsi-ccw.xml|  2 +-
>  .../hostdev-scsi-vhost-scsi-pci.xml|  2 +-
>  .../hostdev-scsi-vhost-scsi-pcie.xml   |  2 +-
>  .../hostdev-scsi-virtio-iscsi-auth.xml |  4 ++--
>  .../hostdev-scsi-virtio-iscsi.xml  |  4 ++--
>  .../hostdev-scsi-virtio-scsi.xml   |  2 +-
>  .../hostdev-subsys-mdev-vfio-ccw.xml   |  2 +-
>  tests/qemuxml2xmloutdata/hostdev-usb-address.xml   |  2 +-
>  tests/xlconfigdata/test-usb.xml|  2 +-
>  47 files changed, 80 insertions(+), 78 deletions(-)
> 
> diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c
> index ceeb247..9ff659c 100644
> --- a/src/conf/domain_conf.c
> +++ b/src/conf/domain_conf.c
> @@ -27330,8 +27330,10 @@ virDomainHostdevDefFormat(virBufferPtr buf,
>  virBufferAsprintf(buf, "mode, type);
>  if (def->mode == VIR_DOMAIN_HOSTDEV_MODE_SUBSYS) {
> -virBufferAsprintf(buf, " managed='%s'",
> -  def->managed ? "yes" : "no");
> +if (def->source.subsys.type == VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_PCI) {
> +virBufferAsprintf(buf, " managed='%s'",
> +  def->managed ? "yes" : "no");
> +}

Do you think perhaps @managed should be changed to a virTristateBool?
After all the RNG attribute is a virYesNo like other Tristate's.

That way the printing would only be done *if* found specifically on input.

The problem with blindly removing the "no" even though it's listed as
not being parsed on input is the differences it creates in output when
someone for some reason does add 

Re: [libvirt] [PATCH v2 09/11] virsh: Expose bulk snapshot dumpxml/redefine

2019-02-27 Thread Eric Blake
On 2/27/19 10:54 AM, John Ferlan wrote:
> 
> 
> On 2/23/19 4:24 PM, Eric Blake wrote:
>> Add flags to the 'dumpxml' and 'snapshot-create' commands to pass
>> the newly-added bulk snapshot flags through.
>>
>> For command-line convenience, I intentionally made --redefine-list
>> imply --redefine, even though the counterpart C flags are distinct
>> (and you get an error if you pass _REDEFINE_LIST without _REDEFINE).
>>
>> Signed-off-by: Eric Blake 
>> ---
>>  tools/virsh-domain.c   |  7 +++
>>  tools/virsh-snapshot.c | 14 ++
>>  2 files changed, 21 insertions(+)
>>
> 
> Need to update virsh.pod as well to describe new arguments. Do you think
> that a separation of the dumpxml and the parse/create into order
> pertinent patches would be better? That is the --snapshots for dumpxml
> after patch7 (which probably could swap places w/ patch6) so that the
> dumpxml and parse/create functionality is all in logical order. It's not
> that important.

Yeah, I waffled on that. v1 was definitely more of a "do all dumpxml
changes, then do all redefine changes" breakup. But I intentionally
refactored this way (do all API changes, then all virsh changes),
especially since the virsh changes are so small that it's easy to review
both at once.  Depending on how you feel about the qemu changes, I'm
still open to the idea of doing dumpxml separate from redefine in each
of the drivers, if it makes it easier to backport one but not the other.
Furthermore, your comments against v4 of the incremental backup sparked
my idea of possibly using VIR_DOMAIN_XML_SNAPSHOTS internally (so that
domains have just ONE xml file on disk, rather than the main domain xml
+ one xml per snapshot), and that may have fallout on making the dumpxml
portion reasonable to backport in isolation.

I'll have to see how things play out in the rest of the series before
deciding if splitting this one is worth it.

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

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


Re: [libvirt] [PATCH v2 07/11] domain: Add VIR_DOMAIN_XML_SNAPSHOTS flag

2019-02-27 Thread Eric Blake
On 2/27/19 10:32 AM, John Ferlan wrote:

>>
>> Unfortunately, libvirt versions between 1.2.12 and 5.0.0 will
>> silently ignore the new flag, rather than diagnosing that they
>> don't support it; but at least silent lack of snapshots from
>> an older server is not a security hole.
>>
>> Signed-off-by: Eric Blake 
>> ---
>>  include/libvirt/libvirt-domain.h |  1 +
>>  src/conf/domain_conf.c   | 13 -
>>  src/libvirt-domain.c |  5 +
>>  3 files changed, 14 insertions(+), 5 deletions(-)
>>
> 
> [...]
> 
>> diff --git a/src/libvirt-domain.c b/src/libvirt-domain.c
>> index 072b92b717..2691698bd5 100644
>> --- a/src/libvirt-domain.c
>> +++ b/src/libvirt-domain.c
>> @@ -2570,6 +2570,11 @@ virDomainGetControlInfo(virDomainPtr domain,
>>   * XML might not validate against the schema, so it is mainly for
>>   * internal use.
>>   *
>> + * If @flags contains VIR_DOMAIN_XML_SNAPSHOTS, the XML will include
> 
> Should we even try to say that "and supported by the target libvirt
> system with the appropriate version of the software installed" ;-)... I
> know implied somewhat - but perhaps notable in this (and future) cases
> because of the issue mentioned in the commit message that outward facing
> docs consumers may never read.

Maybe, since this is indeed enough of a break from the usual norms of
rejecting unknown flags (at least for a couple of years) to be worth it.
 The upcoming VIR_DOMAIN_XML_CHECKPOINTS will have the same wording, of
course.

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

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


Re: [libvirt] [PATCH v2 05/11] domain: Expand virDomainDefFormatInternal with snapshots

2019-02-27 Thread Eric Blake
On 2/27/19 10:27 AM, John Ferlan wrote:
> 
> 
> On 2/23/19 4:24 PM, Eric Blake wrote:
>> Make it possible to grab all snapshot XMLs via a single API
>> call, by adding a new internal flag.  All callers are adjusted,
>> for now passing NULL and not using the new flag. A new wrapper
>> virDomainDefFormatFull() is added to make it easier for the
> 
> Not really the next any more it seems - definitely in future ones though.
> 
>> next patch to add a few callers without having to revisit all
>> existing clients of virDomainDefFormat().
>>

>> @@ -28212,6 +28212,8 @@ virDomainVsockDefFormat(virBufferPtr buf,
>>  int
>>  virDomainDefFormatInternal(virDomainDefPtr def,
>> virCapsPtr caps,
>> +   virDomainSnapshotObjListPtr snapshots,
>> +   virDomainSnapshotObjPtr current_snapshot,
>> unsigned int flags,
>> virBufferPtr buf,
>> virDomainXMLOptionPtr xmlopt)
> 
> Rather than possibly continually adding parameters to
> virDomainDefFormatInternal, maybe we should take the plunge now to
> create a local struct that would be passed along that would fill in
> fields based on what "extra" format flags beyond the common set are
> being used.
> 

Ooh, nice idea, especially since I _will_ be adding more parameters for
bulk listing of checkpoints :)  Will do for v3 (since, as you point out,
everything beyond patch 1 is now 5.2 material).

> struct virDomainDefFormatInternalFlagsData {
> virDomainSnapshotObjListPtr snapshots;
> virDomainSnapshotObjPtr current_snapshot;
> };
> 
> I am of course assuming checkpoints in the future will do something similar.

Yep.


>> @@ -29016,6 +29025,23 @@ virDomainDefFormatInternal(virDomainDefPtr def,
>>
>>  virDomainSEVDefFormat(buf, def->sev);
>>
> 
> I think all of the next hunk should be in it's own helper method
> 
>> +if (flags & VIR_DOMAIN_DEF_FORMAT_SNAPSHOTS) {
>> +unsigned int snapflags = flags & VIR_DOMAIN_DEF_FORMAT_SECURE ?
>> +VIR_DOMAIN_SNAPSHOT_FORMAT_SECURE : 0;
>> +
>> +virBufferAddLit(buf, "> +if (current_snapshot)
>> +virBufferEscapeString(buf, " current='%s'",
>> +  current_snapshot->def->name);
>> +virBufferAddLit(buf, ">\n");
>> +virBufferAdjustIndent(buf, 2);
>> +if (virDomainSnapshotObjListFormat(buf, uuidstr, snapshots, caps,
>> +   xmlopt, snapflags))

Can do.  Or maybe virDomainSnapshotObjListFormat() should do ALL of the
work (but then it needs a pointer to the current snapshot - but then
again, you also made me question whether the current snapshot should be
an internal detail to virDomainSnapshotObjList rather than tracked
separately, so that alone is a separate cleanup potentially worth doing
first).

> 
> So this answers my question from patch4...
> 
> Anyway, the return checking should be < 0 and I believe the @childrenBuf
> is how other similar constructs attempted for format the child XML
> output - I believe it could be used in this case as well or at least a
> similarly named/used childrenBuf in a method/helper.

I'm not sure a childrenBuf adds much. After all, whether we do:

most output direct to main buf
snapshot output to children buf
concatenate children buf to main buf

or

most output direct to main buf
snapshot output to main buf

we get the same result: on success, main buf is populated; on failure,
main buf may be half-built but it is going to be thrown away.


>> +char *
>> +virDomainDefFormatFull(virDomainDefPtr def, virCapsPtr caps,
>> +   virDomainSnapshotObjListPtr snapshots,
>> +   virDomainSnapshotObjPtr current_snapshot,
>> +   unsigned int flags)
> 
> Naming is hard, but is "Full" just another way of saying "all flags" not
> just the common ones?
> 
> Not that we necessarily want to see N different implementations of
> virDomainDefFormat; however, if at some point in the future someone
> wanted to list all Checkpoints (;-)), but not all Snapshots - then would
> *Full still fit the bill or would we need a new method.

The alternative is to fix all current callers to pass the extra
parameter(s) even when they don't use them. Which may not be too bad, if
I take your advice to use a struct (so all existing callers pass NULL,
and don't have to be touched again), instead of my current approach of
adding yet more parameters for every additional thing to be printed.  I
don't necessarily need this helper function (test_driver.c was the only
immediate beneficiary), but having it reduced the churn (all other
non-qemu drivers have to be touched due to an added parameter, if I
don't add it).

> 
> Just want to be sure we rightly name it considering your knowledge of
> intended future changes.
> 
> It almost seems DefFormat is "format only common flags" while
> 

Re: [libvirt] [PATCH v2 0/6] Alter domain_conf to make use of autofree

2019-02-27 Thread John Ferlan
ping?

I also think that w/ Peter's addition of VIR_XPATH_NODE_AUTORESTORE even
more changes could be done, but I'd leave those for either Peter to
finish what he started or the mythical future someone else.

Tks -

John

On 2/20/19 1:33 PM, John Ferlan wrote:
> v1: https://www.redhat.com/archives/libvir-list/2019-February/msg01160.html
> 
> Changes since v1:
> 
>  * Push patch 1 
> 
>  * Split patch 2 to follow code review guidance:
> 
>* (Patch1) Pull out virDomainEmulatorPinDefParseXML changes to
>use VIR_STEAL_PTR
>* (Patch2) Use VIR_AUTOPTR(virBitmap) 
>* (Patch3) Handle a couple cases where goto's no longer necessary
> 
>  * Drop Patch 3
> 
>  * Split Patch 4 to follow code review guidance:
> 
>* (Patch4) Remove unused variables
>* (Patch5) Just use VIR_AUTOFREE
>* (Patch6) Handle the removal of goto logic that's no longer necessary
>   
> 
> John Ferlan (6):
>   conf: Rework virDomainEmulatorPinDefParseXML
>   conf: Use VIR_AUTOPTR(virBitmap) in domain_conf
>   conf: Clean up some unnecessary goto paths
>   conf: Remove a few unused variables in domain_conf
>   conf: Use VIR_AUTOFREE in domain_conf
>   conf: Clean up some unnecessary goto paths
> 
>  src/conf/domain_conf.c | 1937 ++--
>  1 file changed, 676 insertions(+), 1261 deletions(-)
> 

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


Re: [libvirt] [PATCH v2 00/17] Add support to list Storage Driver backend capabilities

2019-02-27 Thread John Ferlan
ping^2?  Yes, there are patches that indicate 5.1.0 that would need to
be changed to 5.2.0 that I've already changed in my local branch.

Tks,

John

On 2/12/19 10:27 AM, John Ferlan wrote:
> v1: https://www.redhat.com/archives/libvir-list/2019-January/msg00479.html
> 
> Changes since v1:
> 
>  * The first 4 patches were already R-by'd and pushed.
> 
>  * From v1, rework patch 5 & 6 into what now is patches 8 & 9. The
>format of the output for what results in the output for the
>connectGetCapabilities (virConnectGetCapabilities).
> 
>  * From v1, drop patch 7
> 
>  * In v2, patches 1-7 are new as a result of work done for patches 10-17.
>patches 1-5 were posted upstream, but left unreviewed:
> 
>https://www.redhat.com/archives/libvir-list/2019-February/msg00333.html
> 
>These essentially ensure the volOptions and poolOptions don't list
>or use something unexpected per documentation. The doc patch is a
>simple update to add some missing text and fix an entry
> 
>  * Patches 10-17 are new to implement the ability to get/format the
>Storage Driver backend capabilities via:
> 
>storageConnectGetStoragePoolCapabilities
>virConnectGetStoragePoolCapabilities
> 
>similar to how virConnectGetDomainCapabilities returns domain specific
>output. The output is essentially what is provided in the poolOptions
>and volOptions from storage_conf as valid values for format type fields
>for pool and/or volume as well as an enumerated list for the required
>source elements for creation. Whether the latter is useful or not was
>not clear, but since it is something that can cause a creation error
>when missing, I figured it'd be useful.  The new virsh command follows
>then domcapabilities nomenclature.
> 
> John Ferlan (17):
>   conf: Remove volOptions for VIR_STORAGE_POOL_SHEEPDOG
>   conf: Remove volOptions for VIR_STORAGE_POOL_RBD
>   conf: Remove volOptions for VIR_STORAGE_POOL_SCSI
>   conf: Remove volOptions for VIR_STORAGE_POOL_ISCSI[_DIRECT]
>   conf: Remove volOptions for VIR_STORAGE_POOL_MPATH
>   conf: Remove defaultFormat from VIR_STORAGE_POOL_ZFS
>   docs: Fix a few storage.html.in typos
>   conf: Introduce storage pool functions into capabilities
>   storage: Process storage pool capabilities
>   docs: Add schema for storage pool capabilities
>   conf: Add storage pool capability formatting
>   tests: Introduce storage pool capabilites test
>   docs: Add description for Storage Pool Capabilities
>   libvirt: Introduce virConnectGetStoragePoolCapabilities
>   storage: Introduce storageConnectGetStoragePoolCapabilities
>   virsh: Expose virConnectGetStoragePoolCapabilities
>   docs: Add news article
> 
>  docs/docs.html.in |   1 +
>  docs/format.html.in   |   1 +
>  docs/formatstoragecaps.html.in| 108 +++
>  docs/index.html.in|   1 +
>  docs/news.xml |  12 +
>  docs/schemas/storagepoolcaps.rng  |  88 ++
>  docs/storage.html.in  |   8 +-
>  include/libvirt/libvirt-storage.h |   4 +
>  libvirt.spec.in   |   1 +
>  mingw-libvirt.spec.in |   2 +
>  src/conf/Makefile.inc.am  |   2 +
>  src/conf/capabilities.c   |  74 +
>  src/conf/capabilities.h   |  15 +
>  src/conf/storage_capabilities.c   | 135 +
>  src/conf/storage_capabilities.h   |  41 +++
>  src/conf/storage_conf.c   | 131 +++--
>  src/conf/storage_conf.h   |   7 +
>  src/conf/virstorageobj.h  |   5 +
>  src/driver-storage.h  |   5 +
>  src/libvirt-storage.c |  40 +++
>  src/libvirt_private.syms  |   8 +
>  src/libvirt_public.syms   |   5 +
>  src/remote/remote_driver.c|   1 +
>  src/remote/remote_protocol.x  |  15 +-
>  src/remote_protocol-structs   |   7 +
>  src/storage/storage_backend.c |  16 ++
>  src/storage/storage_backend.h |   3 +
>  src/storage/storage_driver.c  |  44 +++
>  tests/Makefile.am |   7 +
>  .../storagepoolcapsschemadata/poolcaps-fs.xml | 268 ++
>  .../poolcaps-full.xml | 268 ++
>  tests/storagepoolcapstest.c   | 124 
>  tests/storagevolxml2xmlout/vol-sheepdog.xml   |   1 -
>  tests/virschematest.c |   1 +
>  tools/virsh-pool.c|  42 +++
>  tools/virsh.pod   |   7 +
>  36 files changed, 1473 insertions(+), 25 deletions(-)
>  create mode 100644 docs/formatstoragecaps.html.in
>  create mode 100644 

Re: [libvirt] [PATCH v2 11/11] qemu: Implement bulk snapshot operations

2019-02-27 Thread John Ferlan



On 2/23/19 4:24 PM, Eric Blake wrote:
> Implement the new flags for bulk snapshot dump and redefine. This
> borrows from ideas in the test driver, but is further complicated
> by the fact that qemu must write snapshot XML to disk, and thus must
> do additional validation after the initial parse to ensure the user
> didn't attempt to rename a snapshot with "../" or similar.
> 
> Of note: all prior callers of qemuDomainSnapshotDiscardAllMetadata()
> were at points where it did not matter if vm->current_snapshot and
> the metaroot in vm->snapshots were left pointing to stale memory,
> because we were about to delete the entire vm object; but now it is
> important to reset things properly so that the domain still shows
> as having no snapshots on failure.
> 
> Signed-off-by: Eric Blake 
> ---
>  src/qemu/qemu_domain.h |  2 +-
>  src/qemu/qemu_domain.c | 35 +--
>  src/qemu/qemu_driver.c | 64 --
>  3 files changed, 89 insertions(+), 12 deletions(-)
> 

NB: I couldn't get this one to git am -3 apply - I didn't chase the
conflict though.

> diff --git a/src/qemu/qemu_domain.h b/src/qemu/qemu_domain.h
> index 7c6b50184c..37c9813ec5 100644
> --- a/src/qemu/qemu_domain.h
> +++ b/src/qemu/qemu_domain.h
> @@ -683,7 +683,7 @@ int qemuDomainSnapshotWriteMetadata(virDomainObjPtr vm,
>  virDomainSnapshotObjPtr snapshot,
>  virCapsPtr caps,
>  virDomainXMLOptionPtr xmlopt,
> -char *snapshotDir);
> +const char *snapshotDir);

Theoretically separable.

> 
>  int qemuDomainSnapshotForEachQcow2(virQEMUDriverPtr driver,
> virDomainObjPtr vm,
> diff --git a/src/qemu/qemu_domain.c b/src/qemu/qemu_domain.c
> index cb1665c8f9..cf8b6e8eaf 100644
> --- a/src/qemu/qemu_domain.c
> +++ b/src/qemu/qemu_domain.c
> @@ -7704,6 +7704,7 @@ qemuDomainDefCopy(virQEMUDriverPtr driver,
> 
>  static int
>  qemuDomainDefFormatBufInternal(virQEMUDriverPtr driver,
> +   virDomainObjPtr vm,
> virDomainDefPtr def,
> virCPUDefPtr origCPU,
> unsigned int flags,
> @@ -7713,8 +7714,10 @@ qemuDomainDefFormatBufInternal(virQEMUDriverPtr driver,
>  virDomainDefPtr copy = NULL;
>  virCapsPtr caps = NULL;
>  virQEMUCapsPtr qemuCaps = NULL;
> +bool snapshots = flags & VIR_DOMAIN_XML_SNAPSHOTS;
> 
> -virCheckFlags(VIR_DOMAIN_XML_COMMON_FLAGS | VIR_DOMAIN_XML_UPDATE_CPU, 
> -1);
> +virCheckFlags(VIR_DOMAIN_XML_COMMON_FLAGS | VIR_DOMAIN_XML_UPDATE_CPU |
> +  VIR_DOMAIN_XML_SNAPSHOTS, -1);
> 
>  if (!(caps = virQEMUDriverGetCapabilities(driver, false)))
>  goto cleanup;
> @@ -7881,7 +7884,14 @@ qemuDomainDefFormatBufInternal(virQEMUDriverPtr driver,
>  }
> 
>   format:
> -ret = virDomainDefFormatInternal(def, caps, NULL, NULL,
> +if (snapshots && !vm) {
> +virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
> +   _("snapshots XML requested but not provided"));

Error msg is a bit odd - the error is that a snapshot listing was
desired, but consumer didn't pass the @vm object.

> +goto cleanup;
> +}
> +ret = virDomainDefFormatInternal(def, caps,
> + snapshots ? vm->snapshots : NULL,
> + snapshots ? vm->current_snapshot : NULL,
>   
> virDomainDefFormatConvertXMLFlags(flags),
>   buf, driver->xmlopt);

Perhaps this one should [be | have been] turned into a
virDomainDefFormatFull (or whatever new name is chosen if one is
chosen).  I think it shows the hazards of exposing *Internal to many
consumers.

> 
> @@ -7899,19 +7909,21 @@ qemuDomainDefFormatBuf(virQEMUDriverPtr driver,
> unsigned int flags,
> virBufferPtr buf)
>  {
> -return qemuDomainDefFormatBufInternal(driver, def, NULL, flags, buf);
> +return qemuDomainDefFormatBufInternal(driver, NULL, def, NULL, flags, 
> buf);
>  }
> 
> 
>  static char *
>  qemuDomainDefFormatXMLInternal(virQEMUDriverPtr driver,
> +   virDomainObjPtr vm,
> virDomainDefPtr def,
> virCPUDefPtr origCPU,
> unsigned int flags)
>  {
>  virBuffer buf = VIR_BUFFER_INITIALIZER;
> 
> -if (qemuDomainDefFormatBufInternal(driver, def, origCPU, flags, ) < 
> 0)
> +if (qemuDomainDefFormatBufInternal(driver, vm, def, origCPU, flags,
> +   ) < 0)

Existing; however, considering earlier comment about snapshot list being
filled into the buffer until error, but the *ListFormat not clearing the
buffer 

Re: [libvirt] [PATCH v2 10/11] test: Implement bulk snapshot operations

2019-02-27 Thread John Ferlan



On 2/23/19 4:24 PM, Eric Blake wrote:
> Implement the new flags for bulk snapshot dump and redefine. The
> bulk of the work is already done by the common code.
> 
> Since each connection to test:///default restarts at the same
> canned state, this can easily be tested with:
> 
> $ virsh -c test:///default "
>snapshot-create-as test s1
>snapshot-create-as test s2
>dumpxml test --snapshots" | sed -n '/ list.xml
> $ virsh -c test:///default "
>snapshot-list test
>snapshot-create test --redefine-list list.xml
>snapshot-current --name test
>snapshot-list --parent test
> "
>  Name   Creation Time   State
> ---
> 
> Domain snapshot list imported successfully
> s2
>  Name   Creation Time   State Parent
> --
>  s1 2019-02-20 22:26:52 -0600   running
>  s2 2019-02-20 22:26:52 -0600   running   s1
> 
> The test driver also makes it easy to test input validation, by
> modifying list.xml incorrectly (such as trying to attempt circular
> dependencies).
> 
> Signed-off-by: Eric Blake 
> ---
>  src/test/test_driver.c | 25 -
>  1 file changed, 20 insertions(+), 5 deletions(-)
> 
> diff --git a/src/test/test_driver.c b/src/test/test_driver.c
> index a6a67d42e2..fd0fd6a67a 100644
> --- a/src/test/test_driver.c
> +++ b/src/test/test_driver.c
> @@ -2628,7 +2628,7 @@ static char *testDomainGetXMLDesc(virDomainPtr domain, 
> unsigned int flags)
>  virDomainObjPtr privdom;
>  char *ret = NULL;
> 
> -virCheckFlags(VIR_DOMAIN_XML_COMMON_FLAGS, NULL);
> +virCheckFlags(VIR_DOMAIN_XML_COMMON_FLAGS | VIR_DOMAIN_XML_SNAPSHOTS, 
> NULL);
> 
>  if (!(privdom = testDomObjFromDomain(domain)))
>  return NULL;
> @@ -2636,8 +2636,9 @@ static char *testDomainGetXMLDesc(virDomainPtr domain, 
> unsigned int flags)
>  def = (flags & VIR_DOMAIN_XML_INACTIVE) &&
>  privdom->newDef ? privdom->newDef : privdom->def;
> 
> -ret = virDomainDefFormat(def, privconn->caps,
> - virDomainDefFormatConvertXMLFlags(flags));
> +ret = virDomainDefFormatFull(def, privconn->caps,
> + privdom->snapshots, 
> privdom->current_snapshot,
> + virDomainDefFormatConvertXMLFlags(flags));
> 
>  virDomainObjEndAPI();
>  return ret;
> @@ -6314,6 +6315,7 @@ testDomainSnapshotCreateXML(virDomainPtr domain,
>   * QUIESCE: Nothing to do
>   * ATOMIC: Nothing to do
>   * LIVE: Nothing to do
> + * REDEFINE_LIST: Implemented
>   */
>  virCheckFlags(
>  VIR_DOMAIN_SNAPSHOT_CREATE_REDEFINE |
> @@ -6321,7 +6323,8 @@ testDomainSnapshotCreateXML(virDomainPtr domain,
>  VIR_DOMAIN_SNAPSHOT_CREATE_HALT |
>  VIR_DOMAIN_SNAPSHOT_CREATE_QUIESCE |
>  VIR_DOMAIN_SNAPSHOT_CREATE_ATOMIC |
> -VIR_DOMAIN_SNAPSHOT_CREATE_LIVE, NULL);
> +VIR_DOMAIN_SNAPSHOT_CREATE_LIVE |
> +VIR_DOMAIN_SNAPSHOT_CREATE_REDEFINE_LIST, NULL);
> 
>  if ((redefine && !(flags & VIR_DOMAIN_SNAPSHOT_CREATE_CURRENT)))
>  update_current = false;
> @@ -6337,6 +6340,18 @@ testDomainSnapshotCreateXML(virDomainPtr domain,
>  goto cleanup;
>  }
> 
> +if (flags & VIR_DOMAIN_SNAPSHOT_CREATE_REDEFINE_LIST) {
> +if (virDomainSnapshotDefParseList(xmlDesc, vm->def->uuid, 
> vm->snapshots,
> +  >current_snapshot, 
> privconn->caps,
> +  privconn->xmlopt, parse_flags) < 0)
> +goto cleanup;
> +
> +/* Return is arbitrary, so use the first root */
> +snap = virDomainSnapshotFindByName(vm->snapshots, NULL);

Hmm... I don't think @snap is used since cleanup: code filters on
REDEFINE_LIST, so it would seem this would be leaked then.

Reviewed-by: John Ferlan 

John

> +snapshot = virGetDomainSnapshot(domain, 
> snap->first_child->def->name);
> +goto cleanup;
> +}
> +
>  if (!(def = virDomainSnapshotDefParseString(xmlDesc,
>  privconn->caps,
>  privconn->xmlopt,
> @@ -6384,7 +6399,7 @@ testDomainSnapshotCreateXML(virDomainPtr domain,
>  snapshot = virGetDomainSnapshot(domain, snap->def->name);
>   cleanup:
>  if (vm) {
> -if (snapshot) {
> +if (snapshot && !(flags & VIR_DOMAIN_SNAPSHOT_CREATE_REDEFINE_LIST)) 
> {
>  virDomainSnapshotObjPtr other;
>  if (update_current)
>  vm->current_snapshot = snap;
> 

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


Re: [libvirt] [PATCH v2 09/11] virsh: Expose bulk snapshot dumpxml/redefine

2019-02-27 Thread John Ferlan



On 2/23/19 4:24 PM, Eric Blake wrote:
> Add flags to the 'dumpxml' and 'snapshot-create' commands to pass
> the newly-added bulk snapshot flags through.
> 
> For command-line convenience, I intentionally made --redefine-list
> imply --redefine, even though the counterpart C flags are distinct
> (and you get an error if you pass _REDEFINE_LIST without _REDEFINE).
> 
> Signed-off-by: Eric Blake 
> ---
>  tools/virsh-domain.c   |  7 +++
>  tools/virsh-snapshot.c | 14 ++
>  2 files changed, 21 insertions(+)
> 

Need to update virsh.pod as well to describe new arguments. Do you think
that a separation of the dumpxml and the parse/create into order
pertinent patches would be better? That is the --snapshots for dumpxml
after patch7 (which probably could swap places w/ patch6) so that the
dumpxml and parse/create functionality is all in logical order. It's not
that important.

John

[...]

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


Re: [libvirt] [PATCH v2 08/11] snapshot: Add VIR_DOMAIN_SNAPSHOT_CREATE_REDEFINE_LIST flag

2019-02-27 Thread John Ferlan



On 2/23/19 4:24 PM, Eric Blake wrote:
> Continue the work of the previous patch in making it possible
> to copy the state of a transient domain with snapshots from one
> host to another, by allowing the destination to perform bulk
> redefines.  Note that the destination still has to do separate
> calls for creating/defining the domain first, and then redefining
> the snapshots (that is, there is intentional asymmetry between
> dumping the list in virDomainGetXMLDesc() but redefining it via
> virDomainSnapshotCreateXML()), but this is better than the
> previous state of having to make multiple REDEFINE calls.  The
> bulk flag requires no pre-existing snapshot metadata (as that
> makes life much easier if there is a failure encountered partway
> through the list processing - simply remove all other snapshot
> metadatas), and makes no guarantees on which snapshot (when there
> are multiple) will actually be returned.
> 
> Actual driver implementations will be in later patches.
> 
> Signed-off-by: Eric Blake 
> ---
>  include/libvirt/libvirt-domain-snapshot.h |  3 +++
>  src/libvirt-domain-snapshot.c | 21 ++---
>  2 files changed, 21 insertions(+), 3 deletions(-)
> 

Reviewed-by: John Ferlan 

John

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


Re: [libvirt] [PATCH v2 07/11] domain: Add VIR_DOMAIN_XML_SNAPSHOTS flag

2019-02-27 Thread John Ferlan



On 2/23/19 4:24 PM, Eric Blake wrote:
> Right now, copying the state of a transient domain with snapshots
> from one host to another requires multiple API calls on both
> machines - on the host: get the domain XML, get a list of the
> snapshots, and then for each snapshot get the snapshot's XML;
> then on the destination: create the domain, then multiple
> domain snapshot create calls with the REDEFINE flag.  This
> patch aims to make the process use fewer APIs by making it
> possible to grab the XML for all snapshots at the same time as
> grabbing the domain XML.  Note that we had to do the modification
> to virDomainGetXMLDesc(), rather than virDomainSnapshotGetXMLDesc(),
> since the latter requires a single non-NULL snapshot object,
> whereas we want the list of all snapshots for the domain (even
> if the list has 0 elements).
> 
> Once wired up in drivers in later patches, the new information
> is provided as:
> 
> 
>   ...
>   
>   
> 
>   ...
> 
> 
>   ...
> 
>   
> 
> 
> For now, I did not modify the schema to permit this information
> during virDomainDefineXML; it is still necessary to use
> virDomainSnapshotCreateXML with VIR_DOMAIN_SNAPSHOT_CREATE_REDEFINE
> multiple times to recreate the added state output here.
> 
> Unfortunately, libvirt versions between 1.2.12 and 5.0.0 will
> silently ignore the new flag, rather than diagnosing that they
> don't support it; but at least silent lack of snapshots from
> an older server is not a security hole.
> 
> Signed-off-by: Eric Blake 
> ---
>  include/libvirt/libvirt-domain.h |  1 +
>  src/conf/domain_conf.c   | 13 -
>  src/libvirt-domain.c |  5 +
>  3 files changed, 14 insertions(+), 5 deletions(-)
> 

[...]

> diff --git a/src/libvirt-domain.c b/src/libvirt-domain.c
> index 072b92b717..2691698bd5 100644
> --- a/src/libvirt-domain.c
> +++ b/src/libvirt-domain.c
> @@ -2570,6 +2570,11 @@ virDomainGetControlInfo(virDomainPtr domain,
>   * XML might not validate against the schema, so it is mainly for
>   * internal use.
>   *
> + * If @flags contains VIR_DOMAIN_XML_SNAPSHOTS, the XML will include

Should we even try to say that "and supported by the target libvirt
system with the appropriate version of the software installed" ;-)... I
know implied somewhat - but perhaps notable in this (and future) cases
because of the issue mentioned in the commit message that outward facing
docs consumers may never read.

> + * an additional  child element describing all snapshots
> + * belonging to the domain, including an attribute current='name' if
> + * one of those snapshots is current.
> + *
>   * Returns a 0 terminated UTF-8 encoded XML instance, or NULL in case of 
> error.
>   * the caller must free() the returned value.
>   */
> 

Reviewed-by: John Ferlan 

John

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


[libvirt] [PATCH v2 32/36] network: add implementation of network port APIs

2019-02-27 Thread Daniel P . Berrangé
This initial implementation just wires up the APIs and does tracking of
the port XML definitions. It is not yet integrated into the resource
allocation logic.

Signed-off-by: Daniel P. Berrangé 
---
 src/network/bridge_driver.c | 400 
 1 file changed, 400 insertions(+)

diff --git a/src/network/bridge_driver.c b/src/network/bridge_driver.c
index b23037335f..675abe0fc2 100644
--- a/src/network/bridge_driver.c
+++ b/src/network/bridge_driver.c
@@ -2765,6 +2765,8 @@ networkStartNetwork(virNetworkDriverStatePtr driver,
 
 VIR_DEBUG("Beginning network startup process");
 
+virNetworkObjDeleteAllPorts(obj, driver->stateDir);
+
 VIR_DEBUG("Setting current network def as transient");
 if (virNetworkObjSetDefTransient(obj, true) < 0)
 goto cleanup;
@@ -3940,6 +3942,9 @@ networkDestroy(virNetworkPtr net)
 
 if ((ret = networkShutdownNetwork(driver, obj)) < 0)
 goto cleanup;
+
+virNetworkObjDeleteAllPorts(obj, driver->stateDir);
+
 /* @def replaced in virNetworkObjUnsetDefTransient*/
 def = virNetworkObjGetDef(obj);
 
@@ -5521,6 +5526,394 @@ networkBandwidthUpdate(virDomainNetDefPtr iface,
 }
 
 
+static virNetworkPortPtr
+networkPortLookupByUUID(virNetworkPtr net,
+const unsigned char *uuid)
+{
+virNetworkObjPtr obj;
+virNetworkDefPtr def;
+virNetworkPortDefPtr portdef = NULL;
+virNetworkPortPtr ret = NULL;
+char uuidstr[VIR_UUID_STRING_BUFLEN];
+virUUIDFormat(uuid, uuidstr);
+
+if (!(obj = networkObjFromNetwork(net)))
+return ret;
+
+def = virNetworkObjGetDef(obj);
+
+if (!(portdef = virNetworkObjLookupPort(obj, uuid)))
+goto cleanup;
+
+if (virNetworkPortLookupByUUIDEnsureACL(net->conn, def, portdef) < 0)
+goto cleanup;
+
+if (!virNetworkObjIsActive(obj)) {
+virReportError(VIR_ERR_OPERATION_INVALID,
+   _("network '%s' is not active"),
+   def->name);
+goto cleanup;
+}
+
+ret = virGetNetworkPort(net, uuid);
+
+ cleanup:
+virNetworkObjEndAPI();
+return ret;
+}
+
+
+static virNetworkPortPtr
+networkPortCreateXML(virNetworkPtr net,
+ const char *xmldesc,
+ unsigned int flags)
+{
+virNetworkDriverStatePtr driver = networkGetDriver();
+virNetworkObjPtr obj;
+virNetworkDefPtr def;
+virNetworkPortDefPtr portdef = NULL;
+virNetworkPortPtr ret = NULL;
+int rc;
+
+virCheckFlags(VIR_NETWORK_PORT_CREATE_RECLAIM, NULL);
+
+if (!(obj = networkObjFromNetwork(net)))
+return ret;
+
+def = virNetworkObjGetDef(obj);
+
+if (!(portdef = virNetworkPortDefParseString(xmldesc)))
+goto cleanup;
+
+if (virNetworkPortCreateXMLEnsureACL(net->conn, def, portdef) < 0)
+goto cleanup;
+
+if (!virNetworkObjIsActive(obj)) {
+virReportError(VIR_ERR_OPERATION_INVALID,
+   _("network '%s' is not active"),
+   def->name);
+goto cleanup;
+}
+
+if (portdef->plugtype == VIR_NETWORK_PORT_PLUG_TYPE_NONE) {
+if (flags & VIR_NETWORK_PORT_CREATE_RECLAIM) {
+virReportError(VIR_ERR_INVALID_ARG, "%s",
+   _("Port reclaim requested but plug type is none"));
+goto cleanup;
+}
+} else {
+if (!(flags & VIR_NETWORK_PORT_CREATE_RECLAIM)) {
+virReportError(VIR_ERR_INVALID_ARG, "%s",
+   _("Port reclaim not requested but plug type is not 
none"));
+goto cleanup;
+}
+}
+
+if (flags & VIR_NETWORK_PORT_CREATE_RECLAIM)
+rc = networkNotifyPort(obj, portdef);
+else
+rc = networkAllocatePort(obj, portdef);
+if (rc < 0) {
+virErrorPtr saved;
+saved = virSaveLastError();
+ignore_value(networkReleasePort(obj, portdef));
+virSetError(saved);
+virFreeError(saved);
+goto cleanup;
+}
+
+if (virNetworkObjAddPort(obj, portdef, driver->stateDir) < 0) {
+virNetworkPortDefFree(portdef);
+goto cleanup;
+}
+
+ret = virGetNetworkPort(net, portdef->uuid);
+ cleanup:
+virNetworkObjEndAPI();
+return ret;
+}
+
+
+static char *
+networkPortGetXMLDesc(virNetworkPortPtr port,
+  unsigned int flags)
+{
+virNetworkObjPtr obj;
+virNetworkDefPtr def;
+virNetworkPortDefPtr portdef = NULL;
+char *ret = NULL;
+
+virCheckFlags(0, NULL);
+
+if (!(obj = networkObjFromNetwork(port->net)))
+return ret;
+
+def = virNetworkObjGetDef(obj);
+
+if (!(portdef = virNetworkObjLookupPort(obj, port->uuid)))
+goto cleanup;
+
+if (virNetworkPortGetXMLDescEnsureACL(port->net->conn, def, portdef) < 0)
+goto cleanup;
+
+if (!virNetworkObjIsActive(obj)) {
+virReportError(VIR_ERR_OPERATION_INVALID,
+   _("network '%s' is not active"),
+  

[libvirt] [PATCH v2 34/36] lxc, libxl: save domain status after reconnect

2019-02-27 Thread Daniel P . Berrangé
The various steps involved in reconnecting to a domain may cause updates
to the virDomainObj struct that need to be reflected in the saved status
file.

Signed-off-by: Daniel P. Berrangé 
---
 src/libxl/libxl_driver.c | 3 +++
 src/lxc/lxc_process.c| 5 +
 2 files changed, 8 insertions(+)

diff --git a/src/libxl/libxl_driver.c b/src/libxl/libxl_driver.c
index 68587db303..84a1cb44c5 100644
--- a/src/libxl/libxl_driver.c
+++ b/src/libxl/libxl_driver.c
@@ -454,6 +454,9 @@ libxlReconnectDomain(virDomainObjPtr vm,
 
 libxlReconnectNotifyNets(vm->def);
 
+if (virDomainSaveStatus(driver->xmlopt, cfg->stateDir, vm, cfg->caps) < 0)
+VIR_WARN("Cannot update XML for running Xen guest %s", vm->def->name);
+
 /* now that we know it's reconnected call the hook if present */
 if (virHookPresent(VIR_HOOK_DRIVER_LIBXL) &&
 STRNEQ("Domain-0", vm->def->name)) {
diff --git a/src/lxc/lxc_process.c b/src/lxc/lxc_process.c
index 49776fba3a..a08c3c6a72 100644
--- a/src/lxc/lxc_process.c
+++ b/src/lxc/lxc_process.c
@@ -1676,6 +1676,7 @@ virLXCProcessReconnectDomain(virDomainObjPtr vm,
 {
 virLXCDriverPtr driver = opaque;
 virLXCDomainObjPrivatePtr priv;
+virLXCDriverConfigPtr cfg = virLXCDriverGetConfig(driver);
 int ret = -1;
 
 virObjectLock(vm);
@@ -1718,6 +1719,9 @@ virLXCProcessReconnectDomain(virDomainObjPtr vm,
 
 virLXCProcessReconnectNotifyNets(vm->def);
 
+if (virDomainSaveStatus(driver->xmlopt, cfg->stateDir, vm, 
driver->caps) < 0)
+VIR_WARN("Cannot update XML for running LXC guest %s", 
vm->def->name);
+
 /* now that we know it's reconnected call the hook if present */
 if (virHookPresent(VIR_HOOK_DRIVER_LXC)) {
 char *xml = virDomainDefFormat(vm->def, driver->caps, 0);
@@ -1738,6 +1742,7 @@ virLXCProcessReconnectDomain(virDomainObjPtr vm,
 
 ret = 0;
  cleanup:
+virObjectUnref(cfg);
 virObjectUnlock(vm);
 return ret;
 
-- 
2.20.1

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

[libvirt] [PATCH v2 33/36] lxc, libxl: notify network driver of NICs during reconnect

2019-02-27 Thread Daniel P . Berrangé
When starting up it is important to notify the network driver of any
NICs which are used by running guests so that it can account for any
resources they are using.

Signed-off-by: Daniel P. Berrangé 
---
 src/libxl/libxl_driver.c | 30 ++
 src/lxc/lxc_process.c| 30 ++
 2 files changed, 60 insertions(+)

diff --git a/src/libxl/libxl_driver.c b/src/libxl/libxl_driver.c
index 2df3f5d363..68587db303 100644
--- a/src/libxl/libxl_driver.c
+++ b/src/libxl/libxl_driver.c
@@ -352,6 +352,34 @@ libxlAutostartDomain(virDomainObjPtr vm,
 return ret;
 }
 
+
+static void
+libxlReconnectNotifyNets(virDomainDefPtr def)
+{
+size_t i;
+virConnectPtr conn = NULL;
+
+for (i = 0; i < def->nnets; i++) {
+virDomainNetDefPtr net = def->nets[i];
+/* keep others from trying to use the macvtap device name, but
+ * don't return error if this happens, since that causes the
+ * domain to be unceremoniously killed, which would be *very*
+ * impolite.
+ */
+if (virDomainNetGetActualType(net) == VIR_DOMAIN_NET_TYPE_DIRECT)
+   ignore_value(virNetDevMacVLanReserveName(net->ifname, false));
+
+if (net->type == VIR_DOMAIN_NET_TYPE_NETWORK) {
+if (!conn && !(conn = virGetConnectNetwork()))
+continue;
+virDomainNetNotifyActualDevice(conn, def, net);
+}
+}
+
+virObjectUnref(conn);
+}
+
+
 /*
  * Reconnect to running domains that were previously started/created
  * with libxenlight driver.
@@ -424,6 +452,8 @@ libxlReconnectDomain(virDomainObjPtr vm,
 /* Enable domain death events */
 libxl_evenable_domain_death(cfg->ctx, vm->def->id, 0, >deathW);
 
+libxlReconnectNotifyNets(vm->def);
+
 /* now that we know it's reconnected call the hook if present */
 if (virHookPresent(VIR_HOOK_DRIVER_LIBXL) &&
 STRNEQ("Domain-0", vm->def->name)) {
diff --git a/src/lxc/lxc_process.c b/src/lxc/lxc_process.c
index 8c3f884d75..49776fba3a 100644
--- a/src/lxc/lxc_process.c
+++ b/src/lxc/lxc_process.c
@@ -1642,6 +1642,34 @@ virLXCProcessAutostartAll(virLXCDriverPtr driver)
 virObjectUnref(conn);
 }
 
+
+static void
+virLXCProcessReconnectNotifyNets(virDomainDefPtr def)
+{
+size_t i;
+virConnectPtr conn = NULL;
+
+for (i = 0; i < def->nnets; i++) {
+virDomainNetDefPtr net = def->nets[i];
+/* keep others from trying to use the macvtap device name, but
+ * don't return error if this happens, since that causes the
+ * domain to be unceremoniously killed, which would be *very*
+ * impolite.
+ */
+if (virDomainNetGetActualType(net) == VIR_DOMAIN_NET_TYPE_DIRECT)
+   ignore_value(virNetDevMacVLanReserveName(net->ifname, false));
+
+if (net->type == VIR_DOMAIN_NET_TYPE_NETWORK) {
+if (!conn && !(conn = virGetConnectNetwork()))
+continue;
+virDomainNetNotifyActualDevice(conn, def, net);
+}
+}
+
+virObjectUnref(conn);
+}
+
+
 static int
 virLXCProcessReconnectDomain(virDomainObjPtr vm,
  void *opaque)
@@ -1688,6 +1716,8 @@ virLXCProcessReconnectDomain(virDomainObjPtr vm,
vm->def, vm->pid) < 0)
 goto error;
 
+virLXCProcessReconnectNotifyNets(vm->def);
+
 /* now that we know it's reconnected call the hook if present */
 if (virHookPresent(VIR_HOOK_DRIVER_LXC)) {
 char *xml = virDomainDefFormat(vm->def, driver->caps, 0);
-- 
2.20.1

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

Re: [libvirt] [PATCH v2 06/11] snapshot: Add virDomainSnapshotDefParseList

2019-02-27 Thread John Ferlan



On 2/23/19 4:24 PM, Eric Blake wrote:
> Add a new function to make it possible to parse a list of snapshots
> at once.  This is a counterpart to the previous patch making it
> possible to produce all snapshots in a single XML string, and
> intentionally parses the same top-level element  with
> an optional attribute current='name'.
> 
> Note that existing REDEFINE code uses virDomainSnapshotRedefinePrep()
> for some sanity checking - much of that checking involves parent/child
> relationships (which make sense when doing one element at a time and
> worrying about replacement), but where this patch gets away with the
> much simpler final call to virDomainSnapshotUpdateRelations() (for
> all relationship checking after the end, since we know we started with
> no relations at all, and since checking parent relationships
> per-snapshot is not viable as we don't control which order the
> snapshots appear in).  All other domain-agnostic sanity checks used
> during a redefinition are copied here.

Some day maybe there's a helper that can handle both uses...

> 
> Signed-off-by: Eric Blake 
> ---
>  src/conf/snapshot_conf.h |   7 ++
>  src/conf/snapshot_conf.c | 135 +++
>  src/libvirt_private.syms |   1 +
>  3 files changed, 143 insertions(+)
> 
> diff --git a/src/conf/snapshot_conf.h b/src/conf/snapshot_conf.h
> index 19ab75f895..6a92241fe6 100644
> --- a/src/conf/snapshot_conf.h
> +++ b/src/conf/snapshot_conf.h
> @@ -117,6 +117,13 @@ virDomainSnapshotDefPtr 
> virDomainSnapshotDefParseNode(xmlDocPtr xml,
>virCapsPtr caps,
>virDomainXMLOptionPtr 
> xmlopt,
>unsigned int flags);
> +int virDomainSnapshotDefParseList(const char *xmlSstr,
> +  const unsigned char *domain_uuid,
> +  virDomainSnapshotObjListPtr snapshots,
> +  virDomainSnapshotObjPtr *current_snap,
> +  virCapsPtr caps,
> +  virDomainXMLOptionPtr xmlopt,
> +  unsigned int flags);

virDomainSnapshotObjListParse (consistency w/
virDomainSnapshotObjListFormat)

>  void virDomainSnapshotDefFree(virDomainSnapshotDefPtr def);
>  char *virDomainSnapshotDefFormat(const char *uuidstr,
>   virDomainSnapshotDefPtr def,
> diff --git a/src/conf/snapshot_conf.c b/src/conf/snapshot_conf.c
> index 963dc10247..61e26726e9 100644
> --- a/src/conf/snapshot_conf.c
> +++ b/src/conf/snapshot_conf.c
> @@ -426,6 +426,141 @@ virDomainSnapshotDefParseString(const char *xmlStr,
>  }
> 
> 
> +int virDomainSnapshotDefParseList(const char *xmlStr,
> +  const unsigned char *domain_uuid,
> +  virDomainSnapshotObjListPtr snapshots,
> +  virDomainSnapshotObjPtr *current_snap,
> +  virCapsPtr caps,
> +  virDomainXMLOptionPtr xmlopt,
> +  unsigned int flags)

int
virDomainSnapshotObjListParse(...)

> +{
> +int ret = -1;
> +xmlDocPtr xml;
> +xmlNodePtr root;
> +xmlXPathContextPtr ctxt = NULL;
> +char *current = NULL;
> +int n;
> +size_t i;
> +VIR_AUTOFREE(xmlNodePtr *) nodes = NULL;
> +int keepBlanksDefault = xmlKeepBlanksDefault(0);
VIR_AUTOFREE(char *) current = NULL;

Typically it's been requested to keep all the VIR_AUTO* at the end of
arguments... Of course beyond the one change Peter decided not to
re-open his editor to modify after review comment requested otherwise.

[...]

> diff --git a/src/libvirt_private.syms b/src/libvirt_private.syms
> index c623737c30..96f54a97fe 100644
> --- a/src/libvirt_private.syms
> +++ b/src/libvirt_private.syms
> @@ -881,6 +881,7 @@ virDomainSnapshotAssignDef;
>  virDomainSnapshotDefFormat;
>  virDomainSnapshotDefFree;
>  virDomainSnapshotDefIsExternal;
> +virDomainSnapshotDefParseList;

virDomainSnapshotObjListParse;

>  virDomainSnapshotDefParseString;
>  virDomainSnapshotDropParent;
>  virDomainSnapshotFindByName;
> 

Simple enough adjustments...

Reviewed-by: John Ferlan 

John

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


[libvirt] [PATCH v2 28/36] access: add permissions for network port objects

2019-02-27 Thread Daniel P . Berrangé
Signed-off-by: Daniel P. Berrangé 
---
 src/access/genpolkit.pl|  2 +-
 src/access/viraccessdriver.h   |  6 
 src/access/viraccessdrivernop.c| 11 
 src/access/viraccessdriverpolkit.c | 26 ++
 src/access/viraccessdriverstack.c  | 25 +
 src/access/viraccessmanager.c  | 16 +++
 src/access/viraccessmanager.h  |  6 
 src/access/viraccessperm.c |  6 
 src/access/viraccessperm.h | 44 ++
 9 files changed, 141 insertions(+), 1 deletion(-)

diff --git a/src/access/genpolkit.pl b/src/access/genpolkit.pl
index e074c90eb6..f8f20caf65 100755
--- a/src/access/genpolkit.pl
+++ b/src/access/genpolkit.pl
@@ -21,7 +21,7 @@ use strict;
 use warnings;
 
 my @objects = (
-"CONNECT", "DOMAIN", "INTERFACE",
+"CONNECT", "DOMAIN", "INTERFACE", "NETWORK_PORT",
 "NETWORK","NODE_DEVICE", "NWFILTER_BINDING", "NWFILTER",
 "SECRET", "STORAGE_POOL", "STORAGE_VOL",
 );
diff --git a/src/access/viraccessdriver.h b/src/access/viraccessdriver.h
index 2cc3950f60..590d86fdf0 100644
--- a/src/access/viraccessdriver.h
+++ b/src/access/viraccessdriver.h
@@ -39,6 +39,11 @@ typedef int 
(*virAccessDriverCheckNetworkDrv)(virAccessManagerPtr manager,
   const char *driverName,
   virNetworkDefPtr network,
   virAccessPermNetwork av);
+typedef int (*virAccessDriverCheckNetworkPortDrv)(virAccessManagerPtr manager,
+  const char *driverName,
+  virNetworkDefPtr network,
+  virNetworkPortDefPtr port,
+  virAccessPermNetworkPort av);
 typedef int (*virAccessDriverCheckNodeDeviceDrv)(virAccessManagerPtr manager,
  const char *driverName,
  virNodeDeviceDefPtr nodedev,
@@ -82,6 +87,7 @@ struct _virAccessDriver {
 virAccessDriverCheckDomainDrv checkDomain;
 virAccessDriverCheckInterfaceDrv checkInterface;
 virAccessDriverCheckNetworkDrv checkNetwork;
+virAccessDriverCheckNetworkPortDrv checkNetworkPort;
 virAccessDriverCheckNodeDeviceDrv checkNodeDevice;
 virAccessDriverCheckNWFilterDrv checkNWFilter;
 virAccessDriverCheckNWFilterBindingDrv checkNWFilterBinding;
diff --git a/src/access/viraccessdrivernop.c b/src/access/viraccessdrivernop.c
index 98ef9206c5..5e9d9db759 100644
--- a/src/access/viraccessdrivernop.c
+++ b/src/access/viraccessdrivernop.c
@@ -57,6 +57,16 @@ virAccessDriverNopCheckNetwork(virAccessManagerPtr manager 
ATTRIBUTE_UNUSED,
 return 1; /* Allow */
 }
 
+static int
+virAccessDriverNopCheckNetworkPort(virAccessManagerPtr manager 
ATTRIBUTE_UNUSED,
+   const char *driverName ATTRIBUTE_UNUSED,
+   virNetworkDefPtr network ATTRIBUTE_UNUSED,
+   virNetworkPortDefPtr port ATTRIBUTE_UNUSED,
+   virAccessPermNetworkPort perm 
ATTRIBUTE_UNUSED)
+{
+return 1; /* Allow */
+}
+
 static int
 virAccessDriverNopCheckNodeDevice(virAccessManagerPtr manager ATTRIBUTE_UNUSED,
   const char *driverName ATTRIBUTE_UNUSED,
@@ -119,6 +129,7 @@ virAccessDriver accessDriverNop = {
 .checkDomain = virAccessDriverNopCheckDomain,
 .checkInterface = virAccessDriverNopCheckInterface,
 .checkNetwork = virAccessDriverNopCheckNetwork,
+.checkNetworkPort = virAccessDriverNopCheckNetworkPort,
 .checkNodeDevice = virAccessDriverNopCheckNodeDevice,
 .checkNWFilter = virAccessDriverNopCheckNWFilter,
 .checkNWFilterBinding = virAccessDriverNopCheckNWFilterBinding,
diff --git a/src/access/viraccessdriverpolkit.c 
b/src/access/viraccessdriverpolkit.c
index 6954d74a15..b1473cd0a4 100644
--- a/src/access/viraccessdriverpolkit.c
+++ b/src/access/viraccessdriverpolkit.c
@@ -237,6 +237,31 @@ virAccessDriverPolkitCheckNetwork(virAccessManagerPtr 
manager,
   attrs);
 }
 
+static int
+virAccessDriverPolkitCheckNetworkPort(virAccessManagerPtr manager,
+  const char *driverName,
+  virNetworkDefPtr network,
+  virNetworkPortDefPtr port,
+  virAccessPermNetworkPort perm)
+{
+char uuidstr1[VIR_UUID_STRING_BUFLEN];
+char uuidstr2[VIR_UUID_STRING_BUFLEN];
+const char *attrs[] = {
+"connect_driver", driverName,
+"network_name", network->name,
+"network_uuid", uuidstr1,
+"port_uuid", uuidstr2,
+NULL,
+};
+virUUIDFormat(network->uuid, uuidstr1);
+virUUIDFormat(port->uuid, 

[libvirt] [PATCH v2 21/36] network: convert hook script to take a network port XML

2019-02-27 Thread Daniel P . Berrangé
When (un)plugging an interface into a network, the 'plugged'
and 'unplugged' operations are invoked in the hook script.

The data provided to the script contains the network XML, the
domain XML and the domain interface XML. When we strictly split the
drivers up this will no longer be possible and thus breakage is
unavoidable. The hook scripts are not considered to be covered by the
API guarantee so this is OK.

To avoid existing scripts taking the wrong action, the existing
operations are changed to 'port-created' and 'port-deleted'
instead. These will receive the network XML and the network port
XML.

Signed-off-by: Daniel P. Berrangé 
---
 docs/hooks.html.in  | 24 +++-
 src/network/bridge_driver.c | 27 +++
 src/util/virhook.c  |  4 ++--
 src/util/virhook.h  |  4 ++--
 4 files changed, 26 insertions(+), 33 deletions(-)

diff --git a/docs/hooks.html.in b/docs/hooks.html.in
index 2c4c39b771..7c9d3ef7f3 100644
--- a/docs/hooks.html.in
+++ b/docs/hooks.html.in
@@ -91,10 +91,8 @@
   /network
 /hookData
 
-In the case of an interface
-   being plugged/unplugged to/from the network, the network XML will be
-   followed with the full XML description of the domain containing the
-   interface that is being plugged/unplugged:
+In the case of an network port being created / deleted, the network
+   XML will be followed with the full XML description of the port:
 
 hookData
   network
@@ -102,11 +100,11 @@
  uuidafca425a-2c3a-420c-b2fb-dd7b4950d722/uuid
  ...
   /network
-  domain type='$domain_type' id='$domain_id'
- name$domain_name/name
- uuidafca425a-2c3a-420c-b2fb-dd7b4950d722/uuid
- ...
-  /domain
+  networkport
+uuid5d744f21-ba4a-4d6e-bdb2-30a35ff3207d/uuid
+...
+plug type='direct' dev='ens3' mode='vepa'/
+  /networkport
 /hookData
 
 Please note that this approach is different from other cases such as
@@ -296,15 +294,15 @@
   /etc/libvirt/hooks/network network_name stopped end -
   Later, when network is started and there's an interface from a
 domain to be plugged into the network, the hook script is called 
as:
-  /etc/libvirt/hooks/network network_name plugged begin -
+  /etc/libvirt/hooks/network network_name port-created begin 
-
 Please note, that in this case, the script is passed both network and
-domain XMLs on its stdin.
+port XMLs on its stdin.
   When network is updated, the hook script is called as:
   /etc/libvirt/hooks/network network_name updated begin 
-
   When the domain from previous case is shutting down, the interface
 is unplugged. This leads to another script invocation:
-  /etc/libvirt/hooks/network network_name unplugged begin -
-And again, as in previous case, both network and domain XMLs are passed
+  /etc/libvirt/hooks/network network_name port-deleted begin 
-
+And again, as in previous case, both network and port XMLs are passed
 onto script's stdin.
 
 
diff --git a/src/network/bridge_driver.c b/src/network/bridge_driver.c
index b122acfb6d..6911424e45 100644
--- a/src/network/bridge_driver.c
+++ b/src/network/bridge_driver.c
@@ -205,14 +205,13 @@ networkObjFromNetwork(virNetworkPtr net)
 
 static int
 networkRunHook(virNetworkObjPtr obj,
-   virDomainDefPtr dom,
-   virDomainNetDefPtr iface,
+   virNetworkPortDefPtr port,
int op,
int sub_op)
 {
 virNetworkDefPtr def;
 virBuffer buf = VIR_BUFFER_INITIALIZER;
-char *xml = NULL, *net_xml = NULL, *dom_xml = NULL;
+char *xml = NULL;
 int hookret;
 int ret = -1;
 
@@ -226,11 +225,9 @@ networkRunHook(virNetworkObjPtr obj,
 
 virBufferAddLit(, "\n");
 virBufferAdjustIndent(, 2);
-if (iface && virDomainNetDefFormat(, iface, NULL, 0) < 0)
-goto cleanup;
 if (virNetworkDefFormatBuf(, def, 0) < 0)
 goto cleanup;
-if (dom && virDomainDefFormatInternal(dom, NULL, 0, , NULL) < 0)
+if (port && virNetworkPortDefFormatBuf(, port) < 0)
 goto cleanup;
 
 virBufferAdjustIndent(, -2);
@@ -256,8 +253,6 @@ networkRunHook(virNetworkObjPtr obj,
  cleanup:
 virBufferFreeAndReset();
 VIR_FREE(xml);
-VIR_FREE(net_xml);
-VIR_FREE(dom_xml);
 return ret;
 }
 
@@ -2776,7 +2771,7 @@ networkStartNetwork(virNetworkDriverStatePtr driver,
 
 /* Run an early hook to set-up missing devices.
  * If the script raised an error abort the launch. */
-if (networkRunHook(obj, NULL, NULL,
+if (networkRunHook(obj, NULL,
VIR_HOOK_NETWORK_OP_START,
VIR_HOOK_SUBOP_BEGIN) < 0)
 goto cleanup;
@@ -2818,7 +2813,7 @@ networkStartNetwork(virNetworkDriverStatePtr driver,
 }
 
 /* finally we can call the 'started' hook script if any */
-if 

[libvirt] [PATCH v2 20/36] network: convert networkReleaseActualDevice to virNetworkPortDef

2019-02-27 Thread Daniel P . Berrangé
Convert the virDomainNetDef object into a virNetworkPortDef object
at the start of networkReleaseActualDevice. This largely decouples
the method impl from the domain object type.

Signed-off-by: Daniel P. Berrangé 
---
 src/network/bridge_driver.c | 137 +++-
 1 file changed, 56 insertions(+), 81 deletions(-)

diff --git a/src/network/bridge_driver.c b/src/network/bridge_driver.c
index bbf0ab090c..b122acfb6d 100644
--- a/src/network/bridge_driver.c
+++ b/src/network/bridge_driver.c
@@ -4931,10 +4931,10 @@ networkReleaseActualDevice(virNetworkPtr net,
virDomainNetDefPtr iface)
 {
 virNetworkDriverStatePtr driver = networkGetDriver();
-virDomainNetType actualType = virDomainNetGetActualType(iface);
 virNetworkObjPtr obj;
 virNetworkDefPtr netdef;
 virNetworkForwardIfDefPtr dev = NULL;
+virNetworkPortDefPtr port = NULL;
 size_t i;
 int ret = -1;
 
@@ -4943,77 +4943,49 @@ networkReleaseActualDevice(virNetworkPtr net,
 virReportError(VIR_ERR_NO_NETWORK,
_("no network with matching name '%s'"),
net->name);
-goto error;
+goto cleanup;
 }
 
 if (iface->type != VIR_DOMAIN_NET_TYPE_NETWORK) {
 virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
_("Expected a interface for a virtual network"));
-goto error;
+goto cleanup;
 }
 
+if (iface->data.network.actual == NULL) {
+ret = 0;
+goto cleanup;
+}
+
+if (!(port = virDomainNetDefActualToNetworkPort(dom, iface)))
+goto cleanup;
+
 netdef = virNetworkObjGetDef(obj);
 
-switch ((virNetworkForwardType) netdef->forward.type) {
-case VIR_NETWORK_FORWARD_NONE:
-case VIR_NETWORK_FORWARD_NAT:
-case VIR_NETWORK_FORWARD_ROUTE:
-case VIR_NETWORK_FORWARD_OPEN:
-if (iface->data.network.actual &&
-networkUnplugBandwidth(obj, iface->bandwidth,
-   >data.network.actual->class_id) < 0)
-goto error;
+switch ((virNetworkPortPlugType)port->plugtype) {
+case VIR_NETWORK_PORT_PLUG_TYPE_NONE:
+VIR_DEBUG("Releasing network device with no plug type");
 break;
 
-case VIR_NETWORK_FORWARD_BRIDGE:
-if (iface->data.network.actual &&
-actualType == VIR_DOMAIN_NET_TYPE_BRIDGE &&
-networkUnplugBandwidth(obj, iface->bandwidth,
-   >data.network.actual->class_id) < 0)
-goto error;
-break;
-case VIR_NETWORK_FORWARD_PRIVATE:
-case VIR_NETWORK_FORWARD_VEPA:
-case VIR_NETWORK_FORWARD_PASSTHROUGH:
-case VIR_NETWORK_FORWARD_HOSTDEV:
+case VIR_NETWORK_PORT_PLUG_TYPE_BRIDGE:
+if (networkUnplugBandwidth(obj, port->bandwidth,
+   >class_id) < 0)
+goto cleanup;
 break;
 
-case VIR_NETWORK_FORWARD_LAST:
-default:
-virReportEnumRangeError(virNetworkForwardType, netdef->forward.type);
-goto error;
-}
-
-if ((!iface->data.network.actual) ||
-((actualType != VIR_DOMAIN_NET_TYPE_DIRECT) &&
- (actualType != VIR_DOMAIN_NET_TYPE_HOSTDEV))) {
-VIR_DEBUG("Nothing to release to network %s", 
iface->data.network.name);
-goto success;
-}
-
-if (netdef->forward.nifs == 0) {
-virReportError(VIR_ERR_INTERNAL_ERROR,
-   _("network '%s' uses a direct/hostdev mode, but "
- "has no forward dev and no interface pool"),
-   netdef->name);
-goto error;
-}
-
-if (actualType == VIR_DOMAIN_NET_TYPE_DIRECT) {
-const char *actualDev;
-
-actualDev = virDomainNetGetActualDirectDev(iface);
-if (!actualDev) {
-virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
-   _("the interface uses a direct mode, "
- "but has no source dev"));
-goto error;
+case VIR_NETWORK_PORT_PLUG_TYPE_DIRECT:
+if (netdef->forward.nifs == 0) {
+virReportError(VIR_ERR_INTERNAL_ERROR,
+   _("network '%s' uses a direct mode, but "
+ "has no forward dev and no interface pool"),
+   netdef->name);
+goto cleanup;
 }
 
 for (i = 0; i < netdef->forward.nifs; i++) {
 if (netdef->forward.ifs[i].type
 == VIR_NETWORK_FORWARD_HOSTDEV_DEVICE_NETDEV &&
-STREQ(actualDev, netdef->forward.ifs[i].device.dev)) {
+STREQ(port->plug.direct.linkdev, 
netdef->forward.ifs[i].device.dev)) {
 dev = >forward.ifs[i];
 break;
 }
@@ -5023,23 +4995,24 @@ networkReleaseActualDevice(virNetworkPtr net,
 virReportError(VIR_ERR_INTERNAL_ERROR,
_("network '%s' doesn't have 

[libvirt] [PATCH v2 31/36] conf: support recording ports against virNetworkObjPtr

2019-02-27 Thread Daniel P . Berrangé
The virNetworkObjPtr state will need to maintain a record of all
virNetworkPortDefPtr objects associated with the network. Record these
in a hash and add APIs for manipulating them.

Signed-off-by: Daniel P. Berrangé 
---
 src/conf/virnetworkobj.c | 303 +++
 src/conf/virnetworkobj.h |  34 +
 src/libvirt_private.syms |   6 +
 3 files changed, 343 insertions(+)

diff --git a/src/conf/virnetworkobj.c b/src/conf/virnetworkobj.c
index ae1264325a..4b7b255b0f 100644
--- a/src/conf/virnetworkobj.c
+++ b/src/conf/virnetworkobj.c
@@ -58,6 +58,8 @@ struct _virNetworkObj {
 
 /* Immutable pointer, self locking APIs */
 virMacMapPtr macmap;
+
+virHashTablePtr ports; /* uuid -> virNetworkPortDefPtr */
 };
 
 struct _virNetworkObjList {
@@ -86,6 +88,17 @@ virNetworkObjOnceInit(void)
 
 VIR_ONCE_GLOBAL_INIT(virNetworkObj);
 
+static int
+virNetworkObjLoadAllPorts(virNetworkObjPtr net,
+  const char *stateDir);
+
+
+static void
+virNetworkObjPortFree(void *val, const void *key ATTRIBUTE_UNUSED)
+{
+virNetworkPortDefFree(val);
+}
+
 virNetworkObjPtr
 virNetworkObjNew(void)
 {
@@ -106,6 +119,10 @@ virNetworkObjNew(void)
 virBitmapSetBitExpand(obj->classIdMap, 2) < 0)
 goto error;
 
+if (!(obj->ports = virHashCreate(10,
+ virNetworkObjPortFree)))
+goto error;
+
 virObjectLock(obj);
 
 return obj;
@@ -458,6 +475,7 @@ virNetworkObjDispose(void *opaque)
 {
 virNetworkObjPtr obj = opaque;
 
+virHashFree(obj->ports);
 virNetworkDefFree(obj->def);
 virNetworkDefFree(obj->newDef);
 virBitmapFree(obj->classIdMap);
@@ -1072,9 +1090,16 @@ virNetworkObjLoadAllState(virNetworkObjListPtr nets,
 continue;
 
 obj = virNetworkLoadState(nets, stateDir, entry->d_name);
+
+if (obj &&
+virNetworkObjLoadAllPorts(obj, stateDir) < 0) {
+virNetworkObjEndAPI();
+goto cleanup;
+}
 virNetworkObjEndAPI();
 }
 
+ cleanup:
 VIR_DIR_CLOSE(dir);
 return ret;
 }
@@ -1584,3 +1609,281 @@ virNetworkObjListPrune(virNetworkObjListPtr nets,
 virHashRemoveSet(nets->objs, virNetworkObjListPruneHelper, );
 virObjectRWUnlock(nets);
 }
+
+
+char *
+virNetworkObjGetPortStatusDir(virNetworkObjPtr net,
+  const char *stateDir)
+{
+char *ret;
+ignore_value(virAsprintf(, "%s/%s/ports", stateDir, net->def->name));
+return ret;
+}
+
+int
+virNetworkObjAddPort(virNetworkObjPtr net,
+ virNetworkPortDefPtr portdef,
+ const char *stateDir)
+{
+int ret = -1;
+char uuidstr[VIR_UUID_STRING_BUFLEN];
+char *dir = NULL;
+
+virUUIDFormat(portdef->uuid, uuidstr);
+
+if (virHashLookup(net->ports, uuidstr)) {
+virReportError(VIR_ERR_NETWORK_PORT_EXIST,
+   _("Network port with UUID %s already exists"),
+   uuidstr);
+goto cleanup;
+}
+
+if (!(dir = virNetworkObjGetPortStatusDir(net, stateDir)))
+goto cleanup;
+
+if (virHashAddEntry(net->ports, uuidstr, portdef) < 0)
+goto cleanup;
+
+if (virNetworkPortDefSaveStatus(portdef, dir) < 0) {
+virHashRemoveEntry(net->ports, uuidstr);
+goto cleanup;
+}
+
+ret = 0;
+
+ cleanup:
+return ret;
+}
+
+
+virNetworkPortDefPtr
+virNetworkObjLookupPort(virNetworkObjPtr net,
+const unsigned char *uuid)
+{
+virNetworkPortDefPtr ret = NULL;
+char uuidstr[VIR_UUID_STRING_BUFLEN];
+
+virUUIDFormat(uuid, uuidstr);
+
+if (!(ret = virHashLookup(net->ports, uuidstr))) {
+virReportError(VIR_ERR_NO_NETWORK_PORT,
+   _("Network port with UUID %s does not exist"),
+   uuidstr);
+goto cleanup;
+}
+
+ cleanup:
+return ret;
+}
+
+
+int
+virNetworkObjDeletePort(virNetworkObjPtr net,
+const unsigned char *uuid,
+const char *stateDir)
+{
+int ret = -1;
+char uuidstr[VIR_UUID_STRING_BUFLEN];
+char *dir = NULL;
+virNetworkPortDefPtr portdef;
+
+virUUIDFormat(uuid, uuidstr);
+
+if (!(portdef = virHashLookup(net->ports, uuidstr))) {
+virReportError(VIR_ERR_NO_NETWORK_PORT,
+   _("Network port with UUID %s does not exist"),
+   uuidstr);
+goto cleanup;
+}
+
+if (!(dir = virNetworkObjGetPortStatusDir(net, stateDir)))
+goto cleanup;
+
+if (virNetworkPortDefDeleteStatus(portdef, dir) < 0)
+goto cleanup;
+
+if (virHashRemoveEntry(net->ports, uuidstr) < 0)
+goto cleanup;
+
+ret = 0;
+
+ cleanup:
+VIR_FREE(dir);
+return ret;
+}
+
+
+int
+virNetworkObjDeleteAllPorts(virNetworkObjPtr net,
+const char *stateDir)
+{
+char *dir;
+DIR *dh;
+struct dirent *de;
+int rc;
+int ret = -1;
+
+  

[libvirt] [PATCH v2 25/36] network: introduce networkReleasePort

2019-02-27 Thread Daniel P . Berrangé
Separate network port deletion code from the domain driver network
callback implementation.

Signed-off-by: Daniel P. Berrangé 
---
 src/network/bridge_driver.c | 91 -
 1 file changed, 59 insertions(+), 32 deletions(-)

diff --git a/src/network/bridge_driver.c b/src/network/bridge_driver.c
index ef85456d5f..abc6b248aa 100644
--- a/src/network/bridge_driver.c
+++ b/src/network/bridge_driver.c
@@ -4940,9 +4940,9 @@ networkNotifyActualDevice(virNetworkPtr net,
 }
 
 
-/* networkReleaseActualDevice:
- * @dom: domain definition that @iface belongs to
- * @iface:  a domain's NetDef (interface definition)
+/* networkReleasePort:
+ * @obj: the network to release from
+ * @port: the port definition to release
  *
  * Given a domain  element that previously had its 
  * element filled in (and possibly a physical device allocated to it),
@@ -4952,40 +4952,15 @@ networkNotifyActualDevice(virNetworkPtr net,
  * Returns 0 on success, -1 on failure.
  */
 static int
-networkReleaseActualDevice(virNetworkPtr net,
-   virDomainDefPtr dom,
-   virDomainNetDefPtr iface)
+networkReleasePort(virNetworkObjPtr obj,
+   virNetworkPortDefPtr port)
 {
 virNetworkDriverStatePtr driver = networkGetDriver();
-virNetworkObjPtr obj;
 virNetworkDefPtr netdef;
 virNetworkForwardIfDefPtr dev = NULL;
-virNetworkPortDefPtr port = NULL;
 size_t i;
 int ret = -1;
 
-obj = virNetworkObjFindByName(driver->networks, net->name);
-if (!obj) {
-virReportError(VIR_ERR_NO_NETWORK,
-   _("no network with matching name '%s'"),
-   net->name);
-goto cleanup;
-}
-
-if (iface->type != VIR_DOMAIN_NET_TYPE_NETWORK) {
-virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
-   _("Expected a interface for a virtual network"));
-goto cleanup;
-}
-
-if (iface->data.network.actual == NULL) {
-ret = 0;
-goto cleanup;
-}
-
-if (!(port = virDomainNetDefActualToNetworkPort(dom, iface)))
-goto cleanup;
-
 netdef = virNetworkObjGetDef(obj);
 
 switch ((virNetworkPortPlugType)port->plugtype) {
@@ -5064,7 +5039,7 @@ networkReleaseActualDevice(virNetworkPtr net,
 goto cleanup;
 }
 
-virNetworkObjMacMgrDel(obj, driver->dnsmasqStateDir, dom->name, 
>mac);
+virNetworkObjMacMgrDel(obj, driver->dnsmasqStateDir, port->ownername, 
>mac);
 
 netdef->connections--;
 if (dev)
@@ -5072,7 +5047,59 @@ networkReleaseActualDevice(virNetworkPtr net,
 /* finally we can call the 'unplugged' hook script if any */
 networkRunHook(obj, port, VIR_HOOK_NETWORK_OP_PORT_DELETED,
VIR_HOOK_SUBOP_BEGIN);
-networkLogAllocation(netdef, dev, >mac, false);
+networkLogAllocation(netdef, dev, >mac, false);
+
+ret = 0;
+ cleanup:
+return ret;
+}
+
+
+/* networkReleaseActualDevice:
+ * @dom: domain definition that @iface belongs to
+ * @iface:  a domain's NetDef (interface definition)
+ *
+ * Given a domain  element that previously had its 
+ * element filled in (and possibly a physical device allocated to it),
+ * free up the physical device for use by someone else, and free the
+ * virDomainActualNetDef.
+ *
+ * Returns 0 on success, -1 on failure.
+ */
+static int
+networkReleaseActualDevice(virNetworkPtr net,
+   virDomainDefPtr dom,
+   virDomainNetDefPtr iface)
+{
+virNetworkDriverStatePtr driver = networkGetDriver();
+virNetworkObjPtr obj;
+virNetworkPortDefPtr port = NULL;
+int ret = -1;
+
+obj = virNetworkObjFindByName(driver->networks, net->name);
+if (!obj) {
+virReportError(VIR_ERR_NO_NETWORK,
+   _("no network with matching name '%s'"),
+   net->name);
+goto cleanup;
+}
+
+if (iface->type != VIR_DOMAIN_NET_TYPE_NETWORK) {
+virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
+   _("Expected a interface for a virtual network"));
+goto cleanup;
+}
+
+if (iface->data.network.actual == NULL) {
+ret = 0;
+goto cleanup;
+}
+
+if (!(port = virDomainNetDefActualToNetworkPort(dom, iface)))
+goto cleanup;
+
+if (networkReleasePort(obj, port) < 0)
+goto cleanup;
 
 ret = 0;
  cleanup:
-- 
2.20.1

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

[libvirt] [PATCH v2 19/36] network: convert networkNotifyActualDevice to virNetworkPortDef

2019-02-27 Thread Daniel P . Berrangé
Convert the virDomainNetDef object into a virNetworkPortDef object
at the start of networkNotifyActualDevice. This largely decouples
the method impl from the domain object type.

Signed-off-by: Daniel P. Berrangé 
---
 src/network/bridge_driver.c | 91 ++---
 1 file changed, 44 insertions(+), 47 deletions(-)

diff --git a/src/network/bridge_driver.c b/src/network/bridge_driver.c
index 365753baf2..bbf0ab090c 100644
--- a/src/network/bridge_driver.c
+++ b/src/network/bridge_driver.c
@@ -4748,10 +4748,10 @@ networkNotifyActualDevice(virNetworkPtr net,
   virDomainNetDefPtr iface)
 {
 virNetworkDriverStatePtr driver = networkGetDriver();
-virDomainNetType actualType = virDomainNetGetActualType(iface);
 virNetworkObjPtr obj;
 virNetworkDefPtr netdef;
 virNetworkForwardIfDefPtr dev = NULL;
+virNetworkPortDefPtr port = NULL;
 size_t i;
 int ret = -1;
 
@@ -4778,40 +4778,34 @@ networkNotifyActualDevice(virNetworkPtr net,
 goto error;
 }
 
-if (!iface->data.network.actual ||
-(actualType != VIR_DOMAIN_NET_TYPE_DIRECT &&
- actualType != VIR_DOMAIN_NET_TYPE_HOSTDEV)) {
-VIR_DEBUG("Nothing to claim from network %s", 
iface->data.network.name);
-goto success;
-}
-
-if (networkCreateInterfacePool(netdef) < 0)
-goto error;
+if (!(port = virDomainNetDefActualToNetworkPort(dom, iface)))
+goto cleanup;
 
-if (netdef->forward.nifs == 0) {
-virReportError(VIR_ERR_INTERNAL_ERROR,
-   _("network '%s' uses a direct or hostdev mode, "
- "but has no forward dev and no interface pool"),
-   netdef->name);
+switch (port->plugtype) {
+case VIR_NETWORK_PORT_PLUG_TYPE_NONE:
+virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
+   _("Unexpectedly got a network port without a plug"));
 goto error;
-}
 
-if (actualType == VIR_DOMAIN_NET_TYPE_DIRECT) {
-const char *actualDev;
-
-actualDev = virDomainNetGetActualDirectDev(iface);
-if (!actualDev) {
+case VIR_NETWORK_PORT_PLUG_TYPE_BRIDGE:
+/* see if we're connected to the correct bridge */
+if (!netdef->bridge) {
 virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
-   _("the interface uses a direct mode, "
- "but has no source dev"));
+   _("Unexpectedly got a network port plugged into a 
bridge"));
 goto error;
 }
+break;
+
+case VIR_NETWORK_PORT_PLUG_TYPE_DIRECT:
+if (networkCreateInterfacePool(netdef) < 0)
+goto error;
 
 /* find the matching interface and increment its connections */
 for (i = 0; i < netdef->forward.nifs; i++) {
 if (netdef->forward.ifs[i].type
 == VIR_NETWORK_FORWARD_HOSTDEV_DEVICE_NETDEV &&
-STREQ(actualDev, netdef->forward.ifs[i].device.dev)) {
+STREQ(port->plug.direct.linkdev,
+  netdef->forward.ifs[i].device.dev)) {
 dev = >forward.ifs[i];
 break;
 }
@@ -4820,8 +4814,9 @@ networkNotifyActualDevice(virNetworkPtr net,
 if (!dev) {
 virReportError(VIR_ERR_INTERNAL_ERROR,
_("network '%s' doesn't have dev='%s' "
- "in use by domain"),
-   netdef->name, actualDev);
+ "in use by network port '%s'"),
+   netdef->name, port->plug.direct.linkdev,
+   port->uuid);
 goto error;
 }
 
@@ -4832,31 +4827,26 @@ networkNotifyActualDevice(virNetworkPtr net,
 if ((dev->connections > 0) &&
 ((netdef->forward.type == VIR_NETWORK_FORWARD_PASSTHROUGH) ||
  ((netdef->forward.type == VIR_NETWORK_FORWARD_PRIVATE) &&
-  iface->data.network.actual->virtPortProfile &&
-  (iface->data.network.actual->virtPortProfile->virtPortType
-   == VIR_NETDEV_VPORT_PROFILE_8021QBH {
+  port->virtPortProfile &&
+  (port->virtPortProfile->virtPortType == 
VIR_NETDEV_VPORT_PROFILE_8021QBH {
 virReportError(VIR_ERR_INTERNAL_ERROR,
_("network '%s' claims dev='%s' is already in "
- "use by a different domain"),
-   netdef->name, actualDev);
+ "use by a different port"),
+   netdef->name, port->plug.direct.linkdev);
 goto error;
 }
-}  else /* if (actualType == VIR_DOMAIN_NET_TYPE_HOSTDEV) */ {
-virDomainHostdevDefPtr hostdev;
+break;
 
-hostdev = virDomainNetGetActualHostdev(iface);
-if (!hostdev) {
-

[libvirt] [PATCH v2 26/36] network: introduce networkUpdatePortBandwidth

2019-02-27 Thread Daniel P . Berrangé
Separate network port bandwidth update code from the domain driver
network callback implementation.

Signed-off-by: Daniel P. Berrangé 
---
 src/network/bridge_driver.c | 115 
 1 file changed, 65 insertions(+), 50 deletions(-)

diff --git a/src/network/bridge_driver.c b/src/network/bridge_driver.c
index abc6b248aa..b23037335f 100644
--- a/src/network/bridge_driver.c
+++ b/src/network/bridge_driver.c
@@ -5393,77 +5393,56 @@ networkNetworkObjTaint(virNetworkObjPtr obj,
 
 
 static int
-networkBandwidthUpdate(virDomainNetDefPtr iface,
-   virNetDevBandwidthPtr newBandwidth)
+networkUpdatePortBandwidth(virNetworkObjPtr obj,
+   virMacAddrPtr mac,
+   unsigned int *class_id,
+   virNetDevBandwidthPtr oldBandwidth,
+   virNetDevBandwidthPtr newBandwidth)
 {
 virNetworkDriverStatePtr driver = networkGetDriver();
-virNetworkObjPtr obj = NULL;
 virNetworkDefPtr def;
 unsigned long long tmp_floor_sum;
-virNetDevBandwidthPtr ifaceBand = virDomainNetGetActualBandwidth(iface);
 unsigned long long new_rate = 0;
 unsigned long long old_floor, new_floor;
 int plug_ret;
-int ret = -1;
-
-if (iface->type != VIR_DOMAIN_NET_TYPE_NETWORK) {
-virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
-   _("Expected a interface for a virtual network"));
-return -1;
-}
-
-if (virDomainNetGetActualType(iface) != VIR_DOMAIN_NET_TYPE_BRIDGE ||
-iface->data.network.actual->data.bridge.brname == NULL) {
-/* This is not an interface that's plugged into a network.
- * We don't care. Thus from our POV bandwidth change is allowed. */
-return 0;
-}
 
 old_floor = new_floor = 0;
 
-if (ifaceBand && ifaceBand->in)
-old_floor = ifaceBand->in->floor;
+if (oldBandwidth && oldBandwidth->in)
+old_floor = oldBandwidth->in->floor;
 if (newBandwidth && newBandwidth->in)
 new_floor = newBandwidth->in->floor;
 
 if (new_floor == old_floor)
 return 0;
 
-obj = virNetworkObjFindByName(driver->networks, iface->data.network.name);
-if (!obj) {
-virReportError(VIR_ERR_NO_NETWORK,
-   _("no network with matching name '%s'"),
-   iface->data.network.name);
-return ret;
-}
 def = virNetworkObjGetDef(obj);
 
-if ((plug_ret = networkCheckBandwidth(obj, newBandwidth, ifaceBand,
-  >mac, _rate)) < 0) {
+if ((plug_ret = networkCheckBandwidth(obj, newBandwidth, oldBandwidth,
+  mac, _rate)) < 0) {
 /* helper reported error */
-goto cleanup;
+return -1;
 }
 
 if (plug_ret > 0) {
 /* no QoS needs to be set; claim success */
-ret = 0;
-goto cleanup;
+return 0;
 }
 
 /* Okay, there are three possible scenarios: */
 
-if (ifaceBand && ifaceBand->in && ifaceBand->in->floor &&
+if (oldBandwidth && oldBandwidth->in && oldBandwidth->in->floor &&
 newBandwidth->in && newBandwidth->in->floor) {
 /* Either we just need to update @floor .. */
 
 if (virNetDevBandwidthUpdateRate(def->bridge,
- iface->data.network.actual->class_id,
+ *class_id,
  def->bandwidth,
  newBandwidth->in->floor) < 0)
-goto cleanup;
+return -1;
 
 tmp_floor_sum = virNetworkObjGetFloorSum(obj);
-tmp_floor_sum -= ifaceBand->in->floor;
+tmp_floor_sum -= oldBandwidth->in->floor;
 tmp_floor_sum += newBandwidth->in->floor;
 virNetworkObjSetFloorSum(obj, tmp_floor_sum);
 new_rate -= tmp_floor_sum;
@@ -5473,34 +5452,70 @@ networkBandwidthUpdate(virDomainNetDefPtr iface,
 virNetworkObjSaveStatus(driver->stateDir, obj) < 0) {
 /* Ouch, rollback */
 tmp_floor_sum -= newBandwidth->in->floor;
-tmp_floor_sum += ifaceBand->in->floor;
+tmp_floor_sum += oldBandwidth->in->floor;
 virNetworkObjSetFloorSum(obj, tmp_floor_sum);
 
 ignore_value(virNetDevBandwidthUpdateRate(def->bridge,
-  
iface->data.network.actual->class_id,
+  *class_id,
   def->bandwidth,
-  ifaceBand->in->floor));
-goto cleanup;
+  
oldBandwidth->in->floor));
+return -1;
 }
 } else if (newBandwidth->in && newBandwidth->in->floor) {
 /* .. or we need to plug in new .. */
 
-

[libvirt] [PATCH v2 22/36] network: remove the virDomainNetBandwidthChangeAllowed callback

2019-02-27 Thread Daniel P . Berrangé
The current qemu driver code for changing bandwidth on a NIC first asks
the network driver if the change is supported, then changes the
bandwidth on the VIF, and then tells the network driver to update the
bandwidth on the bridge.

This is potentially racing if a parallel API call causes the network
driver to allocate bandwidth on the bridge between the check and the
update phases.

Change the code to just try to apply the network bridge update
immediately and rollback at the end if something failed.

Signed-off-by: Daniel P. Berrangé 
---
 src/conf/domain_conf.c  | 15 
 src/conf/domain_conf.h  | 10 -
 src/libvirt_private.syms|  1 -
 src/network/bridge_driver.c | 75 -
 src/qemu/qemu_driver.c  |  8 ++--
 5 files changed, 20 insertions(+), 89 deletions(-)

diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c
index 327b5d3497..d159ddf154 100644
--- a/src/conf/domain_conf.c
+++ b/src/conf/domain_conf.c
@@ -31052,7 +31052,6 @@ virDomainNetDefActualToNetworkPort(virDomainDefPtr dom,
 static virDomainNetAllocateActualDeviceImpl netAllocate;
 static virDomainNetNotifyActualDeviceImpl netNotify;
 static virDomainNetReleaseActualDeviceImpl netRelease;
-static virDomainNetBandwidthChangeAllowedImpl netBandwidthChangeAllowed;
 static virDomainNetBandwidthUpdateImpl netBandwidthUpdate;
 
 
@@ -31060,13 +31059,11 @@ void
 virDomainNetSetDeviceImpl(virDomainNetAllocateActualDeviceImpl allocate,
   virDomainNetNotifyActualDeviceImpl notify,
   virDomainNetReleaseActualDeviceImpl release,
-  virDomainNetBandwidthChangeAllowedImpl 
bandwidthChangeAllowed,
   virDomainNetBandwidthUpdateImpl bandwidthUpdate)
 {
 netAllocate = allocate;
 netNotify = notify;
 netRelease = release;
-netBandwidthChangeAllowed = bandwidthChangeAllowed;
 netBandwidthUpdate = bandwidthUpdate;
 }
 
@@ -31174,18 +31171,6 @@ virDomainNetReleaseActualDevice(virConnectPtr conn,
 return ret;
 }
 
-bool
-virDomainNetBandwidthChangeAllowed(virDomainNetDefPtr iface,
-   virNetDevBandwidthPtr newBandwidth)
-{
-if (!netBandwidthChangeAllowed) {
-virReportError(VIR_ERR_NO_SUPPORT, "%s",
-   _("Virtual networking driver is not available"));
-return -1;
-}
-
-return netBandwidthChangeAllowed(iface, newBandwidth);
-}
 
 int
 virDomainNetBandwidthUpdate(virDomainNetDefPtr iface,
diff --git a/src/conf/domain_conf.h b/src/conf/domain_conf.h
index 527f20d08a..7f9917ac30 100644
--- a/src/conf/domain_conf.h
+++ b/src/conf/domain_conf.h
@@ -3672,10 +3672,6 @@ typedef int
virDomainDefPtr dom,
virDomainNetDefPtr iface);
 
-typedef bool
-(*virDomainNetBandwidthChangeAllowedImpl)(virDomainNetDefPtr iface,
-  virNetDevBandwidthPtr newBandwidth);
-
 typedef int
 (*virDomainNetBandwidthUpdateImpl)(virDomainNetDefPtr iface,
virNetDevBandwidthPtr newBandwidth);
@@ -3685,7 +3681,6 @@ void
 virDomainNetSetDeviceImpl(virDomainNetAllocateActualDeviceImpl allocate,
   virDomainNetNotifyActualDeviceImpl notify,
   virDomainNetReleaseActualDeviceImpl release,
-  virDomainNetBandwidthChangeAllowedImpl 
bandwidthChangeAllowed,
   virDomainNetBandwidthUpdateImpl bandwidthUpdate);
 
 int
@@ -3706,11 +3701,6 @@ virDomainNetReleaseActualDevice(virConnectPtr conn,
 virDomainNetDefPtr iface)
 ATTRIBUTE_NONNULL(1) ATTRIBUTE_NONNULL(2);
 
-bool
-virDomainNetBandwidthChangeAllowed(virDomainNetDefPtr iface,
-  virNetDevBandwidthPtr newBandwidth)
-ATTRIBUTE_NONNULL(1) ATTRIBUTE_NONNULL(2);
-
 int
 virDomainNetBandwidthUpdate(virDomainNetDefPtr iface,
 virNetDevBandwidthPtr newBandwidth)
diff --git a/src/libvirt_private.syms b/src/libvirt_private.syms
index adc23a914e..6f2bf6bad6 100644
--- a/src/libvirt_private.syms
+++ b/src/libvirt_private.syms
@@ -449,7 +449,6 @@ virDomainMemorySourceTypeFromString;
 virDomainMemorySourceTypeToString;
 virDomainNetAllocateActualDevice;
 virDomainNetAppendIPAddress;
-virDomainNetBandwidthChangeAllowed;
 virDomainNetBandwidthUpdate;
 virDomainNetDefActualFromNetworkPort;
 virDomainNetDefActualToNetworkPort;
diff --git a/src/network/bridge_driver.c b/src/network/bridge_driver.c
index 6911424e45..3778c65bc2 100644
--- a/src/network/bridge_driver.c
+++ b/src/network/bridge_driver.c
@@ -5334,63 +5334,6 @@ networkNetworkObjTaint(virNetworkObjPtr obj,
 }
 
 
-static bool
-networkBandwidthGenericChecks(virDomainNetDefPtr iface,
-  virNetDevBandwidthPtr newBandwidth)
-{
-virNetDevBandwidthPtr ifaceBand;
-unsigned long long 

[libvirt] [PATCH v2 13/36] conf: introduce virNetworkPortDefPtr struct and XML support

2019-02-27 Thread Daniel P . Berrangé
Introduce a virNetworkPortDefPtr struct to represent the data associated
with a virtual network port. Add APIs for parsing/formatting XML docs
with the data.

Signed-off-by: Daniel P. Berrangé 
---
 src/conf/Makefile.inc.am  |   2 +
 src/conf/virnetworkportdef.c  | 514 ++
 src/conf/virnetworkportdef.h  | 112 
 src/libvirt_private.syms  |  10 +
 tests/Makefile.am |   7 +
 .../plug-bridge-mactbl.xml|   9 +
 .../virnetworkportxml2xmldata/plug-bridge.xml |  12 +
 .../virnetworkportxml2xmldata/plug-direct.xml |  12 +
 .../plug-hostdev-pci.xml  |  12 +
 tests/virnetworkportxml2xmldata/plug-none.xml |   8 +
 tests/virnetworkportxml2xmltest.c | 104 
 11 files changed, 802 insertions(+)
 create mode 100644 src/conf/virnetworkportdef.c
 create mode 100644 src/conf/virnetworkportdef.h
 create mode 100644 tests/virnetworkportxml2xmldata/plug-bridge-mactbl.xml
 create mode 100644 tests/virnetworkportxml2xmldata/plug-bridge.xml
 create mode 100644 tests/virnetworkportxml2xmldata/plug-direct.xml
 create mode 100644 tests/virnetworkportxml2xmldata/plug-hostdev-pci.xml
 create mode 100644 tests/virnetworkportxml2xmldata/plug-none.xml
 create mode 100644 tests/virnetworkportxml2xmltest.c

diff --git a/src/conf/Makefile.inc.am b/src/conf/Makefile.inc.am
index 219ff350d7..eec861591f 100644
--- a/src/conf/Makefile.inc.am
+++ b/src/conf/Makefile.inc.am
@@ -5,6 +5,8 @@ NETDEV_CONF_SOURCES = \
conf/netdev_vport_profile_conf.c \
conf/netdev_vlan_conf.h \
conf/netdev_vlan_conf.c \
+   conf/virnetworkportdef.h \
+   conf/virnetworkportdef.c \
$(NULL)
 
 DOMAIN_CONF_SOURCES = \
diff --git a/src/conf/virnetworkportdef.c b/src/conf/virnetworkportdef.c
new file mode 100644
index 00..7023d9607e
--- /dev/null
+++ b/src/conf/virnetworkportdef.c
@@ -0,0 +1,514 @@
+/*
+ * virnetworkportdef.c: network port XML processing
+ *
+ * Copyright (C) 2018 Red Hat, Inc.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library.  If not, see
+ * .
+ */
+
+#include 
+
+#include "viralloc.h"
+#include "virerror.h"
+#include "virstring.h"
+#include "virfile.h"
+#include "virnetworkportdef.h"
+#include "network_conf.h"
+
+#define VIR_FROM_THIS VIR_FROM_NETWORK
+
+VIR_ENUM_IMPL(virNetworkPortPlug, VIR_NETWORK_PORT_PLUG_TYPE_LAST,
+  "none", "bridge", "direct", "hostdev-pci");
+
+void
+virNetworkPortDefFree(virNetworkPortDefPtr def)
+{
+if (!def)
+return;
+
+VIR_FREE(def->ownername);
+VIR_FREE(def->group);
+
+virNetDevBandwidthFree(def->bandwidth);
+virNetDevVlanClear(>vlan);
+VIR_FREE(def->virtPortProfile);
+
+switch ((virNetworkPortPlugType)def->plugtype) {
+case VIR_NETWORK_PORT_PLUG_TYPE_NONE:
+break;
+
+case VIR_NETWORK_PORT_PLUG_TYPE_BRIDGE:
+VIR_FREE(def->plug.bridge.brname);
+break;
+
+case VIR_NETWORK_PORT_PLUG_TYPE_DIRECT:
+VIR_FREE(def->plug.direct.linkdev);
+break;
+
+case VIR_NETWORK_PORT_PLUG_TYPE_HOSTDEV_PCI:
+break;
+
+case VIR_NETWORK_PORT_PLUG_TYPE_LAST:
+default:
+break;
+}
+
+VIR_FREE(def);
+}
+
+
+
+static virNetworkPortDefPtr
+virNetworkPortDefParseXML(xmlXPathContextPtr ctxt)
+{
+virNetworkPortDefPtr def;
+char *uuid = NULL;
+xmlNodePtr virtPortNode;
+xmlNodePtr vlanNode;
+xmlNodePtr bandwidthNode;
+xmlNodePtr addressNode;
+char *trustGuestRxFilters = NULL;
+char *mac = NULL;
+char *macmgr = NULL;
+char *mode = NULL;
+char *plugtype = NULL;
+char *managed = NULL;
+char *driver = NULL;
+char *class_id = NULL;
+
+if (VIR_ALLOC(def) < 0)
+return NULL;
+
+uuid = virXPathString("string(./uuid)", ctxt);
+if (!uuid) {
+virReportError(VIR_ERR_INTERNAL_ERROR,
+   "%s", _("network port has no uuid"));
+goto error;
+}
+if (virUUIDParse(uuid, def->uuid) < 0) {
+virReportError(VIR_ERR_INTERNAL_ERROR,
+   _("Unable to parse UUID '%s'"), uuid);
+goto error;
+}
+
+def->ownername = virXPathString("string(./owner/name)", ctxt);
+if (!def->ownername) {
+virReportError(VIR_ERR_INTERNAL_ERROR,
+   "%s", 

[libvirt] [PATCH v2 35/36] conf: record a portid against the domain conf

2019-02-27 Thread Daniel P . Berrangé
The portid will be the UUID of the virNetworkPort object associated
with the network interface when a guest is running.

Signed-off-by: Daniel P. Berrangé 
---
 docs/formatdomain.html.in |  8 +++
 docs/schemas/domaincommon.rng |  5 +
 src/conf/domain_conf.c| 22 +++
 src/conf/domain_conf.h|  4 
 .../net-virtio-network-portgroup.xml  |  6 ++---
 5 files changed, 42 insertions(+), 3 deletions(-)

diff --git a/docs/formatdomain.html.in b/docs/formatdomain.html.in
index b848e535e6..8e3a382eeb 100644
--- a/docs/formatdomain.html.in
+++ b/docs/formatdomain.html.in
@@ -5187,6 +5187,14 @@
   information for different classes of network
   connections. Since 0.9.4.
 
+
+  When a guest is running and interface of type network
+  may include a portid attribute. This provides the UUID
+  of an associated virNetworkPortPtr object that records the association
+  between the domain interface and the network. This attribute is
+  read-only since port objects are create and deleted automatically
+  during startup and shutdown. Since 5.1.0/
+
 
   Also, similar to direct network connections
   (described below), a connection of type network may
diff --git a/docs/schemas/domaincommon.rng b/docs/schemas/domaincommon.rng
index 5345e54342..ccf1e7289f 100644
--- a/docs/schemas/domaincommon.rng
+++ b/docs/schemas/domaincommon.rng
@@ -2536,6 +2536,11 @@
 
   
 
+
+  
+
+  
+
   
 
   
diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c
index d159ddf154..61987e7f51 100644
--- a/src/conf/domain_conf.c
+++ b/src/conf/domain_conf.c
@@ -11292,6 +11292,7 @@ virDomainNetDefParseXML(virDomainXMLOptionPtr xmlopt,
 char *type = NULL;
 char *network = NULL;
 char *portgroup = NULL;
+char *portid = NULL;
 char *bridge = NULL;
 char *dev = NULL;
 char *ifname = NULL;
@@ -11374,6 +11375,8 @@ virDomainNetDefParseXML(virDomainXMLOptionPtr xmlopt,
virXMLNodeNameEqual(cur, "source")) {
 network = virXMLPropString(cur, "network");
 portgroup = virXMLPropString(cur, "portgroup");
+if (!(flags & VIR_DOMAIN_DEF_PARSE_INACTIVE))
+portid = virXMLPropString(cur, "portid");
 } else if (!internal &&
def->type == VIR_DOMAIN_NET_TYPE_INTERNAL &&
virXMLNodeNameEqual(cur, "source")) {
@@ -11597,6 +11600,13 @@ virDomainNetDefParseXML(virDomainXMLOptionPtr xmlopt,
  "specified with "));
 goto error;
 }
+if (portid &&
+virUUIDParse(portid, def->data.network.portid) < 0) {
+virReportError(VIR_ERR_INTERNAL_ERROR,
+   _("Unable to parse port id '%s'"), portid);
+goto error;
+}
+
 VIR_STEAL_PTR(def->data.network.name, network);
 VIR_STEAL_PTR(def->data.network.portgroup, portgroup);
 VIR_STEAL_PTR(def->data.network.actual, actual);
@@ -12077,6 +12087,7 @@ virDomainNetDefParseXML(virDomainXMLOptionPtr xmlopt,
 VIR_FREE(macaddr);
 VIR_FREE(network);
 VIR_FREE(portgroup);
+VIR_FREE(portid);
 VIR_FREE(address);
 VIR_FREE(port);
 VIR_FREE(vhostuser_type);
@@ -25240,6 +25251,11 @@ virDomainActualNetDefContentsFormat(virBufferPtr buf,
   def->data.network.name);
 virBufferEscapeString(buf, " portgroup='%s'",
   def->data.network.portgroup);
+if (virUUIDIsValid(def->data.network.portid)) {
+char uuidstr[VIR_UUID_STRING_BUFLEN];
+virUUIDFormat(def->data.network.portid, uuidstr);
+virBufferAsprintf(buf, " portid='%s'", uuidstr);
+}
 }
 if (actualType == VIR_DOMAIN_NET_TYPE_BRIDGE ||
 actualType == VIR_DOMAIN_NET_TYPE_NETWORK) {
@@ -25543,6 +25559,12 @@ virDomainNetDefFormat(virBufferPtr buf,
   def->data.network.name);
 virBufferEscapeString(buf, " portgroup='%s'",
   def->data.network.portgroup);
+if (virUUIDIsValid(def->data.network.portid) &&
+!(flags & (VIR_DOMAIN_DEF_FORMAT_INACTIVE))) {
+char portidstr[VIR_UUID_STRING_BUFLEN];
+virUUIDFormat(def->data.network.portid, portidstr);
+virBufferEscapeString(buf, " portid='%s'", portidstr);
+}
 sourceLines++;
 break;
 
diff --git a/src/conf/domain_conf.h b/src/conf/domain_conf.h
index 7f9917ac30..a12bb46ced 100644
--- a/src/conf/domain_conf.h
+++ b/src/conf/domain_conf.h
@@ -1027,6 +1027,7 @@ struct _virDomainNetDef {
 struct {
 char *name;
 char *portgroup;
+

[libvirt] [PATCH v2 27/36] network: add public APIs for network port object

2019-02-27 Thread Daniel P . Berrangé
Introduce a new virNetworPort object that will present an attachment to
a virtual network from a VM.

Signed-off-by: Daniel P. Berrangé 
---
 include/libvirt/libvirt-network.h | 122 
 include/libvirt/virterror.h   |   3 +
 src/datatypes.c   |  60 
 src/datatypes.h   |  41 +++
 src/driver-network.h  |  41 +++
 src/libvirt-network.c | 444 ++
 src/libvirt_private.syms  |   2 +
 src/libvirt_public.syms   |  16 ++
 src/util/virerror.c   |   9 +
 9 files changed, 738 insertions(+)

diff --git a/include/libvirt/libvirt-network.h 
b/include/libvirt/libvirt-network.h
index 5115251fbe..97eceef754 100644
--- a/include/libvirt/libvirt-network.h
+++ b/include/libvirt/libvirt-network.h
@@ -46,6 +46,22 @@ typedef struct _virNetwork virNetwork;
  */
 typedef virNetwork *virNetworkPtr;
 
+/**
+ * virNetworkPort:
+ *
+ * a virNetworkPort is a private structure representing a virtual network
+ * port
+ */
+typedef struct _virNetworkPort virNetworkPort;
+
+/**
+ * virNetworkPortPtr:
+ *
+ * a virNetworkPortPtr is pointer to a virNetworkPort private structure,
+ * this is the type used to reference a virtual network port in the API.
+ */
+typedef virNetworkPort *virNetworkPortPtr;
+
 /*
  * Get connection from network.
  */
@@ -333,4 +349,110 @@ int virConnectNetworkEventRegisterAny(virConnectPtr conn,
 int virConnectNetworkEventDeregisterAny(virConnectPtr conn,
 int callbackID);
 
+
+virNetworkPortPtr
+virNetworkPortLookupByUUID(virNetworkPtr net,
+   const unsigned char *uuid);
+
+virNetworkPortPtr
+virNetworkPortLookupByUUIDString(virNetworkPtr net,
+ const char *uuidstr);
+
+typedef enum {
+VIR_NETWORK_PORT_CREATE_RECLAIM = (1 << 0), /* reclaim existing used 
resources */
+} virNetworkPortCreateFlags;
+
+virNetworkPortPtr
+virNetworkPortCreateXML(virNetworkPtr net,
+const char *xmldesc,
+unsigned int flags);
+
+virNetworkPtr
+virNetworkPortGetNetwork(virNetworkPortPtr port);
+
+char *
+virNetworkPortGetXMLDesc(virNetworkPortPtr port,
+ unsigned int flags);
+
+int
+virNetworkPortGetUUID(virNetworkPortPtr port,
+  unsigned char *uuid);
+int
+virNetworkPortGetUUIDString(virNetworkPortPtr port,
+char *buf);
+
+/* Management of interface parameters */
+
+/**
+ * VIR_NETWORK_PORT_BANDWIDTH_IN_AVERAGE:
+ *
+ * Macro represents the inbound average of NIC bandwidth, as a uint.
+ */
+# define VIR_NETWORK_PORT_BANDWIDTH_IN_AVERAGE "inbound.average"
+
+/**
+ * VIR_NETWORK_PORT_BANDWIDTH_IN_PEAK:
+ *
+ * Macro represents the inbound peak of NIC bandwidth, as a uint.
+ */
+# define VIR_NETWORK_PORT_BANDWIDTH_IN_PEAK "inbound.peak"
+
+/**
+ * VIR_NETWORK_PORT_BANDWIDTH_IN_BURST:
+ *
+ * Macro represents the inbound burst of NIC bandwidth, as a uint.
+ */
+# define VIR_NETWORK_PORT_BANDWIDTH_IN_BURST "inbound.burst"
+
+/**
+ * VIR_NETWORK_PORT_BANDWIDTH_IN_FLOOR:
+ *
+ * Macro represents the inbound floor of NIC bandwidth, as a uint.
+ */
+# define VIR_NETWORK_PORT_BANDWIDTH_IN_FLOOR "inbound.floor"
+
+/**
+ * VIR_NETWORK_PORT_BANDWIDTH_OUT_AVERAGE:
+ *
+ * Macro represents the outbound average of NIC bandwidth, as a uint.
+ */
+# define VIR_NETWORK_PORT_BANDWIDTH_OUT_AVERAGE "outbound.average"
+
+/**
+ * VIR_NETWORK_PORT_BANDWIDTH_OUT_PEAK:
+ *
+ * Macro represents the outbound peak of NIC bandwidth, as a uint.
+ */
+# define VIR_NETWORK_PORT_BANDWIDTH_OUT_PEAK "outbound.peak"
+
+/**
+ * VIR_NETWORK_PORT_BANDWIDTH_OUT_BURST:
+ *
+ * Macro represents the outbound burst of NIC bandwidth, as a uint.
+ */
+# define VIR_NETWORK_PORT_BANDWIDTH_OUT_BURST "outbound.burst"
+
+int
+virNetworkPortSetParameters(virNetworkPortPtr port,
+virTypedParameterPtr params,
+int nparams,
+unsigned int flags);
+int
+virNetworkPortGetParameters(virNetworkPortPtr port,
+virTypedParameterPtr *params,
+int *nparams,
+unsigned int flags);
+
+int
+virNetworkPortDelete(virNetworkPortPtr port,
+ unsigned int flags);
+
+int
+virNetworkListAllPorts(virNetworkPtr network,
+   virNetworkPortPtr **ports,
+   unsigned int flags);
+
+int
+virNetworkPortFree(virNetworkPortPtr port);
+
 #endif /* LIBVIRT_NETWORK_H */
diff --git a/include/libvirt/virterror.h b/include/libvirt/virterror.h
index 3c19ff5e2e..076903273c 100644
--- a/include/libvirt/virterror.h
+++ b/include/libvirt/virterror.h
@@ -322,6 +322,9 @@ typedef enum {
 VIR_ERR_DEVICE_MISSING = 99,/* fail to find the desired device */
 VIR_ERR_INVALID_NWFILTER_BINDING = 100,  /* invalid nwfilter binding */
 VIR_ERR_NO_NWFILTER_BINDING = 

[libvirt] [PATCH v2 29/36] remote: add support for new network port APIs

2019-02-27 Thread Daniel P . Berrangé
Define the wire protocol for the virNetworkPort APIs and enable the
client/server RPC dispatch.

Signed-off-by: Daniel P. Berrangé 
---
 src/remote/remote_daemon_dispatch.c |  73 
 src/remote/remote_driver.c  |  69 
 src/remote/remote_protocol.x| 124 +++-
 src/remote_protocol-structs |  69 
 src/rpc/gendispatch.pl  |  18 ++--
 5 files changed, 346 insertions(+), 7 deletions(-)

diff --git a/src/remote/remote_daemon_dispatch.c 
b/src/remote/remote_daemon_dispatch.c
index df28259042..856c5e48e7 100644
--- a/src/remote/remote_daemon_dispatch.c
+++ b/src/remote/remote_daemon_dispatch.c
@@ -83,6 +83,7 @@ struct daemonClientEventCallback {
 
 static virDomainPtr get_nonnull_domain(virConnectPtr conn, 
remote_nonnull_domain domain);
 static virNetworkPtr get_nonnull_network(virConnectPtr conn, 
remote_nonnull_network network);
+static virNetworkPortPtr get_nonnull_network_port(virConnectPtr conn, 
remote_nonnull_network_port port);
 static virInterfacePtr get_nonnull_interface(virConnectPtr conn, 
remote_nonnull_interface iface);
 static virStoragePoolPtr get_nonnull_storage_pool(virConnectPtr conn, 
remote_nonnull_storage_pool pool);
 static virStorageVolPtr get_nonnull_storage_vol(virConnectPtr conn, 
remote_nonnull_storage_vol vol);
@@ -93,6 +94,7 @@ static virDomainSnapshotPtr 
get_nonnull_domain_snapshot(virDomainPtr dom, remote
 static virNodeDevicePtr get_nonnull_node_device(virConnectPtr conn, 
remote_nonnull_node_device dev);
 static int make_nonnull_domain(remote_nonnull_domain *dom_dst, virDomainPtr 
dom_src) ATTRIBUTE_RETURN_CHECK;
 static int make_nonnull_network(remote_nonnull_network *net_dst, virNetworkPtr 
net_src) ATTRIBUTE_RETURN_CHECK;
+static int make_nonnull_network_port(remote_nonnull_network_port *port_dst, 
virNetworkPortPtr port_src) ATTRIBUTE_RETURN_CHECK;
 static int make_nonnull_interface(remote_nonnull_interface *interface_dst, 
virInterfacePtr interface_src) ATTRIBUTE_RETURN_CHECK;
 static int make_nonnull_storage_pool(remote_nonnull_storage_pool *pool_dst, 
virStoragePoolPtr pool_src) ATTRIBUTE_RETURN_CHECK;
 static int make_nonnull_storage_vol(remote_nonnull_storage_vol *vol_dst, 
virStorageVolPtr vol_src) ATTRIBUTE_RETURN_CHECK;
@@ -7175,6 +7177,54 @@ remoteDispatchStorageVolGetInfoFlags(virNetServerPtr 
server ATTRIBUTE_UNUSED,
 }
 
 
+static int
+remoteDispatchNetworkPortGetParameters(virNetServerPtr server ATTRIBUTE_UNUSED,
+   virNetServerClientPtr client 
ATTRIBUTE_UNUSED,
+   virNetMessagePtr msg ATTRIBUTE_UNUSED,
+   virNetMessageErrorPtr rerr,
+   remote_network_port_get_parameters_args 
*args,
+   remote_network_port_get_parameters_ret 
*ret)
+{
+int rv = -1;
+virNetworkPortPtr port = NULL;
+virTypedParameterPtr params = NULL;
+int nparams = 0;
+struct daemonClientPrivate *priv =
+virNetServerClientGetPrivateData(client);
+
+if (!priv->networkConn) {
+virReportError(VIR_ERR_INTERNAL_ERROR, "%s", _("connection not open"));
+goto cleanup;
+}
+
+if (!(port = get_nonnull_network_port(priv->networkConn, args->port)))
+goto cleanup;
+
+if (virNetworkPortGetParameters(port, , , args->flags) < 0)
+goto cleanup;
+
+if (nparams > REMOTE_NETWORK_PORT_PARAMETERS_MAX) {
+virReportError(VIR_ERR_INTERNAL_ERROR, "%s", _("nparams too large"));
+goto cleanup;
+}
+
+if (virTypedParamsSerialize(params, nparams,
+(virTypedParameterRemotePtr *) 
>params.params_val,
+>params.params_len,
+args->flags) < 0)
+goto cleanup;
+
+rv = 0;
+
+ cleanup:
+if (rv < 0)
+virNetMessageSaveError(rerr);
+virObjectUnref(port);
+virTypedParamsFree(params, nparams);
+return rv;
+}
+
+
 /*- Helpers. -*/
 
 /* get_nonnull_domain and get_nonnull_network turn an on-wire
@@ -7198,6 +7248,19 @@ get_nonnull_network(virConnectPtr conn, 
remote_nonnull_network network)
 return virGetNetwork(conn, network.name, BAD_CAST network.uuid);
 }
 
+static virNetworkPortPtr
+get_nonnull_network_port(virConnectPtr conn, remote_nonnull_network_port port)
+{
+virNetworkPortPtr ret;
+virNetworkPtr net;
+net = virGetNetwork(conn, port.net.name, BAD_CAST port.net.uuid);
+if (!net)
+return NULL;
+ret = virGetNetworkPort(net, BAD_CAST port.uuid);
+virObjectUnref(net);
+return ret;
+}
+
 static virInterfacePtr
 get_nonnull_interface(virConnectPtr conn, remote_nonnull_interface iface)
 {
@@ -7270,6 +7333,16 @@ make_nonnull_network(remote_nonnull_network *net_dst, 
virNetworkPtr net_src)
 return 0;
 }
 
+static int
+make_nonnull_network_port(remote_nonnull_network_port 

[libvirt] [PATCH v2 30/36] virsh: add support for network port APIs

2019-02-27 Thread Daniel P . Berrangé
Signed-off-by: Daniel P. Berrangé 
---
 tools/virsh-completer.c |  51 +
 tools/virsh-completer.h |   4 +
 tools/virsh-network.c   | 399 +++-
 tools/virsh-network.h   |   5 +
 4 files changed, 458 insertions(+), 1 deletion(-)

diff --git a/tools/virsh-completer.c b/tools/virsh-completer.c
index 7c68e2e832..c360bfa8ae 100644
--- a/tools/virsh-completer.c
+++ b/tools/virsh-completer.c
@@ -22,6 +22,7 @@
 
 #include "virsh-completer.h"
 #include "virsh-domain.h"
+#include "virsh-network.h"
 #include "virsh.h"
 #include "virsh-pool.h"
 #include "virsh-nodedev.h"
@@ -415,6 +416,56 @@ virshNetworkNameCompleter(vshControl *ctl,
 }
 
 
+char **
+virshNetworkPortUUIDCompleter(vshControl *ctl,
+  const vshCmd *cmd ATTRIBUTE_UNUSED,
+  unsigned int flags)
+{
+virshControlPtr priv = ctl->privData;
+virNetworkPtr net = NULL;
+virNetworkPortPtr *ports = NULL;
+int nports = 0;
+size_t i = 0;
+char **ret = NULL;
+
+virCheckFlags(0, NULL);
+
+if (!priv->conn || virConnectIsAlive(priv->conn) <= 0)
+return NULL;
+
+if (!(net = virshCommandOptNetwork(ctl, cmd, NULL)))
+return false;
+
+if ((nports = virNetworkListAllPorts(net, , flags)) < 0)
+return NULL;
+
+if (VIR_ALLOC_N(ret, nports + 1) < 0)
+goto error;
+
+for (i = 0; i < nports; i++) {
+char uuid[VIR_UUID_STRING_BUFLEN];
+
+if (virNetworkPortGetUUIDString(ports[i], uuid) < 0 ||
+VIR_STRDUP(ret[i], uuid) < 0)
+goto error;
+
+virNetworkPortFree(ports[i]);
+}
+VIR_FREE(ports);
+
+return ret;
+
+ error:
+for (; i < nports; i++)
+virNetworkPortFree(ports[i]);
+VIR_FREE(ports);
+for (i = 0; i < nports; i++)
+VIR_FREE(ret[i]);
+VIR_FREE(ret);
+return NULL;
+}
+
+
 char **
 virshNodeDeviceNameCompleter(vshControl *ctl,
  const vshCmd *cmd ATTRIBUTE_UNUSED,
diff --git a/tools/virsh-completer.h b/tools/virsh-completer.h
index 4563fd76ac..ea78e3daa2 100644
--- a/tools/virsh-completer.h
+++ b/tools/virsh-completer.h
@@ -55,6 +55,10 @@ char ** virshNetworkNameCompleter(vshControl *ctl,
   const vshCmd *cmd,
   unsigned int flags);
 
+char ** virshNetworkPortUUIDCompleter(vshControl *ctl,
+  const vshCmd *cmd,
+  unsigned int flags);
+
 char ** virshNodeDeviceNameCompleter(vshControl *ctl,
  const vshCmd *cmd,
  unsigned int flags);
diff --git a/tools/virsh-network.c b/tools/virsh-network.c
index 9b86ef8071..275ca30565 100644
--- a/tools/virsh-network.c
+++ b/tools/virsh-network.c
@@ -1,7 +1,7 @@
 /*
  * virsh-network.c: Commands to manage network
  *
- * Copyright (C) 2005, 2007-2016 Red Hat, Inc.
+ * Copyright (C) 2005, 2007-2019 Red Hat, Inc.
  *
  * This library is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
@@ -53,6 +53,16 @@
 #define VIRSH_COMMON_OPT_NETWORK_OT_STRING_FULL(cflags) \
 VIRSH_COMMON_OPT_NETWORK_OT_STRING(N_("network name or uuid"), cflags)
 
+#define VIRSH_COMMON_OPT_NETWORK_PORT(cflags) \
+{.name = "port", \
+ .type = VSH_OT_DATA, \
+ .flags = VSH_OFLAG_REQ, \
+ .help = N_("port UUID"), \
+ .completer = virshNetworkPortUUIDCompleter, \
+ .completer_flags = cflags, \
+}
+
+
 virNetworkPtr
 virshCommandOptNetworkBy(vshControl *ctl, const vshCmd *cmd,
  const char **name, unsigned int flags)
@@ -91,6 +101,35 @@ virshCommandOptNetworkBy(vshControl *ctl, const vshCmd *cmd,
 return network;
 }
 
+
+virNetworkPortPtr
+virshCommandOptNetworkPort(vshControl *ctl, const vshCmd *cmd,
+   virNetworkPtr net,
+   const char **name)
+{
+virNetworkPortPtr port = NULL;
+const char *n = NULL;
+const char *optname = "port";
+
+if (vshCommandOptStringReq(ctl, cmd, optname, ) < 0)
+return NULL;
+
+vshDebug(ctl, VSH_ERR_INFO, "%s: found option <%s>: %s\n",
+ cmd->def->name, optname, n);
+
+if (name)
+*name = n;
+
+vshDebug(ctl, VSH_ERR_DEBUG, "%s: <%s> trying as network UUID\n",
+ cmd->def->name, optname);
+port = virNetworkPortLookupByUUIDString(net, n);
+
+if (!port)
+vshError(ctl, _("failed to get network port '%s'"), n);
+
+return port;
+}
+
 /*
  * "net-autostart" command
  */
@@ -1422,6 +1461,340 @@ cmdNetworkDHCPLeases(vshControl *ctl, const vshCmd *cmd)
 return ret;
 }
 
+/*
+ * "net-port-create" command
+ */
+static const vshCmdInfo info_network_port_create[] = {
+{.name = "help",
+ .data = N_("create a network port from an XML file")
+},
+{.name = "desc",
+ .data = N_("Create a network port.")
+

[libvirt] [PATCH v2 24/36] network: introduce networkNotifyPort

2019-02-27 Thread Daniel P . Berrangé
Separate network port notification code from the domain driver network
callback implementation.

Signed-off-by: Daniel P. Berrangé 
---
 src/network/bridge_driver.c | 106 +---
 1 file changed, 63 insertions(+), 43 deletions(-)

diff --git a/src/network/bridge_driver.c b/src/network/bridge_driver.c
index 2df80a0af5..ef85456d5f 100644
--- a/src/network/bridge_driver.c
+++ b/src/network/bridge_driver.c
@@ -4737,74 +4737,51 @@ networkAllocateActualDevice(virNetworkPtr net,
 }
 
 
-/* networkNotifyActualDevice:
- * @dom: domain definition that @iface belongs to
- * @iface:  the domain's NetDef with an "actual" device already filled in.
+/* networkNotifyPort:
+ * @obj: the network to notify
+ * @port: the port definition to notify
  *
  * Called to notify the network driver when libvirtd is restarted and
  * finds an already running domain. If appropriate it will force an
  * allocation of the actual->direct.linkdev to get everything back in
  * order.
- *
- * Returns 0 on success, -1 on failure.
  */
 static int
-networkNotifyActualDevice(virNetworkPtr net,
-  virDomainDefPtr dom,
-  virDomainNetDefPtr iface)
+networkNotifyPort(virNetworkObjPtr obj,
+  virNetworkPortDefPtr port)
 {
-virNetworkDriverStatePtr driver = networkGetDriver();
-virNetworkObjPtr obj;
 virNetworkDefPtr netdef;
 virNetworkForwardIfDefPtr dev = NULL;
-virNetworkPortDefPtr port = NULL;
 size_t i;
 int ret = -1;
 
-obj = virNetworkObjFindByName(driver->networks, net->name);
-if (!obj) {
-virReportError(VIR_ERR_NO_NETWORK,
-   _("no network with matching name '%s'"),
-   net->name);
-goto error;
-}
-
-if (iface->type != VIR_DOMAIN_NET_TYPE_NETWORK) {
-virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
-   _("Expected a interface for a virtual network"));
-goto error;
-}
-
 netdef = virNetworkObjGetDef(obj);
 
 if (!virNetworkObjIsActive(obj)) {
 virReportError(VIR_ERR_OPERATION_INVALID,
_("network '%s' is not active"),
netdef->name);
-goto error;
-}
-
-if (!(port = virDomainNetDefActualToNetworkPort(dom, iface)))
 goto cleanup;
+}
 
 switch (port->plugtype) {
 case VIR_NETWORK_PORT_PLUG_TYPE_NONE:
 virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
_("Unexpectedly got a network port without a plug"));
-goto error;
+goto cleanup;
 
 case VIR_NETWORK_PORT_PLUG_TYPE_BRIDGE:
 /* see if we're connected to the correct bridge */
 if (!netdef->bridge) {
 virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
_("Unexpectedly got a network port plugged into a 
bridge"));
-goto error;
+goto cleanup;
 }
 break;
 
 case VIR_NETWORK_PORT_PLUG_TYPE_DIRECT:
 if (networkCreateInterfacePool(netdef) < 0)
-goto error;
+goto cleanup;
 
 /* find the matching interface and increment its connections */
 for (i = 0; i < netdef->forward.nifs; i++) {
@@ -4823,7 +4800,7 @@ networkNotifyActualDevice(virNetworkPtr net,
  "in use by network port '%s'"),
netdef->name, port->plug.direct.linkdev,
port->uuid);
-goto error;
+goto cleanup;
 }
 
 /* PASSTHROUGH mode and PRIVATE Mode + 802.1Qbh both require
@@ -4839,14 +4816,14 @@ networkNotifyActualDevice(virNetworkPtr net,
_("network '%s' claims dev='%s' is already in "
  "use by a different port"),
netdef->name, port->plug.direct.linkdev);
-goto error;
+goto cleanup;
 }
 break;
 
 case VIR_NETWORK_PORT_PLUG_TYPE_HOSTDEV_PCI:
 
 if (networkCreateInterfacePool(netdef) < 0)
-goto error;
+goto cleanup;
 
 /* find the matching interface and increment its connections */
 for (i = 0; i < netdef->forward.nifs; i++) {
@@ -4868,7 +4845,7 @@ networkNotifyActualDevice(virNetworkPtr net,
port->plug.hostdevpci.addr.bus,
port->plug.hostdevpci.addr.slot,
port->plug.hostdevpci.addr.function);
-goto error;
+goto cleanup;
 }
 
 /* PASSTHROUGH mode, PRIVATE Mode + 802.1Qbh, and hostdev (PCI
@@ -4884,7 +4861,7 @@ networkNotifyActualDevice(virNetworkPtr net,
netdef->name,
dev->device.pci.domain, dev->device.pci.bus,
dev->device.pci.slot, dev->device.pci.function);
-goto error;
+goto cleanup;
 }
 
 break;
@@ 

[libvirt] [PATCH v2 23/36] network: introduce networkAllocatePort

2019-02-27 Thread Daniel P . Berrangé
Separate network port allocation code from the domain driver network
callback implementation.

Signed-off-by: Daniel P. Berrangé 
---
 src/network/bridge_driver.c | 143 +++-
 1 file changed, 77 insertions(+), 66 deletions(-)

diff --git a/src/network/bridge_driver.c b/src/network/bridge_driver.c
index 3778c65bc2..2df80a0af5 100644
--- a/src/network/bridge_driver.c
+++ b/src/network/bridge_driver.c
@@ -4356,60 +4356,38 @@ networkLogAllocation(virNetworkDefPtr netdef,
  * "backend" function table.
  */
 
-/* networkAllocateActualDevice:
- * @dom: domain definition that @iface belongs to
- * @iface: the original NetDef from the domain
+/* networkAllocatePort:
+ * @obj: the network to allocate from
+ * @port: the port definition to allocate
  *
- * Looks up the network reference by iface, allocates a physical
+ * Looks up the network reference by port, allocates a physical
  * device from that network (if appropriate), and returns with the
- * virDomainActualNetDef filled in accordingly. If there are no
- * changes to be made in the netdef, then just leave the actualdef
- * empty.
+ * port configuration filled in accordingly.
  *
  * Returns 0 on success, -1 on failure.
  */
 static int
-networkAllocateActualDevice(virNetworkPtr net,
-virDomainDefPtr dom,
-virDomainNetDefPtr iface)
+networkAllocatePort(virNetworkObjPtr obj,
+virNetworkPortDefPtr port)
 {
 virNetworkDriverStatePtr driver = networkGetDriver();
-virNetworkObjPtr obj = NULL;
 virNetworkDefPtr netdef = NULL;
 virPortGroupDefPtr portgroup = NULL;
 virNetworkForwardIfDefPtr dev = NULL;
 size_t i;
 int ret = -1;
 virNetDevVPortProfilePtr portprofile = NULL;
-virNetworkPortDefPtr port = NULL;
-
-VIR_DEBUG("Allocating port from net %s", net->name);
-obj = virNetworkObjFindByName(driver->networks, net->name);
-if (!obj) {
-virReportError(VIR_ERR_NO_NETWORK,
-   _("no network with matching name '%s'"),
-   net->name);
-goto error;
-}
-
-if (iface->type != VIR_DOMAIN_NET_TYPE_NETWORK) {
-virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
-   _("Expected a interface for a virtual network"));
-goto error;
-}
 
 netdef = virNetworkObjGetDef(obj);
+VIR_DEBUG("Allocating port from net %s", netdef->name);
 
 if (!virNetworkObjIsActive(obj)) {
 virReportError(VIR_ERR_OPERATION_INVALID,
_("network '%s' is not active"),
netdef->name);
-goto error;
+goto cleanup;
 }
 
-if (!(port = virDomainNetDefToNetworkPort(dom, iface)))
-goto error;
-
 VIR_DEBUG("Interface port group %s", port->group);
 /* portgroup can be present for any type of network, in particular
  * for bandwidth information, so we need to check for that and
@@ -4421,7 +4399,7 @@ networkAllocateActualDevice(virNetworkPtr net,
 if (portgroup && portgroup->bandwidth &&
 virNetDevBandwidthCopy(>bandwidth,
portgroup->bandwidth) < 0)
-goto error;
+goto cleanup;
 }
 
 if (port->vlan.nTags == 0) {
@@ -4432,7 +4410,7 @@ networkAllocateActualDevice(virNetworkPtr net,
 vlan = >vlan;
 
 if (vlan && virNetDevVlanCopy(>vlan, vlan) < 0)
-goto error;
+goto cleanup;
 }
 
 if (!port->trustGuestRxFilters) {
@@ -4450,7 +4428,7 @@ networkAllocateActualDevice(virNetworkPtr net,
 netdef->virtPortProfile,
 portgroup
 ? portgroup->virtPortProfile : NULL) < 0) {
-goto error;
+goto cleanup;
 }
 if (portprofile) {
 VIR_FREE(port->virtPortProfile);
@@ -4466,7 +,7 @@ networkAllocateActualDevice(virNetworkPtr net,
 port->plugtype = VIR_NETWORK_PORT_PLUG_TYPE_BRIDGE;
 
 if (VIR_STRDUP(port->plug.bridge.brname, netdef->bridge) < 0)
-goto error;
+goto cleanup;
 port->plug.bridge.macTableManager = netdef->macTableManager;
 
 if (port->virtPortProfile) {
@@ -4475,18 +4453,18 @@ networkAllocateActualDevice(virNetworkPtr net,
  "'%s' which uses IP forwarding"),

virNetDevVPortTypeToString(port->virtPortProfile->virtPortType),
netdef->name);
-goto error;
+goto cleanup;
 }
 
 if (networkPlugBandwidth(obj, >mac, port->bandwidth, 
>class_id) < 0)
-goto error;
+goto cleanup;
 break;
 
 case VIR_NETWORK_FORWARD_HOSTDEV: {
 port->plugtype = VIR_NETWORK_PORT_PLUG_TYPE_HOSTDEV_PCI;
 
 if (networkCreateInterfacePool(netdef) < 0)
-goto error;
+

[libvirt] [PATCH v2 16/36] util: add API for copying virtual port profile data

2019-02-27 Thread Daniel P . Berrangé
Signed-off-by: Daniel P. Berrangé 
---
 src/libvirt_private.syms |  1 +
 src/util/virnetdevvportprofile.c | 16 
 src/util/virnetdevvportprofile.h |  2 ++
 3 files changed, 19 insertions(+)

diff --git a/src/libvirt_private.syms b/src/libvirt_private.syms
index c63e204c61..a9c465ba5f 100644
--- a/src/libvirt_private.syms
+++ b/src/libvirt_private.syms
@@ -2466,6 +2466,7 @@ virNetDevVlanFree;
 virNetDevVPortProfileAssociate;
 virNetDevVPortProfileCheckComplete;
 virNetDevVPortProfileCheckNoExtras;
+virNetDevVPortProfileCopy;
 virNetDevVPortProfileDisassociate;
 virNetDevVPortProfileEqual;
 virNetDevVPortProfileMerge3;
diff --git a/src/util/virnetdevvportprofile.c b/src/util/virnetdevvportprofile.c
index fb05190c02..b6e8365e61 100644
--- a/src/util/virnetdevvportprofile.c
+++ b/src/util/virnetdevvportprofile.c
@@ -125,6 +125,22 @@ virNetDevVPortProfileEqual(virNetDevVPortProfilePtr a, 
virNetDevVPortProfilePtr
 return true;
 }
 
+
+int virNetDevVPortProfileCopy(virNetDevVPortProfilePtr *dst, const 
virNetDevVPortProfile *src)
+{
+if (!src) {
+*dst = NULL;
+return 0;
+}
+
+if (VIR_ALLOC(*dst) < 0)
+return -1;
+
+memcpy(*dst, src, sizeof(*src));
+return 0;
+}
+
+
 /* virNetDevVPortProfileCheckComplete() checks that all attributes
  * required for the type of virtport are specified. When
  * generateMissing is true, any missing attribute that can be
diff --git a/src/util/virnetdevvportprofile.h b/src/util/virnetdevvportprofile.h
index 65b4779861..503c44e086 100644
--- a/src/util/virnetdevvportprofile.h
+++ b/src/util/virnetdevvportprofile.h
@@ -79,6 +79,8 @@ struct _virNetDevVPortProfile {
 
 bool virNetDevVPortProfileEqual(virNetDevVPortProfilePtr a,
 virNetDevVPortProfilePtr b);
+int virNetDevVPortProfileCopy(virNetDevVPortProfilePtr *dst,
+  const virNetDevVPortProfile *src);
 
 int virNetDevVPortProfileCheckComplete(virNetDevVPortProfilePtr virtport,
bool generateMissing);
-- 
2.20.1

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

[libvirt] [PATCH v2 14/36] network: stop passing virDomainNetDefPtr into bandwidth functions

2019-02-27 Thread Daniel P . Berrangé
The networkPlugBandwidth & networkUnplugBandwidth methods currently take
a virDomainNetDefPtr. To remove the dependency on the domain config
struct, pass individual parameters instead.

Signed-off-by: Daniel P. Berrangé 
---
 src/network/bridge_driver.c | 94 -
 1 file changed, 50 insertions(+), 44 deletions(-)

diff --git a/src/network/bridge_driver.c b/src/network/bridge_driver.c
index b71175cc4b..1061325d16 100644
--- a/src/network/bridge_driver.c
+++ b/src/network/bridge_driver.c
@@ -169,11 +169,14 @@ networkRefreshDaemons(virNetworkDriverStatePtr driver);
 
 static int
 networkPlugBandwidth(virNetworkObjPtr obj,
- virDomainNetDefPtr iface);
+ virMacAddrPtr mac,
+ virNetDevBandwidthPtr ifaceBand,
+ unsigned int *class_id);
 
 static int
 networkUnplugBandwidth(virNetworkObjPtr obj,
-   virDomainNetDefPtr iface);
+   virNetDevBandwidthPtr ifaceBand,
+   unsigned int *class_id);
 
 static void
 networkNetworkObjTaint(virNetworkObjPtr obj,
@@ -4498,7 +4501,9 @@ networkAllocateActualDevice(virNetworkPtr net,
 goto error;
 }
 
-if (networkPlugBandwidth(obj, iface) < 0)
+if (networkPlugBandwidth(obj, >mac, iface->bandwidth,
+ iface->data.network.actual ?
+ >data.network.actual->class_id : NULL) 
< 0)
 goto error;
 break;
 
@@ -4591,7 +4596,9 @@ networkAllocateActualDevice(virNetworkPtr net,
 }
 }
 
-if (networkPlugBandwidth(obj, iface) < 0)
+if (networkPlugBandwidth(obj, >mac, iface->bandwidth,
+ iface->data.network.actual ?
+ >data.network.actual->class_id : 
NULL) < 0)
 goto error;
 break;
 }
@@ -4998,14 +5005,17 @@ networkReleaseActualDevice(virNetworkPtr net,
 case VIR_NETWORK_FORWARD_NAT:
 case VIR_NETWORK_FORWARD_ROUTE:
 case VIR_NETWORK_FORWARD_OPEN:
-if (iface->data.network.actual && networkUnplugBandwidth(obj, iface) < 
0)
+if (iface->data.network.actual &&
+networkUnplugBandwidth(obj, iface->bandwidth,
+   >data.network.actual->class_id) < 0)
 goto error;
 break;
 
 case VIR_NETWORK_FORWARD_BRIDGE:
 if (iface->data.network.actual &&
 actualType == VIR_DOMAIN_NET_TYPE_BRIDGE &&
-networkUnplugBandwidth(obj, iface) < 0)
+networkUnplugBandwidth(obj, iface->bandwidth,
+   >data.network.actual->class_id) < 0)
 goto error;
 break;
 case VIR_NETWORK_FORWARD_PRIVATE:
@@ -5145,7 +5155,7 @@ static int
 networkCheckBandwidth(virNetworkObjPtr obj,
   virNetDevBandwidthPtr ifaceBand,
   virNetDevBandwidthPtr oldBandwidth,
-  virMacAddr ifaceMac,
+  virMacAddrPtr ifaceMac,
   unsigned long long *new_rate)
 {
 int ret = -1;
@@ -5155,7 +5165,7 @@ networkCheckBandwidth(virNetworkObjPtr obj,
 unsigned long long tmp_new_rate = 0;
 char ifmac[VIR_MAC_STRING_BUFLEN];
 
-virMacAddrFormat(, ifmac);
+virMacAddrFormat(ifaceMac, ifmac);
 
 if (ifaceBand && ifaceBand->in && ifaceBand->in->floor &&
 !(netBand && netBand->in)) {
@@ -5240,44 +5250,45 @@ networkNextClassID(virNetworkObjPtr obj)
 
 static int
 networkPlugBandwidthImpl(virNetworkObjPtr obj,
- virDomainNetDefPtr iface,
+ virMacAddrPtr mac,
  virNetDevBandwidthPtr ifaceBand,
+ unsigned int *class_id,
  unsigned long long new_rate)
 {
 virNetworkDriverStatePtr driver = networkGetDriver();
 virNetworkDefPtr def = virNetworkObjGetDef(obj);
 virBitmapPtr classIdMap = virNetworkObjGetClassIdMap(obj);
 unsigned long long tmp_floor_sum = virNetworkObjGetFloorSum(obj);
-ssize_t class_id = 0;
+ssize_t next_id = 0;
 int plug_ret;
 int ret = -1;
 
 /* generate new class_id */
-if ((class_id = networkNextClassID(obj)) < 0) {
+if ((next_id = networkNextClassID(obj)) < 0) {
 virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
_("Could not generate next class ID"));
 goto cleanup;
 }
 
 plug_ret = virNetDevBandwidthPlug(def->bridge, def->bandwidth,
-  >mac, ifaceBand, class_id);
+  mac, ifaceBand, next_id);
 if (plug_ret < 0) {
-ignore_value(virNetDevBandwidthUnplug(def->bridge, class_id));
+ignore_value(virNetDevBandwidthUnplug(def->bridge, next_id));
 goto cleanup;
 }
 
 /* QoS was set, generate new 

[libvirt] [PATCH v2 15/36] network: make networkLogAllocation independent of domain conf

2019-02-27 Thread Daniel P . Berrangé
Stop passing a virDomainNetDefPtr parameter to networkLogAllocation,
instead just pass in the MAC address. The actual device type is also not
required, since virNetworkForwardIfDefPtr has a type field that can be
used instad.

Signed-off-by: Daniel P. Berrangé 
---
 src/network/bridge_driver.c | 21 +
 1 file changed, 9 insertions(+), 12 deletions(-)

diff --git a/src/network/bridge_driver.c b/src/network/bridge_driver.c
index 1061325d16..cc737c6cee 100644
--- a/src/network/bridge_driver.c
+++ b/src/network/bridge_driver.c
@@ -4323,32 +4323,29 @@ networkGetDHCPLeases(virNetworkPtr net,
 
 static void
 networkLogAllocation(virNetworkDefPtr netdef,
- virDomainNetType actualType,
  virNetworkForwardIfDefPtr dev,
- virDomainNetDefPtr iface,
+ virMacAddrPtr mac,
  bool inUse)
 {
 char macStr[VIR_MAC_STRING_BUFLEN];
 const char *verb = inUse ? "using" : "releasing";
 
+virMacAddrFormat(mac, macStr);
 if (!dev) {
 VIR_INFO("MAC %s %s network %s (%d connections)",
- virMacAddrFormat(>mac, macStr), verb,
- netdef->name, netdef->connections);
+ macStr, verb, netdef->name, netdef->connections);
 } else {
-if (actualType == VIR_DOMAIN_NET_TYPE_HOSTDEV) {
+if (dev->type == VIR_NETWORK_FORWARD_HOSTDEV_DEVICE_PCI) {
 VIR_INFO("MAC %s %s network %s (%d connections) "
  "physical device %04x:%02x:%02x.%x (%d connections)",
- virMacAddrFormat(>mac, macStr), verb,
- netdef->name, netdef->connections,
+ macStr, verb, netdef->name, netdef->connections,
  dev->device.pci.domain, dev->device.pci.bus,
  dev->device.pci.slot, dev->device.pci.function,
  dev->connections);
 } else {
 VIR_INFO("MAC %s %s network %s (%d connections) "
  "physical device %s (%d connections)",
- virMacAddrFormat(>mac, macStr), verb,
- netdef->name, netdef->connections,
+ macStr, verb, netdef->name, netdef->connections,
  dev->device.dev, dev->connections);
 }
 }
@@ -4757,7 +4754,7 @@ networkAllocateActualDevice(virNetworkPtr net,
 dev->connections--;
 goto error;
 }
-networkLogAllocation(netdef, actualType, dev, iface, true);
+networkLogAllocation(netdef, dev, >mac, true);
 
 ret = 0;
 
@@ -4948,7 +4945,7 @@ networkNotifyActualDevice(virNetworkPtr net,
 netdef->connections--;
 goto error;
 }
-networkLogAllocation(netdef, actualType, dev, iface, true);
+networkLogAllocation(netdef, dev, >mac, true);
 ret = 0;
 
  cleanup:
@@ -5115,7 +5112,7 @@ networkReleaseActualDevice(virNetworkPtr net,
 /* finally we can call the 'unplugged' hook script if any */
 networkRunHook(obj, dom, iface, VIR_HOOK_NETWORK_OP_IFACE_UNPLUGGED,
VIR_HOOK_SUBOP_BEGIN);
-networkLogAllocation(netdef, actualType, dev, iface, false);
+networkLogAllocation(netdef, dev, >mac, false);
 }
 ret = 0;
  cleanup:
-- 
2.20.1

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

[libvirt] [PATCH v2 36/36] conf: switch over to use network port APIs for virt drivers

2019-02-27 Thread Daniel P . Berrangé
Change the domain conf so invoke the new network port public APIs instead
of the network callbacks.

Signed-off-by: Daniel P. Berrangé 
---
 src/conf/domain_conf.c  | 262 
 src/conf/domain_conf.h  |  26 
 src/network/bridge_driver.c | 200 ---
 3 files changed, 178 insertions(+), 310 deletions(-)

diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c
index 61987e7f51..2031868101 100644
--- a/src/conf/domain_conf.c
+++ b/src/conf/domain_conf.c
@@ -30869,6 +30869,7 @@ virDomainNetDefActualFromNetworkPort(virDomainNetDefPtr 
iface,
 if (VIR_STRDUP(actual->data.bridge.brname,
port->plug.bridge.brname) < 0)
 goto error;
+actual->type = VIR_DOMAIN_NET_TYPE_BRIDGE;
 actual->data.bridge.macTableManager = 
port->plug.bridge.macTableManager;
 break;
 
@@ -30876,10 +30877,12 @@ 
virDomainNetDefActualFromNetworkPort(virDomainNetDefPtr iface,
 if (VIR_STRDUP(actual->data.direct.linkdev,
port->plug.direct.linkdev) < 0)
 goto error;
+actual->type = VIR_DOMAIN_NET_TYPE_DIRECT;
 actual->data.direct.mode = port->plug.direct.mode;
 break;
 
 case VIR_NETWORK_PORT_PLUG_TYPE_HOSTDEV_PCI:
+actual->type = VIR_DOMAIN_NET_TYPE_HOSTDEV;
 actual->data.hostdev.def.parent = iface;
 actual->data.hostdev.def.info = >info;
 actual->data.hostdev.def.mode = VIR_DOMAIN_HOSTDEV_MODE_SUBSYS;
@@ -31071,45 +31074,100 @@ virDomainNetDefActualToNetworkPort(virDomainDefPtr 
dom,
 return NULL;
 }
 
-static virDomainNetAllocateActualDeviceImpl netAllocate;
-static virDomainNetNotifyActualDeviceImpl netNotify;
-static virDomainNetReleaseActualDeviceImpl netRelease;
-static virDomainNetBandwidthUpdateImpl netBandwidthUpdate;
 
-
-void
-virDomainNetSetDeviceImpl(virDomainNetAllocateActualDeviceImpl allocate,
-  virDomainNetNotifyActualDeviceImpl notify,
-  virDomainNetReleaseActualDeviceImpl release,
-  virDomainNetBandwidthUpdateImpl bandwidthUpdate)
-{
-netAllocate = allocate;
-netNotify = notify;
-netRelease = release;
-netBandwidthUpdate = bandwidthUpdate;
-}
-
-int
-virDomainNetAllocateActualDevice(virConnectPtr conn,
- virDomainDefPtr dom,
- virDomainNetDefPtr iface)
+static int
+virDomainNetCreatePort(virConnectPtr conn,
+   virDomainDefPtr dom,
+   virDomainNetDefPtr iface,
+   unsigned int flags)
 {
 virNetworkPtr net = NULL;
 int ret = -1;
+virNetworkPortDefPtr portdef = NULL;
+virNetworkPortPtr port = NULL;
+char *portxml = NULL;
+virErrorPtr saved;
 
-if (!netAllocate) {
-virReportError(VIR_ERR_NO_SUPPORT, "%s",
-   _("Virtual networking driver is not available"));
+if (!(net = virNetworkLookupByName(conn, iface->data.network.name)))
 return -1;
+
+if (flags & VIR_NETWORK_PORT_CREATE_RECLAIM) {
+virDomainNetType actualType = virDomainNetGetActualType(iface);
+
+/* if we're restarting libvirtd after an upgrade from a version
+ * that didn't save bridge name in actualNetDef for
+ * actualType==network, we need to copy it in so that it will be
+ * available in all cases
+ */
+if (actualType == VIR_DOMAIN_NET_TYPE_NETWORK &&
+!iface->data.network.actual->data.bridge.brname) {
+char *bridge = virNetworkGetBridgeName(net);
+if (!bridge)
+goto cleanup;
+VIR_FREE(iface->data.network.actual->data.bridge.brname);
+iface->data.network.actual->data.bridge.brname = bridge;
+}
+
+/* Older libvirtd uses actualType==network, but we now
+ * just use actualType==bridge, as nothing needs to
+ * distinguish the two cases, and this simplifies virt
+ * drive code */
+if (actualType == VIR_DOMAIN_NET_TYPE_NETWORK) {
+iface->data.network.actual->type = VIR_DOMAIN_NET_TYPE_BRIDGE;
+actualType = VIR_DOMAIN_NET_TYPE_BRIDGE;
+}
+
+if (!(portdef = virDomainNetDefActualToNetworkPort(dom, iface)))
+goto cleanup;
+} else {
+if (!(portdef = virDomainNetDefToNetworkPort(dom, iface)))
+goto cleanup;
 }
 
-if (!(net = virNetworkLookupByName(conn, iface->data.network.name)))
-return -1;
+if (!(portxml = virNetworkPortDefFormat(portdef)))
+goto cleanup;
 
-ret = netAllocate(net, dom, iface);
+virNetworkPortDefFree(portdef);
+portdef = NULL;
 
+if (!(port = virNetworkPortCreateXML(net, portxml, flags)))
+goto cleanup;
+
+VIR_FREE(portxml);
+
+if (!(portxml = virNetworkPortGetXMLDesc(port, 0)))
+goto deleteport;
+
+if (!(portdef 

[libvirt] [PATCH v2 17/36] conf: add APIs to convert virDomainNetDef to virNetworkPortDef

2019-02-27 Thread Daniel P . Berrangé
Helper APIs are needed to

 - Populate basic virNetworkPortDef from virDomainNetDef
 - Set a virDomainActualNetDef from virNetworkPortDef
 - Populate a full virNetworkPortDef from virDomainActualNetDef

Signed-off-by: Daniel P. Berrangé 
---
 src/conf/domain_conf.c   | 272 +++
 src/conf/domain_conf.h   |  17 +++
 src/libvirt_private.syms |   3 +
 3 files changed, 292 insertions(+)

diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c
index 4a67e23137..327b5d3497 100644
--- a/src/conf/domain_conf.c
+++ b/src/conf/domain_conf.c
@@ -39,6 +39,7 @@
 #include "virbuffer.h"
 #include "virlog.h"
 #include "nwfilter_conf.h"
+#include "virnetworkportdef.h"
 #include "storage_conf.h"
 #include "virstoragefile.h"
 #include "virfile.h"
@@ -30777,6 +30778,277 @@ virDomainNetTypeSharesHostView(const virDomainNetDef 
*net)
 return false;
 }
 
+virNetworkPortDefPtr
+virDomainNetDefToNetworkPort(virDomainDefPtr dom,
+ virDomainNetDefPtr iface)
+{
+virNetworkPortDefPtr port;
+
+if (iface->type != VIR_DOMAIN_NET_TYPE_NETWORK) {
+virReportError(VIR_ERR_INTERNAL_ERROR,
+   _("Expected an interface of type 'network' not '%s'"),
+   virDomainNetTypeToString(iface->type));
+return NULL;
+}
+
+if (VIR_ALLOC(port) < 0)
+return NULL;
+
+virUUIDGenerate(port->uuid);
+
+memcpy(port->owneruuid, dom->uuid, VIR_UUID_BUFLEN);
+if (VIR_STRDUP(port->ownername, dom->name) < 0)
+goto error;
+
+if (VIR_STRDUP(port->group, iface->data.network.portgroup) < 0)
+goto error;
+
+memcpy(>mac, >mac, VIR_MAC_BUFLEN);
+
+if (virNetDevVPortProfileCopy(>virtPortProfile, 
iface->virtPortProfile) < 0)
+goto error;
+
+if (virNetDevBandwidthCopy(>bandwidth, iface->bandwidth) < 0)
+goto error;
+
+if (virNetDevVlanCopy(>vlan, >vlan) < 0)
+goto error;
+
+port->trustGuestRxFilters = iface->trustGuestRxFilters;
+
+return port;
+
+ error:
+virNetworkPortDefFree(port);
+return NULL;
+}
+
+int
+virDomainNetDefActualFromNetworkPort(virDomainNetDefPtr iface,
+ virNetworkPortDefPtr port)
+{
+virDomainActualNetDefPtr actual = NULL;
+
+if (iface->type != VIR_DOMAIN_NET_TYPE_NETWORK) {
+virReportError(VIR_ERR_INTERNAL_ERROR,
+   _("Expected an interface of type 'network' not '%s'"),
+   virDomainNetTypeToString(iface->type));
+return -1;
+}
+
+if (VIR_ALLOC(actual) < 0)
+return -1;
+
+switch ((virNetworkPortPlugType)port->plugtype) {
+case VIR_NETWORK_PORT_PLUG_TYPE_NONE:
+break;
+
+case VIR_NETWORK_PORT_PLUG_TYPE_BRIDGE:
+if (VIR_STRDUP(actual->data.bridge.brname,
+   port->plug.bridge.brname) < 0)
+goto error;
+actual->data.bridge.macTableManager = 
port->plug.bridge.macTableManager;
+break;
+
+case VIR_NETWORK_PORT_PLUG_TYPE_DIRECT:
+if (VIR_STRDUP(actual->data.direct.linkdev,
+   port->plug.direct.linkdev) < 0)
+goto error;
+actual->data.direct.mode = port->plug.direct.mode;
+break;
+
+case VIR_NETWORK_PORT_PLUG_TYPE_HOSTDEV_PCI:
+actual->data.hostdev.def.parent = iface;
+actual->data.hostdev.def.info = >info;
+actual->data.hostdev.def.mode = VIR_DOMAIN_HOSTDEV_MODE_SUBSYS;
+actual->data.hostdev.def.managed = port->plug.hostdevpci.managed;
+actual->data.hostdev.def.source.subsys.type = 
VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_PCI;
+actual->data.hostdev.def.source.subsys.u.pci.addr = 
port->plug.hostdevpci.addr;
+switch ((virNetworkForwardDriverNameType)port->plug.hostdevpci.driver) 
{
+case VIR_NETWORK_FORWARD_DRIVER_NAME_DEFAULT:
+actual->data.hostdev.def.source.subsys.u.pci.backend =
+VIR_DOMAIN_HOSTDEV_PCI_BACKEND_DEFAULT;
+break;
+
+case VIR_NETWORK_FORWARD_DRIVER_NAME_KVM:
+actual->data.hostdev.def.source.subsys.u.pci.backend =
+VIR_DOMAIN_HOSTDEV_PCI_BACKEND_KVM;
+break;
+
+case VIR_NETWORK_FORWARD_DRIVER_NAME_VFIO:
+actual->data.hostdev.def.source.subsys.u.pci.backend =
+VIR_DOMAIN_HOSTDEV_PCI_BACKEND_VFIO;
+break;
+
+case VIR_NETWORK_FORWARD_DRIVER_NAME_LAST:
+default:
+virReportEnumRangeError(virNetworkForwardDriverNameType,
+port->plug.hostdevpci.driver);
+goto error;
+}
+
+break;
+
+case VIR_NETWORK_PORT_PLUG_TYPE_LAST:
+default:
+virReportEnumRangeError(virNetworkPortPlugType, port->plugtype);
+goto error;
+}
+
+if (virNetDevVPortProfileCopy(>virtPortProfile, 
port->virtPortProfile) < 0)
+goto error;
+
+if (virNetDevBandwidthCopy(>bandwidth, 

[libvirt] [PATCH v2 18/36] network: convert networkAllocateActualDevice to virNetworkPortDef

2019-02-27 Thread Daniel P . Berrangé
Convert the virDomainNetDef object into a virNetworkPortDef object
at the start of networkAllocateActualDevice. This largely decouples
the method impl from the domain object type.

Signed-off-by: Daniel P. Berrangé 
---
 src/network/bridge_driver.c | 222 +++-
 1 file changed, 91 insertions(+), 131 deletions(-)

diff --git a/src/network/bridge_driver.c b/src/network/bridge_driver.c
index cc737c6cee..365753baf2 100644
--- a/src/network/bridge_driver.c
+++ b/src/network/bridge_driver.c
@@ -67,6 +67,7 @@
 #include "network_event.h"
 #include "virhook.h"
 #include "virjson.h"
+#include "conf/virnetworkportdef.h"
 
 #define VIR_FROM_THIS VIR_FROM_NETWORK
 #define MAX_BRIDGE_ID 256
@@ -4378,17 +4379,16 @@ networkAllocateActualDevice(virNetworkPtr net,
 virDomainNetDefPtr iface)
 {
 virNetworkDriverStatePtr driver = networkGetDriver();
-virDomainNetType actualType = iface->type;
 virNetworkObjPtr obj = NULL;
 virNetworkDefPtr netdef = NULL;
-virNetDevBandwidthPtr bandwidth = NULL;
 virPortGroupDefPtr portgroup = NULL;
-virNetDevVPortProfilePtr virtport = iface->virtPortProfile;
-virNetDevVlanPtr vlan = NULL;
 virNetworkForwardIfDefPtr dev = NULL;
 size_t i;
 int ret = -1;
+virNetDevVPortProfilePtr portprofile = NULL;
+virNetworkPortDefPtr port = NULL;
 
+VIR_DEBUG("Allocating port from net %s", net->name);
 obj = virNetworkObjFindByName(driver->networks, net->name);
 if (!obj) {
 virReportError(VIR_ERR_NO_NETWORK,
@@ -4403,9 +4403,6 @@ networkAllocateActualDevice(virNetworkPtr net,
 goto error;
 }
 
-virDomainActualNetDefFree(iface->data.network.actual);
-iface->data.network.actual = NULL;
-
 netdef = virNetworkObjGetDef(obj);
 
 if (!virNetworkObjIsActive(obj)) {
@@ -4415,99 +4412,84 @@ networkAllocateActualDevice(virNetworkPtr net,
 goto error;
 }
 
-if (VIR_ALLOC(iface->data.network.actual) < 0)
+if (!(port = virDomainNetDefToNetworkPort(dom, iface)))
 goto error;
 
+VIR_DEBUG("Interface port group %s", port->group);
 /* portgroup can be present for any type of network, in particular
  * for bandwidth information, so we need to check for that and
  * fill it in appropriately for all forward types.
  */
-portgroup = virPortGroupFindByName(netdef, iface->data.network.portgroup);
-
-/* If there is already interface-specific bandwidth, just use that
- * (already in NetDef). Otherwise, if there is bandwidth info in
- * the portgroup, fill that into the ActualDef.
- */
-
-if (iface->bandwidth)
-bandwidth = iface->bandwidth;
-else if (portgroup && portgroup->bandwidth)
-bandwidth = portgroup->bandwidth;
+portgroup = virPortGroupFindByName(netdef, port->group);
 
-if (bandwidth && 
virNetDevBandwidthCopy(>data.network.actual->bandwidth,
-bandwidth) < 0)
-goto error;
+if (!port->bandwidth) {
+if (portgroup && portgroup->bandwidth &&
+virNetDevBandwidthCopy(>bandwidth,
+   portgroup->bandwidth) < 0)
+goto error;
+}
 
-/* copy appropriate vlan info to actualNet */
-if (iface->vlan.nTags > 0)
-vlan = >vlan;
-else if (portgroup && portgroup->vlan.nTags > 0)
-vlan = >vlan;
-else if (netdef->vlan.nTags > 0)
-vlan = >vlan;
+if (port->vlan.nTags == 0) {
+virNetDevVlanPtr vlan = NULL;
+if (portgroup && portgroup->vlan.nTags > 0)
+vlan = >vlan;
+else if (netdef->vlan.nTags > 0)
+vlan = >vlan;
 
-if (vlan && virNetDevVlanCopy(>data.network.actual->vlan, vlan) < 0)
-goto error;
+if (vlan && virNetDevVlanCopy(>vlan, vlan) < 0)
+goto error;
+}
 
-if (iface->trustGuestRxFilters)
-   iface->data.network.actual->trustGuestRxFilters
-  = iface->trustGuestRxFilters;
-else if (portgroup && portgroup->trustGuestRxFilters)
-   iface->data.network.actual->trustGuestRxFilters
-  = portgroup->trustGuestRxFilters;
-else if (netdef->trustGuestRxFilters)
-   iface->data.network.actual->trustGuestRxFilters
-  = netdef->trustGuestRxFilters;
+if (!port->trustGuestRxFilters) {
+if (portgroup && portgroup->trustGuestRxFilters)
+port->trustGuestRxFilters = portgroup->trustGuestRxFilters;
+else if (netdef->trustGuestRxFilters)
+port->trustGuestRxFilters = netdef->trustGuestRxFilters;
+}
 
 /* merge virtualports from interface, network, and portgroup to
  * arrive at actual virtualport to use
  */
-if 
(virNetDevVPortProfileMerge3(>data.network.actual->virtPortProfile,
-iface->virtPortProfile,
+if (virNetDevVPortProfileMerge3(,
+port->virtPortProfile,
 

[libvirt] [PATCH v2 12/36] conf: don't pass interface type into virNetDevBandwidthParse

2019-02-27 Thread Daniel P . Berrangé
The virNetDevBandwidthParse method uses the interface type to decide
whether to allow use of the "floor" parameter. Using the interface
type is not convenient as callers may not have that available, but
still wish to allow use of "floor". Switch to an explicit boolean
to control its usage.

Signed-off-by: Daniel P. Berrangé 
---
 src/conf/domain_conf.c   |  4 ++--
 src/conf/netdev_bandwidth_conf.c | 22 +++---
 src/conf/netdev_bandwidth_conf.h |  2 +-
 src/conf/network_conf.c  |  4 ++--
 tests/virnetdevbandwidthtest.c   |  2 +-
 5 files changed, 13 insertions(+), 21 deletions(-)

diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c
index afc4321a9a..4a67e23137 100644
--- a/src/conf/domain_conf.c
+++ b/src/conf/domain_conf.c
@@ -11171,7 +11171,7 @@ virDomainActualNetDefParseXML(xmlNodePtr node,
 if (bandwidth_node &&
 virNetDevBandwidthParse(>bandwidth,
 bandwidth_node,
-actual->type) < 0)
+actual->type == VIR_DOMAIN_NET_TYPE_NETWORK) < 
0)
 goto error;
 
 vlanNode = virXPathNode("./vlan", ctxt);
@@ -11519,7 +11519,7 @@ virDomainNetDefParseXML(virDomainXMLOptionPtr xmlopt,
 } else if (virXMLNodeNameEqual(cur, "bandwidth")) {
 if (virNetDevBandwidthParse(>bandwidth,
 cur,
-def->type) < 0)
+def->type == 
VIR_DOMAIN_NET_TYPE_NETWORK) < 0)
 goto error;
 } else if (virXMLNodeNameEqual(cur, "vlan")) {
 if (virNetDevVlanParse(cur, ctxt, >vlan) < 0)
diff --git a/src/conf/netdev_bandwidth_conf.c b/src/conf/netdev_bandwidth_conf.c
index 3113cde888..014941836d 100644
--- a/src/conf/netdev_bandwidth_conf.c
+++ b/src/conf/netdev_bandwidth_conf.c
@@ -100,18 +100,18 @@ virNetDevBandwidthParseRate(xmlNodePtr node, 
virNetDevBandwidthRatePtr rate)
  * virNetDevBandwidthParse:
  * @bandwidth: parsed bandwidth
  * @node: XML node
- * @net_type: one of virDomainNetType
+ * @allowFloor: whether "floor" setting is supported
  *
  * Parse bandwidth XML and return pointer to structure.
- * @net_type tell to which type will/is interface connected to.
- * Pass -1 if this is not called on interface.
+ * The @allowFloor attribute indicates whether the caller
+ * is able to support use of the "floor" setting.
  *
  * Returns !NULL on success, NULL on error.
  */
 int
 virNetDevBandwidthParse(virNetDevBandwidthPtr *bandwidth,
 xmlNodePtr node,
-int net_type)
+bool allowFloor)
 {
 int ret = -1;
 virNetDevBandwidthPtr def = NULL;
@@ -162,17 +162,9 @@ virNetDevBandwidthParse(virNetDevBandwidthPtr *bandwidth,
 goto cleanup;
 }
 
-if (def->in->floor && net_type != VIR_DOMAIN_NET_TYPE_NETWORK) {
-if (net_type == -1) {
-/* 'floor' on network isn't supported */
-virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
-   _("floor attribute isn't supported for "
- "network's bandwidth yet"));
-} else {
-virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
-   _("floor attribute is supported only for "
- "interfaces of type network"));
-}
+if (def->in->floor && !allowFloor) {
+virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
+   _("floor attribute is not supported for this 
config"));
 goto cleanup;
 }
 }
diff --git a/src/conf/netdev_bandwidth_conf.h b/src/conf/netdev_bandwidth_conf.h
index cb1ffd29e0..7fe750ce27 100644
--- a/src/conf/netdev_bandwidth_conf.h
+++ b/src/conf/netdev_bandwidth_conf.h
@@ -27,7 +27,7 @@
 
 int virNetDevBandwidthParse(virNetDevBandwidthPtr *bandwidth,
 xmlNodePtr node,
-int net_type)
+bool allowFloor)
 ATTRIBUTE_NONNULL(1) ATTRIBUTE_RETURN_CHECK;
 int virNetDevBandwidthFormat(virNetDevBandwidthPtr def,
  virBufferPtr buf);
diff --git a/src/conf/network_conf.c b/src/conf/network_conf.c
index 87bf158049..274f482bfc 100644
--- a/src/conf/network_conf.c
+++ b/src/conf/network_conf.c
@@ -1187,7 +1187,7 @@ virNetworkPortGroupParseXML(virPortGroupDefPtr def,
 
 bandwidth_node = virXPathNode("./bandwidth", ctxt);
 if (bandwidth_node &&
-virNetDevBandwidthParse(>bandwidth, bandwidth_node, -1) < 0)
+virNetDevBandwidthParse(>bandwidth, bandwidth_node, false) < 0)
 goto cleanup;
 
 vlanNode = virXPathNode("./vlan", ctxt);
@@ -1681,7 +1681,7 @@ virNetworkDefParseXML(xmlXPathContextPtr ctxt)
 }
 
 if ((bandwidthNode = virXPathNode("./bandwidth", ctxt)) 

[libvirt] [PATCH v2 10/36] network: move fixup for domain actual net def out of network driver

2019-02-27 Thread Daniel P . Berrangé
The hypervisor drivers are soon going to communicate with the network
driver via public APIs only. As such the network driver will not ever
see the domain actual network def. Thus the backwards compatibility
fixup logic must be moved out of the network driver.

Signed-off-by: Daniel P. Berrangé 
---
 src/conf/domain_conf.c  | 25 +
 src/network/bridge_driver.c | 20 
 2 files changed, 25 insertions(+), 20 deletions(-)

diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c
index ed0b24081e..afc4321a9a 100644
--- a/src/conf/domain_conf.c
+++ b/src/conf/domain_conf.c
@@ -30826,6 +30826,7 @@ virDomainNetNotifyActualDevice(virConnectPtr conn,
virDomainDefPtr dom,
virDomainNetDefPtr iface)
 {
+virDomainNetType actualType = virDomainNetGetActualType(iface);
 virNetworkPtr net = NULL;
 
 if (!netNotify)
@@ -30834,6 +30835,30 @@ virDomainNetNotifyActualDevice(virConnectPtr conn,
 if (!(net = virNetworkLookupByName(conn, iface->data.network.name)))
 return;
 
+/* if we're restarting libvirtd after an upgrade from a version
+ * that didn't save bridge name in actualNetDef for
+ * actualType==network, we need to copy it in so that it will be
+ * available in all cases
+ */
+if (actualType == VIR_DOMAIN_NET_TYPE_NETWORK &&
+!iface->data.network.actual->data.bridge.brname) {
+char *bridge = virNetworkGetBridgeName(net);
+if (!bridge)
+goto cleanup;
+VIR_FREE(iface->data.network.actual->data.bridge.brname);
+iface->data.network.actual->data.bridge.brname = bridge;
+}
+
+/* Older libvirtd uses actualType==network, but we now
+ * just use actualType==bridge, as nothing needs to
+ * distinguish the two cases, and this simplifies virt
+ * drive code */
+if (actualType == VIR_DOMAIN_NET_TYPE_NETWORK) {
+iface->data.network.actual->type = VIR_DOMAIN_NET_TYPE_BRIDGE;
+actualType = VIR_DOMAIN_NET_TYPE_BRIDGE;
+}
+
+
 if (netNotify(net, dom, iface) < 0)
 goto cleanup;
 
diff --git a/src/network/bridge_driver.c b/src/network/bridge_driver.c
index 5a6523c839..be26d97558 100644
--- a/src/network/bridge_driver.c
+++ b/src/network/bridge_driver.c
@@ -4826,26 +4826,6 @@ networkNotifyActualDevice(virNetworkPtr net,
 goto error;
 }
 
-/* if we're restarting libvirtd after an upgrade from a version
- * that didn't save bridge name in actualNetDef for
- * actualType==network, we need to copy it in so that it will be
- * available in all cases
- */
-if (actualType == VIR_DOMAIN_NET_TYPE_NETWORK &&
-!iface->data.network.actual->data.bridge.brname &&
-(VIR_STRDUP(iface->data.network.actual->data.bridge.brname,
-netdef->bridge) < 0))
-goto error;
-
-/* Older libvirtd uses actualType==network, but we now
- * just use actualType==bridge, as nothing needs to
- * distinguish the two cases, and this simplifies virt
- * drive code */
-if (actualType == VIR_DOMAIN_NET_TYPE_NETWORK) {
-iface->data.network.actual->type = VIR_DOMAIN_NET_TYPE_BRIDGE;
-actualType = VIR_DOMAIN_NET_TYPE_BRIDGE;
-}
-
 if (!iface->data.network.actual ||
 (actualType != VIR_DOMAIN_NET_TYPE_DIRECT &&
  actualType != VIR_DOMAIN_NET_TYPE_HOSTDEV)) {
-- 
2.20.1

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

[libvirt] [PATCH v2 11/36] network: unconditionally merge port profiles

2019-02-27 Thread Daniel P . Berrangé
All but one of the network types supports port profiles. Rather than
duplicating the code to merge profiles 3 times, do it once and then
later report an error if used from the wrong place.

Signed-off-by: Daniel P. Berrangé 
---
 src/network/bridge_driver.c | 54 +++--
 1 file changed, 21 insertions(+), 33 deletions(-)

diff --git a/src/network/bridge_driver.c b/src/network/bridge_driver.c
index be26d97558..b71175cc4b 100644
--- a/src/network/bridge_driver.c
+++ b/src/network/bridge_driver.c
@@ -4459,6 +4459,18 @@ networkAllocateActualDevice(virNetworkPtr net,
iface->data.network.actual->trustGuestRxFilters
   = netdef->trustGuestRxFilters;
 
+/* merge virtualports from interface, network, and portgroup to
+ * arrive at actual virtualport to use
+ */
+if 
(virNetDevVPortProfileMerge3(>data.network.actual->virtPortProfile,
+iface->virtPortProfile,
+netdef->virtPortProfile,
+portgroup
+? portgroup->virtPortProfile : NULL) < 0) {
+goto error;
+}
+virtport = iface->data.network.actual->virtPortProfile;
+
 switch ((virNetworkForwardType) netdef->forward.type) {
 case VIR_NETWORK_FORWARD_NONE:
 case VIR_NETWORK_FORWARD_NAT:
@@ -4477,6 +4489,15 @@ networkAllocateActualDevice(virNetworkPtr net,
 iface->data.network.actual->data.bridge.macTableManager
= netdef->macTableManager;
 
+if (virtport) {
+virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
+   _(" not supported for 
network "
+ "'%s' which uses IP forwarding"),
+   virNetDevVPortTypeToString(virtport->virtPortType),
+   netdef->name);
+goto error;
+}
+
 if (networkPlugBandwidth(obj, iface) < 0)
 goto error;
 break;
@@ -4529,17 +4550,6 @@ networkAllocateActualDevice(virNetworkPtr net,
 
iface->data.network.actual->data.hostdev.def.source.subsys.u.pci.backend
 = backend;
 
-/* merge virtualports from interface, network, and portgroup to
- * arrive at actual virtualport to use
- */
-if 
(virNetDevVPortProfileMerge3(>data.network.actual->virtPortProfile,
-iface->virtPortProfile,
-netdef->virtPortProfile,
-portgroup
-? portgroup->virtPortProfile : NULL) < 
0) {
-goto error;
-}
-virtport = iface->data.network.actual->virtPortProfile;
 if (virtport) {
 /* make sure type is supported for hostdev connections */
 if (virtport->virtPortType != VIR_NETDEV_VPORT_PROFILE_8021QBG &&
@@ -4569,17 +4579,6 @@ networkAllocateActualDevice(virNetworkPtr net,
 iface->data.network.actual->data.bridge.macTableManager
= netdef->macTableManager;
 
-/* merge virtualports from interface, network, and portgroup to
- * arrive at actual virtualport to use
- */
-if 
(virNetDevVPortProfileMerge3(>data.network.actual->virtPortProfile,
-iface->virtPortProfile,
-netdef->virtPortProfile,
-portgroup
-? portgroup->virtPortProfile : 
NULL) < 0) {
-goto error;
-}
-virtport = iface->data.network.actual->virtPortProfile;
 if (virtport) {
 /* only type='openvswitch' is allowed for bridges */
 if (virtport->virtPortType != 
VIR_NETDEV_VPORT_PROFILE_OPENVSWITCH) {
@@ -4618,17 +4617,6 @@ networkAllocateActualDevice(virNetworkPtr net,
 iface->data.network.actual->data.direct.mode =
 
virNetDevMacVLanModeTypeFromString(virNetworkForwardTypeToString(netdef->forward.type));
 
-/* merge virtualports from interface, network, and portgroup to
- * arrive at actual virtualport to use
- */
-if 
(virNetDevVPortProfileMerge3(>data.network.actual->virtPortProfile,
-iface->virtPortProfile,
-netdef->virtPortProfile,
-portgroup
-? portgroup->virtPortProfile : NULL) < 
0) {
-goto error;
-}
-virtport = iface->data.network.actual->virtPortProfile;
 if (virtport) {
 /* make sure type is supported for macvtap connections */
 if (virtport->virtPortType != VIR_NETDEV_VPORT_PROFILE_8021QBG &&
-- 
2.20.1

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

[libvirt] [PATCH v2 09/36] network: move re-attach of bridge device out of network driver

2019-02-27 Thread Daniel P . Berrangé
During initial NIC setup the hypervisor drivers are responsible for
attaching the TAP device to the bridge device. Any fixup after libvirtd
restarts should thus also be their responsibility.

Signed-off-by: Daniel P. Berrangé 
---
 src/conf/domain_conf.c  | 20 +++-
 src/conf/domain_conf.h  |  2 +-
 src/network/bridge_driver.c | 27 ++-
 3 files changed, 26 insertions(+), 23 deletions(-)

diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c
index cc352dc6d0..ed0b24081e 100644
--- a/src/conf/domain_conf.c
+++ b/src/conf/domain_conf.c
@@ -54,6 +54,7 @@
 #include "virsecret.h"
 #include "virstring.h"
 #include "virnetdev.h"
+#include "virnetdevtap.h"
 #include "virnetdevmacvlan.h"
 #include "virhostdev.h"
 #include "virmdev.h"
@@ -30833,8 +30834,25 @@ virDomainNetNotifyActualDevice(virConnectPtr conn,
 if (!(net = virNetworkLookupByName(conn, iface->data.network.name)))
 return;
 
-netNotify(net, dom, iface);
+if (netNotify(net, dom, iface) < 0)
+goto cleanup;
+
+if (virDomainNetGetActualType(iface) == VIR_DOMAIN_NET_TYPE_BRIDGE) {
+/*
+ * NB: we can't notify the guest of any MTU change anyway,
+ * so there is no point in trying to learn the actualMTU
+ * (final arg to virNetDevTapReattachBridge())
+ */
+if (virNetDevTapReattachBridge(iface->ifname,
+   
iface->data.network.actual->data.bridge.brname,
+   >mac, dom->uuid,
+   
virDomainNetGetActualVirtPortProfile(iface),
+   virDomainNetGetActualVlan(iface),
+   iface->mtu, NULL) < 0)
+goto cleanup;
+}
 
+ cleanup:
 virObjectUnref(net);
 }
 
diff --git a/src/conf/domain_conf.h b/src/conf/domain_conf.h
index 0b84e48f1b..be7101600e 100644
--- a/src/conf/domain_conf.h
+++ b/src/conf/domain_conf.h
@@ -3645,7 +3645,7 @@ typedef int
 virDomainDefPtr dom,
 virDomainNetDefPtr iface);
 
-typedef void
+typedef int
 (*virDomainNetNotifyActualDeviceImpl)(virNetworkPtr net,
   virDomainDefPtr dom,
   virDomainNetDefPtr iface);
diff --git a/src/network/bridge_driver.c b/src/network/bridge_driver.c
index 0d8adcd8b1..5a6523c839 100644
--- a/src/network/bridge_driver.c
+++ b/src/network/bridge_driver.c
@@ -4786,12 +4786,11 @@ networkAllocateActualDevice(virNetworkPtr net,
  * Called to notify the network driver when libvirtd is restarted and
  * finds an already running domain. If appropriate it will force an
  * allocation of the actual->direct.linkdev to get everything back in
- * order, or re-attach the interface's tap device to the network's
- * bridge.
+ * order.
  *
- * No return value (but does log any failures)
+ * Returns 0 on success, -1 on failure.
  */
-static void
+static int
 networkNotifyActualDevice(virNetworkPtr net,
   virDomainDefPtr dom,
   virDomainNetDefPtr iface)
@@ -4802,6 +4801,7 @@ networkNotifyActualDevice(virNetworkPtr net,
 virNetworkDefPtr netdef;
 virNetworkForwardIfDefPtr dev = NULL;
 size_t i;
+int ret = -1;
 
 obj = virNetworkObjFindByName(driver->networks, net->name);
 if (!obj) {
@@ -4846,22 +4846,6 @@ networkNotifyActualDevice(virNetworkPtr net,
 actualType = VIR_DOMAIN_NET_TYPE_BRIDGE;
 }
 
-/* see if we're connected to the correct bridge */
-if (netdef->bridge) {
-/*
- * NB: we can't notify the guest of any MTU change anyway,
- * so there is no point in trying to learn the actualMTU
- * (final arg to virNetDevTapReattachBridge())
- */
-if (virNetDevTapReattachBridge(iface->ifname, netdef->bridge,
-   >mac, dom->uuid,
-   
virDomainNetGetActualVirtPortProfile(iface),
-   virDomainNetGetActualVlan(iface),
-   iface->mtu, NULL) < 0) {
-goto error;
-}
-}
-
 if (!iface->data.network.actual ||
 (actualType != VIR_DOMAIN_NET_TYPE_DIRECT &&
  actualType != VIR_DOMAIN_NET_TYPE_HOSTDEV)) {
@@ -4990,10 +4974,11 @@ networkNotifyActualDevice(virNetworkPtr net,
 goto error;
 }
 networkLogAllocation(netdef, actualType, dev, iface, true);
+ret = 0;
 
  cleanup:
 virNetworkObjEndAPI();
-return;
+return ret;
 
  error:
 goto cleanup;
-- 
2.20.1

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

[libvirt] [PATCH v2 07/36] network: use virNetDevTapReattachBridge API

2019-02-27 Thread Daniel P . Berrangé
Switch over to use the new API for re-attaching the bridge device

Signed-off-by: Daniel P. Berrangé 
---
 src/network/bridge_driver.c | 47 -
 1 file changed, 10 insertions(+), 37 deletions(-)

diff --git a/src/network/bridge_driver.c b/src/network/bridge_driver.c
index 287c0e1889..0d8adcd8b1 100644
--- a/src/network/bridge_driver.c
+++ b/src/network/bridge_driver.c
@@ -4802,7 +4802,6 @@ networkNotifyActualDevice(virNetworkPtr net,
 virNetworkDefPtr netdef;
 virNetworkForwardIfDefPtr dev = NULL;
 size_t i;
-char *master = NULL;
 
 obj = virNetworkObjFindByName(driver->networks, net->name);
 if (!obj) {
@@ -4849,42 +4848,17 @@ networkNotifyActualDevice(virNetworkPtr net,
 
 /* see if we're connected to the correct bridge */
 if (netdef->bridge) {
-bool useOVS = false;
-
-if (virNetDevGetMaster(iface->ifname, ) < 0)
+/*
+ * NB: we can't notify the guest of any MTU change anyway,
+ * so there is no point in trying to learn the actualMTU
+ * (final arg to virNetDevTapReattachBridge())
+ */
+if (virNetDevTapReattachBridge(iface->ifname, netdef->bridge,
+   >mac, dom->uuid,
+   
virDomainNetGetActualVirtPortProfile(iface),
+   virDomainNetGetActualVlan(iface),
+   iface->mtu, NULL) < 0) {
 goto error;
-
-/* IFLA_MASTER for a tap on an OVS switch is always "ovs-system" */
-if (STREQ_NULLABLE(master, "ovs-system")) {
-useOVS = true;
-VIR_FREE(master);
-if (virNetDevOpenvswitchInterfaceGetMaster(iface->ifname, ) 
< 0)
-goto error;
-}
-
-if (STRNEQ_NULLABLE(netdef->bridge, master)) {
-/* disconnect from current (incorrect) bridge */
-if (master) {
-VIR_INFO("Removing %s from %s", iface->ifname, master);
-if (useOVS)
-ignore_value(virNetDevOpenvswitchRemovePort(master, 
iface->ifname));
-else
-ignore_value(virNetDevBridgeRemovePort(master, 
iface->ifname));
-}
-
-/* attach/reattach to correct bridge.
- * NB: we can't notify the guest of any MTU change anyway,
- * so there is no point in trying to learn the actualMTU
- * (final arg to virNetDevTapAttachBridge())
- */
-VIR_INFO("Attaching %s to %s", iface->ifname, netdef->bridge);
-if (virNetDevTapAttachBridge(iface->ifname, netdef->bridge,
- >mac, dom->uuid,
- 
virDomainNetGetActualVirtPortProfile(iface),
- virDomainNetGetActualVlan(iface),
- iface->mtu, NULL) < 0) {
-goto error;
-}
 }
 }
 
@@ -5019,7 +4993,6 @@ networkNotifyActualDevice(virNetworkPtr net,
 
  cleanup:
 virNetworkObjEndAPI();
-VIR_FREE(master);
 return;
 
  error:
-- 
2.20.1

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

[libvirt] [PATCH v2 03/36] conf: simplify link from hostdev back to network device

2019-02-27 Thread Daniel P . Berrangé
hostdevs have a link back to the original network device. This is fairly
generic accepting any type of device, however, we don't intend to make
use of this approach in future. It can thus be specialized to network
devices.

Signed-off-by: Daniel P. Berrangé 
---
 src/conf/domain_conf.c | 18 --
 src/conf/domain_conf.h |  8 +++-
 src/libxl/libxl_driver.c   |  4 ++--
 src/network/bridge_driver.c|  3 +--
 src/qemu/qemu_command.c|  3 +--
 src/qemu/qemu_domain_address.c |  4 ++--
 src/qemu/qemu_driver.c |  2 +-
 src/qemu/qemu_hotplug.c| 14 ++
 src/qemu/qemu_hotplug.h|  2 +-
 src/util/virhostdev.c  | 17 -
 10 files changed, 37 insertions(+), 38 deletions(-)

diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c
index 96aa750683..cc352dc6d0 100644
--- a/src/conf/domain_conf.c
+++ b/src/conf/domain_conf.c
@@ -2721,7 +2721,7 @@ void virDomainHostdevDefClear(virDomainHostdevDefPtr def)
 /* If there is a parent device object, it will handle freeing
  * def->info.
  */
-if (def->parent.type == VIR_DOMAIN_DEVICE_NONE)
+if (!def->parent)
 virDomainDeviceInfoFree(def->info);
 
 switch (def->mode) {
@@ -2792,7 +2792,7 @@ void virDomainHostdevDefFree(virDomainHostdevDefPtr def)
 /* If there is a parent device object, it will handle freeing
  * the memory.
  */
-if (def->parent.type == VIR_DOMAIN_DEVICE_NONE)
+if (!def->parent)
 VIR_FREE(def);
 }
 
@@ -5350,7 +5350,7 @@ virDomainDefCollectBootOrder(virDomainDefPtr def 
ATTRIBUTE_UNUSED,
 return 0;
 
 if (dev->type == VIR_DOMAIN_DEVICE_HOSTDEV &&
-dev->data.hostdev->parent.type != VIR_DOMAIN_DEVICE_NONE) {
+dev->data.hostdev->parent) {
 /* This hostdev is a child of a higher level device
  * (e.g. interface), and thus already being counted on the
  * list for the other device type.
@@ -6191,7 +6191,7 @@ virDomainDeviceDefValidateAliasesIterator(virDomainDefPtr 
def,
 return 0;
 
 if (dev->type == VIR_DOMAIN_DEVICE_HOSTDEV &&
-dev->data.hostdev->parent.type == VIR_DOMAIN_DEVICE_NET) {
+dev->data.hostdev->parent) {
 /* This hostdev is a copy of some previous interface.
  * Aliases are duplicated. */
 return 0;
@@ -2,8 +2,7 @@ virDomainActualNetDefParseXML(xmlNodePtr node,
 } else if (actual->type == VIR_DOMAIN_NET_TYPE_HOSTDEV) {
 virDomainHostdevDefPtr hostdev = >data.hostdev.def;
 
-hostdev->parent.type = VIR_DOMAIN_DEVICE_NET;
-hostdev->parent.data.net = parent;
+hostdev->parent = parent;
 hostdev->info = >info;
 /* The helper function expects type to already be found and
  * passed in as a string, since it is in a different place in
@@ -11774,8 +11773,7 @@ virDomainNetDefParseXML(virDomainXMLOptionPtr xmlopt,
 
 case VIR_DOMAIN_NET_TYPE_HOSTDEV:
 hostdev = >data.hostdev.def;
-hostdev->parent.type = VIR_DOMAIN_DEVICE_NET;
-hostdev->parent.data.net = def;
+hostdev->parent = def;
 hostdev->info = >info;
 /* The helper function expects type to already be found and
  * passed in as a string, since it is in a different place in
@@ -28971,11 +28969,11 @@ virDomainDefFormatInternal(virDomainDefPtr def,
 }
 
 for (n = 0; n < def->nhostdevs; n++) {
-/* If parent.type != NONE, this is just a pointer to the
+/* If parent != NONE, this is just a pointer to the
  * hostdev in a higher-level device (e.g. virDomainNetDef),
  * and will have already been formatted there.
  */
-if (def->hostdevs[n]->parent.type == VIR_DOMAIN_DEVICE_NONE &&
+if (!def->hostdevs[n]->parent &&
 virDomainHostdevDefFormat(buf, def->hostdevs[n], flags) < 0) {
 goto error;
 }
diff --git a/src/conf/domain_conf.h b/src/conf/domain_conf.h
index 07c4e3bd69..0b84e48f1b 100644
--- a/src/conf/domain_conf.h
+++ b/src/conf/domain_conf.h
@@ -444,7 +444,13 @@ struct _virDomainHostdevCaps {
 
 /* basic device for direct passthrough */
 struct _virDomainHostdevDef {
-virDomainDeviceDef parent; /* higher level Def containing this */
+/* If 'parent' is non-NULL it means this host dev was
+ * not originally present in the XML. It was copied from
+ * a network interface for convenience when handling
+ * hostdevs internally. This hostdev should never be
+ * visible to the user except as part of the interface
+ */
+virDomainNetDefPtr parent;
 
 int mode; /* enum virDomainHostdevMode */
 int startupPolicy; /* enum virDomainStartupPolicy */
diff --git a/src/libxl/libxl_driver.c b/src/libxl/libxl_driver.c
index 8bf5b50f32..2df3f5d363 100644
--- a/src/libxl/libxl_driver.c
+++ b/src/libxl/libxl_driver.c
@@ -3922,9 +3922,9 @@ libxlDomainDetachDeviceLive(libxlDriverPrivatePtr driver,
 /* If 

[libvirt] [PATCH v2 02/36] network: pass a virNetworkPtr to port management APIs

2019-02-27 Thread Daniel P . Berrangé
The APIs for allocating/notifying/removing network ports just take
an internal domain interface struct right now. As a step towards
turning these into public facing APIs, add a virNetworkPtr argument
to all of them.

Signed-off-by: Daniel P. Berrangé 
---
 src/conf/domain_conf.c  | 40 
 src/conf/domain_conf.h  | 18 +++
 src/libxl/libxl_domain.c| 30 +-
 src/libxl/libxl_driver.c| 26 +++-
 src/lxc/lxc_driver.c| 24 +++---
 src/lxc/lxc_process.c   | 24 +-
 src/network/bridge_driver.c | 54 ++--
 src/qemu/qemu_hotplug.c | 62 +++--
 src/qemu/qemu_process.c | 30 +-
 9 files changed, 223 insertions(+), 85 deletions(-)

diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c
index a2ce9c8ef8..96aa750683 100644
--- a/src/conf/domain_conf.c
+++ b/src/conf/domain_conf.c
@@ -30800,37 +30800,65 @@ 
virDomainNetSetDeviceImpl(virDomainNetAllocateActualDeviceImpl allocate,
 }
 
 int
-virDomainNetAllocateActualDevice(virDomainDefPtr dom,
+virDomainNetAllocateActualDevice(virConnectPtr conn,
+ virDomainDefPtr dom,
  virDomainNetDefPtr iface)
 {
+virNetworkPtr net = NULL;
+int ret = -1;
+
 if (!netAllocate) {
 virReportError(VIR_ERR_NO_SUPPORT, "%s",
_("Virtual networking driver is not available"));
 return -1;
 }
 
-return netAllocate(dom, iface);
+if (!(net = virNetworkLookupByName(conn, iface->data.network.name)))
+return -1;
+
+ret = netAllocate(net, dom, iface);
+
+virObjectUnref(net);
+return ret;
 }
 
 void
-virDomainNetNotifyActualDevice(virDomainDefPtr dom,
+virDomainNetNotifyActualDevice(virConnectPtr conn,
+   virDomainDefPtr dom,
virDomainNetDefPtr iface)
 {
+virNetworkPtr net = NULL;
+
 if (!netNotify)
 return;
 
-netNotify(dom, iface);
+if (!(net = virNetworkLookupByName(conn, iface->data.network.name)))
+return;
+
+netNotify(net, dom, iface);
+
+virObjectUnref(net);
 }
 
 
 int
-virDomainNetReleaseActualDevice(virDomainDefPtr dom,
+virDomainNetReleaseActualDevice(virConnectPtr conn,
+virDomainDefPtr dom,
 virDomainNetDefPtr iface)
 {
+virNetworkPtr net = NULL;
+int ret;
+
 if (!netRelease)
 return 0;
 
-return netRelease(dom, iface);
+if (!(net = virNetworkLookupByName(conn, iface->data.network.name)))
+return -1;
+
+ret = netRelease(net, dom, iface);
+
+virObjectUnref(net);
+return ret;
 }
 
 bool
diff --git a/src/conf/domain_conf.h b/src/conf/domain_conf.h
index 1f8454b38c..07c4e3bd69 100644
--- a/src/conf/domain_conf.h
+++ b/src/conf/domain_conf.h
@@ -3635,15 +3635,18 @@ virDomainDefLifecycleActionAllowed(virDomainLifecycle 
type,
virDomainLifecycleAction action);
 
 typedef int
-(*virDomainNetAllocateActualDeviceImpl)(virDomainDefPtr dom,
+(*virDomainNetAllocateActualDeviceImpl)(virNetworkPtr net,
+virDomainDefPtr dom,
 virDomainNetDefPtr iface);
 
 typedef void
-(*virDomainNetNotifyActualDeviceImpl)(virDomainDefPtr dom,
+(*virDomainNetNotifyActualDeviceImpl)(virNetworkPtr net,
+  virDomainDefPtr dom,
   virDomainNetDefPtr iface);
 
 typedef int
-(*virDomainNetReleaseActualDeviceImpl)(virDomainDefPtr dom,
+(*virDomainNetReleaseActualDeviceImpl)(virNetworkPtr net,
+   virDomainDefPtr dom,
virDomainNetDefPtr iface);
 
 typedef bool
@@ -3663,17 +3666,20 @@ 
virDomainNetSetDeviceImpl(virDomainNetAllocateActualDeviceImpl allocate,
   virDomainNetBandwidthUpdateImpl bandwidthUpdate);
 
 int
-virDomainNetAllocateActualDevice(virDomainDefPtr dom,
+virDomainNetAllocateActualDevice(virConnectPtr conn,
+ virDomainDefPtr dom,
  virDomainNetDefPtr iface)
 ATTRIBUTE_NONNULL(1) ATTRIBUTE_NONNULL(2);
 
 void
-virDomainNetNotifyActualDevice(virDomainDefPtr dom,
+virDomainNetNotifyActualDevice(virConnectPtr conn,
+   virDomainDefPtr dom,
virDomainNetDefPtr iface)
 ATTRIBUTE_NONNULL(1) ATTRIBUTE_NONNULL(2);
 
 int
-virDomainNetReleaseActualDevice(virDomainDefPtr dom,
+virDomainNetReleaseActualDevice(virConnectPtr conn,
+virDomainDefPtr dom,
 virDomainNetDefPtr iface)
 ATTRIBUTE_NONNULL(1) ATTRIBUTE_NONNULL(2);
 
diff --git a/src/libxl/libxl_domain.c b/src/libxl/libxl_domain.c
index 

[libvirt] [PATCH v2 01/36] network: restrict usage of port management APIs

2019-02-27 Thread Daniel P . Berrangé
The port allocation APIs are currently called unconditionally for all
types of NIC, but (mostly) only do anything for NICs with type=network.

The exception is the port allocate API which does some validation even
for NICs with type!=network. Relying on this validation is flawed,
however, since the network driver may not even be installed. IOW virt
drivers must not delegate validation to the network driver for NICs
with type != network.

This change allows us to report errors when the virtual network driver
is not registered.

Signed-off-by: Daniel P. Berrangé 
---
 src/conf/domain_conf.c  | 26 --
 src/libxl/libxl_domain.c|  6 ++--
 src/libxl/libxl_driver.c|  9 +++--
 src/lxc/lxc_driver.c|  6 ++--
 src/lxc/lxc_process.c   |  9 +++--
 src/network/bridge_driver.c | 72 +++--
 src/qemu/qemu_driver.c  |  6 ++--
 src/qemu/qemu_hotplug.c | 17 +
 src/qemu/qemu_process.c |  9 +++--
 9 files changed, 94 insertions(+), 66 deletions(-)

diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c
index 477deb777e..a2ce9c8ef8 100644
--- a/src/conf/domain_conf.c
+++ b/src/conf/domain_conf.c
@@ -30803,13 +30803,11 @@ int
 virDomainNetAllocateActualDevice(virDomainDefPtr dom,
  virDomainNetDefPtr iface)
 {
-/* Just silently ignore if network driver isn't present. If something
- * has tried to use a NIC with type=network, other code will already
- * cause an error. This ensures type=bridge doesn't break when
- * network driver is compiled out.
- */
-if (!netAllocate)
-return 0;
+if (!netAllocate) {
+virReportError(VIR_ERR_NO_SUPPORT, "%s",
+   _("Virtual networking driver is not available"));
+return -1;
+}
 
 return netAllocate(dom, iface);
 }
@@ -30839,8 +30837,11 @@ bool
 virDomainNetBandwidthChangeAllowed(virDomainNetDefPtr iface,
virNetDevBandwidthPtr newBandwidth)
 {
-if (!netBandwidthChangeAllowed)
-return 0;
+if (!netBandwidthChangeAllowed) {
+virReportError(VIR_ERR_NO_SUPPORT, "%s",
+   _("Virtual networking driver is not available"));
+return -1;
+}
 
 return netBandwidthChangeAllowed(iface, newBandwidth);
 }
@@ -30849,8 +30850,11 @@ int
 virDomainNetBandwidthUpdate(virDomainNetDefPtr iface,
 virNetDevBandwidthPtr newBandwidth)
 {
-if (!netBandwidthUpdate)
-return 0;
+if (!netBandwidthUpdate) {
+virReportError(VIR_ERR_NO_SUPPORT, "%s",
+   _("Virtual networking driver is not available"));
+return -1;
+}
 
 return netBandwidthUpdate(iface, newBandwidth);
 }
diff --git a/src/libxl/libxl_domain.c b/src/libxl/libxl_domain.c
index ffafa7967d..575748a76f 100644
--- a/src/libxl/libxl_domain.c
+++ b/src/libxl/libxl_domain.c
@@ -898,7 +898,8 @@ libxlDomainCleanup(libxlDriverPrivatePtr driver,
 
 /* cleanup actual device */
 virDomainNetRemoveHostdev(vm->def, net);
-virDomainNetReleaseActualDevice(vm->def, net);
+if (net->type == VIR_DOMAIN_NET_TYPE_NETWORK)
+virDomainNetReleaseActualDevice(vm->def, net);
 }
 }
 
@@ -1055,7 +1056,8 @@ libxlNetworkPrepareDevices(virDomainDefPtr def)
  * network's pool of devices, or resolve bridge device name
  * to the one defined in the network definition.
  */
-if (virDomainNetAllocateActualDevice(def, net) < 0)
+if (net->type == VIR_DOMAIN_NET_TYPE_NETWORK &&
+virDomainNetAllocateActualDevice(def, net) < 0)
 return -1;
 
 actualType = virDomainNetGetActualType(net);
diff --git a/src/libxl/libxl_driver.c b/src/libxl/libxl_driver.c
index 31b842aeee..b2aeea6468 100644
--- a/src/libxl/libxl_driver.c
+++ b/src/libxl/libxl_driver.c
@@ -3397,7 +3397,8 @@ libxlDomainAttachNetDevice(libxlDriverPrivatePtr driver,
  * network's pool of devices, or resolve bridge device name
  * to the one defined in the network definition.
  */
-if (virDomainNetAllocateActualDevice(vm->def, net) < 0)
+if (net->type == VIR_DOMAIN_NET_TYPE_NETWORK &&
+virDomainNetAllocateActualDevice(vm->def, net) < 0)
 goto cleanup;
 
 actualType = virDomainNetGetActualType(net);
@@ -3447,7 +3448,8 @@ libxlDomainAttachNetDevice(libxlDriverPrivatePtr driver,
 vm->def->nets[vm->def->nnets++] = net;
 } else {
 virDomainNetRemoveHostdev(vm->def, net);
-virDomainNetReleaseActualDevice(vm->def, net);
+if (net->type == VIR_DOMAIN_NET_TYPE_NETWORK)
+virDomainNetReleaseActualDevice(vm->def, net);
 }
 virObjectUnref(cfg);
 return ret;
@@ -3870,7 +3872,8 @@ libxlDomainDetachNetDevice(libxlDriverPrivatePtr driver,
  cleanup:
 libxl_device_nic_dispose();
 if (!ret) {
-virDomainNetReleaseActualDevice(vm->def, 

[libvirt] [PATCH v2 04/36] network: add missing bandwidth limits for bridge forward type

2019-02-27 Thread Daniel P . Berrangé
In the case of a network with forward=bridge, which has a bridge device
listed, we are capable of setting bandwidth limits but fail to call the
function to register them.

Signed-off-by: Daniel P. Berrangé 
---
 src/network/bridge_driver.c | 39 ++---
 1 file changed, 28 insertions(+), 11 deletions(-)

diff --git a/src/network/bridge_driver.c b/src/network/bridge_driver.c
index 314939cb17..0e6279e7c1 100644
--- a/src/network/bridge_driver.c
+++ b/src/network/bridge_driver.c
@@ -3239,7 +3239,7 @@ networkValidate(virNetworkDriverStatePtr driver,
 virPortGroupDefPtr defaultPortGroup = NULL;
 virNetworkIPDefPtr ipdef;
 bool ipv4def = false, ipv6def = false;
-bool bandwidthAllowed = true;
+bool bandwidthAllowed = false;
 bool usesInterface = false, usesAddress = false;
 
 if (virXMLCheckIllegalChars("name", def->name, "\n") < 0)
@@ -3260,9 +3260,15 @@ networkValidate(virNetworkDriverStatePtr driver,
 return -1;
 
 virNetworkSetBridgeMacAddr(def);
+bandwidthAllowed = true;
 break;
 
 case VIR_NETWORK_FORWARD_BRIDGE:
+if (def->bridge != NULL)
+bandwidthAllowed = true;
+
+ATTRIBUTE_FALLTHROUGH;
+
 case VIR_NETWORK_FORWARD_PRIVATE:
 case VIR_NETWORK_FORWARD_VEPA:
 case VIR_NETWORK_FORWARD_PASSTHROUGH:
@@ -3303,15 +3309,6 @@ networkValidate(virNetworkDriverStatePtr driver,
virNetworkForwardTypeToString(def->forward.type));
 return -1;
 }
-if (def->bandwidth) {
-virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
-   _("Unsupported network-wide  element "
- "in network %s with forward mode='%s'"),
-   def->name,
-   virNetworkForwardTypeToString(def->forward.type));
-return -1;
-}
-bandwidthAllowed = false;
 break;
 
 case VIR_NETWORK_FORWARD_LAST:
@@ -3320,6 +3317,16 @@ networkValidate(virNetworkDriverStatePtr driver,
 return -1;
 }
 
+if (def->bandwidth &&
+!bandwidthAllowed) {
+virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
+   _("Unsupported network-wide  element "
+ "in network %s with forward mode='%s'"),
+   def->name,
+   virNetworkForwardTypeToString(def->forward.type));
+return -1;
+}
+
 /* we support configs with a single PF defined:
  *   
  * or with a list of netdev names:
@@ -4588,6 +4595,9 @@ networkAllocateActualDevice(virNetworkPtr net,
 goto error;
 }
 }
+
+if (networkPlugBandwidth(obj, iface) < 0)
+goto error;
 break;
 }
 
@@ -5062,6 +5072,11 @@ networkReleaseActualDevice(virNetworkPtr net,
 break;
 
 case VIR_NETWORK_FORWARD_BRIDGE:
+if (iface->data.network.actual &&
+actualType == VIR_DOMAIN_NET_TYPE_BRIDGE &&
+networkUnplugBandwidth(obj, iface) < 0)
+goto error;
+break;
 case VIR_NETWORK_FORWARD_PRIVATE:
 case VIR_NETWORK_FORWARD_VEPA:
 case VIR_NETWORK_FORWARD_PASSTHROUGH:
@@ -5470,7 +5485,9 @@ networkBandwidthGenericChecks(virDomainNetDefPtr iface,
 virNetDevBandwidthPtr ifaceBand;
 unsigned long long old_floor, new_floor;
 
-if (virDomainNetGetActualType(iface) != VIR_DOMAIN_NET_TYPE_NETWORK) {
+if (virDomainNetGetActualType(iface) != VIR_DOMAIN_NET_TYPE_NETWORK &&
+(virDomainNetGetActualType(iface) != VIR_DOMAIN_NET_TYPE_BRIDGE ||
+ iface->data.network.actual->data.bridge.brname == NULL)) {
 /* This is not an interface that's plugged into a network.
  * We don't care. Thus from our POV bandwidth change is allowed. */
 return false;
-- 
2.20.1

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

[libvirt] [PATCH v2 05/36] network: use 'bridge' as actual type instead of 'network'

2019-02-27 Thread Daniel P . Berrangé
Ports allocated on virtual networks with type=nat|route|open all get
given an actual type of 'network'.

Only ports in networks with type=bridge use an actual type of 'bridge'.

This distinction makes little sense since the virtualization drivers
will treat both actual types in exactly the same way, as they're all
just bridge devices a VM needs to be connected to.

This doesn't affect user visible XML since the "actual" device XML
is internal only, but we need code to convert the data upgrades.

Signed-off-by: Daniel P. Berrangé 
---
 src/network/bridge_driver.c | 20 
 1 file changed, 12 insertions(+), 8 deletions(-)

diff --git a/src/network/bridge_driver.c b/src/network/bridge_driver.c
index 0e6279e7c1..287c0e1889 100644
--- a/src/network/bridge_driver.c
+++ b/src/network/bridge_driver.c
@@ -4464,11 +4464,7 @@ networkAllocateActualDevice(virNetworkPtr net,
 case VIR_NETWORK_FORWARD_NAT:
 case VIR_NETWORK_FORWARD_ROUTE:
 case VIR_NETWORK_FORWARD_OPEN:
-/* for these forward types, the actual net type really *is*
- * NETWORK; we just keep the info from the portgroup in
- * iface->data.network.actual
- */
-iface->data.network.actual->type = VIR_DOMAIN_NET_TYPE_NETWORK;
+iface->data.network.actual->type = VIR_DOMAIN_NET_TYPE_BRIDGE;
 
 /* we also store the bridge device and macTableManager settings
  * in iface->data.network.actual->data.bridge for later use
@@ -4842,6 +4838,15 @@ networkNotifyActualDevice(virNetworkPtr net,
 netdef->bridge) < 0))
 goto error;
 
+/* Older libvirtd uses actualType==network, but we now
+ * just use actualType==bridge, as nothing needs to
+ * distinguish the two cases, and this simplifies virt
+ * drive code */
+if (actualType == VIR_DOMAIN_NET_TYPE_NETWORK) {
+iface->data.network.actual->type = VIR_DOMAIN_NET_TYPE_BRIDGE;
+actualType = VIR_DOMAIN_NET_TYPE_BRIDGE;
+}
+
 /* see if we're connected to the correct bridge */
 if (netdef->bridge) {
 bool useOVS = false;
@@ -5485,9 +5490,8 @@ networkBandwidthGenericChecks(virDomainNetDefPtr iface,
 virNetDevBandwidthPtr ifaceBand;
 unsigned long long old_floor, new_floor;
 
-if (virDomainNetGetActualType(iface) != VIR_DOMAIN_NET_TYPE_NETWORK &&
-(virDomainNetGetActualType(iface) != VIR_DOMAIN_NET_TYPE_BRIDGE ||
- iface->data.network.actual->data.bridge.brname == NULL)) {
+if (virDomainNetGetActualType(iface) != VIR_DOMAIN_NET_TYPE_BRIDGE ||
+iface->data.network.actual->data.bridge.brname == NULL) {
 /* This is not an interface that's plugged into a network.
  * We don't care. Thus from our POV bandwidth change is allowed. */
 return false;
-- 
2.20.1

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

[libvirt] [PATCH v2 08/36] virt drivers: don't handle type=network after resolving actual network type

2019-02-27 Thread Daniel P . Berrangé
The call to resolve the actual network type will turn any NICs with
type=network into one of the other types. Thus there should be no need
to handle type=network in later switch() statements jumping off the
actual type.

Signed-off-by: Daniel P. Berrangé 
---
 src/libxl/libxl_conf.c| 21 +++--
 src/lxc/lxc_driver.c  | 15 +++
 src/qemu/qemu_command.c   |  8 ++--
 src/qemu/qemu_hotplug.c   | 13 +++--
 src/qemu/qemu_interface.c | 12 ++--
 src/qemu/qemu_process.c   |  5 -
 6 files changed, 45 insertions(+), 29 deletions(-)

diff --git a/src/libxl/libxl_conf.c b/src/libxl/libxl_conf.c
index 0e08b8f0a2..f250ae0f8a 100644
--- a/src/libxl/libxl_conf.c
+++ b/src/libxl/libxl_conf.c
@@ -1341,25 +1341,10 @@ libxlMakeNic(virDomainDefPtr def,
 }
 break;
 case VIR_DOMAIN_NET_TYPE_NETWORK:
-{
-if (!(conn = virConnectOpen("xen:///system")))
-goto cleanup;
-
-if (!(network =
-  virNetworkLookupByName(conn, l_nic->data.network.name))) {
-goto cleanup;
-}
-
-if (l_nic->guestIP.nips > 0) {
-x_nic->ip = xenMakeIPList(_nic->guestIP);
-if (!x_nic->ip)
-goto cleanup;
-}
+virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
+   _("Unexpectedly found type=network for actual NIC 
type"));
+goto cleanup;
 
-if (!(x_nic->bridge = virNetworkGetBridgeName(network)))
-goto cleanup;
-break;
-}
 case VIR_DOMAIN_NET_TYPE_VHOSTUSER:
 case VIR_DOMAIN_NET_TYPE_USER:
 case VIR_DOMAIN_NET_TYPE_SERVER:
diff --git a/src/lxc/lxc_driver.c b/src/lxc/lxc_driver.c
index 2b4f4faa9f..ca208075eb 100644
--- a/src/lxc/lxc_driver.c
+++ b/src/lxc/lxc_driver.c
@@ -3870,8 +3870,7 @@ lxcDomainAttachDeviceNetLive(virConnectPtr conn,
 actualType = virDomainNetGetActualType(net);
 
 switch (actualType) {
-case VIR_DOMAIN_NET_TYPE_BRIDGE:
-case VIR_DOMAIN_NET_TYPE_NETWORK: {
+case VIR_DOMAIN_NET_TYPE_BRIDGE: {
 const char *brname = virDomainNetGetActualBridgeName(net);
 if (!brname) {
 virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
@@ -3889,6 +3888,10 @@ lxcDomainAttachDeviceNetLive(virConnectPtr conn,
 if (!(veth = virLXCProcessSetupInterfaceDirect(conn, vm->def, net)))
 goto cleanup;
 }   break;
+case VIR_DOMAIN_NET_TYPE_NETWORK:
+virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
+   _("Unexpectedly found type=network for actual NIC 
type"));
+goto cleanup;
 case VIR_DOMAIN_NET_TYPE_USER:
 case VIR_DOMAIN_NET_TYPE_VHOSTUSER:
 case VIR_DOMAIN_NET_TYPE_SERVER:
@@ -3934,7 +3937,6 @@ lxcDomainAttachDeviceNetLive(virConnectPtr conn,
 } else if (veth) {
 switch (actualType) {
 case VIR_DOMAIN_NET_TYPE_BRIDGE:
-case VIR_DOMAIN_NET_TYPE_NETWORK:
 case VIR_DOMAIN_NET_TYPE_ETHERNET:
 ignore_value(virNetDevVethDelete(veth));
 break;
@@ -3943,6 +3945,7 @@ lxcDomainAttachDeviceNetLive(virConnectPtr conn,
 ignore_value(virNetDevMacVLanDelete(veth));
 break;
 
+case VIR_DOMAIN_NET_TYPE_NETWORK:
 case VIR_DOMAIN_NET_TYPE_USER:
 case VIR_DOMAIN_NET_TYPE_VHOSTUSER:
 case VIR_DOMAIN_NET_TYPE_SERVER:
@@ -4374,7 +4377,6 @@ lxcDomainDetachDeviceNetLive(virDomainObjPtr vm,
 
 switch (actualType) {
 case VIR_DOMAIN_NET_TYPE_BRIDGE:
-case VIR_DOMAIN_NET_TYPE_NETWORK:
 case VIR_DOMAIN_NET_TYPE_ETHERNET:
 if (virNetDevVethDelete(detach->ifname) < 0) {
 virDomainAuditNet(vm, detach, NULL, "detach", false);
@@ -4382,6 +4384,11 @@ lxcDomainDetachDeviceNetLive(virDomainObjPtr vm,
 }
 break;
 
+case VIR_DOMAIN_NET_TYPE_NETWORK:
+virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
+   _("Unexpectedly found type=network for actual NIC 
type"));
+goto cleanup;
+
 /* It'd be nice to support this, but with macvlan
  * once assigned to a container nothing exists on
  * the host side. Further the container can change
diff --git a/src/qemu/qemu_command.c b/src/qemu/qemu_command.c
index 11c40f2019..2ab82fa170 100644
--- a/src/qemu/qemu_command.c
+++ b/src/qemu/qemu_command.c
@@ -8645,7 +8645,6 @@ qemuBuildInterfaceCommandLine(virQEMUDriverPtr driver,
 }
 
 switch (actualType) {
-case VIR_DOMAIN_NET_TYPE_NETWORK:
 case VIR_DOMAIN_NET_TYPE_BRIDGE:
 tapfdSize = net->driver.virtio.queues;
 if (!tapfdSize)
@@ -8723,6 +8722,11 @@ qemuBuildInterfaceCommandLine(virQEMUDriverPtr driver,
 
 break;
 
+case VIR_DOMAIN_NET_TYPE_NETWORK:
+virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
+   _("Unexpectedly found type=network for actual NIC 
type"));
+  

[libvirt] [PATCH v2 06/36] util: add helper method for re-attaching a tap device to a bridge

2019-02-27 Thread Daniel P . Berrangé
Signed-off-by: Daniel P. Berrangé 
---
 src/libvirt_private.syms |  1 +
 src/util/virnetdevtap.c  | 69 
 src/util/virnetdevtap.h  | 12 +++
 3 files changed, 82 insertions(+)

diff --git a/src/libvirt_private.syms b/src/libvirt_private.syms
index 038a744981..07bc7d94d2 100644
--- a/src/libvirt_private.syms
+++ b/src/libvirt_private.syms
@@ -2437,6 +2437,7 @@ virNetDevTapDelete;
 virNetDevTapGetName;
 virNetDevTapGetRealDeviceName;
 virNetDevTapInterfaceStats;
+virNetDevTapReattachBridge;
 
 
 # util/virnetdevveth.h
diff --git a/src/util/virnetdevtap.c b/src/util/virnetdevtap.c
index 972f3405aa..0484c7c5a4 100644
--- a/src/util/virnetdevtap.c
+++ b/src/util/virnetdevtap.c
@@ -553,6 +553,75 @@ virNetDevTapAttachBridge(const char *tapname,
 }
 
 
+/**
+ * virNetDevTapReattachBridge:
+ * @tapname: the tap interface name (or name template)
+ * @brname: the bridge name
+ * @macaddr: desired MAC address
+ * @virtPortProfile: bridge/port specific configuration
+ * @virtVlan: vlan tag info
+ * @mtu: requested MTU for port (or 0 for "default")
+ * @actualMTU: MTU actually set for port (after accounting for bridge's MTU)
+ *
+ * Ensures that the tap device (@tapname) is connected to the bridge
+ * (@brname), potentially removing it from any existing bridge that
+ * does not match.
+ *
+ * Returns 0 in case of success or -1 on failure
+ */
+int
+virNetDevTapReattachBridge(const char *tapname,
+   const char *brname,
+   const virMacAddr *macaddr,
+   const unsigned char *vmuuid,
+   virNetDevVPortProfilePtr virtPortProfile,
+   virNetDevVlanPtr virtVlan,
+   unsigned int mtu,
+   unsigned int *actualMTU)
+{
+bool useOVS = false;
+char *master = NULL;
+
+if (virNetDevGetMaster(tapname, ) < 0)
+return -1;
+
+/* IFLA_MASTER for a tap on an OVS switch is always "ovs-system" */
+if (STREQ_NULLABLE(master, "ovs-system")) {
+useOVS = true;
+VIR_FREE(master);
+if (virNetDevOpenvswitchInterfaceGetMaster(tapname, ) < 0)
+return -1;
+}
+
+/* Nothing more todo if we're on the right bridge already */
+if (STREQ_NULLABLE(brname, master))
+return 0;
+
+/* disconnect from current (incorrect) bridge, if any  */
+if (master) {
+int ret;
+VIR_INFO("Removing %s from %s", tapname, master);
+if (useOVS)
+ret = virNetDevOpenvswitchRemovePort(master, tapname);
+else
+ret = virNetDevBridgeRemovePort(master, tapname);
+VIR_FREE(master);
+if (ret < 0)
+return -1;
+}
+
+VIR_INFO("Attaching %s to %s", tapname, brname);
+if (virNetDevTapAttachBridge(tapname, brname,
+ macaddr, vmuuid,
+ virtPortProfile,
+ virtVlan,
+ mtu, actualMTU) < 0)
+return -1;
+
+return 0;
+}
+
+
 /**
  * virNetDevTapCreateInBridgePort:
  * @brname: the bridge name
diff --git a/src/util/virnetdevtap.h b/src/util/virnetdevtap.h
index 226122aa2c..2b3893cd37 100644
--- a/src/util/virnetdevtap.h
+++ b/src/util/virnetdevtap.h
@@ -71,6 +71,18 @@ virNetDevTapAttachBridge(const char *tapname,
 ATTRIBUTE_NONNULL(1) ATTRIBUTE_NONNULL(2) ATTRIBUTE_NONNULL(3)
 ATTRIBUTE_RETURN_CHECK;
 
+int
+virNetDevTapReattachBridge(const char *tapname,
+   const char *brname,
+   const virMacAddr *macaddr,
+   const unsigned char *vmuuid,
+   virNetDevVPortProfilePtr virtPortProfile,
+   virNetDevVlanPtr virtVlan,
+   unsigned int mtu,
+   unsigned int *actualMTU)
+ATTRIBUTE_NONNULL(1) ATTRIBUTE_NONNULL(2) ATTRIBUTE_NONNULL(3)
+ATTRIBUTE_RETURN_CHECK;
+
 int virNetDevTapCreateInBridgePort(const char *brname,
char **ifname,
const virMacAddr *macaddr,
-- 
2.20.1

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

[libvirt] [PATCH v2 00/36] network: refactor to decouple virt drivers from network driver

2019-02-27 Thread Daniel P . Berrangé
An update to

  v1: https://www.redhat.com/archives/libvir-list/2018-December/msg00681.html

Currently the network driver registers a set of callbacks with the virt
driver in order to handle allocating/releasing network ports associated
with guest NICs.

This series introduces a virNetworkPortPtr object and associated XML
that describes a network port. The virt drivers now call public APIs
associated with this new object to create/delete ports for guest NICs.

Changed in v2:

 - Fix many bugs related to upgrades with running VMs
 - Convert over bandwidth controls to the new APIs
 - Handle reconnecting VIFs to bridges during startup
 - Much much more that I can't remember

Daniel P. Berrangé (36):
  network: restrict usage of port management APIs
  network: pass a virNetworkPtr to port management APIs
  conf: simplify link from hostdev back to network device
  network: add missing bandwidth limits for bridge forward type
  network: use 'bridge' as actual type instead of 'network'
  util: add helper method for re-attaching a tap device to a bridge
  network: use virNetDevTapReattachBridge API
  virt drivers: don't handle type=network after resolving actual network
type
  network: move re-attach of bridge device out of network driver
  network: move fixup for domain actual net def out of network driver
  network: unconditionally merge port profiles
  conf: don't pass interface type into virNetDevBandwidthParse
  conf: introduce virNetworkPortDefPtr struct and XML support
  network: stop passing virDomainNetDefPtr into bandwidth functions
  network: make networkLogAllocation independent of domain conf
  util: add API for copying virtual port profile data
  conf: add APIs to convert virDomainNetDef to virNetworkPortDef
  network: convert networkAllocateActualDevice to virNetworkPortDef
  network: convert networkNotifyActualDevice to virNetworkPortDef
  network: convert networkReleaseActualDevice to virNetworkPortDef
  network: convert hook script to take a network port XML
  network: remove the virDomainNetBandwidthChangeAllowed callback
  network: introduce networkAllocatePort
  network: introduce networkNotifyPort
  network: introduce networkReleasePort
  network: introduce networkUpdatePortBandwidth
  network: add public APIs for network port object
  access: add permissions for network port objects
  remote: add support for new network port APIs
  virsh: add support for network port APIs
  conf: support recording ports against virNetworkObjPtr
  network: add implementation of network port APIs
  lxc, libxl: notify network driver of NICs during reconnect
  lxc, libxl: save domain status after reconnect
  conf: record a portid against the domain conf
  conf: switch over to use network port APIs for virt drivers

 docs/formatdomain.html.in |8 +
 docs/hooks.html.in|   24 +-
 docs/schemas/domaincommon.rng |5 +
 include/libvirt/libvirt-network.h |  122 ++
 include/libvirt/virterror.h   |3 +
 src/access/genpolkit.pl   |2 +-
 src/access/viraccessdriver.h  |6 +
 src/access/viraccessdrivernop.c   |   11 +
 src/access/viraccessdriverpolkit.c|   26 +
 src/access/viraccessdriverstack.c |   25 +
 src/access/viraccessmanager.c |   16 +
 src/access/viraccessmanager.h |6 +
 src/access/viraccessperm.c|6 +
 src/access/viraccessperm.h|   44 +
 src/conf/Makefile.inc.am  |2 +
 src/conf/domain_conf.c|  558 ++-
 src/conf/domain_conf.h|   63 +-
 src/conf/netdev_bandwidth_conf.c  |   22 +-
 src/conf/netdev_bandwidth_conf.h  |2 +-
 src/conf/network_conf.c   |4 +-
 src/conf/virnetworkobj.c  |  303 
 src/conf/virnetworkobj.h  |   34 +
 src/conf/virnetworkportdef.c  |  514 +++
 src/conf/virnetworkportdef.h  |  112 ++
 src/datatypes.c   |   60 +
 src/datatypes.h   |   41 +
 src/driver-network.h  |   41 +
 src/libvirt-network.c |  444 ++
 src/libvirt_private.syms  |   24 +-
 src/libvirt_public.syms   |   16 +
 src/libxl/libxl_conf.c|   21 +-
 src/libxl/libxl_domain.c  |   28 +-
 src/libxl/libxl_driver.c  |   60 +-
 src/lxc/lxc_driver.c  |   37 +-
 src/lxc/lxc_process.c |   56 +-
 src/network/bridge_driver.c   | 1364 +
 src/qemu/qemu_command.c   |   11 +-
 src/qemu/qemu_domain_address.c|4 +-
 src/qemu/qemu_driver.c|   10 

Re: [libvirt] [PATCH v2 05/11] domain: Expand virDomainDefFormatInternal with snapshots

2019-02-27 Thread John Ferlan



On 2/23/19 4:24 PM, Eric Blake wrote:
> Make it possible to grab all snapshot XMLs via a single API
> call, by adding a new internal flag.  All callers are adjusted,
> for now passing NULL and not using the new flag. A new wrapper
> virDomainDefFormatFull() is added to make it easier for the

Not really the next any more it seems - definitely in future ones though.

> next patch to add a few callers without having to revisit all
> existing clients of virDomainDefFormat().
> 
> Signed-off-by: Eric Blake 
> ---
>  src/conf/domain_conf.h  |  8 +
>  src/conf/domain_conf.c  | 58 +++--
>  src/conf/snapshot_conf.c|  4 +--
>  src/network/bridge_driver.c |  3 +-
>  src/qemu/qemu_domain.c  |  2 +-
>  5 files changed, 62 insertions(+), 13 deletions(-)
> 
> diff --git a/src/conf/domain_conf.h b/src/conf/domain_conf.h
> index 9bccd8bcd1..9b13c147da 100644
> --- a/src/conf/domain_conf.h
> +++ b/src/conf/domain_conf.h
> @@ -3047,6 +3047,7 @@ typedef enum {
>  VIR_DOMAIN_DEF_FORMAT_ALLOW_ROM   = 1 << 6,
>  VIR_DOMAIN_DEF_FORMAT_ALLOW_BOOT  = 1 << 7,
>  VIR_DOMAIN_DEF_FORMAT_CLOCK_ADJUST= 1 << 8,
> +VIR_DOMAIN_DEF_FORMAT_SNAPSHOTS   = 1 << 9,
>  } virDomainDefFormatFlags;
> 
>  /* Use these flags to skip specific domain ABI consistency checks done
> @@ -3124,12 +3125,19 @@ unsigned int 
> virDomainDefFormatConvertXMLFlags(unsigned int flags);
>  char *virDomainDefFormat(virDomainDefPtr def,
>   virCapsPtr caps,
>   unsigned int flags);
> +char *virDomainDefFormatFull(virDomainDefPtr def,
> + virCapsPtr caps,
> + virDomainSnapshotObjListPtr snapshots,
> + virDomainSnapshotObjPtr current_snapshot,
> + unsigned int flags);
>  char *virDomainObjFormat(virDomainXMLOptionPtr xmlopt,
>   virDomainObjPtr obj,
>   virCapsPtr caps,
>   unsigned int flags);
>  int virDomainDefFormatInternal(virDomainDefPtr def,
> virCapsPtr caps,
> +   virDomainSnapshotObjListPtr snapshots,
> +   virDomainSnapshotObjPtr current_snapshot,
> unsigned int flags,
> virBufferPtr buf,
> virDomainXMLOptionPtr xmlopt);
> diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c
> index ceeb247ef4..46ae79e738 100644
> --- a/src/conf/domain_conf.c
> +++ b/src/conf/domain_conf.c
> @@ -1,7 +1,7 @@
>  /*
>   * domain_conf.c: domain XML processing
>   *
> - * Copyright (C) 2006-2016 Red Hat, Inc.
> + * Copyright (C) 2006-2019 Red Hat, Inc.
>   * Copyright (C) 2006-2008 Daniel P. Berrange
>   * Copyright (c) 2015 SUSE LINUX Products GmbH, Nuernberg, Germany.
>   *
> @@ -28212,6 +28212,8 @@ virDomainVsockDefFormat(virBufferPtr buf,
>  int
>  virDomainDefFormatInternal(virDomainDefPtr def,
> virCapsPtr caps,
> +   virDomainSnapshotObjListPtr snapshots,
> +   virDomainSnapshotObjPtr current_snapshot,
> unsigned int flags,
> virBufferPtr buf,
> virDomainXMLOptionPtr xmlopt)

Rather than possibly continually adding parameters to
virDomainDefFormatInternal, maybe we should take the plunge now to
create a local struct that would be passed along that would fill in
fields based on what "extra" format flags beyond the common set are
being used.

struct virDomainDefFormatInternalFlagsData {
virDomainSnapshotObjListPtr snapshots;
virDomainSnapshotObjPtr current_snapshot;
};

I am of course assuming checkpoints in the future will do something similar.

> @@ -28229,9 +28231,16 @@ virDomainDefFormatInternal(virDomainDefPtr def,
>VIR_DOMAIN_DEF_FORMAT_STATUS |
>VIR_DOMAIN_DEF_FORMAT_ACTUAL_NET |
>VIR_DOMAIN_DEF_FORMAT_PCI_ORIG_STATES |
> -  VIR_DOMAIN_DEF_FORMAT_CLOCK_ADJUST,
> +  VIR_DOMAIN_DEF_FORMAT_CLOCK_ADJUST |
> +  VIR_DOMAIN_DEF_FORMAT_SNAPSHOTS,
>-1);
> 
> +if ((flags & VIR_DOMAIN_DEF_FORMAT_SNAPSHOTS) && !snapshots) {
> +virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
> +   _("snapshots requested but not provided"));
> +goto error;
> +}
> +
>  if (!(type = virDomainVirtTypeToString(def->virtType))) {
>  virReportError(VIR_ERR_INTERNAL_ERROR,
> _("unexpected domain type %d"), def->virtType);
> @@ -29016,6 +29025,23 @@ virDomainDefFormatInternal(virDomainDefPtr def,
> 
>  virDomainSEVDefFormat(buf, def->sev);
> 

I think all of the next hunk should be in it's own helper method

> +if (flags & 

Re: [libvirt] [PATCH v2 04/11] snapshot: Add virDomainSnapshotObjListFormat

2019-02-27 Thread John Ferlan



On 2/23/19 4:24 PM, Eric Blake wrote:
> Add a new function to output all of the domain's snapshots in one
> buffer.
> 
> Signed-off-by: Eric Blake 
> ---
>  src/conf/snapshot_conf.h |  8 +++-
>  src/conf/snapshot_conf.c | 39 +++
>  src/libvirt_private.syms |  1 +
>  3 files changed, 47 insertions(+), 1 deletion(-)
> 

[...]

> diff --git a/src/conf/snapshot_conf.c b/src/conf/snapshot_conf.c
> index 5cb977336a..a572da5b58 100644
> --- a/src/conf/snapshot_conf.c
> +++ b/src/conf/snapshot_conf.c
> @@ -803,6 +803,45 @@ virDomainSnapshotDefFormat(const char *uuidstr,
>  return virBufferContentAndReset();
>  }
> 
> +struct virDomainSnapshotFormatData {
> +virBufferPtr buf;
> +const char *uuidstr;
> +virCapsPtr caps;
> +virDomainXMLOptionPtr xmlopt;
> +unsigned int flags;
> +};
> +
> +static int
> +virDomainSnapshotFormatOne(void *payload, const void *name ATTRIBUTE_UNUSED,

One arg per line.

> +   void *opaque)
> +{
> +virDomainSnapshotObjPtr snap = payload;
> +struct virDomainSnapshotFormatData *data = opaque;
> +return virDomainSnapshotDefFormatInternal(data->buf, data->uuidstr,
> +  snap->def, data->caps,
> +  data->xmlopt, data->flags);
> +}
> +
> +

There's no parameter and method description here leading me to wonder...

> +int
> +virDomainSnapshotObjListFormat(virBufferPtr buf,
> +   const char *uuidstr,
> +   virDomainSnapshotObjListPtr snapshots,
> +   virCapsPtr caps,
> +   virDomainXMLOptionPtr xmlopt,
> +   unsigned int flags)
> +{
> +struct virDomainSnapshotFormatData data = {
> +.buf = buf,
> +.uuidstr = uuidstr,
> +.caps = caps,
> +.xmlopt = xmlopt,
> +.flags = flags,
> +};

...Hmm... so should this also clear and reset buffer if
virDomainSnapshotForEach returns -1 or trust the caller to do that?

With a bit of extra docs and since I have read the next patch...

Reviewed-by: John Ferlan 

John

> +return virDomainSnapshotForEach(snapshots, virDomainSnapshotFormatOne,
> +);
> +}
> +
>  /* Snapshot Obj functions */
>  static virDomainSnapshotObjPtr virDomainSnapshotObjNew(void)
>  {
> diff --git a/src/libvirt_private.syms b/src/libvirt_private.syms
> index 6bfb497648..c623737c30 100644
> --- a/src/libvirt_private.syms
> +++ b/src/libvirt_private.syms
> @@ -891,6 +891,7 @@ virDomainSnapshotFormatConvertXMLFlags;
>  virDomainSnapshotIsExternal;
>  virDomainSnapshotLocationTypeFromString;
>  virDomainSnapshotLocationTypeToString;
> +virDomainSnapshotObjListFormat;
>  virDomainSnapshotObjListFree;
>  virDomainSnapshotObjListGetNames;
>  virDomainSnapshotObjListNew;
> 

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


Re: [libvirt] [PATCH 3/1] virsh: Test batch mode parser improvements

2019-02-27 Thread Andrea Bolognani
On Wed, 2019-02-27 at 09:22 -0600, Eric Blake wrote:
> On 2/27/19 2:53 AM, Andrea Bolognani wrote:
> > On Tue, 2019-02-26 at 15:48 -0600, Eric Blake wrote:
> > > I redid this into the two patches, and pushed.
> > 
> > I don't think that was appropriate, considering that we're during
> > the pre-release freeze and this looks like a new feature rather
> > than an urgent fix.
> 
> The ack was given before the freeze. But I'm also okay with reverting
> them back out of 5.1 if you think that is more appropriate.

I didn't realize that, sorry.

I'm not really sure whether we have an established policy for this
kind of situation, but in my opinion the freeze applies regardless
of when the ACK was granted, since it's intended to be a period
during which the code that's going to end up in the next release is
tested and validated, which makes minimizing changes and limit them
to bugfixes only highly desiderable.

That said, the feature is small enough and was merged early enough
in the freeze period that I would not have advocated for reverting
it either way.

-- 
Andrea Bolognani / Red Hat / Virtualization

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


Re: [libvirt] [PATCH v2 03/11] snapshot: Refactor virDomainSnapshotDefFormat

2019-02-27 Thread John Ferlan



On 2/23/19 4:24 PM, Eric Blake wrote:
> Split out an internal helper that produces format into a
> virBuffer, similar to what domain_conf.c does, and making
> the next patch easier to write.
> 
> Signed-off-by: Eric Blake 
> ---
>  src/conf/snapshot_conf.c | 103 ++-
>  1 file changed, 59 insertions(+), 44 deletions(-)
> 

If you feel compelled - you could add an extra blank line between
virDomainSnapshotDefFormat and virDomainSnapshotDefFormatInternal.

Reviewed-by: John Ferlan 

John

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


Re: [libvirt] [PATCH v2 02/11] snapshot: Give virDomainSnapshotDefFormat its own flags

2019-02-27 Thread John Ferlan



On 2/23/19 4:24 PM, Eric Blake wrote:
> virDomainSnapshotDefFormat currently takes two sets of knobs:
> an 'unsigned int flags' argument that can currently just be
> VIR_DOMAIN_DEF_FORMAT_SECURE, and an 'int internal' argument used as
> a bool to determine whether to output an additional element.  It
> then reuses the 'flags' knob to call into virDomainDefFormatInternal(),
> which takes a different set of flags. In fact, prior to commit 0ecd6851
> (1.2.12), the 'flags' argument actually took the public
> VIR_DOMAIN_XML_SECURE, which was even more confusing.  Let's borrow
> from the style of that earlier commit, by introducing a function
> for translating from the public flags (VIR_DOMAIN_SNAPSHOT_XML_SECURE
> was just recently introduced) into a new enum specific to snapshot
> formatting, and adjust all callers to use snapshot-specific enum
> values when formatting, and where the formatter now uses a new
> variable 'domainflags' to make it obvious when we are translating
> from snapshot flags back to domain flags.  We don't even have to
> use the conversion function for drivers that don't accept the
> public VIR_DOMAIN_SNAPSHOT_XML_SECURE flag.
> 
> Signed-off-by: Eric Blake 
> ---
>  src/conf/snapshot_conf.h  | 10 --
>  src/conf/snapshot_conf.c  | 28 ++--
>  src/esx/esx_driver.c  |  1 -
>  src/libvirt_private.syms  |  1 +
>  src/qemu/qemu_domain.c|  3 +--
>  src/qemu/qemu_driver.c|  3 +--
>  src/test/test_driver.c|  3 +--
>  src/vbox/vbox_common.c|  5 ++---
>  src/vz/vz_driver.c|  3 +--
>  tests/domainsnapshotxml2xmltest.c | 16 +---
>  10 files changed, 46 insertions(+), 27 deletions(-)
> 

[...]

> diff --git a/src/conf/snapshot_conf.c b/src/conf/snapshot_conf.c
> index 3372c4df86..652d963f84 100644
> --- a/src/conf/snapshot_conf.c
> +++ b/src/conf/snapshot_conf.c
> @@ -652,6 +652,19 @@ virDomainSnapshotAlignDisks(virDomainSnapshotDefPtr def,
>  return ret;
>  }
> 
> +/* Converts public VIR_DOMAIN_SNAPSHOT_XML_* into
> + * VIR_DOMAIN_SNAPSHOT_FORMAT_* flags, and silently ignores any other
> + * flags.  */

NIT: extra spaces between . and *

> +unsigned int virDomainSnapshotFormatConvertXMLFlags(unsigned int flags)
> +{
> +unsigned int formatFlags = 0;
> +
> +if (flags & VIR_DOMAIN_SNAPSHOT_XML_SECURE)
> +formatFlags |= VIR_DOMAIN_SNAPSHOT_FORMAT_SECURE;
> +
> +return formatFlags;
> +}
> +

[...]

> diff --git a/src/vbox/vbox_common.c b/src/vbox/vbox_common.c
> index d95fe7c7ae..1efd357b49 100644
> --- a/src/vbox/vbox_common.c
> +++ b/src/vbox/vbox_common.c

[...]

> @@ -6321,8 +6321,7 @@ static char 
> *vboxDomainSnapshotGetXMLDesc(virDomainSnapshotPtr snapshot,
>  virUUIDFormat(dom->uuid, uuidstr);
>  memcpy(def->dom->uuid, dom->uuid, VIR_UUID_BUFLEN);
>  ret = virDomainSnapshotDefFormat(uuidstr, def, data->caps, data->xmlopt,
> -  
> virDomainDefFormatConvertXMLFlags(flags),
> -  0);
> + 0);

NIT:

The "0);" could fit on the previous line.

> 
>   cleanup:
>  virDomainSnapshotDefFree(def);

[...]

Reviewed-by: John Ferlan 

This and the rest would be 5.2.0 related...

John

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


Re: [libvirt] [PATCH v2 01/11] domain: Document VIR_DOMAIN_XML_MIGRATABLE

2019-02-27 Thread John Ferlan



On 2/23/19 4:24 PM, Eric Blake wrote:
> Commit 28f8dfdc (1.0.0) added a flag to virDomainGetXMLDesc, but
> failed to document its effects.  And considering that the
> MIGRATABLE flag has been the source of past bugs (CVE-2014-7823,
> fixed in commit b1674ad5 (1.2.11), or even cf2d4c60 (1.2.13) where
> flag mismatch broke virsh edit), make the wording wishy-washy
> enough to discourage using the flag casually, by mentioning that
> the resulting XML is more for internal use than for validation
> against the schema.
> 
> Signed-off-by: Eric Blake 
> ---
>  src/libvirt-domain.c | 9 +
>  1 file changed, 9 insertions(+)
> 

Reviewed-by: John Ferlan 

This one is seemingly safe for freeze -

John

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


Re: [libvirt] [tck PATCH] Add script testing network bandwidth functionality

2019-02-27 Thread Daniel P . Berrangé
On Tue, Feb 26, 2019 at 06:44:18PM -0500, Laine Stump wrote:
> On 2/26/19 1:07 PM, Daniel P. Berrangé wrote:
> > Signed-off-by: Daniel P. Berrangé 
> > ---
> >   lib/Sys/Virt/TCK/DomainBuilder.pm  |  10 ++
> >   lib/Sys/Virt/TCK/NetworkBuilder.pm |  20 
> >   scripts/networks/400-guest-bandwidth.t | 147 +
> 
> 
> You forgot to add the test file to MANIFEST :-)
> 
> 
> Other than that,
> 
> 
> Reviewed-by: Laine Stump 
> 
> 
> (the test could be made more thorough by checking that the bandwidth had
> actually been set (by checking the output of whatever appropriate tc
> command, and maybe even by doing a netcat from host to guest and making sure
> it stays below the limit), but this is a lot better than what we were
> testing before!)

Yes, I was wondering about checking tc in some way.

This new script already found some nice bugs in my network refactor patches
which proves its worth.


Regards,
Daniel
-- 
|: https://berrange.com  -o-https://www.flickr.com/photos/dberrange :|
|: https://libvirt.org -o-https://fstop138.berrange.com :|
|: https://entangle-photo.org-o-https://www.instagram.com/dberrange :|

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

Re: [libvirt] [PATCH 4/5] util: XML: Introduce automatic reset of XPath's current node

2019-02-27 Thread Eric Blake
On 2/27/19 3:27 AM, Peter Krempa wrote:

>>> + * node pointer is reset to the original value when this macro was used.
>>> + */
>>> +# define VIR_XPATH_NODE_AUTORESTORE(ctxt) \
>>> +VIR_AUTOCLEAN(virXPathContextNodeSave) ctxt ## CtxtSave = {(ctxt), 
>>> (ctxt)->node}
>>
>> Worth using C99 syntax as in { .ctxt = (ctxt), .node = (ctxt)->node, } ?
> 
> It would require renaming the argument of the macro as it would be
> replaced otherwise. Interrestingly in most cases it would actually work
> as in most cases the macro is used with 'ctxt'.

And hence why it's a good idea to use macro parameter names which can't
conflict with normal cods, such as:

#define VIR_XPATH_NODE_AUTORESTORE(_ctxt) \
VIR_AUTOCLEAN(virXPathContextNodeSave) _ctxt##CtxtSave = { \
.ctxt = (_ctxt), .node = (_ctxt)->node, }

But I'll leave it up to you to decide whether it makes sense to worry
about C99 initializers.

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

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


Re: [libvirt] [Qemu-devel] Virtio-net control queue handling

2019-02-27 Thread Stefan Hajnoczi
On Tue, Feb 26, 2019 at 02:13:43PM +, Nikhil Agarwal wrote:
> Is there any option in QEMU to offload virtio device control queue handling 
> to backend instead of deciphering and passing to libvirt via QMP? if not, is 
> there any interface in libvirt which passes on these message to application 
> or i directly use QMP interface from QEMU?

I'm not sure I understand your question.  It could be because of
terminology:

"virtio device control queue" == virtio-net control virtqueue?

"backend" == vhost-user-net device backend?

"message" == QMP event?

I have CCed Jason Wang, QEMU network subsystem maintainer, and the
libvirt mailing list.

Stefan


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

Re: [libvirt] [PATCH 3/1] virsh: Test batch mode parser improvements

2019-02-27 Thread Eric Blake
On 2/27/19 2:53 AM, Andrea Bolognani wrote:
> On Tue, 2019-02-26 at 15:48 -0600, Eric Blake wrote:
>> I redid this into the two patches, and pushed.
> 
> I don't think that was appropriate, considering that we're during
> the pre-release freeze and this looks like a new feature rather
> than an urgent fix.

The ack was given before the freeze. But I'm also okay with reverting
them back out of 5.1 if you think that is more appropriate.

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

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


Re: [libvirt] [PATCH] util: Use VIR_AUTOUNREF for virstoragefile

2019-02-27 Thread John Ferlan
ping?  I know, not for this release, but to be queued when 5.2.0 opens.

Tks,

John

On 2/18/19 10:27 AM, John Ferlan wrote:
> Let's make use of the auto __cleanup capabilities cleaning up any
> now unnecessary goto paths.
> 
> Signed-off-by: John Ferlan 
> ---
> 
>  BTW: I did try this with a linked travis-ci and github branch, and it
>   worked for me. I'm avoiding altering virStorageFileMetadataNew...
> 
>  src/util/virstoragefile.c | 130 +++---
>  1 file changed, 52 insertions(+), 78 deletions(-)
> 
> diff --git a/src/util/virstoragefile.c b/src/util/virstoragefile.c
> index b2e308d81d..003183bf76 100644
> --- a/src/util/virstoragefile.c
> +++ b/src/util/virstoragefile.c
> @@ -1205,11 +1205,11 @@ virStorageFileGetMetadataFromFD(const char *path,
>  
>  {
>  virStorageSourcePtr ret = NULL;
> -virStorageSourcePtr meta = NULL;
>  ssize_t len = VIR_STORAGE_MAX_HEADER;
>  struct stat sb;
>  int dummy;
>  VIR_AUTOFREE(char *) buf = NULL;
> +VIR_AUTOUNREF(virStorageSourcePtr) meta = NULL;
>  
>  if (!backingFormat)
>  backingFormat = 
> @@ -1231,21 +1231,21 @@ virStorageFileGetMetadataFromFD(const char *path,
>  meta->type = VIR_STORAGE_TYPE_DIR;
>  meta->format = VIR_STORAGE_FILE_DIR;
>  VIR_STEAL_PTR(ret, meta);
> -goto cleanup;
> +return ret;
>  }
>  
>  if (lseek(fd, 0, SEEK_SET) == (off_t)-1) {
>  virReportSystemError(errno, _("cannot seek to start of '%s'"), 
> meta->path);
> -goto cleanup;
> +return NULL;
>  }
>  
>  if ((len = virFileReadHeaderFD(fd, len, )) < 0) {
>  virReportSystemError(errno, _("cannot read header '%s'"), 
> meta->path);
> -goto cleanup;
> +return NULL;
>  }
>  
>  if (virStorageFileGetMetadataInternal(meta, buf, len, backingFormat) < 0)
> -goto cleanup;
> +return NULL;
>  
>  if (S_ISREG(sb.st_mode))
>  meta->type = VIR_STORAGE_TYPE_FILE;
> @@ -1253,9 +1253,6 @@ virStorageFileGetMetadataFromFD(const char *path,
>  meta->type = VIR_STORAGE_TYPE_BLOCK;
>  
>  VIR_STEAL_PTR(ret, meta);
> -
> - cleanup:
> -virObjectUnref(meta);
>  return ret;
>  }
>  
> @@ -2243,7 +2240,8 @@ virStorageSourcePtr
>  virStorageSourceCopy(const virStorageSource *src,
>   bool backingChain)
>  {
> -virStorageSourcePtr def = NULL;
> +virStorageSourcePtr ret = NULL;
> +VIR_AUTOUNREF(virStorageSourcePtr) def = NULL;
>  
>  if (!(def = virStorageSourceNew()))
>  return NULL;
> @@ -2282,60 +2280,57 @@ virStorageSourceCopy(const virStorageSource *src,
>  VIR_STRDUP(def->compat, src->compat) < 0 ||
>  VIR_STRDUP(def->tlsAlias, src->tlsAlias) < 0 ||
>  VIR_STRDUP(def->tlsCertdir, src->tlsCertdir) < 0)
> -goto error;
> +return NULL;
>  
>  if (src->nhosts) {
>  if (!(def->hosts = virStorageNetHostDefCopy(src->nhosts, 
> src->hosts)))
> -goto error;
> +return NULL;
>  
>  def->nhosts = src->nhosts;
>  }
>  
>  if (src->srcpool &&
>  !(def->srcpool = virStorageSourcePoolDefCopy(src->srcpool)))
> -goto error;
> +return NULL;
>  
>  if (src->features &&
>  !(def->features = virBitmapNewCopy(src->features)))
> -goto error;
> +return NULL;
>  
>  if (src->encryption &&
>  !(def->encryption = virStorageEncryptionCopy(src->encryption)))
> -goto error;
> +return NULL;
>  
>  if (src->perms &&
>  !(def->perms = virStoragePermsCopy(src->perms)))
> -goto error;
> +return NULL;
>  
>  if (src->timestamps &&
>  !(def->timestamps = virStorageTimestampsCopy(src->timestamps)))
> -goto error;
> +return NULL;
>  
>  if (virStorageSourceSeclabelsCopy(def, src) < 0)
> -goto error;
> +return NULL;
>  
>  if (src->auth &&
>  !(def->auth = virStorageAuthDefCopy(src->auth)))
> -goto error;
> +return NULL;
>  
>  if (src->pr &&
>  !(def->pr = virStoragePRDefCopy(src->pr)))
> -goto error;
> +return NULL;
>  
>  if (virStorageSourceInitiatorCopy(>initiator, >initiator))
> -goto error;
> +return NULL;
>  
>  if (backingChain && src->backingStore) {
>  if (!(def->backingStore = virStorageSourceCopy(src->backingStore,
> true)))
> -goto error;
> +return NULL;
>  }
>  
> -return def;
> -
> - error:
> -virObjectUnref(def);
> -return NULL;
> +VIR_STEAL_PTR(ret, def);
> +return ret;
>  }
>  
>  
> @@ -2601,27 +2596,28 @@ static virStorageSourcePtr
>  virStorageSourceNewFromBackingRelative(virStorageSourcePtr parent,
> const char *rel)
>  {
> -virStorageSourcePtr def;
> +virStorageSourcePtr ret = 

[libvirt] [PATCH] conf: fix title and description for virDomainSetMetadata API

2019-02-27 Thread Pavel Hrdina
If we pass XML to virDomainDefineXML API with these two elements:

...


...

libvirt correctly ignores these two elements and they will not appear
in the parsed XML.

However, if we use virDomainSetMetadata API and with "" as value for
title or description we will end up with the parsed XML that contains
these empty elements.

Let's fix the behavior of this API to behave the same as
virDomainDefineXML.

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

Signed-off-by: Pavel Hrdina 
---
 src/conf/domain_conf.c |  6 +++---
 tests/metadatatest.c   | 23 ---
 2 files changed, 19 insertions(+), 10 deletions(-)

diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c
index 477deb777e..2fba58e5c4 100644
--- a/src/conf/domain_conf.c
+++ b/src/conf/domain_conf.c
@@ -30363,7 +30363,7 @@ virDomainDefSetMetadata(virDomainDefPtr def,
 xmlDocPtr doc = NULL;
 xmlNodePtr old;
 xmlNodePtr new = NULL;
-char *tmp;
+char *tmp = NULL;
 int ret = -1;
 
 if (type >= VIR_DOMAIN_METADATA_LAST) {
@@ -30374,7 +30374,7 @@ virDomainDefSetMetadata(virDomainDefPtr def,
 
 switch ((virDomainMetadataType) type) {
 case VIR_DOMAIN_METADATA_DESCRIPTION:
-if (VIR_STRDUP(tmp, metadata) < 0)
+if (STRNEQ_NULLABLE(metadata, "") && VIR_STRDUP(tmp, metadata) < 0)
 goto cleanup;
 
 VIR_FREE(def->description);
@@ -30382,7 +30382,7 @@ virDomainDefSetMetadata(virDomainDefPtr def,
 break;
 
 case VIR_DOMAIN_METADATA_TITLE:
-if (VIR_STRDUP(tmp, metadata) < 0)
+if (STRNEQ_NULLABLE(metadata, "") && VIR_STRDUP(tmp, metadata) < 0)
 goto cleanup;
 
 VIR_FREE(def->title);
diff --git a/tests/metadatatest.c b/tests/metadatatest.c
index 786c62e623..a9080b32d7 100644
--- a/tests/metadatatest.c
+++ b/tests/metadatatest.c
@@ -167,6 +167,7 @@ struct metadataTest {
 virDomainPtr dom;
 
 const char *data;
+const char *expect;
 int type;
 bool fail;
 };
@@ -232,7 +233,7 @@ testTextMetadata(const void *data)
 
 actual = virDomainGetMetadata(test->dom, test->type, NULL, 0);
 
-if (STRNEQ_NULLABLE(test->data, actual)) {
+if (STRNEQ_NULLABLE(test->expect, actual)) {
 virReportError(VIR_ERR_INTERNAL_ERROR,
"expected metadata doesn't match actual: "
"expected:'%s'\ngot: '%s'",
@@ -248,10 +249,11 @@ testTextMetadata(const void *data)
 return ret;
 }
 
-#define TEST_TEXT_METADATA(INDEX, TYPE, DATA, FAIL) \
+#define TEST_TEXT_METADATA(INDEX, TYPE, DATA, EXPECT, FAIL) \
 do { \
 test.type = VIR_DOMAIN_METADATA_ ## TYPE; \
 test.data = DATA; \
+test.expect = EXPECT; \
 test.fail = FAIL; \
  \
 if (virTestRun("text metadata: " #TYPE " " INDEX " ", \
@@ -259,9 +261,16 @@ testTextMetadata(const void *data)
 ret = EXIT_FAILURE; \
 } while (0)
 
-#define TEST_TITLE(INDEX, DATA) TEST_TEXT_METADATA(INDEX, TITLE, DATA, false)
-#define TEST_TITLE_FAIL(INDEX, DATA) TEST_TEXT_METADATA(INDEX, TITLE, DATA, 
true)
-#define TEST_DESCR(INDEX, DATA) TEST_TEXT_METADATA(INDEX, DESCRIPTION, DATA, 
false)
+#define TEST_TITLE(INDEX, DATA) \
+TEST_TEXT_METADATA(INDEX, TITLE, DATA, DATA, false)
+#define TEST_TITLE_EXPECT(INDEX, DATA, EXPECT) \
+TEST_TEXT_METADATA(INDEX, TITLE, DATA, EXPECT, false)
+#define TEST_TITLE_FAIL(INDEX, DATA) \
+TEST_TEXT_METADATA(INDEX, TITLE, DATA, DATA, true)
+#define TEST_DESCR(INDEX, DATA) \
+TEST_TEXT_METADATA(INDEX, DESCRIPTION, DATA, DATA, false)
+#define TEST_DESCR_EXPECT(INDEX, DATA, EXPECT) \
+TEST_TEXT_METADATA(INDEX, DESCRIPTION, DATA, EXPECT, false)
 
 static int
 mymain(void)
@@ -290,7 +299,7 @@ mymain(void)
 TEST_TITLE("2", NULL);
 TEST_TITLE("3", "blah");
 TEST_TITLE_FAIL("4", "qwe\nrt");
-TEST_TITLE("5", "");
+TEST_TITLE_EXPECT("5", "", NULL);
 TEST_TITLE_FAIL("6", "qwert\n");
 TEST_TITLE_FAIL("7", "\n");
 
@@ -298,7 +307,7 @@ mymain(void)
 TEST_DESCR("2", NULL);
 TEST_DESCR("3", "qwert");
 TEST_DESCR("4", "\n");
-TEST_DESCR("5", "");
+TEST_DESCR_EXPECT("5", "", NULL);
 
 virDomainFree(test.dom);
 virConnectClose(test.conn);
-- 
2.20.1

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


[libvirt] [PATCH 2/2] monitor: deprecate acl_show, acl_reset, acl_policy, acl_add, acl_remove

2019-02-27 Thread Daniel P . Berrangé
The various ACL related commands are obsolete now that the QAuthZ
framework for authorization is fully integrated throughout QEMU network
services. These only ever worked with VNC and were never used by libvirt.
Mark it as deprecated with no direct replacement to be provided.

Authorization is now provided by using 'object_add' together with
the 'tls-authz' or 'sasl-authz' parameters to the VNC server, and
equivalent for other network services.

Reviewed-by: Juan Quintela 
Signed-off-by: Daniel P. Berrangé 
---
 monitor.c| 23 +++
 qemu-deprecated.texi |  6 ++
 2 files changed, 29 insertions(+)

diff --git a/monitor.c b/monitor.c
index defa129319..72061d5bae 100644
--- a/monitor.c
+++ b/monitor.c
@@ -2032,6 +2032,19 @@ static QAuthZList *find_auth(Monitor *mon, const char 
*name)
 return QAUTHZ_LIST(obj);
 }
 
+static bool warn_acl;
+static void hmp_warn_acl(void)
+{
+if (warn_acl) {
+return;
+}
+error_report("The acl_show, acl_reset, acl_policy, acl_add, acl_remove "
+ "commands are deprecated with no replacement. Authorization "
+ "for VNC should be performed using the pluggable QAuthZ "
+ "objects");
+warn_acl = true;
+}
+
 static void hmp_acl_show(Monitor *mon, const QDict *qdict)
 {
 const char *aclname = qdict_get_str(qdict, "aclname");
@@ -2039,6 +2052,8 @@ static void hmp_acl_show(Monitor *mon, const QDict *qdict)
 QAuthZListRuleList *rules;
 size_t i = 0;
 
+hmp_warn_acl();
+
 if (!auth) {
 return;
 }
@@ -2062,6 +2077,8 @@ static void hmp_acl_reset(Monitor *mon, const QDict 
*qdict)
 const char *aclname = qdict_get_str(qdict, "aclname");
 QAuthZList *auth = find_auth(mon, aclname);
 
+hmp_warn_acl();
+
 if (!auth) {
 return;
 }
@@ -2080,6 +2097,8 @@ static void hmp_acl_policy(Monitor *mon, const QDict 
*qdict)
 int val;
 Error *err = NULL;
 
+hmp_warn_acl();
+
 if (!auth) {
 return;
 }
@@ -2124,6 +2143,8 @@ static void hmp_acl_add(Monitor *mon, const QDict *qdict)
 QAuthZListFormat format;
 size_t i = 0;
 
+hmp_warn_acl();
+
 if (!auth) {
 return;
 }
@@ -2169,6 +2190,8 @@ static void hmp_acl_remove(Monitor *mon, const QDict 
*qdict)
 QAuthZList *auth = find_auth(mon, aclname);
 ssize_t i = 0;
 
+hmp_warn_acl();
+
 if (!auth) {
 return;
 }
diff --git a/qemu-deprecated.texi b/qemu-deprecated.texi
index 1258da4795..1e15f57e9c 100644
--- a/qemu-deprecated.texi
+++ b/qemu-deprecated.texi
@@ -104,6 +104,12 @@ The @option{[hub_id name]} parameter tuple of the 
'hostfwd_add' and
 Use ``device_add'' for hotplugging vCPUs instead of ``cpu-add''.  See
 documentation of ``query-hotpluggable-cpus'' for additional details.
 
+@subsection acl_show, acl_reset, acl_policy, acl_add, acl_remove (since 4.0.0)
+
+The ``acl_show'', ``acl_reset'', ``acl_policy'', ``acl_add'', and
+``acl_remove'' commands are deprecated with no replacement. Authorization
+for VNC should be performed using the pluggable QAuthZ objects.
+
 @section System emulator devices
 
 @subsection bluetooth (since 3.1)
-- 
2.20.1

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

[libvirt] [PATCH 1/2] vnc: allow specifying a custom authorization object name

2019-02-27 Thread Daniel P . Berrangé
From: "Daniel P. Berrange" 

The VNC server has historically had support for ACLs to check both the
SASL username and the TLS x509 distinguished name. The VNC server was
responsible for creating the initial ACL, and the client app was then
responsible for populating it with rules using the HMP 'acl_add' command.

This is not satisfactory for a variety of reasons. There is no way to
populate the ACLs from the command line, users are forced to use the
HMP. With multiple network services all supporting TLS and ACLs now, it
is desirable to be able to define a single ACL that is referenced by all
services.

To address these limitations, two new options are added to the VNC
server CLI. The 'tls-authz' option takes the ID of a QAuthZ object to
use for checking TLS x509 distinguished names, and the 'sasl-authz'
option takes the ID of another object to use for checking SASL usernames.

In this example, we setup two authorization rules. The first allows any
client with a certificate issued by the 'RedHat' organization in the
'London' locality. The second ACL allows clients with either the
'j...@redhat.com' or  'f...@redhat.com' kerberos usernames. Both checks
must pass for the user to be allowed.

$QEMU -object tls-creds-x509,id=tls0,dir=/home/berrange/qemutls,\
  endpoint=server,verify-peer=yes \
  -object authz-simple,id=authz0,policy=deny,\
  rules.0.match=O=RedHat,,L=London,rules.0.policy=allow \
  -object authz-simple,id=authz1,policy=deny,\
  rules.0.match=f...@redhat.com,rules.0.policy=allow \
  rules.0.match=j...@redhat.com,rules.0.policy=allow \
  -vnc 0.0.0.0:1,tls-creds=tls0,tls-authz=authz0,
   sasl,sasl-authz=authz1 \
  ...other QEMU args...

Reviewed-by: Juan Quintela 
Signed-off-by: Daniel P. Berrange 
---
 qemu-deprecated.texi |  5 
 qemu-options.hx  | 35 ++
 ui/vnc.c | 58 +---
 3 files changed, 79 insertions(+), 19 deletions(-)

diff --git a/qemu-deprecated.texi b/qemu-deprecated.texi
index 45c57952da..1258da4795 100644
--- a/qemu-deprecated.texi
+++ b/qemu-deprecated.texi
@@ -60,6 +60,11 @@ Support for invalid topologies will be removed, the user 
must ensure
 topologies described with -smp include all possible cpus, i.e.
   @math{@var{sockets} * @var{cores} * @var{threads} = @var{maxcpus}}.
 
+@subsection -vnc acl (since 4.0.0)
+
+The @code{acl} option to the @code{-vnc} argument has been replaced
+by the @code{tls-authz} and @code{sasl-authz} options.
+
 @section QEMU Machine Protocol (QMP) commands
 
 @subsection block-dirty-bitmap-add "autoload" parameter (since 2.12.0)
diff --git a/qemu-options.hx b/qemu-options.hx
index 1cf9aac1fe..c74f99b265 100644
--- a/qemu-options.hx
+++ b/qemu-options.hx
@@ -1624,6 +1624,14 @@ will cause the VNC server socket to enable the VeNCrypt 
auth
 mechanism.  The credentials should have been previously created
 using the @option{-object tls-creds} argument.
 
+@item tls-authz=@var{ID}
+
+Provides the ID of the QAuthZ authorization object against which
+the client's x509 distinguished name will validated. This object is
+only resolved at time of use, so can be deleted and recreated on the
+fly while the VNC server is active. If missing, it will default
+to denying access.
+
 @item sasl
 
 Require that the client use SASL to authenticate with the VNC server.
@@ -1639,18 +1647,25 @@ ensures a data encryption preventing compromise of 
authentication
 credentials. See the @ref{vnc_security} section for details on using
 SASL authentication.
 
+@item sasl-authz=@var{ID}
+
+Provides the ID of the QAuthZ authorization object against which
+the client's SASL username will validated. This object is
+only resolved at time of use, so can be deleted and recreated on the
+fly while the VNC server is active. If missing, it will default
+to denying access.
+
 @item acl
 
-Turn on access control lists for checking of the x509 client certificate
-and SASL party. For x509 certs, the ACL check is made against the
-certificate's distinguished name. This is something that looks like
-@code{C=GB,O=ACME,L=Boston,CN=bob}. For SASL party, the ACL check is
-made against the username, which depending on the SASL plugin, may
-include a realm component, eg @code{bob} or @code{bob@@EXAMPLE.COM}.
-When the @option{acl} flag is set, the initial access list will be
-empty, with a @code{deny} policy. Thus no one will be allowed to
-use the VNC server until the ACLs have been loaded. This can be
-achieved using the @code{acl} monitor command.
+Legacy method for enabling authorization of clients against the
+x509 distinguished name and SASL username. It results in the creation
+of two @code{authz-list} objects with IDs of @code{vnc.username} and
+@code{vnc.x509dname}. The rules for these objects must be configured
+with the HMP ACL commands.
+
+This option is deprecated and should no longer be used. The 

[libvirt] [PATCH 0/2] ui: support for authorization control on TLS connections

2019-02-27 Thread Daniel P . Berrangé
This series provides the VNC parts of the authorization control series
previously posted as:

  v1: https://lists.gnu.org/archive/html/qemu-devel/2018-06/msg04482.html
  v2: https://lists.gnu.org/archive/html/qemu-devel/2018-06/msg05727.html
  v3: https://lists.gnu.org/archive/html/qemu-devel/2018-10/msg01639.html
  v4: https://lists.gnu.org/archive/html/qemu-devel/2019-02/msg04319.html

The core authz framework is now merged & these patches have all had
positive review. Thus these VNC parts are ready to go into the VNC
maintainer's tree, should the maintainer consider them acceptable.

Note the 2nd patch is modifying the HMP, but I considered it part
of ui/vnc, since that's the only bit of QEMU which ever used these
HMP commands, and it has a dependancy on the first patch merging
first.

Daniel P. Berrangé (2):
  vnc: allow specifying a custom authorization object name
  monitor: deprecate acl_show, acl_reset, acl_policy, acl_add,
acl_remove

 monitor.c| 23 ++
 qemu-deprecated.texi | 11 +
 qemu-options.hx  | 35 ++
 ui/vnc.c | 58 +---
 4 files changed, 108 insertions(+), 19 deletions(-)

-- 
2.20.1

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

Re: [libvirt] [PATCH 05/26] cputest: Add data for Intel(R) Xeon(R) CPU E5-2650

2019-02-27 Thread Ján Tomko

On Wed, Feb 27, 2019 at 02:28:55PM +0100, Jiri Denemark wrote:

Signed-off-by: Jiri Denemark 
---
tests/cputest.c   |   1 +
.../x86_64-cpuid-Xeon-E5-2650-disabled.xml|   5 +
.../x86_64-cpuid-Xeon-E5-2650-enabled.xml |   8 +
.../x86_64-cpuid-Xeon-E5-2650-guest.xml   |  29 +
.../x86_64-cpuid-Xeon-E5-2650-host.xml|  30 +
.../x86_64-cpuid-Xeon-E5-2650-json.xml|  14 +
.../x86_64-cpuid-Xeon-E5-2650.json| 931 ++
.../cputestdata/x86_64-cpuid-Xeon-E5-2650.xml |  34 +
8 files changed, 1052 insertions(+)
create mode 100644 tests/cputestdata/x86_64-cpuid-Xeon-E5-2650-disabled.xml
create mode 100644 tests/cputestdata/x86_64-cpuid-Xeon-E5-2650-enabled.xml
create mode 100644 tests/cputestdata/x86_64-cpuid-Xeon-E5-2650-guest.xml
create mode 100644 tests/cputestdata/x86_64-cpuid-Xeon-E5-2650-host.xml
create mode 100644 tests/cputestdata/x86_64-cpuid-Xeon-E5-2650-json.xml
create mode 100644 tests/cputestdata/x86_64-cpuid-Xeon-E5-2650.json
create mode 100644 tests/cputestdata/x86_64-cpuid-Xeon-E5-2650.xml



Reviewed-by: Ján Tomko 

Jano


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

[libvirt] [PATCH] Drop some useless comparisons and checks

2019-02-27 Thread Michal Privoznik
In these cases the check that is removed has been done a few
lines above already (as can even be seen in the context). Drop
them.

Signed-off-by: Michal Privoznik 
---
 examples/dommigrate/dommigrate.c |  3 +--
 src/conf/nwfilter_conf.c |  4 +---
 src/qemu/qemu_command.c  |  3 +--
 src/qemu/qemu_hotplug.c  | 20 +---
 src/util/virresctrl.c|  2 +-
 tools/virsh-snapshot.c   |  5 ++---
 6 files changed, 15 insertions(+), 22 deletions(-)

diff --git a/examples/dommigrate/dommigrate.c b/examples/dommigrate/dommigrate.c
index 1b6072d138..60cfb3fb83 100644
--- a/examples/dommigrate/dommigrate.c
+++ b/examples/dommigrate/dommigrate.c
@@ -37,51 +37,50 @@ int
 main(int argc, char *argv[])
 {
 char *src_uri, *dst_uri, *domname;
 int ret = 0;
 virConnectPtr conn = NULL;
 virDomainPtr dom = NULL;
 
 if (argc < 4) {
 ret = usage(argv[0], 1);
 goto out;
 }
 
 src_uri = argv[1];
 dst_uri = argv[2];
 domname = argv[3];
 
 printf("Attempting to connect to the source hypervisor...\n");
 conn = virConnectOpenAuth(src_uri, virConnectAuthPtrDefault, 0);
 if (!conn) {
 ret = 1;
 fprintf(stderr, "No connection to the source hypervisor: %s.\n",
 virGetLastErrorMessage());
 goto out;
 }
 
 printf("Attempting to retrieve domain %s...\n", domname);
 dom = virDomainLookupByName(conn, domname);
 if (!dom) {
 fprintf(stderr, "Failed to find domain %s.\n", domname);
 goto cleanup;
 }
 
 printf("Attempting to migrate %s to %s...\n", domname, dst_uri);
 if ((ret = virDomainMigrateToURI(dom, dst_uri,
  VIR_MIGRATE_PEER2PEER,
  NULL, 0)) != 0) {
 fprintf(stderr, "Failed to migrate domain %s.\n", domname);
 goto cleanup;
 }
 
 printf("Migration finished with success.\n");
 
  cleanup:
 if (dom != NULL)
 virDomainFree(dom);
-if (conn != NULL)
-virConnectClose(conn);
+virConnectClose(conn);
 
  out:
 return ret;
 }
diff --git a/src/conf/nwfilter_conf.c b/src/conf/nwfilter_conf.c
index 7cad3ccc57..3f28c7b451 100644
--- a/src/conf/nwfilter_conf.c
+++ b/src/conf/nwfilter_conf.c
@@ -2610,128 +2610,126 @@ static virNWFilterDefPtr
 virNWFilterDefParseXML(xmlXPathContextPtr ctxt)
 {
 virNWFilterDefPtr ret;
 xmlNodePtr curr = ctxt->node;
 char *uuid = NULL;
 char *chain = NULL;
 char *chain_pri_s = NULL;
 virNWFilterEntryPtr entry;
 int chain_priority;
 const char *name_prefix;
 
 if (VIR_ALLOC(ret) < 0)
 return NULL;
 
 ret->name = virXPathString("string(./@name)", ctxt);
 if (!ret->name) {
 virReportError(VIR_ERR_INTERNAL_ERROR,
"%s", _("filter has no name"));
 goto cleanup;
 }
 
 chain_pri_s = virXPathString("string(./@priority)", ctxt);
 if (chain_pri_s) {
 if (virStrToLong_i(chain_pri_s, NULL, 10, _priority) < 0) {
 virReportError(VIR_ERR_INVALID_ARG,
_("Could not parse chain priority '%s'"),
chain_pri_s);
 goto cleanup;
 }
 if (chain_priority < NWFILTER_MIN_FILTER_PRIORITY ||
 chain_priority > NWFILTER_MAX_FILTER_PRIORITY) {
 virReportError(VIR_ERR_INVALID_ARG,
_("Priority '%d' is outside valid "
  "range of [%d,%d]"),
chain_priority,
NWFILTER_MIN_FILTER_PRIORITY,
NWFILTER_MAX_FILTER_PRIORITY);
 goto cleanup;
 }
 }
 
 chain = virXPathString("string(./@chain)", ctxt);
 if (chain) {
 name_prefix = virNWFilterIsAllowedChain(chain);
 if (name_prefix == NULL)
 goto cleanup;
 ret->chainsuffix = chain;
 
 if (chain_pri_s) {
 ret->chainPriority = chain_priority;
 } else {
 /* assign default priority if none can be found via lookup */
-if (!name_prefix ||
- intMapGetByString(chain_priorities, name_prefix, 0,
-   >chainPriority) < 0) {
+if (intMapGetByString(chain_priorities, name_prefix, 0, 
>chainPriority) < 0) {
 /* assign default chain priority */
 ret->chainPriority = (NWFILTER_MAX_FILTER_PRIORITY +
   NWFILTER_MIN_FILTER_PRIORITY) / 2;
 }
 }
 chain = NULL;
 } else {
 if (VIR_STRDUP(ret->chainsuffix,

virNWFilterChainSuffixTypeToString(VIR_NWFILTER_CHAINSUFFIX_ROOT)) < 0)
 goto cleanup;
 }
 
 uuid = virXPathString("string(./uuid)", ctxt);
 ret->uuid_specified = (uuid != NULL);
 if (uuid == NULL) {
 if 

Re: [libvirt] [PATCH 04/26] cputest: Add data for Intel(R) Xeon(R) CPU E7540

2019-02-27 Thread Ján Tomko

On Wed, Feb 27, 2019 at 02:28:54PM +0100, Jiri Denemark wrote:

Signed-off-by: Jiri Denemark 
---
tests/cputest.c   |1 +
.../x86_64-cpuid-Xeon-E7540-disabled.xml  |5 +
.../x86_64-cpuid-Xeon-E7540-enabled.xml   |7 +
.../x86_64-cpuid-Xeon-E7540-guest.xml |   25 +
.../x86_64-cpuid-Xeon-E7540-host.xml  |   26 +
.../x86_64-cpuid-Xeon-E7540-json.xml  |   14 +
.../cputestdata/x86_64-cpuid-Xeon-E7540.json  | 1117 +
tests/cputestdata/x86_64-cpuid-Xeon-E7540.xml |   30 +
8 files changed, 1225 insertions(+)
create mode 100644 tests/cputestdata/x86_64-cpuid-Xeon-E7540-disabled.xml
create mode 100644 tests/cputestdata/x86_64-cpuid-Xeon-E7540-enabled.xml
create mode 100644 tests/cputestdata/x86_64-cpuid-Xeon-E7540-guest.xml
create mode 100644 tests/cputestdata/x86_64-cpuid-Xeon-E7540-host.xml
create mode 100644 tests/cputestdata/x86_64-cpuid-Xeon-E7540-json.xml
create mode 100644 tests/cputestdata/x86_64-cpuid-Xeon-E7540.json
create mode 100644 tests/cputestdata/x86_64-cpuid-Xeon-E7540.xml



Reviewed-by: Ján Tomko 

Jano


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

Re: [libvirt] [PATCH 03/26] cputest: Add data for Intel(R) Core(TM) i7-7600U

2019-02-27 Thread Ján Tomko

On Wed, Feb 27, 2019 at 02:28:53PM +0100, Jiri Denemark wrote:

Signed-off-by: Jiri Denemark 
---
tests/cputest.c   |   1 +
.../x86_64-cpuid-Core-i7-7600U-disabled.xml   |   6 +
.../x86_64-cpuid-Core-i7-7600U-enabled.xml|   8 +
.../x86_64-cpuid-Core-i7-7600U-guest.xml  |  28 +
.../x86_64-cpuid-Core-i7-7600U-host.xml   |  29 +
.../x86_64-cpuid-Core-i7-7600U-json.xml   |  13 +
.../x86_64-cpuid-Core-i7-7600U.json   | 755 ++
.../x86_64-cpuid-Core-i7-7600U.xml|  47 ++
8 files changed, 887 insertions(+)
create mode 100644 tests/cputestdata/x86_64-cpuid-Core-i7-7600U-disabled.xml
create mode 100644 tests/cputestdata/x86_64-cpuid-Core-i7-7600U-enabled.xml
create mode 100644 tests/cputestdata/x86_64-cpuid-Core-i7-7600U-guest.xml
create mode 100644 tests/cputestdata/x86_64-cpuid-Core-i7-7600U-host.xml
create mode 100644 tests/cputestdata/x86_64-cpuid-Core-i7-7600U-json.xml
create mode 100644 tests/cputestdata/x86_64-cpuid-Core-i7-7600U.json
create mode 100644 tests/cputestdata/x86_64-cpuid-Core-i7-7600U.xml



Reviewed-by: Ján Tomko 

Jano


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

Re: [libvirt] [PATCH 02/26] cputest: Add data for Intel(R) Xeon(R) CPU E5-2630 v4

2019-02-27 Thread Ján Tomko

On Wed, Feb 27, 2019 at 02:28:52PM +0100, Jiri Denemark wrote:

Signed-off-by: Jiri Denemark 
---
tests/cputest.c   |   1 +
.../x86_64-cpuid-Xeon-E5-2630-v4-disabled.xml |   7 +
.../x86_64-cpuid-Xeon-E5-2630-v4-enabled.xml  |   8 +
.../x86_64-cpuid-Xeon-E5-2630-v4-guest.xml|  31 +
.../x86_64-cpuid-Xeon-E5-2630-v4-host.xml |  35 +
.../x86_64-cpuid-Xeon-E5-2630-v4-json.xml |  11 +
.../x86_64-cpuid-Xeon-E5-2630-v4.json | 596 ++
.../x86_64-cpuid-Xeon-E5-2630-v4.xml  |  43 ++
8 files changed, 732 insertions(+)
create mode 100644 tests/cputestdata/x86_64-cpuid-Xeon-E5-2630-v4-disabled.xml
create mode 100644 tests/cputestdata/x86_64-cpuid-Xeon-E5-2630-v4-enabled.xml
create mode 100644 tests/cputestdata/x86_64-cpuid-Xeon-E5-2630-v4-guest.xml
create mode 100644 tests/cputestdata/x86_64-cpuid-Xeon-E5-2630-v4-host.xml
create mode 100644 tests/cputestdata/x86_64-cpuid-Xeon-E5-2630-v4-json.xml
create mode 100644 tests/cputestdata/x86_64-cpuid-Xeon-E5-2630-v4.json
create mode 100644 tests/cputestdata/x86_64-cpuid-Xeon-E5-2630-v4.xml



Reviewed-by: Ján Tomko 

Jano


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

[libvirt] [PATCH] virstoragefile: identify GPFS as cluster FS

2019-02-27 Thread Diego Michelotto
GPFS is 'IBM General Parallel File System', also called
'IBM Spectrum Scale', stalls when a process issues a lot
of fsyncs in a short timeframe.

It is better if the VM I/O is not synchronous.
It is racommended to use writeback caching policy.

In order to permit that it is added VIR_FILE_SHFS_GPFS to
the list of shared file systems in virStorageFileIsClusterFS
function.

Signed-off-by: Diego Michelotto 
---
 src/util/virstoragefile.c | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/src/util/virstoragefile.c b/src/util/virstoragefile.c
index b2e308d81d..0fe2819dc6 100644
--- a/src/util/virstoragefile.c
+++ b/src/util/virstoragefile.c
@@ -1349,7 +1349,8 @@ int virStorageFileIsClusterFS(const char *path)
 return virFileIsSharedFSType(path,
  VIR_FILE_SHFS_GFS2 |
  VIR_FILE_SHFS_OCFS |
- VIR_FILE_SHFS_CEPH);
+ VIR_FILE_SHFS_CEPH |
+ VIR_FILE_SHFS_GPFS);
 }
 
 #ifdef LVS
-- 
2.20.1

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


Re: [libvirt] [PATCH v2 4/4] util: alloc: Note that VIR_AUTOPTR/VIR_AUTOCLEAN must not be used with vectors

2019-02-27 Thread Erik Skultety
On Tue, Feb 26, 2019 at 04:48:26PM +0100, Peter Krempa wrote:
> We'd free only the first element of the vector leaking the rest.
>
> Signed-off-by: Peter Krempa 
> ---
>  src/util/viralloc.h | 6 ++
>  1 file changed, 6 insertions(+)
>
> diff --git a/src/util/viralloc.h b/src/util/viralloc.h
> index 15451d4673..572b7d1c1c 100644
> --- a/src/util/viralloc.h
> +++ b/src/util/viralloc.h
> @@ -650,6 +650,9 @@ void virAllocTestHook(void (*func)(int, void*), void 
> *data);
>   * the variable declared with it by calling the function
>   * defined by VIR_DEFINE_AUTOPTR_FUNC when the variable
>   * goes out of scope.
> + *
> + * Note that this macro must NOT be used with vectors! The cleaning function
> + * will not free any elements beyond the first.

s/cleaning/freeing/

I understand, but if you have happen to have a dedicated list type, then you'd
have a dedicated destructor, so both of these would be okay with vectors. On
the other hand I'm not sure whether we have such a thing at the moment, so I
guess it's meaningful to document in the meantime.

Reviewed-by: Erik Skultety 

>   */
>  # define VIR_AUTOPTR(type) \
>  __attribute__((cleanup(VIR_AUTOPTR_FUNC_NAME(type type *
> @@ -662,6 +665,9 @@ void virAllocTestHook(void (*func)(int, void*), void 
> *data);
>   * when the variable goes out of scope.
>   * The cleanup function is registered by VIR_DEFINE_AUTOCLEAN_FUNC macro for
>   * the given type.
> + *
> + * Note that this macro must NOT be used with vectors! The cleaning function
> + * will not free any elements beyond the first.
>   */
>  # define VIR_AUTOCLEAN(type) \
>  __attribute__((cleanup(VIR_AUTOCLEAN_FUNC_NAME(type type
> --
> 2.20.1
>
> --
> libvir-list mailing list
> libvir-list@redhat.com
> https://www.redhat.com/mailman/listinfo/libvir-list

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


Re: [libvirt] [PATCH 01/26] cputest: Make sure generated files pass syntax-check

2019-02-27 Thread Ján Tomko

On Wed, Feb 27, 2019 at 02:28:51PM +0100, Jiri Denemark wrote:

The tests/cputestdata/cpu-parse.sh would produce JSON files with QEMU
replies which wouldn't pass syntax-check. Let's fix this by not emitting
an extra new line after reformatting the JSON file.

Signed-off-by: Jiri Denemark 
---
tests/cputestdata/cpu-reformat.py | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)



Reviewed-by: Ján Tomko 

Jano


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

Re: [libvirt] [PATCH 5/5] qemu: Use VIR_XPATH_NODE_AUTORESTORE when XPath context is modified

2019-02-27 Thread Ján Tomko

On Tue, Feb 26, 2019 at 06:08:12PM +0100, Peter Krempa wrote:

Use the new helper when moving around the current node of the XPath
context.

Signed-off-by: Peter Krempa 
---
src/qemu/qemu_capabilities.c | 3 +--
src/qemu/qemu_domain.c   | 6 ++
src/qemu/qemu_migration_cookie.c | 9 +++--
3 files changed, 6 insertions(+), 12 deletions(-)



Reviewed-by: Ján Tomko 

Jano


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

Re: [libvirt] [PATCH 4/5] util: XML: Introduce automatic reset of XPath's current node

2019-02-27 Thread Ján Tomko

On Tue, Feb 26, 2019 at 06:08:11PM +0100, Peter Krempa wrote:

Quite a few parts modify the XPath context current node to shif the


shift


scope and allow easier queries. This also means that the node needs
to be restored afterwards.

Introduce a macro based on 'VIR_AUTOCLEAN' which adds a local structure
on the stack remembering the original node along with a function which
will make sure that the node is reset when the local structure leaves
scope.

Signed-off-by: Peter Krempa 
---
src/libvirt_private.syms |  1 +
src/util/virxml.c| 10 ++
src/util/virxml.h| 22 ++
3 files changed, 33 insertions(+)



Reviewed-by: Ján Tomko 

Jano


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

Re: [libvirt] [glib PATCH v2 00/15] po: improve translation handling

2019-02-27 Thread Michal Privoznik

On 2/20/19 6:49 PM, Daniel P. Berrangé wrote:
>

ACK

Michal

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

Re: [libvirt] [PATCH 3/5] util: alloc: Clarify docs for VIR_DEFINE_AUTOCLEAN_FUNC

2019-02-27 Thread Ján Tomko

On Tue, Feb 26, 2019 at 06:08:10PM +0100, Peter Krempa wrote:

Document that @func must take pointer to @type.

Signed-off-by: Peter Krempa 
---
src/util/viralloc.h | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)



Reviewed-by: Ján Tomko 

Jano


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

  1   2   >