Re: [libvirt] VN-Link vNIC memory state copying on VM Migration

2012-04-13 Thread Jagath Weerasinghe
Chris,

Thanks for the reply.

>  what memory state do you refer to exactly?
What I meant by the memory state is the traffic being
transferred through the vNIC when VM migration is triggered.

If this memory state (or traffic) is not copied and moved to the
destination vNIC how the smooth communication, which is
guaranteed on VM migration, is achieved?

Thanks
Jagath

>
> If you refer to port profile info, then there is no copying involved:
>  the source host disassociates the vnic port profile and
>  the destination host re-associates the port profile on the new vnic.
>
> /Chris
>
>> -Original Message-
>> From: libvir-list-boun...@redhat.com
> [mailto:libvir-list-boun...@redhat.com] On Behalf Of Jagath
>> Weerasinghe
>> Sent: Friday, April 13, 2012 9:16 AM
>> To: libvir-list@redhat.com
>> Subject: [libvirt] VN-Link vNIC memory state copying on VM Migration
>>
>> Hi All,
>>
>> I am new to libvirt. And want to know how the VM migration
>> occurs in VN-Link (IEEE802.1Qbh). As far as I know,
>> the memory state of vNICs in M81KR VIC has to be copied
>> and moved to the destination vNIC on VM migration.
>> Is that correct? If so, could you please tell me how this
>> has been implemented in libvirt?
>>
>> Thanks
>> Jagath
>>
>> --
>> 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] [PATCHv4 16/18] blockjob: add virDomainBlockCopy

2012-04-13 Thread Eric Blake
On 04/13/2012 03:25 PM, Jiri Denemark wrote:
> On Mon, Apr 09, 2012 at 21:52:25 -0600, Eric Blake wrote:
>> This new API provides additional flexibility over what can be
>> crammed on top of virDomainBlockRebase (namely, the ability to
>> specify an arbitrary destination format, for things like copying
>> qcow2 into qed without having to pre-create the destination), at
>> the expense that it cannot be backported without bumping the .so
>> version.
>>

>> +typedef enum {
>> +VIR_DOMAIN_BLOCK_COPY_SHALLOW   = 1 << 0, /* Limit copy to top of source
>> + backing chain */
>> +VIR_DOMAIN_BLOCK_COPY_REUSE_EXT = 1 << 1, /* Reuse existing external
>> + file for a copy */
>> +} virDomainBlockCopyFlags;
> 
> Hmm, we have several flags enums that end up being passed to a single internal
> API and one has to be extra careful when adding new flags. Should we make a
> note about this to the affected enums?

Yes, a note would be helpful (it's only the two least-significant bits
that we are playing fast and loose with at the moment, but if we ever
expand to a third common bit, I see where it could get confusing).

>>
>>  /**
>> + * virDomainBlockCopy:
>> + * @dom: pointer to domain object
>> + * @disk: path to the block device, or device shorthand
>> + * @dest: path to the copy destination
>> + * @format: format of the destination
>> + * @bandwidth: (optional) specify copy bandwidth limit in Mbps
>> + * @flags: bitwise-OR of virDomainBlockCopyFlags
> 
> OK, so this new API may be used to avoid format guessing involved in
> virDomainBlockRebase. Shouldn't we introduce an enhanced version of
> virDomainBlockRebase with format parameter instead of introducing an API with
> a different name that does almost the same as virDomainBlockRebase?

And what would you name it?  I'm saying that virDomainBlockCopy _is_ an
enhanced virDomainBlockRebase, and the name BlockCopy was the name I
picked, as it looks nicer than virDomainBlockRebase2().

I'm also debating whether to add a 'const char *base' argument, to allow
a copy of a partial chain.  That is, starting from:

base <- snap1 <- snap2

virDomainBlockRebase can only give you:

copy (flat image, no backing file, by omitting _SHALLOW)
base <- snap1 <- copy (use _SHALLOW, topmost backing file is shared)

and if you want to get to:

base <- copy

you currently have to call virDomainBlockRebase _twice_, with the
following API sequence:

virDomainBlockRebase(dom, disk, "copy", bandwidth,
 VIR_DOMAIN_BLOCK_REBASE_COPY | VIR_DOMAIN_BLOCK_REBASE_SHALLOW);
virDomainBlockJobAbort(dom, disk, VIR_DOMAIN_BLOCK_JOB_ABORT_PIVOT);
virDomainBlockRebase(dom, disk, "base", bandwidth, 0);

But you could theoretically do the same result in one less step, with an
optional base argument, by calling:

virDomainBlockCopy(dom, disk, "copy", "base", bandwidth, 0);
virDomainBlockJobAbort(dom, disk, VIR_DOMAIN_BLOCK_JOB_ABORT_PIVOT);

non-NULL base combined with the _SHALLOW flag would either be outright
rejected, or else be useful to validate that the 'base' you are passing
in really is the backing file of the source that you are copying from
(or even be a way to signify whether you want an absolute or relative
backing file name jammed into the destination file).

But Paolo hasn't yet decided whether to commit to that optional argument
in qemu yet (I originally had it in place for v1 of this series, back
when Paolo was trying to add a blkmirror device instead of a block job
for mirroring, but ripped it out along my way).

I guess I should wait for more feedback on the qemu front before
committing to the final form of this proposed libvirt API.

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



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

Re: [libvirt] [PATCHv4 18/18] blockjob: wire up qemu and RPC for block copy

2012-04-13 Thread Jiri Denemark
On Mon, Apr 09, 2012 at 21:52:27 -0600, Eric Blake wrote:
> Almost trivial; the trick was dealing with the fact that we're
> stuck with 'unsigned long bandwidth' due to earlier design
> decisions.  Also, prefer the correct flag names (although we
> intentionally chose the _SHALLOW and _REUSE_EXT values to be
> equal, to allow for loose handling in our code).
> 
> * src/remote/remote_protocol.x (remote_domain_block_copy_args):
> New struct.
> * src/remote/remote_driver.c (remote_driver): Use it.
> * src/rpc/gendispatch.pl (name_to_ProcName): Cater to legacy
> bandwidth type.
> * src/remote_protocol-structs: Regenerate.
> * src/qemu/qemu_driver.c (qemuDriver): Wire up driver callback.
> (qemuDomainBlockCopy): Use preferred flag names.
> ---
>  src/qemu/qemu_driver.c   |   13 +++--
>  src/remote/remote_driver.c   |1 +
>  src/remote/remote_protocol.x |   12 +++-
>  src/remote_protocol-structs  |9 +
>  src/rpc/gendispatch.pl   |1 +
>  5 files changed, 29 insertions(+), 7 deletions(-)

Looks OK.

Jirka

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


Re: [libvirt] [PATCHv4 17/18] blockjob: enhance virsh 'blockcopy'

2012-04-13 Thread Jiri Denemark
On Mon, Apr 09, 2012 at 21:52:26 -0600, Eric Blake wrote:
> Expose the full abilities of virDomainBlockCopy.
> 
> * tools/virsh.c (blockJobImpl): Add --format option for block copy.
> * tools/virsh.pod (blockcopy): Document this.
> ---
>  tools/virsh.c   |   26 --
>  tools/virsh.pod |   10 +-
>  2 files changed, 25 insertions(+), 11 deletions(-)
> 
> diff --git a/tools/virsh.c b/tools/virsh.c
> index 25403f5..8669a8a 100644
> --- a/tools/virsh.c
> +++ b/tools/virsh.c
> @@ -7527,6 +7527,7 @@ blockJobImpl(vshControl *ctl, const vshCmd *cmd,
>  unsigned long bandwidth = 0;
>  int ret = -1;
>  const char *base = NULL;
> +const char *format = NULL;
>  unsigned int flags = 0;
> 
>  if (!vshConnectionUsability(ctl, ctl->conn))
> @@ -7566,16 +7567,28 @@ blockJobImpl(vshControl *ctl, const vshCmd *cmd,
>  ret = virDomainBlockPull(dom, path, bandwidth, 0);
>  break;
>  case VSH_CMD_BLOCK_JOB_COPY:
> -flags |= VIR_DOMAIN_BLOCK_REBASE_COPY;
>  if (vshCommandOptBool(cmd, "shallow"))
> -flags |= VIR_DOMAIN_BLOCK_REBASE_SHALLOW;
> +flags |= VIR_DOMAIN_BLOCK_COPY_SHALLOW;
>  if (vshCommandOptBool(cmd, "reuse-external"))
> -flags |= VIR_DOMAIN_BLOCK_REBASE_REUSE_EXT;
> -if (vshCommandOptBool(cmd, "raw"))
> -flags |= VIR_DOMAIN_BLOCK_REBASE_COPY_RAW;
> +flags |= VIR_DOMAIN_BLOCK_COPY_REUSE_EXT;
>  if (vshCommandOptString(cmd, "dest", &base) < 0)
>  goto cleanup;
> -ret = virDomainBlockRebase(dom, path, base, bandwidth, flags);
> +if (vshCommandOptString(cmd, "format", &format) < 0)
> +goto cleanup;
> +if (!format) {
> +if (vshCommandOptBool(cmd, "raw"))
> +flags |= VIR_DOMAIN_BLOCK_REBASE_COPY_RAW;
> +flags |= VIR_DOMAIN_BLOCK_REBASE_COPY;
> +ret = virDomainBlockRebase(dom, path, base, bandwidth, flags);
> +} else {
> +if (vshCommandOptBool(cmd, "raw")) {
> +vshError(ctl, "%s",
> + _("--raw and --format are mutually exclusive"));
> +goto cleanup;
> +}
> +ret = virDomainBlockCopy(dom, path, base, format,
> + bandwidth, flags);
> +}
>  }
> 
>  cleanup:
> @@ -7598,6 +7611,7 @@ static const vshCmdOptDef opts_block_copy[] = {
>  {"path", VSH_OT_DATA, VSH_OFLAG_REQ, N_("Fully-qualified path of disk")},
>  {"dest", VSH_OT_DATA, VSH_OFLAG_REQ, N_("path of the copy to create")},
>  {"bandwidth", VSH_OT_DATA, VSH_OFLAG_NONE, N_("Bandwidth limit in 
> MB/s")},
> +{"format", VSH_OT_DATA, VSH_OFLAG_NONE, N_("file format of dest")},
>  {"shallow", VSH_OT_BOOL, 0, N_("make the copy share a backing chain")},
>  {"reuse-external", VSH_OT_BOOL, 0, N_("reuse existing destination")},
>  {"raw", VSH_OT_BOOL, 0, N_("use raw destination file")},
> diff --git a/tools/virsh.pod b/tools/virsh.pod
> index ee84ce5..65e2429 100644
> --- a/tools/virsh.pod
> +++ b/tools/virsh.pod
> @@ -639,7 +639,7 @@ address of virtual interface (such as I 
> or
>  I) will accept the MAC address printed by this command.
> 
>  =item B I I I [I] [I<--shallow>]
> -[I<--reuse-external>] [I<--raw>]
> +[I<--reuse-external>] { [I<--raw>] | I }
> 
>  Copy a disk backing image chain to I. By default, this command
>  flattens the entire chain; but if I<--shallow> is specified, the copy
> @@ -652,10 +652,10 @@ is used, otherwise it must start empty); this option is 
> typically used
>  to set up a relative backing file name in the destination.
> 
>  The format of the destination is determined by the first match in the
> -following list: if I<--raw> is specified, it will be raw; if
> -I<--reuse-external> is specified, the existing destination is probed
> -for a format; and in all other cases, the destination format will
> -match the source format.
> +following list: if I<--raw> is specified, it will be raw; if I
> +is specified, it will have that format; if I<--reuse-external> is
> +specified, the existing destination is probed for a format; and in
> +all other cases, the destination format will match the source format.
> 
>  The copy runs in the background; initially, the job must copy all data
>  from the source, and during this phase, the job can only be canceled to

OK but this patch may be affected in case we decide to rename
virDomainBlockCopy.

Jirka

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


Re: [libvirt] [PATCHv4 16/18] blockjob: add virDomainBlockCopy

2012-04-13 Thread Jiri Denemark
On Mon, Apr 09, 2012 at 21:52:25 -0600, Eric Blake wrote:
> This new API provides additional flexibility over what can be
> crammed on top of virDomainBlockRebase (namely, the ability to
> specify an arbitrary destination format, for things like copying
> qcow2 into qed without having to pre-create the destination), at
> the expense that it cannot be backported without bumping the .so
> version.
> 
> * include/libvirt/libvirt.h.in (virDomainBlockCopy): New API.
> * src/libvirt.c (virDomainBlockCopy): Implement it.
> * src/libvirt_public.syms (LIBVIRT_0.9.12): Export it.
> * src/driver.h (virDrvDomainBlockCopy): New driver callback.
> * docs/apibuild.py (CParser.parseSignature): Add exception.
> ---
>  docs/apibuild.py |1 +
>  include/libvirt/libvirt.h.in |   18 ++-
>  src/driver.h |5 ++
>  src/libvirt.c|  119 
> +-
>  src/libvirt_public.syms  |5 ++
>  5 files changed, 145 insertions(+), 3 deletions(-)
> 
> diff --git a/docs/apibuild.py b/docs/apibuild.py
> index 1ac0281..bf06f3b 100755
> --- a/docs/apibuild.py
> +++ b/docs/apibuild.py
> @@ -1650,6 +1650,7 @@ class CParser:
>  "virDomainBlockJobSetSpeed"  : (False, ("bandwidth")),
>  "virDomainBlockPull" : (False, ("bandwidth")),
>  "virDomainBlockRebase"   : (False, ("bandwidth")),
> +"virDomainBlockCopy" : (False, ("bandwidth")),
>  "virDomainMigrateGetMaxSpeed": (False, ("bandwidth")) }
> 
>  def checkLongLegacyFunction(self, name, return_type, signature):
> diff --git a/include/libvirt/libvirt.h.in b/include/libvirt/libvirt.h.in
> index ac5df95..7cd5bbe 100644
> --- a/include/libvirt/libvirt.h.in
> +++ b/include/libvirt/libvirt.h.in
> @@ -1937,7 +1937,7 @@ int virDomainUpdateDeviceFlags(virDomainPtr domain,
>   * VIR_DOMAIN_BLOCK_JOB_TYPE_PULL: Block Pull (virDomainBlockPull, or
>   * virDomainBlockRebase without flags), job ends on completion
>   * VIR_DOMAIN_BLOCK_JOB_TYPE_COPY: Block Copy (virDomainBlockRebase with
> - * flags), job exists as long as mirroring is active
> + * flags, or virDomainBlockCopy), job exists as long as mirroring is active
>   */
>  typedef enum {
>  VIR_DOMAIN_BLOCK_JOB_TYPE_UNKNOWN = 0,
> @@ -2007,6 +2007,22 @@ int   virDomainBlockRebase(virDomainPtr dom, 
> const char *disk,
> const char *base, unsigned long bandwidth,
> unsigned int flags);
> 
> +/**
> + * virDomainBlockCopyFlags:
> + *
> + * Flags available for virDomainBlockCopy().
> + */
> +typedef enum {
> +VIR_DOMAIN_BLOCK_COPY_SHALLOW   = 1 << 0, /* Limit copy to top of source
> + backing chain */
> +VIR_DOMAIN_BLOCK_COPY_REUSE_EXT = 1 << 1, /* Reuse existing external
> + file for a copy */
> +} virDomainBlockCopyFlags;

Hmm, we have several flags enums that end up being passed to a single internal
API and one has to be extra careful when adding new flags. Should we make a
note about this to the affected enums?

> +
> +int virDomainBlockCopy(virDomainPtr dom, const char *disk,  const char *dest,
> +   const char *format, unsigned long bandwidth,
> +   unsigned int flags);
> +
> 
>  /* Block I/O throttling support */
> 
> diff --git a/src/driver.h b/src/driver.h
> index 03d249b..e10ba71 100644
> --- a/src/driver.h
> +++ b/src/driver.h
> @@ -788,6 +788,10 @@ typedef int
>  (*virDrvDomainBlockRebase)(virDomainPtr dom, const char *path,
> const char *base, unsigned long bandwidth,
> unsigned int flags);
> +typedef int
> +(*virDrvDomainBlockCopy)(virDomainPtr dom, const char *path,
> + const char *dest, const char *format,
> + unsigned long bandwidth, unsigned int flags);
> 
>  typedef int
>  (*virDrvSetKeepAlive)(virConnectPtr conn,
> @@ -1005,6 +1009,7 @@ struct _virDriver {
>  virDrvDomainBlockJobSetSpeed domainBlockJobSetSpeed;
>  virDrvDomainBlockPull domainBlockPull;
>  virDrvDomainBlockRebase domainBlockRebase;
> +virDrvDomainBlockCopy domainBlockCopy;
>  virDrvSetKeepAlive setKeepAlive;
>  virDrvConnectIsAlive isAlive;
>  virDrvNodeSuspendForDuration nodeSuspendForDuration;
> diff --git a/src/libvirt.c b/src/libvirt.c
> index 753a2e0..bdde654 100644
> --- a/src/libvirt.c
> +++ b/src/libvirt.c
> @@ -18263,7 +18263,11 @@ error:
>   * return an error if bandwidth is not 0.
>   *
>   * When @base is NULL and @flags is 0, this is identical to
> - * virDomainBlockPull().
> + * virDomainBlockPull().  Conversely, when @flags includes
> + * VIR_DOMAIN_BLOCK_REBASE_COPY, this is shorthand for
> + * virDomainBlockCopy(dom, disk, base,
> + * flags & VIR_DOMAIN_BLOCK_COPY_RAW ? "raw" : NULL, bandwidth,
> + * fl

Re: [libvirt] [PATCHv4 14/18] blockjob: allow mirroring under SELinux

2012-04-13 Thread Eric Blake
On 04/13/2012 03:15 PM, Jiri Denemark wrote:
>>> Is there a reason for calling virDomainLockDiskDetach only when 
>>> SetImageLabel
>>> fails and not calling it if mirroring itself fails?
>>
>> Simplicity of code - it's easier to code up permissions granting (and
>> leaking that) then it is to figure out which permissions need to be
>> reversed.  I'll attempt to do a better job in v5, at least when
>> mirroring fails.  But revoking permissions after 'drive-reopen' is a
>> bear - you can't do it immediately after the 'drive-reopen' command, but
> 
> But there's no drive-reopen involved here. We only issue drive-mirror command
> that starts the process. And if it fails, i.e., we don't even start copying
> data, we don't call virDomainLockDiskDetach to undo virDomainLockDiskAttach.
> It's possible we don't need to call that because the file is unlinked in the
> end, which is sufficient to remove the lock but I'm not sure and that's why
> I'm asking :-)

I'm not sure whether virDomainSnapshotCreateXML shares the same bug, or
whether when I converted things over to the 'transaction' command if I
got it fixed.  At any rate, you're right that I should at least clean up
this instance, since we know the failure path of drive-mirror is a lot
simpler than the success path of drive-reopen.

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



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

Re: [libvirt] [PATCHv4 14/18] blockjob: allow mirroring under SELinux

2012-04-13 Thread Jiri Denemark
On Fri, Apr 13, 2012 at 14:59:32 -0600, Eric Blake wrote:
> On 04/13/2012 02:45 PM, Jiri Denemark wrote:
> > On Mon, Apr 09, 2012 at 21:52:23 -0600, Eric Blake wrote:
> >> This copies heavily from qemuDomainSnapshotCreateSingleDiskActive(),
> >> in order to set the SELinux label, obtain locking manager lease, and
> >> audit the fact that we hand a new file over to qemu.  Alas, releasing
> >> the lease and label on failure or at the end of the mirroring is a
> >> trickier prospect.
> >>
> 
> >> +
> >> +if (virDomainLockDiskAttach(driver->lockManager, vm, disk) < 0)
> >> +goto endjob;
> >> +if (virSecurityManagerSetImageLabel(driver->securityManager, vm->def,
> >> +disk) < 0) {
> >> +if (virDomainLockDiskDetach(driver->lockManager, vm, disk) < 0)
> >> +VIR_WARN("Unable to release lock on %s", dest);
> >> +goto endjob;
> >> +}
> > 
> > Is there a reason for calling virDomainLockDiskDetach only when 
> > SetImageLabel
> > fails and not calling it if mirroring itself fails?
> 
> Simplicity of code - it's easier to code up permissions granting (and
> leaking that) then it is to figure out which permissions need to be
> reversed.  I'll attempt to do a better job in v5, at least when
> mirroring fails.  But revoking permissions after 'drive-reopen' is a
> bear - you can't do it immediately after the 'drive-reopen' command, but

But there's no drive-reopen involved here. We only issue drive-mirror command
that starts the process. And if it fails, i.e., we don't even start copying
data, we don't call virDomainLockDiskDetach to undo virDomainLockDiskAttach.
It's possible we don't need to call that because the file is unlinked in the
end, which is sufficient to remove the lock but I'm not sure and that's why
I'm asking :-)

Jirka

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


Re: [libvirt] [PATCH] util: only register callbacks for CREATE operations in virnetdevmacvlan.c

2012-04-13 Thread Laine Stump
On 04/13/2012 08:41 AM, D. Herrendoerfer wrote:
> From: "D. Herrendoerfer" 
>
> currently upon a migration a callback is created when a 802.1qbg link
> is set to PREASSOCIATE, this should not happen because this is
> a no-op on most switches, and does not lead to an ASSOCIATE state.
> This patch only creates callbacks when CREATE is requested.
> Migration and libvirtd restart scenarios are already handeled elsewhere.
>
> Signed-off-by: D. Herrendoerfer 
> ---
>  src/util/virnetdevmacvlan.c |7 +--
>  1 files changed, 5 insertions(+), 2 deletions(-)
>
> diff --git a/src/util/virnetdevmacvlan.c b/src/util/virnetdevmacvlan.c
> index 17ea883..73f41ff 100644
> --- a/src/util/virnetdevmacvlan.c
> +++ b/src/util/virnetdevmacvlan.c
> @@ -945,9 +945,12 @@ create_name:
>  goto disassociate_exit;
>  }
>  
> -if (virNetDevMacVLanVPortProfileRegisterCallback(cr_ifname, macaddress,
> - linkdev, vmuuid, virtPortProfile, 
> vmOp) < 0 )
> +if (vmOp == VIR_NETDEV_VPORT_PROFILE_OP_CREATE) {


I'm not sure this is going to work for all startup scenarios. For
example, What about when a guest is restarted
(qemuDomainSaveImageStartVM)? The call to qemuProcessStart sets the vmOp
to VIR_NETDEV_VPORT_PROFILE_OP_RESTORE, but I would assume that when a
guest is saved (implying that its memory image was written to disk and
the qemu process was terminated), the callback was cancelled (if not,
that's a bug. Note also that it's possible the host may be rebooted
while the guest isn't running, and the guest then resumed from its image
on disk).


> +/*Only directly register upon a create - migration and restart are 
> handled elsewhere*/
> +if (virNetDevMacVLanVPortProfileRegisterCallback(cr_ifname, 
> macaddress,
> + linkdev, vmuuid, 
> virtPortProfile, vmOp) < 0 )


A more minor point - I know that, due to the length of the function
name, it's impossible to make this all fit inside 80 columns while also
satisfying libvirt's indenting standards, but it would be nice to wrap
the comment at 80 columns (and put a space after the opening /* and
before the closing */).

>  goto disassociate_exit;
> +}
>  
>  return rc;
>  

I don't have the hardware to actually test this, but I would like to see
either a change that's been tested to show proper operation when a guest
goes through the "virsh save xxx xxx.save; virsh restore xxx.save" (or
"virsh managedsave xxx; virsh start xxx") cycle, or your acknowledgement
that such a sequence operates properly without any change.

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


Re: [libvirt] [PATCHv4 14/18] blockjob: allow mirroring under SELinux

2012-04-13 Thread Eric Blake
On 04/13/2012 02:45 PM, Jiri Denemark wrote:
> On Mon, Apr 09, 2012 at 21:52:23 -0600, Eric Blake wrote:
>> This copies heavily from qemuDomainSnapshotCreateSingleDiskActive(),
>> in order to set the SELinux label, obtain locking manager lease, and
>> audit the fact that we hand a new file over to qemu.  Alas, releasing
>> the lease and label on failure or at the end of the mirroring is a
>> trickier prospect.
>>

>> +
>> +if (virDomainLockDiskAttach(driver->lockManager, vm, disk) < 0)
>> +goto endjob;
>> +if (virSecurityManagerSetImageLabel(driver->securityManager, vm->def,
>> +disk) < 0) {
>> +if (virDomainLockDiskDetach(driver->lockManager, vm, disk) < 0)
>> +VIR_WARN("Unable to release lock on %s", dest);
>> +goto endjob;
>> +}
> 
> Is there a reason for calling virDomainLockDiskDetach only when SetImageLabel
> fails and not calling it if mirroring itself fails?

Simplicity of code - it's easier to code up permissions granting (and
leaking that) then it is to figure out which permissions need to be
reversed.  I'll attempt to do a better job in v5, at least when
mirroring fails.  But revoking permissions after 'drive-reopen' is a
bear - you can't do it immediately after the 'drive-reopen' command, but
have to wait until after the BLOCK_JOB_COMPLETED event before you know
that qemu no longer needs the file that you are about to revoke rights
on.  And if libvirtd restarts in between the 'drive-reopen' command and
the eventual event from qemu, then we have to store state in the XML to
remind ourselves to do 'query-block' and 'query-block-job' when
reconnecting to the domain to figure out what state qemu is still in.

In fact, Paolo just made a proposal to upstream qemu today that would
add another aspect into the cleanup arena:
https://lists.gnu.org/archive/html/qemu-devel/2012-04/msg01638.html
the idea there is that libvirt would be responsible for creating a local
file (under /var/lib/libvirt/qemu, alongside the domain XML), and qemu
writes one byte to the file when the drive-reopen actually alters state,
so that part of the libvirtd restart recovery process is to check
whether the file is empty (the reopen didn't happen) or has contents
(the reopen succeeded, start the cleanup work for any resources no
longer appropriate to qemu).  I'll have to figure out how much of that I
can interact with in my v5 series.

In short, I figured it was better to have code that could at least
demonstrate the API, even if it leaks, and work on plugging the leaks as
I have more time, than it was to wait for perfect code but miss out on
review and integration time.

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



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

Re: [libvirt] [PATCHv4 14/18] blockjob: allow mirroring under SELinux

2012-04-13 Thread Jiri Denemark
On Mon, Apr 09, 2012 at 21:52:23 -0600, Eric Blake wrote:
> This copies heavily from qemuDomainSnapshotCreateSingleDiskActive(),
> in order to set the SELinux label, obtain locking manager lease, and
> audit the fact that we hand a new file over to qemu.  Alas, releasing
> the lease and label on failure or at the end of the mirroring is a
> trickier prospect.
> 
> * src/qemu/qemu_driver.c (qemuDomainBlockCopy): Set up labeling.
> ---
>  src/qemu/qemu_driver.c |   63 
> +---
>  1 files changed, 54 insertions(+), 9 deletions(-)
> 
> diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c
> index 661ccb4..41f545f 100644
> --- a/src/qemu/qemu_driver.c
> +++ b/src/qemu/qemu_driver.c
> @@ -11895,6 +11895,11 @@ qemuDomainBlockCopy(virDomainPtr dom, const char 
> *path,
>  int ret = -1;
>  int idx;
>  struct stat st;
> +bool need_unlink = false;
> +char *mirror = NULL;
> +char *mirrorFormat = NULL;
> +char *origsrc = NULL;
> +char *origdriver = NULL;
> 
>  /* Preliminaries: find the disk we are editing, sanity checks */
>  virCheckFlags(VIR_DOMAIN_BLOCK_REBASE_SHALLOW |
> @@ -11976,29 +11981,69 @@ qemuDomainBlockCopy(virDomainPtr dom, const char 
> *path,
>  goto endjob;
>  }
> 
> -/* XXX We also need to add security labeling, lock manager lease,
> - * and auditing of those events.  */
> -if (!format && !(flags & VIR_DOMAIN_BLOCK_REBASE_REUSE_EXT))
> -format = disk->driverType;
> -if ((format && !(disk->mirrorFormat = strdup(format))) ||
> -!(disk->mirror = strdup(dest))) {
> +if (!(flags & VIR_DOMAIN_BLOCK_REBASE_REUSE_EXT)) {
> +int fd = qemuOpenFile(driver, dest, O_WRONLY | O_TRUNC | O_CREAT,
> +  &need_unlink, NULL);
> +if (fd < 0)
> +goto endjob;
> +VIR_FORCE_CLOSE(fd);
> +if (!format)
> +format = disk->driverType;
> +}
> +if ((format && !(mirrorFormat = strdup(format))) ||
> +!(mirror = strdup(dest))) {
>  virReportOOMError();
>  goto endjob;
>  }
> 
> +/* Manipulate disk in place, in a way that can be reverted on
> + * failure, in order to set up labeling and locking.  */
> +origsrc = disk->src;
> +disk->src = (char *) dest;
> +origdriver = disk->driverType;
> +disk->driverType = (char *) "raw"; /* Don't want to probe backing files 
> */
> +
> +if (virDomainLockDiskAttach(driver->lockManager, vm, disk) < 0)
> +goto endjob;
> +if (virSecurityManagerSetImageLabel(driver->securityManager, vm->def,
> +disk) < 0) {
> +if (virDomainLockDiskDetach(driver->lockManager, vm, disk) < 0)
> +VIR_WARN("Unable to release lock on %s", dest);
> +goto endjob;
> +}

Is there a reason for calling virDomainLockDiskDetach only when SetImageLabel
fails and not calling it if mirroring itself fails?

> +
> +disk->src = origsrc;
> +origsrc = NULL;
> +disk->driverType = origdriver;
> +origdriver = NULL;
> +
>  /* Actually start the mirroring */
>  qemuDomainObjEnterMonitorWithDriver(driver, vm);
>  ret = qemuMonitorDriveMirror(priv->mon, NULL, device, dest, format, 
> flags);
> +virDomainAuditDisk(vm, NULL, dest, "mirror", ret >= 0);
>  if (ret == 0 && bandwidth != 0)
>  ret = qemuMonitorBlockJob(priv->mon, device, NULL, bandwidth, NULL,
>BLOCK_JOB_SPEED_INTERNAL);
>  qemuDomainObjExitMonitorWithDriver(driver, vm);
> +if (ret < 0)
> +goto endjob;
> +
> +/* Update vm in place to match changes.  */
> +need_unlink = false;
> +disk->mirror = mirror;
> +disk->mirrorFormat = mirrorFormat;
> +mirror = NULL;
> +mirrorFormat = NULL;
> 
>  endjob:
> -if (ret < 0) {
> -VIR_FREE(disk->mirror);
> -VIR_FREE(disk->mirrorFormat);
> +if (origsrc) {
> +disk->src = origsrc;
> +disk->driverType = origdriver;
>  }
> +if (need_unlink && unlink(dest))
> +VIR_WARN("unable to unlink just-created %s", dest);
> +VIR_FREE(mirror);
> +VIR_FREE(mirrorFormat);
>  if (qemuDomainObjEndJob(driver, vm) == 0) {
>  vm = NULL;
>  goto cleanup;

Jirka

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


Re: [libvirt] [PATCHv4 13/18] blockjob: allow for existing files

2012-04-13 Thread Jiri Denemark
On Mon, Apr 09, 2012 at 21:52:22 -0600, Eric Blake wrote:
> This copies some of the checks from snapshots regarding testing
> when a file already exists.  In the process, I noticed a missing
> sanity check in snapshots: REUSE_EXT should require the destination
> to already be present.
> 
> * src/qemu/qemu_driver.c (qemuDomainBlockRebase): Allow REUSE_EXT
> flag.
> (qemuDomainBlockCopy): Wire up flag, and add some sanity checks.
> (qemuDomainSnapshotDiskPrepare): Require destination on REUSE_EXT.
> ---
>  src/qemu/qemu_driver.c |   48 
> +++-
>  1 files changed, 43 insertions(+), 5 deletions(-)
> 
> diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c
> index 6d5a5da..661ccb4 100644
> --- a/src/qemu/qemu_driver.c
> +++ b/src/qemu/qemu_driver.c
> @@ -9812,6 +9812,11 @@ qemuDomainSnapshotDiskPrepare(virDomainObjPtr vm, 
> virDomainSnapshotDefPtr def,
>   _("unable to stat for disk %s: %s"),
>   disk->name, disk->file);
>  goto cleanup;
> +} else if (allow_reuse) {
> +virReportSystemError(errno,
> + _("missing existing file for disk 
> %s: %s"),
> + disk->name, disk->file);
> +goto cleanup;
>  }
>  } else if (!(S_ISBLK(st.st_mode) || !st.st_size || allow_reuse)) 
> {
>  qemuReportError(VIR_ERR_CONFIG_UNSUPPORTED,
> @@ -11889,9 +11894,11 @@ qemuDomainBlockCopy(virDomainPtr dom, const char 
> *path,
>  virDomainDiskDefPtr disk;
>  int ret = -1;
>  int idx;
> +struct stat st;
> 
>  /* Preliminaries: find the disk we are editing, sanity checks */
> -virCheckFlags(VIR_DOMAIN_BLOCK_REBASE_SHALLOW, -1);
> +virCheckFlags(VIR_DOMAIN_BLOCK_REBASE_SHALLOW |
> +  VIR_DOMAIN_BLOCK_REBASE_REUSE_EXT, -1);
> 
>  qemuDriverLock(driver);
>  virUUIDFormat(dom->uuid, uuidstr);
> @@ -11936,12 +11943,42 @@ qemuDomainBlockCopy(virDomainPtr dom, const char 
> *path,
>  goto endjob;
>  }
> 
> +/* XXX this is pessimistic; we could use 'query-block' or even
> + * keep track of the backing chain ourselves, rather than assuming
> + * that all non-raw source files have a current backing image */
> +if ((flags & VIR_DOMAIN_BLOCK_REBASE_SHALLOW) &&
> +STREQ_NULLABLE(format, "raw") &&
> +STRNEQ_NULLABLE(disk->driverType, "raw")) {
> +qemuReportError(VIR_ERR_INVALID_ARG,
> +_("raw shallow copy of non-raw disk '%s' not 
> possible"),
> +disk->dst);
> +goto endjob;
> +}
> +
>  /* Prepare the destination file.  */
> +if (stat(dest, &st) < 0) {
> +if (errno != ENOENT) {
> +virReportSystemError(errno, _("unable to stat for disk %s: %s"),
> + disk->dst, dest);
> +goto endjob;
> +} else if (flags & VIR_DOMAIN_BLOCK_REBASE_REUSE_EXT) {
> +virReportSystemError(errno,
> + _("missing destination file for disk %s: 
> %s"),
> + disk->dst, dest);
> +goto endjob;
> +}
> +} else if (!(S_ISBLK(st.st_mode) || !st.st_size ||
> + (flags & VIR_DOMAIN_BLOCK_REBASE_REUSE_EXT))) {

Eh, this is quite hard to parse, I'd move the negation inside;

  if (!S_ISBLK(st.st_mode) && st.st_size &&
  !(flags & VIR_DOMAIN_BLOCK_REBASE_REUSE_EXT))

> +qemuReportError(VIR_ERR_CONFIG_UNSUPPORTED,
> +_("external destination file for disk %s already "
> +  "exists and is not a block device: %s"),
> +disk->dst, dest);
> +goto endjob;
> +}
> +
>  /* XXX We also need to add security labeling, lock manager lease,
> - * and auditing of those events, as well as to support reuse of
> - * existing images, including probing the existing format of an
> - * existing image.  */
> -if (!format)
> + * and auditing of those events.  */
> +if (!format && !(flags & VIR_DOMAIN_BLOCK_REBASE_REUSE_EXT))
>  format = disk->driverType;
>  if ((format && !(disk->mirrorFormat = strdup(format))) ||
>  !(disk->mirror = strdup(dest))) {
> @@ -11980,6 +12017,7 @@ qemuDomainBlockRebase(virDomainPtr dom, const char 
> *path, const char *base,
>unsigned long bandwidth, unsigned int flags)
>  {
>  virCheckFlags(VIR_DOMAIN_BLOCK_REBASE_SHALLOW |
> +  VIR_DOMAIN_BLOCK_REBASE_REUSE_EXT |
>VIR_DOMAIN_BLOCK_REBASE_COPY |
>VIR_DOMAIN_BLOCK_REBASE_COPY_RAW, -1);
> 

OK

Jirka

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


Re: [libvirt] Start of freeze for libvirt-0.9.11 and availability of rc1

2012-04-13 Thread Guido Günther
On Fri, Apr 13, 2012 at 03:52:46PM +0200, Philipp Hahn wrote:
> Hello Guido,
> 
> Am Freitag 13 April 2012 15:10:49 schrieb Guido Günther:
> > könntest Du das als richtigen Patch schicken, dann apply ich das.
> [Guido asks me to send a full patch, so he can apply it.]
> 
> Sure, see the attached patch.
Pushed. Thanks!
 -- Guido

> 
> Sincerely
> Philipp
> -- 
> Philipp Hahn   Open Source Software Engineer  h...@univention.de
> Univention GmbHbe open.   fon: +49 421 22 232- 0
> Mary-Somerville-Str.1  D-28359 Bremen fax: +49 421 22 232-99
>http://www.univention.de/

> From 800a2689ea22842abebdff8568f105ca28dfad15 Mon Sep 17 00:00:00 2001
> From: Philipp Hahn 
> Date: Fri, 13 Apr 2012 15:43:58 +0200
> Subject: [PATCH] virnetdev: Check for defined IFLA_VF_*
> To: libvir-list@redhat.com
> 
> The linux-2.6.32 kernel header does not yet define IFLA_VF_MAX and others,
> which breaks compiling a new libvirt on old systems like Debian Squeeze.
> 
> (I also have to add --without-macvtap --disable-werror --without-virtualport 
> to
>  ./configure to get it to compile.)
> 
> Signed-off-by: Philipp Hahn 
> ---
>  src/util/virnetdev.c |2 +-
>  1 files changed, 1 insertions(+), 1 deletions(-)
> 
> diff --git a/src/util/virnetdev.c b/src/util/virnetdev.c
> index ec7435a..460aa83 100644
> --- a/src/util/virnetdev.c
> +++ b/src/util/virnetdev.c
> @@ -1215,7 +1215,7 @@ virNetDevGetVirtualFunctionInfo(const char *vfname 
> ATTRIBUTE_UNUSED,
>  return -1;
>  }
>  #endif /* !__linux__ */
> -#if defined(__linux__) && defined(HAVE_LIBNL)
> +#if defined(__linux__) && defined(HAVE_LIBNL) && defined(IFLA_VF_MAX)
>  
>  static struct nla_policy ifla_vf_policy[IFLA_VF_MAX+1] = {
>  [IFLA_VF_MAC]   = { .type = NLA_UNSPEC,
> -- 
> 1.7.2.5
> 



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


Re: [libvirt] VN-Link vNIC memory state copying on VM Migration

2012-04-13 Thread Christian Benvenuti (benve)
Jagath,
  what memory state do you refer to exactly?

If you refer to port profile info, then there is no copying involved:
  the source host disassociates the vnic port profile and
  the destination host re-associates the port profile on the new vnic.

/Chris

> -Original Message-
> From: libvir-list-boun...@redhat.com
[mailto:libvir-list-boun...@redhat.com] On Behalf Of Jagath
> Weerasinghe
> Sent: Friday, April 13, 2012 9:16 AM
> To: libvir-list@redhat.com
> Subject: [libvirt] VN-Link vNIC memory state copying on VM Migration
> 
> Hi All,
> 
> I am new to libvirt. And want to know how the VM migration
> occurs in VN-Link (IEEE802.1Qbh). As far as I know,
> the memory state of vNICs in M81KR VIC has to be copied
> and moved to the destination vNIC on VM migration.
> Is that correct? If so, could you please tell me how this
> has been implemented in libvirt?
> 
> Thanks
> Jagath
> 
> --
> libvir-list mailing list
> libvir-list@redhat.com
> https://www.redhat.com/mailman/listinfo/libvir-list

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


[libvirt] [PATCH 0/9] Add basic driver for Parallels Virtuozzo Server

2012-04-13 Thread Dmitry Guryanov
Parallels Virtuozzo Server is a cloud-ready virtualization
solution that allows users to simultaneously run multiple virtual
machines and containers on the same physical server.

Current name of this product is Parallels Server Bare Metal and
more information about it can be found here -
http://www.parallels.com/products/server/baremetal/sp/.

This driver will work with PVS version 6.0 , beta version
scheduled at 2012 Q2.

Dmitry Guryanov (9):
  pvs: add driver skeleton
  util: add functions for interating over json object
  pvs: add functions to list domains and get info
  pvs: implement functions for domain life cycle management
  pvs: get info about serial ports
  pvs: add support of VNC remote display
  pvs: implement virDomainDefineXML operation for existing domains
  pvs: add storage driver
  pvs: implement VM creation

 cfg.mk  |1 +
 configure.ac|   20 +
 docs/drvpvs.html.in |   28 +
 include/libvirt/virterror.h |1 +
 libvirt.spec.in |7 +
 mingw32-libvirt.spec.in |6 +
 po/POTFILES.in  |1 +
 src/Makefile.am |   23 +
 src/conf/domain_conf.c  |3 +-
 src/conf/domain_conf.h  |1 +
 src/driver.h|1 +
 src/libvirt.c   |   12 +
 src/pvs/pvs_driver.c| 1259 +
 src/pvs/pvs_driver.h|   76 +++
 src/pvs/pvs_storage.c   | 1460 +++
 src/pvs/pvs_utils.c |  139 
 src/util/json.c |   30 +
 src/util/json.h |4 +
 src/util/virterror.c|3 +
 19 files changed, 3074 insertions(+), 1 deletions(-)
 create mode 100644 docs/drvpvs.html.in
 create mode 100644 src/pvs/pvs_driver.c
 create mode 100644 src/pvs/pvs_driver.h
 create mode 100644 src/pvs/pvs_storage.c
 create mode 100644 src/pvs/pvs_utils.c

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


[libvirt] [PATCH 9/9] pvs: implement VM creation

2012-04-13 Thread Dmitry Guryanov
To create a new VM in PVS we should issue "prlctl create" command,
and give path to the directory, where VM should be created. VM's
storage will be in that directory later. So in this first version
find out location of first VM's hard disk and create VM there.

Signed-off-by: Dmitry Guryanov 
---
 src/pvs/pvs_driver.c  |   77 -
 src/pvs/pvs_driver.h  |4 ++
 src/pvs/pvs_storage.c |6 +---
 3 files changed, 81 insertions(+), 6 deletions(-)

diff --git a/src/pvs/pvs_driver.c b/src/pvs/pvs_driver.c
index 5e9b691..7a072bf 100644
--- a/src/pvs/pvs_driver.c
+++ b/src/pvs/pvs_driver.c
@@ -1077,6 +1077,73 @@ pvsApplyChanges(virDomainObjPtr dom, virDomainDefPtr 
newdef)
 return 0;
 }
 
+static int
+pvsCreateVm(virConnectPtr conn, virDomainDefPtr def)
+{
+pvsConnPtr privconn = conn->privateData;
+int i;
+virStorageVolDefPtr privvol = NULL;
+virStoragePoolObjPtr pool = NULL;
+virStorageVolPtr vol = NULL;
+   char uuidstr[VIR_UUID_STRING_BUFLEN];
+
+for (i = 0; i < def->ndisks; i++) {
+if (def->disks[i]->device != VIR_DOMAIN_DISK_DEVICE_DISK)
+continue;
+
+vol = pvsStorageVolumeLookupByPathLocked(conn, def->disks[i]->src);
+if (!vol) {
+pvsError(VIR_ERR_INVALID_ARG,
+ _("Can't find volume with path '%s'"),
+ def->disks[i]->src);
+return -1;
+}
+break;
+}
+
+if (!vol) {
+pvsError(VIR_ERR_INVALID_ARG,
+ _("Can't create VM without hard disks"));
+return -1;
+}
+
+pool = virStoragePoolObjFindByName(&privconn->pools, vol->pool);
+if (!pool) {
+pvsError(VIR_ERR_INVALID_ARG,
+ _("Can't find storage pool with name '%s'"),
+ vol->pool);
+goto error;
+}
+
+privvol = virStorageVolDefFindByPath(pool, def->disks[i]->src);
+if (!privvol) {
+pvsError(VIR_ERR_INVALID_ARG,
+ _("Can't find storage volume definition for path '%s'"),
+ def->disks[i]->src);
+goto error2;
+}
+
+   virUUIDFormat(def->uuid, uuidstr);
+
+if (pvsCmdRun(PRLCTL, "create", def->name, "--dst",
+  pool->def->target.path, "--no-hdd", "--uuid", uuidstr, NULL))
+goto error2;
+
+if (pvsCmdRun(PRLCTL, "set", def->name, "--vnc-mode", "auto", NULL))
+goto error2;
+
+virStoragePoolObjUnlock(pool);
+virUnrefStorageVol(vol);
+
+return 0;
+
+  error2:
+virStoragePoolObjUnlock(pool);
+  error:
+virUnrefStorageVol(vol);
+return -1;
+}
+
 static virDomainPtr
 pvsDomainDefineXML(virConnectPtr conn, const char *xml)
 {
@@ -1113,8 +1180,16 @@ pvsDomainDefineXML(virConnectPtr conn, const char *xml)
 
 def = NULL;
 } else {
-pvsError(VIR_ERR_NO_SUPPORT, _("Not implemented yet"));
+if (pvsCreateVm(conn, def))
 goto cleanup;
+if (pvsLoadDomains(privconn, def->name))
+goto cleanup;
+dom = virDomainFindByName(&privconn->domains, def->name);
+if (!dom) {
+pvsError(VIR_ERR_INTERNAL_ERROR,
+ _("Domain is not defined after creation"));
+goto cleanup;
+}
 }
 
 event = virDomainEventNewFromObj(dom,
diff --git a/src/pvs/pvs_driver.h b/src/pvs/pvs_driver.h
index 7384eb1..1d502f3 100644
--- a/src/pvs/pvs_driver.h
+++ b/src/pvs/pvs_driver.h
@@ -68,5 +68,9 @@ int pvsCmdRun(const char *binary, ...);
 char * pvsAddFileExt(const char *path, const char *ext);
 void pvsDriverLock(pvsConnPtr driver);
 void pvsDriverUnlock(pvsConnPtr driver);
+virStorageVolPtr pvsStorageVolumeLookupByPathLocked(virConnectPtr
+   conn,
+   const char
+   *path);
 
 #endif
diff --git a/src/pvs/pvs_storage.c b/src/pvs/pvs_storage.c
index 95f1fde..c177ef3 100644
--- a/src/pvs/pvs_storage.c
+++ b/src/pvs/pvs_storage.c
@@ -41,10 +41,6 @@ static virStorageVolDefPtr 
pvsStorageVolumeDefine(virStoragePoolObjPtr pool,
   const char *xmldesc,
   const char *xmlfile,
   bool is_new);
-static virStorageVolPtr pvsStorageVolumeLookupByPathLocked(virConnectPtr
-   conn,
-   const char
-   *path);
 static virStorageVolPtr pvsStorageVolumeLookupByPath(virConnectPtr conn,
  const char *path);
 static int pvsStoragePoolGetAlloc(virStoragePoolDefPtr def);
@@ -941,7 +937,7 @@ pvsStorageVolumeLookupByKey(virConnectPtr conn, const char 
*key)
 return ret;
 }
 

[libvirt] [PATCH 6/9] pvs: add support of VNC remote display

2012-04-13 Thread Dmitry Guryanov

Signed-off-by: Dmitry Guryanov 
---
 src/pvs/pvs_driver.c |   65 ++
 1 files changed, 65 insertions(+), 0 deletions(-)

diff --git a/src/pvs/pvs_driver.c b/src/pvs/pvs_driver.c
index 7f59e3b..20243eb 100644
--- a/src/pvs/pvs_driver.c
+++ b/src/pvs/pvs_driver.c
@@ -258,6 +258,68 @@ pvsAddDomainHardware(virDomainObjPtr dom, virJSONValuePtr 
jobj)
 return -1;
 }
 
+static int
+pvsAddVNCInfo(virDomainObjPtr dom, virJSONValuePtr jobj_root)
+{
+const char *tmp;
+unsigned int port;
+virJSONValuePtr jobj;
+int ret = -1;
+
+virDomainDefPtr def = dom->def;
+
+virDomainGraphicsDefPtr gr = NULL;
+
+jobj = virJSONValueObjectGet(jobj_root, "Remote display");
+if (!jobj) {
+pvsParseError();
+goto cleanup;
+}
+
+tmp = virJSONValueObjectGetString(jobj, "mode");
+if (!tmp) {
+pvsParseError();
+goto cleanup;
+}
+
+if (STREQ(tmp, "off")) {
+ret = 0;
+goto cleanup;
+}
+
+if (VIR_ALLOC(gr) < 0)
+goto no_memory;
+
+if (virJSONValueObjectGetNumberUint(jobj, "port", &port) < 0) {
+pvsParseError();
+goto cleanup;
+}
+
+/* TODO: handle non-auto vnc mode */
+gr->type = VIR_DOMAIN_GRAPHICS_TYPE_VNC;
+gr->data.vnc.port = port;
+gr->data.vnc.autoport = 0;
+gr->data.vnc.keymap = NULL;
+gr->data.vnc.socket = NULL;
+gr->data.vnc.auth.passwd = NULL;
+gr->data.vnc.auth.expires = 0;
+gr->data.vnc.auth.connected = 0;
+
+if (VIR_REALLOC_N(def->graphics, def->ngraphics + 1) < 0) {
+virDomainGraphicsDefFree(gr);
+goto no_memory;
+}
+
+def->graphics[def->ngraphics++] = gr;
+return 0;
+
+  no_memory:
+virReportOOMError();
+  cleanup:
+VIR_FREE(gr);
+return ret;
+}
+
 /*
  * Must be called with privconn->lock held
  */
@@ -397,6 +459,9 @@ pvsLoadDomain(pvsConnPtr privconn, virJSONValuePtr jobj)
 if (pvsAddDomainHardware(dom, jobj2))
 goto cleanup_unlock;
 
+if (pvsAddVNCInfo(dom, jobj))
+goto cleanup_unlock;
+
 virDomainObjUnlock(dom);
 
 return dom;
-- 
1.7.1

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


[libvirt] [PATCH 8/9] pvs: add storage driver

2012-04-13 Thread Dmitry Guryanov
PVS has one serious discrepancy with libvirt: libvirt stores
domain configuration files always in one place, and storage files
in other places (with API of storage pools and storage volumes).
PVS store all domain data in a single directory, for example, you
may have domain with name fedora-15, which will be located in
'/var/parallels/fedora-15.pvm', and it's hard disk image will be
in '/var/parallels/fedora-15.pvm/harddisk1.hdd'.

I've decided to create storage driver, which produces pseudo-volumes
(xml files with volume description), and they will be 'converted' to
real disk images after attaching to a VM.

So if someone creates VM with one hard disk using virt-manager,
at first virt-manager creates a new volume, and then defines a
domain. We can lookup a volume by path in XML domain definition
and find out location of new domain and size of its hard disk.

This code mostly duplicates code in libvirt's default storage
driver, but I haven't found, how functions from that driver can
be reused. So if it possible I'll be very grateful for the advice,
how to do it.

Signed-off-by: Dmitry Guryanov 
---
 src/Makefile.am   |3 +-
 src/pvs/pvs_driver.c  |6 +-
 src/pvs/pvs_driver.h  |5 +
 src/pvs/pvs_storage.c | 1464 +
 src/pvs/pvs_utils.c   |   20 +
 5 files changed, 1495 insertions(+), 3 deletions(-)
 create mode 100644 src/pvs/pvs_storage.c

diff --git a/src/Makefile.am b/src/Makefile.am
index bc9efcf..0765aaf 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -468,7 +468,8 @@ HYPERV_DRIVER_EXTRA_DIST =  
\
 PVS_DRIVER_SOURCES =   
\
pvs/pvs_driver.h
\
pvs/pvs_driver.c
\
-   pvs/pvs_utils.c
+   pvs/pvs_utils.c 
\
+   pvs/pvs_storage.c
 
 NETWORK_DRIVER_SOURCES =   \
network/bridge_driver.h network/bridge_driver.c
diff --git a/src/pvs/pvs_driver.c b/src/pvs/pvs_driver.c
index ceca50d..5e9b691 100644
--- a/src/pvs/pvs_driver.c
+++ b/src/pvs/pvs_driver.c
@@ -66,13 +66,13 @@ int pvsStart(virDomainObjPtr privdom);
 int pvsKill(virDomainObjPtr privdom);
 int pvsStop(virDomainObjPtr privdom);
 
-static void
+void
 pvsDriverLock(pvsConnPtr driver)
 {
 virMutexLock(&driver->lock);
 }
 
-static void
+void
 pvsDriverUnlock(pvsConnPtr driver)
 {
 virMutexUnlock(&driver->lock);
@@ -1177,6 +1177,8 @@ pvsRegister(void)
 {
 if (virRegisterDriver(&pvsDriver) < 0)
 return -1;
+if (pvsStorageRegister())
+return -1;
 
 return 0;
 }
diff --git a/src/pvs/pvs_driver.h b/src/pvs/pvs_driver.h
index d3cbca2..7384eb1 100644
--- a/src/pvs/pvs_driver.h
+++ b/src/pvs/pvs_driver.h
@@ -27,6 +27,7 @@
 
 #include "domain_conf.h"
 #include "storage_conf.h"
+#include "driver.h"
 #include "domain_event.h"
 
 #define PRLCTL  "prlctl"
@@ -60,8 +61,12 @@ typedef struct _pvsConn pvsConn;
 typedef struct _pvsConn *pvsConnPtr;
 
 int pvsRegister(void);
+int pvsStorageRegister(void);
 
 virJSONValuePtr pvsParseOutput(const char *binary, ...);
 int pvsCmdRun(const char *binary, ...);
+char * pvsAddFileExt(const char *path, const char *ext);
+void pvsDriverLock(pvsConnPtr driver);
+void pvsDriverUnlock(pvsConnPtr driver);
 
 #endif
diff --git a/src/pvs/pvs_storage.c b/src/pvs/pvs_storage.c
new file mode 100644
index 000..95f1fde
--- /dev/null
+++ b/src/pvs/pvs_storage.c
@@ -0,0 +1,1464 @@
+/*
+ * pvs_storage.c: core driver functions for managing
+ * Parallels Virtuozzo Server hosts
+ *
+ * Copyright (C) 2012 Parallels, 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, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307  USA
+ *
+ */
+
+#include 
+
+#include 
+#include 
+#include 
+
+#include "datatypes.h"
+#include "memory.h"
+#include "configmake.h"
+#include "storage_file.h"
+#include "virterror_internal.h"
+
+#include "pvs_driver.h"
+
+#define VIR_FROM_THIS VIR_FROM_PVS
+
+static int pvsStorageClose(virConnectPtr conn);
+static virStorageVolDefPtr pvsStorageVolumeDefine(virStoragePoolObjPtr pool,
+  c

[libvirt] [PATCH 3/9] pvs: add functions to list domains and get info

2012-04-13 Thread Dmitry Guryanov
PVS driver is 'stateless', like vmware or openvz drivers.
It collects information about domains during startup using
command-line utility prlctl. VMs in PVS identified by UUIDs
or unique names, which can be used as respective fields in
virDomainDef structure. Currently only basic info, like
description, virtual cpus number and memory amount implemented.
Quering devices information will be added in the next patches.

PVS does't support non-persistent domains - you can't run
a domain having only disk image, it must always be registered
in system.

Functions for quering domain info have been just copied from
test driver with some changes - they extract needed data from
previouly created list of virDomainObj objects.

Signed-off-by: Dmitry Guryanov 
---
 src/Makefile.am  |3 +-
 src/pvs/pvs_driver.c |  504 +-
 src/pvs/pvs_driver.h |   17 ++
 src/pvs/pvs_utils.c  |  101 ++
 4 files changed, 623 insertions(+), 2 deletions(-)
 create mode 100644 src/pvs/pvs_utils.c

diff --git a/src/Makefile.am b/src/Makefile.am
index 3cbd385..bc9efcf 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -467,7 +467,8 @@ HYPERV_DRIVER_EXTRA_DIST =  
\
 
 PVS_DRIVER_SOURCES =   
\
pvs/pvs_driver.h
\
-   pvs/pvs_driver.c
+   pvs/pvs_driver.c
\
+   pvs/pvs_utils.c
 
 NETWORK_DRIVER_SOURCES =   \
network/bridge_driver.h network/bridge_driver.c
diff --git a/src/pvs/pvs_driver.c b/src/pvs/pvs_driver.c
index 33bfa21..c854664 100644
--- a/src/pvs/pvs_driver.c
+++ b/src/pvs/pvs_driver.c
@@ -51,12 +51,13 @@
 #include "configmake.h"
 #include "storage_file.h"
 #include "nodeinfo.h"
-#include "json.h"
+#include "domain_conf.h"
 
 #include "pvs_driver.h"
 
 #define VIR_FROM_THIS VIR_FROM_PVS
 
+void pvsFreeDomObj(void *p);
 static virCapsPtr pvsBuildCapabilities(void);
 static int pvsClose(virConnectPtr conn);
 
@@ -78,6 +79,14 @@ pvsDefaultConsoleType(const char *ostype ATTRIBUTE_UNUSED)
 return VIR_DOMAIN_CHR_CONSOLE_TARGET_TYPE_SERIAL;
 }
 
+void
+pvsFreeDomObj(void *p)
+{
+pvsDomObjPtr pdom = (pvsDomObjPtr) p;
+
+VIR_FREE(pdom);
+};
+
 static virCapsPtr
 pvsBuildCapabilities(void)
 {
@@ -126,6 +135,206 @@ pvsGetCapabilities(virConnectPtr conn)
 return xml;
 }
 
+/*
+ * Must be called with privconn->lock held
+ */
+static virDomainObjPtr
+pvsLoadDomain(pvsConnPtr privconn, virJSONValuePtr jobj)
+{
+virDomainObjPtr dom = NULL;
+virDomainDefPtr def = NULL;
+pvsDomObjPtr pdom = NULL;
+virJSONValuePtr jobj2, jobj3;
+const char *tmp;
+unsigned int x;
+
+if (VIR_ALLOC(def) < 0)
+goto cleanup;
+
+def->virtType = VIR_DOMAIN_VIRT_PVS;
+def->id = -1;
+
+tmp = virJSONValueObjectGetString(jobj, "Name");
+if (!tmp) {
+pvsParseError();
+goto cleanup;
+}
+if (!(def->name = strdup(tmp)))
+goto no_memory;
+
+tmp = virJSONValueObjectGetString(jobj, "ID");
+if (!tmp) {
+pvsParseError();
+goto cleanup;
+}
+
+if (virUUIDParse(tmp, def->uuid) == -1) {
+pvsError(VIR_ERR_INTERNAL_ERROR, "%s",
+ _("UUID in config file malformed"));
+goto cleanup;
+}
+
+tmp = virJSONValueObjectGetString(jobj, "Description");
+if (!tmp) {
+pvsParseError();
+goto cleanup;
+}
+if (!(def->description = strdup(tmp)))
+goto no_memory;
+
+jobj2 = virJSONValueObjectGet(jobj, "Hardware");
+if (!jobj2) {
+pvsParseError();
+goto cleanup;
+}
+
+jobj3 = virJSONValueObjectGet(jobj2, "cpu");
+if (!jobj3) {
+pvsParseError();
+goto cleanup;
+}
+
+if (virJSONValueObjectGetNumberUint(jobj3, "cpus", &x) < 0) {
+pvsParseError();
+goto cleanup;
+}
+def->vcpus = x;
+def->maxvcpus = x;
+
+jobj3 = virJSONValueObjectGet(jobj2, "memory");
+if (!jobj3) {
+pvsParseError();
+goto cleanup;
+}
+
+tmp = virJSONValueObjectGetString(jobj3, "size");
+
+def->mem.max_balloon = atoi(tmp);
+def->mem.max_balloon <<= 10;
+def->mem.cur_balloon = def->mem.max_balloon;
+
+if (!(def->os.type = strdup("hvm")))
+goto no_memory;
+
+if (!(def->os.init = strdup("/sbin/init")))
+goto no_memory;
+
+if (!(dom = virDomainAssignDef(privconn->caps,
+   &privconn->domains, def, false)))
+goto cleanup;
+/* dom is locked here */
+
+if (VIR_ALLOC(pdom))
+goto no_memory_unlock;
+dom->privateDataFreeFunc = pvsFreeDomObj;
+dom->privateData = pdom;
+
+if (virJSONValueObjectGetNumberUint(jobj, "EnvID", &x) < 0)
+goto cleanup_unlock;
+pdom->id = x;

[libvirt] [PATCH 4/9] pvs: implement functions for domain life cycle management

2012-04-13 Thread Dmitry Guryanov

Signed-off-by: Dmitry Guryanov 
---
 src/pvs/pvs_driver.c |  148 ++
 src/pvs/pvs_driver.h |1 +
 src/pvs/pvs_utils.c  |   18 ++
 3 files changed, 167 insertions(+), 0 deletions(-)

diff --git a/src/pvs/pvs_driver.c b/src/pvs/pvs_driver.c
index c854664..b0c9a20 100644
--- a/src/pvs/pvs_driver.c
+++ b/src/pvs/pvs_driver.c
@@ -60,6 +60,11 @@
 void pvsFreeDomObj(void *p);
 static virCapsPtr pvsBuildCapabilities(void);
 static int pvsClose(virConnectPtr conn);
+int pvsPause(virDomainObjPtr privdom);
+int pvsResume(virDomainObjPtr privdom);
+int pvsStart(virDomainObjPtr privdom);
+int pvsKill(virDomainObjPtr privdom);
+int pvsStop(virDomainObjPtr privdom);
 
 static void
 pvsDriverLock(pvsConnPtr driver)
@@ -87,6 +92,12 @@ pvsFreeDomObj(void *p)
 VIR_FREE(pdom);
 };
 
+static void
+pvsDomainEventQueue(pvsConnPtr driver, virDomainEventPtr event)
+{
+virDomainEventStateQueue(driver->domainEventState, event);
+}
+
 static virCapsPtr
 pvsBuildCapabilities(void)
 {
@@ -726,6 +737,138 @@ pvsDomainGetAutostart(virDomainPtr domain, int *autostart)
 return ret;
 }
 
+typedef int (*pvsChangeState)(virDomainObjPtr privdom);
+#define PVS_UUID(x) (((pvsDomObjPtr)(x->privateData))->uuid)
+
+static int
+pvsDomainChangeState(virDomainPtr domain,
+ virDomainState req_state, const char * req_state_name,
+ pvsChangeState chstate,
+ virDomainState new_state, int reason,
+ int event_type, int event_detail)
+{
+pvsConnPtr privconn = domain->conn->privateData;
+virDomainObjPtr privdom;
+virDomainEventPtr event = NULL;
+int state;
+int ret = -1;
+
+pvsDriverLock(privconn);
+privdom = virDomainFindByName(&privconn->domains, domain->name);
+pvsDriverUnlock(privconn);
+
+if (privdom == NULL) {
+pvsError(VIR_ERR_INVALID_ARG, __FUNCTION__);
+goto cleanup;
+}
+
+state = virDomainObjGetState(privdom, NULL);
+if (state != req_state) {
+pvsError(VIR_ERR_INTERNAL_ERROR, _("domain '%s' not %s"),
+ privdom->def->name, req_state_name);
+goto cleanup;
+}
+
+if (chstate(privdom))
+goto cleanup;
+
+virDomainObjSetState(privdom, new_state, reason);
+
+event = virDomainEventNewFromObj(privdom, event_type, event_detail);
+ret = 0;
+
+  cleanup:
+if (privdom)
+virDomainObjUnlock(privdom);
+
+if (event) {
+pvsDriverLock(privconn);
+pvsDomainEventQueue(privconn, event);
+pvsDriverUnlock(privconn);
+}
+return ret;
+}
+
+int pvsPause(virDomainObjPtr privdom)
+{
+return pvsCmdRun(PRLCTL, "pause", PVS_UUID(privdom), NULL);
+}
+
+static int
+pvsPauseDomain(virDomainPtr domain)
+{
+return pvsDomainChangeState(domain,
+VIR_DOMAIN_RUNNING, "running",
+pvsPause,
+VIR_DOMAIN_PAUSED, VIR_DOMAIN_PAUSED_USER,
+VIR_DOMAIN_EVENT_SUSPENDED,
+VIR_DOMAIN_EVENT_SUSPENDED_PAUSED);
+}
+
+int pvsResume(virDomainObjPtr privdom)
+{
+return pvsCmdRun(PRLCTL, "resume", PVS_UUID(privdom), NULL);
+}
+
+static int
+pvsResumeDomain(virDomainPtr domain)
+{
+return pvsDomainChangeState(domain,
+VIR_DOMAIN_PAUSED, "paused",
+pvsResume,
+VIR_DOMAIN_RUNNING, 
VIR_DOMAIN_RUNNING_UNPAUSED,
+VIR_DOMAIN_EVENT_RESUMED,
+VIR_DOMAIN_EVENT_RESUMED_UNPAUSED);
+}
+
+int pvsStart(virDomainObjPtr privdom)
+{
+return pvsCmdRun(PRLCTL, "start", PVS_UUID(privdom), NULL);
+}
+
+static int
+pvsDomainCreate(virDomainPtr domain)
+{
+return pvsDomainChangeState(domain,
+VIR_DOMAIN_SHUTOFF, "stopped",
+pvsStart,
+VIR_DOMAIN_RUNNING, 
VIR_DOMAIN_EVENT_STARTED_BOOTED,
+VIR_DOMAIN_EVENT_STARTED,
+VIR_DOMAIN_EVENT_STARTED_BOOTED);
+}
+
+int pvsKill(virDomainObjPtr privdom)
+{
+return pvsCmdRun(PRLCTL, "stop", PVS_UUID(privdom), "--kill", NULL);
+}
+
+static int
+pvsDestroyDomain(virDomainPtr domain)
+{
+return pvsDomainChangeState(domain,
+VIR_DOMAIN_RUNNING, "running",
+pvsKill,
+VIR_DOMAIN_SHUTOFF, 
VIR_DOMAIN_SHUTOFF_DESTROYED,
+VIR_DOMAIN_EVENT_STOPPED,
+VIR_DOMAIN_EVENT_STOPPED_DESTROYED);
+}
+
+int pvsStop(virDomainObjPtr privdom)
+{
+return pvsCmdRun(PRLCTL, "stop", PVS_UUID(privdom), NULL);
+}
+
+static int
+pvsShutdownDomain(virDomainPtr domain)
+{
+return pvsDomainChangeState(domain,
+V

[libvirt] [PATCH 5/9] pvs: get info about serial ports

2012-04-13 Thread Dmitry Guryanov
Add support of collecting information about serial
ports. This change is needed mostly as an example,
support of other devices will be added later.

Signed-off-by: Dmitry Guryanov 
---
 src/pvs/pvs_driver.c |  115 ++
 1 files changed, 115 insertions(+), 0 deletions(-)

diff --git a/src/pvs/pvs_driver.c b/src/pvs/pvs_driver.c
index b0c9a20..7f59e3b 100644
--- a/src/pvs/pvs_driver.c
+++ b/src/pvs/pvs_driver.c
@@ -146,6 +146,118 @@ pvsGetCapabilities(virConnectPtr conn)
 return xml;
 }
 
+static int
+pvsGetSerialInfo(virDomainChrDefPtr chr,
+ const char *name, virJSONValuePtr value)
+{
+const char *tmp;
+
+chr->deviceType = VIR_DOMAIN_CHR_DEVICE_TYPE_SERIAL;
+chr->targetType = VIR_DOMAIN_CHR_CONSOLE_TARGET_TYPE_SERIAL;
+chr->target.port = atoi(name + strlen("serial"));
+
+if (virJSONValueObjectHasKey(value, "output")) {
+chr->source.type = VIR_DOMAIN_CHR_TYPE_FILE;
+
+tmp = virJSONValueObjectGetString(value, "output");
+if (!tmp) {
+pvsParseError();
+return -1;
+}
+
+if (!(chr->source.data.file.path = strdup(tmp)))
+goto no_memory;
+} else if (virJSONValueObjectHasKey(value, "socket")) {
+chr->source.type = VIR_DOMAIN_CHR_TYPE_UNIX;
+
+tmp = virJSONValueObjectGetString(value, "socket");
+if (!tmp) {
+pvsParseError();
+return -1;
+}
+
+if (!(chr->source.data.nix.path = strdup(tmp)))
+goto no_memory;
+chr->source.data.nix.listen = false;
+} else if (virJSONValueObjectHasKey(value, "real")) {
+chr->source.type = VIR_DOMAIN_CHR_TYPE_DEV;
+
+tmp = virJSONValueObjectGetString(value, "real");
+if (!tmp) {
+pvsParseError();
+return -1;
+}
+
+if (!(chr->source.data.file.path = strdup(tmp)))
+goto no_memory;
+} else {
+pvsParseError();
+return -1;
+}
+
+return 0;
+
+  no_memory:
+virReportOOMError();
+return -1;
+}
+
+static int
+pvsAddSerialInfo(virDomainObjPtr dom,
+ const char *key, virJSONValuePtr value)
+{
+virDomainDefPtr def = dom->def;
+virDomainChrDefPtr chr = NULL;
+
+if (!(chr = virDomainChrDefNew()))
+goto no_memory;
+
+if (pvsGetSerialInfo(chr, key, value))
+goto cleanup;
+
+if (VIR_REALLOC_N(def->serials, def->nserials + 1) < 0) {
+virDomainChrDefFree(chr);
+goto no_memory;
+}
+
+def->serials[def->nserials++] = chr;
+
+return 0;
+
+  no_memory:
+virReportOOMError();
+  cleanup:
+virDomainChrDefFree(chr);
+return -1;
+}
+
+static int
+pvsAddDomainHardware(virDomainObjPtr dom, virJSONValuePtr jobj)
+{
+int n, i;
+virJSONValuePtr value;
+const char *key;
+
+n = virJSONValueObjectKeysNumber(jobj);
+if (n < 1)
+goto cleanup;
+
+for (i = 0; i < n; i++) {
+key = virJSONValueObjectGetKey(jobj, i);
+value = virJSONValueObjectGetValue(jobj, i);
+
+if (STRPREFIX(key, "serial")) {
+if (pvsAddSerialInfo(dom, key, value))
+goto cleanup;
+}
+}
+
+return 0;
+
+  cleanup:
+return -1;
+}
+
 /*
  * Must be called with privconn->lock held
  */
@@ -282,6 +394,9 @@ pvsLoadDomain(pvsConnPtr privconn, virJSONValuePtr jobj)
 else
 dom->autostart = 0;
 
+if (pvsAddDomainHardware(dom, jobj2))
+goto cleanup_unlock;
+
 virDomainObjUnlock(dom);
 
 return dom;
-- 
1.7.1

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


[libvirt] [PATCH 2/9] util: add functions for interating over json object

2012-04-13 Thread Dmitry Guryanov
Add function virJSONValueObjectKeysNumber, virJSONValueObjectGetKey
and virJSONValueObjectGetValue, which allow you to iterate over all
fields of json object: you can get number of fields and then get
name and value, stored in field with that name by index.

Signed-off-by: Dmitry Guryanov 
---
 src/util/json.c |   30 ++
 src/util/json.h |4 
 2 files changed, 34 insertions(+), 0 deletions(-)

diff --git a/src/util/json.c b/src/util/json.c
index a85f580..9109e06 100644
--- a/src/util/json.c
+++ b/src/util/json.c
@@ -428,6 +428,36 @@ virJSONValuePtr virJSONValueObjectGet(virJSONValuePtr 
object, const char *key)
 return NULL;
 }
 
+int virJSONValueObjectKeysNumber(virJSONValuePtr object)
+{
+if (object->type != VIR_JSON_TYPE_OBJECT)
+return -1;
+
+return object->data.object.npairs;
+}
+
+const char *virJSONValueObjectGetKey(virJSONValuePtr object, unsigned int n)
+{
+if (object->type != VIR_JSON_TYPE_OBJECT)
+return NULL;
+
+if (n >= object->data.object.npairs)
+return NULL;
+
+return object->data.object.pairs[n].key;
+}
+
+virJSONValuePtr virJSONValueObjectGetValue(virJSONValuePtr object, unsigned 
int n)
+{
+if (object->type != VIR_JSON_TYPE_OBJECT)
+return NULL;
+
+if (n >= object->data.object.npairs)
+return NULL;
+
+return object->data.object.pairs[n].value;
+}
+
 int virJSONValueArraySize(virJSONValuePtr array)
 {
 if (array->type != VIR_JSON_TYPE_ARRAY)
diff --git a/src/util/json.h b/src/util/json.h
index 4572654..2677ffc 100644
--- a/src/util/json.h
+++ b/src/util/json.h
@@ -99,6 +99,10 @@ virJSONValuePtr virJSONValueObjectGet(virJSONValuePtr 
object, const char *key);
 int virJSONValueArraySize(virJSONValuePtr object);
 virJSONValuePtr virJSONValueArrayGet(virJSONValuePtr object, unsigned int 
element);
 
+int virJSONValueObjectKeysNumber(virJSONValuePtr object);
+const char *virJSONValueObjectGetKey(virJSONValuePtr object, unsigned int n);
+virJSONValuePtr virJSONValueObjectGetValue(virJSONValuePtr object, unsigned 
int n);
+
 const char *virJSONValueGetString(virJSONValuePtr object);
 int virJSONValueGetNumberInt(virJSONValuePtr object, int *value);
 int virJSONValueGetNumberUint(virJSONValuePtr object, unsigned int *value);
-- 
1.7.1

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


[libvirt] [PATCH 7/9] pvs: implement virDomainDefineXML operation for existing domains

2012-04-13 Thread Dmitry Guryanov
Add pvsDomainDefineXML functions, it works only for existing
domains for the present.

It's too hard to convert libvirt's XML domain configuration into
PVS's one, so I've decided to compare virDomainDef structures:
current domain definition and the one created from XML, given to
the function. And change only different parameters.

Only description change implemetented, changing other parameters
will be implemented later.

Signed-off-by: Dmitry Guryanov 
---
 src/pvs/pvs_driver.c |   89 ++
 1 files changed, 89 insertions(+), 0 deletions(-)

diff --git a/src/pvs/pvs_driver.c b/src/pvs/pvs_driver.c
index 20243eb..ceca50d 100644
--- a/src/pvs/pvs_driver.c
+++ b/src/pvs/pvs_driver.c
@@ -1049,6 +1049,94 @@ pvsShutdownDomain(virDomainPtr domain)
 VIR_DOMAIN_EVENT_STOPPED_SHUTDOWN);
 }
 
+static int
+pvsSetDescription(virDomainObjPtr dom, const char *description)
+{
+pvsDomObjPtr pvsdom;
+
+pvsdom = dom->privateData;
+if (pvsCmdRun(PRLCTL, "set", pvsdom->uuid,
+  "--description", description, NULL))
+return -1;
+
+return 0;
+}
+
+static int
+pvsApplyChanges(virDomainObjPtr dom, virDomainDefPtr newdef)
+{
+virDomainDefPtr olddef = dom->def;
+
+if (newdef->description && !STREQ(olddef->description, 
newdef->description)) {
+if (pvsSetDescription(dom, newdef->description))
+return -1;
+}
+
+/* TODO: compare all other parameters */
+
+return 0;
+}
+
+static virDomainPtr
+pvsDomainDefineXML(virConnectPtr conn, const char *xml)
+{
+pvsConnPtr privconn = conn->privateData;
+virDomainPtr ret = NULL;
+virDomainDefPtr def;
+virDomainObjPtr dom = NULL, olddom = NULL;
+virDomainEventPtr event = NULL;
+int dupVM;
+
+pvsDriverLock(privconn);
+if ((def = virDomainDefParseString(privconn->caps, xml,
+   1 << VIR_DOMAIN_VIRT_PVS,
+   VIR_DOMAIN_XML_INACTIVE)) == NULL) {
+pvsError(VIR_ERR_INVALID_ARG, _("Can't parse XML desc"));
+goto cleanup;
+}
+
+if ((dupVM = virDomainObjIsDuplicate(&privconn->domains, def, 0)) < 0) {
+pvsError(VIR_ERR_INVALID_ARG, _("Already exists"));
+goto cleanup;
+}
+
+if (dupVM == 1) {
+olddom = virDomainFindByUUID(&privconn->domains, def->uuid);
+pvsApplyChanges(olddom, def);
+virDomainObjUnlock(olddom);
+
+if (!(dom = virDomainAssignDef(privconn->caps,
+   &privconn->domains, def, false))) {
+pvsError(VIR_ERR_INTERNAL_ERROR, _("Can't allocate domobj"));
+goto cleanup;
+}
+
+def = NULL;
+} else {
+pvsError(VIR_ERR_NO_SUPPORT, _("Not implemented yet"));
+goto cleanup;
+}
+
+event = virDomainEventNewFromObj(dom,
+ VIR_DOMAIN_EVENT_DEFINED,
+ !dupVM ?
+ VIR_DOMAIN_EVENT_DEFINED_ADDED :
+ VIR_DOMAIN_EVENT_DEFINED_UPDATED);
+
+ret = virGetDomain(conn, dom->def->name, dom->def->uuid);
+if (ret)
+ret->id = dom->def->id;
+
+  cleanup:
+virDomainDefFree(def);
+if (dom)
+virDomainObjUnlock(dom);
+if (event)
+pvsDomainEventQueue(privconn, event);
+pvsDriverUnlock(privconn);
+return ret;
+}
+
 static virDriver pvsDriver = {
 .no = VIR_DRV_PVS,
 .name = "PVS",
@@ -1076,6 +1164,7 @@ static virDriver pvsDriver = {
 .domainDestroy = pvsDestroyDomain,  /* 0.9.11 */
 .domainShutdown = pvsShutdownDomain, /* 0.9.11 */
 .domainCreate = pvsDomainCreate,/* 0.9.11 */
+.domainDefineXML = pvsDomainDefineXML,  /* 0.9.11 */
 };
 
 /**
-- 
1.7.1

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


Re: [libvirt] [PATCH V9 0/6] Add DHCP snooping support to nwfilter

2012-04-13 Thread dennis jenkins
On Fri, Apr 13, 2012 at 10:09 AM, Stefan Berger
wrote:

> This series of patches adds DHCP snooping support to libvirt's
> nwfilter subsystem.
>
> DHCP snooping detects DHCP leases obtained by a VM and automatically
> adjusts the network traffic filters to reflect the IP addresses
> with which a VM may send its traffic, thus for example preventing
> IP address spoofing.
> Once leases on IP addresses expire or if a VM gives up on a
> lease on an IP address, the filters are also adjusted.
> All leases are persisted and automatically applied upon a VM's restart.
> Leases are associated with the tuple of VM-UUID and interface MAC
> address.
>
> The following interface XML activates and uses the DHCP snooping:
>
>
>  
>  
>
>  
>
>
>
> Regards,
>   David and Stefan
>


Would libvirt (via the perl wrapper) be able to query the IP address
information?

I am developing a light-weight web interface for managing several QEMU
instances on my server (apache, mod_perl, Sys-Virt, libvirtd).  I can get
the MAC address of each VM from the XML file ($dom->get_xml_description,
XML::Simple), but at the moment I do not have a clean way to get the
corresponding IP address.

My system runs its own DHCP server and "arpwatch".  I was considering
trying to extract the MAC->IP mapping from those, but if QEMU/libvirtd
itself knows the IP in use by the VM, then that would be fantastic.

I should mention that I'm using "br0", not "virbr0" style bridges.  I don't
know if that matters.

Thank you guys for your excellent work and your time.  Libvirt and the
wrapper APIs are incredibly useful.
--
libvir-list mailing list
libvir-list@redhat.com
https://www.redhat.com/mailman/listinfo/libvir-list

Re: [libvirt] [PATCH] blockjob: add virsh blockjob --wait

2012-04-13 Thread Eric Blake
On 04/13/2012 01:29 AM, Michal Privoznik wrote:
> On 12.04.2012 21:59, Eric Blake wrote:
>> I'm tired of shell-scripting to wait for completion of a block pull,
>> when virsh can be taught to do the same.  I couldn't quite reuse
>> vshWatchJob, as this is not a case of a long-running command where
>> a second thread must be used to probe job status (at least, not unless
>> I make virsh start doing blocking waits for an event to fire), but it
>> served as inspiration for my simpler single-threaded loop.  There is
>> up to a half-second delay between sending SIGINT and the job being
>> aborted, but I didn't think it worth the complexity of a second thread
>> and use of poll() just to minimize that delay.
>>
>> @@ -7295,8 +7295,9 @@ repoll:
>>  }
>>
>>  GETTIMEOFDAY(&curr);
>> -if ( timeout && ((int)(curr.tv_sec - start.tv_sec)  * 1000 + \
>> - (int)(curr.tv_usec - start.tv_usec) / 1000) > 
>> timeout * 1000 ) {
>> +if (timeout && (((int)(curr.tv_sec - start.tv_sec)  * 1000 +
>> + (int)(curr.tv_usec - start.tv_usec) / 1000) >
>> +timeout * 1000)) {
>>  /* suspend the domain when migration timeouts. */
>>  vshDebug(ctl, VSH_ERR_DEBUG, "%s timeout", label);
>>  if (timeout_func)
> 
> These two chunks are rather cosmetic but I'm okay with having them in
> this patch not a separate one.

I noticed them because I was copying and pasting from them.  Depending
on whether I spot other cleanups for my v2, I may split the cleanups
into a separate patch.

>> +while (blocking) {
>> +virDomainBlockJobInfo info;
>> +int result = virDomainGetBlockJobInfo(dom, path, &info, 0);
>> +
>> +if (result < 0) {
>> +vshError(ctl, _("failed to query job for disk %s"), path);
>> +goto cleanup;
>> +}
>> +if (result == 0)
>> +break;
>> +
>> +if (verbose)
>> +print_job_progress(_("Block Pull"), info.end - info.cur, 
>> info.end);
>> +
>> +GETTIMEOFDAY(&curr);
>> +if (intCaught || (timeout &&
>> +  (((int)(curr.tv_sec - start.tv_sec)  * 1000 +
>> +(int)(curr.tv_usec - start.tv_usec) / 1000) >
>> +   timeout * 1000))) {
>> +vshDebug(ctl, VSH_ERR_DEBUG,
>> + intCaught ? "interrupted" : "timeout");
>> +intCaught = 0;
>> +timeout = 0;
>> +quit = true;
>> +if (virDomainBlockJobAbort(dom, path, 0) < 0) {
>> +vshError(ctl, _("failed to abort job for disk %s"), path);
>> +goto cleanup;
>> +}
> 
> Don't we need blocking = false; here? Otherwise we may spin another
> rounds and issue GetBlockJobInfo API over and over again. But on the
> other hand, I can imagine this is desired behavior. If BlockJobAbort
> succeeds and returns 0 (we are enforcing synchronous operation here) it
> should mean that block job has really been aborted. Therefore we may
> issue GetBlockJobInfo to ascertain ourselves.

Hmm, interesting question, especially in light of the new async cancel
flag.  I'm not sure how long a cancellation can take (it has to flush
all pending I/O, which may take a while), but you are correct that
passing in 0 for the abort flags means to wait until the cancel is done;
we may be waiting up to half a second to issue the abort from the time
you pressed Ctrl-C, but worse, we are now waiting for the entire
duration of the BlockJobAbort call, which might possibly be in the range
of seconds, and that can feel awfully slow to a user trying to hit
Ctrl-C to regain control of their terminal as fast as possible.

I think I need to add an --async flag that controls whether we return
control to the user as fast as possible after Ctrl-C (and fails if we
are talking to a too-old libvirtd), or omit the flag so that we
guarantee to wait until the job is cancelled, even if it takes a while
after the Ctrl-C.  I'll have to respin this patch, and since I want to
do the same for my new 'virsh blockcopy' patch, I'll fold it into my
block storage migration series.

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



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

[libvirt] VN-Link vNIC memory state copying on VM Migration

2012-04-13 Thread Jagath Weerasinghe
Hi All,

I am new to libvirt. And want to know how the VM migration
occurs in VN-Link (IEEE802.1Qbh). As far as I know,
the memory state of vNICs in M81KR VIC has to be copied
and moved to the destination vNIC on VM migration.
Is that correct? If so, could you please tell me how this
has been implemented in libvirt?

Thanks
Jagath

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


Re: [libvirt] [PATCH] Web placeholder for pending patches on the web site

2012-04-13 Thread Daniel Veillard
On Fri, Apr 13, 2012 at 09:30:45AM -0600, Eric Blake wrote:
> On 04/13/2012 09:16 AM, Daniel Veillard wrote:
> > This is based on recent developments on patch checker and the
> > goal is to keep a list of pending patches needing review on the
> > project web site. The page template in git just hold a pointer
> 
> s/hold/holds/
> 
> > to the web page.
> > 
> > diff --git a/docs/pending.html.in b/docs/pending.html.in
> > new file mode 100644
> > index 000..dfbe647
> > --- /dev/null
> > +++ b/docs/pending.html.in
> > @@ -0,0 +1,13 @@
> > +
> > +  
> > +
> > +Pending patches needing review
> > +  
> > +  
> > +Pending patches needing review
> > + A list of pending patches needing review upstream is available
> > +on http://libvirt.org/pending.html";>the project pending
> > +patches page.
> 
> Self-referential, at least when installed on libvirt.org (but makes
> sense when installed locally to end-user machines).  And I suppose you
> will eventually be changing libvirt.org's page to be generated live
> based on your patch checker tool.  Works for me.

  Yup, that's the intent, though I didn't set the crontabs yet :-)
  But I have put a first page there http://libvirt.org/pending.html.
It needs quite some improvements (especially with patch reported as
squashed just before commits).

> ACK.

  thanks, pushed !

Daniel

-- 
Daniel Veillard  | libxml Gnome XML XSLT toolkit  http://xmlsoft.org/
dan...@veillard.com  | Rpmfind RPM search engine http://rpmfind.net/
http://veillard.com/ | virtualization library  http://libvirt.org/

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


[libvirt] [PATCH v2] domain:screenshot: fixed screen parameter

2012-04-13 Thread Martin Kletzander
The screen parameter must be an integer.
I also chnaged it to variable parameter with the reasonable default.
---
v2:
 - fixed "'screen'" to "screen" (stupid typo)

 repos/domain/screenshot.py |7 ---
 1 files changed, 4 insertions(+), 3 deletions(-)

diff --git a/repos/domain/screenshot.py b/repos/domain/screenshot.py
index d73e980..3c0f85b 100644
--- a/repos/domain/screenshot.py
+++ b/repos/domain/screenshot.py
@@ -7,8 +7,8 @@ import mimetypes

 import libvirt

-required_params = ('guestname', 'screen', 'filename',)
-optional_params = ()
+required_params = ('guestname', 'filename',)
+optional_params = ('screen',)

 def saver(stream, data, file_):
 return file_.write(data)
@@ -24,7 +24,8 @@ def screenshot(params):
 dom = conn.lookupByName(params['guestname'])

 st = conn.newStream(0)
-mime = dom.screenshot(st, params['screen'], 0)
+screen = params.get('screen', 0)
+mime = dom.screenshot(st, int(screen), 0)

 ext = mimetypes.guess_extension(mime) or '.ppm'
 filename = params['filename'] + ext
--
1.7.8.5

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


[libvirt] [PATCH] domain:screenshot: Added cleanup function

2012-04-13 Thread Martin Kletzander
Added cleanup function to the screeshot testcase. This makes use of
the new "sharedmod" module.
---

WARNING: don't push this before the patch with sharedmod is pushed in
the repo, otherwise this will not work. Thanks.

 repos/domain/screenshot.py |6 ++
 1 files changed, 6 insertions(+), 0 deletions(-)

diff --git a/repos/domain/screenshot.py b/repos/domain/screenshot.py
index 3e727a7..5a12c4b 100644
--- a/repos/domain/screenshot.py
+++ b/repos/domain/screenshot.py
@@ -6,6 +6,7 @@ import os
 import mimetypes

 import libvirt
+import sharedmod

 required_params = ('guestname', 'filename',)
 optional_params = ('screen',)
@@ -36,6 +37,7 @@ def screenshot(params):
 logger.debug('Mimetype of the file is %s' % mime)

 ret = st.finish()
+sharedmod.dict['screenshot_filename'] = filename

 finally:
 # Some error occurred, cleanup
@@ -43,3 +45,7 @@ def screenshot(params):
 conn.close()

 return ret
+
+def cleanup(params):
+if sharedmod.has_key('screenshot_filename'):
+os.remove(sharedmod['screenshot_filename'])
--
1.7.8.5

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


[libvirt] [PATCH] domain:screenshot: fixed screen parameter

2012-04-13 Thread Martin Kletzander
The screen parameter must be an integer.
I also chnaged it to variable parameter with the reasonable default.
---
 repos/domain/screenshot.py |7 ---
 1 files changed, 4 insertions(+), 3 deletions(-)

diff --git a/repos/domain/screenshot.py b/repos/domain/screenshot.py
index d73e980..3e727a7 100644
--- a/repos/domain/screenshot.py
+++ b/repos/domain/screenshot.py
@@ -7,8 +7,8 @@ import mimetypes

 import libvirt

-required_params = ('guestname', 'screen', 'filename',)
-optional_params = ()
+required_params = ('guestname', 'filename',)
+optional_params = ('screen',)

 def saver(stream, data, file_):
 return file_.write(data)
@@ -24,7 +24,8 @@ def screenshot(params):
 dom = conn.lookupByName(params['guestname'])

 st = conn.newStream(0)
-mime = dom.screenshot(st, params['screen'], 0)
+screen = params.get('screen', 0)
+mime = dom.screenshot(st, int('screen'), 0)

 ext = mimetypes.guess_extension(mime) or '.ppm'
 filename = params['filename'] + ext
--
1.7.8.5

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


Re: [libvirt] [PATCHv4 07/18] blockjob: enhance xml to track mirrors across libvirtd restart

2012-04-13 Thread Eric Blake
On 04/13/2012 05:23 AM, Jiri Denemark wrote:
> On Mon, Apr 09, 2012 at 21:52:16 -0600, Eric Blake wrote:
>> QUESTION: should we parse and ignore  on input, rather than
>> rejecting it?  By rejecting it, I can't add a unit test, since the
>> unit test framework currently doesn't expose a way to trigger
>> internal parsing.
>>
>> In order to track a block copy job across libvirtd restarts, we
>> need to save internal XML that tracks the name of the file
>> holding the mirror.  Displaying this name in dumpxml might also
>> be useful to the user, even if we don't yet have a way to (re-)
>> start a domain with mirroring enabled up front.  This is done
>> with a new  sub-element to , as in:
>>
>> 
>>   
>>   
>>   
>>   ...
>> 
> 
> However, this would mean, the XML from virDomainGetXMLDesc() cannot be
> directly used for defining new domain. I think there are two possible ways to
> go. Either output  the way you did it and ignore it on input
> (similarly to what we do with aliases or SELinux labels) or put the mirror
> element out of domain XML and put it into state XML only.

I like seeing the output (it makes it obvious that a mirror is still
running, and what --pivot will switch to).  I'll redo this patch to
ignore rather than reject  on input for inactive domains, at
which point I can then add an xml2xml round-trip testcase (and remove
the QUESTION paragraph from my commit message).
>> @@ -3453,6 +3457,22 @@ virDomainDiskDefParseXML(virCapsPtr caps,
>>  ioeventfd = virXMLPropString(cur, "ioeventfd");
>>  event_idx = virXMLPropString(cur, "event_idx");
>>  copy_on_read = virXMLPropString(cur, "copy_on_read");
>> +} else if ((mirror == NULL) &&
>> +   (xmlStrEqual(cur->name, BAD_CAST "mirror"))) {
> 
> You could have also removed those extra () when copy&pasting the code :-)

Copy-and-paste strikes again :)

>>
>> +char *mirror;
>> +char *mirrorFormat;
>> +bool mirroring;
>> +
>>  virDomainBlockIoTuneInfo blkdeviotune;
>>
>>  char *serial;
>> @@ -2125,6 +2129,7 @@ VIR_ENUM_DECL(virDomainDiskIo)
>>  VIR_ENUM_DECL(virDomainDiskSecretType)
>>  VIR_ENUM_DECL(virDomainDiskSnapshot)
>>  VIR_ENUM_DECL(virDomainDiskTray)
>> +VIR_ENUM_DECL(virDomainDiskMirrorStage)
>>  VIR_ENUM_DECL(virDomainIoEventFd)
>>  VIR_ENUM_DECL(virDomainVirtioEventIdx)
>>  VIR_ENUM_DECL(virDomainDiskCopyOnRead)
> 
> This last hunk looks weired. Should it go into another patch perhaps?

Good catch.  Junk left over from an earlier revision (back when qemu
didn't keep the job once in the mirroring stage, so I had to track the
job manually via additional xml state).  I'll delete it for v5.

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



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

Re: [libvirt] [PATCH] Web placeholder for pending patches on the web site

2012-04-13 Thread Eric Blake
On 04/13/2012 09:16 AM, Daniel Veillard wrote:
> This is based on recent developments on patch checker and the
> goal is to keep a list of pending patches needing review on the
> project web site. The page template in git just hold a pointer

s/hold/holds/

> to the web page.
> 
> diff --git a/docs/pending.html.in b/docs/pending.html.in
> new file mode 100644
> index 000..dfbe647
> --- /dev/null
> +++ b/docs/pending.html.in
> @@ -0,0 +1,13 @@
> +
> +  
> +
> +Pending patches needing review
> +  
> +  
> +Pending patches needing review
> + A list of pending patches needing review upstream is available
> +on http://libvirt.org/pending.html";>the project pending
> +patches page.

Self-referential, at least when installed on libvirt.org (but makes
sense when installed locally to end-user machines).  And I suppose you
will eventually be changing libvirt.org's page to be generated live
based on your patch checker tool.  Works for me.

ACK.

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



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

Re: [libvirt] [test-API PATCHv2 1/2] sharemod: Add a new file for variable sharing in testcases

2012-04-13 Thread Martin Kletzander
On 04/13/2012 02:23 PM, Guannan Ren wrote:
> On 04/10/2012 09:55 PM, Guannan Ren wrote:
>>  sharedmod.py
>> ---
>>   sharedmod.py |   16 
>>   1 files changed, 16 insertions(+), 0 deletions(-)
>>   create mode 100644 sharedmod.py
>>
>> diff --git a/sharedmod.py b/sharedmod.py
>> new file mode 100644
>> index 000..8af26d8
>> --- /dev/null
>> +++ b/sharedmod.py
>> @@ -0,0 +1,16 @@
>> +# This is a module for variable sharing across testcases during
>> +# running. You have to import it in each of testcases which want
>> +# to share data. The framwork have already set {'conn': connobj}
>> +# in libvirtobj dictionary for use in testcases.
>> +
>> +# The libvirtobj dictionary is only set and used by framework
>> +# in testcases you could use sharedmod.libvirtobj['conn'] to get
>> +# the connection object in libvirt.py, you need not to close it,
>> +# the framework do it.
>> +libvirtobj = {}
>> +
>> +# shared variables for customized use in testcases
>> +# set variable: sharedmod.data['my_test_variable'] = 'test_value'
>> +# check the variable: sharedmod.data.has_key('my_test_variable')
>> +# get the varialbe: sharedmod.data.get('my_test_variable',
>> 'test_variable_default_value')
>> +data = {}
> 
> If no more comments, I will push these two patches.
> 
> Guannan Ren
> 
> -- 
> libvir-list mailing list
> libvir-list@redhat.com
> https://www.redhat.com/mailman/listinfo/libvir-list

This one looks ok, I haven't had a chance to look at the second one yet.

Martin

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


Re: [libvirt] [PATCHv4 08/18] blockjob: react to active block copy

2012-04-13 Thread Eric Blake
On 04/13/2012 05:35 AM, Jiri Denemark wrote:
> On Mon, Apr 09, 2012 at 21:52:17 -0600, Eric Blake wrote:
>> For now, disk migration via block copy job is not implemented.  But
>> when we do implement it, we have to deal with the fact that qemu does
>> not provide an easy way to re-start a qemu process with mirroring
>> still intact (it _might_ be possible by using qemu -S then an
>> initial 'drive-mirror' with disk reuse before starting the domain,
>> but that gets hairy).  Even something like 'virDomainSave' becomes
>> hairy, if you realize the implications that 'virDomainRestore' would
>> be stuck with recreating the same mirror layout.
>>

>> @@ -4947,6 +4952,12 @@ static virDomainPtr qemudDomainDefine(virConnectPtr 
>> conn, const char *xml) {
>>  goto cleanup;
>>  }
>>  def = NULL;
>> +if (virDomainHasDiskMirror(vm)) {
>> +qemuReportError(VIR_ERR_BLOCK_COPY_ACTIVE, "%s",
>> +_("domain has active block copy job"));
>> +virDomainObjAssignDef(vm, NULL, false);
>> +goto cleanup;
>> +}
>>  vm->persistent = 1;
> 
> I think it would be better to do this check a bit earlier in the process to
> avoid the need to undo virDomainObjAssignDef().

I see where you are coming from in the limited context shown in this
patch (and it even matches my initial thoughts when first trying to
write the patch), but look at the bigger picture:

 if (!(vm = virDomainAssignDef(driver->caps,
   &driver->domains,
   def, false))) {
 goto cleanup;
 }
 def = NULL;
+if (virDomainHasDiskMirror(vm)) {
+qemuReportError(VIR_ERR_BLOCK_COPY_ACTIVE, "%s",
+_("domain has active block copy job"));
+virDomainObjAssignDef(vm, NULL, false);
+goto cleanup;
+}
 vm->persistent = 1;

That is, we don't know what vm is, to check if it has a disk mirror,
until after we have already associated a potential persistent definition
to vm, since virDomainAssignDef has the effect of doing both a lookup
and assignment in one function.  The only way to avoid assigning the
persistent definition would be to do a lookup to see if there is already
an existing vm that matches the name/uuid in the def, but that still
implies that you have to have def available, and it also implies a
change to domain_conf.c to add a new entry point that does a lookup
without the assignment, just so we can probe for active mirrors, then
follow it by another lookup with assignment.

Therefore, I decided that it was easier to keep the existing lookup with
assignment and undo the assignment than to add new entry points and
redundant lookup work.

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



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

[libvirt] [libvirt-glib 1/5] Make GVirConfigDomainTimer abstract

2012-04-13 Thread Christophe Fergeau
Specialized timer classes will inherit from it
---
 libvirt-gconfig/libvirt-gconfig-domain-timer.c |   22 +-
 libvirt-gconfig/libvirt-gconfig-domain-timer.h |4 
 libvirt-gconfig/libvirt-gconfig.sym|2 --
 3 files changed, 1 insertion(+), 27 deletions(-)

diff --git a/libvirt-gconfig/libvirt-gconfig-domain-timer.c 
b/libvirt-gconfig/libvirt-gconfig-domain-timer.c
index 70215ae..67a1812 100644
--- a/libvirt-gconfig/libvirt-gconfig-domain-timer.c
+++ b/libvirt-gconfig/libvirt-gconfig-domain-timer.c
@@ -32,7 +32,7 @@ struct _GVirConfigDomainTimerPrivate
 gboolean unused;
 };
 
-G_DEFINE_TYPE(GVirConfigDomainTimer, gvir_config_domain_timer, 
GVIR_CONFIG_TYPE_OBJECT);
+G_DEFINE_ABSTRACT_TYPE(GVirConfigDomainTimer, gvir_config_domain_timer, 
GVIR_CONFIG_TYPE_OBJECT);
 
 
 static void gvir_config_domain_timer_class_init(GVirConfigDomainTimerClass 
*klass)
@@ -47,23 +47,3 @@ static void 
gvir_config_domain_timer_init(GVirConfigDomainTimer *timer)
 
 timer->priv = GVIR_CONFIG_DOMAIN_TIMER_GET_PRIVATE(timer);
 }
-
-
-GVirConfigDomainTimer *gvir_config_domain_timer_new(void)
-{
-GVirConfigObject *object;
-
-object = gvir_config_object_new(GVIR_CONFIG_TYPE_DOMAIN_TIMER, "timer", 
NULL);
-return GVIR_CONFIG_DOMAIN_TIMER(object);
-}
-
-
-GVirConfigDomainTimer *gvir_config_domain_timer_new_from_xml(const gchar *xml,
-GError **error)
-{
-GVirConfigObject *object;
-
-object = gvir_config_object_new_from_xml(GVIR_CONFIG_TYPE_DOMAIN_TIMER,
- "timer", NULL, xml, error);
-return GVIR_CONFIG_DOMAIN_TIMER(object);
-}
diff --git a/libvirt-gconfig/libvirt-gconfig-domain-timer.h 
b/libvirt-gconfig/libvirt-gconfig-domain-timer.h
index 11038e2..a7b4332 100644
--- a/libvirt-gconfig/libvirt-gconfig-domain-timer.h
+++ b/libvirt-gconfig/libvirt-gconfig-domain-timer.h
@@ -59,10 +59,6 @@ struct _GVirConfigDomainTimerClass
 
 GType gvir_config_domain_timer_get_type(void);
 
-GVirConfigDomainTimer *gvir_config_domain_timer_new(void);
-GVirConfigDomainTimer *gvir_config_domain_timer_new_from_xml(const gchar *xml,
-  GError **error);
-
 G_END_DECLS
 
 #endif /* __LIBVIRT_GCONFIG_DOMAIN_TIMER_H__ */
diff --git a/libvirt-gconfig/libvirt-gconfig.sym 
b/libvirt-gconfig/libvirt-gconfig.sym
index 2378a3c..77d0a45 100644
--- a/libvirt-gconfig/libvirt-gconfig.sym
+++ b/libvirt-gconfig/libvirt-gconfig.sym
@@ -227,8 +227,6 @@ LIBVIRT_GCONFIG_0.0.7 {
gvir_config_domain_sound_set_model;
 
gvir_config_domain_timer_get_type;
-   gvir_config_domain_timer_new;
-   gvir_config_domain_timer_new_from_xml;
 
gvir_config_domain_video_get_type;
gvir_config_domain_video_model_get_type;
-- 
1.7.10

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


[libvirt] [libvirt-glib 5/5] Add GVirConfigDomainTimerPit class

2012-04-13 Thread Christophe Fergeau
---
 libvirt-gconfig/Makefile.am|2 +
 libvirt-gconfig/libvirt-gconfig-domain-timer-pit.c |   72 
 libvirt-gconfig/libvirt-gconfig-domain-timer-pit.h |   67 ++
 libvirt-gconfig/libvirt-gconfig.h  |1 +
 libvirt-gconfig/libvirt-gconfig.sym|4 ++
 libvirt-gconfig/tests/test-domain-create.c |8 +++
 6 files changed, 154 insertions(+)
 create mode 100644 libvirt-gconfig/libvirt-gconfig-domain-timer-pit.c
 create mode 100644 libvirt-gconfig/libvirt-gconfig-domain-timer-pit.h

diff --git a/libvirt-gconfig/Makefile.am b/libvirt-gconfig/Makefile.am
index 0177a72..5f15803 100644
--- a/libvirt-gconfig/Makefile.am
+++ b/libvirt-gconfig/Makefile.am
@@ -41,6 +41,7 @@ GCONFIG_HEADER_FILES = \
libvirt-gconfig-domain-snapshot.h \
libvirt-gconfig-domain-sound.h \
libvirt-gconfig-domain-timer.h \
+   libvirt-gconfig-domain-timer-pit.h \
libvirt-gconfig-domain-timer-rtc.h \
libvirt-gconfig-domain-video.h \
libvirt-gconfig-helpers.h \
@@ -95,6 +96,7 @@ GCONFIG_SOURCE_FILES = \
libvirt-gconfig-domain-snapshot.c \
libvirt-gconfig-domain-sound.c \
libvirt-gconfig-domain-timer.c \
+   libvirt-gconfig-domain-timer-pit.c \
libvirt-gconfig-domain-timer-rtc.c \
libvirt-gconfig-domain-video.c \
libvirt-gconfig-helpers.c \
diff --git a/libvirt-gconfig/libvirt-gconfig-domain-timer-pit.c 
b/libvirt-gconfig/libvirt-gconfig-domain-timer-pit.c
new file mode 100644
index 000..d75cd30
--- /dev/null
+++ b/libvirt-gconfig/libvirt-gconfig-domain-timer-pit.c
@@ -0,0 +1,72 @@
+/*
+ * libvirt-gconfig-domain-timer-pit.c: libvirt domain PIT timer configuration
+ *
+ * Copyright (C) 2012 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, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307  USA
+ *
+ * Author: Christophe Fergeau 
+ */
+
+#include 
+
+#include "libvirt-gconfig/libvirt-gconfig.h"
+#include "libvirt-gconfig/libvirt-gconfig-private.h"
+
+#define GVIR_CONFIG_DOMAIN_TIMER_PIT_GET_PRIVATE(obj) \
+(G_TYPE_INSTANCE_GET_PRIVATE((obj), GVIR_CONFIG_TYPE_DOMAIN_TIMER_PIT, 
GVirConfigDomainTimerPitPrivate))
+
+struct _GVirConfigDomainTimerPitPrivate
+{
+gboolean unused;
+};
+
+G_DEFINE_TYPE(GVirConfigDomainTimerPit, gvir_config_domain_timer_pit, 
GVIR_CONFIG_TYPE_DOMAIN_TIMER);
+
+
+static void 
gvir_config_domain_timer_pit_class_init(GVirConfigDomainTimerPitClass *klass)
+{
+g_type_class_add_private(klass, sizeof(GVirConfigDomainTimerPitPrivate));
+}
+
+
+static void gvir_config_domain_timer_pit_init(GVirConfigDomainTimerPit *timer)
+{
+g_debug("Init GVirConfigDomainTimerPit=%p", timer);
+
+timer->priv = GVIR_CONFIG_DOMAIN_TIMER_PIT_GET_PRIVATE(timer);
+}
+
+
+GVirConfigDomainTimerPit *gvir_config_domain_timer_pit_new(void)
+{
+GVirConfigObject *object;
+
+object = gvir_config_object_new(GVIR_CONFIG_TYPE_DOMAIN_TIMER_PIT,
+"timer", NULL);
+gvir_config_object_set_attribute(object, "name", "pit", NULL);
+return GVIR_CONFIG_DOMAIN_TIMER_PIT(object);
+}
+
+GVirConfigDomainTimerPit *gvir_config_domain_timer_pit_new_from_xml(const 
gchar *xml,
+GError **error)
+{
+GVirConfigObject *object;
+
+object = gvir_config_object_new_from_xml(GVIR_CONFIG_TYPE_DOMAIN_TIMER_PIT,
+ "timer", NULL, xml, error);
+gvir_config_object_set_attribute(object, "name", "pit", NULL);
+return GVIR_CONFIG_DOMAIN_TIMER_PIT(object);
+}
diff --git a/libvirt-gconfig/libvirt-gconfig-domain-timer-pit.h 
b/libvirt-gconfig/libvirt-gconfig-domain-timer-pit.h
new file mode 100644
index 000..7709825
--- /dev/null
+++ b/libvirt-gconfig/libvirt-gconfig-domain-timer-pit.h
@@ -0,0 +1,67 @@
+/*
+ * libvirt-gconfig-domain-timer-pit.h: libvirt domain PIT timer configuration
+ *
+ * Copyright (C) 2012 Red Hat, Inc.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the ter

[libvirt] [libvirt-glib 4/5] Add GVirConfigDomainTimerRtc class

2012-04-13 Thread Christophe Fergeau
---
 libvirt-gconfig/Makefile.am|2 +
 libvirt-gconfig/libvirt-gconfig-domain-timer-rtc.c |   72 
 libvirt-gconfig/libvirt-gconfig-domain-timer-rtc.h |   67 ++
 libvirt-gconfig/libvirt-gconfig.h  |1 +
 libvirt-gconfig/libvirt-gconfig.sym|4 ++
 libvirt-gconfig/tests/test-domain-create.c |9 +++
 6 files changed, 155 insertions(+)
 create mode 100644 libvirt-gconfig/libvirt-gconfig-domain-timer-rtc.c
 create mode 100644 libvirt-gconfig/libvirt-gconfig-domain-timer-rtc.h

diff --git a/libvirt-gconfig/Makefile.am b/libvirt-gconfig/Makefile.am
index 181ec57..0177a72 100644
--- a/libvirt-gconfig/Makefile.am
+++ b/libvirt-gconfig/Makefile.am
@@ -41,6 +41,7 @@ GCONFIG_HEADER_FILES = \
libvirt-gconfig-domain-snapshot.h \
libvirt-gconfig-domain-sound.h \
libvirt-gconfig-domain-timer.h \
+   libvirt-gconfig-domain-timer-rtc.h \
libvirt-gconfig-domain-video.h \
libvirt-gconfig-helpers.h \
libvirt-gconfig-interface.h \
@@ -94,6 +95,7 @@ GCONFIG_SOURCE_FILES = \
libvirt-gconfig-domain-snapshot.c \
libvirt-gconfig-domain-sound.c \
libvirt-gconfig-domain-timer.c \
+   libvirt-gconfig-domain-timer-rtc.c \
libvirt-gconfig-domain-video.c \
libvirt-gconfig-helpers.c \
libvirt-gconfig-interface.c \
diff --git a/libvirt-gconfig/libvirt-gconfig-domain-timer-rtc.c 
b/libvirt-gconfig/libvirt-gconfig-domain-timer-rtc.c
new file mode 100644
index 000..b99c1e3
--- /dev/null
+++ b/libvirt-gconfig/libvirt-gconfig-domain-timer-rtc.c
@@ -0,0 +1,72 @@
+/*
+ * libvirt-gconfig-domain-timer-rtc.c: libvirt domain RTC timer configuration
+ *
+ * Copyright (C) 2012 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, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307  USA
+ *
+ * Author: Christophe Fergeau 
+ */
+
+#include 
+
+#include "libvirt-gconfig/libvirt-gconfig.h"
+#include "libvirt-gconfig/libvirt-gconfig-private.h"
+
+#define GVIR_CONFIG_DOMAIN_TIMER_RTC_GET_PRIVATE(obj) \
+(G_TYPE_INSTANCE_GET_PRIVATE((obj), GVIR_CONFIG_TYPE_DOMAIN_TIMER_RTC, 
GVirConfigDomainTimerRtcPrivate))
+
+struct _GVirConfigDomainTimerRtcPrivate
+{
+gboolean unused;
+};
+
+G_DEFINE_TYPE(GVirConfigDomainTimerRtc, gvir_config_domain_timer_rtc, 
GVIR_CONFIG_TYPE_DOMAIN_TIMER);
+
+
+static void 
gvir_config_domain_timer_rtc_class_init(GVirConfigDomainTimerRtcClass *klass)
+{
+g_type_class_add_private(klass, sizeof(GVirConfigDomainTimerRtcPrivate));
+}
+
+
+static void gvir_config_domain_timer_rtc_init(GVirConfigDomainTimerRtc *timer)
+{
+g_debug("Init GVirConfigDomainTimerRtc=%p", timer);
+
+timer->priv = GVIR_CONFIG_DOMAIN_TIMER_RTC_GET_PRIVATE(timer);
+}
+
+
+GVirConfigDomainTimerRtc *gvir_config_domain_timer_rtc_new(void)
+{
+GVirConfigObject *object;
+
+object = gvir_config_object_new(GVIR_CONFIG_TYPE_DOMAIN_TIMER_RTC,
+"timer", NULL);
+gvir_config_object_set_attribute(object, "name", "rtc", NULL);
+return GVIR_CONFIG_DOMAIN_TIMER_RTC(object);
+}
+
+GVirConfigDomainTimerRtc *gvir_config_domain_timer_rtc_new_from_xml(const 
gchar *xml,
+GError 
**error)
+{
+GVirConfigObject *object;
+
+object = gvir_config_object_new_from_xml(GVIR_CONFIG_TYPE_DOMAIN_TIMER_RTC,
+ "timer", NULL, xml, error);
+gvir_config_object_set_attribute(object, "name", "rtc", NULL);
+return GVIR_CONFIG_DOMAIN_TIMER_RTC(object);
+}
diff --git a/libvirt-gconfig/libvirt-gconfig-domain-timer-rtc.h 
b/libvirt-gconfig/libvirt-gconfig-domain-timer-rtc.h
new file mode 100644
index 000..6d76371
--- /dev/null
+++ b/libvirt-gconfig/libvirt-gconfig-domain-timer-rtc.h
@@ -0,0 +1,67 @@
+/*
+ * libvirt-gconfig-domain-timer-rtc.h: libvirt domain RTC timer configuration
+ *
+ * Copyright (C) 2012 Red Hat, Inc.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under 

Re: [libvirt] [PATCHv4 09/18] blockjob: expose qemu commands for mirrored storage migration

2012-04-13 Thread Eric Blake
On 04/13/2012 06:31 AM, Jiri Denemark wrote:
> On Mon, Apr 09, 2012 at 21:52:18 -0600, Eric Blake wrote:
>> As mentioned several commits ago when the capability bits were added,
>> the new block copy storage migration sequence requires both the
>> 'drive-mirror' and 'drive-reopen' monitor commands.
>>

>> +
>> +if (mon->json)
>> +ret = qemuMonitorJSONDriveMirror(mon, actions, device, file, format,
>> + flags);
>> +else
>> +qemuReportError(VIR_ERR_INVALID_ARG, "%s",
>> +_("drive-mirror requires JSON monitor"));
> 
> Why is this VIR_ERR_INVALID_ARG instead of VIR_ERR_CONFIG_UNSUPPORTED?

Probably copy-and-paste, but worth fixing along the same lines as the
other message about "qemu binary" being too old.

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



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

[libvirt] [libvirt-glib 3/5] Implement gvir_config_domain_clock_add_timer

2012-04-13 Thread Christophe Fergeau
---
 libvirt-gconfig/libvirt-gconfig-domain-clock.c |   10 ++
 libvirt-gconfig/libvirt-gconfig-domain-clock.h |4 
 libvirt-gconfig/libvirt-gconfig.sym|1 +
 3 files changed, 15 insertions(+)

diff --git a/libvirt-gconfig/libvirt-gconfig-domain-clock.c 
b/libvirt-gconfig/libvirt-gconfig-domain-clock.c
index 338b558..7c41dbf 100644
--- a/libvirt-gconfig/libvirt-gconfig-domain-clock.c
+++ b/libvirt-gconfig/libvirt-gconfig-domain-clock.c
@@ -101,3 +101,13 @@ void 
gvir_config_domain_clock_set_variable_offset(GVirConfigDomainClock *klock,
"adjustment", G_TYPE_INT, 
seconds,
NULL);
 }
+
+void gvir_config_domain_clock_add_timer(GVirConfigDomainClock *klock,
+GVirConfigDomainTimer *timer)
+{
+g_return_if_fail(GVIR_CONFIG_IS_DOMAIN_CLOCK(klock));
+g_return_if_fail(GVIR_CONFIG_IS_DOMAIN_TIMER(timer));
+
+gvir_config_object_attach_add(GVIR_CONFIG_OBJECT(klock),
+  GVIR_CONFIG_OBJECT(timer));
+}
diff --git a/libvirt-gconfig/libvirt-gconfig-domain-clock.h 
b/libvirt-gconfig/libvirt-gconfig-domain-clock.h
index 6eb2b52..b311048 100644
--- a/libvirt-gconfig/libvirt-gconfig-domain-clock.h
+++ b/libvirt-gconfig/libvirt-gconfig-domain-clock.h
@@ -27,6 +27,8 @@
 #ifndef __LIBVIRT_GCONFIG_DOMAIN_CLOCK_H__
 #define __LIBVIRT_GCONFIG_DOMAIN_CLOCK_H__
 
+#include 
+
 G_BEGIN_DECLS
 
 #define GVIR_CONFIG_TYPE_DOMAIN_CLOCK
(gvir_config_domain_clock_get_type ())
@@ -74,6 +76,8 @@ void 
gvir_config_domain_clock_set_timezone(GVirConfigDomainClock *klock,
const char *tz);
 void gvir_config_domain_clock_set_variable_offset(GVirConfigDomainClock *klock,
   gint seconds);
+void gvir_config_domain_clock_add_timer(GVirConfigDomainClock *klock,
+GVirConfigDomainTimer *timer);
 
 
 G_END_DECLS
diff --git a/libvirt-gconfig/libvirt-gconfig.sym 
b/libvirt-gconfig/libvirt-gconfig.sym
index 386597b..8eefb95 100644
--- a/libvirt-gconfig/libvirt-gconfig.sym
+++ b/libvirt-gconfig/libvirt-gconfig.sym
@@ -59,6 +59,7 @@ LIBVIRT_GCONFIG_0.0.7 {
gvir_config_domain_clock_offset_get_type;
gvir_config_domain_clock_new;
gvir_config_domain_clock_new_from_xml;
+   gvir_config_domain_clock_add_timer;
gvir_config_domain_clock_set_offset;
gvir_config_domain_clock_set_timezone;
gvir_config_domain_clock_set_variable_offset;
-- 
1.7.10

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


[libvirt] [libvirt-glib 2/5] Implement gvir_config_domain_timer_[gs]et_tick_policy

2012-04-13 Thread Christophe Fergeau
---
 libvirt-gconfig/libvirt-gconfig-domain-timer.c |   26 
 libvirt-gconfig/libvirt-gconfig-domain-timer.h |9 
 libvirt-gconfig/libvirt-gconfig.sym|3 +++
 3 files changed, 38 insertions(+)

diff --git a/libvirt-gconfig/libvirt-gconfig-domain-timer.c 
b/libvirt-gconfig/libvirt-gconfig-domain-timer.c
index 67a1812..07cbf47 100644
--- a/libvirt-gconfig/libvirt-gconfig-domain-timer.c
+++ b/libvirt-gconfig/libvirt-gconfig-domain-timer.c
@@ -23,6 +23,7 @@
 #include 
 
 #include "libvirt-gconfig/libvirt-gconfig.h"
+#include "libvirt-gconfig/libvirt-gconfig-private.h"
 
 #define GVIR_CONFIG_DOMAIN_TIMER_GET_PRIVATE(obj) \
 (G_TYPE_INSTANCE_GET_PRIVATE((obj), GVIR_CONFIG_TYPE_DOMAIN_TIMER, 
GVirConfigDomainTimerPrivate))
@@ -47,3 +48,28 @@ static void 
gvir_config_domain_timer_init(GVirConfigDomainTimer *timer)
 
 timer->priv = GVIR_CONFIG_DOMAIN_TIMER_GET_PRIVATE(timer);
 }
+
+void gvir_config_domain_timer_set_tick_policy(GVirConfigDomainTimer *timer,
+  GVirConfigDomainTimerTickPolicy 
policy)
+{
+g_return_if_fail(GVIR_CONFIG_IS_DOMAIN_TIMER(timer));
+
+gvir_config_object_set_attribute_with_type(GVIR_CONFIG_OBJECT(timer),
+   "tickpolicy",
+   
GVIR_CONFIG_TYPE_DOMAIN_TIMER_TICK_POLICY,
+   policy,
+   NULL);
+}
+
+GVirConfigDomainTimerTickPolicy
+gvir_config_domain_timer_get_tick_policy(GVirConfigDomainTimer *timer)
+{
+g_return_val_if_fail(GVIR_CONFIG_IS_DOMAIN_TIMER(timer),
+ GVIR_CONFIG_DOMAIN_TIMER_TICK_POLICY_DELAY);
+
+return gvir_config_object_get_attribute_genum(GVIR_CONFIG_OBJECT(timer),
+  NULL,
+  "tickpolicy",
+  
GVIR_CONFIG_TYPE_DOMAIN_TIMER_TICK_POLICY,
+  
GVIR_CONFIG_DOMAIN_TIMER_TICK_POLICY_DELAY);
+}
diff --git a/libvirt-gconfig/libvirt-gconfig-domain-timer.h 
b/libvirt-gconfig/libvirt-gconfig-domain-timer.h
index a7b4332..84ea7e1 100644
--- a/libvirt-gconfig/libvirt-gconfig-domain-timer.h
+++ b/libvirt-gconfig/libvirt-gconfig-domain-timer.h
@@ -56,9 +56,18 @@ struct _GVirConfigDomainTimerClass
 gpointer padding[20];
 };
 
+typedef enum {
+GVIR_CONFIG_DOMAIN_TIMER_TICK_POLICY_DELAY,
+GVIR_CONFIG_DOMAIN_TIMER_TICK_POLICY_CATCHUP,
+GVIR_CONFIG_DOMAIN_TIMER_TICK_POLICY_MERGE,
+GVIR_CONFIG_DOMAIN_TIMER_TICK_POLICY_DISCARD
+} GVirConfigDomainTimerTickPolicy;
 
 GType gvir_config_domain_timer_get_type(void);
 
+GVirConfigDomainTimerTickPolicy 
gvir_config_domain_timer_get_tick_policy(GVirConfigDomainTimer *timer);
+void gvir_config_domain_timer_set_tick_policy(GVirConfigDomainTimer *timer, 
GVirConfigDomainTimerTickPolicy policy);
+
 G_END_DECLS
 
 #endif /* __LIBVIRT_GCONFIG_DOMAIN_TIMER_H__ */
diff --git a/libvirt-gconfig/libvirt-gconfig.sym 
b/libvirt-gconfig/libvirt-gconfig.sym
index 77d0a45..386597b 100644
--- a/libvirt-gconfig/libvirt-gconfig.sym
+++ b/libvirt-gconfig/libvirt-gconfig.sym
@@ -227,6 +227,9 @@ LIBVIRT_GCONFIG_0.0.7 {
gvir_config_domain_sound_set_model;
 
gvir_config_domain_timer_get_type;
+   gvir_config_domain_timer_tick_policy_get_type;
+   gvir_config_domain_timer_get_tick_policy;
+   gvir_config_domain_timer_set_tick_policy;
 
gvir_config_domain_video_get_type;
gvir_config_domain_video_model_get_type;
-- 
1.7.10

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


[libvirt] [PATCH] Web placeholder for pending patches on the web site

2012-04-13 Thread Daniel Veillard
This is based on recent developments on patch checker and the
goal is to keep a list of pending patches needing review on the
project web site. The page template in git just hold a pointer
to the web page.

diff --git a/docs/pending.html.in b/docs/pending.html.in
new file mode 100644
index 000..dfbe647
--- /dev/null
+++ b/docs/pending.html.in
@@ -0,0 +1,13 @@
+
+  
+
+Pending patches needing review
+  
+  
+Pending patches needing review
+ A list of pending patches needing review upstream is available
+on http://libvirt.org/pending.html";>the project pending
+patches page.
+  
+
+
diff --git a/docs/sitemap.html.in b/docs/sitemap.html.in
index 1de2b20..8f58d46 100644
--- a/docs/sitemap.html.in
+++ b/docs/sitemap.html.in
@@ -332,6 +332,10 @@
 Todo list
 Main feature request list
   
+  
+Pending patches
+Pending patches awaiting reviews and integration
+  
 
   
   

-- 
Daniel Veillard  | libxml Gnome XML XSLT toolkit  http://xmlsoft.org/
dan...@veillard.com  | Rpmfind RPM search engine http://rpmfind.net/
http://veillard.com/ | virtualization library  http://libvirt.org/

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


[libvirt] [PATCH V9 3/6] nwfilter: Fix support for trusted DHCP servers

2012-04-13 Thread Stefan Berger
Fix the support for trusted DHCP server in the ebtables code's
hard-coded function applying DHCP only filtering rules:
Rather than using a char * use the more flexible
virNWFilterVarValuePtr that contains the trusted DHCP server(s)
IP address. Process all entries.

Since all callers so far provided NULL as parameter, no changes
are necessary in any other code.

---
 src/conf/nwfilter_conf.h  |2 
 src/nwfilter/nwfilter_ebiptables_driver.c |   72 +-
 2 files changed, 44 insertions(+), 30 deletions(-)

Index: libvirt-acl/src/conf/nwfilter_conf.h
===
--- libvirt-acl.orig/src/conf/nwfilter_conf.h
+++ libvirt-acl/src/conf/nwfilter_conf.h
@@ -625,7 +625,7 @@ typedef int (*virNWFilterApplyBasicRules
 
 typedef int (*virNWFilterApplyDHCPOnlyRules)(const char *ifname,
  const unsigned char *macaddr,
- const char *dhcpserver,
+ virNWFilterVarValuePtr dhcpsrvs,
  bool leaveTemporary);
 
 typedef int (*virNWFilterRemoveBasicRules)(const char *ifname);
Index: libvirt-acl/src/nwfilter/nwfilter_ebiptables_driver.c
===
--- libvirt-acl.orig/src/nwfilter/nwfilter_ebiptables_driver.c
+++ libvirt-acl/src/nwfilter/nwfilter_ebiptables_driver.c
@@ -3195,7 +3195,7 @@ tear_down_tmpebchains:
  * @ifname: name of the backend-interface to which to apply the rules
  * @macaddr: MAC address the VM is using in packets sent through the
  *interface
- * @dhcpserver: The DHCP server from which the VM may receive traffic
+ * @dhcpsrvrs: The DHCP server(s) from which the VM may receive traffic
  *from; may be NULL
  * @leaveTemporary: Whether to leave the table names with their temporary
  *names (true) or also perform the renaming to their final names as
@@ -3209,14 +3209,15 @@ tear_down_tmpebchains:
 static int
 ebtablesApplyDHCPOnlyRules(const char *ifname,
const unsigned char *macaddr,
-   const char *dhcpserver,
+   virNWFilterVarValuePtr dhcpsrvrs,
bool leaveTemporary)
 {
 virBuffer buf = VIR_BUFFER_INITIALIZER;
 char chain_in [MAX_CHAINNAME_LENGTH],
  chain_out[MAX_CHAINNAME_LENGTH];
 char macaddr_str[VIR_MAC_STRING_BUFLEN];
-char *srcIPParam = NULL;
+unsigned int idx = 0;
+unsigned int num_dhcpsrvrs;
 
 if (!ebtables_cmd_path) {
 virNWFilterReportError(VIR_ERR_INTERNAL_ERROR, "%s",
@@ -3225,15 +3226,6 @@ ebtablesApplyDHCPOnlyRules(const char *i
 return -1;
 }
 
-if (dhcpserver) {
-virBufferAsprintf(&buf, " --ip-src %s", dhcpserver);
-if (virBufferError(&buf)) {
-virBufferFreeAndReset(&buf);
-return -1;
-}
-srcIPParam = virBufferContentAndReset(&buf);
-}
-
 virMacAddrFormat(macaddr, macaddr_str);
 
 ebiptablesAllTeardown(ifname);
@@ -3267,20 +3259,46 @@ ebtablesApplyDHCPOnlyRules(const char *i
   chain_in,
   CMD_STOPONERR(1));
 
-virBufferAsprintf(&buf,
-  CMD_DEF("$EBT -t nat -A %s"
-  " -d %s"
-  " -p ipv4 --ip-protocol udp"
-  " %s"
-  " --ip-sport 67 --ip-dport 68"
-  " -j ACCEPT") CMD_SEPARATOR
-  CMD_EXEC
-  "%s",
+num_dhcpsrvrs = (dhcpsrvrs != NULL)
+? virNWFilterVarValueGetCardinality(dhcpsrvrs)
+: 0;
 
-  chain_out,
-  macaddr_str,
-  srcIPParam != NULL ? srcIPParam : "",
-  CMD_STOPONERR(1));
+while (true) {
+char *srcIPParam = NULL;
+
+if (idx < num_dhcpsrvrs) {
+const char *dhcpserver;
+
+dhcpserver = virNWFilterVarValueGetNthValue(dhcpsrvrs, idx);
+
+if (virAsprintf(&srcIPParam, "--ip-src %s", dhcpserver) < 0) {
+virReportOOMError();
+goto tear_down_tmpebchains;
+}
+}
+
+virBufferAsprintf(&buf,
+  CMD_DEF("$EBT -t nat -A %s"
+  " -d %s"
+  " -p ipv4 --ip-protocol udp"
+  " %s"
+  " --ip-sport 67 --ip-dport 68"
+  " -j ACCEPT") CMD_SEPARATOR
+  CMD_EXEC
+  "%s",
+
+  chain_out,
+  macaddr_str,
+  srcIPParam != NULL ? srcIPParam : "",
+  CMD_S

[libvirt] [PATCH V9 5/6] nwfilter: move code for IP address map into separate file

2012-04-13 Thread Stefan Berger
The goal of this patch is to prepare for support for multiple IP
addresses per interface in the DHCP snooping code.

Move the code for the IP address map that maps interface names to
IP addresses into their own file. Rename the functions on the way
but otherwise leave the code as-is. Initialize this new layer
separately before dependent layers (iplearning, dhcpsnooping)
and shut it down after them.

---
 src/Makefile.am|2 
 src/nwfilter/nwfilter_driver.c |   11 +-
 src/nwfilter/nwfilter_gentech_driver.c |5 
 src/nwfilter/nwfilter_ipaddrmap.c  |  167 +
 src/nwfilter/nwfilter_ipaddrmap.h  |   37 +++
 src/nwfilter/nwfilter_learnipaddr.c|  126 
 src/nwfilter/nwfilter_learnipaddr.h|3 
 7 files changed, 220 insertions(+), 131 deletions(-)

Index: libvirt-acl/src/nwfilter/nwfilter_ipaddrmap.h
===
--- /dev/null
+++ libvirt-acl/src/nwfilter/nwfilter_ipaddrmap.h
@@ -0,0 +1,37 @@
+/*
+ * nwfilter_ipaddrmap.h: IP address map for mapping interfaces to their
+ *   detected/expected IP addresses
+ *
+ * Copyright (C) 2010, 2012 IBM Corp.
+ *
+ * Author:
+ * Stefan Berger 
+ *
+ * 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, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307  USA
+ *
+ */
+
+#ifndef __VIR_NWFILTER_IPADDRMAP_H
+# define __VIR_NWFILTER_IPADDRMAP_H
+
+int virNWFilterIPAddrMapInit(void);
+void virNWFilterIPAddrMapShutdown(void);
+
+int virNWFilterIPAddrMapAddIPAddr(const char *ifname, char *addr);
+int virNWFilterIPAddrMapDelIPAddr(const char *ifname,
+  const char *ipaddr);
+virNWFilterVarValuePtr virNWFilterIPAddrMapGetIPAddr(const char *ifname);
+
+#endif /* __VIR_NWFILTER_IPADDRMAP_H */
Index: libvirt-acl/src/Makefile.am
===
--- libvirt-acl.orig/src/Makefile.am
+++ libvirt-acl/src/Makefile.am
@@ -513,6 +513,8 @@ NWFILTER_DRIVER_SOURCES =   
\
nwfilter/nwfilter_dhcpsnoop.h   \
nwfilter/nwfilter_ebiptables_driver.c   \
nwfilter/nwfilter_ebiptables_driver.h   \
+   nwfilter/nwfilter_ipaddrmap.c   \
+   nwfilter/nwfilter_ipaddrmap.h   \
nwfilter/nwfilter_learnipaddr.c \
nwfilter/nwfilter_learnipaddr.h
 
Index: libvirt-acl/src/nwfilter/nwfilter_driver.c
===
--- libvirt-acl.orig/src/nwfilter/nwfilter_driver.c
+++ libvirt-acl/src/nwfilter/nwfilter_driver.c
@@ -39,6 +39,7 @@
 #include "nwfilter_gentech_driver.h"
 #include "configmake.h"
 
+#include "nwfilter_ipaddrmap.h"
 #include "nwfilter_dhcpsnoop.h"
 #include "nwfilter_learnipaddr.h"
 
@@ -67,10 +68,12 @@ static int
 nwfilterDriverStartup(int privileged) {
 char *base = NULL;
 
-if (virNWFilterDHCPSnoopInit() < 0)
+if (virNWFilterIPAddrMapInit() < 0)
 return -1;
 if (virNWFilterLearnInit() < 0)
-return -1;
+goto err_exit_ipaddrmapshutdown;
+if (virNWFilterDHCPSnoopInit() < 0)
+goto err_exit_learnshutdown;
 
 virNWFilterTechDriversInit(privileged);
 
@@ -131,7 +134,10 @@ alloc_err_exit:
 conf_init_err:
 virNWFilterTechDriversShutdown();
 virNWFilterDHCPSnoopShutdown();
+err_exit_learnshutdown:
 virNWFilterLearnShutdown();
+err_exit_ipaddrmapshutdown:
+virNWFilterIPAddrMapShutdown();
 
 return -1;
 }
@@ -210,6 +216,7 @@ nwfilterDriverShutdown(void) {
 virNWFilterTechDriversShutdown();
 virNWFilterDHCPSnoopShutdown();
 virNWFilterLearnShutdown();
+virNWFilterIPAddrMapShutdown();
 
 nwfilterDriverLock(driverState);
 
Index: libvirt-acl/src/nwfilter/nwfilter_gentech_driver.c
===
--- libvirt-acl.orig/src/nwfilter/nwfilter_gentech_driver.c
+++ libvirt-acl/src/nwfilter/nwfilter_gentech_driver.c
@@ -33,6 +33,7 @@
 #include "nwfilter_gentech_driver.h"
 #include "nwfilter_ebiptables_driver.h"
 #include "nwfilter_dhcpsnoop.h"
+#include "nwfilter_ipaddrmap.h"
 #inc

[libvirt] [PATCH V9 6/6] nwfilter: Add multiple IP address support to DHCP snooping

2012-04-13 Thread Stefan Berger
With support for multiple IP addresses per interface in place, this patch
now adds support for multiple IP addresses per interface for the DHCP
snooping code.


Testing:

Since the infrastructure I tested this with does not provide multiple IP
addresses per MAC address (anymore), I either had to plug the VM's interface
from the virtual bride connected directly to the infrastructure to virbr0
to get a 2nd IP address from dnsmasq (kill and run dhclient inside the VM)
or changed the lease file  (/var/run/libvirt/network/nwfilter.leases) and
restart libvirtd to have a 2nd IP address on an existing interface.
Note that dnsmasq can take a lease timeout parameter as part of the --dhcp-range
command line parameter, so that timeouts can be tested that way
(--dhcp-range 192.168.122.2,192.168.122.254,120). So, terminating and restarting
dnsmasq with that parameter is another choice to watch an IP address disappear
after 120 seconds.

Regards,
   Stefan

---
 src/nwfilter/nwfilter_dhcpsnoop.c |  102 ++
 1 file changed, 70 insertions(+), 32 deletions(-)

Index: libvirt-acl/src/nwfilter/nwfilter_dhcpsnoop.c
===
--- libvirt-acl.orig/src/nwfilter/nwfilter_dhcpsnoop.c
+++ libvirt-acl/src/nwfilter/nwfilter_dhcpsnoop.c
@@ -59,6 +59,7 @@
 #include "conf/domain_conf.h"
 #include "nwfilter_gentech_driver.h"
 #include "nwfilter_dhcpsnoop.h"
+#include "nwfilter_ipaddrmap.h"
 #include "virnetdev.h"
 #include "virfile.h"
 #include "viratomic.h"
@@ -222,7 +223,8 @@ struct _virNWFilterSnoopDHCPHdr {
 
 /* local function prototypes */
 static int virNWFilterSnoopReqLeaseDel(virNWFilterSnoopReqPtr req,
-   uint32_t ipaddr, bool update_leasefile);
+   uint32_t ipaddr, bool update_leasefile,
+   bool instantiate);
 
 static void virNWFilterSnoopReqLock(virNWFilterSnoopReqPtr req);
 static void virNWFilterSnoopReqUnlock(virNWFilterSnoopReqPtr req);
@@ -398,8 +400,8 @@ virNWFilterSnoopIPLeaseInstallRule(virNW
 {
 char ipbuf[INET_ADDRSTRLEN];
 int rc = -1;
-virNWFilterVarValuePtr ipVar;
 virNWFilterSnoopReqPtr req;
+char *ipaddr;
 
 if (!inet_ntop(AF_INET, &ipl->IPAddress, ipbuf, sizeof(ipbuf))) {
 virNWFilterReportError(VIR_ERR_INTERNAL_ERROR,
@@ -408,18 +410,19 @@ virNWFilterSnoopIPLeaseInstallRule(virNW
__func__, ipl->IPAddress);
 return -1;
 }
-ipVar = virNWFilterVarValueCreateSimpleCopyValue(ipbuf);
-if (!ipVar) {
+
+ipaddr = strdup(ipbuf);
+if (ipaddr == NULL) {
 virReportOOMError();
 return -1;
 }
-if (virNWFilterHashTablePut(ipl->SnoopReq->vars, "IP", ipVar, 1) < 0) {
-virNWFilterReportError(VIR_ERR_INTERNAL_ERROR,
-   _("Could not add variable \"IP\" to hashmap"));
-virNWFilterVarValueFree(ipVar);
+
+if (virNWFilterIPAddrMapAddIPAddr(ipl->SnoopReq->ifname, ipaddr) < 0) {
+VIR_FREE(ipaddr);
 return -1;
 }
 
+
 if (!instantiate)
 return 0;
 
@@ -480,12 +483,18 @@ static unsigned int
 virNWFilterSnoopReqLeaseTimerRun(virNWFilterSnoopReqPtr req)
 {
 time_t now = time(0);
+bool is_last = false;
 
 /* protect req->start */
 virNWFilterSnoopReqLock(req);
 
-while (req->start && req->start->Timeout <= now)
-virNWFilterSnoopReqLeaseDel(req, req->start->IPAddress, true);
+while (req->start && req->start->Timeout <= now) {
+if (req->start->next == NULL ||
+req->start->next->Timeout > now)
+is_last = true;
+virNWFilterSnoopReqLeaseDel(req, req->start->IPAddress, true,
+is_last);
+}
 
 virNWFilterSnoopReqUnlock(req);
 
@@ -552,7 +561,7 @@ virNWFilterSnoopReqFree(virNWFilterSnoop
 
 /* free all leases */
 for (ipl = req->start; ipl; ipl = req->start)
-virNWFilterSnoopReqLeaseDel(req, ipl->IPAddress, false);
+virNWFilterSnoopReqLeaseDel(req, ipl->IPAddress, false, false);
 
 /* free all req data */
 VIR_FREE(req->ifname);
@@ -685,15 +694,6 @@ virNWFilterSnoopReqLeaseAdd(virNWFilterS
 
 virNWFilterSnoopReqUnlock(req);
 
-/* support for multiple addresses requires the ability to add filters
- * to existing chains, or to instantiate address lists via
- * virNWFilterInstantiateFilterLate(). Until one of those capabilities
- * is added, don't allow a new address when one is already assigned to
- * this interface.
- */
-if (req->start)
- return 0;/* silently ignore multiple addresses */
-
 if (VIR_ALLOC(pl) < 0) {
 virReportOOMError();
 return -1;
@@ -761,34 +761,64 @@ virNWFilterSnoopReqRestore(virNWFilterSn
  *memory or when calling this function while reading
  *leases from the file.
  *
+ * @instantiate: 

[libvirt] [PATCH V9 1/6] Implement virHashRemoveAll function

2012-04-13 Thread Stefan Berger
Implement function to remove all entries of a hash table.

---
 src/libvirt_private.syms |1 +
 src/util/virhash.c   |   25 +
 src/util/virhash.h   |5 +
 3 files changed, 31 insertions(+)

Index: libvirt-acl/src/libvirt_private.syms
===
--- libvirt-acl.orig/src/libvirt_private.syms
+++ libvirt-acl/src/libvirt_private.syms
@@ -578,6 +578,7 @@ virHashForEach;
 virHashFree;
 virHashGetItems;
 virHashLookup;
+virHashRemoveAll;
 virHashRemoveEntry;
 virHashRemoveSet;
 virHashSearch;
Index: libvirt-acl/src/util/virhash.c
===
--- libvirt-acl.orig/src/util/virhash.c
+++ libvirt-acl/src/util/virhash.c
@@ -575,6 +575,31 @@ virHashRemoveSet(virHashTablePtr table,
 return count;
 }
 
+static int
+_virHashRemoveAllIter(const void *payload ATTRIBUTE_UNUSED,
+  const void *name ATTRIBUTE_UNUSED,
+  const void *data ATTRIBUTE_UNUSED)
+{
+return 1;
+}
+
+/**
+ * virHashRemoveAll
+ * @table: the hash table to clear
+ *
+ * Free the hash @table's contents. The userdata is
+ * deallocated with the function provided at creation time.
+ *
+ * Returns the number of items removed on success, -1 on failure
+ */
+ssize_t
+virHashRemoveAll(virHashTablePtr table)
+{
+return virHashRemoveSet(table,
+_virHashRemoveAllIter,
+NULL);
+}
+
 /**
  * virHashSearch:
  * @table: the hash table to search
Index: libvirt-acl/src/util/virhash.h
===
--- libvirt-acl.orig/src/util/virhash.h
+++ libvirt-acl/src/util/virhash.h
@@ -127,6 +127,11 @@ int virHashRemoveEntry(virHashTablePtr t
const void *name);
 
 /*
+ * Remove all entries from the hash table.
+ */
+ssize_t virHashRemoveAll(virHashTablePtr table);
+
+/*
  * Retrieve the userdata.
  */
 void *virHashLookup(virHashTablePtr table, const void *name);

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


Re: [libvirt] [PATCHv4 12/18] blockjob: implement block copy for qemu

2012-04-13 Thread Eric Blake
On 04/13/2012 08:46 AM, Jiri Denemark wrote:
> On Mon, Apr 09, 2012 at 21:52:21 -0600, Eric Blake wrote:
>> Minimal patch to wire up all the pieces in the previous patches
>> to actually enable a block copy job.  By minimal, I mean that
>> qemu creates the file (that is, no REUSE_EXT flag support yet),
>> SELinux must be disabled, a lock manager is not informed, and
>> the audit logs aren't updated.  But those will be added as
>> improvements in future patches.
>>
>> * src/qemu/qemu_driver.c (qemuDomainBlockCopy): New function.
>> (qemuDomainBlockRebase): Call it when appropriate.
>> ---
>>  src/qemu/qemu_driver.c |  114 
>> +++-
>>  1 files changed, 113 insertions(+), 1 deletions(-)

>> +
>> +priv = vm->privateData;
>> +if (!(qemuCapsGet(priv->qemuCaps, QEMU_CAPS_DRIVE_MIRROR) &&
>> +  qemuCapsGet(priv->qemuCaps, QEMU_CAPS_DRIVE_REOPEN))) {
>> +qemuReportError(VIR_ERR_OPERATION_INVALID, "%s",
> 
> We usually use VIR_ERR_CONFIG_UNSUPPORTED in such cases.

Sure, easy to fix.  Actually, looking at 'git grep -B3 -i "qemu binary"
src/qemu', I counted an INTERNAL_ERROR, an OPERATION_FAILED, and a
couple of OPERATION_INVALID that should all be cleaned up, to match the
fact that the majority of uses did indeed favor CONFIG_UNSUPPORTED.
I'll split the cleanup into a separate patch.

> 
>> +_("block copy is not supported with this QEMU 
>> binary"));
>> +goto cleanup;
>> +}
>> +if (vm->persistent) {
>> +qemuReportError(VIR_ERR_OPERATION_INVALID, "%s",
>> +_("domain is not transient"));
>> +goto cleanup;
>> +}
> 
> I guess I wasn't paying enough attention somewhere but why do we forbid block
> copy for persistent domains? I understand why we want to forbid certain
> operations when block copy is active but I don't see a reason for penalizing
> persistent domains.

It was in patch 8/18 where I added the restrictions, and hopefully
documented in that commit message why limiting things to transient is a
good first step:

1. the first client of live migration is oVirt, which uses transient domains

2. qemu does not (yet) provide a way to resume a mirror when restarting
a domain, so anything that would require restoring a domain from saved
state is broken: incoming migration, virsh restore, and virsh start
after a managed save.  But users would be upset if they saved a domain,
only to find out that they cannot then restore it, so I squelched things
one step earlier in the process, by preventing any save of a domain so
that we never have a broken save image in the first place.

My worry now comes from the fact that managedsave is on the list of
forbidden operations.  If a domain is transient, managedsave is already
forbidden (it is assumed that you either don't care about the domain if
the host dies, or that you are running a higher-level app like oVirt
that knows how to rebuild the guest on a different host).  But if a
guest is persistent, and you use the libvirt-guests init script, then
you have a right to assume that rebooting your host will resume your
guests in the same state that they were prior to the host going down -
because libvirt-guests uses managedsave.  If we allow a mirror job on a
persistent domain, we violate this assumption (libvirt-guests will fail
to save the guest).  Therefore, I forbid to start a mirror job on a
persistent domain, just as I forbid to 'virsh define' a transient domain
into a persistent domain if a mirror job is active.

If, at a later date, qemu comes up with a way to resume mirroring when
restarting a domain, we can relax these restrictions.

>> +
>> +/* Actually start the mirroring */
>> +qemuDomainObjEnterMonitorWithDriver(driver, vm);
>> +ret = qemuMonitorDriveMirror(priv->mon, NULL, device, dest, format, 
>> flags);
>> +if (ret == 0 && bandwidth != 0)
>> +ret = qemuMonitorBlockJob(priv->mon, device, NULL, bandwidth, NULL,
>> +  BLOCK_JOB_SPEED_INTERNAL);
>> +qemuDomainObjExitMonitorWithDriver(driver, vm);
> 
> Can BLOCK_JOB_SPEED_INTERNAL fail while block copy remains running? If so, we
> should try to abort the job in case we fail to set the speed, otherwise we
> will report an error and forget about the job while qemu will keep copying
> data.

Good catch, and virDomainBlockPull() suffers from the same
ramifications.  I think both code paths need the same fix.

>> @@ -11889,6 +12000,7 @@ static int
>>  qemuDomainBlockPull(virDomainPtr dom, const char *path, unsigned long 
>> bandwidth,
>>  unsigned int flags)
>>  {
>> +virCheckFlags(0, -1);
>>  return qemuDomainBlockRebase(dom, path, NULL, bandwidth, flags);
>>  }
> 
> Hmm, personally, I would make qemuDomainBlockPull call qemuDomainBlockJobImpl
> directly instead of going through qemuDomainBlockRebase while adding the flags
> check...

Easy enough to change.

-- 
Eric Blake   ebl...@redhat.c

[libvirt] [PATCH V9 2/6] Support for atomic operations on integers

2012-04-13 Thread Stefan Berger
For threading support, add atomic add and sub operations working on
integers. Base this on locking support provided by virMutex.

---
 src/util/viratomic.h |   91 +++
 1 file changed, 91 insertions(+)

Index: libvirt-acl/src/util/viratomic.h
===
--- /dev/null
+++ libvirt-acl/src/util/viratomic.h
@@ -0,0 +1,91 @@
+/*
+ * viratomic.h: atomic integer operations
+ *
+ * Copyright (C) 2012 IBM Corporation
+ *
+ * Authors:
+ * Stefan Berger 
+ *
+ * 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, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307  USA
+ *
+ */
+
+#ifndef __VIR_ATOMIC_H__
+# define __VIR_ATOMIC_H__
+
+# include "threads.h"
+
+typedef struct _virAtomicInt virAtomicInt;
+typedef virAtomicInt *virAtomicIntPtr;
+
+struct _virAtomicInt {
+virMutex lock;
+int value;
+};
+
+static inline int
+virAtomicIntInit(virAtomicIntPtr vaip)
+{
+vaip->value = 0;
+return virMutexInit(&vaip->lock);
+}
+
+static inline void
+virAtomicIntSet(virAtomicIntPtr vaip, int value)
+{
+ virMutexLock(&vaip->lock);
+
+ vaip->value = value;
+
+ virMutexUnlock(&vaip->lock);
+}
+
+static inline int
+virAtomicIntRead(virAtomicIntPtr vaip)
+{
+ return vaip->value;
+}
+
+static inline int
+virAtomicIntAdd(virAtomicIntPtr vaip, int add)
+{
+int ret;
+
+virMutexLock(&vaip->lock);
+
+vaip->value += add;
+ret = vaip->value;
+
+virMutexUnlock(&vaip->lock);
+
+return ret;
+}
+
+static inline int
+virAtomicIntSub(virAtomicIntPtr vaip, int sub)
+{
+int ret;
+
+virMutexLock(&vaip->lock);
+
+vaip->value -= sub;
+ret = vaip->value;
+
+virMutexUnlock(&vaip->lock);
+
+return ret;
+}
+
+#endif /* __VIR_ATOMIC_H */

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


[libvirt] [PATCH V9 0/6] Add DHCP snooping support to nwfilter

2012-04-13 Thread Stefan Berger
This series of patches adds DHCP snooping support to libvirt's
nwfilter subsystem.

DHCP snooping detects DHCP leases obtained by a VM and automatically
adjusts the network traffic filters to reflect the IP addresses
with which a VM may send its traffic, thus for example preventing
IP address spoofing.
Once leases on IP addresses expire or if a VM gives up on a
lease on an IP address, the filters are also adjusted.
All leases are persisted and automatically applied upon a VM's restart.
Leases are associated with the tuple of VM-UUID and interface MAC
address.

The following interface XML activates and uses the DHCP snooping:


  
  

  



Regards,
   David and Stefan

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


Re: [libvirt] [PATCHv4 12/18] blockjob: implement block copy for qemu

2012-04-13 Thread Jiri Denemark
On Mon, Apr 09, 2012 at 21:52:21 -0600, Eric Blake wrote:
> Minimal patch to wire up all the pieces in the previous patches
> to actually enable a block copy job.  By minimal, I mean that
> qemu creates the file (that is, no REUSE_EXT flag support yet),
> SELinux must be disabled, a lock manager is not informed, and
> the audit logs aren't updated.  But those will be added as
> improvements in future patches.
> 
> * src/qemu/qemu_driver.c (qemuDomainBlockCopy): New function.
> (qemuDomainBlockRebase): Call it when appropriate.
> ---
>  src/qemu/qemu_driver.c |  114 
> +++-
>  1 files changed, 113 insertions(+), 1 deletions(-)
> 
> diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c
> index 2207184..6d5a5da 100644
> --- a/src/qemu/qemu_driver.c
> +++ b/src/qemu/qemu_driver.c
> @@ -11877,10 +11877,121 @@ qemuDomainBlockJobSetSpeed(virDomainPtr dom, const 
> char *path,
>  }
> 
>  static int
> +qemuDomainBlockCopy(virDomainPtr dom, const char *path,
> +const char *dest, const char *format,
> +unsigned long bandwidth, unsigned int flags)
> +{
> +struct qemud_driver *driver = dom->conn->privateData;
> +virDomainObjPtr vm = NULL;
> +qemuDomainObjPrivatePtr priv;
> +char uuidstr[VIR_UUID_STRING_BUFLEN];
> +char *device = NULL;
> +virDomainDiskDefPtr disk;
> +int ret = -1;
> +int idx;
> +
> +/* Preliminaries: find the disk we are editing, sanity checks */
> +virCheckFlags(VIR_DOMAIN_BLOCK_REBASE_SHALLOW, -1);
> +
> +qemuDriverLock(driver);
> +virUUIDFormat(dom->uuid, uuidstr);
> +vm = virDomainFindByUUID(&driver->domains, dom->uuid);
> +if (!vm) {
> +qemuReportError(VIR_ERR_NO_DOMAIN,
> +_("no domain with matching uuid '%s'"), uuidstr);
> +goto cleanup;
> +}
> +
> +device = qemuDiskPathToAlias(vm, path, &idx);
> +if (!device) {
> +goto cleanup;
> +}
> +disk = vm->def->disks[idx];
> +if (disk->mirror) {
> +qemuReportError(VIR_ERR_BLOCK_COPY_ACTIVE,
> +_("disk '%s' already in active block copy job"),
> +disk->dst);
> +goto cleanup;
> +}
> +
> +priv = vm->privateData;
> +if (!(qemuCapsGet(priv->qemuCaps, QEMU_CAPS_DRIVE_MIRROR) &&
> +  qemuCapsGet(priv->qemuCaps, QEMU_CAPS_DRIVE_REOPEN))) {
> +qemuReportError(VIR_ERR_OPERATION_INVALID, "%s",

We usually use VIR_ERR_CONFIG_UNSUPPORTED in such cases.

> +_("block copy is not supported with this QEMU 
> binary"));
> +goto cleanup;
> +}
> +if (vm->persistent) {
> +qemuReportError(VIR_ERR_OPERATION_INVALID, "%s",
> +_("domain is not transient"));
> +goto cleanup;
> +}

I guess I wasn't paying enough attention somewhere but why do we forbid block
copy for persistent domains? I understand why we want to forbid certain
operations when block copy is active but I don't see a reason for penalizing
persistent domains.

> +
> +if (qemuDomainObjBeginJobWithDriver(driver, vm, QEMU_JOB_MODIFY) < 0)
> +goto cleanup;
> +
> +if (!virDomainObjIsActive(vm)) {
> +qemuReportError(VIR_ERR_OPERATION_INVALID, "%s",
> +_("domain is not running"));
> +goto endjob;
> +}
> +
> +/* Prepare the destination file.  */
> +/* XXX We also need to add security labeling, lock manager lease,
> + * and auditing of those events, as well as to support reuse of
> + * existing images, including probing the existing format of an
> + * existing image.  */
> +if (!format)
> +format = disk->driverType;
> +if ((format && !(disk->mirrorFormat = strdup(format))) ||
> +!(disk->mirror = strdup(dest))) {
> +virReportOOMError();
> +goto endjob;
> +}
> +
> +/* Actually start the mirroring */
> +qemuDomainObjEnterMonitorWithDriver(driver, vm);
> +ret = qemuMonitorDriveMirror(priv->mon, NULL, device, dest, format, 
> flags);
> +if (ret == 0 && bandwidth != 0)
> +ret = qemuMonitorBlockJob(priv->mon, device, NULL, bandwidth, NULL,
> +  BLOCK_JOB_SPEED_INTERNAL);
> +qemuDomainObjExitMonitorWithDriver(driver, vm);

Can BLOCK_JOB_SPEED_INTERNAL fail while block copy remains running? If so, we
should try to abort the job in case we fail to set the speed, otherwise we
will report an error and forget about the job while qemu will keep copying
data.

> +
> +endjob:
> +if (ret < 0) {
> +VIR_FREE(disk->mirror);
> +VIR_FREE(disk->mirrorFormat);
> +}
> +if (qemuDomainObjEndJob(driver, vm) == 0) {
> +vm = NULL;
> +goto cleanup;
> +}
> +
> +cleanup:
> +VIR_FREE(device);
> +if (vm)
> +virDomainObjUnlock(vm);
> +qemuDriverUnlock(driver);
> +return ret;
> +}
> +
> +static int
>  qemuDomainBlockRebase(v

[libvirt] ANNOUNCE: Release of libvirt-sandbox version 0.0.3

2012-04-13 Thread Daniel P. Berrange
I pleased to announce the a new public release of libvirt-sandbox,
version 0.0.3, is now available for download

  ftp://libvirt.org/libvirt/sandbox/

The packages are GPG signed with

Key fingerprint: DAF3 A6FD B26B 6291 2D0E  8E3F BE86 EBB4 1510 4FDF (4096R)

The libvirt-sandbox package provides an API layer on top of libvirt-gobject
which facilitates the cration of application sandboxes using virtualization
technology. An application sandbox is a virtual machine or container that
runs a single application binary, directly from the host OS filesystem.
In other words there is no separate guest operating system install to build
or manager.

At this point in time libvirt-sandbox can create sandboxes using either LXC
or KVM, and should in theory be extendable to any libvirt driver. The first
release is able to run simple command line based programs. This release has
focused on making the sandbox infrastructure more reliable and expanding
the functionality available. Dan Walsh has also contributed a new tool called
virt-sandbox-service which facilitates the creation of sandboxes for running
system services like apache.

 - Ensure root/config filesystems are readonly in KVM
 - Add support for mounting host disk images in guests
 - Add support for binding guest filesystems to new locations
 - Add support for an optional interactive shell for debugging
   or administrative purposes
 - Add a virt-sandbox-service script for preparing sandboxes
   for system services, integrating with systemd
 - Misc compiler warning fixes
 - Replace invocation of insmod with direct syscalls
 - Refactor API to separate interactive sandbox functionality
   from base class & service sandbox functionality
 - Rewrite host/guest I/O handling to separate stdout from
   stderr correctly, improve reliability of startup/shutdown
   handshakes and propagate exit status back to host
 - Exec away the first hypervisor specific init process,
   so generic init process get PID 1
 - Turn on reboot-on-panic in KVM to ensure guest exists on
   fatal problems


Some examples

$ virt-sandbox -c qemu:///session  /bin/date
Thu Jan 12 22:30:03 GMT 2012


$ virt-sandbox -c qemu:///session /bin/cat /proc/cpuinfo
processor   : 0
vendor_id   : GenuineIntel
cpu family  : 6
model   : 2
model name  : QEMU Virtual CPU version 1.0
stepping: 3
cpu MHz : 2793.084
cache size  : 4096 KB
fpu : yes
fpu_exception   : yes
cpuid level : 4
wp  : yes
flags   : fpu de pse tsc msr pae mce cx8 apic sep mtrr pge mca cmov 
pse36 clflush mmx fxsr sse sse2 syscall nx lm up rep_good nopl
+pni cx16 hypervisor lahf_lm
bogomips: 5586.16
clflush size: 64
cache_alignment : 64
address sizes   : 40 bits physical, 48 bits virtual
power management:



$ virt-sandbox -c lxc:/// /bin/sh
sh-4.2$ ps -axuwf
USER   PID %CPU %MEMVSZ   RSS TTY  STAT START   TIME COMMAND
berrange 1  0.0  0.1 167680  4688 pts/0S+   22:31   0:00 
libvirt-sandbox-init-common
berrange47  0.0  0.0  13852  1608 pts/1Ss   22:31   0:00  \_ /bin/sh
berrange48  0.0  0.0  13124   996 pts/1R+   22:31   0:00  \_ ps 
-axuwf


Feedback / patches / etc should be directed to the main libvirt
development mailing list.

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

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


Re: [libvirt] [PATCH] storage: lvm: use correct lv* command parameters

2012-04-13 Thread Cole Robinson
On 04/13/2012 09:03 AM, Osier Yang wrote:
> On 04/13/2012 07:50 PM, Cole Robinson wrote:
>> lvcreate want's the parent pool's name, not the pool path
>> lvchange and lvremove want lv specified as $vgname/$lvname
>>
>> This largely worked before because these commands strip off a
>> starting /dev. But https://bugzilla.redhat.com/show_bug.cgi?id=714986
>> is from a user using a 'nested VG' that was having problems.
>>
>> I couldn't find any info on nested LVM and the reporter never responded,
>> but I reproduced with XML that specified a valid source name, and
>> set target path to a symlink.
>>
>> Signed-off-by: Cole Robinson
>> ---
>>   src/storage/storage_backend_logical.c |   21 +++--
>>   1 files changed, 11 insertions(+), 10 deletions(-)
>>
>> diff --git a/src/storage/storage_backend_logical.c
>> b/src/storage/storage_backend_logical.c
>> index 6a235f6..9a91dd9 100644
>> --- a/src/storage/storage_backend_logical.c
>> +++ b/src/storage/storage_backend_logical.c
>> @@ -672,7 +672,7 @@ virStorageBackendLogicalCreateVol(virConnectPtr conn,
>>   char size[100];
>>   const char *cmdargvnew[] = {
>>   LVCREATE, "--name", vol->name, "-L", size,
>> -pool->def->target.path, NULL
>> +pool->def->source.name, NULL
> 
> This makes sense.
> 
>>   };
>>   const char *cmdargvsnap[] = {
>>   LVCREATE, "--name", vol->name, "-L", size,
>> @@ -778,23 +778,23 @@ virStorageBackendLogicalDeleteVol(virConnectPtr conn
>> ATTRIBUTE_UNUSED,
>> unsigned int flags)
>>   {
>>   int ret = -1;
>> +char *volpath = NULL;
>>
>>   virCommandPtr lvchange_cmd = NULL;
>>   virCommandPtr lvremove_cmd = NULL;
>>
>>   virCheckFlags(0, -1);
>>
>> -virFileWaitForDevices();
>> +if (virAsprintf(&volpath, "%s/%s",
>> +pool->def->source.name, vol->name)<  0) {
>> +virReportOOMError();
>> +goto cleanup;
>> +}
>>
>> -lvchange_cmd = virCommandNewArgList(LVCHANGE,
>> -"-aln",
>> -vol->target.path,
>> -NULL);
>> +virFileWaitForDevices();
>>
>> -lvremove_cmd = virCommandNewArgList(LVREMOVE,
>> -"-f",
>> -vol->target.path,
>> -NULL);
>> +lvchange_cmd = virCommandNewArgList(LVCHANGE, "-aln", volpath, NULL);
>> +lvremove_cmd = virCommandNewArgList(LVREMOVE, "-f", volpath, NULL);
> 
> I tried with both vol->target.path, and $vgname/$lvname, both
> of them work. So do we really need these changes?

They both work, just like lvcreate /dev/myvgname also works. But we do need
this if this 'nested lvm' thing actually exists as the reporter mentioned, or
user uses a symlink as the target path (I'm not saying that's a valid use case
but it's a data point).

Also the man pages for lvremove and lvchange but use that format in their
examples.

Thanks,
Cole

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


Re: [libvirt] Start of freeze for libvirt-0.9.11 and availability of rc1

2012-04-13 Thread Philipp Hahn
Hello Guido,

Am Freitag 13 April 2012 15:10:49 schrieb Guido Günther:
> könntest Du das als richtigen Patch schicken, dann apply ich das.
[Guido asks me to send a full patch, so he can apply it.]

Sure, see the attached patch.

Sincerely
Philipp
-- 
Philipp Hahn   Open Source Software Engineer  h...@univention.de
Univention GmbHbe open.   fon: +49 421 22 232- 0
Mary-Somerville-Str.1  D-28359 Bremen fax: +49 421 22 232-99
   http://www.univention.de/
From 800a2689ea22842abebdff8568f105ca28dfad15 Mon Sep 17 00:00:00 2001
From: Philipp Hahn 
Date: Fri, 13 Apr 2012 15:43:58 +0200
Subject: [PATCH] virnetdev: Check for defined IFLA_VF_*
To: libvir-list@redhat.com

The linux-2.6.32 kernel header does not yet define IFLA_VF_MAX and others,
which breaks compiling a new libvirt on old systems like Debian Squeeze.

(I also have to add --without-macvtap --disable-werror --without-virtualport to
 ./configure to get it to compile.)

Signed-off-by: Philipp Hahn 
---
 src/util/virnetdev.c |2 +-
 1 files changed, 1 insertions(+), 1 deletions(-)

diff --git a/src/util/virnetdev.c b/src/util/virnetdev.c
index ec7435a..460aa83 100644
--- a/src/util/virnetdev.c
+++ b/src/util/virnetdev.c
@@ -1215,7 +1215,7 @@ virNetDevGetVirtualFunctionInfo(const char *vfname ATTRIBUTE_UNUSED,
 return -1;
 }
 #endif /* !__linux__ */
-#if defined(__linux__) && defined(HAVE_LIBNL)
+#if defined(__linux__) && defined(HAVE_LIBNL) && defined(IFLA_VF_MAX)
 
 static struct nla_policy ifla_vf_policy[IFLA_VF_MAX+1] = {
 [IFLA_VF_MAC]   = { .type = NLA_UNSPEC,
-- 
1.7.2.5



signature.asc
Description: This is a digitally signed message part.
--
libvir-list mailing list
libvir-list@redhat.com
https://www.redhat.com/mailman/listinfo/libvir-list

Re: [libvirt] [libvirt-glib] Getter/setter for disk source's startupPolicy attribute

2012-04-13 Thread Christophe Fergeau
On Fri, Apr 13, 2012 at 04:41:32PM +0300, Zeeshan Ali (Khattak) wrote:
> On Fri, Apr 13, 2012 at 2:26 PM, Christophe Fergeau  
> wrote:
> > On Thu, Apr 12, 2012 at 11:50:30PM +0300, Zeeshan Ali (Khattak) wrote:
> >> From: "Zeeshan Ali (Khattak)" 
> >>
> >> ---
> >>  libvirt-gconfig/libvirt-gconfig-domain-disk.c |   26 
> >> +
> >>  libvirt-gconfig/libvirt-gconfig-domain-disk.h |    9 
> >>  libvirt-gconfig/libvirt-gconfig.sym           |    5 +++-
> >>  libvirt-gconfig/tests/test-domain-create.c    |    2 +
> >>  4 files changed, 41 insertions(+), 1 deletions(-)
> >>
> >> diff --git a/libvirt-gconfig/libvirt-gconfig-domain-disk.c 
> >> b/libvirt-gconfig/libvirt-gconfig-domain-disk.c
> >> index 5d0acb5..a29ea47 100644
> >> --- a/libvirt-gconfig/libvirt-gconfig-domain-disk.c
> >> +++ b/libvirt-gconfig/libvirt-gconfig-domain-disk.c
> >> @@ -127,6 +127,18 @@ void 
> >> gvir_config_domain_disk_set_snapshot_type(GVirConfigDomainDisk *disk,
> >>                                                 type, NULL);
> >>  }
> >>
> >> +void gvir_config_domain_disk_set_startup_policy(GVirConfigDomainDisk 
> >> *disk,
> >> +                                                
> >> GVirConfigDomainDiskStartupPolicy policy)
> >> +{
> >> +    const char *str;
> >> +
> >> +    g_return_if_fail(GVIR_CONFIG_IS_DOMAIN_DISK(disk));
> >> +    str = 
> >> gvir_config_genum_get_nick(GVIR_CONFIG_TYPE_DOMAIN_DISK_STARTUP_POLICY, 
> >> policy);
> >> +    g_return_if_fail(str != NULL);
> >> +    gvir_config_object_add_child_with_attribute(GVIR_CONFIG_OBJECT(disk),
> >> +                                                "source", 
> >> "startupPolicy", str);
> >> +}
> >> +
> >>  void gvir_config_domain_disk_set_source(GVirConfigDomainDisk *disk,
> >>                                          const char *source)
> >>  {
> >> @@ -235,6 +247,19 @@ 
> >> gvir_config_domain_disk_get_snapshot_type(GVirConfigDomainDisk *disk)
> >>                                                    
> >> GVIR_CONFIG_DOMAIN_DISK_SNAPSHOT_NO);
> >>  }
> >>
> >> +GVirConfigDomainDiskStartupPolicy
> >> +gvir_config_domain_disk_get_startup_policy(GVirConfigDomainDisk *disk)
> >> +{
> >> +    g_return_val_if_fail(GVIR_CONFIG_IS_DOMAIN_DISK(disk),
> >> +                         
> >> GVIR_CONFIG_DOMAIN_DISK_STARTUP_POLICY_MANDATORY);
> >> +
> >> +    return gvir_config_object_get_attribute_genum
> >> +                (GVIR_CONFIG_OBJECT(disk),
> >> +                 "source", "startupPolicy",
> >> +                 GVIR_CONFIG_TYPE_DOMAIN_DISK_STARTUP_POLICY,
> >> +                 GVIR_CONFIG_DOMAIN_DISK_STARTUP_POLICY_MANDATORY);
> >> +}
> >> +
> >>  const char *
> >>  gvir_config_domain_disk_get_source(GVirConfigDomainDisk *disk)
> >>  {
> >> @@ -291,6 +316,7 @@ 
> >> gvir_config_domain_disk_get_driver_cache(GVirConfigDomainDisk *disk)
> >>                                                    
> >> GVIR_CONFIG_TYPE_DOMAIN_DISK_CACHE_TYPE,
> >>                                                    
> >> GVIR_CONFIG_DOMAIN_DISK_CACHE_DEFAULT);
> >>  }
> >> +
> >>  GVirConfigDomainDiskBus
> >>  gvir_config_domain_disk_get_target_bus(GVirConfigDomainDisk *disk)
> >>  {
> >> diff --git a/libvirt-gconfig/libvirt-gconfig-domain-disk.h 
> >> b/libvirt-gconfig/libvirt-gconfig-domain-disk.h
> >> index 916421d..7e85d75 100644
> >> --- a/libvirt-gconfig/libvirt-gconfig-domain-disk.h
> >> +++ b/libvirt-gconfig/libvirt-gconfig-domain-disk.h
> >> @@ -95,6 +95,12 @@ typedef enum {
> >>      GVIR_CONFIG_DOMAIN_DISK_SNAPSHOT_EXTERNAL
> >>  } GVirConfigDomainDiskSnapshotType;
> >>
> >> +typedef enum {
> >> +    GVIR_CONFIG_DOMAIN_DISK_STARTUP_POLICY_MANDATORY,
> >> +    GVIR_CONFIG_DOMAIN_DISK_STARTUP_POLICY_REQUISITE,
> >> +    GVIR_CONFIG_DOMAIN_DISK_STARTUP_POLICY_OPTIONAL
> >> +} GVirConfigDomainDiskStartupPolicy;
> >> +
> >>  GType gvir_config_domain_disk_get_type(void);
> >>
> >>  GVirConfigDomainDisk *gvir_config_domain_disk_new(void);
> >> @@ -107,6 +113,8 @@ void 
> >> gvir_config_domain_disk_set_guest_device_type(GVirConfigDomainDisk *disk,
> >>                                                     
> >> GVirConfigDomainDiskGuestDeviceType type);
> >>  void gvir_config_domain_disk_set_snapshot_type(GVirConfigDomainDisk *disk,
> >>                                                 
> >> GVirConfigDomainDiskSnapshotType type);
> >> +void gvir_config_domain_disk_set_startup_policy(GVirConfigDomainDisk 
> >> *disk,
> >> +                                                
> >> GVirConfigDomainDiskStartupPolicy policy);
> >>  void gvir_config_domain_disk_set_source(GVirConfigDomainDisk *disk,
> >>                                          const char *source);
> >>  void gvir_config_domain_disk_set_driver_cache(GVirConfigDomainDisk *disk,
> >> @@ -123,6 +131,7 @@ void 
> >> gvir_config_domain_disk_set_target_dev(GVirConfigDomainDisk *disk,
> >>  GVirConfigDomainDiskType 
> >> gvir_config_domain_disk_get_disk_type(GVirConfigDomainDisk *disk);
> >>  GVirConfigDomainDiskGuestD

Re: [libvirt] [libvirt-glib] Getter/setter for disk source's startupPolicy attribute

2012-04-13 Thread Zeeshan Ali (Khattak)
On Fri, Apr 13, 2012 at 2:26 PM, Christophe Fergeau  wrote:
> On Thu, Apr 12, 2012 at 11:50:30PM +0300, Zeeshan Ali (Khattak) wrote:
>> From: "Zeeshan Ali (Khattak)" 
>>
>> ---
>>  libvirt-gconfig/libvirt-gconfig-domain-disk.c |   26 
>> +
>>  libvirt-gconfig/libvirt-gconfig-domain-disk.h |    9 
>>  libvirt-gconfig/libvirt-gconfig.sym           |    5 +++-
>>  libvirt-gconfig/tests/test-domain-create.c    |    2 +
>>  4 files changed, 41 insertions(+), 1 deletions(-)
>>
>> diff --git a/libvirt-gconfig/libvirt-gconfig-domain-disk.c 
>> b/libvirt-gconfig/libvirt-gconfig-domain-disk.c
>> index 5d0acb5..a29ea47 100644
>> --- a/libvirt-gconfig/libvirt-gconfig-domain-disk.c
>> +++ b/libvirt-gconfig/libvirt-gconfig-domain-disk.c
>> @@ -127,6 +127,18 @@ void 
>> gvir_config_domain_disk_set_snapshot_type(GVirConfigDomainDisk *disk,
>>                                                 type, NULL);
>>  }
>>
>> +void gvir_config_domain_disk_set_startup_policy(GVirConfigDomainDisk *disk,
>> +                                                
>> GVirConfigDomainDiskStartupPolicy policy)
>> +{
>> +    const char *str;
>> +
>> +    g_return_if_fail(GVIR_CONFIG_IS_DOMAIN_DISK(disk));
>> +    str = 
>> gvir_config_genum_get_nick(GVIR_CONFIG_TYPE_DOMAIN_DISK_STARTUP_POLICY, 
>> policy);
>> +    g_return_if_fail(str != NULL);
>> +    gvir_config_object_add_child_with_attribute(GVIR_CONFIG_OBJECT(disk),
>> +                                                "source", "startupPolicy", 
>> str);
>> +}
>> +
>>  void gvir_config_domain_disk_set_source(GVirConfigDomainDisk *disk,
>>                                          const char *source)
>>  {
>> @@ -235,6 +247,19 @@ 
>> gvir_config_domain_disk_get_snapshot_type(GVirConfigDomainDisk *disk)
>>                                                    
>> GVIR_CONFIG_DOMAIN_DISK_SNAPSHOT_NO);
>>  }
>>
>> +GVirConfigDomainDiskStartupPolicy
>> +gvir_config_domain_disk_get_startup_policy(GVirConfigDomainDisk *disk)
>> +{
>> +    g_return_val_if_fail(GVIR_CONFIG_IS_DOMAIN_DISK(disk),
>> +                         GVIR_CONFIG_DOMAIN_DISK_STARTUP_POLICY_MANDATORY);
>> +
>> +    return gvir_config_object_get_attribute_genum
>> +                (GVIR_CONFIG_OBJECT(disk),
>> +                 "source", "startupPolicy",
>> +                 GVIR_CONFIG_TYPE_DOMAIN_DISK_STARTUP_POLICY,
>> +                 GVIR_CONFIG_DOMAIN_DISK_STARTUP_POLICY_MANDATORY);
>> +}
>> +
>>  const char *
>>  gvir_config_domain_disk_get_source(GVirConfigDomainDisk *disk)
>>  {
>> @@ -291,6 +316,7 @@ 
>> gvir_config_domain_disk_get_driver_cache(GVirConfigDomainDisk *disk)
>>                                                    
>> GVIR_CONFIG_TYPE_DOMAIN_DISK_CACHE_TYPE,
>>                                                    
>> GVIR_CONFIG_DOMAIN_DISK_CACHE_DEFAULT);
>>  }
>> +
>>  GVirConfigDomainDiskBus
>>  gvir_config_domain_disk_get_target_bus(GVirConfigDomainDisk *disk)
>>  {
>> diff --git a/libvirt-gconfig/libvirt-gconfig-domain-disk.h 
>> b/libvirt-gconfig/libvirt-gconfig-domain-disk.h
>> index 916421d..7e85d75 100644
>> --- a/libvirt-gconfig/libvirt-gconfig-domain-disk.h
>> +++ b/libvirt-gconfig/libvirt-gconfig-domain-disk.h
>> @@ -95,6 +95,12 @@ typedef enum {
>>      GVIR_CONFIG_DOMAIN_DISK_SNAPSHOT_EXTERNAL
>>  } GVirConfigDomainDiskSnapshotType;
>>
>> +typedef enum {
>> +    GVIR_CONFIG_DOMAIN_DISK_STARTUP_POLICY_MANDATORY,
>> +    GVIR_CONFIG_DOMAIN_DISK_STARTUP_POLICY_REQUISITE,
>> +    GVIR_CONFIG_DOMAIN_DISK_STARTUP_POLICY_OPTIONAL
>> +} GVirConfigDomainDiskStartupPolicy;
>> +
>>  GType gvir_config_domain_disk_get_type(void);
>>
>>  GVirConfigDomainDisk *gvir_config_domain_disk_new(void);
>> @@ -107,6 +113,8 @@ void 
>> gvir_config_domain_disk_set_guest_device_type(GVirConfigDomainDisk *disk,
>>                                                     
>> GVirConfigDomainDiskGuestDeviceType type);
>>  void gvir_config_domain_disk_set_snapshot_type(GVirConfigDomainDisk *disk,
>>                                                 
>> GVirConfigDomainDiskSnapshotType type);
>> +void gvir_config_domain_disk_set_startup_policy(GVirConfigDomainDisk *disk,
>> +                                                
>> GVirConfigDomainDiskStartupPolicy policy);
>>  void gvir_config_domain_disk_set_source(GVirConfigDomainDisk *disk,
>>                                          const char *source);
>>  void gvir_config_domain_disk_set_driver_cache(GVirConfigDomainDisk *disk,
>> @@ -123,6 +131,7 @@ void 
>> gvir_config_domain_disk_set_target_dev(GVirConfigDomainDisk *disk,
>>  GVirConfigDomainDiskType 
>> gvir_config_domain_disk_get_disk_type(GVirConfigDomainDisk *disk);
>>  GVirConfigDomainDiskGuestDeviceType 
>> gvir_config_domain_disk_get_guest_device_type(GVirConfigDomainDisk *disk);
>>  GVirConfigDomainDiskSnapshotType 
>> gvir_config_domain_disk_get_snapshot_type(GVirConfigDomainDisk *disk);
>> +GVirConfigDomainDiskStartupPolicy 
>> gvir_config_domain_disk_get_startup_policy(GVirConfigDomainDisk *disk

[libvirt] [PATCH v2] libvirt: xen: do not use ioemu type for any emulated NIC

2012-04-13 Thread Stefan Bader
> I think it would be better if we just centralized this logic, as in,
> only set that (type ioemu) bit in conditional rather than 2. Should
> be pretty straightforward.

Did you have something like below in mind?

-Stefan

>From a0e214fa6dea9bd66616f37246067a2c631f4184 Mon Sep 17 00:00:00 2001
From: Stefan Bader 
Date: Thu, 12 Apr 2012 15:32:41 +0200
Subject: [PATCH] libvirt: xen: do not use ioemu type for any emulated NIC

When using the xm/xend stack to manage instances there is a bug
that causes the emulated interfaces to be unusable when the vif
config contains type=ioemu.

The current code already has a special quirk to not use this
keyword if no specific model is given for the emulated NIC
(defaulting to rtl8139).
Essentially it works because regardless of the type argument,i
the Xen stack always creates emulated and paravirt interfaces and
lets the guest decide which one to use. So neither xl nor xm stack
actually require the type keyword for emulated NICs.

[v2: move code around to have the exception in one case together]
Signed-off-by: Stefan Bader 
---
 src/xenxs/xen_sxpr.c |   28 +++-
 src/xenxs/xen_xm.c   |   27 ++-
 2 files changed, 29 insertions(+), 26 deletions(-)

diff --git a/src/xenxs/xen_sxpr.c b/src/xenxs/xen_sxpr.c
index e1bbd76..3a56345 100644
--- a/src/xenxs/xen_sxpr.c
+++ b/src/xenxs/xen_sxpr.c
@@ -1999,20 +1999,22 @@ xenFormatSxprNet(virConnectPtr conn,
 if (def->model != NULL)
 virBufferEscapeSexpr(buf, "(model '%s')", def->model);
 }
-else if (def->model == NULL) {
-/*
- * apparently (type ioemu) breaks paravirt drivers on HVM so skip
- * this from XEND_CONFIG_MAX_VERS_NET_TYPE_IOEMU
- */
-if (xendConfigVersion <= XEND_CONFIG_MAX_VERS_NET_TYPE_IOEMU)
-virBufferAddLit(buf, "(type ioemu)");
-}
-else if (STREQ(def->model, "netfront")) {
-virBufferAddLit(buf, "(type netfront)");
-}
 else {
-virBufferEscapeSexpr(buf, "(model '%s')", def->model);
-virBufferAddLit(buf, "(type ioemu)");
+if (def->model != NULL && STREQ(def->model, "netfront")) {
+virBufferAddLit(buf, "(type netfront)");
+}
+else {
+if (def->model != NULL) {
+virBufferEscapeSexpr(buf, "(model '%s')", def->model);
+}
+/*
+ * apparently (type ioemu) breaks paravirt drivers on HVM so skip
+ * this from XEND_CONFIG_MAX_VERS_NET_TYPE_IOEMU
+ */
+if (xendConfigVersion <= XEND_CONFIG_MAX_VERS_NET_TYPE_IOEMU) {
+virBufferAddLit(buf, "(type ioemu)");
+}
+}
 }
 
 if (!isAttach)
diff --git a/src/xenxs/xen_xm.c b/src/xenxs/xen_xm.c
index d65e97a..93a26f9 100644
--- a/src/xenxs/xen_xm.c
+++ b/src/xenxs/xen_xm.c
@@ -1381,20 +1381,21 @@ static int xenFormatXMNet(virConnectPtr conn,
 if (net->model != NULL)
 virBufferAsprintf(&buf, ",model=%s", net->model);
 }
-else if (net->model == NULL) {
-/*
- * apparently type ioemu breaks paravirt drivers on HVM so skip this
- * from XEND_CONFIG_MAX_VERS_NET_TYPE_IOEMU
- */
-if (xendConfigVersion <= XEND_CONFIG_MAX_VERS_NET_TYPE_IOEMU)
-virBufferAddLit(&buf, ",type=ioemu");
-}
-else if (STREQ(net->model, "netfront")) {
-virBufferAddLit(&buf, ",type=netfront");
-}
 else {
-virBufferAsprintf(&buf, ",model=%s", net->model);
-virBufferAddLit(&buf, ",type=ioemu");
+if (net->model != NULL && STREQ(net->model, "netfront")) {
+virBufferAddLit(&buf, ",type=netfront");
+}
+else {
+if (net->model != NULL)
+virBufferAsprintf(&buf, ",model=%s", net->model);
+
+/*
+ * apparently type ioemu breaks paravirt drivers on HVM so skip 
this
+ * from XEND_CONFIG_MAX_VERS_NET_TYPE_IOEMU
+ */
+if (xendConfigVersion <= XEND_CONFIG_MAX_VERS_NET_TYPE_IOEMU)
+virBufferAddLit(&buf, ",type=ioemu");
+}
 }
 
 if (net->ifname)
-- 
1.7.9.5

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


[libvirt] [PATCH] vbox: avoid provoking assertions in VBoxSVC

2012-04-13 Thread Jean-Baptiste Rouault
Passing a NULL pointer to IMachine::delete virtualbox API
causes VBoxSVC to raise an assertion. This patch passes
an empty array instead.
---
 src/vbox/vbox_tmpl.c |3 ++-
 1 files changed, 2 insertions(+), 1 deletions(-)

diff --git a/src/vbox/vbox_tmpl.c b/src/vbox/vbox_tmpl.c
index 68e3b05..be25828 100644
--- a/src/vbox/vbox_tmpl.c
+++ b/src/vbox/vbox_tmpl.c
@@ -5294,7 +5294,8 @@ vboxDomainUndefineFlags(virDomainPtr dom, unsigned int 
flags)
 
 ((IMachine_Delete)machine->vtbl->Delete)(machine, &safeArray, 
&progress);
 # else
-machine->vtbl->Delete(machine, 0, NULL, &progress);
+vboxArray array = VBOX_ARRAY_INITIALIZER;
+machine->vtbl->Delete(machine, 0, (IMedium**)&array, &progress);
 # endif
 if (progress != NULL) {
 progress->vtbl->WaitForCompletion(progress, -1);
-- 
1.7.9.1

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


Re: [libvirt] [PATCHv4 11/18] blockjob: support pivot operation on cancel

2012-04-13 Thread Jiri Denemark
On Mon, Apr 09, 2012 at 21:52:20 -0600, Eric Blake wrote:
> This is the bare minimum to end a copy job (of course, until a
> later patch adds the ability to start a copy job, this patch
> doesn't do much in isolation; I've just split the patches to
> ease the review).

Yeah, thanks for doing that.

> This patch intentionally avoids SELinux, lock manager, and audit
> actions, saving that for a later patch that affects the overall
> lifecycle of a disk copy.  In particular, I'm still fuzzy on the
> exact qemu error semantics, and whether I need to make more of
> an effort after a 'drive-reopen' fails.
> 
> When a mirror job is started, cancelling the job safely reverts back
> to the source disk, regardless of whether the destination is in
> phase 1 (streaming, in which case the destination is worthless) or
> phase 2 (mirroring, in which case the destination is sync'd up to
> the source at the time of the cancel).  Our existing code does just
> fine in either phase, other than some bookkeeping cleanup.
> 
> Pivoting the job requires the use of the new 'drive-reopen' command.
> Here, failure of the command is potentially catastrophic to the
> domain, since it rips out the old disk before attempting to open
> the new one; if our recovery path of retrying the reopen on the
> original source disk also fails, the domain is hosed.  If only qemu
> could get 'drive-reopen' inside 'transaction'...
> 
> Interesting side note: while snapshot-create --disk-only creates a
> copy of the disk at a point in time by moving the domain on to a
> new file (the copy is the file now in the just-extended backing
> chain), blockjob --abort of a copy job creates a copy of the disk
> while keeping the domain on the original file.  There may be
> potential improvements to the snapshot code to exploit block copy
> over multiple disks all at one point in time.  And, if
> 'block_job_cancel' were made part of 'transaction', you could
> copy multiple disks at the same point in time without pausing
> the domain.  This also implies we may want to add a --quiesce
> flag to the pivot operation, so that when breaking a mirror, the
> side of the mirror that we are abandoning is at least in a stable
> state with regards to guest I/O.
> 
> * src/qemu/qemu_driver.c (qemuDomainBlockJobAbort): Accept new flag.
> (qemuDomainBlockPivot): New helper function.
> (qemuDomainBlockJobImpl): Implement it.
> ---
>  src/qemu/qemu_driver.c |  115 +--
>  1 files changed, 110 insertions(+), 5 deletions(-)

OK

Jirka

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


Re: [libvirt] [test-API PATCH] repo: Add test for console input and output operations

2012-04-13 Thread Guannan Ren

On 04/13/2012 08:54 PM, Martin Kletzander wrote:

On 04/13/2012 11:41 AM, Peter Krempa wrote:

This test checks if the console input and output work as desired. The
test takes as an argument a filename, whose contents are sent to the
console. The optional parameter 'expect' can be set to a filename that
should contain expected output from the guest and is compared with the
actual output. The optional parameter 'output' can be set to a filename
where the test script saves the output of the host (useful for initial
test setup).

This test requires that the guest machine runs code that handles input and
output on the serial console (programs such as agetty or something like that).
---
  repos/domain/console_io.py |  123 
  1 files changed, 123 insertions(+), 0 deletions(-)
  create mode 100644 repos/domain/console_io.py

diff --git a/repos/domain/console_io.py b/repos/domain/console_io.py
new file mode 100644
index 000..98fd5b6
--- /dev/null
+++ b/repos/domain/console_io.py
@@ -0,0 +1,123 @@
+#!/usr/bin/env python
+# test console interactions
+# This test sends contents of file 'input' to the guest's console
+# and reads from the console the reply and compares it to 'expect' or
+# writes the output to file 'output'
+
+import libvirt
+import signal
+import os
+
+from libvirt import libvirtError
+from exception import TestError
+
+required_params = ('guestname',)
+optional_params = ('device', 'timeout', 'input', 'output', 'expect',)
+
+def alarm_handler(signum, frame):
+raise TestError("Timed out while waiting for console")
+
+def console_io(params):
+"""Attach to console"""
+logger = params['logger']
+guest = params['guestname']
+device = params.get('device', 'serial0')
+infile = params.get('input', None)
+outfile = params.get('output', None)
+expect = params.get('expect', None)
+timeout = params.get('timeout', 5)
+
+uri = params['uri']
+
+#store the old signal handler
+oldhandler = signal.getsignal(signal.SIGALRM)
+
+try:
+logger.info("Connecting to hypervisor: '%s'" % uri)
+conn = libvirt.open(uri)
+dom = conn.lookupByName(guest)
+if not dom.isActive():
+raise TestError("Guest '%s' not active" % guest)
+
+logger.info("Creating stream object")
+stream = conn.newStream(0)
+
+logger.info("Open a new console connection")
+dom.openConsole(device, stream, libvirt.VIR_DOMAIN_CONSOLE_FORCE)
+
+if infile != None:
+try:
+f = open(infile, 'r')
+instr = f.read()
+f.close()
+except e:
+raise TestError("Can't read input file '%s': %s" % (infile, 
str(e)))
+
+logger.info("Sending %d bytes of contents of file '%s' to console 
'%s'" % (len(instr), infile, device))
+stream.send(instr)
+
+if expect != None or outfile != None:
+logger.info("Recieving data from console device. Timeout %d 
seconds." % timeout)
+
+# register a new signal handler
+logger.info("Registering custom SIGALRM handler")
+signal.signal(signal.SIGALRM, alarm_handler)
+signal.alarm(timeout)
+
+reply = ""
+try:
+while True:
+recv = stream.recv(1024)
+reply += recv
+except TestError:
+pass
+
+logger.info("Recieved %d bytes." % len(reply))
+
+if outfile != None:
+try:
+f = open(outfile, 'w')
+f.write(reply)
+f.close()
+except e:
+raise TestError("Can't write output to file '%s': %s" % 
(outfile, str(e)))
+
+if expect != None:
+try:
+f = open(expect, 'r')
+expectstr = f.read()
+f.close()
+except Exception, e:
+raise TestError("Can't read expected output file '%s': 
'%s'" % (expect, str(e)))
+
+if reply.startswith(expectstr):
+logger.info("Recieved expected output from the host")
+else:
+raise TestError("Reply from the guest doesn't match with 
expected reply")
+
+except libvirtError, e:
+logger.error("Libvirt call failed: " + str(e))
+ret = 1
+
+except TestError, e:
+logger.error("Test failed: " + str(e))
+ret = 1
+
+else:
+logger.info("All tests succeeded")
+ret = 0
+
+finally:
+logger.info("Restoring signal handler")
+signal.signal(signal.SIGALRM, oldhandler)
+logger.info("Closing hypervisor connection")
+try:
+stream.abort()
+except:
+pass
+conn.close()
+
+logger.info("Done")
+
+return ret
+

Looks great, ACK.

Martin

--
li

Re: [libvirt] [PATCHv4 05/18] blockjob: add new API flags

2012-04-13 Thread Eric Blake
On 04/13/2012 03:38 AM, Jiri Denemark wrote:
> On Mon, Apr 09, 2012 at 21:52:14 -0600, Eric Blake wrote:
>> This patch introduces a new block job, useful for live storage
>> migration using pre-copy streaming.
>>
>> Using a live VM with the backing chain:
>>   base <- snap1 <- snap2
>> as the starting point, we have:
>>
>> - virDomainBlockRebase(dom, disk, "/path/to/copy", 0,
>> VIR_DOMAIN_BLOCK_REBASE_COPY)
>> creates /path/to/copy with the same format as snap2, with no backing
>> file, so entire chain is copied and flattened
>>
>> - virDomainBlockRebase(dom, disk, "/path/to/copy", 0,
>> VIR_DOMAIN_BLOCK_REBASE_COPY|VIR_DOMAIN_BLOCK_REBASE_COPY_RAW)
>> creates /path/to/copy as a raw file, so entire chain is copied and
>> flattened
>>
>> - virDomainBlockRebase(dom, disk, "/path/to/copy", 0,
>> VIR_DOMAIN_BLOCK_REBASE_COPY|VIR_DOMAIN_BLOCK_REBASE_SHALLOW)
>> creates /path/to/copy with the same format as snap2, but with snap1 as
>> a backing file, so only snap2 is copied.
> 
> In other words, this doesn't do any rebase at all, it just copies snap2 into
> copy and the result is the following chain:
> base <- snap1 <- copy
> 
> Did I get it right?

Yes, you got the correct end result.  I'll restate things in a slightly
different manner, to explain even more why I like the naming:

virDomainBlockRebase(,0) sets up a one-shot job that will eventually
rebase the current image to have a different backing file; when the job
completes (automatically), the rebase is complete (that is, the qemu
process now has a different backing chain in memory).  It is a property
of 'block_stream' that the job can be aborted and restarted at will (if
you abort at 20% pulled, then the next pull will start at 20%).

virDomainBlockRebase(,_REBASE_COPY) sets up a long-running job that
never completes without user intervention.  When the user completes the
job by use of virDomainBlockJobAbort(,_ABORT_PIVOT), then the rebase is
complete (that is, the qemu process now has a different backing chain in
memory).  The job can be aborted at will, but if you abort before the
streaming phase is complete, you have to start from scratch on the next
attempt (that is, if you abort 'drive-mirror' at 20%, you  have to
restart it at 0%).  More interesting is the case where you abort after
streaming is complete and you are now in the mirroring phase - in that
case, the copy is guaranteed to be consistent with the state of the
source at the time you reverted to the source.

But since both operations (with or without the flag) set up a block job
that starts a rebase, and it is the completion of the block job (whether
automatically or by user intervention) that finally commits qemu to
using the alternate backing chain in memory, both operations fit under
the generic name of causing a BlockRebase.

> 
>> - virDomainBlockRebase(dom, disk, "/path/to/copy", 0,
>> VIR_DOMAIN_BLOCK_REBASE_COPY|VIR_DOMAIN_BLOCK_REBASE_REUSE_EXT)
>> reuse existing /path/to/copy (must have empty contents, and format is
>> probed from the metadata), and copy the full chain
> 
> Hmm, in the past we tried to avoid format probing for security reasons.
> Shouldn't we avoid introducing new code that needs format probing? However,
> I'm not sure that's doable at all in this case.

I definitely thought about that.  The security hold can be summarized as:

If you give the guest a raw image, but do not explicitly mark it as raw,
then the guest can trivially (as in, without having to crack qemu)
modify the header of the image in such a manner as to make a future
probe detect something other than raw.  For all other image types, there
is no way for a guest to fake the wrong image type (at least, not
without also cracking qemu, in which case you've got worse problems on
your hand), since the guest cannot corrupt the metadata that a probe is
reading.

Therefore, there are two ways to defeat this hole, and using either
method works in isolation to avoid the hole:

Mitigation #1: Never probe a raw image; any other type of image can be
safely probed once you have eliminated raw images.
Mitigation #2: Be explicit about the image format for all images.

You are asking for mitigation 2 (and see patch 16/18 where I give that
to you in a new API virDomainBlockCopy).  But I have already given you
mitigation 1: if you specify VIR_DOMAIN_BLOCK_REBASE_COPY_RAW, then you
are avoiding the probe by declaring the image to be raw, and for all
other image types, the probe is no longer a security hole.

>> Management applications can pre-create the copy with a relative
>> backing file name, and use the VIR_DOMAIN_BLOCK_REBASE_REUSE_EXT
>> flag to have qemu reuse the metadata; if the management application
>> also copies the backing files to a new location, this can be used
>> to perform live storage migration of an entire backing chain.
> 
> This all sounds quite complicated but you explained it well in the
> documentation block for virDomainBlockRebase. When reading the above, I
> thought an ex

Re: [libvirt] [test-API PATCH 2/2] parser: put the syntax checking to testcase line at end of flags checking

2012-04-13 Thread Guannan Ren

On 04/13/2012 08:59 PM, Martin Kletzander wrote:

On 04/13/2012 09:56 AM, Guannan Ren wrote:

 we use the "re.match(".+:.+", tripped_casename)" only check testcase
 name line, such as domain:start, we don't want it to check flag.
 placing it just after flags checking is right place.
---
  parser.py |5 +++--
  1 files changed, 3 insertions(+), 2 deletions(-)

diff --git a/parser.py b/parser.py
index 18f6ccd..e569d7f 100644
--- a/parser.py
+++ b/parser.py
@@ -327,8 +327,6 @@ class CaseFileParser(object):

  tripped_caselist = casestring.strip().split()
  tripped_casename = tripped_caselist[0]
-if not re.match(".+:.+", tripped_casename):
-raise exception.CaseConfigfileError("casename line format 
error!")

  if self.debug:
  self.debug_print("we begin to handle the case",
@@ -416,6 +414,9 @@ class CaseFileParser(object):
  list.append(option_case)
  continue

+if not re.match(".+:.+", tripped_casename):
+raise exception.CaseConfigfileError("%s line format 
error!" % tripped_casename)
+
  for caselist in list:
  newdict = {}
  newdict[tripped_casename] = {}

I think both of these are fine, ACK series.

Martin


Thanks, pushed

Guannan Ren

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


Re: [libvirt] [test-API PATCH 2/2] parser: put the syntax checking to testcase line at end of flags checking

2012-04-13 Thread Martin Kletzander
On 04/13/2012 09:56 AM, Guannan Ren wrote:
> we use the "re.match(".+:.+", tripped_casename)" only check testcase
> name line, such as domain:start, we don't want it to check flag.
> placing it just after flags checking is right place.
> ---
>  parser.py |5 +++--
>  1 files changed, 3 insertions(+), 2 deletions(-)
> 
> diff --git a/parser.py b/parser.py
> index 18f6ccd..e569d7f 100644
> --- a/parser.py
> +++ b/parser.py
> @@ -327,8 +327,6 @@ class CaseFileParser(object):
>  
>  tripped_caselist = casestring.strip().split()
>  tripped_casename = tripped_caselist[0]
> -if not re.match(".+:.+", tripped_casename):
> -raise exception.CaseConfigfileError("casename line 
> format error!")
>  
>  if self.debug:
>  self.debug_print("we begin to handle the case",
> @@ -416,6 +414,9 @@ class CaseFileParser(object):
>  list.append(option_case)
>  continue
>  
> +if not re.match(".+:.+", tripped_casename):
> +raise exception.CaseConfigfileError("%s line format 
> error!" % tripped_casename)
> +
>  for caselist in list:
>  newdict = {}
>  newdict[tripped_casename] = {}

I think both of these are fine, ACK series.

Martin

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


Re: [libvirt] [test-API PATCH] repo: Add test for console input and output operations

2012-04-13 Thread Martin Kletzander
On 04/13/2012 11:41 AM, Peter Krempa wrote:
> This test checks if the console input and output work as desired. The
> test takes as an argument a filename, whose contents are sent to the
> console. The optional parameter 'expect' can be set to a filename that
> should contain expected output from the guest and is compared with the
> actual output. The optional parameter 'output' can be set to a filename
> where the test script saves the output of the host (useful for initial
> test setup).
> 
> This test requires that the guest machine runs code that handles input and
> output on the serial console (programs such as agetty or something like that).
> ---
>  repos/domain/console_io.py |  123 
> 
>  1 files changed, 123 insertions(+), 0 deletions(-)
>  create mode 100644 repos/domain/console_io.py
> 
> diff --git a/repos/domain/console_io.py b/repos/domain/console_io.py
> new file mode 100644
> index 000..98fd5b6
> --- /dev/null
> +++ b/repos/domain/console_io.py
> @@ -0,0 +1,123 @@
> +#!/usr/bin/env python
> +# test console interactions
> +# This test sends contents of file 'input' to the guest's console
> +# and reads from the console the reply and compares it to 'expect' or
> +# writes the output to file 'output'
> +
> +import libvirt
> +import signal
> +import os
> +
> +from libvirt import libvirtError
> +from exception import TestError
> +
> +required_params = ('guestname',)
> +optional_params = ('device', 'timeout', 'input', 'output', 'expect',)
> +
> +def alarm_handler(signum, frame):
> +raise TestError("Timed out while waiting for console")
> +
> +def console_io(params):
> +"""Attach to console"""
> +logger = params['logger']
> +guest = params['guestname']
> +device = params.get('device', 'serial0')
> +infile = params.get('input', None)
> +outfile = params.get('output', None)
> +expect = params.get('expect', None)
> +timeout = params.get('timeout', 5)
> +
> +uri = params['uri']
> +
> +#store the old signal handler
> +oldhandler = signal.getsignal(signal.SIGALRM)
> +
> +try:
> +logger.info("Connecting to hypervisor: '%s'" % uri)
> +conn = libvirt.open(uri)
> +dom = conn.lookupByName(guest)
> +if not dom.isActive():
> +raise TestError("Guest '%s' not active" % guest)
> +
> +logger.info("Creating stream object")
> +stream = conn.newStream(0)
> +
> +logger.info("Open a new console connection")
> +dom.openConsole(device, stream, libvirt.VIR_DOMAIN_CONSOLE_FORCE)
> +
> +if infile != None:
> +try:
> +f = open(infile, 'r')
> +instr = f.read()
> +f.close()
> +except e:
> +raise TestError("Can't read input file '%s': %s" % (infile, 
> str(e)))
> +
> +logger.info("Sending %d bytes of contents of file '%s' to 
> console '%s'" % (len(instr), infile, device))
> +stream.send(instr)
> +
> +if expect != None or outfile != None:
> +logger.info("Recieving data from console device. Timeout %d 
> seconds." % timeout)
> +
> +# register a new signal handler
> +logger.info("Registering custom SIGALRM handler")
> +signal.signal(signal.SIGALRM, alarm_handler)
> +signal.alarm(timeout)
> +
> +reply = ""
> +try:
> +while True:
> +recv = stream.recv(1024)
> +reply += recv
> +except TestError:
> +pass
> +
> +logger.info("Recieved %d bytes." % len(reply))
> +
> +if outfile != None:
> +try:
> +f = open(outfile, 'w')
> +f.write(reply)
> +f.close()
> +except e:
> +raise TestError("Can't write output to file '%s': %s" % 
> (outfile, str(e)))
> +
> +if expect != None:
> +try:
> +f = open(expect, 'r')
> +expectstr = f.read()
> +f.close()
> +except Exception, e:
> +raise TestError("Can't read expected output file '%s': 
> '%s'" % (expect, str(e)))
> +
> +if reply.startswith(expectstr):
> +logger.info("Recieved expected output from the host")
> +else:
> +raise TestError("Reply from the guest doesn't match with 
> expected reply")
> +
> +except libvirtError, e:
> +logger.error("Libvirt call failed: " + str(e))
> +ret = 1
> +
> +except TestError, e:
> +logger.error("Test failed: " + str(e))
> +ret = 1
> +
> +else:
> +logger.info("All tests succeeded")
> +ret = 0
> +
> +finally:
> +logger.info("Restoring signal handler")
> +signal.signal(signal.SIGALRM, oldhandler)
> +

[libvirt] [PATCH] util: only register callbacks for CREATE operations in virnetdevmacvlan.c

2012-04-13 Thread D. Herrendoerfer
From: "D. Herrendoerfer" 

currently upon a migration a callback is created when a 802.1qbg link
is set to PREASSOCIATE, this should not happen because this is
a no-op on most switches, and does not lead to an ASSOCIATE state.
This patch only creates callbacks when CREATE is requested.
Migration and libvirtd restart scenarios are already handeled elsewhere.

Signed-off-by: D. Herrendoerfer 
---
 src/util/virnetdevmacvlan.c |7 +--
 1 files changed, 5 insertions(+), 2 deletions(-)

diff --git a/src/util/virnetdevmacvlan.c b/src/util/virnetdevmacvlan.c
index 17ea883..73f41ff 100644
--- a/src/util/virnetdevmacvlan.c
+++ b/src/util/virnetdevmacvlan.c
@@ -945,9 +945,12 @@ create_name:
 goto disassociate_exit;
 }
 
-if (virNetDevMacVLanVPortProfileRegisterCallback(cr_ifname, macaddress,
- linkdev, vmuuid, virtPortProfile, 
vmOp) < 0 )
+if (vmOp == VIR_NETDEV_VPORT_PROFILE_OP_CREATE) {
+/*Only directly register upon a create - migration and restart are 
handled elsewhere*/
+if (virNetDevMacVLanVPortProfileRegisterCallback(cr_ifname, macaddress,
+ linkdev, vmuuid, 
virtPortProfile, vmOp) < 0 )
 goto disassociate_exit;
+}
 
 return rc;
 
-- 
1.7.7.6

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


Re: [libvirt] [PATCHv4 10/18] blockjob: return appropriate event and info

2012-04-13 Thread Jiri Denemark
On Mon, Apr 09, 2012 at 21:52:19 -0600, Eric Blake wrote:
> Handle the new type of block copy event and info.  Of course,
> this patch does nothing until a later patch actually allows the
> creation/abort of a block copy job.
> 
> * src/qemu/qemu_monitor_json.c (qemuMonitorJSONHandleBlockJobImpl)
> (qemuMonitorJSONGetBlockJobInfoOne): Translate new job type.
> * src/qemu/qemu_driver.c (qemuDomainBlockJobImpl): Snoop a successful
> info query to save effort on a pivot request.
> ---
>  src/qemu/qemu_driver.c   |6 ++
>  src/qemu/qemu_monitor_json.c |4 
>  2 files changed, 10 insertions(+), 0 deletions(-)
> 
> diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c
> index b0937eb..931e095 100644
> --- a/src/qemu/qemu_driver.c
> +++ b/src/qemu/qemu_driver.c
> @@ -11687,6 +11687,12 @@ qemuDomainBlockJobImpl(virDomainPtr dom, const char 
> *path, const char *base,
>  if (ret < 0)
>  goto endjob;
> 
> +/* Snoop block copy operations, so future cancel operations can
> + * avoid checking if pivot is safe.  */
> +if (mode == BLOCK_JOB_INFO && ret == 1 && vm->def->disks[idx]->mirror &&
> +info->cur == info->end && info->type == 
> VIR_DOMAIN_BLOCK_JOB_TYPE_COPY)
> +vm->def->disks[idx]->mirroring = true;
> +
>  /* Qemu provides asynchronous block job cancellation, but without
>   * the VIR_DOMAIN_BLOCK_JOB_ABORT_ASYNC flag libvirt guarantees a
>   * synchronous operation.  Provide this behavior by waiting here,
> diff --git a/src/qemu/qemu_monitor_json.c b/src/qemu/qemu_monitor_json.c
> index 89f0eb8..8475dab 100644
> --- a/src/qemu/qemu_monitor_json.c
> +++ b/src/qemu/qemu_monitor_json.c
> @@ -788,6 +788,8 @@ qemuMonitorJSONHandleBlockJobImpl(qemuMonitorPtr mon,
> 
>  if (STREQ(type_str, "stream"))
>  type = VIR_DOMAIN_BLOCK_JOB_TYPE_PULL;
> +else if (STREQ(type_str, "mirror"))
> +type = VIR_DOMAIN_BLOCK_JOB_TYPE_COPY;
> 
>  switch (event) {
>  case VIR_DOMAIN_BLOCK_JOB_COMPLETED:
> @@ -3412,6 +3414,8 @@ static int 
> qemuMonitorJSONGetBlockJobInfoOne(virJSONValuePtr entry,
>  }
>  if (STREQ(type, "stream"))
>  info->type = VIR_DOMAIN_BLOCK_JOB_TYPE_PULL;
> +else if (STREQ(type, "mirror"))
> +info->type = VIR_DOMAIN_BLOCK_JOB_TYPE_COPY;
>  else
>  info->type = VIR_DOMAIN_BLOCK_JOB_TYPE_UNKNOWN;

OK

Jirka

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


Re: [libvirt] [test-API PATCH 0/4]Add feature to check case file before running

2012-04-13 Thread Guannan Ren

On 04/13/2012 08:19 PM, Martin Kletzander wrote:

On 04/12/2012 07:03 PM, Guannan Ren wrote:

On 04/12/2012 09:43 PM, Guannan Ren wrote:

On 04/12/2012 07:53 PM, Peter Krempa wrote:

I don't think pushing this series without a review was a good idea.
You actualy broke all of the tests in the repos/ as you didn't do the
modifications to the parameter checking algorithm in a way that
didn't require modification of the tests, neither did you change the
tests to cope with the new code. The result is now:

exception.TestCaseError: 'required_params or optional_params not
found in interface:destroy'

or similar for every test case.

Peter


 Yes, sorry about this.
 There is some new feature and cleanup work on my hand, I don't know
 the exact time to get review.
 The error is generated by framework.  the part job of framework is
done.
 The cleanup work on testcase is ongoing,  I am sure that I will
finish the work today.


 The cleanup is done and pushed.
 I only wan to send framework code here, the cleaning code in
testcases is huge
 and mechanical, maybe nobody likes seeing it :)
 Sorry about the intact commit again.

 Guannan Ren

I was writing next email about this when the internet at my place (and
thus VPN) started disconnecting me.
I had a thought in mind how we can keep all the tests working without
any change. However if this is now fixed then the thought is not needed
anymore.
Next time if there is some major change like this, then I'd like to keep
it that way. In case we don't rewrite it from scratch of course :)

Martin


  Any change to the framework will lead to big changes to all 
existing testcases.
  It worth though, but don't worry, I like to do the labor work. 
you guys just focus

  on framework.

  Guannan Ren

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


Re: [libvirt] [PATCHv4 09/18] blockjob: expose qemu commands for mirrored storage migration

2012-04-13 Thread Jiri Denemark
On Mon, Apr 09, 2012 at 21:52:18 -0600, Eric Blake wrote:
> As mentioned several commits ago when the capability bits were added,
> the new block copy storage migration sequence requires both the
> 'drive-mirror' and 'drive-reopen' monitor commands.
> 
> As of this[1] qemu email, both commands have been proposed but not yet
> incorporated into the tree; in fact, the implementation I tested with
> has changed to match this[2] email that suggested a mandatory
> 'full':'bool' argument rather than 'mode':'no-backing-file'.  So there
> is a risk that qemu 1.1 will have yet another subtly different
> implementation.
> [1]https://lists.gnu.org/archive/html/qemu-devel/2012-03/msg01524.html
> [2]https://lists.gnu.org/archive/html/qemu-devel/2012-04/msg00886.html
> 
> * src/qemu/qemu_monitor_json.c (qemuMonitorJSONDriveMirror)
> (qemuMonitorDriveReopen): New functions.
> * src/qemu/qemu_monitor_json.h (qemuMonitorJSONDriveMirror)
> (qemuMonitorDriveReopen): Declare them.
> * src/qemu/qemu_monitor.c (qemuMonitorDriveMirror)
> (qemuMonitorDriveReopen): New passthroughs.
> * src/qemu/qemu_monitor.h (qemuMonitorDriveMirror)
> (qemuMonitorDriveReopen): Declare them.
> ---
>  src/qemu/qemu_monitor.c  |   50 ++
>  src/qemu/qemu_monitor.h  |   13 
>  src/qemu/qemu_monitor_json.c |   70 
> ++
>  src/qemu/qemu_monitor_json.h |   19 ++-
>  4 files changed, 150 insertions(+), 2 deletions(-)
> 
> diff --git a/src/qemu/qemu_monitor.c b/src/qemu/qemu_monitor.c
> index e1a8d4c..969e453 100644
> --- a/src/qemu/qemu_monitor.c
> +++ b/src/qemu/qemu_monitor.c
> @@ -2685,6 +2685,32 @@ qemuMonitorDiskSnapshot(qemuMonitorPtr mon, 
> virJSONValuePtr actions,
>  return ret;
>  }
> 
> +/* Add the drive-mirror action to a transaction.  */
> +int
> +qemuMonitorDriveMirror(qemuMonitorPtr mon, virJSONValuePtr actions,
> +   const char *device, const char *file,
> +   const char *format, unsigned int flags)
> +{
> +int ret = -1;
> +
> +VIR_DEBUG("mon=%p, actions=%p, device=%s, file=%s, format=%s, flags=%x",
> +  mon, actions, device, file, format, flags);
> +
> +if (!mon) {
> +qemuReportError(VIR_ERR_INVALID_ARG, "%s",
> +_("monitor must not be NULL"));
> +return -1;
> +}
> +
> +if (mon->json)
> +ret = qemuMonitorJSONDriveMirror(mon, actions, device, file, format,
> + flags);
> +else
> +qemuReportError(VIR_ERR_INVALID_ARG, "%s",
> +_("drive-mirror requires JSON monitor"));

Why is this VIR_ERR_INVALID_ARG instead of VIR_ERR_CONFIG_UNSUPPORTED?

> +return ret;
> +}
> +
>  /* Use the transaction QMP command to run atomic snapshot commands.  */
>  int
>  qemuMonitorTransaction(qemuMonitorPtr mon, virJSONValuePtr actions)
> @@ -2701,6 +2727,30 @@ qemuMonitorTransaction(qemuMonitorPtr mon, 
> virJSONValuePtr actions)
>  return ret;
>  }
> 
> +/* Use the drive-reopen monitor command.  */
> +int
> +qemuMonitorDriveReopen(qemuMonitorPtr mon, const char *device,
> +   const char *file, const char *format)
> +{
> +int ret = -1;
> +
> +VIR_DEBUG("mon=%p, device=%s, file=%s, format=%s",
> +  mon, device, file, format);
> +
> +if (!mon) {
> +qemuReportError(VIR_ERR_INVALID_ARG, "%s",
> +_("monitor must not be NULL"));
> +return -1;
> +}
> +
> +if (mon->json)
> +ret = qemuMonitorJSONDriveReopen(mon, device, file, format);
> +else
> +qemuReportError(VIR_ERR_INVALID_ARG, "%s",
> +_("drive-reopen requires JSON monitor"));

Likewise.

> +return ret;
> +}
> +
>  int qemuMonitorArbitraryCommand(qemuMonitorPtr mon,
>  const char *cmd,
>  char **reply,
> diff --git a/src/qemu/qemu_monitor.h b/src/qemu/qemu_monitor.h
> index 2e6ac79..0534b4a 100644
> --- a/src/qemu/qemu_monitor.h
> +++ b/src/qemu/qemu_monitor.h
> @@ -508,8 +508,21 @@ int qemuMonitorDiskSnapshot(qemuMonitorPtr mon,
>  const char *file,
>  const char *format,
>  bool reuse);
> +
> +int qemuMonitorDriveMirror(qemuMonitorPtr mon,
> +   virJSONValuePtr actions,
> +   const char *device,
> +   const char *file,
> +   const char *format,
> +   unsigned int flags)
> +ATTRIBUTE_NONNULL(1) ATTRIBUTE_NONNULL(3) ATTRIBUTE_NONNULL(4);
>  int qemuMonitorTransaction(qemuMonitorPtr mon, virJSONValuePtr actions)
>  ATTRIBUTE_NONNULL(1) ATTRIBUTE_NONNULL(2);
> +int qemuMonitorDriveReopen(qemuMonitorPtr mon,
> +   const char *device,
> +   const char *file,
> +   

Re: [libvirt] [PATCH] storage: lvm: use correct lv* command parameters

2012-04-13 Thread Osier Yang

On 04/13/2012 07:50 PM, Cole Robinson wrote:

lvcreate want's the parent pool's name, not the pool path
lvchange and lvremove want lv specified as $vgname/$lvname

This largely worked before because these commands strip off a
starting /dev. But https://bugzilla.redhat.com/show_bug.cgi?id=714986
is from a user using a 'nested VG' that was having problems.

I couldn't find any info on nested LVM and the reporter never responded,
but I reproduced with XML that specified a valid source name, and
set target path to a symlink.

Signed-off-by: Cole Robinson
---
  src/storage/storage_backend_logical.c |   21 +++--
  1 files changed, 11 insertions(+), 10 deletions(-)

diff --git a/src/storage/storage_backend_logical.c 
b/src/storage/storage_backend_logical.c
index 6a235f6..9a91dd9 100644
--- a/src/storage/storage_backend_logical.c
+++ b/src/storage/storage_backend_logical.c
@@ -672,7 +672,7 @@ virStorageBackendLogicalCreateVol(virConnectPtr conn,
  char size[100];
  const char *cmdargvnew[] = {
  LVCREATE, "--name", vol->name, "-L", size,
-pool->def->target.path, NULL
+pool->def->source.name, NULL


This makes sense.


  };
  const char *cmdargvsnap[] = {
  LVCREATE, "--name", vol->name, "-L", size,
@@ -778,23 +778,23 @@ virStorageBackendLogicalDeleteVol(virConnectPtr conn 
ATTRIBUTE_UNUSED,
unsigned int flags)
  {
  int ret = -1;
+char *volpath = NULL;

  virCommandPtr lvchange_cmd = NULL;
  virCommandPtr lvremove_cmd = NULL;

  virCheckFlags(0, -1);

-virFileWaitForDevices();
+if (virAsprintf(&volpath, "%s/%s",
+pool->def->source.name, vol->name)<  0) {
+virReportOOMError();
+goto cleanup;
+}

-lvchange_cmd = virCommandNewArgList(LVCHANGE,
-"-aln",
-vol->target.path,
-NULL);
+virFileWaitForDevices();

-lvremove_cmd = virCommandNewArgList(LVREMOVE,
-"-f",
-vol->target.path,
-NULL);
+lvchange_cmd = virCommandNewArgList(LVCHANGE, "-aln", volpath, NULL);
+lvremove_cmd = virCommandNewArgList(LVREMOVE, "-f", volpath, NULL);


I tried with both vol->target.path, and $vgname/$lvname, both
of them work. So do we really need these changes?



  if (virCommandRun(lvremove_cmd, NULL)<  0) {
  if (virCommandRun(lvchange_cmd, NULL)<  0) {
@@ -807,6 +807,7 @@ virStorageBackendLogicalDeleteVol(virConnectPtr conn 
ATTRIBUTE_UNUSED,

  ret = 0;
  cleanup:
+VIR_FREE(volpath);
  virCommandFree(lvchange_cmd);
  virCommandFree(lvremove_cmd);
  return ret;


Osier

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


Re: [libvirt] [test-API PATCH 0/4]Add feature to check case file before running

2012-04-13 Thread Martin Kletzander
On 04/12/2012 07:03 PM, Guannan Ren wrote:
> On 04/12/2012 09:43 PM, Guannan Ren wrote:
>> On 04/12/2012 07:53 PM, Peter Krempa wrote:
>>> I don't think pushing this series without a review was a good idea.
>>> You actualy broke all of the tests in the repos/ as you didn't do the
>>> modifications to the parameter checking algorithm in a way that
>>> didn't require modification of the tests, neither did you change the
>>> tests to cope with the new code. The result is now:
>>>
>>> exception.TestCaseError: 'required_params or optional_params not
>>> found in interface:destroy'
>>>
>>> or similar for every test case.
>>>
>>> Peter
>>
>>
>> Yes, sorry about this.
>> There is some new feature and cleanup work on my hand, I don't know
>> the exact time to get review.
>> The error is generated by framework.  the part job of framework is
>> done.
>> The cleanup work on testcase is ongoing,  I am sure that I will
>> finish the work today.
>>
> 
> The cleanup is done and pushed.
> I only wan to send framework code here, the cleaning code in
> testcases is huge
> and mechanical, maybe nobody likes seeing it :)
> Sorry about the intact commit again.
> 
> Guannan Ren

I was writing next email about this when the internet at my place (and
thus VPN) started disconnecting me.
I had a thought in mind how we can keep all the tests working without
any change. However if this is now fixed then the thought is not needed
anymore.
Next time if there is some major change like this, then I'd like to keep
it that way. In case we don't rewrite it from scratch of course :)

Martin

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


Re: [libvirt] Start of freeze for libvirt-0.9.11 and availability of rc1

2012-04-13 Thread Daniel P. Berrange
On Fri, Apr 13, 2012 at 02:13:59PM +0200, Guido Günther wrote:
> Hi Laine,
> On Tue, Apr 03, 2012 at 08:27:39PM +0200, Guido Günther wrote:
> > On Tue, Apr 03, 2012 at 09:22:56AM +0200, Philipp Hahn wrote:
> > > Hello,
> > > 
> > > On Tuesday 27 March 2012 18:30:17 Guido Günther wrote:
> > > > On Mon, Mar 26, 2012 at 10:32:23AM +0800, Daniel Veillard wrote:
> > > > >   As scheduled, we are entering the freeze for 0.9.11.
> > > ...
> > > > >  Please give it a try ! Stability and portability feedback are really
> > > > > welcome as we didn't had a release in Feb and the risk of having
> > > > > something messed up is slightly higher than usual !
> > > >
> > > > Looks good so far on Debian's autobuilders:
> > > >
> > > > 
> > > > https://buildd.debian.org/status/package.php?p=libvirt&suite=experimental
> > > 
> > > Compiling 0.9.11-rc on a Debian-Squeeze (EGLIBC 2.11.3-2, Kernel 
> > > 2.6.32-52, 
> > > gcc 4.4.5-8.) fails with
> > >   CC libvirt_util_la-virnetdevbandwidth.lo
> > > util/virnetdev.c:1220: error: 'IFLA_VF_MAX' undeclared here (not in a 
> > > function)
> > > 
> > > The following patch fixes that for me:
> > > --- a/src/util/virnetdev.c
> > > +++ b/src/util/virnetdev.c
> > > @@ -1215,7 +1215,7 @@ virNetDevGetVirtualFunctionInfo(const char *vfname 
> > > ATTRIBUTE_UNUSED,
> > >  return -1;
> > >  }
> > >  #endif /* !__linux__ */
> > > -#if defined(__linux__) && defined(HAVE_LIBNL)
> > > +#if defined(__linux__) && defined(HAVE_LIBNL) && defined(IFLA_VF_MAX)
> > 
> > This looks reasonable to me since this isn't available in Debian
> > Squeeze's kernel headers and I don't think it's worth a separate
> > configure check since we'd only check for IFLA_VF_MAX there.
> 
> Can I go ahead and push this change?

ACK


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

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

Re: [libvirt] [test-API PATCHv2 1/2] sharemod: Add a new file for variable sharing in testcases

2012-04-13 Thread Guannan Ren

On 04/10/2012 09:55 PM, Guannan Ren wrote:

 sharedmod.py
---
  sharedmod.py |   16 
  1 files changed, 16 insertions(+), 0 deletions(-)
  create mode 100644 sharedmod.py

diff --git a/sharedmod.py b/sharedmod.py
new file mode 100644
index 000..8af26d8
--- /dev/null
+++ b/sharedmod.py
@@ -0,0 +1,16 @@
+# This is a module for variable sharing across testcases during
+# running. You have to import it in each of testcases which want
+# to share data. The framwork have already set {'conn': connobj}
+# in libvirtobj dictionary for use in testcases.
+
+# The libvirtobj dictionary is only set and used by framework
+# in testcases you could use sharedmod.libvirtobj['conn'] to get
+# the connection object in libvirt.py, you need not to close it,
+# the framework do it.
+libvirtobj = {}
+
+# shared variables for customized use in testcases
+# set variable: sharedmod.data['my_test_variable'] = 'test_value'
+# check the variable: sharedmod.data.has_key('my_test_variable')
+# get the varialbe: sharedmod.data.get('my_test_variable', 
'test_variable_default_value')
+data = {}


If no more comments, I will push these two patches.

Guannan Ren

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


Re: [libvirt] [PATCH 3/3] qemu: Split if condition in qemuDomainSnapshotUndoSingleDiskActive

2012-04-13 Thread Eric Blake
On 04/13/2012 03:39 AM, Daniel P. Berrange wrote:
> On Fri, Apr 13, 2012 at 11:12:54AM +0200, Michal Privoznik wrote:
>> Since compilers are trying to optimize code they are allowed to
>> reorder evaluation of conditions in if statement (okay, not in all
>> cases, but they can in this one). Therefore if we do:
>> if (stat(file, &st) == 0 && unlink(file) < 0)
>> after compiler chews this it may get feeling that swapping order
>> is a good idea. However, we obviously don't want to call stat()
>> on just unlink()-ed file.
> 
> Really ? I'm not sure I believe that. IIRC in-order short-circuit
> evaluation is a part of the C standard. Compilers can't do any
> optimization which changes the order of evalation without breaking
> countless C programs.

I concur - NACK to this patch.  Any C compiler that violates
short-circuiting semantics is too severely broken to be worth working
around in our code.

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



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

Re: [libvirt] Start of freeze for libvirt-0.9.11 and availability of rc1

2012-04-13 Thread Guido Günther
On Mon, Apr 02, 2012 at 10:42:21AM -0400, Laine Stump wrote:
> On 04/02/2012 06:43 AM, Philipp Hahn wrote:
> > The patch still aplies, but sending new version as you requested. Still 
> > compiles (with minor problems regarding undefined IFLA_PORT_MAX and broken 
> > libnl on my Debian-Squeeze here)
> 
> What is the version of libnl?
> 
> Different versions of libnl are unfortunately not API compatible.
> libvirt's libnl usage has been developed for / tested with libnl 1.1.

This is what's being used in Debian. Ubuntu builds againt libnl 3 AFAIK.
Cheers,
 -- Guido

> 
> --
> 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] Start of freeze for libvirt-0.9.11 and availability of rc1

2012-04-13 Thread Guido Günther
Hi Laine,
On Tue, Apr 03, 2012 at 08:27:39PM +0200, Guido Günther wrote:
> On Tue, Apr 03, 2012 at 09:22:56AM +0200, Philipp Hahn wrote:
> > Hello,
> > 
> > On Tuesday 27 March 2012 18:30:17 Guido Günther wrote:
> > > On Mon, Mar 26, 2012 at 10:32:23AM +0800, Daniel Veillard wrote:
> > > >   As scheduled, we are entering the freeze for 0.9.11.
> > ...
> > > >  Please give it a try ! Stability and portability feedback are really
> > > > welcome as we didn't had a release in Feb and the risk of having
> > > > something messed up is slightly higher than usual !
> > >
> > > Looks good so far on Debian's autobuilders:
> > >
> > >   
> > > https://buildd.debian.org/status/package.php?p=libvirt&suite=experimental
> > 
> > Compiling 0.9.11-rc on a Debian-Squeeze (EGLIBC 2.11.3-2, Kernel 2.6.32-52, 
> > gcc 4.4.5-8.) fails with
> >   CC libvirt_util_la-virnetdevbandwidth.lo
> > util/virnetdev.c:1220: error: 'IFLA_VF_MAX' undeclared here (not in a 
> > function)
> > 
> > The following patch fixes that for me:
> > --- a/src/util/virnetdev.c
> > +++ b/src/util/virnetdev.c
> > @@ -1215,7 +1215,7 @@ virNetDevGetVirtualFunctionInfo(const char *vfname 
> > ATTRIBUTE_UNUSED,
> >  return -1;
> >  }
> >  #endif /* !__linux__ */
> > -#if defined(__linux__) && defined(HAVE_LIBNL)
> > +#if defined(__linux__) && defined(HAVE_LIBNL) && defined(IFLA_VF_MAX)
> 
> This looks reasonable to me since this isn't available in Debian
> Squeeze's kernel headers and I don't think it's worth a separate
> configure check since we'd only check for IFLA_VF_MAX there.

Can I go ahead and push this change?
Cheers,
 -- Guido

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


[libvirt] [PATCH] storage: lvm: use correct lv* command parameters

2012-04-13 Thread Cole Robinson
lvcreate want's the parent pool's name, not the pool path
lvchange and lvremove want lv specified as $vgname/$lvname

This largely worked before because these commands strip off a
starting /dev. But https://bugzilla.redhat.com/show_bug.cgi?id=714986
is from a user using a 'nested VG' that was having problems.

I couldn't find any info on nested LVM and the reporter never responded,
but I reproduced with XML that specified a valid source name, and
set target path to a symlink.

Signed-off-by: Cole Robinson 
---
 src/storage/storage_backend_logical.c |   21 +++--
 1 files changed, 11 insertions(+), 10 deletions(-)

diff --git a/src/storage/storage_backend_logical.c 
b/src/storage/storage_backend_logical.c
index 6a235f6..9a91dd9 100644
--- a/src/storage/storage_backend_logical.c
+++ b/src/storage/storage_backend_logical.c
@@ -672,7 +672,7 @@ virStorageBackendLogicalCreateVol(virConnectPtr conn,
 char size[100];
 const char *cmdargvnew[] = {
 LVCREATE, "--name", vol->name, "-L", size,
-pool->def->target.path, NULL
+pool->def->source.name, NULL
 };
 const char *cmdargvsnap[] = {
 LVCREATE, "--name", vol->name, "-L", size,
@@ -778,23 +778,23 @@ virStorageBackendLogicalDeleteVol(virConnectPtr conn 
ATTRIBUTE_UNUSED,
   unsigned int flags)
 {
 int ret = -1;
+char *volpath = NULL;
 
 virCommandPtr lvchange_cmd = NULL;
 virCommandPtr lvremove_cmd = NULL;
 
 virCheckFlags(0, -1);
 
-virFileWaitForDevices();
+if (virAsprintf(&volpath, "%s/%s",
+pool->def->source.name, vol->name) < 0) {
+virReportOOMError();
+goto cleanup;
+}
 
-lvchange_cmd = virCommandNewArgList(LVCHANGE,
-"-aln",
-vol->target.path,
-NULL);
+virFileWaitForDevices();
 
-lvremove_cmd = virCommandNewArgList(LVREMOVE,
-"-f",
-vol->target.path,
-NULL);
+lvchange_cmd = virCommandNewArgList(LVCHANGE, "-aln", volpath, NULL);
+lvremove_cmd = virCommandNewArgList(LVREMOVE, "-f", volpath, NULL);
 
 if (virCommandRun(lvremove_cmd, NULL) < 0) {
 if (virCommandRun(lvchange_cmd, NULL) < 0) {
@@ -807,6 +807,7 @@ virStorageBackendLogicalDeleteVol(virConnectPtr conn 
ATTRIBUTE_UNUSED,
 
 ret = 0;
 cleanup:
+VIR_FREE(volpath);
 virCommandFree(lvchange_cmd);
 virCommandFree(lvremove_cmd);
 return ret;
-- 
1.7.7.6

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


Re: [libvirt] [PATCH 2/3] gitignore: Reorder alphabetically

2012-04-13 Thread Michal Privoznik
On 13.04.2012 14:28, Osier Yang wrote:
> On 04/13/2012 05:12 PM, Michal Privoznik wrote:
>> Recent git reorders .gitignore alphabetically. However, changes are
>> not committed and I am tired of discarding these changes from
>> my patches.
>> ---
>>   .gitignore |6 +++---
>>   1 files changed, 3 insertions(+), 3 deletions(-)
>>

> 
> ACK
> 
> Osier

Thanks, pushed.

Michal

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


Re: [libvirt] [PATCH 2/3] gitignore: Reorder alphabetically

2012-04-13 Thread Osier Yang

On 04/13/2012 05:12 PM, Michal Privoznik wrote:

Recent git reorders .gitignore alphabetically. However, changes are
not committed and I am tired of discarding these changes from
my patches.
---
  .gitignore |6 +++---
  1 files changed, 3 insertions(+), 3 deletions(-)

diff --git a/.gitignore b/.gitignore
index 5aa9c9b..14a21d0 100644
--- a/.gitignore
+++ b/.gitignore
@@ -48,12 +48,12 @@
  /daemon/*_dispatch.h
  /daemon/libvirt_qemud
  /daemon/libvirtd
-/daemon/libvirtd.init
-/daemon/libvirtd.service
  /daemon/libvirtd*.logrotate
  /daemon/libvirtd.8
  /daemon/libvirtd.8.in
+/daemon/libvirtd.init
  /daemon/libvirtd.pod
+/daemon/libvirtd.service
  /docs/devhelp/libvirt.devhelp
  /docs/hvsupport.html.in
  /docs/libvirt-api.xml
@@ -118,6 +118,7 @@
  /tests/eventtest
  /tests/hashtest
  /tests/jsontest
+/tests/libvirtdconftest
  /tests/networkxml2argvtest
  /tests/nodeinfotest
  /tests/nwfilterxml2xmltest
@@ -150,7 +151,6 @@
  /tests/vmx2xmltest
  /tests/xencapstest
  /tests/xmconfigtest
-/tests/libvirtdconftest
  /tools/*.[18]
  /tools/libvirt-guests.init
  /tools/virsh


ACK

Osier

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


Re: [libvirt] [PATCHv4 08/18] blockjob: react to active block copy

2012-04-13 Thread Jiri Denemark
On Mon, Apr 09, 2012 at 21:52:17 -0600, Eric Blake wrote:
> For now, disk migration via block copy job is not implemented.  But
> when we do implement it, we have to deal with the fact that qemu does
> not provide an easy way to re-start a qemu process with mirroring
> still intact (it _might_ be possible by using qemu -S then an
> initial 'drive-mirror' with disk reuse before starting the domain,
> but that gets hairy).  Even something like 'virDomainSave' becomes
> hairy, if you realize the implications that 'virDomainRestore' would
> be stuck with recreating the same mirror layout.
> 
> But if we step back and look at the bigger picture, we realize that
> the initial client of live storage migration via disk mirroring is
> oVirt, which always uses transient domains, and that if a transient
> domain is destroyed while a mirror exists, oVirt can easily restart
> the storage migration by creating a new domain that visits just the
> source storage, with no loss in data.
> 
> We can make life a lot easier by being cowards, and forbidding
> certain operations on a domain.  This patch guarantees that we
> never get in a state where we would have to restart a domain with
> a mirroring block copy, by preventing saves, snapshots, hot
> unplug of a disk in use, and conversion to a persistent domain.
> 
> * src/conf/domain_conf.h (virDomainHasDiskMirror): New prototype.
> * src/conf/domain_conf.c (virDomainHasDiskMirror): New function.
> * src/libvirt_private.syms (domain_conf.h): Export it.
> * src/qemu/qemu_driver.c (qemuDomainSaveInternal)
> (qemuDomainSnapshotCreateXML, qemuDomainRevertToSnapshot)
> (qemuDomainBlockJobImpl, qemudDomainDefine): Prevent dangerous
> actions while block copy is already in action.
> * src/qemu/qemu_hotplug.c (qemuDomainDetachDiskDevice): Likewise.
> ---
>  src/conf/domain_conf.c   |   12 
>  src/conf/domain_conf.h   |1 +
>  src/libvirt_private.syms |1 +
>  src/qemu/qemu_driver.c   |   31 ++-
>  src/qemu/qemu_hotplug.c  |7 +++
>  5 files changed, 51 insertions(+), 1 deletions(-)
> 
> diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c
> index 8899653..3aa6861 100644
> --- a/src/conf/domain_conf.c
> +++ b/src/conf/domain_conf.c
> @@ -7183,6 +7183,18 @@ virDomainDiskRemoveByName(virDomainDefPtr def, const 
> char *name)
>  return virDomainDiskRemove(def, i);
>  }
> 
> +/* Return true if VM has at least one disk involved in a current block
> + * copy job (that is, with a  element in the disk xml).  */
> +bool
> +virDomainHasDiskMirror(virDomainObjPtr vm)
> +{
> +int i;
> +for (i = 0; i < vm->def->ndisks; i++)
> +if (vm->def->disks[i]->mirror)
> +return true;
> +return false;
> +}
> +
>  int virDomainNetInsert(virDomainDefPtr def, virDomainNetDefPtr net)
>  {
>  if (VIR_REALLOC_N(def->nets, def->nnets + 1) < 0)
> diff --git a/src/conf/domain_conf.h b/src/conf/domain_conf.h
> index abc953d..77c501c 100644
> --- a/src/conf/domain_conf.h
> +++ b/src/conf/domain_conf.h
> @@ -1954,6 +1954,7 @@ virDomainDiskDefPtr
>  virDomainDiskRemove(virDomainDefPtr def, size_t i);
>  virDomainDiskDefPtr
>  virDomainDiskRemoveByName(virDomainDefPtr def, const char *name);
> +bool virDomainHasDiskMirror(virDomainObjPtr vm);
> 
>  int virDomainNetIndexByMac(virDomainDefPtr def, const unsigned char *mac);
>  int virDomainNetInsert(virDomainDefPtr def, virDomainNetDefPtr net);
> diff --git a/src/libvirt_private.syms b/src/libvirt_private.syms
> index a90f8a0..570940d 100644
> --- a/src/libvirt_private.syms
> +++ b/src/libvirt_private.syms
> @@ -354,6 +354,7 @@ virDomainGraphicsSpiceZlibCompressionTypeFromString;
>  virDomainGraphicsSpiceZlibCompressionTypeToString;
>  virDomainGraphicsTypeFromString;
>  virDomainGraphicsTypeToString;
> +virDomainHasDiskMirror;
>  virDomainHostdevDefAlloc;
>  virDomainHostdevDefClear;
>  virDomainHostdevDefFree;
> diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c
> index 425d340..b0937eb 100644
> --- a/src/qemu/qemu_driver.c
> +++ b/src/qemu/qemu_driver.c
> @@ -2558,6 +2558,11 @@ qemuDomainSaveInternal(struct qemud_driver *driver, 
> virDomainPtr dom,
>  "%s", _("domain is marked for auto destroy"));
>  goto cleanup;
>  }
> +if (virDomainHasDiskMirror(vm)) {
> +qemuReportError(VIR_ERR_BLOCK_COPY_ACTIVE, "%s",
> +_("domain has active block copy job"));
> +goto cleanup;
> +}
> 
>  memset(&header, 0, sizeof(header));
>  memcpy(header.magic, QEMUD_SAVE_PARTIAL, sizeof(header.magic));
> @@ -4947,6 +4952,12 @@ static virDomainPtr qemudDomainDefine(virConnectPtr 
> conn, const char *xml) {
>  goto cleanup;
>  }
>  def = NULL;
> +if (virDomainHasDiskMirror(vm)) {
> +qemuReportError(VIR_ERR_BLOCK_COPY_ACTIVE, "%s",
> +_("domain has active block copy job"));
> +virDomainObjAssignDef(vm, NULL, false);
> +goto cleanup;

Re: [libvirt] [libvirt-glib] Getter/setter for disk source's startupPolicy attribute

2012-04-13 Thread Christophe Fergeau
On Thu, Apr 12, 2012 at 11:50:30PM +0300, Zeeshan Ali (Khattak) wrote:
> From: "Zeeshan Ali (Khattak)" 
> 
> ---
>  libvirt-gconfig/libvirt-gconfig-domain-disk.c |   26 
> +
>  libvirt-gconfig/libvirt-gconfig-domain-disk.h |9 
>  libvirt-gconfig/libvirt-gconfig.sym   |5 +++-
>  libvirt-gconfig/tests/test-domain-create.c|2 +
>  4 files changed, 41 insertions(+), 1 deletions(-)
> 
> diff --git a/libvirt-gconfig/libvirt-gconfig-domain-disk.c 
> b/libvirt-gconfig/libvirt-gconfig-domain-disk.c
> index 5d0acb5..a29ea47 100644
> --- a/libvirt-gconfig/libvirt-gconfig-domain-disk.c
> +++ b/libvirt-gconfig/libvirt-gconfig-domain-disk.c
> @@ -127,6 +127,18 @@ void 
> gvir_config_domain_disk_set_snapshot_type(GVirConfigDomainDisk *disk,
> type, NULL);
>  }
>  
> +void gvir_config_domain_disk_set_startup_policy(GVirConfigDomainDisk *disk,
> +
> GVirConfigDomainDiskStartupPolicy policy)
> +{
> +const char *str;
> +
> +g_return_if_fail(GVIR_CONFIG_IS_DOMAIN_DISK(disk));
> +str = 
> gvir_config_genum_get_nick(GVIR_CONFIG_TYPE_DOMAIN_DISK_STARTUP_POLICY, 
> policy);
> +g_return_if_fail(str != NULL);
> +gvir_config_object_add_child_with_attribute(GVIR_CONFIG_OBJECT(disk),
> +"source", "startupPolicy", 
> str);
> +}
> +
>  void gvir_config_domain_disk_set_source(GVirConfigDomainDisk *disk,
>  const char *source)
>  {
> @@ -235,6 +247,19 @@ 
> gvir_config_domain_disk_get_snapshot_type(GVirConfigDomainDisk *disk)
>
> GVIR_CONFIG_DOMAIN_DISK_SNAPSHOT_NO);
>  }
>  
> +GVirConfigDomainDiskStartupPolicy
> +gvir_config_domain_disk_get_startup_policy(GVirConfigDomainDisk *disk)
> +{
> +g_return_val_if_fail(GVIR_CONFIG_IS_DOMAIN_DISK(disk),
> + GVIR_CONFIG_DOMAIN_DISK_STARTUP_POLICY_MANDATORY);
> +
> +return gvir_config_object_get_attribute_genum
> +(GVIR_CONFIG_OBJECT(disk),
> + "source", "startupPolicy",
> + GVIR_CONFIG_TYPE_DOMAIN_DISK_STARTUP_POLICY,
> + GVIR_CONFIG_DOMAIN_DISK_STARTUP_POLICY_MANDATORY);
> +}
> +
>  const char *
>  gvir_config_domain_disk_get_source(GVirConfigDomainDisk *disk)
>  {
> @@ -291,6 +316,7 @@ 
> gvir_config_domain_disk_get_driver_cache(GVirConfigDomainDisk *disk)
>
> GVIR_CONFIG_TYPE_DOMAIN_DISK_CACHE_TYPE,
>
> GVIR_CONFIG_DOMAIN_DISK_CACHE_DEFAULT);
>  }
> +
>  GVirConfigDomainDiskBus
>  gvir_config_domain_disk_get_target_bus(GVirConfigDomainDisk *disk)
>  {
> diff --git a/libvirt-gconfig/libvirt-gconfig-domain-disk.h 
> b/libvirt-gconfig/libvirt-gconfig-domain-disk.h
> index 916421d..7e85d75 100644
> --- a/libvirt-gconfig/libvirt-gconfig-domain-disk.h
> +++ b/libvirt-gconfig/libvirt-gconfig-domain-disk.h
> @@ -95,6 +95,12 @@ typedef enum {
>  GVIR_CONFIG_DOMAIN_DISK_SNAPSHOT_EXTERNAL
>  } GVirConfigDomainDiskSnapshotType;
>  
> +typedef enum {
> +GVIR_CONFIG_DOMAIN_DISK_STARTUP_POLICY_MANDATORY,
> +GVIR_CONFIG_DOMAIN_DISK_STARTUP_POLICY_REQUISITE,
> +GVIR_CONFIG_DOMAIN_DISK_STARTUP_POLICY_OPTIONAL
> +} GVirConfigDomainDiskStartupPolicy;
> +
>  GType gvir_config_domain_disk_get_type(void);
>  
>  GVirConfigDomainDisk *gvir_config_domain_disk_new(void);
> @@ -107,6 +113,8 @@ void 
> gvir_config_domain_disk_set_guest_device_type(GVirConfigDomainDisk *disk,
> 
> GVirConfigDomainDiskGuestDeviceType type);
>  void gvir_config_domain_disk_set_snapshot_type(GVirConfigDomainDisk *disk,
> 
> GVirConfigDomainDiskSnapshotType type);
> +void gvir_config_domain_disk_set_startup_policy(GVirConfigDomainDisk *disk,
> +
> GVirConfigDomainDiskStartupPolicy policy);
>  void gvir_config_domain_disk_set_source(GVirConfigDomainDisk *disk,
>  const char *source);
>  void gvir_config_domain_disk_set_driver_cache(GVirConfigDomainDisk *disk,
> @@ -123,6 +131,7 @@ void 
> gvir_config_domain_disk_set_target_dev(GVirConfigDomainDisk *disk,
>  GVirConfigDomainDiskType 
> gvir_config_domain_disk_get_disk_type(GVirConfigDomainDisk *disk);
>  GVirConfigDomainDiskGuestDeviceType 
> gvir_config_domain_disk_get_guest_device_type(GVirConfigDomainDisk *disk);
>  GVirConfigDomainDiskSnapshotType 
> gvir_config_domain_disk_get_snapshot_type(GVirConfigDomainDisk *disk);
> +GVirConfigDomainDiskStartupPolicy 
> gvir_config_domain_disk_get_startup_policy(GVirConfigDomainDisk *disk);
>  const char *gvir_config_domain_disk_get_source(GVirConfigDomainDisk *disk);
>  GVirConfigDomainDiskCacheType 
> gvir_config_domain_disk_get_driver_cache(GVirCo

Re: [libvirt] [PATCHv4 07/18] blockjob: enhance xml to track mirrors across libvirtd restart

2012-04-13 Thread Jiri Denemark
On Mon, Apr 09, 2012 at 21:52:16 -0600, Eric Blake wrote:
> QUESTION: should we parse and ignore  on input, rather than
> rejecting it?  By rejecting it, I can't add a unit test, since the
> unit test framework currently doesn't expose a way to trigger
> internal parsing.
>
> In order to track a block copy job across libvirtd restarts, we
> need to save internal XML that tracks the name of the file
> holding the mirror.  Displaying this name in dumpxml might also
> be useful to the user, even if we don't yet have a way to (re-)
> start a domain with mirroring enabled up front.  This is done
> with a new  sub-element to , as in:
> 
> 
>   
>   
>   
>   ...
> 

However, this would mean, the XML from virDomainGetXMLDesc() cannot be
directly used for defining new domain. I think there are two possible ways to
go. Either output  the way you did it and ignore it on input
(similarly to what we do with aliases or SELinux labels) or put the mirror
element out of domain XML and put it into state XML only.

> * docs/schemas/domaincommon.rng (diskspec): Add diskMirror.
> * docs/formatdomain.html.in (elementsDisks): Document it.
> * src/conf/domain_conf.h (_virDomainDiskDef): New members.
> * src/conf/domain_conf.c (virDomainDiskDefFree): Clean them.
> (virDomainDiskDefParseXML): Parse them, but only internally.
> (virDomainDiskDefFormat): Output them.
> ---
>  docs/formatdomain.html.in |   11 ++
>  docs/schemas/domaincommon.rng |   19 +++--
>  src/conf/domain_conf.c|   42 
> +
>  src/conf/domain_conf.h|5 
>  4 files changed, 74 insertions(+), 3 deletions(-)
> 
> diff --git a/docs/formatdomain.html.in b/docs/formatdomain.html.in
> index a382d30..534c44b 100644
> --- a/docs/formatdomain.html.in
> +++ b/docs/formatdomain.html.in
> @@ -1296,6 +1296,17 @@
>  
>  Since 0.9.7
>  
> +  mirror
> +  
> +This element is present if the hypervisor has started a block
> +copy operation (via the virDomainBlockCopy API),
> +where the mirror location in attribute file will
> +eventually have the same contents as the source, and with the
> +file format in attribute format (which might
> +differ from the format of the source).  For now, this element
> +only valid in output; it is rejected on
> +input.  Since 0.9.12
> +  
>target
>The target element controls the bus / device
>  under which the disk is exposed to the guest
> diff --git a/docs/schemas/domaincommon.rng b/docs/schemas/domaincommon.rng
> index 0cc04af..66c91a2 100644
> --- a/docs/schemas/domaincommon.rng
> +++ b/docs/schemas/domaincommon.rng
> @@ -772,6 +772,9 @@
>  
>
>
> +
> +  
> +  
>  
>
>
> @@ -1013,9 +1016,7 @@
>  
>
>

Unrelated but it's not worth a separate patch.

>
>  
> @@ -3024,6 +3025,18 @@
>
>  
>
> +  
> +
> +  
> +
> +  
> +  
> +
> +  
> +
> +  
> +
> +  
>
>  
>
> diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c
> index c6b97e1..8899653 100644
> --- a/src/conf/domain_conf.c
> +++ b/src/conf/domain_conf.c
> @@ -933,6 +933,8 @@ void virDomainDiskDefFree(virDomainDiskDefPtr def)
>  VIR_FREE(def->dst);
>  VIR_FREE(def->driverName);
>  VIR_FREE(def->driverType);
> +VIR_FREE(def->mirror);
> +VIR_FREE(def->mirrorFormat);
>  VIR_FREE(def->auth.username);
>  if (def->auth.secretType == VIR_DOMAIN_DISK_SECRET_TYPE_USAGE)
>  VIR_FREE(def->auth.secret.usage);
> @@ -3318,6 +3320,8 @@ virDomainDiskDefParseXML(virCapsPtr caps,
>  char *ioeventfd = NULL;
>  char *event_idx = NULL;
>  char *copy_on_read = NULL;
> +char *mirror = NULL;
> +char *mirrorFormat = NULL;
>  char *devaddr = NULL;
>  virStorageEncryptionPtr encryption = NULL;
>  char *serial = NULL;
> @@ -3453,6 +3457,22 @@ virDomainDiskDefParseXML(virCapsPtr caps,
>  ioeventfd = virXMLPropString(cur, "ioeventfd");
>  event_idx = virXMLPropString(cur, "event_idx");
>  copy_on_read = virXMLPropString(cur, "copy_on_read");
> +} else if ((mirror == NULL) &&
> +   (xmlStrEqual(cur->name, BAD_CAST "mirror"))) {

You could have also removed those extra () when copy&pasting the code :-)

> +if (flags & VIR_DOMAIN_XML_INTERNAL_STATUS) {
> +mirror = virXMLPropString(cur, "file");
> +if (!mirror) {
> +virDomainReportError(VIR_ERR_XML_ERROR, "%s",
> + _("mirror requires file name"));
> +goto error;
> +}
> +mirrorFormat = virXMLPropString(cur, "format");
> +} else {
> +

Re: [libvirt] [libvirt-glib] Getter/setter for disk source's startupPolicy attribute

2012-04-13 Thread Christophe Fergeau
On Thu, Apr 12, 2012 at 12:08:42PM +0200, Guido Günther wrote:
> On Thu, Apr 12, 2012 at 05:54:25AM +0300, Zeeshan Ali (Khattak) wrote:
> > From: "Zeeshan Ali (Khattak)" 
> > 
> > ---
> >  libvirt-gconfig/libvirt-gconfig-domain-disk.c |   26 
> > +
> >  libvirt-gconfig/libvirt-gconfig-domain-disk.h |9 
> >  libvirt-gconfig/libvirt-gconfig.sym   |3 ++
> >  3 files changed, 38 insertions(+), 0 deletions(-)
> > 
> > diff --git a/libvirt-gconfig/libvirt-gconfig-domain-disk.c 
> > b/libvirt-gconfig/libvirt-gconfig-domain-disk.c
> > index 5d0acb5..a29ea47 100644
> > --- a/libvirt-gconfig/libvirt-gconfig-domain-disk.c
> > +++ b/libvirt-gconfig/libvirt-gconfig-domain-disk.c
> > @@ -127,6 +127,18 @@ void 
> > gvir_config_domain_disk_set_snapshot_type(GVirConfigDomainDisk *disk,
> > type, NULL);
> >  }
> >  
> > +void gvir_config_domain_disk_set_startup_policy(GVirConfigDomainDisk *disk,
> > +
> > GVirConfigDomainDiskStartupPolicy policy)
> > +{
> > +const char *str;
> > +
> > +g_return_if_fail(GVIR_CONFIG_IS_DOMAIN_DISK(disk));
> > +str = 
> > gvir_config_genum_get_nick(GVIR_CONFIG_TYPE_DOMAIN_DISK_STARTUP_POLICY, 
> > policy);
> > +g_return_if_fail(str != NULL);
> > +gvir_config_object_add_child_with_attribute(GVIR_CONFIG_OBJECT(disk),
> > +"source", "startupPolicy", 
> > str);
> > +}
> > +
> >  void gvir_config_domain_disk_set_source(GVirConfigDomainDisk *disk,
> >  const char *source)
> >  {
> > @@ -235,6 +247,19 @@ 
> > gvir_config_domain_disk_get_snapshot_type(GVirConfigDomainDisk *disk)
> >
> > GVIR_CONFIG_DOMAIN_DISK_SNAPSHOT_NO);
> >  }
> >  
> > +GVirConfigDomainDiskStartupPolicy
> > +gvir_config_domain_disk_get_startup_policy(GVirConfigDomainDisk *disk)
> > +{
> > +g_return_val_if_fail(GVIR_CONFIG_IS_DOMAIN_DISK(disk),
> > + GVIR_CONFIG_DOMAIN_DISK_STARTUP_POLICY_MANDATORY);
> > +
> > +return gvir_config_object_get_attribute_genum
> > +(GVIR_CONFIG_OBJECT(disk),
> > + "source", "startupPolicy",
> > + GVIR_CONFIG_TYPE_DOMAIN_DISK_STARTUP_POLICY,
> > + GVIR_CONFIG_DOMAIN_DISK_STARTUP_POLICY_MANDATORY);
> > +}
> > +
> >  const char *
> >  gvir_config_domain_disk_get_source(GVirConfigDomainDisk *disk)
> >  {
> > @@ -291,6 +316,7 @@ 
> > gvir_config_domain_disk_get_driver_cache(GVirConfigDomainDisk *disk)
> >
> > GVIR_CONFIG_TYPE_DOMAIN_DISK_CACHE_TYPE,
> >
> > GVIR_CONFIG_DOMAIN_DISK_CACHE_DEFAULT);
> >  }
> > +
> >  GVirConfigDomainDiskBus
> >  gvir_config_domain_disk_get_target_bus(GVirConfigDomainDisk *disk)
> >  {
> > diff --git a/libvirt-gconfig/libvirt-gconfig-domain-disk.h 
> > b/libvirt-gconfig/libvirt-gconfig-domain-disk.h
> > index 916421d..7e85d75 100644
> > --- a/libvirt-gconfig/libvirt-gconfig-domain-disk.h
> > +++ b/libvirt-gconfig/libvirt-gconfig-domain-disk.h
> > @@ -95,6 +95,12 @@ typedef enum {
> >  GVIR_CONFIG_DOMAIN_DISK_SNAPSHOT_EXTERNAL
> >  } GVirConfigDomainDiskSnapshotType;
> >  
> > +typedef enum {
> > +GVIR_CONFIG_DOMAIN_DISK_STARTUP_POLICY_MANDATORY,
> > +GVIR_CONFIG_DOMAIN_DISK_STARTUP_POLICY_REQUISITE,
> > +GVIR_CONFIG_DOMAIN_DISK_STARTUP_POLICY_OPTIONAL
> > +} GVirConfigDomainDiskStartupPolicy;
> > +
> >  GType gvir_config_domain_disk_get_type(void);
> >  
> >  GVirConfigDomainDisk *gvir_config_domain_disk_new(void);
> > @@ -107,6 +113,8 @@ void 
> > gvir_config_domain_disk_set_guest_device_type(GVirConfigDomainDisk *disk,
> > 
> > GVirConfigDomainDiskGuestDeviceType type);
> >  void gvir_config_domain_disk_set_snapshot_type(GVirConfigDomainDisk *disk,
> > 
> > GVirConfigDomainDiskSnapshotType type);
> > +void gvir_config_domain_disk_set_startup_policy(GVirConfigDomainDisk *disk,
> > +
> > GVirConfigDomainDiskStartupPolicy policy);
> >  void gvir_config_domain_disk_set_source(GVirConfigDomainDisk *disk,
> >  const char *source);
> >  void gvir_config_domain_disk_set_driver_cache(GVirConfigDomainDisk *disk,
> > @@ -123,6 +131,7 @@ void 
> > gvir_config_domain_disk_set_target_dev(GVirConfigDomainDisk *disk,
> >  GVirConfigDomainDiskType 
> > gvir_config_domain_disk_get_disk_type(GVirConfigDomainDisk *disk);
> >  GVirConfigDomainDiskGuestDeviceType 
> > gvir_config_domain_disk_get_guest_device_type(GVirConfigDomainDisk *disk);
> >  GVirConfigDomainDiskSnapshotType 
> > gvir_config_domain_disk_get_snapshot_type(GVirConfigDomainDisk *disk);
> > +GVirConfigDomainDiskStartupPolicy 
> > gvir_

Re: [libvirt] [PATCH 4/3] conf: Avoid double assignment in virDomainDiskRemove

2012-04-13 Thread Michal Privoznik
On 13.04.2012 12:25, Osier Yang wrote:
> On 04/13/2012 05:24 PM, Michal Privoznik wrote:
>> Although it should be harmless to do:
>>  disk = disk = def->disks[i]
>> some not-so-wise compilers may fool around.
>> Besides, such assignment is useless here.
>> ---
>>   src/conf/domain_conf.c |2 +-
>>   1 files changed, 1 insertions(+), 1 deletions(-)
>>

> 
> ACK


Thanks, pushed.

Michal

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


Re: [libvirt] [PATCH 1/3] qemu: Fix mem leak in qemuProcessInitCpuAffinity

2012-04-13 Thread Michal Privoznik
On 13.04.2012 12:24, Osier Yang wrote:
> On 04/13/2012 05:12 PM, Michal Privoznik wrote:
>> If placement mode is AUTO, on some return paths char *cpumap or
>> char *nodeset are leaked.
>> ---
>>   src/qemu/qemu_process.c |   23 +--
>>   1 files changed, 13 insertions(+), 10 deletions(-)
>>

> 
> ACK.

Thanks, pushed.

Michal

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


Re: [libvirt] [PATCHv4 06/18] blockjob: add 'blockcopy' to virsh

2012-04-13 Thread Jiri Denemark
On Mon, Apr 09, 2012 at 21:52:15 -0600, Eric Blake wrote:
> Rather than further overloading 'blockpull', I decided to create a
> new virsh command to expose the new flags of virDomainBlockRebase.
> 
> Someday, I'd also like to make blockpull and blockcopy have a
> synchronous mode, which blocks until the event happens or Ctrl-C
> is pressed, as well as a --verbose flag to print status updates
> before the job finishes - but not today.
> 
> * tools/virsh.c (VSH_CMD_BLOCK_JOB_COPY): New mode.
> (blockJobImpl): Support new flags.
> (cmdBlockCopy): New command.
> (cmdBlockJob): Support new job info, new abort flag.
> * tools/virsh.pod (blockcopy, blockjob): Document the new command
> and flags.
> ---
>  tools/virsh.c   |   78 +++---
>  tools/virsh.pod |   36 +++--
>  2 files changed, 101 insertions(+), 13 deletions(-)
> 
> diff --git a/tools/virsh.c b/tools/virsh.c
> index 084d533..25403f5 100644
> --- a/tools/virsh.c
> +++ b/tools/virsh.c
> @@ -7515,16 +7515,18 @@ typedef enum {
>  VSH_CMD_BLOCK_JOB_INFO = 1,
>  VSH_CMD_BLOCK_JOB_SPEED = 2,
>  VSH_CMD_BLOCK_JOB_PULL = 3,
> -} VSH_CMD_BLOCK_JOB_MODE;
> +VSH_CMD_BLOCK_JOB_COPY = 4,
> +} vshCmdBlockJobMode;
> 
>  static int
>  blockJobImpl(vshControl *ctl, const vshCmd *cmd,
> -  virDomainBlockJobInfoPtr info, int mode)
> + virDomainBlockJobInfoPtr info, int mode)
>  {
>  virDomainPtr dom = NULL;
>  const char *name, *path;
>  unsigned long bandwidth = 0;
>  int ret = -1;
> +const char *base = NULL;
>  unsigned int flags = 0;
> 
>  if (!vshConnectionUsability(ctl, ctl->conn))
> @@ -7541,22 +7543,39 @@ blockJobImpl(vshControl *ctl, const vshCmd *cmd,
>  goto cleanup;
>  }
> 
> -if (mode == VSH_CMD_BLOCK_JOB_ABORT) {
> +switch ((vshCmdBlockJobMode) mode) {
> +case  VSH_CMD_BLOCK_JOB_ABORT:
>  if (vshCommandOptBool(cmd, "async"))
>  flags |= VIR_DOMAIN_BLOCK_JOB_ABORT_ASYNC;
> +if (vshCommandOptBool(cmd, "pivot"))
> +flags |= VIR_DOMAIN_BLOCK_JOB_ABORT_PIVOT;
>  ret = virDomainBlockJobAbort(dom, path, flags);
> -} else if (mode == VSH_CMD_BLOCK_JOB_INFO) {
> +break;
> +case VSH_CMD_BLOCK_JOB_INFO:
>  ret = virDomainGetBlockJobInfo(dom, path, info, 0);
> -} else if (mode == VSH_CMD_BLOCK_JOB_SPEED) {
> +break;
> +case VSH_CMD_BLOCK_JOB_SPEED:
>  ret = virDomainBlockJobSetSpeed(dom, path, bandwidth, 0);
> -} else if (mode == VSH_CMD_BLOCK_JOB_PULL) {
> -const char *base = NULL;
> +break;
> +case VSH_CMD_BLOCK_JOB_PULL:
>  if (vshCommandOptString(cmd, "base", &base) < 0)
>  goto cleanup;
>  if (base)
>  ret = virDomainBlockRebase(dom, path, base, bandwidth, 0);
>  else
>  ret = virDomainBlockPull(dom, path, bandwidth, 0);
> +break;
> +case VSH_CMD_BLOCK_JOB_COPY:
> +flags |= VIR_DOMAIN_BLOCK_REBASE_COPY;
> +if (vshCommandOptBool(cmd, "shallow"))
> +flags |= VIR_DOMAIN_BLOCK_REBASE_SHALLOW;
> +if (vshCommandOptBool(cmd, "reuse-external"))
> +flags |= VIR_DOMAIN_BLOCK_REBASE_REUSE_EXT;
> +if (vshCommandOptBool(cmd, "raw"))
> +flags |= VIR_DOMAIN_BLOCK_REBASE_COPY_RAW;
> +if (vshCommandOptString(cmd, "dest", &base) < 0)
> +goto cleanup;
> +ret = virDomainBlockRebase(dom, path, base, bandwidth, flags);
>  }
> 
>  cleanup:
> @@ -7566,6 +7585,34 @@ cleanup:
>  }
> 
>  /*
> + * "blockcopy" command
> + */
> +static const vshCmdInfo info_block_copy[] = {
> +{"help", N_("Start a block copy operation.")},
> +{"desc", N_("Populate a disk from its backing image.")},
> +{NULL, NULL}
> +};
> +
> +static const vshCmdOptDef opts_block_copy[] = {
> +{"domain", VSH_OT_DATA, VSH_OFLAG_REQ, N_("domain name, id or uuid")},
> +{"path", VSH_OT_DATA, VSH_OFLAG_REQ, N_("Fully-qualified path of disk")},
> +{"dest", VSH_OT_DATA, VSH_OFLAG_REQ, N_("path of the copy to create")},
> +{"bandwidth", VSH_OT_DATA, VSH_OFLAG_NONE, N_("Bandwidth limit in 
> MB/s")},
> +{"shallow", VSH_OT_BOOL, 0, N_("make the copy share a backing chain")},
> +{"reuse-external", VSH_OT_BOOL, 0, N_("reuse existing destination")},
> +{"raw", VSH_OT_BOOL, 0, N_("use raw destination file")},
> +{NULL, 0, 0, NULL}
> +};

You are pretty inconsistent in upper/lower-case letter at the beginning of
each description string.

> +
> +static bool
> +cmdBlockCopy(vshControl *ctl, const vshCmd *cmd)
> +{
> +if (blockJobImpl(ctl, cmd, NULL, VSH_CMD_BLOCK_JOB_COPY) != 0)
> +return false;
> +return true;
> +}
> +
> +/*
>   * "blockpull" command
>   */
>  static const vshCmdInfo info_block_pull[] = {
> @@ -7607,6 +7654,8 @@ static const vshCmdOptDef opts_block_job[] = {
>   N_("Abort the active job on the specified disk")},
>  {"a

Re: [libvirt] [PATCHv4 05/18] blockjob: add new API flags

2012-04-13 Thread Jiri Denemark
On Mon, Apr 09, 2012 at 21:52:14 -0600, Eric Blake wrote:
> This patch introduces a new block job, useful for live storage
> migration using pre-copy streaming.
> 
> Using a live VM with the backing chain:
>   base <- snap1 <- snap2
> as the starting point, we have:
> 
> - virDomainBlockRebase(dom, disk, "/path/to/copy", 0,
> VIR_DOMAIN_BLOCK_REBASE_COPY)
> creates /path/to/copy with the same format as snap2, with no backing
> file, so entire chain is copied and flattened
> 
> - virDomainBlockRebase(dom, disk, "/path/to/copy", 0,
> VIR_DOMAIN_BLOCK_REBASE_COPY|VIR_DOMAIN_BLOCK_REBASE_COPY_RAW)
> creates /path/to/copy as a raw file, so entire chain is copied and
> flattened
> 
> - virDomainBlockRebase(dom, disk, "/path/to/copy", 0,
> VIR_DOMAIN_BLOCK_REBASE_COPY|VIR_DOMAIN_BLOCK_REBASE_SHALLOW)
> creates /path/to/copy with the same format as snap2, but with snap1 as
> a backing file, so only snap2 is copied.
> 
> - virDomainBlockRebase(dom, disk, "/path/to/copy", 0,
> VIR_DOMAIN_BLOCK_REBASE_COPY|VIR_DOMAIN_BLOCK_REBASE_REUSE_EXT)
> reuse existing /path/to/copy (must have empty contents, and format is
> probed from the metadata), and copy the full chain
> 
> - virDomainBlockRebase(dom, disk, "/path/to/copy", 0,
> VIR_DOMAIN_BLOCK_REBASE_COPY|VIR_DOMAIN_BLOCK_REBASE_REUSE_EXT|
> VIR_DOMAIN_BLOCK_REBASE_SHALLOW)
> reuse existing /path/to/copy (contents must be identical to snap1,
> and format is probed from the metadata), and copy only the contents
> of snap2
> 
> - virDomainBlockRebase(dom, disk, "/path/to/copy", 0,
> VIR_DOMAIN_BLOCK_REBASE_COPY|VIR_DOMAIN_BLOCK_REBASE_REUSE_EXT|
> VIR_DOMAIN_BLOCK_REBASE_SHALLOW|VIR_DOMAIN_BLOCK_REBASE_COPY_RAW)
> reuse existing /path/to/copy (must be raw volume with contents
> identical to snap1), and copy only the contents of snap2
> 
> Less useful combinations:
> 
> - virDomainBlockRebase(dom, disk, "/path/to/copy", 0,
> VIR_DOMAIN_BLOCK_REBASE_COPY|VIR_DOMAIN_BLOCK_REBASE_SHALLOW|
> VIR_DOMAIN_BLOCK_REBASE_COPY_RAW)
> fail if source is not raw, otherwise create /path/to/copy as raw and
> the single file is copied (no chain involved)
> 
> - virDomainBlockRebase(dom, disk, "/path/to/copy", 0,
> VIR_DOMAIN_BLOCK_REBASE_COPY|VIR_DOMAIN_BLOCK_REBASE_REUSE_EXT|
> VIR_DOMAIN_BLOCK_REBASE_COPY_RAW)
> makes little sense: the destination must be raw but have no contents,
> meaning that it is an empty file, so there is nothing to reuse
> 
> The other three flags are rejected without VIR_DOMAIN_BLOCK_COPY.
> 
> It would be nice if we could issue an event when pivoting from phase 1
> to phase 2, but qemu hasn't implemented that, and we would have to poll
> in order to synthesize it ourselves.  Meanwhile, qemu will give us a
> distinct job info and completion event when we either cancel or pivot
> to end the job.  Pivoting is accomplished via the new:
> 
> virDomainBlockJobAbort(dom, disk, VIR_DOMAIN_BLOCK_JOB_ABORT_PIVOT)
> 
> Management applications can pre-create the copy with a relative
> backing file name, and use the VIR_DOMAIN_BLOCK_REBASE_REUSE_EXT
> flag to have qemu reuse the metadata; if the management application
> also copies the backing files to a new location, this can be used
> to perform live storage migration of an entire backing chain.
> 
> * include/libvirt/libvirt.h.in (VIR_DOMAIN_BLOCK_JOB_TYPE_COPY):
> New block job type.
> (virDomainBlockJobAbortFlags, virDomainBlockRebaseFlags): New enums.
> * src/libvirt.c (virDomainBlockRebase): Document the new flags,
> and implement general restrictions on flag combinations.
> (virDomainBlockJobAbort): Document the new flag.
> (virDomainSaveFlags, virDomainSnapshotCreateXML)
> (virDomainRevertToSnapshot, virDomainDetachDeviceFlags): Document
> restrictions.
> * include/libvirt/virterror.h (VIR_ERR_BLOCK_COPY_ACTIVE): New
> error.
> * src/util/virterror.c (virErrorMsg): Define it.
> ---
>  include/libvirt/libvirt.h.in |   24 ++-
>  include/libvirt/virterror.h  |1 +
>  src/libvirt.c|   94 
> ++
>  src/util/virterror.c |6 +++
>  4 files changed, 115 insertions(+), 10 deletions(-)
> 
> diff --git a/include/libvirt/libvirt.h.in b/include/libvirt/libvirt.h.in
> index 97ad99d..ac5df95 100644
> --- a/include/libvirt/libvirt.h.in
> +++ b/include/libvirt/libvirt.h.in
> @@ -1934,12 +1934,15 @@ int virDomainUpdateDeviceFlags(virDomainPtr domain,
>  /**
>   * virDomainBlockJobType:
>   *
> - * VIR_DOMAIN_BLOCK_JOB_TYPE_PULL: Block Pull (virDomainBlockPull or
> - * virDomainBlockRebase)
> + * VIR_DOMAIN_BLOCK_JOB_TYPE_PULL: Block Pull (virDomainBlockPull, or
> + * virDomainBlockRebase without flags), job ends on completion
> + * VIR_DOMAIN_BLOCK_JOB_TYPE_COPY: Block Copy (virDomainBlockRebase with
> + * flags), job exists as long as mirroring is active
>   */
>  typedef enum {
>  VIR_DOMAIN_BLOCK_JOB_TYPE_UNKNOWN = 0,
>  VIR_DOMAIN_BLOCK_JOB_TYPE_PULL = 1,
> +VIR_DOMAIN_BLOCK_JOB_TYPE_COPY = 2,
> 

Re: [libvirt] [PATCH 4/3] conf: Avoid double assignment in virDomainDiskRemove

2012-04-13 Thread Osier Yang

On 04/13/2012 05:24 PM, Michal Privoznik wrote:

Although it should be harmless to do:
 disk = disk = def->disks[i]
some not-so-wise compilers may fool around.
Besides, such assignment is useless here.
---
  src/conf/domain_conf.c |2 +-
  1 files changed, 1 insertions(+), 1 deletions(-)

diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c
index c6b97e1..a9c5cbc 100644
--- a/src/conf/domain_conf.c
+++ b/src/conf/domain_conf.c
@@ -7124,7 +7124,7 @@ void virDomainDiskInsertPreAlloced(virDomainDefPtr def,
  virDomainDiskDefPtr
  virDomainDiskRemove(virDomainDefPtr def, size_t i)
  {
-virDomainDiskDefPtr disk = disk = def->disks[i];
+virDomainDiskDefPtr disk = def->disks[i];

  if (def->ndisks>  1) {
  memmove(def->disks + i,


ACK

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


Re: [libvirt] [PATCH 1/3] qemu: Fix mem leak in qemuProcessInitCpuAffinity

2012-04-13 Thread Osier Yang

On 04/13/2012 05:12 PM, Michal Privoznik wrote:

If placement mode is AUTO, on some return paths char *cpumap or
char *nodeset are leaked.
---
  src/qemu/qemu_process.c |   23 +--
  1 files changed, 13 insertions(+), 10 deletions(-)

diff --git a/src/qemu/qemu_process.c b/src/qemu/qemu_process.c
index 19569cf..692fc32 100644
--- a/src/qemu/qemu_process.c
+++ b/src/qemu/qemu_process.c
@@ -1796,6 +1796,7 @@ static int
  qemuProcessInitCpuAffinity(struct qemud_driver *driver,
 virDomainObjPtr vm)
  {
+int ret = -1;
  int i, hostcpus, maxcpu = QEMUD_CPUMASK_LEN;
  virNodeInfo nodeinfo;
  unsigned char *cpumap;
@@ -1824,19 +1825,21 @@ qemuProcessInitCpuAffinity(struct qemud_driver *driver,

  nodeset = qemuGetNumadAdvice(vm->def);
  if (!nodeset)
-return -1;
+goto cleanup;

  if (VIR_ALLOC_N(tmp_cpumask, VIR_DOMAIN_CPUMASK_LEN)<  0) {
  virReportOOMError();
-return -1;
+VIR_FREE(nodeset);
+goto cleanup;
  }

  if (virDomainCpuSetParse(nodeset, 0, tmp_cpumask,
   VIR_DOMAIN_CPUMASK_LEN)<  0) {
  VIR_FREE(tmp_cpumask);
  VIR_FREE(nodeset);
-return -1;
+goto cleanup;
  }
+VIR_FREE(nodeset);

  for (i = 0; i<  maxcpu&&  i<  VIR_DOMAIN_CPUMASK_LEN; i++) {
  if (tmp_cpumask[i])
@@ -1849,7 +1852,6 @@ qemuProcessInitCpuAffinity(struct qemud_driver *driver,
  VIR_WARN("Unable to save status on vm %s after state change",
   vm->def->name);
  }
-VIR_FREE(nodeset);
  } else {
  if (vm->def->cpumask) {
  /* XXX why don't we keep 'cpumask' in the libvirt cpumap
@@ -1872,13 +1874,14 @@ qemuProcessInitCpuAffinity(struct qemud_driver *driver,
   * running at this point
   */
  if (virProcessInfoSetAffinity(0, /* Self */
-  cpumap, cpumaplen, maxcpu)<  0) {
-VIR_FREE(cpumap);
-return -1;
-}
+  cpumap, cpumaplen, maxcpu)<  0)
+goto cleanup;
+
+ret = 0;
+
+cleanup:
  VIR_FREE(cpumap);
-
-return 0;
+return ret;
  }

  /* set link states to down on interfaces at qemu start */


ACK.

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


[libvirt] [test-API PATCH] repo: Add test for console input and output operations

2012-04-13 Thread Peter Krempa
This test checks if the console input and output work as desired. The
test takes as an argument a filename, whose contents are sent to the
console. The optional parameter 'expect' can be set to a filename that
should contain expected output from the guest and is compared with the
actual output. The optional parameter 'output' can be set to a filename
where the test script saves the output of the host (useful for initial
test setup).

This test requires that the guest machine runs code that handles input and
output on the serial console (programs such as agetty or something like that).
---
 repos/domain/console_io.py |  123 
 1 files changed, 123 insertions(+), 0 deletions(-)
 create mode 100644 repos/domain/console_io.py

diff --git a/repos/domain/console_io.py b/repos/domain/console_io.py
new file mode 100644
index 000..98fd5b6
--- /dev/null
+++ b/repos/domain/console_io.py
@@ -0,0 +1,123 @@
+#!/usr/bin/env python
+# test console interactions
+# This test sends contents of file 'input' to the guest's console
+# and reads from the console the reply and compares it to 'expect' or
+# writes the output to file 'output'
+
+import libvirt
+import signal
+import os
+
+from libvirt import libvirtError
+from exception import TestError
+
+required_params = ('guestname',)
+optional_params = ('device', 'timeout', 'input', 'output', 'expect',)
+
+def alarm_handler(signum, frame):
+raise TestError("Timed out while waiting for console")
+
+def console_io(params):
+"""Attach to console"""
+logger = params['logger']
+guest = params['guestname']
+device = params.get('device', 'serial0')
+infile = params.get('input', None)
+outfile = params.get('output', None)
+expect = params.get('expect', None)
+timeout = params.get('timeout', 5)
+
+uri = params['uri']
+
+#store the old signal handler
+oldhandler = signal.getsignal(signal.SIGALRM)
+
+try:
+logger.info("Connecting to hypervisor: '%s'" % uri)
+conn = libvirt.open(uri)
+dom = conn.lookupByName(guest)
+if not dom.isActive():
+raise TestError("Guest '%s' not active" % guest)
+
+logger.info("Creating stream object")
+stream = conn.newStream(0)
+
+logger.info("Open a new console connection")
+dom.openConsole(device, stream, libvirt.VIR_DOMAIN_CONSOLE_FORCE)
+
+if infile != None:
+try:
+f = open(infile, 'r')
+instr = f.read()
+f.close()
+except e:
+raise TestError("Can't read input file '%s': %s" % (infile, 
str(e)))
+
+logger.info("Sending %d bytes of contents of file '%s' to console 
'%s'" % (len(instr), infile, device))
+stream.send(instr)
+
+if expect != None or outfile != None:
+logger.info("Recieving data from console device. Timeout %d 
seconds." % timeout)
+
+# register a new signal handler
+logger.info("Registering custom SIGALRM handler")
+signal.signal(signal.SIGALRM, alarm_handler)
+signal.alarm(timeout)
+
+reply = ""
+try:
+while True:
+recv = stream.recv(1024)
+reply += recv
+except TestError:
+pass
+
+logger.info("Recieved %d bytes." % len(reply))
+
+if outfile != None:
+try:
+f = open(outfile, 'w')
+f.write(reply)
+f.close()
+except e:
+raise TestError("Can't write output to file '%s': %s" % 
(outfile, str(e)))
+
+if expect != None:
+try:
+f = open(expect, 'r')
+expectstr = f.read()
+f.close()
+except Exception, e:
+raise TestError("Can't read expected output file '%s': 
'%s'" % (expect, str(e)))
+
+if reply.startswith(expectstr):
+logger.info("Recieved expected output from the host")
+else:
+raise TestError("Reply from the guest doesn't match with 
expected reply")
+
+except libvirtError, e:
+logger.error("Libvirt call failed: " + str(e))
+ret = 1
+
+except TestError, e:
+logger.error("Test failed: " + str(e))
+ret = 1
+
+else:
+logger.info("All tests succeeded")
+ret = 0
+
+finally:
+logger.info("Restoring signal handler")
+signal.signal(signal.SIGALRM, oldhandler)
+logger.info("Closing hypervisor connection")
+try:
+stream.abort()
+except:
+pass
+conn.close()
+
+logger.info("Done")
+
+return ret
+
-- 
1.7.3.4

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


Re: [libvirt] [PATCHv4 05/18] blockjob: add new API flags

2012-04-13 Thread Jiri Denemark
On Mon, Apr 09, 2012 at 21:52:14 -0600, Eric Blake wrote:
> This patch introduces a new block job, useful for live storage
> migration using pre-copy streaming.
> 
> Using a live VM with the backing chain:
>   base <- snap1 <- snap2
> as the starting point, we have:
> 
> - virDomainBlockRebase(dom, disk, "/path/to/copy", 0,
> VIR_DOMAIN_BLOCK_REBASE_COPY)
> creates /path/to/copy with the same format as snap2, with no backing
> file, so entire chain is copied and flattened
> 
> - virDomainBlockRebase(dom, disk, "/path/to/copy", 0,
> VIR_DOMAIN_BLOCK_REBASE_COPY|VIR_DOMAIN_BLOCK_REBASE_COPY_RAW)
> creates /path/to/copy as a raw file, so entire chain is copied and
> flattened
> 
> - virDomainBlockRebase(dom, disk, "/path/to/copy", 0,
> VIR_DOMAIN_BLOCK_REBASE_COPY|VIR_DOMAIN_BLOCK_REBASE_SHALLOW)
> creates /path/to/copy with the same format as snap2, but with snap1 as
> a backing file, so only snap2 is copied.

In other words, this doesn't do any rebase at all, it just copies snap2 into
copy and the result is the following chain:
base <- snap1 <- copy

Did I get it right?

> - virDomainBlockRebase(dom, disk, "/path/to/copy", 0,
> VIR_DOMAIN_BLOCK_REBASE_COPY|VIR_DOMAIN_BLOCK_REBASE_REUSE_EXT)
> reuse existing /path/to/copy (must have empty contents, and format is
> probed from the metadata), and copy the full chain

Hmm, in the past we tried to avoid format probing for security reasons.
Shouldn't we avoid introducing new code that needs format probing? However,
I'm not sure that's doable at all in this case.

> - virDomainBlockRebase(dom, disk, "/path/to/copy", 0,
> VIR_DOMAIN_BLOCK_REBASE_COPY|VIR_DOMAIN_BLOCK_REBASE_REUSE_EXT|
> VIR_DOMAIN_BLOCK_REBASE_SHALLOW)
> reuse existing /path/to/copy (contents must be identical to snap1,
> and format is probed from the metadata), and copy only the contents
> of snap2
> 
> - virDomainBlockRebase(dom, disk, "/path/to/copy", 0,
> VIR_DOMAIN_BLOCK_REBASE_COPY|VIR_DOMAIN_BLOCK_REBASE_REUSE_EXT|
> VIR_DOMAIN_BLOCK_REBASE_SHALLOW|VIR_DOMAIN_BLOCK_REBASE_COPY_RAW)
> reuse existing /path/to/copy (must be raw volume with contents
> identical to snap1), and copy only the contents of snap2
> 
> Less useful combinations:
> 
> - virDomainBlockRebase(dom, disk, "/path/to/copy", 0,
> VIR_DOMAIN_BLOCK_REBASE_COPY|VIR_DOMAIN_BLOCK_REBASE_SHALLOW|
> VIR_DOMAIN_BLOCK_REBASE_COPY_RAW)
> fail if source is not raw, otherwise create /path/to/copy as raw and
> the single file is copied (no chain involved)
> 
> - virDomainBlockRebase(dom, disk, "/path/to/copy", 0,
> VIR_DOMAIN_BLOCK_REBASE_COPY|VIR_DOMAIN_BLOCK_REBASE_REUSE_EXT|
> VIR_DOMAIN_BLOCK_REBASE_COPY_RAW)
> makes little sense: the destination must be raw but have no contents,
> meaning that it is an empty file, so there is nothing to reuse
> 
> The other three flags are rejected without VIR_DOMAIN_BLOCK_COPY.
> 
> It would be nice if we could issue an event when pivoting from phase 1
> to phase 2, but qemu hasn't implemented that, and we would have to poll
> in order to synthesize it ourselves.  Meanwhile, qemu will give us a
> distinct job info and completion event when we either cancel or pivot
> to end the job.  Pivoting is accomplished via the new:
> 
> virDomainBlockJobAbort(dom, disk, VIR_DOMAIN_BLOCK_JOB_ABORT_PIVOT)
> 
> Management applications can pre-create the copy with a relative
> backing file name, and use the VIR_DOMAIN_BLOCK_REBASE_REUSE_EXT
> flag to have qemu reuse the metadata; if the management application
> also copies the backing files to a new location, this can be used
> to perform live storage migration of an entire backing chain.

This all sounds quite complicated but you explained it well in the
documentation block for virDomainBlockRebase. When reading the above, I
thought an example showing all steps needed to copy a disk image would be
useful but reading virDomainBlockRebase documentation clarified it enough that
I don't think the example is required :-)

This all looks good and I think sticking this functionality into
virDomainBlockRebase makes sense. Since the qemu interface is not set in stone
yet, I won't formally ack any of these block copy patches :-)

Jirka

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


Re: [libvirt] [PATCH 3/3] qemu: Split if condition in qemuDomainSnapshotUndoSingleDiskActive

2012-04-13 Thread Daniel P. Berrange
On Fri, Apr 13, 2012 at 11:12:54AM +0200, Michal Privoznik wrote:
> Since compilers are trying to optimize code they are allowed to
> reorder evaluation of conditions in if statement (okay, not in all
> cases, but they can in this one). Therefore if we do:
> if (stat(file, &st) == 0 && unlink(file) < 0)
> after compiler chews this it may get feeling that swapping order
> is a good idea. However, we obviously don't want to call stat()
> on just unlink()-ed file.

Really ? I'm not sure I believe that. IIRC in-order short-circuit
evaluation is a part of the C standard. Compilers can't do any
optimization which changes the order of evalation without breaking
countless C programs.

> ---
>  src/qemu/qemu_driver.c |9 +++--
>  1 files changed, 7 insertions(+), 2 deletions(-)
> 
> diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c
> index 65ed290..037d45c 100644
> --- a/src/qemu/qemu_driver.c
> +++ b/src/qemu/qemu_driver.c
> @@ -9998,9 +9998,14 @@ qemuDomainSnapshotUndoSingleDiskActive(struct 
> qemud_driver *driver,
>  VIR_WARN("Unable to restore security label on %s", disk->src);
>  if (virDomainLockDiskDetach(driver->lockManager, vm, disk) < 0)
>  VIR_WARN("Unable to release lock on %s", disk->src);
> +
> +/* Deliberately do not join these two ifs. Compiler may mix up
> + * the order of evaluation so unlink() may proceed stat()
> + * which is not what we want */
>  if (need_unlink && stat(disk->src, &st) == 0 &&
> -st.st_size == 0 && S_ISREG(st.st_mode) && unlink(disk->src) < 0)
> -VIR_WARN("Unable to remove just-created %s", disk->src);
> +st.st_size == 0 && S_ISREG(st.st_mode))
> +if (unlink(disk->src) < 0)
> +VIR_WARN("Unable to remove just-created %s", disk->src);
>  
>  /* Update vm in place to match changes.  */
>  VIR_FREE(disk->src);


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

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


Re: [libvirt] [Guidelines Change] Changes to the Packaging Guidelines

2012-04-13 Thread Daniel P. Berrange
On Thu, Apr 12, 2012 at 03:13:13PM -0600, Eric Blake wrote:
> things we should be thinking about:
> 
> On 04/12/2012 02:57 PM, Tom Callaway wrote:
> > Here is the latest set of changes to the Fedora Packaging Guidelines:
> > 
> > ---
> > 
> > Packages which have SysV initscripts that contain 'non-standard service
> > commands' (commands besides start, stop, reload, restart, or
> > try-restart) must convert those commands into standalone helper scripts.
> > Systemd does not support non-standard unit commands.
> > 
> > https://fedoraproject.org/wiki/Packaging:Systemd#Unit_Files
> 
> I think libvirt-guests falls into this category.
> 
> > 
> > ---
> > 
> > The guidelines relating to PIE and Hardened Packages were updated. Now,
> > if your package meets the following critera you MUST enable the PIE
> > compiler flags:
> > 
> > * Your package is long running. This means it's likely to be started and
> > keep running until the machine is rebooted, not start on demand and quit
> > on idle.
> > 
> > * Your package has suid binaries, or binaries with capabilities.
> > 
> > * Your package runs as root.
> > 
> > https://fedoraproject.org/wiki/Packaging:Guidelines#PIE
> 
> libvirtd definitely qualifies as one of these packages needing PIE
> compilation in our libvirt.spec file.

We should make sure libvirt always uses these PIE flags, avoiding the
need for the RPM macro

> Plus, we still haven't converted our mingw specfile over to the mingw64
> toolchain.  Anyone up for some specfile maintenance?

That's waiting on other Fedora maintainers to port over things we
depend on. Once they're ported, I'll update libvirt


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

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


Re: [libvirt] [PATCH v2] Pull DBus event code out into common area

2012-04-13 Thread Daniel P. Berrange
On Thu, Apr 12, 2012 at 05:34:54PM -0600, Eric Blake wrote:
> On 04/12/2012 02:07 PM, Daniel P. Berrange wrote:
> > From: "Daniel P. Berrange" 
> > 
> > The policy kit and HAL node device drivers both require a
> > DBus connection. The HAL device code further requires that
> > the DBus connection is integrated with the event loop and
> > provides such glue logic itself.
> > 
> > The forthcoming FirewallD integration also requires a
> > dbus connection with event loop integration. Thus we need
> > to pull the current event loop glue out of the HAL driver.
> > 
> > Thus we create src/util/virdbus.{c,h} files. This contains
> > just one method virDBusGetSystemBus() which obtains a handle
> > to the single shared system bus instance, with event glue
> > automagically setup.
> > ---
> >  .gitignore|6 +-
> >  configure.ac  |   37 ++-
> >  daemon/Makefile.am|3 +-
> >  daemon/libvirtd.c |4 -
> >  daemon/remote.c   |8 +-
> >  include/libvirt/virterror.h   |1 +
> >  src/Makefile.am   |   13 +--
> >  src/libvirt_dbus.syms |2 -
> 
> You're dropping libvirt_dbus.syms, but I don't see where you are
> modifying libvirt_private.syms to make up for it.

The symbol in question was completely deleted from the code.


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

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


[libvirt] [PATCH 4/3] conf: Avoid double assignment in virDomainDiskRemove

2012-04-13 Thread Michal Privoznik
Although it should be harmless to do:
disk = disk = def->disks[i]
some not-so-wise compilers may fool around.
Besides, such assignment is useless here.
---
 src/conf/domain_conf.c |2 +-
 1 files changed, 1 insertions(+), 1 deletions(-)

diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c
index c6b97e1..a9c5cbc 100644
--- a/src/conf/domain_conf.c
+++ b/src/conf/domain_conf.c
@@ -7124,7 +7124,7 @@ void virDomainDiskInsertPreAlloced(virDomainDefPtr def,
 virDomainDiskDefPtr
 virDomainDiskRemove(virDomainDefPtr def, size_t i)
 {
-virDomainDiskDefPtr disk = disk = def->disks[i];
+virDomainDiskDefPtr disk = def->disks[i];
 
 if (def->ndisks > 1) {
 memmove(def->disks + i,
-- 
1.7.8.5

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


[libvirt] [PATCH 3/3] qemu: Split if condition in qemuDomainSnapshotUndoSingleDiskActive

2012-04-13 Thread Michal Privoznik
Since compilers are trying to optimize code they are allowed to
reorder evaluation of conditions in if statement (okay, not in all
cases, but they can in this one). Therefore if we do:
if (stat(file, &st) == 0 && unlink(file) < 0)
after compiler chews this it may get feeling that swapping order
is a good idea. However, we obviously don't want to call stat()
on just unlink()-ed file.
---
 src/qemu/qemu_driver.c |9 +++--
 1 files changed, 7 insertions(+), 2 deletions(-)

diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c
index 65ed290..037d45c 100644
--- a/src/qemu/qemu_driver.c
+++ b/src/qemu/qemu_driver.c
@@ -9998,9 +9998,14 @@ qemuDomainSnapshotUndoSingleDiskActive(struct 
qemud_driver *driver,
 VIR_WARN("Unable to restore security label on %s", disk->src);
 if (virDomainLockDiskDetach(driver->lockManager, vm, disk) < 0)
 VIR_WARN("Unable to release lock on %s", disk->src);
+
+/* Deliberately do not join these two ifs. Compiler may mix up
+ * the order of evaluation so unlink() may proceed stat()
+ * which is not what we want */
 if (need_unlink && stat(disk->src, &st) == 0 &&
-st.st_size == 0 && S_ISREG(st.st_mode) && unlink(disk->src) < 0)
-VIR_WARN("Unable to remove just-created %s", disk->src);
+st.st_size == 0 && S_ISREG(st.st_mode))
+if (unlink(disk->src) < 0)
+VIR_WARN("Unable to remove just-created %s", disk->src);
 
 /* Update vm in place to match changes.  */
 VIR_FREE(disk->src);
-- 
1.7.8.5

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


[libvirt] [PATCH 1/3] qemu: Fix mem leak in qemuProcessInitCpuAffinity

2012-04-13 Thread Michal Privoznik
If placement mode is AUTO, on some return paths char *cpumap or
char *nodeset are leaked.
---
 src/qemu/qemu_process.c |   23 +--
 1 files changed, 13 insertions(+), 10 deletions(-)

diff --git a/src/qemu/qemu_process.c b/src/qemu/qemu_process.c
index 19569cf..692fc32 100644
--- a/src/qemu/qemu_process.c
+++ b/src/qemu/qemu_process.c
@@ -1796,6 +1796,7 @@ static int
 qemuProcessInitCpuAffinity(struct qemud_driver *driver,
virDomainObjPtr vm)
 {
+int ret = -1;
 int i, hostcpus, maxcpu = QEMUD_CPUMASK_LEN;
 virNodeInfo nodeinfo;
 unsigned char *cpumap;
@@ -1824,19 +1825,21 @@ qemuProcessInitCpuAffinity(struct qemud_driver *driver,
 
 nodeset = qemuGetNumadAdvice(vm->def);
 if (!nodeset)
-return -1;
+goto cleanup;
 
 if (VIR_ALLOC_N(tmp_cpumask, VIR_DOMAIN_CPUMASK_LEN) < 0) {
 virReportOOMError();
-return -1;
+VIR_FREE(nodeset);
+goto cleanup;
 }
 
 if (virDomainCpuSetParse(nodeset, 0, tmp_cpumask,
  VIR_DOMAIN_CPUMASK_LEN) < 0) {
 VIR_FREE(tmp_cpumask);
 VIR_FREE(nodeset);
-return -1;
+goto cleanup;
 }
+VIR_FREE(nodeset);
 
 for (i = 0; i < maxcpu && i < VIR_DOMAIN_CPUMASK_LEN; i++) {
 if (tmp_cpumask[i])
@@ -1849,7 +1852,6 @@ qemuProcessInitCpuAffinity(struct qemud_driver *driver,
 VIR_WARN("Unable to save status on vm %s after state change",
  vm->def->name);
 }
-VIR_FREE(nodeset);
 } else {
 if (vm->def->cpumask) {
 /* XXX why don't we keep 'cpumask' in the libvirt cpumap
@@ -1872,13 +1874,14 @@ qemuProcessInitCpuAffinity(struct qemud_driver *driver,
  * running at this point
  */
 if (virProcessInfoSetAffinity(0, /* Self */
-  cpumap, cpumaplen, maxcpu) < 0) {
-VIR_FREE(cpumap);
-return -1;
-}
+  cpumap, cpumaplen, maxcpu) < 0)
+goto cleanup;
+
+ret = 0;
+
+cleanup:
 VIR_FREE(cpumap);
-
-return 0;
+return ret;
 }
 
 /* set link states to down on interfaces at qemu start */
-- 
1.7.8.5

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


[libvirt] [PATCH 2/3] gitignore: Reorder alphabetically

2012-04-13 Thread Michal Privoznik
Recent git reorders .gitignore alphabetically. However, changes are
not committed and I am tired of discarding these changes from
my patches.
---
 .gitignore |6 +++---
 1 files changed, 3 insertions(+), 3 deletions(-)

diff --git a/.gitignore b/.gitignore
index 5aa9c9b..14a21d0 100644
--- a/.gitignore
+++ b/.gitignore
@@ -48,12 +48,12 @@
 /daemon/*_dispatch.h
 /daemon/libvirt_qemud
 /daemon/libvirtd
-/daemon/libvirtd.init
-/daemon/libvirtd.service
 /daemon/libvirtd*.logrotate
 /daemon/libvirtd.8
 /daemon/libvirtd.8.in
+/daemon/libvirtd.init
 /daemon/libvirtd.pod
+/daemon/libvirtd.service
 /docs/devhelp/libvirt.devhelp
 /docs/hvsupport.html.in
 /docs/libvirt-api.xml
@@ -118,6 +118,7 @@
 /tests/eventtest
 /tests/hashtest
 /tests/jsontest
+/tests/libvirtdconftest
 /tests/networkxml2argvtest
 /tests/nodeinfotest
 /tests/nwfilterxml2xmltest
@@ -150,7 +151,6 @@
 /tests/vmx2xmltest
 /tests/xencapstest
 /tests/xmconfigtest
-/tests/libvirtdconftest
 /tools/*.[18]
 /tools/libvirt-guests.init
 /tools/virsh
-- 
1.7.8.5

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


[libvirt] [PATCH 0/3] Couple of cleanups in qemu code

2012-04-13 Thread Michal Privoznik

Michal Privoznik (3):
  qemu: Fix mem leak in qemuProcessInitCpuAffinity
  gitignore: Reorder alphabetically
  qemu: Split if condition in qemuDomainSnapshotUndoSingleDiskActive

 .gitignore  |6 +++---
 src/qemu/qemu_driver.c  |9 +++--
 src/qemu/qemu_process.c |   23 +--
 3 files changed, 23 insertions(+), 15 deletions(-)

-- 
1.7.8.5

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


[libvirt] [test-API PATCH 1/2] casecfgcheck: ignore flags defined in testcase flag

2012-04-13 Thread Guannan Ren
When flag defined in testcase config file like as follows
the casecfgcheck still trys to use flag 'clean' or 'sleep' as
the key to get required_params, optional_params variables.
so it reports 'KeyError' becuase no testcases named 'clean'
or 'sleep' in case_params data format. The patch ignore
the check for these flags.

domain:start
guestname
fedora16
clean

domain:shutdown
guestname
fedora16
sleep 6

domain:destroy
guestname
fedora16
---
 casecfgcheck.py |8 ++--
 1 files changed, 6 insertions(+), 2 deletions(-)

diff --git a/casecfgcheck.py b/casecfgcheck.py
index a88eb74..40d7c6e 100644
--- a/casecfgcheck.py
+++ b/casecfgcheck.py
@@ -33,14 +33,18 @@ class CaseCfgCheck(object):
 error_flag = 0
 passed_testcase = []
 for testcase in self.activity:
-case_number += 1
 if testcase in passed_testcase:
 continue
 
 testcase_name = testcase.keys()[0]
-actual_params = testcase.values()[0]
+if testcase_name == 'clean' or \
+   testcase_name == 'sleep':
+continue
 
+actual_params = testcase.values()[0]
 required_params, optional_params = self.case_params[testcase_name]
+
+case_number += 1
 ret = self._check_params(required_params, optional_params, 
actual_params)
 if ret:
 error_flag = 1
-- 
1.7.7.5

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


[libvirt] [test-API PATCH 2/2] parser: put the syntax checking to testcase line at end of flags checking

2012-04-13 Thread Guannan Ren
we use the "re.match(".+:.+", tripped_casename)" only check testcase
name line, such as domain:start, we don't want it to check flag.
placing it just after flags checking is right place.
---
 parser.py |5 +++--
 1 files changed, 3 insertions(+), 2 deletions(-)

diff --git a/parser.py b/parser.py
index 18f6ccd..e569d7f 100644
--- a/parser.py
+++ b/parser.py
@@ -327,8 +327,6 @@ class CaseFileParser(object):
 
 tripped_caselist = casestring.strip().split()
 tripped_casename = tripped_caselist[0]
-if not re.match(".+:.+", tripped_casename):
-raise exception.CaseConfigfileError("casename line format 
error!")
 
 if self.debug:
 self.debug_print("we begin to handle the case",
@@ -416,6 +414,9 @@ class CaseFileParser(object):
 list.append(option_case)
 continue
 
+if not re.match(".+:.+", tripped_casename):
+raise exception.CaseConfigfileError("%s line format 
error!" % tripped_casename)
+
 for caselist in list:
 newdict = {}
 newdict[tripped_casename] = {}
-- 
1.7.7.5

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


Re: [libvirt] [PATCH] blockjob: add virsh blockjob --wait

2012-04-13 Thread Michal Privoznik
On 12.04.2012 21:59, Eric Blake wrote:
> I'm tired of shell-scripting to wait for completion of a block pull,
> when virsh can be taught to do the same.  I couldn't quite reuse
> vshWatchJob, as this is not a case of a long-running command where
> a second thread must be used to probe job status (at least, not unless
> I make virsh start doing blocking waits for an event to fire), but it
> served as inspiration for my simpler single-threaded loop.  There is
> up to a half-second delay between sending SIGINT and the job being
> aborted, but I didn't think it worth the complexity of a second thread
> and use of poll() just to minimize that delay.
> 
> * tools/virsh.c (cmdBlockPull): Add new options to wait for
> completion.
> (blockJobImpl): Add argument.
> (cmdBlockJob): Adjust caller.
> * tools/virsh.pod (blockjob): Document new mode.
> ---
>  tools/virsh.c   |  122 +-
>  tools/virsh.pod |   11 -
>  2 files changed, 119 insertions(+), 14 deletions(-)
> 
> diff --git a/tools/virsh.c b/tools/virsh.c
> index 8ef57e0..c54add9 100644
> --- a/tools/virsh.c
> +++ b/tools/virsh.c
> @@ -7274,11 +7274,11 @@ repoll:
>  if (pollfd.revents & POLLIN &&
>  saferead(pipe_fd, &retchar, sizeof(retchar)) > 0 &&
>  retchar == '0') {
> -if (verbose) {
> -/* print [100 %] */
> -print_job_progress(label, 0, 1);
> -}
> -break;
> +if (verbose) {
> +/* print [100 %] */
> +print_job_progress(label, 0, 1);
> +}
> +break;
>  }
>  goto cleanup;
>  }
> @@ -7295,8 +7295,9 @@ repoll:
>  }
> 
>  GETTIMEOFDAY(&curr);
> -if ( timeout && ((int)(curr.tv_sec - start.tv_sec)  * 1000 + \
> - (int)(curr.tv_usec - start.tv_usec) / 1000) > 
> timeout * 1000 ) {
> +if (timeout && (((int)(curr.tv_sec - start.tv_sec)  * 1000 +
> + (int)(curr.tv_usec - start.tv_usec) / 1000) >
> +timeout * 1000)) {
>  /* suspend the domain when migration timeouts. */
>  vshDebug(ctl, VSH_ERR_DEBUG, "%s timeout", label);
>  if (timeout_func)

These two chunks are rather cosmetic but I'm okay with having them in
this patch not a separate one.

> @@ -7519,7 +7520,8 @@ typedef enum {
> 
>  static int
>  blockJobImpl(vshControl *ctl, const vshCmd *cmd,
> -  virDomainBlockJobInfoPtr info, int mode)
> + virDomainBlockJobInfoPtr info, int mode,
> + virDomainPtr *pdom)
>  {
>  virDomainPtr dom = NULL;
>  const char *name, *path;
> @@ -7560,7 +7562,9 @@ blockJobImpl(vshControl *ctl, const vshCmd *cmd,
>  }
> 
>  cleanup:
> -if (dom)
> +if (pdom && ret == 0)
> +*pdom = dom;
> +else if (dom)
>  virDomainFree(dom);
>  return ret;
>  }
> @@ -7580,15 +7584,109 @@ static const vshCmdOptDef opts_block_pull[] = {
>  {"bandwidth", VSH_OT_DATA, VSH_OFLAG_NONE, N_("Bandwidth limit in 
> MB/s")},
>  {"base", VSH_OT_DATA, VSH_OFLAG_NONE,
>   N_("path of backing file in chain for a partial pull")},
> +{"wait", VSH_OT_BOOL, 0, N_("wait for job to finish")},
> +{"verbose", VSH_OT_BOOL, 0, N_("with --wait, display the progress")},
> +{"timeout", VSH_OT_INT, VSH_OFLAG_NONE,
> + N_("with --wait, abort if pull exceeds timeout (in seconds)")},
>  {NULL, 0, 0, NULL}
>  };
> 
>  static bool
>  cmdBlockPull(vshControl *ctl, const vshCmd *cmd)
>  {
> -if (blockJobImpl(ctl, cmd, NULL, VSH_CMD_BLOCK_JOB_PULL) != 0)
> +virDomainPtr dom = NULL;
> +bool ret = false;
> +bool blocking = vshCommandOptBool(cmd, "wait");
> +bool verbose = vshCommandOptBool(cmd, "verbose");
> +int timeout = 0;
> +struct sigaction sig_action;
> +struct sigaction old_sig_action;
> +sigset_t sigmask;
> +struct timeval start;
> +struct timeval curr;
> +const char *path = NULL;
> +bool quit = false;
> +
> +if (blocking) {
> +if (vshCommandOptInt(cmd, "timeout", &timeout) > 0) {
> +if (timeout < 1) {
> +vshError(ctl, "%s", _("migrate: Invalid timeout"));
> +return false;
> +}
> +
> +/* Ensure that we can multiply by 1000 without overflowing. */
> +if (timeout > INT_MAX / 1000) {
> +vshError(ctl, "%s", _("migrate: Timeout is too big"));
> +return false;
> +}
> +}
> +if (vshCommandOptString(cmd, "path", &path) < 0)
> +return false;
> +
> +sigemptyset(&sigmask);
> +sigaddset(&sigmask, SIGINT);
> +
> +intCaught = 0;
> +sig_action.sa_sigaction = vshCatchInt;
> +sigemptyset(&sig_action.sa_mask);
> +sigaction(SIGINT,