[libvirt] [PATCH 0/4] Make rewriting XML files more robust
by Jiri Denemark
Jiri Denemark (4):
Introduce virFileSync
Introduce virFileRewrite for safe file rewrite
Introduce virXMLSaveFile as a wrapper for virFileRewrite
Use virXMLSaveFile when writing XML config
src/conf/domain_conf.c | 32 +-------------------
src/conf/network_conf.c | 34 +--------------------
src/conf/nwfilter_conf.c | 68 ++----------------------------------------
src/conf/storage_conf.c | 37 ++---------------------
src/libvirt_private.syms | 3 ++
src/qemu/qemu_domain.c | 19 +-----------
src/util/util.c | 4 ++-
src/util/virfile.c | 72 ++++++++++++++++++++++++++++++++++++++++++++++
src/util/virfile.h | 8 +++++
src/util/xml.c | 36 +++++++++++++++++++++++
src/util/xml.h | 5 +++
11 files changed, 141 insertions(+), 177 deletions(-)
--
1.7.7
13 years, 1 month
[libvirt] [PATCH V3 0/4] Support for multiple IP addresses using lists
by Stefan Berger
This patch series builds on the previously posted patch series
https://www.redhat.com/archives/libvir-list/2011-October/msg00912.html
and introduces the capability to assign a list to a variable and
have multiple rules instantiated, one for each item in the list.
This means, that if for example a variable like IP has been assigned
a list of values
IP = [1.2.3.4, 5.6.7.8, 10.0.0.1]
it will instantiate 3 rules (on the ebtables/iptables level) for a single
XML filtering rule. This in turn allows us to build filters that can
evaluate multiple possible values per field, i.e., allow the filtering for
multiple IP addresses (per interface). It would then need David Steven's
patch for support of 'RETURN' (and 'CONTINUE') target(s).
v3:
- following Daniel Berrange's comment regarding how a list of items
should be represented in the XML
v2:
- reimplementation of iterator
- other nits
Regards,
Stefan
13 years, 1 month
Re: [libvirt] [libvirt PATCHv4 1/2] add DHCP snooping
by Stefan Berger
David Stevens/Beaverton/IBM wrote on 10/26/2011 06:51:26 PM:
> Stefan Berger <stefanb(a)linux.vnet.ibm.com> wrote on 10/26/2011 11:32:25
AM:
>
>
> > Also, in case learning is NULL, you may need to set it to 'any' (for
> > backwards-compatibility) to avoid a NULL pointer crash later on.
>
> I didn't try it with NULL -- if it is not set (ie, the variable is not
> present at all), it defaults to "any" already. If it's set to garbage,
That was not the behavior I had encountered. I forgot to put the
ip_learning into
the collection of variables and then learning ended up being NULL, which
then crashed it.
> I did have some issues with restarting libvirtd (primarily VM's exiting
when
> I restarted multiple times), but those were there before I applied any of
> these patches; no log messages when that happened.
By the way, also try the 'kill -SIGHUP `pidof libvirtd`' to have the
filters rebuilt.
It's similar to a restart of libvirtd.
Stefan
13 years, 1 month
[libvirt] [PATCH v3 00/13] Implement keepalive protocol for libvirt RPC
by Jiri Denemark
This patchset can also be found at
https://gitorious.org/~jirka/libvirt/jirka-staging/commits/keepalive
This allows us to detect broken connections between server and client without
waiting for TCP timeout and dead deamon/client. By default a connection is
considered broken after about 30 seconds of no messages received from remote
party. After that period, the connection is automatically closed.
The main reason for implementing this is that peer-to-peer migration can now be
canceled when a connection between source and target breaks. Although this will
really work only after qemu fixes migrate_cancel command so that it doesn't
block when outgoing TCP buffers are full.
Version 3 addresses comments from Daniel (more details can be found in each
patch) except for the default settings on server side. Daniel suggested
keepalive should be switched off by default, while I think it should be on if
possible, but that (and if on, with what interval and count) can be discussed
further since it has negligible impact on the patchset.
Jiri Denemark (13):
Define keepalive protocol
Implement common keepalive handling
Introduce virConnectSetKeepAlive
virsh: Always run event loop
Implement keepalive protocol in libvirt daemon
Add support for non-blocking calls in client RPC
Add support for async close of client RPC socket
Implement keepalive protocol in remote driver
Introduce virConnectIsAlive API
Implement virConnectIsAlive in all drivers
Add keepalive support into domain-events examples
qemu: Add support for keepalive messages during p2p migration
qemu: Cancel p2p migration when connection breaks
.gitignore | 1 +
daemon/libvirtd.aug | 5 +
daemon/libvirtd.c | 15 +
daemon/libvirtd.conf | 22 +
daemon/libvirtd.h | 1 +
daemon/remote.c | 48 +++-
examples/domain-events/events-c/event-test.c | 9 +-
examples/domain-events/events-python/event-test.py | 4 +-
include/libvirt/libvirt.h.in | 5 +
po/POTFILES.in | 1 +
src/Makefile.am | 15 +-
src/driver.h | 8 +
src/esx/esx_driver.c | 18 +
src/hyperv/hyperv_driver.c | 18 +
src/libvirt.c | 90 ++++
src/libvirt_internal.h | 10 +-
src/libvirt_private.syms | 2 +
src/libvirt_public.syms | 2 +
src/libxl/libxl_driver.c | 8 +
src/lxc/lxc_driver.c | 7 +
src/openvz/openvz_driver.c | 7 +
src/phyp/phyp_driver.c | 18 +
src/qemu/libvirtd_qemu.aug | 2 +
src/qemu/qemu.conf | 19 +
src/qemu/qemu_conf.c | 11 +
src/qemu/qemu_conf.h | 3 +
src/qemu/qemu_driver.c | 6 +
src/qemu/qemu_migration.c | 43 ++-
src/qemu/test_libvirtd_qemu.aug | 6 +
src/remote/remote_driver.c | 70 ++++
src/remote/remote_protocol.x | 2 +-
src/rpc/virkeepalive.c | 426 ++++++++++++++++++++
src/rpc/virkeepalive.h | 56 +++
src/rpc/virkeepaliveprotocol.x | 7 +
src/rpc/virnetclient.c | 316 +++++++++++++---
src/rpc/virnetclient.h | 6 +
src/rpc/virnetserver.c | 22 +
src/rpc/virnetserver.h | 5 +
src/rpc/virnetserverclient.c | 143 ++++++-
src/rpc/virnetserverclient.h | 7 +
src/test/test_driver.c | 6 +
src/uml/uml_driver.c | 7 +
src/util/event.c | 6 +-
src/vbox/vbox_tmpl.c | 6 +
src/vmware/vmware_driver.c | 7 +
src/xen/xen_driver.c | 8 +
src/xenapi/xenapi_driver.c | 12 +
tools/console.c | 17 +-
tools/virsh.c | 31 ++
49 files changed, 1477 insertions(+), 87 deletions(-)
create mode 100644 src/rpc/virkeepalive.c
create mode 100644 src/rpc/virkeepalive.h
create mode 100644 src/rpc/virkeepaliveprotocol.x
--
1.7.7
13 years, 1 month
[libvirt] custom network filter
by Shahar Havivi
Hi,
I am having a VDSM hook that use custom network filter:
<filter name='isolatedprivatevlan-vdsm' chain='root'>
<uuid>aca4bfab-432c-54ac-aa62-b76c328ebbf2</uuid>
<filterref filter='clean-traffic'/>
<rule action='drop' direction='out' priority='500'>
<mac match='no' dstmacaddr='$GATEWAY_MAC'/>
</rule>
</filter>
the filter file name is isolatedprivatevlan-vdsm.xml, and installed in:
/etc/libvirt/nwfilter/isolatedprivatevlan-vdsm.xml
when I try to use it in libvirt domain xml:
<interface>
...
<filterref filter="isolatedprivatevlan-rhevm">
<parameter name="GATEWAY_MAC" value="aa:aa:aa:aa:aa:aa"/>
</filterref>
</interface>
I am getting the following error:
Network filter not found: Could not find filter 'isolatedprivatevlan-rhevm'
The hook was running but not at my current version: libvirt-0.9.4-17.el6.x86_64
I try to install nwfilter-define via virsh and the list command,
nwfilter-list - I can see the custom filter but again the same error.
any ideas?
Thank you,
Shahar Havivi.
13 years, 1 month
[libvirt] changes to domain XML for SCSI support
by Paolo Bonzini
Hi all,
let's kick off the discussion on what changes are needed in domain XML
for more complete SCSI support.
There are three relevant topics:
1) providing channel/target/lun addresses for SCSI disks;
2) supporting LUN passthrough;
3) supporting SCSI host passthrough.
A fourth topic is supporting NPIV. It is a special case of SCSI host
passthrough, and it is important that any extension to the domain XML
can cover it.
Enhanced addressing for SCSI devices
====================================
This is the simplest part. The proposal is to add a new address type
<address type='scsi' host='...'
bus='...' target='...' lun='...'/>
where host selects the qdev parent device, while channel/target/lun are
passed as qdev properties (the QEMU names are respectively channel,
scsi-id, lun).
Libvirt should check for QEMU 1.0 and, for older versions, only allow
channel=lun=0 and 0<=target<=7.
LUN passthrough
===============
A SCSI block device from the host can be attached to a domain in two
ways: as an emulated LUN with SCSI commands implemented within QEMU, or
by passing SCSI commands down to the block device. The former is
handled by the existing <disk type='disk'> and <disk type='cdrom'> XML
syntax. The latter is not yet supported.
On the QEMU side, LUN passthrough is implemented by one of the
scsi-generic and scsi-block devices. Scsi-generic requires a /dev/sg
device name, and can be applied to any device. scsi-block is only
available in QEMU 1.0 or newer, requires a block device, can be applied
only to block devices (sd/sr) and has better performance. The choice
between one and the other should be as transparent as possible.
Currently, using a block device as the backend for a virtio disk
implements a kind of LUN passthrough, since the guest can execute
There are two possible choices here:
1) add a new <hostdev> tag.
<hostdev mode='subsystem' type='scsi'>
<source>
<address type='scsi' host='...' bus='...' target='...' lun='...'/>
</source>
<address type='scsi' host='...' bus='...' target='...' lun='...'/>
</hostdev>
Advantages:
- allows using the same XML for all SCSI devices (i.e. scsi-generic vs.
scsi-block is an internal detail of libvirt);
Disadvantages:
- does not make it clear which device is being passed through;
- completely different from the syntax that virtio is using for the same
purpose; perhaps virtio could be covered by
<hostdev mode='subsystem' type='scsi'>
<source>
<address type='scsi' host='...' bus='...' target='...' lun='...'/>
</source>
<target dev='vda' bus='virtio'/>
<address type='pci' host='...' bus='...' target='...' lun='...'/>
</hostdev>
- <address> specifies the address to a <capability type='scsi'> device,
but the device to be passed to scsi-block is its block_sdXX_* child
(aside: it would be nice if the /dev/sgNN name was placed somewhere in
the nodedev XML for <capability type='scsi'> devices);
- emulated and passthrough LUNs have a completely different XML;
- host numbers are not stable when hotplugging.
2) add a new <drive device='lun'> attribute.
<drive type='block' device='lun'>
<driver name='qemu' type='raw'/>
<source dev='/dev/sda'/>
<target dev='sda' bus='scsi'>
<address type='scsi' host='...' bus='...' target='...' lun='...'/>
</drive>
Advantages:
- allows using the same syntax for virtio and SCSI. virtio could be
changed to accept device='lun' too.
- the passed-through device is immediately visible
- a stable addressing is available via /dev/disk/by-id and /dev/disk/by-path
- can easily switch a disk between emulated and passthrough modes;
Disadvantages:
- does not extend to scsi-generic and to host passthrough;
3) something between (1) and (2). If I understand correctly
http://www.redhat.com/archives/libvir-list/2008-July/msg00429.html this
would use <hostdev mode='capability'>. More on this below.
SCSI target/host passthrough: rethinking <hostdev mode='capability'>
====================================================================
SCSI target/host passthrough passes the entire set of LUNs attached to a
SCSI target or host. On the QEMU side, this is done manually by adding
a scsi_block or scsi_generic device for each LUN.
This can be realized using something like:
<hostdev mode='subsystem' type='scsi_host'>
<source>
<address type='scsi' host='...'/>
</source>
<address type='scsi' host='...'/>
</hostdev>
<hostdev mode='subsystem' type='scsi_target'>
<source>
<address type='scsi' host='...' bus='...' target='...'/>
</source>
<address type='scsi' host='...' bus='...' target='...'/>
</hostdev>
However, as for LUN passthrough, the main problem is that Linux host
indices are not stable. Thus, in this case using <hostdev
mode='capability'> seems like the only reasonable possibility.
That said, <hostdev mode='capability'> has never been documented and
never even implemented. For this reason, I'm proposing to redo its
functionality in a different way. The two examples given in
http://www.redhat.com/archives/libvir-list/2008-July/msg00429.html were
the following:
> A network card by name (ie for OpenVZ)
>
> <hostdev mode='capability'>
> <source name='eth0'/>
> </hostdev>
>
> A SCSI device by name (eg, SCSI PV passthrough), also specifying
> the target adress
>
> <hostdev mode='capability' type='scsi'>
> <source name='sg3'/>
> <target address='0:0:0:0'/>
> </hostdev>
In my proposal:
1) the "mode" attribute is dropped (more precisely, only "subsystem" is
allowed and never printed; everything else is rejected);
2) the "type" attribute can in principle get any value that is valid for
a nodedev capability---more or less: for example the usb type maps to
the usb_device capability; :(
3) the "source" element can get a name "attribute" pointing to a nodedev
name, and a "rel" attribute that is "child" or "parent". "child"
instructs libvirt to search for a device possessing the given
capability, and that is a child of the named device; "parent" instructs
libvirt to pick the parent of the indicated device. When the "name"
attribute is included, the element must be empty.
Given this, here is how the two examples above would look like:
A network card for OpenVZ:
- by name (has adding aliases for nodedevs ever been considered, such as
simply "eth0" in this case?):
<hostdev type='net'>
<source name='net_eth0_00_22_68_0b_dc_ac'/>
</hostdev>
- by position:
<hostdev type='net'>
<source rel='child' name='pci_0000_00_19_0'/>
</hostdev>
A SCSI device:
- by name:
<hostdev type='scsi'>
<source name='scsi_0_0_0_0'/>
<address type='scsi' host='...' bus='...' target='...' lun='...'/>
</hostdev>
- by position (aliases also would allow to specify /dev/sda easily):
<hostdev type='scsi'>
<source rel='parent' name='block_sda_ST9160411AS_5TG11QWL'/>
<address type='scsi' host='...' bus='...' target='...' lun='...'/>
</hostdev>
A SCSI host:
- by name:
<hostdev type='scsi_host'>
<source name='scsi_host0'/>
<address type='scsi' host='...'/>
</hostdev>
- by position:
<hostdev type='scsi_host'>
<source rel='child' name='pci_0000_00_1f_2'/>
<address type='scsi' host='...'/>
</hostdev>
NPIV support: generalizing hostdev source addresses
===================================================
In NPIV, a virtual HBA is created using "virsh nodedev-create" and
passed to the guest. Such virtual adapter does have a stable address,
namely its WWN. As such, it can be addressed simply by generalizing the
kind of source address that can be passed to <hostdev type='scsi_host'/>:
<hostdev type='scsi_host'>
<source>
<address type='wwn' wwpn='...' wwnn='...'/>
</source>
</hostdev>
(Note that this doesn't use <source name='...'/> and, as such, it does
not rely on the ideas above).
Ideas and opinions are welcome!
Paolo
13 years, 1 month
[libvirt] [PATCH] lxc: remove dummy function
by ajia@redhat.com
From: Alex Jia <ajia(a)redhat.com>
Cppcheck detected a syntaxError on lxcDomainInterfaceStats, my initial patch
added a '{' to reserve 'else' branch to avoid a syntax error, in fact, don't
need the dummy function in 'else' branch.
* src/lxc/lxc_driver.c: remove dummy function entirely.
Signed-off-by: Alex Jia <ajia(a)redhat.com>
---
src/lxc/lxc_driver.c | 9 ---------
1 files changed, 0 insertions(+), 9 deletions(-)
diff --git a/src/lxc/lxc_driver.c b/src/lxc/lxc_driver.c
index 06bfa85..251fa92 100644
--- a/src/lxc/lxc_driver.c
+++ b/src/lxc/lxc_driver.c
@@ -2666,15 +2666,6 @@ cleanup:
virDomainObjUnlock(vm);
return ret;
}
-#else
-static int
-lxcDomainInterfaceStats(virDomainPtr dom,
- const char *path ATTRIBUTE_UNUSED,
- struct _virDomainInterfaceStats *stats ATTRIBUTE_UNUSED)
-{
- lxcError(VIR_ERR_NO_SUPPORT, "%s", __FUNCTION__);
- return -1;
-}
#endif
static int lxcDomainGetAutostart(virDomainPtr dom,
--
1.7.1
13 years, 1 month
[libvirt] [PATCH] Add documentation about migration.
by Daniel P. Berrange
From: "Daniel P. Berrange" <berrange(a)redhat.com>
This adds a page documenting many aspects of migration:
- The types of migration (managed direct, p2p, unmanaged direct)
- Data transports (native, tunnelled)
- Migration URIs
- Config file handling
- Example scenarios
* libvirt.css: Rules for data tables and diagrams
* Makefile.am: Include extra png/fig files
* migration-managed-direct.fig, migration-managed-direct.png,
migration-managed-direct.png, migration-managed-p2p.png,
migration-native.fig, migration-native.png,
migration-tunnel.fig, migration-tunnel.png,
migration-unmanaged-direct.fig, migration-unmanaged-direct.png:
Diagrams of migration
* migration.html.in, sitemap.html.in: New migration doc
---
docs/Makefile.am | 14 +-
docs/libvirt.css | 48 ++++
docs/migration-managed-direct.fig | 58 +++++
docs/migration-managed-direct.png | Bin 0 -> 3901 bytes
docs/migration-managed-p2p.fig | 58 +++++
docs/migration-managed-p2p.png | Bin 0 -> 3901 bytes
docs/migration-native.fig | 43 ++++
docs/migration-native.png | Bin 0 -> 2173 bytes
docs/migration-tunnel.fig | 49 ++++
docs/migration-tunnel.png | Bin 0 -> 2237 bytes
docs/migration-unmanaged-direct.fig | 58 +++++
docs/migration-unmanaged-direct.png | Bin 0 -> 3951 bytes
docs/migration.html.in | 419 +++++++++++++++++++++++++++++++++--
docs/sitemap.html.in | 2 +-
14 files changed, 730 insertions(+), 19 deletions(-)
create mode 100644 docs/migration-managed-direct.fig
create mode 100644 docs/migration-managed-direct.png
create mode 100644 docs/migration-managed-p2p.fig
create mode 100644 docs/migration-managed-p2p.png
create mode 100644 docs/migration-native.fig
create mode 100644 docs/migration-native.png
create mode 100644 docs/migration-tunnel.fig
create mode 100644 docs/migration-tunnel.png
create mode 100644 docs/migration-unmanaged-direct.fig
create mode 100644 docs/migration-unmanaged-direct.png
diff --git a/docs/Makefile.am b/docs/Makefile.am
index 0b8f226..5644fe2 100644
--- a/docs/Makefile.am
+++ b/docs/Makefile.am
@@ -60,7 +60,12 @@ png = \
libvirt-driver-arch.png \
libvirt-object-model.png \
madeWith.png \
- et.png
+ et.png \
+ migration-managed-direct.png \
+ migration-managed-p2p.png \
+ migration-native.png \
+ migration-tunnel.png \
+ migration-unmanaged-direct.png
gif = \
architecture.gif \
@@ -85,7 +90,12 @@ fig = \
libvirt-net-physical.fig \
libvirt-daemon-arch.fig \
libvirt-driver-arch.fig \
- libvirt-object-model.fig
+ libvirt-object-model.fig \
+ migration-managed-direct.fig \
+ migration-managed-p2p.fig \
+ migration-native.fig \
+ migration-tunnel.fig \
+ migration-unmanaged-direct.fig
EXTRA_DIST= \
apibuild.py \
diff --git a/docs/libvirt.css b/docs/libvirt.css
index 6e54b73..5123ed6 100644
--- a/docs/libvirt.css
+++ b/docs/libvirt.css
@@ -364,3 +364,51 @@ span.since {
font-style: italic;
font-weight: bold;
}
+
+img.diagram {
+ background: rgb(230,230,230);
+ border: 2px dotted rgb(178,178,178);
+ padding: 1em;
+ display: block;
+ margin-left: auto;
+ margin-right: auto;
+}
+
+table.data th, table.data td {
+ padding: 0.3em;
+}
+
+table.data {
+ border-spacing: 0px;
+}
+
+table.data thead th {
+ background: rgb(178,178,178);
+ text-align: center;
+}
+
+table.data {
+ border: 1px solid black;
+ border-collapse: collapse;
+}
+
+table.data thead tr th {
+ border: 1px solid black;
+}
+
+table.data tr.head th {
+ border-left: 1px solid black;
+ border-right: 1px solid black;
+}
+
+table.data tbody td {
+ background: rgb(240,240,240);
+}
+table.data tbody td.y {
+ background: rgb(220,255,220);
+ text-align: center;
+}
+table.data tbody td.n {
+ background: rgb(255,220,220);
+ text-align: center;
+}
diff --git a/docs/migration-managed-direct.fig b/docs/migration-managed-direct.fig
new file mode 100644
index 0000000..59ae996
--- /dev/null
+++ b/docs/migration-managed-direct.fig
@@ -0,0 +1,58 @@
+#FIG 3.2 Produced by xfig version 3.2.5b
+Landscape
+Center
+Inches
+Letter
+100.00
+Single
+-2
+1200 2
+6 2775 2400 3675 2850
+2 2 0 1 0 7 50 -1 -1 0.000 0 0 7 0 0 5
+ 2775 2400 3675 2400 3675 2850 2775 2850 2775 2400
+4 0 0 50 -1 16 12 0.0000 4 150 570 2925 2700 libvirtd\001
+-6
+6 5400 2400 6300 2850
+2 2 0 1 0 7 50 -1 -1 0.000 0 0 7 0 0 5
+ 5400 2400 6300 2400 6300 2850 5400 2850 5400 2400
+4 0 0 50 -1 16 12 0.0000 4 150 570 5550 2700 libvirtd\001
+-6
+2 2 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 5
+ 1200 1200 3825 1200 3825 3000 1200 3000 1200 1200
+2 2 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 5
+ 5250 1200 7875 1200 7875 3000 5250 3000 5250 1200
+2 2 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 5
+ 5400 1350 6075 1350 6075 1950 5400 1950 5400 1350
+2 2 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 5
+ 6225 1350 6900 1350 6900 1950 6225 1950 6225 1350
+2 2 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 5
+ 3000 1350 3675 1350 3675 1950 3000 1950 3000 1350
+2 2 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 5
+ 2175 1350 2850 1350 2850 1950 2175 1950 2175 1350
+2 2 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 5
+ 1350 1350 2025 1350 2025 1950 1350 1950 1350 1350
+2 1 0 3 0 7 50 -1 -1 0.000 0 0 -1 1 0 4
+ 1 1 1.00 135.00 180.00
+ 4350 4275 4350 3600 3300 3600 3300 2850
+2 1 0 3 0 7 50 -1 -1 0.000 0 0 -1 1 0 4
+ 1 1 1.00 135.00 180.00
+ 4800 4275 4800 3600 5775 3600 5775 2850
+2 2 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 5
+ 3225 4125 5850 4125 5850 6000 3225 6000 3225 4125
+2 2 0 1 0 7 50 -1 -1 0.000 0 0 7 0 0 5
+ 3375 5100 5700 5100 5700 5550 3375 5550 3375 5100
+2 1 0 3 0 7 50 -1 -1 0.000 0 0 -1 1 0 3
+ 1 1 1.00 135.00 180.00
+ 3750 5100 3750 4500 4050 4500
+2 2 0 1 0 7 50 -1 -1 0.000 0 0 7 0 0 5
+ 4050 4275 5100 4275 5100 4725 4050 4725 4050 4275
+4 0 0 50 -1 16 12 0.0000 4 150 870 6825 2850 Dest Host\001
+4 0 0 50 -1 16 12 0.0000 4 150 1080 1350 2850 Source Host\001
+4 0 0 50 -1 16 12 0.0000 4 150 495 1425 1725 VM-A\001
+4 0 0 50 -1 16 12 0.0000 4 150 495 2250 1725 VM-B\001
+4 0 0 50 -1 16 12 0.0000 4 150 495 3075 1725 VM-C\001
+4 0 0 50 -1 16 12 0.0000 4 150 495 5475 1725 VM-C\001
+4 0 0 50 -1 16 12 0.0000 4 150 495 6300 1725 VM-D\001
+4 0 0 50 -1 16 12 0.0000 4 150 960 4725 5850 Client Host\001
+4 0 0 50 -1 16 12 0.0000 4 180 1500 3525 5400 management app\001
+4 0 0 50 -1 16 12 0.0000 4 150 735 4200 4575 libvirt.so\001
diff --git a/docs/migration-managed-direct.png b/docs/migration-managed-direct.png
new file mode 100644
index 0000000000000000000000000000000000000000..f8fbb3aabfb710a343c49cce55316e0ad57834be
GIT binary patch
literal 3901
zcmcIn4K&kj|DWoSN?v-=+##j@y+}y%cB7Vv40#RB%*sOC8Y{D*5cS-<?as^OJ-1BA
zD2!oSD9UJsnYW?4OfxoZ&n#y1taG08KlgL)=Q;o9{LgvL`CXsuT-UkYf8X!t^Zh>X
z@^IO{^@pth0ARc81t)I+K&3)iPN=CWdyLwXM9NAf&f5h9AidM$DH~g2F9gN`0NWmX
zFDh1V8Fk9e&GD|_^P4BO0@ZB}deuG81^_geu1;rt6UG-gQQ0+Z8&tiJH7*}Jvd?yP
zJW`eRQocSJx^u+vev}_-k#j6G;j_{H_vJ#FDj;iDAyN04>boaGS*Xdv+^u#St_{b0
zedrX}LVX$RfxNZr^LsmMuFZt`I^Iv^<%e`_K$jZekC;qIUdj=yC&X*M&g(<I7R730
zp?lvP?f&B9KR8$-aJxncLwlLqa_K+E*nXd=X7qocgB{M>4eS=NEYa%vj37>7n)>Za
zZ?r!-9-MbLeQ9oPOcG0u&Z#=e7($g8ErgMppj7dr6!y*aX4o)!@i%?=yoGsBRsI+X
zvJ*auH9BF!@SoMq_^8Oqr(T<tzl+XkIUh)*pv9E$Gi8sMWu|!9i{j}MYwdOUa+Q|n
z%-P)q0XO7hT3tzLtTJ6p(%W}|0{4sbIh|``H9x``%ps<U?Ab(k%nFlmIQ{+Kl7yQ3
z7QftT-#*<6)kpVx>VJZ;Ess`0`GN^WYls8aiW2TyYWXBrQEW0y$0u<MEPl2R+HsNb
z0)_75<!6Wr$ODss9D~`9dddUo-|VmF>9^IeV7a$(l+gR;3iSHeFTZvl_Ov?9yq$Zk
zR+KC6!JrV-sEH-WKdx?xr4#QBKU*Ny7PY~_lQ5vOqYv#gdoW_+Ry-U9u^Q({B6H-I
z0tp1fi6d3q_9yK#xQXycyIcf*<uMC<TO+ES=YXQyiXJh=x_p)Dc5Bp7-Hk{tjal7z
zZ*8@9V4`|E6;&JN8c06EY+s;8bKBh2Lt9D4ivcbM;;e`3Yd4zB^RYySit6dILeHsC
ziAG^2I!0IZ;+$nbDdmOUrHBPebRUng=u>Kr958F^OGXWwL!pUU&U?!s{g&opL@5<u
z)6%(Y-FVrXU^)91Jd_xMfh<kOO?=Kt$1=~4L12LH+f7-d1}OE@Bc{X;y&yzSrWArn
zx+OJdjAeMoy5k6A=H!F4DCfC`*OnEYll7$de(14uMN0oRBUpS}v=J`-AzUHrdeg`Q
zSQndZI0IC<^Y3vc)>FRa!79_B_(OK4x<>bs_BF~lxicAcl{y2YTmV8AU0(zoW474O
z?vdq*uHgSe)BaD)UpZ#&@?Yk(L9JNbOjtwtB7WH={bAa<*$nvyMS?>c51{1?FvR^C
z9eimp)Ab_nNN+b&CZfM$g%Y79GwQlej2M~T?`W08M){j5m(s?w5I;lMavNjtQMt{p
zVi~;5xXN_eblS%}G{p&MjwWALgxm_wt!HnJUs<Q5B}UpdIKJ@z)^cs(ZFAKqaQ|@u
z_f6TrI=8VKxr%M*0T$&B%Bi{DJK;CNaCAbTDSgeJSsOi(PZJI@Gqnn7LX<+NbPp3-
z?jpXUc8V`^NQji)dj&iU#hXtt4cbXElvbMjVa1jT(*;mL&B2$7`(|M|Y3=+rStq3Q
zCOH}-Y@Gfr3bfCD*@b)+(0%VS?VEBtQ0wi?T%jXICrCPwsf7#aQoMN%8&*0!=$j;N
zq$G4+wYAx*hl(_sHV}<nRkTD;5Thr;ff@hPGpgRbRJG3`CH#g19Pv~loLv*IcPd(G
zq?#0R4T8vR43M`Hv#^n;AZq0i6UzaOc9nnQH(Nx{JV(~)pKY8|E3U;0%nJp2%RumL
zmi#MZ+GukmDM0M17{9B}97zj)mJ{G?Njp_YiV0^M*SfzJQT2l0^ttj9$<sm#`WGtg
z^lJt>&(2BUapb2Ci`C7e=SXnAPLBo3Z)L?&!m`U>VKy39(~8>G4xo1aBp^1qShau$
zqGC2uvuEJqJ`<V<l{EOWePcvTDaHjN5v+dY6@@TNeaTq{ob=PTHwMc??CX)f9-PFQ
zc8x0kt4F7Ett3gkgfd1=QOvZ6N1P~&X^YFN7Z7WqWwp|IK}TZi+Lhar29i(4e9L`e
zPdu^K)P3Zr4ZA-$j__*$*8YCjGnOA|copF~n)S=@P18+FG5C3^C5kmR-}@SNYWc#q
zLmT&yNw36jibV(p-)coRQW5v=<X<&fX{(zsq$vyn(u|O|TI2fCOINccsK?c2iNkd3
z5onMG^78m3wh31)3|6hbyY*#z+S41+{VWWI<>xYt_e2fNMxCRe2>};k_RmHgTVW8O
zO~+pin$;BDm7GM<d9}uvc^QF&hYxtw9Sr3IYJ}#;_!ZTO!b=cIWKuIR8H*|~b!^6v
z%3|lK0joMy#4%)oWKvoZS-tonY&C=K8v*G4TB`eUX;JoR%$;Q)XMZV*UyI=PBJvCH
z=oC<@V;=LNEX~Z;6Szn%VcF&Ob|8jSGE3La3?+CSGfdZVE`FZs6{u9j_ii9yImpY^
z5Ub^U=MD&{qNYE!*z1wn*G-lrS!4Hokxd1C3u~E(UVeAZ>TwwKlYYE%q0QQAM!VD9
zHdz<P*eW*R1v?g^uIs8O{aZ;;|0SH^BtP2_sXR!7P9agL`$=g8Z9tIo^)1(RgVrBk
z+oa@00PMelFZ0!srh~UZ=ap(XvH>wDO={4g4dMNkI2mUR<TmHFeXQeiISe~l;+!3i
zxbe>%JrgUi_<hH6tII4$O1;tiqcm$jZsyD}m{pdDqI}JN^I$jK_NU9324d2B*>`rV
z<@#Z+B^%;qK6f@{HhV@tDx&di_iCnV2VKOo>hei^MN_u7TT1F7y5lkhxmrDPX@&9}
zO&|B(2-~y|=#J9LrRR%JKuyp6hNbe`&exUeIl*B8`7VZEEqmjqr6XPWZJe0yhnjmh
zZT#qnK#-c0$z7j2b7byenqklAlU#wYGPe*2-wD?%VUHqvHYj-sdY7<1P|qBIyN)@0
z-BcmOcqXz=rZSuSX7|F2vGzR)Kdr<=tX9SjAxG1-1pBS69P5l|cOCb49_{{osg`%Y
zaeWdQxYG$`Xx~O|Vu{W$)J|)VsHsnBTp#k~aWa(-y;Wi27qaKr=EJ$-zPft*F3l!f
zXeMFEK-65Wx0Qm40dG508L#=`M|?-I-UXYPKEBtAUB?dW(gXF-Z(#`CmkqCPkBYkF
z<53_u>{N4c^{*I-9q{EHGY}AR5a+OZN5>g^g#9m6Nh!96&0=*iautU&z|I3P3HO-9
zA`PW|eUBsm-{|PC5(iStzpUE(Lq@0D8DRN=kK>0=VI4T}-{VWAK>i6E8gsMrlzV2e
zP$hW)%>+HIA~GNhC+$-T1GFxc94*X?3p_i=?&WHK7c$K%<7vhaTMT*8Q7v3sz>1{r
z$~=$C3)sHsK6al_^2PrB$<*JF10Nrjxe|<dFTzS|X87n_;Q-j`H2%<#iTqs@O?o8(
zFE5?5^v|G3XL9b*gmw2!QSF=z7tOQV_a9I8id-4Ha+ce;ERwe6d3gkw)|bwW#!Frx
z@2hvm*0=I`<K*Zt+|P8eg&6HiJn2O28$xmFBj#uJVua63o>a=b)XI6XDIdRP+>AX^
z>gUF*K5T1Ra-zkfkKm-HjCY|am8_Oq4i_0d1Q-b$yPKr@)t|!34&JqbOQ`1|XQ}6F
zVYMsIOf;|ScB<yZ+8==}#-lElC)bDc80RVc#er=G^L)^(<S9j}{B=9?5(TAwdGi%s
zg+-(rfw{t2p2)IfQh(WvAHIm4KdXu#Imfvdpvs=aELDFunqbY)1ZVVD+Os>*0upJa
zS9RC$P>h7b_OS3TMZUSknXlgLhXtwWDvjv(CRkJD>MCQ*CEq0aJop~FDh~{Np01*f
z?f9|baR)*4)++S}*Gz(Tkn_ILlOV=@CIYbWpAwNwi>9K$ZnK2&9}IEUE`}-#u2%a0
zG~f?ei{8P?VWk&2Dr58%H!4>2TF0~VP0AtiX-lDf{+2E^j~z~6v2e&l<T-ST-u1NU
zwT~H*ORX{@JTTi(`t%9k@fQba)gWKT*^Q_0p--VWa;l!{N?cUXF&~Cr@RUEp38-S%
z^4A{szYJbJ<hYDsqrl1!cXP<_Y5Rf*8>hvBsd)<F|I361sfq4D6hzv<H%X6OcUPon
z6rF4WsevcRVBA;sDIamdu2YpTpaAA$8n-~zbFxvdBG~v%(S-H~LKte+7rnr5VZIvJ
zr@<ceN9rMY>;{7*wjO8}fYWnQlH4mUX}igmJm9CYnMXx)A;>RH(K6$XD@Gt-XXbr#
zj}TcwRNyP%`lgYol(mMC@Uh(i8rQ84XlXmYRIRI+r0xa*^<h>z>MP@3rGf&jgi4mT
zY2!jE<E&p6v9{ay;uhGZ!<tWEz+_Z=-fr}m#7{wA&?zbkk1_BmD@dd&Na%uDp#&2r
z&M5p45ADBh>*1%X3$D8Mul(O-_4!uX#1uYT<?`<-=VJA*?lltbQD(aU*Yh4uBv5GT
F-vK=cL}vg1
literal 0
HcmV?d00001
diff --git a/docs/migration-managed-p2p.fig b/docs/migration-managed-p2p.fig
new file mode 100644
index 0000000..59ae996
--- /dev/null
+++ b/docs/migration-managed-p2p.fig
@@ -0,0 +1,58 @@
+#FIG 3.2 Produced by xfig version 3.2.5b
+Landscape
+Center
+Inches
+Letter
+100.00
+Single
+-2
+1200 2
+6 2775 2400 3675 2850
+2 2 0 1 0 7 50 -1 -1 0.000 0 0 7 0 0 5
+ 2775 2400 3675 2400 3675 2850 2775 2850 2775 2400
+4 0 0 50 -1 16 12 0.0000 4 150 570 2925 2700 libvirtd\001
+-6
+6 5400 2400 6300 2850
+2 2 0 1 0 7 50 -1 -1 0.000 0 0 7 0 0 5
+ 5400 2400 6300 2400 6300 2850 5400 2850 5400 2400
+4 0 0 50 -1 16 12 0.0000 4 150 570 5550 2700 libvirtd\001
+-6
+2 2 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 5
+ 1200 1200 3825 1200 3825 3000 1200 3000 1200 1200
+2 2 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 5
+ 5250 1200 7875 1200 7875 3000 5250 3000 5250 1200
+2 2 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 5
+ 5400 1350 6075 1350 6075 1950 5400 1950 5400 1350
+2 2 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 5
+ 6225 1350 6900 1350 6900 1950 6225 1950 6225 1350
+2 2 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 5
+ 3000 1350 3675 1350 3675 1950 3000 1950 3000 1350
+2 2 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 5
+ 2175 1350 2850 1350 2850 1950 2175 1950 2175 1350
+2 2 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 5
+ 1350 1350 2025 1350 2025 1950 1350 1950 1350 1350
+2 1 0 3 0 7 50 -1 -1 0.000 0 0 -1 1 0 4
+ 1 1 1.00 135.00 180.00
+ 4350 4275 4350 3600 3300 3600 3300 2850
+2 1 0 3 0 7 50 -1 -1 0.000 0 0 -1 1 0 4
+ 1 1 1.00 135.00 180.00
+ 4800 4275 4800 3600 5775 3600 5775 2850
+2 2 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 5
+ 3225 4125 5850 4125 5850 6000 3225 6000 3225 4125
+2 2 0 1 0 7 50 -1 -1 0.000 0 0 7 0 0 5
+ 3375 5100 5700 5100 5700 5550 3375 5550 3375 5100
+2 1 0 3 0 7 50 -1 -1 0.000 0 0 -1 1 0 3
+ 1 1 1.00 135.00 180.00
+ 3750 5100 3750 4500 4050 4500
+2 2 0 1 0 7 50 -1 -1 0.000 0 0 7 0 0 5
+ 4050 4275 5100 4275 5100 4725 4050 4725 4050 4275
+4 0 0 50 -1 16 12 0.0000 4 150 870 6825 2850 Dest Host\001
+4 0 0 50 -1 16 12 0.0000 4 150 1080 1350 2850 Source Host\001
+4 0 0 50 -1 16 12 0.0000 4 150 495 1425 1725 VM-A\001
+4 0 0 50 -1 16 12 0.0000 4 150 495 2250 1725 VM-B\001
+4 0 0 50 -1 16 12 0.0000 4 150 495 3075 1725 VM-C\001
+4 0 0 50 -1 16 12 0.0000 4 150 495 5475 1725 VM-C\001
+4 0 0 50 -1 16 12 0.0000 4 150 495 6300 1725 VM-D\001
+4 0 0 50 -1 16 12 0.0000 4 150 960 4725 5850 Client Host\001
+4 0 0 50 -1 16 12 0.0000 4 180 1500 3525 5400 management app\001
+4 0 0 50 -1 16 12 0.0000 4 150 735 4200 4575 libvirt.so\001
diff --git a/docs/migration-managed-p2p.png b/docs/migration-managed-p2p.png
new file mode 100644
index 0000000000000000000000000000000000000000..0532143fe78d9e9bb5b9e96fccf0325d4e554c54
GIT binary patch
literal 3901
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
F{|0-BM8N<6
literal 0
HcmV?d00001
diff --git a/docs/migration-native.fig b/docs/migration-native.fig
new file mode 100644
index 0000000..0b4ac68
--- /dev/null
+++ b/docs/migration-native.fig
@@ -0,0 +1,43 @@
+#FIG 3.2 Produced by xfig version 3.2.5b
+Landscape
+Center
+Inches
+Letter
+100.00
+Single
+-2
+1200 2
+6 2775 2400 3675 2850
+2 2 0 1 0 7 50 -1 -1 0.000 0 0 7 0 0 5
+ 2775 2400 3675 2400 3675 2850 2775 2850 2775 2400
+4 0 0 50 -1 16 12 0.0000 4 150 570 2925 2700 libvirtd\001
+-6
+6 5400 2400 6300 2850
+2 2 0 1 0 7 50 -1 -1 0.000 0 0 7 0 0 5
+ 5400 2400 6300 2400 6300 2850 5400 2850 5400 2400
+4 0 0 50 -1 16 12 0.0000 4 150 570 5550 2700 libvirtd\001
+-6
+2 1 0 3 0 7 50 -1 -1 0.000 0 0 7 1 0 4
+ 1 1 1.00 135.00 180.00
+ 3375 1350 3375 825 5700 825 5700 1350
+2 2 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 5
+ 1200 1200 3825 1200 3825 3000 1200 3000 1200 1200
+2 2 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 5
+ 5250 1200 7875 1200 7875 3000 5250 3000 5250 1200
+2 2 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 5
+ 6225 1350 6900 1350 6900 1950 6225 1950 6225 1350
+2 2 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 5
+ 5400 1350 6075 1350 6075 1950 5400 1950 5400 1350
+2 2 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 5
+ 3000 1350 3675 1350 3675 1950 3000 1950 3000 1350
+2 2 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 5
+ 2175 1350 2850 1350 2850 1950 2175 1950 2175 1350
+2 2 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 5
+ 1350 1350 2025 1350 2025 1950 1350 1950 1350 1350
+4 0 0 50 -1 16 12 0.0000 4 150 495 1425 1725 VM-A\001
+4 0 0 50 -1 16 12 0.0000 4 150 495 2250 1725 VM-B\001
+4 0 0 50 -1 16 12 0.0000 4 150 495 3075 1725 VM-C\001
+4 0 0 50 -1 16 12 0.0000 4 150 495 5475 1725 VM-C\001
+4 0 0 50 -1 16 12 0.0000 4 150 495 6300 1725 VM-D\001
+4 0 0 50 -1 16 12 0.0000 4 150 1080 1350 2850 Source Host\001
+4 0 0 50 -1 16 12 0.0000 4 150 870 6825 2850 Dest Host\001
diff --git a/docs/migration-native.png b/docs/migration-native.png
new file mode 100644
index 0000000000000000000000000000000000000000..bf35cf185b289d6c66c6797ffb0a41410d7c81b6
GIT binary patch
literal 2173
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
E1G_vhcmMzZ
literal 0
HcmV?d00001
diff --git a/docs/migration-tunnel.fig b/docs/migration-tunnel.fig
new file mode 100644
index 0000000..00f1f58
--- /dev/null
+++ b/docs/migration-tunnel.fig
@@ -0,0 +1,49 @@
+#FIG 3.2 Produced by xfig version 3.2.5b
+Landscape
+Center
+Inches
+Letter
+100.00
+Single
+-2
+1200 2
+6 2775 2400 3675 2850
+2 2 0 1 0 7 50 -1 -1 0.000 0 0 7 0 0 5
+ 2775 2400 3675 2400 3675 2850 2775 2850 2775 2400
+4 0 0 50 -1 16 12 0.0000 4 150 570 2925 2700 libvirtd\001
+-6
+6 5400 2400 6300 2850
+2 2 0 1 0 7 50 -1 -1 0.000 0 0 7 0 0 5
+ 5400 2400 6300 2400 6300 2850 5400 2850 5400 2400
+4 0 0 50 -1 16 12 0.0000 4 150 570 5550 2700 libvirtd\001
+-6
+2 1 0 3 0 7 50 -1 -1 0.000 0 0 -1 1 0 2
+ 1 1 1.00 135.00 180.00
+ 3375 1950 3375 2400
+2 1 0 3 0 7 50 -1 -1 0.000 0 0 7 1 0 4
+ 1 1 1.00 135.00 180.00
+ 3375 2850 3375 3375 5700 3375 5700 2850
+2 1 0 3 0 7 50 -1 -1 0.000 0 0 -1 1 0 2
+ 1 1 1.00 135.00 180.00
+ 5700 2400 5700 1950
+2 2 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 5
+ 1200 1200 3825 1200 3825 3000 1200 3000 1200 1200
+2 2 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 5
+ 5250 1200 7875 1200 7875 3000 5250 3000 5250 1200
+2 2 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 5
+ 5400 1350 6075 1350 6075 1950 5400 1950 5400 1350
+2 2 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 5
+ 6225 1350 6900 1350 6900 1950 6225 1950 6225 1350
+2 2 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 5
+ 3000 1350 3675 1350 3675 1950 3000 1950 3000 1350
+2 2 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 5
+ 2175 1350 2850 1350 2850 1950 2175 1950 2175 1350
+2 2 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 5
+ 1350 1350 2025 1350 2025 1950 1350 1950 1350 1350
+4 0 0 50 -1 16 12 0.0000 4 150 870 6825 2850 Dest Host\001
+4 0 0 50 -1 16 12 0.0000 4 150 1080 1350 2850 Source Host\001
+4 0 0 50 -1 16 12 0.0000 4 150 495 1425 1725 VM-A\001
+4 0 0 50 -1 16 12 0.0000 4 150 495 2250 1725 VM-B\001
+4 0 0 50 -1 16 12 0.0000 4 150 495 3075 1725 VM-C\001
+4 0 0 50 -1 16 12 0.0000 4 150 495 5475 1725 VM-C\001
+4 0 0 50 -1 16 12 0.0000 4 150 495 6300 1725 VM-D\001
diff --git a/docs/migration-tunnel.png b/docs/migration-tunnel.png
new file mode 100644
index 0000000000000000000000000000000000000000..0f186d3e9f487ee73c09d09c03ed9e0a7402751d
GIT binary patch
literal 2237
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
literal 0
HcmV?d00001
diff --git a/docs/migration-unmanaged-direct.fig b/docs/migration-unmanaged-direct.fig
new file mode 100644
index 0000000..d4dee04
--- /dev/null
+++ b/docs/migration-unmanaged-direct.fig
@@ -0,0 +1,58 @@
+#FIG 3.2 Produced by xfig version 3.2.5b
+Landscape
+Center
+Inches
+Letter
+100.00
+Single
+-2
+1200 2
+6 2775 2400 3675 2850
+2 2 0 1 0 7 50 -1 -1 0.000 0 0 7 0 0 5
+ 2775 2400 3675 2400 3675 2850 2775 2850 2775 2400
+4 0 0 50 -1 16 12 0.0000 4 150 630 2925 2700 HV Ctrl\001
+-6
+6 5400 2400 6300 2850
+2 2 0 1 0 7 50 -1 -1 0.000 0 0 7 0 0 5
+ 5400 2400 6300 2400 6300 2850 5400 2850 5400 2400
+4 0 0 50 -1 16 12 0.0000 4 150 630 5550 2700 HV Ctrl\001
+-6
+2 2 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 5
+ 1200 1200 3825 1200 3825 3000 1200 3000 1200 1200
+2 2 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 5
+ 5250 1200 7875 1200 7875 3000 5250 3000 5250 1200
+2 2 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 5
+ 5400 1350 6075 1350 6075 1950 5400 1950 5400 1350
+2 2 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 5
+ 6225 1350 6900 1350 6900 1950 6225 1950 6225 1350
+2 2 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 5
+ 3000 1350 3675 1350 3675 1950 3000 1950 3000 1350
+2 2 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 5
+ 2175 1350 2850 1350 2850 1950 2175 1950 2175 1350
+2 2 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 5
+ 1350 1350 2025 1350 2025 1950 1350 1950 1350 1350
+2 1 0 3 0 7 50 -1 -1 0.000 0 0 -1 1 0 4
+ 1 1 1.00 135.00 180.00
+ 4350 4275 4350 3600 3300 3600 3300 2850
+2 2 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 5
+ 3225 4125 5850 4125 5850 6000 3225 6000 3225 4125
+2 2 0 1 0 7 50 -1 -1 0.000 0 0 7 0 0 5
+ 3375 5100 5700 5100 5700 5550 3375 5550 3375 5100
+2 1 0 3 0 7 50 -1 -1 0.000 0 0 -1 1 0 3
+ 1 1 1.00 135.00 180.00
+ 3750 5100 3750 4500 4050 4500
+2 2 0 1 0 7 50 -1 -1 0.000 0 0 7 0 0 5
+ 4050 4275 5100 4275 5100 4725 4050 4725 4050 4275
+2 1 0 3 0 7 50 -1 -1 0.000 0 0 -1 1 0 2
+ 1 1 1.00 135.00 180.00
+ 3675 2625 5400 2625
+4 0 0 50 -1 16 12 0.0000 4 150 870 6825 2850 Dest Host\001
+4 0 0 50 -1 16 12 0.0000 4 150 1080 1350 2850 Source Host\001
+4 0 0 50 -1 16 12 0.0000 4 150 495 1425 1725 VM-A\001
+4 0 0 50 -1 16 12 0.0000 4 150 495 2250 1725 VM-B\001
+4 0 0 50 -1 16 12 0.0000 4 150 495 3075 1725 VM-C\001
+4 0 0 50 -1 16 12 0.0000 4 150 495 5475 1725 VM-C\001
+4 0 0 50 -1 16 12 0.0000 4 150 495 6300 1725 VM-D\001
+4 0 0 50 -1 16 12 0.0000 4 150 960 4725 5850 Client Host\001
+4 0 0 50 -1 16 12 0.0000 4 180 1500 3525 5400 management app\001
+4 0 0 50 -1 16 12 0.0000 4 150 735 4200 4575 libvirt.so\001
diff --git a/docs/migration-unmanaged-direct.png b/docs/migration-unmanaged-direct.png
new file mode 100644
index 0000000000000000000000000000000000000000..d49cd0d0b16957193504eb68b909da8688a9ad60
GIT binary patch
literal 3951
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
UQ*9I3d<?j9$@wDX!p(%g14`InzyJUM
literal 0
HcmV?d00001
diff --git a/docs/migration.html.in b/docs/migration.html.in
index ee72b00..4a16162 100644
--- a/docs/migration.html.in
+++ b/docs/migration.html.in
@@ -2,6 +2,8 @@
<body>
<h1>Guest migration</h1>
+ <ul id="toc"></ul>
+
<p>
Migration of guests between hosts is a complicated problem with many possible
solutions, each with their own positive and negative points. For maximum
@@ -9,34 +11,419 @@
libvirt implements several options for migration.
</p>
- <h2>Data transports</h2>
+ <h2><a id="transport">Network data transports</a></h2>
<p>
There are two options for the data transport used during migration, either
the hypervisor's own <strong>native</strong> transport, or <strong>tunnelled</strong>
over a libvirtd connection.
</p>
+
+ <h3><a id="transportnative">Hypervisor native transport</a></h3>
<p>
- <strong>Native</strong> data transports may, or may not support encryption depending
+ <em>Native</em> data transports may, or may not support encryption depending
on the hypervisor in question, but will typically have the lowest computational costs
by minimising the number of data copies involved. The native data transports will also
require extra hypervisor-specific network configuration steps by the administrator when
- deploying a host.
+ deploying a host. For some hypervisors, it might be neccessary to open up a large range
+ of ports on the firewall to allow multiple concurrent migration operations.
+ </p>
+
+ <p>
+ <img class="diagram" src="migration-native.png" alt="Migration native path">
</p>
+
+ <h3><a id="transporttunnel">libvirt tunnelled transport</a></h3>
<p>
- <strong>Tunnelled</strong> data transports will always be capable of strong encryption
+ <em>Tunnelled</em> data transports will always be capable of strong encryption
since they are able to leverage the capabilities builtin to the libvirt RPC protocol.
- One potentially significant downside of a tunnelled transport is that there will be
- extra data copies involved on both the source and destinations hosts as the data is
- moved between libvirtd & the hypervisor. On the deployment side, tunnelled transports
- do not require any extra network configuration over and above what's already required
- for general libvirtd <a href="remote.html">remote access</a>.
+ The downside of a tunnelled transport, however, is that there will be extra data copies
+ involved on both the source and destinations hosts as the data is moved between libvirtd
+ & the hypervisor. This is likely to be a more significant problem for guests with
+ very large RAM sizes, which dirty memory pages quickly. On the deployment side, tunnelled
+ transports do not require any extra network configuration over and above what's already
+ required for general libvirtd <a href="remote.html">remote access</a>, and there is only
+ need for a single port to be open on the firewall.
+ </p>
+
+ <p>
+ <img class="diagram" src="migration-tunnel.png" alt="Migration tunnel path">
+ </p>
+
+ <h2><a id="flow">Communication control paths/flows</a></h2>
+
+ <p>
+ Migration of virtual machines requires close co-ordination of the two
+ hosts involved, as well as the application invoking the migration
+ operation which might be on a third host.
+ </p>
+
+ <h3><a id="flowmanageddirect">Managed direct migration</a></h3>
+
+ <p>
+ With <em>managed, direct</em> migration, the libvirt client process
+ controls the various phases of migration. The client application must
+ be able to connect & authenticate with the libvirtd daemons on both
+ the source and destination hosts. There is no need for the two libvirtd
+ daemons to communicate with each other. If the client application
+ crashes, or otherwise looses its connection to libvirtd during the
+ migration process, an attempt will be made to abort the migrastion and
+ restart the guest CPUs on the source host. There may be scenarios
+ where this cannot be safely done, in which cases the guest will be
+ left paused on one or both of the hosts.
+ </p>
+
+ <p>
+ <img class="diagram" src="migration-managed-direct.png" alt="Migration direct, managed">
+ </p>
+
+
+ <h3><a id="flowpeer2peer">Managed peer to peer migration</a></h3>
+
+ <p>
+ With <em>peer to peer</em> migration, the libvirt client process only
+ talks to the libvirtd daemon on the source host. The libvirtd daemon
+ will then connect to the destination host libvirtd and controls the
+ entire migration process itself. If the client application crashes,
+ or otherwise looses its connection to libvirtd, the migration process
+ will continue uninterrupted until completion.
+ </p>
+
+ <p>
+ <img class="diagram" src="migration-managed-p2p.png" alt="Migration peer-to-peer">
+ </p>
+
+
+ <h3><a id="flowunmanageddirect">Unmanaged direct migration</a></h3>
+
+ <p>
+ With <em>unmanaged, direct</em> migration, neither the libvirt client
+ or libvirtd daemon control the migration process. Control is instead
+ delegated to the hypervisor's over management services (if any). The
+ libvirt client merely initiates the migration via the hypervisor's
+ management layer. If the libvirt client or libvirtd crash, the
+ migration process will continue uninterrupted until completion.
+ </p>
+
+ <p>
+ <img class="diagram" src="migration-unmanaged-direct.png" alt="Migration direct, unmanaged">
+ </p>
+
+
+ <h2><a id="security">Data security</a></h2>
+
+ <p>
+ Since the migration data stream includes a complete copy of the guest
+ OS RAM, snooping of the migration data stream may allow compromise
+ of sensitive guest information. If the virtualization hosts have
+ multiple network interfaces, or if the network switches support
+ tagged VLANs, then it is very desirable to separate guest network
+ traffic from migration or management traffic.
+ </p>
+
+ <p>
+ In some scenarios, even a separate network for migration data may
+ not offer sufficient security. In this case it is possible to apply
+ encryption to the migration data stream. If the hypervisor does not
+ itself offer encryption, then the libvirt tunnelled migration
+ facility should be used.
+ </p>
+
+ <h2><a id="uris">Migration URIs</a></h2>
+
+ <p>
+ Initiating a guest migration requires the client application to
+ specify upto three URIs, depending on the choice of control
+ flow and/or APIs used. The first URI is that of the libvirt
+ connection to the source host, where the virtual guest is
+ currently running. The second URI is that of the libvirt
+ connection to the destination host, where the virtual guest
+ will be moved to. The third URI is a hypervisor specific
+ URI used to control how the guest will be migrated. With
+ any managed migration flow, the first & second URIs are
+ compulsory, while the third URI is optional. With the
+ unmanaged direct migration mode, the first & third URIs are
+ compulsory and the second URI is not used.
+ </p>
+
+ <p>
+ Ordinarily management applications only need to care about the
+ first and second URIs, which are both in the normal libvirt
+ connection URI format. Libvirt will then automatically determine
+ the hypervisor specific URI, by looking up the target host's
+ configured hostname. There are a few scenarios where the management
+ application may wish to have direct control over the third URI.
</p>
- <h2>Migration scenarios</h2>
+ <ol>
+ <li>The configured hostname is incorrect, or DNS is broken. If a
+ host has a hostname, which will not resolve to match one of its
+ public IP addresses, then libvirt will generate an incorrect
+ URI. In this case the management application should specify the
+ hypervisor specific URI explicitly, using an IP address, or a
+ correct hostname.</li>
+ <li>The host has multiple network interaces. If a host has multiple
+ network interfaces, it might be desirable for the migration data
+ stream to be sent over a specific interface for either security
+ or performance reasons. In this case the management application
+ should specify the hypervisor specific URI, using an IP address
+ associated with the network to be used</li>
+ <li>The firewall restricts what ports are available. When libvirt
+ generates a migration URI will pick a port number using hypervisor
+ specific rules. Some hypervisors only require a single port to be
+ open in the firewalls, while others require a whole range of port
+ numbers. In the latter case the management application may wish
+ to choose a specific port number outside the default range in order
+ to comply with local firewall policies</li>
+ </ol>
+
+ <h2><a id="config">Configuration file handling</a></h2>
+ <p>
+ There are two types of virtual machine known to libvirt. A <em>transient</em>
+ guest only exists while it is running, and has no configuration file stored
+ on disk. A <em>persistent</em> guest maintains a configuration file on disk
+ even when it is not running.
+ </p>
+
+ <p>
+ By default, a migration operation will not attempt to change any configuration
+ files that may be stored on either the source or destination host. It is the
+ administrator, or management application's, responsibility to manage distribution
+ of configuration files (if desired). It is important to note that the <code>/etc/libvirt</code>
+ directory <strong>MUST NEVER BE SHARED BETWEEN HOSTS</strong>. There are some
+ typical scenarios that might be applicable:
+ </p>
+
+ <ul>
+ <li>Centralized configuration files outside libvirt, in shared storage. A cluster
+ aware management application may maintain all the master guest configuration
+ files in a cluster filesystem. When attempting to start a guest, the config
+ will be read from the cluster FS and used to deploy a persistent guest.
+ For migration the configuration wwill need to be copied to the destination
+ host and removed on the original.
+ </li>
+ <li>Centralized configuration files outside libvirt, in a database. A data center
+ management application may not storage configuration files at all. Instead it
+ may generate libvirt XML on the fly when a guest is booted. It will typically
+ use transient guests, and thus not have to consider configuration files during
+ migration.
+ </li>
+ <li>Distributed configuration inside libvirt. The configuration file for each
+ guest is copied to every host where the guest is able to run. Upon migration
+ the existing config merely needs to be updated with any changes
+ </li>
+ <li>Ad-hoc configuration management inside libvirt. Each guest is tied to a
+ specific host and rarely migrated. When migration is required, the config
+ is moved from one host to the other.
+ </li>
+ </ul>
+
+ <p>
+ As mentioned above, libvirt will not touch configuration files during
+ migration by default. The <code>virsh</code> command has two flags to
+ influence this behaviour. The <code>--undefine-source</code> flag
+ will cause the configuration file to be removed on the source host
+ after a successful migration. The <code>--persist</code> flag will
+ cause a configuration file to be created on the destination host
+ after a successful migration. The following table summarizes the
+ configuration file handling in all possible state & flag
+ combinations.
+ </p>
- <h3>Native migration, client to two libvirtd servers</h3>
+ <table class="data">
+ <thead>
+ <tr class="head">
+ <th colspan="3">Before migration</th>
+ <th colspan="2">Flags</th>
+ <th colspan="3">After migration</th>
+ </tr>
+ <tr class="subhead">
+ <th>Guest type</th>
+ <th>Source config</th>
+ <th>Dest config</th>
+ <th>--undefine-source</th>
+ <th>--persist</th>
+ <th>Guest type</th>
+ <th>Source config</th>
+ <th>Dest config</th>
+ </tr>
+ </thead>
+ <tbody>
+ <!-- src:N, dst:N -->
+ <tr>
+ <td>Transient</td>
+ <td class="n">N</td>
+ <td class="n">N</td>
+ <td class="n">N</td>
+ <td class="n">N</td>
+ <td>Transient</td>
+ <td class="n">N</td>
+ <td class="n">N</td>
+ </tr>
+ <tr>
+ <td>Transient</td>
+ <td class="n">N</td>
+ <td class="n">N</td>
+ <td class="y">Y</td>
+ <td class="n">N</td>
+ <td>Transient</td>
+ <td class="n">N</td>
+ <td class="n">N</td>
+ </tr>
+ <tr>
+ <td>Transient</td>
+ <td class="n">N</td>
+ <td class="n">N</td>
+ <td class="n">N</td>
+ <td class="y">Y</td>
+ <td>Persistent</td>
+ <td class="n">N</td>
+ <td class="y">Y</td>
+ </tr>
+ <tr>
+ <td>Transient</td>
+ <td class="n">N</td>
+ <td class="n">N</td>
+ <td class="y">Y</td>
+ <td class="y">Y</td>
+ <td>Persistent</td>
+ <td class="n">N</td>
+ <td class="y">Y</td>
+ </tr>
+
+ <!-- src:N, dst:Y -->
+ <tr>
+ <td>Transient</td>
+ <td class="n">N</td>
+ <td class="y">Y</td>
+ <td class="n">N</td>
+ <td class="n">N</td>
+ <td>Persistent</td>
+ <td class="n">N</td>
+ <td class="n">N</td>
+ </tr>
+ <tr>
+ <td>Transient</td>
+ <td class="n">N</td>
+ <td class="y">Y</td>
+ <td class="y">Y</td>
+ <td class="n">N</td>
+ <td>Persistent</td>
+ <td class="n">N</td>
+ <td class="n">N</td>
+ </tr>
+ <tr>
+ <td>Transient</td>
+ <td class="n">N</td>
+ <td class="y">Y</td>
+ <td class="n">N</td>
+ <td class="y">Y</td>
+ <td>Persistent</td>
+ <td class="n">N</td>
+ <td class="y">Y</td>
+ </tr>
+ <tr>
+ <td>Transient</td>
+ <td class="n">N</td>
+ <td class="y">Y</td>
+ <td class="y">Y</td>
+ <td class="y">Y</td>
+ <td>Persistent</td>
+ <td class="n">N</td>
+ <td class="y">Y</td>
+ </tr>
+
+ <!-- src:Y dst:N -->
+ <tr>
+ <td>Persistent</td>
+ <td class="y">Y</td>
+ <td class="n">N</td>
+ <td class="n">N</td>
+ <td class="n">N</td>
+ <td>Transient</td>
+ <td class="y">Y</td>
+ <td class="n">N</td>
+ </tr>
+ <tr>
+ <td>Persistent</td>
+ <td class="y">Y</td>
+ <td class="n">N</td>
+ <td class="y">Y</td>
+ <td class="n">N</td>
+ <td>Transient</td>
+ <td class="n">N</td>
+ <td class="n">N</td>
+ </tr>
+ <tr>
+ <td>Persistent</td>
+ <td class="y">Y</td>
+ <td class="n">N</td>
+ <td class="n">N</td>
+ <td class="y">Y</td>
+ <td>Persistent</td>
+ <td class="y">Y</td>
+ <td class="y">Y</td>
+ </tr>
+ <tr>
+ <td>Persistent</td>
+ <td class="y">Y</td>
+ <td class="n">N</td>
+ <td class="y">Y</td>
+ <td class="y">Y</td>
+ <td>Persistent</td>
+ <td class="n">N</td>
+ <td class="y">Y</td>
+ </tr>
+
+ <!-- src:Y dst:Y -->
+ <tr>
+ <td>Persistent</td>
+ <td class="y">Y</td>
+ <td class="y">Y</td>
+ <td class="n">N</td>
+ <td class="n">N</td>
+ <td>Persistent</td>
+ <td class="y">Y</td>
+ <td class="y">Y</td>
+ </tr>
+ <tr>
+ <td>Persistent</td>
+ <td class="y">Y</td>
+ <td class="y">Y</td>
+ <td class="y">Y</td>
+ <td class="n">N</td>
+ <td>Persistent</td>
+ <td class="n">N</td>
+ <td class="y">Y</td>
+ </tr>
+ <tr>
+ <td>Persistent</td>
+ <td class="y">Y</td>
+ <td class="y">Y</td>
+ <td class="n">N</td>
+ <td class="y">Y</td>
+ <td>Persistent</td>
+ <td class="y">Y</td>
+ <td class="y">Y</td>
+ </tr>
+ <tr>
+ <td>Persistent</td>
+ <td class="y">Y</td>
+ <td class="y">Y</td>
+ <td class="y">Y</td>
+ <td class="y">Y</td>
+ <td>Persistent</td>
+ <td class="n">N</td>
+ <td class="y">Y</td>
+ </tr>
+ </tbody>
+ </table>
+
+ <h2><a id="scenarios">Migration scenarios</a></h2>
+
+
+ <h3><a id="scenarionativedirect">Native migration, client to two libvirtd servers</a></h3>
<p>
At an API level this requires use of virDomainMigrate, without the
@@ -66,7 +453,7 @@
Supported by Xen, QEMU, VMWare and VirtualBox drivers
</p>
- <h3>Native migration, client to and peer2peer between, two libvirtd servers</h3>
+ <h3><a id="scenarionativepeer2peer">Native migration, client to and peer2peer between, two libvirtd servers</a></h3>
<p>
virDomainMigrate, with the VIR_MIGRATE_PEER2PEER flag set,
@@ -90,7 +477,7 @@
Supported by QEMU driver
</p>
- <h3>Tunnelled migration, client and peer2peer between two libvirtd servers</h3>
+ <h3><a id="scenariotunnelpeer2peer1">Tunnelled migration, client and peer2peer between two libvirtd servers</a></h3>
<p>
virDomainMigrate, with the VIR_MIGRATE_PEER2PEER & VIR_MIGRATE_TUNNELLED
@@ -113,7 +500,7 @@
Supported by QEMU driver
</p>
- <h3>Native migration, client to one libvirtd server</h3>
+ <h3><a id="nativedirectunmanaged">Native migration, client to one libvirtd server</a></h3>
<p>
virDomainMigrateToURI, without the VIR_MIGRATE_PEER2PEER flag set,
@@ -137,7 +524,7 @@
Supported by Xen driver
</p>
- <h3>Native migration, peer2peer between two libvirtd servers</h3>
+ <h3><a id="nativepeer2peer">Native migration, peer2peer between two libvirtd servers</a></h3>
<p>
virDomainMigrateToURI, with the VIR_MIGRATE_PEER2PEER flag set,
@@ -171,7 +558,7 @@
Supported by the QEMU driver
</p>
- <h3>Tunnelled migration, peer2peer between two libvirtd servers</h3>
+ <h3><a id="scenariotunnelpeer2peer2">Tunnelled migration, peer2peer between two libvirtd servers</a></h3>
<p>
virDomainMigrateToURI, with the VIR_MIGRATE_PEER2PEER & VIR_MIGRATE_TUNNELLED
diff --git a/docs/sitemap.html.in b/docs/sitemap.html.in
index 254efbb..1de2b20 100644
--- a/docs/sitemap.html.in
+++ b/docs/sitemap.html.in
@@ -61,7 +61,7 @@
<span>Configure authentication for the libvirt daemon</span>
</li>
<li>
- <a href="migration.html">Guest migration</a>
+ <a href="migration.html">Migration</a>
<span>Migrating guests between machines</span>
</li>
<li>
--
1.7.6.4
13 years, 1 month
[libvirt] [PATCH] Add a systemtap script for watching QEMU monitor interactions
by Daniel P. Berrange
From: "Daniel P. Berrange" <berrange(a)redhat.com>
This change adds some systemtap/dtrace probes to the QEMU monitor
client code. In particular it allows watching of all operations
for a VM
* examples/systemtap/qemu-monitor.stp: Watch all monitor commands
* src/Makefile.am: Passing libdir/bindir/sbindir to dtrace2systemtap.pl
* src/dtrace2systemtap.pl: Accept libdir/bindir/sbindir as args
and look for '# binary:' comment to mark probes against libvirtd
vs libvirt.so
* src/qemu/qemu_monitor.c, src/qemu/qemu_monitor_json.c,
src/qemu/qemu_monitor_text.c: Add probes for key functions
---
examples/systemtap/qemu-monitor.stp | 81 +++++++++++++++++++++++++++++++++++
src/Makefile.am | 2 +-
src/dtrace2systemtap.pl | 15 ++++++-
src/probes.d | 20 +++++++++
src/qemu/qemu_monitor.c | 31 ++++++++++++-
src/qemu/qemu_monitor_json.c | 4 ++
src/qemu/qemu_monitor_text.c | 3 +
7 files changed, 150 insertions(+), 6 deletions(-)
create mode 100644 examples/systemtap/qemu-monitor.stp
diff --git a/examples/systemtap/qemu-monitor.stp b/examples/systemtap/qemu-monitor.stp
new file mode 100644
index 0000000..647eacc
--- /dev/null
+++ b/examples/systemtap/qemu-monitor.stp
@@ -0,0 +1,81 @@
+#!/usr/bin/stap
+#
+# Copyright (C) 2011 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: Daniel P. Berrange <berrange(a)redhat.com>
+#
+# This script will monitor all messages sent/received between libvirt
+# and the QEMU monitor
+#
+# stap qemu-monitor.stp
+# 0.000 begin
+# 3.848 ! 0x7f2dc00017b0 {"timestamp": {"seconds": 1319466931, "microseconds": 187755}, "event": "SHUTDOWN"}
+# 5.773 > 0x7f2dc0007960 {"execute":"qmp_capabilities","id":"libvirt-1"}
+# 5.774 < 0x7f2dc0007960 {"return": {}, "id": "libvirt-1"}
+# 5.774 > 0x7f2dc0007960 {"execute":"query-commands","id":"libvirt-2"}
+# 5.777 < 0x7f2dc0007960 {"return": [{"name": "quit"}, {"name": ....snip....
+# 5.777 > 0x7f2dc0007960 {"execute":"query-chardev","id":"libvirt-3"}
+# 5.778 < 0x7f2dc0007960 {"return": [{"filename": ....snip....
+# 5.779 > 0x7f2dc0007960 {"execute":"query-cpus","id":"libvirt-4"}
+# 5.780 < 0x7f2dc0007960 {"return": [{"current": true, "CPU": 0, "pc": 1048560, "halted": false, "thread_id": 13299}], "id": "libvirt-4"}
+# 5.780 > 0x7f2dc0007960 {"execute":"set_password","arguments":{"protocol":"vnc","password":"123456","connected":"keep"},"id":"libvirt-5"}
+# 5.782 < 0x7f2dc0007960 {"return": {}, "id": "libvirt-5"}
+# 5.782 > 0x7f2dc0007960 {"execute":"expire_password","arguments":{"protocol":"vnc","time":"never"},"id":"libvirt-6"}
+# 5.783 < 0x7f2dc0007960 {"return": {}, "id": "libvirt-6"}
+# 5.783 > 0x7f2dc0007960 {"execute":"balloon","arguments":{"value":224395264},"id":"libvirt-7"}
+# 5.785 < 0x7f2dc0007960 {"return": {}, "id": "libvirt-7"}
+# 5.785 > 0x7f2dc0007960 {"execute":"cont","id":"libvirt-8"}
+# 5.789 ! 0x7f2dc0007960 {"timestamp": {"seconds": 1319466933, "microseconds": 129980}, "event": "RESUME"}
+# 5.789 < 0x7f2dc0007960 {"return": {}, "id": "libvirt-8"}
+# 7.537 ! 0x7f2dc0007960 {"timestamp": {"seconds": 1319466934, "microseconds": 881214}, "event": "SHUTDOWN"}
+#
+
+
+global start
+
+# Print a string, with a timestamp relative to the start of the script
+function print_ts(msg)
+{
+ now = gettimeofday_ns() / (1000*1000)
+ delta = (now - start)
+
+ printf("%3d.%03d %s\n", (delta / 1000), (delta % 1000), msg);
+}
+
+
+# Just so we know the script is now running
+probe begin {
+ start = gettimeofday_ns() / (1000*1000)
+ print_ts("begin")
+}
+
+probe libvirt.qemu.monitor_send_msg {
+ if (fd != -1) {
+ print_ts(sprintf("> %p %s (fd=%d)", mon, substr(msg, 0, strlen(msg)-2), fd));
+ } else {
+ print_ts(sprintf("> %p %s", mon, substr(msg, 0, strlen(msg)-2)));
+ }
+}
+
+probe libvirt.qemu.monitor_recv_reply {
+ print_ts(sprintf("< %p %s", mon, reply));
+}
+
+probe libvirt.qemu.monitor_recv_event {
+ print_ts(sprintf("! %p %s", mon, event));
+}
+
diff --git a/src/Makefile.am b/src/Makefile.am
index 2555f81..81ec730 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -1288,7 +1288,7 @@ libvirt_functions.stp: $(RPC_PROBE_FILES) $(srcdir)/rpc/gensystemtap.pl
$(AM_V_GEN)perl -w $(srcdir)/rpc/gensystemtap.pl $(RPC_PROBE_FILES) > $@
libvirt_probes.stp: probes.d $(srcdir)/dtrace2systemtap.pl
- $(AM_V_GEN)perl -w $(srcdir)/dtrace2systemtap.pl $< > $@
+ $(AM_V_GEN)perl -w $(srcdir)/dtrace2systemtap.pl $(bindir) $(sbindir) $(libdir) $< > $@
CLEANFILES += probes.h probes.o libvirt_functions.stp libvirt_probes.stp
endif
diff --git a/src/dtrace2systemtap.pl b/src/dtrace2systemtap.pl
index fab066b..b577eac 100755
--- a/src/dtrace2systemtap.pl
+++ b/src/dtrace2systemtap.pl
@@ -31,6 +31,10 @@ my $file;
my @files;
my %files;
+my $bindir = shift @ARGV;
+my $sbindir = shift @ARGV;
+my $libdir = shift @ARGV;
+
my $probe;
my $args;
@@ -47,6 +51,8 @@ while (<>) {
$files{$file} = { prefix => undef, probes => [] };
} elsif (m,^\s*\#\s*prefix:\s*(\S+)\s*$,) {
$files{$file}->{prefix} = $1;
+ } elsif (m,^\s*\#\s*binary:\s*(\S+)\s*$,) {
+ $files{$file}->{binary} = $1;
} else {
if (m,\s*probe\s+([a-zA-Z0-9_]+)\((.*?)(\);)?$,) {
$probe = $1;
@@ -66,7 +72,7 @@ while (<>) {
die "unexpected data $_ on line $.";
}
} else {
- die "unexpected data $_ on line $.";
+ #die "unexpected data $_ on line $.";
}
}
}
@@ -84,7 +90,12 @@ foreach my $file (@files) {
my $pname = $name;
$pname =~ s/${prefix}_/libvirt.$prefix./;
- print "probe $pname = process(\"libvirt.so\").mark(\"$name\") {\n";
+ my $binary = "$libdir/libvirt.so";
+ if (exists $files{$file}->{binary}) {
+ $binary = $sbindir . "/" . $files{$file}->{binary};
+ }
+
+ print "probe $pname = process(\"$binary\").mark(\"$name\") {\n";
my @args = split /,/, $args;
for (my $i = 0 ; $i <= $#args ; $i++) {
diff --git a/src/probes.d b/src/probes.d
index 6d95c84..7f66ac0 100644
--- a/src/probes.d
+++ b/src/probes.d
@@ -69,4 +69,24 @@ provider libvirt {
probe rpc_tls_session_handshake_pass(void *sess);
probe rpc_tls_session_handshake_fail(void *sess);
+
+ # file: src/qemu/qemu_monitor.c
+ # prefix: qemu
+ # binary: libvirtd
+ # Monitor lifecycle
+ probe qemu_monitor_new(void *mon, int refs, int fd);
+ probe qemu_monitor_ref(void *mon, int refs);
+ probe qemu_monitor_unref(void *mon, int refs);
+ probe qemu_monitor_close(void *monm, int refs);
+
+ # High level monitor message processing
+ probe qemu_monitor_send_msg(void *mon, const char *msg, int fd);
+ probe qemu_monitor_recv_reply(void *mon, const char *reply);
+ probe qemu_monitor_recv_event(void *mon, const char *event);
+
+ # Low level monitor I/O processing
+ probe qemu_monitor_io_process(void *mon, const char *buf, unsigned int len);
+ probe qemu_monitor_io_read(void *mon, const char *buf, unsigned int len, int ret, int errno);
+ probe qemu_monitor_io_write(void *mon, const char *buf, unsigned int len, int ret, int errno);
+ probe qemu_monitor_io_send_fd(void *mon, int fd, int ret, int errno);
};
diff --git a/src/qemu/qemu_monitor.c b/src/qemu/qemu_monitor.c
index 182e63d..75429fa 100644
--- a/src/qemu/qemu_monitor.c
+++ b/src/qemu/qemu_monitor.c
@@ -183,6 +183,8 @@ static void qemuMonitorFree(qemuMonitorPtr mon)
int qemuMonitorRef(qemuMonitorPtr mon)
{
mon->refs++;
+ PROBE(QEMU_MONITOR_UNREF,
+ "mon=%p refs=%d", mon, mon->refs);
return mon->refs;
}
@@ -190,6 +192,8 @@ int qemuMonitorUnref(qemuMonitorPtr mon)
{
mon->refs--;
+ PROBE(QEMU_MONITOR_UNREF,
+ "mon=%p refs=%d", mon, mon->refs);
if (mon->refs == 0) {
qemuMonitorUnlock(mon);
qemuMonitorFree(mon);
@@ -305,6 +309,9 @@ qemuMonitorIOProcess(qemuMonitorPtr mon)
# endif
#endif
+ PROBE(QEMU_MONITOR_IO_PROCESS,
+ "mon=%p buf=%s len=%zu", mon, mon->buffer, mon->bufferOffset);
+
if (mon->json)
len = qemuMonitorJSONIOProcess(mon,
mon->buffer, mon->bufferOffset,
@@ -403,6 +410,18 @@ qemuMonitorIOWrite(qemuMonitorPtr mon)
mon->msg->txLength - mon->msg->txOffset,
mon->msg->txFD);
+ PROBE(QEMU_MONITOR_IO_WRITE,
+ "mon=%p buf=%s len=%d ret=%d errno=%d",
+ mon,
+ mon->msg->txBuffer + mon->msg->txOffset,
+ mon->msg->txLength - mon->msg->txOffset,
+ done, errno);
+
+ if (mon->msg->txFD != -1)
+ PROBE(QEMU_MONITOR_IO_SEND_FD,
+ "mon=%p fd=%d ret=%d errno=%d",
+ mon, mon->msg->txFD, done, errno);
+
if (done < 0) {
if (errno == EAGAIN)
return 0;
@@ -696,7 +715,9 @@ qemuMonitorOpen(virDomainObjPtr vm,
}
qemuMonitorRef(mon);
- VIR_DEBUG("New mon %p fd =%d watch=%d", mon, mon->fd, mon->watch);
+ PROBE(QEMU_MONITOR_NEW,
+ "mon=%p refs=%d fd=%d",
+ mon, mon->refs, mon->fd);
qemuMonitorUnlock(mon);
return mon;
@@ -719,9 +740,9 @@ void qemuMonitorClose(qemuMonitorPtr mon)
if (!mon)
return;
- VIR_DEBUG("mon=%p", mon);
-
qemuMonitorLock(mon);
+ PROBE(QEMU_MONITOR_CLOSE,
+ "mon=%p refs=%d", mon, mon->refs);
if (mon->fd >= 0) {
if (mon->watch)
@@ -762,6 +783,10 @@ int qemuMonitorSend(qemuMonitorPtr mon,
mon->msg = msg;
qemuMonitorUpdateWatch(mon);
+ PROBE(QEMU_MONITOR_SEND_MSG,
+ "mon=%p msg=%s fd=%d",
+ mon, mon->msg->txBuffer, mon->msg->txFD);
+
while (!mon->msg->finished) {
if (virCondWait(&mon->notify, &mon->lock) < 0) {
qemuReportError(VIR_ERR_INTERNAL_ERROR, "%s",
diff --git a/src/qemu/qemu_monitor_json.c b/src/qemu/qemu_monitor_json.c
index cd8f1e5..2c4aee5 100644
--- a/src/qemu/qemu_monitor_json.c
+++ b/src/qemu/qemu_monitor_json.c
@@ -126,9 +126,13 @@ qemuMonitorJSONIOProcessLine(qemuMonitorPtr mon,
if (virJSONValueObjectHasKey(obj, "QMP") == 1) {
ret = 0;
} else if (virJSONValueObjectHasKey(obj, "event") == 1) {
+ PROBE(QEMU_MONITOR_RECV_EVENT,
+ "mon=%p event=%s", mon, line);
ret = qemuMonitorJSONIOProcessEvent(mon, obj);
} else if (virJSONValueObjectHasKey(obj, "error") == 1 ||
virJSONValueObjectHasKey(obj, "return") == 1) {
+ PROBE(QEMU_MONITOR_RECV_REPLY,
+ "mon=%p reply=%s", mon, line);
if (msg) {
msg->rxObject = obj;
msg->finished = 1;
diff --git a/src/qemu/qemu_monitor_text.c b/src/qemu/qemu_monitor_text.c
index 4774df9..c652321 100644
--- a/src/qemu/qemu_monitor_text.c
+++ b/src/qemu/qemu_monitor_text.c
@@ -198,6 +198,9 @@ int qemuMonitorTextIOProcess(qemuMonitorPtr mon ATTRIBUTE_UNUSED,
VIR_DEBUG("Finished 0 byte reply");
#endif
}
+ PROBE(QEMU_MONITOR_RECV_REPLY,
+ "mon=%p reply=%s",
+ mon, msg->rxBuffer);
msg->finished = 1;
used += end - (data + used);
used += strlen(BASIC_PROMPT);
--
1.7.6.4
13 years, 1 month