[libvirt] [PATCH] macvtap: Fix error return values to -1 instead of 1
by Roopa Prabhu
From: Roopa Prabhu <roprabhu(a)cisco.com>
Fixes some cases where 1 was being returned instead of -1.
There are still some inconsistencies in the file with respect
to what the return variable is initialized to. Can be fixed
as a separate patch if needed. The scope of this patch is just
to fix the return value 1. Did some basic sanity test.
Signed-off-by: Roopa Prabhu <roprabhu(a)cisco.com>
Reported-by: Eric Blake <eblake(a)redhat.com>
---
src/util/macvtap.c | 22 ++++++++--------------
1 files changed, 8 insertions(+), 14 deletions(-)
diff --git a/src/util/macvtap.c b/src/util/macvtap.c
index 7fd6eb5..f8b9d55 100644
--- a/src/util/macvtap.c
+++ b/src/util/macvtap.c
@@ -480,7 +480,7 @@ getPortProfileStatus(struct nlattr **tb, int32_t vf,
bool is8021Qbg,
uint16_t *status)
{
- int rc = 1;
+ int rc = -1;
const char *msg = NULL;
struct nlattr *tb_port[IFLA_PORT_MAX + 1] = { NULL, };
@@ -806,7 +806,7 @@ doPortProfileOpCommon(bool nltarget_kernel,
_("error %d during port-profile setlink on "
"interface %s (%d)"),
status, ifname, ifindex);
- rc = 1;
+ rc = -1;
break;
}
@@ -867,7 +867,7 @@ doPortProfileOp8021Qbg(const char *ifname,
const virVirtualPortProfileParamsPtr virtPort,
enum virVirtualPortOp virtPortOp)
{
- int rc;
+ int rc = -1;
# ifndef IFLA_VF_PORT_MAX
@@ -877,7 +877,6 @@ doPortProfileOp8021Qbg(const char *ifname,
(void)virtPortOp;
macvtapError(VIR_ERR_INTERNAL_ERROR, "%s",
_("Kernel VF Port support was missing at compile time."));
- rc = 1;
# else /* IFLA_VF_PORT_MAX */
@@ -893,10 +892,8 @@ doPortProfileOp8021Qbg(const char *ifname,
int vf = PORT_SELF_VF;
if (getPhysdevAndVlan(ifname, &physdev_ifindex, physdev_ifname,
- &vlanid) != 0) {
- rc = 1;
+ &vlanid) != 0)
goto err_exit;
- }
if (vlanid < 0)
vlanid = 0;
@@ -918,7 +915,6 @@ doPortProfileOp8021Qbg(const char *ifname,
default:
macvtapError(VIR_ERR_INTERNAL_ERROR,
_("operation type %d not supported"), virtPortOp);
- rc = 1;
goto err_exit;
}
@@ -982,7 +978,7 @@ doPortProfileOp8021Qbh(const char *ifname,
const unsigned char *vm_uuid,
enum virVirtualPortOp virtPortOp)
{
- int rc;
+ int rc = -1;
# ifndef IFLA_VF_PORT_MAX
@@ -993,7 +989,6 @@ doPortProfileOp8021Qbh(const char *ifname,
(void)virtPortOp;
macvtapError(VIR_ERR_INTERNAL_ERROR, "%s",
_("Kernel VF Port support was missing at compile time."));
- rc = 1;
# else /* IFLA_VF_PORT_MAX */
@@ -1008,10 +1003,9 @@ doPortProfileOp8021Qbh(const char *ifname,
if (rc)
goto err_exit;
- if (ifaceGetIndex(true, physfndev, &ifindex) < 0) {
- rc = 1;
+ rc = ifaceGetIndex(true, physfndev, &ifindex);
+ if (rc < 0)
goto err_exit;
- }
switch (virtPortOp) {
case PREASSOCIATE_RR:
@@ -1059,7 +1053,7 @@ doPortProfileOp8021Qbh(const char *ifname,
default:
macvtapError(VIR_ERR_INTERNAL_ERROR,
_("operation type %d not supported"), virtPortOp);
- rc = 1;
+ rc = -1;
}
err_exit:
13 years, 1 month
[libvirt] [PATCH] lxc: avoid missing '{' in the function
by ajia@redhat.com
From: Alex Jia <ajia(a)redhat.com>
Cppcheck detected a syntaxError on lxcDomainInterfaceStats.
* src/lxc/lxc_driver.c: fixed missing '{' in the function lxcDomainInterfaceStats.
Signed-off-by: Alex Jia <ajia(a)redhat.com>
---
src/lxc/lxc_driver.c | 1 +
1 files changed, 1 insertions(+), 0 deletions(-)
diff --git a/src/lxc/lxc_driver.c b/src/lxc/lxc_driver.c
index f08e8d1..06bfa85 100644
--- a/src/lxc/lxc_driver.c
+++ b/src/lxc/lxc_driver.c
@@ -2671,6 +2671,7 @@ static int
lxcDomainInterfaceStats(virDomainPtr dom,
const char *path ATTRIBUTE_UNUSED,
struct _virDomainInterfaceStats *stats ATTRIBUTE_UNUSED)
+{
lxcError(VIR_ERR_NO_SUPPORT, "%s", __FUNCTION__);
return -1;
}
--
1.7.1
13 years, 1 month
[libvirt] [PATCH v2] 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
In v2:
- All Eric's fixes
- Squash in the preceeding patch which was mistakenly
left out before
* 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 -> 4004 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 | 601 +++++++++++++++++++++++++++++++++++
docs/sitemap.html.in | 4 +
14 files changed, 931 insertions(+), 2 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
create mode 100644 docs/migration.html.in
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
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
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..4287548
--- /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 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-managed-p2p.png b/docs/migration-managed-p2p.png
new file mode 100644
index 0000000000000000000000000000000000000000..eb9355866b9159c1c4dca9c4ce58482e3ac7d10e
GIT binary patch
literal 4004
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
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
new file mode 100644
index 0000000..bb66fdd
--- /dev/null
+++ b/docs/migration.html.in
@@ -0,0 +1,601 @@
+<html>
+ <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
+ flexibility of both hypervisor integration, and adminsitrator deployment,
+ libvirt implements several options for migration.
+ </p>
+
+ <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>
+ <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. 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>
+ <em>Tunnelled</em> data transports will always be capable of strong encryption
+ since they are able to leverage the capabilities built in to the libvirt RPC protocol.
+ 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
+ and 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 to support multiple concurrent
+ migration operations.
+ </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,
+ which may be on the source, the destination, or 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 and 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 loses its connection to libvirtd during the
+ migration process, an attempt will be made to abort the migration 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 source libvirtd
+ daemon controls the entire migration process itself, by directly
+ connecting the destination host libvirtd. If the client application crashes,
+ or otherwise loses 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 up to 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 and second URIs are
+ compulsory, while the third URI is optional. With the
+ unmanaged direct migration mode, the first and 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>
+
+ <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 will 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 and flag
+ combinations.
+ </p>
+
+ <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>Transient</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>Transient</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
+ VIR_MIGRATE_PEER2PEER flag set. The destination libvirtd server
+ will automatically determine the native hypervisor URI for migration
+ based off the primary hostname. To force migration over an alternate
+ network interface the optional hypervisor specific URI must be provided
+ </p>
+
+ <pre>
+ syntax: virsh migrate GUESTNAME DEST-LIBVIRT-URI [HV-URI]
+
+
+ eg using default network interface
+
+ virsh migrate web1 qemu+ssh://desthost/system
+ virsh migrate web1 xen+tls://desthost/system
+
+
+ eg using secondary network interface
+
+ virsh migrate web1 qemu://desthost/system tcp://10.0.0.1/
+ virsh migrate web1 xen+tcp://desthost/system xenmigr:10.0.0.1/
+ </pre>
+
+ <p>
+ Supported by Xen, QEMU, VMWare and VirtualBox drivers
+ </p>
+
+ <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,
+ using the libvirt URI format for the 'uri' parameter. The
+ destination libvirtd server will automatically determine
+ the native hypervisor URI for migration, based off the
+ primary hostname. The optional uri parameter controls how
+ the source libvirtd connects to the destination libvirtd,
+ in case it is not accessible using the same address that
+ the client uses to connect to the destiation, or a different
+ encryption/auth scheme is required. There is no
+ scope for forcing an alternative network interface for the
+ native migration data with this method.
+ </p>
+
+ <p>
+ This mode cannot be invoked from virsh
+ </p>
+
+ <p>
+ Supported by QEMU driver
+ </p>
+
+ <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
+ flags set, using the libvirt URI format for the 'uri' parameter. The
+ destination libvirtd server will automatically determine
+ the native hypervisor URI for migration, based off the
+ primary hostname. The optional uri parameter controls how
+ the source libvirtd connects to the destination libvirtd,
+ in case it is not accessible using the same address that
+ the client uses to connect to the destiation, or a different
+ encryption/auth scheme is required. The native hypervisor URI
+ format is not used at all.
+ </p>
+
+ <p>
+ This mode cannot be invoked from virsh
+ </p>
+
+ <p>
+ Supported by QEMU driver
+ </p>
+
+ <h3><a id="nativedirectunmanaged">Native migration, client to one libvirtd server</a></h3>
+
+ <p>
+ virDomainMigrateToURI, without the VIR_MIGRATE_PEER2PEER flag set,
+ using a hypervisor specific URI format for the 'uri' parameter.
+ There is no use or requirement for a destination libvirtd instance
+ at all. This is typically used when the hypervisor has its own
+ native management daemon available to handle incoming migration
+ attempts on the destination.
+ </p>
+
+ <pre>
+ syntax: virsh migrate GUESTNAME HV-URI
+
+
+ eg using same libvirt URI for all connections
+
+ virsh migrate --direct web1 xenmigr://desthost/
+ </pre>
+
+ <p>
+ Supported by Xen driver
+ </p>
+
+ <h3><a id="nativepeer2peer">Native migration, peer2peer between two libvirtd servers</a></h3>
+
+ <p>
+ virDomainMigrateToURI, with the VIR_MIGRATE_PEER2PEER flag set,
+ using the libvirt URI format for the 'uri' parameter. The
+ destination libvirtd server will automatically determine
+ the native hypervisor URI for migration, based off the
+ primary hostname. There is no scope for forcing an alternative
+ network interface for the native migration data with this method.
+ </p>
+
+ <pre>
+ syntax: virsh migrate GUESTNAME DEST-LIBVIRT-URI [ALT-DEST-LIBVIRT-URI]
+
+
+ eg using same libvirt URI for all connections
+
+ virsh migrate --p2p web1 qemu+ssh://desthost/system
+
+
+ eg using different libvirt URI auth scheme for peer2peer connections
+
+ virsh migrate --p2p web1 qemu+ssh://desthost/system qemu+tls:/desthost/system
+
+
+ eg using different libvirt URI hostname for peer2peer connections
+
+ virsh migrate --p2p web1 qemu+ssh://desthost/system qemu+ssh://10.0.0.1/system
+ </pre>
+
+ <p>
+ Supported by the QEMU driver
+ </p>
+
+ <h3><a id="scenariotunnelpeer2peer2">Tunnelled migration, peer2peer between two libvirtd servers</a></h3>
+
+ <p>
+ virDomainMigrateToURI, with the VIR_MIGRATE_PEER2PEER & VIR_MIGRATE_TUNNELLED
+ flags set, using the libvirt URI format for the 'uri' parameter. The
+ destination libvirtd server will automatically determine
+ the native hypervisor URI for migration, based off the
+ primary hostname. The optional uri parameter controls how
+ the source libvirtd connects to the destination libvirtd,
+ in case it is not accessible using the same address that
+ the client uses to connect to the destiation, or a different
+ encryption/auth scheme is required. The native hypervisor URI
+ format is not used at all.
+ </p>
+
+ <pre>
+ syntax: virsh migrate GUESTNAME DEST-LIBVIRT-URI [ALT-DEST-LIBVIRT-URI]
+
+
+ eg using same libvirt URI for all connections
+
+ virsh migrate --p2p --tunnelled web1 qemu+ssh://desthost/system
+
+
+ eg using different libvirt URI auth scheme for peer2peer connections
+
+ virsh migrate --p2p --tunnelled web1 qemu+ssh://desthost/system qemu+tls:/desthost/system
+
+
+ eg using different libvirt URI hostname for peer2peer connections
+
+ virsh migrate --p2p --tunnelled web1 qemu+ssh://desthost/system qemu+ssh://10.0.0.1/system
+ </pre>
+
+ <p>
+ Supported by QEMU driver
+ </p>
+
+ </body>
+</html>
diff --git a/docs/sitemap.html.in b/docs/sitemap.html.in
index 505b599..1de2b20 100644
--- a/docs/sitemap.html.in
+++ b/docs/sitemap.html.in
@@ -61,6 +61,10 @@
<span>Configure authentication for the libvirt daemon</span>
</li>
<li>
+ <a href="migration.html">Migration</a>
+ <span>Migrating guests between machines</span>
+ </li>
+ <li>
<a href="windows.html">Windows port</a>
<span>Access the libvirt daemon from a native Windows client</span>
</li>
--
1.7.6.4
13 years, 1 month
[libvirt] [PATCH] virsh: Fix error message on vol-create-from failure
by Ryota Ozaki
If vol-create-from is failed due to 'input volume not found',
virsh outputs like this:
$ sudo virsh vol-create-from testpool test-vol.xml test.img
error: failed to get vol 'test.img', specifying --pool might help
error: Storage volume not found: no storage vol with matching path
However, '--pool' is incorrect because it is already specified as
second argument ('testpool' in this case). It should be "--inputpool".
The patch fixes this by using pooloptname, which will be "inputpool"
in this case and "pool" in other cases, as error message.
---
tools/virsh.c | 4 ++--
1 files changed, 2 insertions(+), 2 deletions(-)
diff --git a/tools/virsh.c b/tools/virsh.c
index 72344f0..5544a41 100644
--- a/tools/virsh.c
+++ b/tools/virsh.c
@@ -15216,8 +15216,8 @@ vshCommandOptVolBy(vshControl *ctl, const vshCmd *cmd,
if (pool)
vshError(ctl, _("failed to get vol '%s'"), n);
else
- vshError(ctl, _("failed to get vol '%s', specifying --pool "
- "might help"), n);
+ vshError(ctl, _("failed to get vol '%s', specifying --%s "
+ "might help"), n, pooloptname);
}
if (pool)
--
1.7.4.1
13 years, 1 month
[libvirt] [PATCH 5/8] Getting Block IO Throttle support to remote driver
by Lei Li
Add getting Block IO Throttle support to remote driver.
Signed-off-by: Zhi Yong Wu <wuzhy(a)linux.vnet.ibm.com>
Signed-off-by: Lei Li <lilei(a)linux.vnet.ibm.com>
---
daemon/remote.c | 43 ++++++++++++++++++++++++++++++++++++++++++
src/remote/remote_driver.c | 42 +++++++++++++++++++++++++++++++++++++++++
src/remote/remote_protocol.x | 23 ++++++++++++++++++++++
src/remote_protocol-structs | 21 ++++++++++++++++++++
4 files changed, 129 insertions(+), 0 deletions(-)
diff --git a/daemon/remote.c b/daemon/remote.c
index c604556..ae8d5ed 100644
--- a/daemon/remote.c
+++ b/daemon/remote.c
@@ -1890,6 +1890,49 @@ cleanup:
return rv;
}
+static int
+remoteDispatchDomainGetBlockIoThrottle(virNetServerPtr server ATTRIBUTE_UNUSED,
+ virNetServerClientPtr client ATTRIBUTE_UNUSED,
+ virNetMessageHeaderPtr hdr ATTRIBUTE_UNUSED,
+ virNetMessageErrorPtr rerr,
+ remote_domain_get_block_io_throttle_args *args,
+ remote_domain_get_block_io_throttle_ret *ret)
+{
+ virDomainPtr dom = NULL;
+ virDomainBlockIoThrottleInfo reply;
+ int rv = -1;
+ struct daemonClientPrivate *priv =
+ virNetServerClientGetPrivateData(client);
+
+ if (!priv->conn) {
+ virNetError(VIR_ERR_INTERNAL_ERROR, "%s", _("connection not open"));
+ goto cleanup;
+ }
+
+ if (!(dom = get_nonnull_domain(priv->conn, args->dom)))
+ goto cleanup;
+
+ rv = virDomainGetBlockIoThrottle(dom, args->disk, &reply, args->flags);
+
+ if (rv < 0)
+ goto cleanup;
+
+ ret->bps = reply.bps;
+ ret->bps_rd = reply.bps_rd;
+ ret->bps_wr = reply.bps_wr;
+ ret->iops = reply.iops;
+ ret->iops_rd = reply.iops_rd;
+ ret->iops_wr = reply.iops_wr;
+ ret->found = 1;
+
+cleanup:
+ if (rv < 0)
+ virNetMessageSaveError(rerr);
+ if (dom)
+ virDomainFree(dom);
+ return rv;
+}
+
/*-------------------------------------------------------------*/
static int
diff --git a/src/remote/remote_driver.c b/src/remote/remote_driver.c
index a2d78f0..3c54184 100644
--- a/src/remote/remote_driver.c
+++ b/src/remote/remote_driver.c
@@ -2187,6 +2187,47 @@ done:
return rv;
}
+static int remoteDomainGetBlockIoThrottle(virDomainPtr domain,
+ const char *disk,
+ virDomainBlockIoThrottleInfoPtr reply,
+ unsigned int flags)
+{
+ int rv = -1;
+ remote_domain_get_block_io_throttle_args args;
+ remote_domain_get_block_io_throttle_ret ret;
+ struct private_data *priv = domain->conn->privateData;
+
+ remoteDriverLock(priv);
+
+ make_nonnull_domain(&args.dom, domain);
+ args.disk = (char *)disk;
+ args.flags = flags;
+
+ memset(&ret, 0, sizeof(ret));
+
+ if (call(domain->conn, priv, 0, REMOTE_PROC_DOMAIN_GET_BLOCK_IO_THROTTLE,
+ (xdrproc_t) xdr_remote_domain_get_block_io_throttle_args,
+ (char *) &args,
+ (xdrproc_t) xdr_remote_domain_get_block_io_throttle_ret,
+ (char *) &ret) == -1) {
+ goto done;
+ }
+
+ if (ret.found) {
+ reply->bps = ret.bps;
+ reply->bps_rd = ret.bps_rd;
+ reply->bps_wr = ret.bps_wr;
+ reply->iops = ret.iops;
+ reply->iops_rd = ret.iops_rd;
+ reply->iops_wr = ret.iops_wr;
+ }
+ rv = 0;
+
+done:
+ remoteDriverUnlock(priv);
+ return rv;
+}
+
/*----------------------------------------------------------------------*/
static virDrvOpenStatus ATTRIBUTE_NONNULL (1)
@@ -4512,6 +4553,7 @@ static virDriver remote_driver = {
.domainBlockJobSetSpeed = remoteDomainBlockJobSetSpeed, /* 0.9.4 */
.domainBlockPull = remoteDomainBlockPull, /* 0.9.4 */
.domainSetBlockIoThrottle = remoteDomainSetBlockIoThrottle, /* 0.9.8 */
+ .domainGetBlockIoThrottle = remoteDomainGetBlockIoThrottle, /* 0.9.8 */
};
static virNetworkDriver network_driver = {
diff --git a/src/remote/remote_protocol.x b/src/remote/remote_protocol.x
index b467952..46774cc 100644
--- a/src/remote/remote_protocol.x
+++ b/src/remote/remote_protocol.x
@@ -1085,6 +1085,28 @@ struct remote_domain_set_block_io_throttle_args {
unsigned int flags;
};
+struct remote_domain_get_block_io_throttle_args {
+ remote_nonnull_domain dom;
+ remote_nonnull_string disk;
+ unsigned hyper bps;
+ unsigned hyper bps_rd;
+ unsigned hyper bps_wr;
+ unsigned hyper iops;
+ unsigned hyper iops_rd;
+ unsigned hyper iops_wr;
+ unsigned int flags;
+};
+
+struct remote_domain_get_block_io_throttle_ret {
+ unsigned hyper bps;
+ unsigned hyper bps_rd;
+ unsigned hyper bps_wr;
+ unsigned hyper iops;
+ unsigned hyper iops_rd;
+ unsigned hyper iops_wr;
+ unsigned int found;
+};
+
/* Network calls: */
struct remote_num_of_networks_ret {
@@ -2569,6 +2591,7 @@ enum remote_procedure {
REMOTE_PROC_DOMAIN_SNAPSHOT_LIST_CHILDREN_NAMES = 247, /* autogen autogen priority:high */
REMOTE_PROC_DOMAIN_EVENT_DISK_CHANGE = 248, /* skipgen skipgen */
REMOTE_PROC_DOMAIN_SET_BLOCK_IO_THROTTLE = 249, /* skipgen skipgen */
+ REMOTE_PROC_DOMAIN_GET_BLOCK_IO_THROTTLE = 250 /* skipgen skipgen */
/*
* Notice how the entries are grouped in sets of 10 ?
diff --git a/src/remote_protocol-structs b/src/remote_protocol-structs
index 4f8bcf6..6aa1186 100644
--- a/src/remote_protocol-structs
+++ b/src/remote_protocol-structs
@@ -768,6 +768,26 @@ struct remote_domain_set_block_io_throttle_args {
uint64_t iops_wr;
u_int flags;
};
+struct remote_domain_get_block_io_throttle_args {
+ remote_nonnull_domain dom;
+ remote_nonnull_string disk;
+ uint64_t bps;
+ uint64_t bps_rd;
+ uint64_t bps_wr;
+ uint64_t iops;
+ uint64_t iops_rd;
+ uint64_t iops_wr;
+ u_int flags;
+};
+struct remote_domain_get_block_io_throttle_ret {
+ uint64_t bps;
+ uint64_t bps_rd;
+ uint64_t bps_wr;
+ uint64_t iops;
+ uint64_t iops_rd;
+ uint64_t iops_wr;
+ u_int found;
+};
struct remote_num_of_networks_ret {
int num;
};
@@ -2011,4 +2031,5 @@ enum remote_procedure {
REMOTE_PROC_DOMAIN_SNAPSHOT_LIST_CHILDREN_NAMES = 247,
REMOTE_PROC_DOMAIN_EVENT_DISK_CHANGE = 248,
REMOTE_PROC_DOMAIN_SET_BLOCK_IO_THROTTLE = 249,
+ REMOTE_PROC_DOMAIN_GET_BLOCK_IO_THROTTLE = 250,
};
--
1.7.1
13 years, 1 month
[libvirt] [PATCH 4/8] Add new API virDomainGetBlockIoThrottle
by Lei Li
Support virDomainGetBlockIoThrottle to src/libvirt.c
Signed-off-by: Zhi Yong Wu <wuzhy(a)linux.vnet.ibm.com>
Signed-off-by: Lei Li <lilei(a)linux.vnet.ibm.com>
---
include/libvirt/libvirt.h.in | 5 +++
src/driver.h | 6 ++++
src/libvirt.c | 57 ++++++++++++++++++++++++++++++++++++++++++
src/libvirt_public.syms | 1 +
4 files changed, 69 insertions(+), 0 deletions(-)
diff --git a/include/libvirt/libvirt.h.in b/include/libvirt/libvirt.h.in
index ff2926e..a844f61 100644
--- a/include/libvirt/libvirt.h.in
+++ b/include/libvirt/libvirt.h.in
@@ -1592,6 +1592,11 @@ virDomainSetBlockIoThrottle(virDomainPtr dom,
virDomainBlockIoThrottleInfoPtr info,
unsigned int flags);
+int
+virDomainGetBlockIoThrottle(virDomainPtr dom,
+ const char *disk,
+ virDomainBlockIoThrottleInfoPtr reply,
+ unsigned int flags);
/*
* NUMA support
diff --git a/src/driver.h b/src/driver.h
index ffa71c8..936fc09 100644
--- a/src/driver.h
+++ b/src/driver.h
@@ -745,6 +745,11 @@ typedef int
virDomainBlockIoThrottleInfoPtr info,
unsigned int flags);
+typedef int
+ (*virDrvDomainGetBlockIoThrottle)(virDomainPtr dom,
+ const char *disk,
+ virDomainBlockIoThrottleInfoPtr reply,
+ unsigned int flags);
/**
* _virDriver:
@@ -904,6 +909,7 @@ struct _virDriver {
virDrvDomainBlockJobSetSpeed domainBlockJobSetSpeed;
virDrvDomainBlockPull domainBlockPull;
virDrvDomainSetBlockIoThrottle domainSetBlockIoThrottle;
+ virDrvDomainGetBlockIoThrottle domainGetBlockIoThrottle;
};
typedef int
diff --git a/src/libvirt.c b/src/libvirt.c
index dfc74fb..cf6ce38 100644
--- a/src/libvirt.c
+++ b/src/libvirt.c
@@ -17026,3 +17026,60 @@ error:
return -1;
}
+/**
+ * virDomainGetBlockIoThrottle:
+ * @dom: pointer to domain object
+ * @disk: Fully-qualified disk name
+ * @reply: specify block I/O info in bytes
+ * @flags: indicate if it set or display block I/O limits info
+ *
+ * This function is mainly to enable Block I/O throttling function in libvirt.
+ * It is used to get the block I/O throttling setting for specified domain.
+ *
+ * Returns 0 if the operation has started, -1 on failure.
+ */
+
+int virDomainGetBlockIoThrottle(virDomainPtr dom,
+ const char *disk,
+ virDomainBlockIoThrottleInfoPtr reply,
+ unsigned int flags)
+{
+ virConnectPtr conn;
+
+ VIR_DOMAIN_DEBUG(dom, "disk=%p, reply=%p, flags=%x",
+ disk, reply, flags);
+
+ virResetLastError();
+
+ if (!VIR_IS_CONNECTED_DOMAIN (dom)) {
+ virLibDomainError(VIR_ERR_INVALID_DOMAIN, __FUNCTION__);
+ virDispatchError(NULL);
+ return -1;
+ }
+ conn = dom->conn;
+
+ if (dom->conn->flags & VIR_CONNECT_RO) {
+ virLibDomainError(VIR_ERR_OPERATION_DENIED, __FUNCTION__);
+ goto error;
+ }
+
+ if (!disk) {
+ virLibDomainError(VIR_ERR_INVALID_ARG, __FUNCTION__);
+ goto error;
+ }
+
+ if (conn->driver->domainGetBlockIoThrottle) {
+ int ret;
+ ret = conn->driver->domainGetBlockIoThrottle(dom, disk, reply, flags);
+ if (ret < 0)
+ goto error;
+ return ret;
+ }
+
+ virLibDomainError(VIR_ERR_NO_SUPPORT, __FUNCTION__);
+
+error:
+ virDispatchError(dom->conn);
+ return -1;
+
+}
diff --git a/src/libvirt_public.syms b/src/libvirt_public.syms
index ce29978..3acfa6c 100644
--- a/src/libvirt_public.syms
+++ b/src/libvirt_public.syms
@@ -496,6 +496,7 @@ LIBVIRT_0.9.7 {
virDomainSnapshotListChildrenNames;
virDomainSnapshotNumChildren;
virDomainSetBlockIoThrottle;
+ virDomainGetBlockIoThrottle;
} LIBVIRT_0.9.5;
# .... define new API here using predicted next version number ....
--
1.7.1
13 years, 1 month
[libvirt] [PATCH 3/8] Implement Block Io Throttle setting for the qemu driver
by Lei Li
This patch implement the block io throtte setting for the qemu driver through
- qmp/hmp command 'block_set_io_throttle'.
Signed-off-by: Zhi Yong Wu <wuzhy(a)linux.vnet.ibm.com>
Signed-off-by: Lei Li <lilei(a)linux.vnet.ibm.com>
---
src/qemu/qemu_command.c | 35 +++++++++++++++++++++++++++
src/qemu/qemu_driver.c | 53 ++++++++++++++++++++++++++++++++++++++++++
src/qemu/qemu_monitor.c | 18 ++++++++++++++
src/qemu/qemu_monitor.h | 5 ++++
src/qemu/qemu_monitor_json.c | 45 +++++++++++++++++++++++++++++++++++
src/qemu/qemu_monitor_json.h | 5 ++++
src/qemu/qemu_monitor_text.c | 39 ++++++++++++++++++++++++++++++
src/qemu/qemu_monitor_text.h | 5 ++++
8 files changed, 205 insertions(+), 0 deletions(-)
diff --git a/src/qemu/qemu_command.c b/src/qemu/qemu_command.c
index 0c5bfab..9422e17 100644
--- a/src/qemu/qemu_command.c
+++ b/src/qemu/qemu_command.c
@@ -1734,6 +1734,41 @@ qemuBuildDriveStr(virDomainDiskDefPtr disk,
}
}
+ /*block I/O throttling*/
+ if (disk->blkiothrottle.bps || disk->blkiothrottle.bps_rd
+ || disk->blkiothrottle.bps_wr || disk->blkiothrottle.iops
+ || disk->blkiothrottle.iops_rd || disk->blkiothrottle.iops_wr) {
+ if (disk->blkiothrottle.bps) {
+ virBufferAsprintf(&opt, ",bps=%llu",
+ disk->blkiothrottle.bps);
+ }
+
+ if (disk->blkiothrottle.bps_rd) {
+ virBufferAsprintf(&opt, ",bps_rd=%llu",
+ disk->blkiothrottle.bps_rd);
+ }
+
+ if (disk->blkiothrottle.bps_wr) {
+ virBufferAsprintf(&opt, ",bps_wr=%llu",
+ disk->blkiothrottle.bps_wr);
+ }
+
+ if (disk->blkiothrottle.iops) {
+ virBufferAsprintf(&opt, ",iops=%llu",
+ disk->blkiothrottle.iops);
+ }
+
+ if (disk->blkiothrottle.iops_rd) {
+ virBufferAsprintf(&opt, ",iops_rd=%llu",
+ disk->blkiothrottle.iops_rd);
+ }
+
+ if (disk->blkiothrottle.iops_wr) {
+ virBufferAsprintf(&opt, ",iops_wr=%llu",
+ disk->blkiothrottle.iops_wr);
+ }
+ }
+
if (virBufferError(&opt)) {
virReportOOMError();
goto error;
diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c
index e053a97..b41a7d3 100644
--- a/src/qemu/qemu_driver.c
+++ b/src/qemu/qemu_driver.c
@@ -10660,6 +10660,58 @@ qemuDomainBlockPull(virDomainPtr dom, const char *path, unsigned long bandwidth,
return ret;
}
+static int
+qemuDomainSetBlockIoThrottle(virDomainPtr dom,
+ const char *disk,
+ virDomainBlockIoThrottleInfoPtr info,
+ unsigned int flags)
+{
+ struct qemud_driver *driver = dom->conn->privateData;
+ virDomainObjPtr vm = NULL;
+ qemuDomainObjPrivatePtr priv;
+ char uuidstr[VIR_UUID_STRING_BUFLEN];
+ const char *device = NULL;
+ int ret = -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;
+ }
+
+ if (!virDomainObjIsActive(vm)) {
+ qemuReportError(VIR_ERR_OPERATION_INVALID,
+ "%s", _("domain is not running"));
+ goto cleanup;
+ }
+
+ device = qemuDiskPathToAlias(vm, disk);
+ if (!device) {
+ goto cleanup;
+ }
+
+ if (qemuDomainObjBeginJobWithDriver(driver, vm, QEMU_JOB_MODIFY) < 0)
+ goto cleanup;
+ qemuDomainObjEnterMonitorWithDriver(driver, vm);
+ priv = vm->privateData;
+ ret = qemuMonitorSetBlockIoThrottle(priv->mon, device, info, flags);
+ qemuDomainObjExitMonitorWithDriver(driver, vm);
+ if (qemuDomainObjEndJob(driver, vm) == 0) {
+ vm = NULL;
+ goto cleanup;
+ }
+
+cleanup:
+ VIR_FREE(device);
+ if (vm)
+ virDomainObjUnlock(vm);
+ qemuDriverUnlock(driver);
+ return ret;
+}
+
static virDriver qemuDriver = {
.no = VIR_DRV_QEMU,
.name = "QEMU",
@@ -10802,6 +10854,7 @@ static virDriver qemuDriver = {
.domainGetBlockJobInfo = qemuDomainGetBlockJobInfo, /* 0.9.4 */
.domainBlockJobSetSpeed = qemuDomainBlockJobSetSpeed, /* 0.9.4 */
.domainBlockPull = qemuDomainBlockPull, /* 0.9.4 */
+ .domainSetBlockIoThrottle = qemuDomainSetBlockIoThrottle, /* 0.9.8 */
};
diff --git a/src/qemu/qemu_monitor.c b/src/qemu/qemu_monitor.c
index 182e63d..b061631 100644
--- a/src/qemu/qemu_monitor.c
+++ b/src/qemu/qemu_monitor.c
@@ -2542,6 +2542,24 @@ int qemuMonitorBlockJob(qemuMonitorPtr mon,
return ret;
}
+int qemuMonitorSetBlockIoThrottle(qemuMonitorPtr mon,
+ const char *device,
+ virDomainBlockIoThrottleInfoPtr info,
+ unsigned int flags)
+{
+ int ret;
+
+ VIR_DEBUG("mon=%p, device=%p, info=%p, flags=%x",
+ mon, device, info, flags);
+
+ if (mon->json) {
+ ret = qemuMonitorJSONSetBlockIoThrottle(mon, device, info, flags);
+ } else {
+ ret = qemuMonitorTextSetBlockIoThrottle(mon, device, info, flags);
+ }
+ return ret;
+}
+
int qemuMonitorVMStatusToPausedReason(const char *status)
{
int st;
diff --git a/src/qemu/qemu_monitor.h b/src/qemu/qemu_monitor.h
index 90e7b45..1269430 100644
--- a/src/qemu/qemu_monitor.h
+++ b/src/qemu/qemu_monitor.h
@@ -515,6 +515,11 @@ int qemuMonitorBlockJob(qemuMonitorPtr mon,
virDomainBlockJobInfoPtr info,
int mode);
+int qemuMonitorSetBlockIoThrottle(qemuMonitorPtr mon,
+ const char *device,
+ virDomainBlockIoThrottleInfoPtr info,
+ unsigned int flags);
+
/**
* When running two dd process and using <> redirection, we need a
* shell that will not truncate files. These two strings serve that
diff --git a/src/qemu/qemu_monitor_json.c b/src/qemu/qemu_monitor_json.c
index cd8f1e5..2f93830 100644
--- a/src/qemu/qemu_monitor_json.c
+++ b/src/qemu/qemu_monitor_json.c
@@ -3245,3 +3245,48 @@ int qemuMonitorJSONBlockJob(qemuMonitorPtr mon,
virJSONValueFree(reply);
return ret;
}
+
+int qemuMonitorJSONSetBlockIoThrottle(qemuMonitorPtr mon,
+ const char *device,
+ virDomainBlockIoThrottleInfoPtr info,
+ unsigned int flags)
+{
+ int ret = -1;
+ virJSONValuePtr cmd = NULL;
+ virJSONValuePtr result = NULL;
+
+ if (flags) {
+ cmd = qemuMonitorJSONMakeCommand("block_set_io_throttle",
+ "s:device", device,
+ "U:bps", info->bps,
+ "U:bps_rd", info->bps_rd,
+ "U:bps_wr", info->bps_wr,
+ "U:iops", info->iops,
+ "U:iops_rd", info->iops_rd,
+ "U:iops_wr", info->iops_wr,
+ NULL);
+ }
+
+ if (!cmd)
+ return -1;
+
+ ret = qemuMonitorJSONCommand(mon, cmd, &result);
+
+ if (ret == 0 && virJSONValueObjectHasKey(result, "error")) {
+ if (qemuMonitorJSONHasError(result, "DeviceNotActive"))
+ qemuReportError(VIR_ERR_OPERATION_INVALID,
+ _("No active operation on device: %s"), device);
+ else if (qemuMonitorJSONHasError(result, "NotSupported"))
+ qemuReportError(VIR_ERR_OPERATION_INVALID,
+ _("Operation is not supported for device: %s"), device);
+ else
+ qemuReportError(VIR_ERR_INTERNAL_ERROR, "%s",
+ _("Unexpected error"));
+ ret = -1;
+ }
+
+ virJSONValueFree(cmd);
+ virJSONValueFree(result);
+ return ret;
+}
+
diff --git a/src/qemu/qemu_monitor_json.h b/src/qemu/qemu_monitor_json.h
index a638b41..36cae79 100644
--- a/src/qemu/qemu_monitor_json.h
+++ b/src/qemu/qemu_monitor_json.h
@@ -250,4 +250,9 @@ int qemuMonitorJSONSetLink(qemuMonitorPtr mon,
const char *name,
enum virDomainNetInterfaceLinkState state);
+int qemuMonitorJSONSetBlockIoThrottle(qemuMonitorPtr mon,
+ const char *device,
+ virDomainBlockIoThrottleInfoPtr info,
+ unsigned int flags);
+
#endif /* QEMU_MONITOR_JSON_H */
diff --git a/src/qemu/qemu_monitor_text.c b/src/qemu/qemu_monitor_text.c
index 4774df9..13fdf55 100644
--- a/src/qemu/qemu_monitor_text.c
+++ b/src/qemu/qemu_monitor_text.c
@@ -3394,3 +3394,42 @@ cleanup:
VIR_FREE(reply);
return ret;
}
+
+int qemuMonitorTextSetBlockIoThrottle(qemuMonitorPtr mon,
+ const char *device,
+ virDomainBlockIoThrottleInfoPtr info,
+ unsigned int flags)
+{
+ char *cmd = NULL;
+ char *result = NULL;
+ int ret = 0;
+
+ if (flags) {
+ ret = virAsprintf(&cmd, "block_set_io_throttle %s %llu %llu %llu %llu %llu %llu",
+ device,
+ info->bps,
+ info->bps_rd,
+ info->bps_wr,
+ info->iops,
+ info->iops_rd,
+ info->iops_wr);
+ }
+
+ if (ret < 0) {
+ virReportOOMError();
+ return -1;
+ }
+
+ if (qemuMonitorHMPCommand(mon, cmd, &result) < 0) {
+ qemuReportError(VIR_ERR_INTERNAL_ERROR,
+ "%s", _("cannot run monitor command"));
+ ret = -1;
+ goto cleanup;
+ }
+
+cleanup:
+ VIR_FREE(cmd);
+ VIR_FREE(result);
+ return ret;
+}
+
diff --git a/src/qemu/qemu_monitor_text.h b/src/qemu/qemu_monitor_text.h
index cc2a252..d64fc55 100644
--- a/src/qemu/qemu_monitor_text.h
+++ b/src/qemu/qemu_monitor_text.h
@@ -243,4 +243,9 @@ int qemuMonitorTextSetLink(qemuMonitorPtr mon,
const char *name,
enum virDomainNetInterfaceLinkState state);
+int qemuMonitorTextSetBlockIoThrottle(qemuMonitorPtr mon,
+ const char *device,
+ virDomainBlockIoThrottleInfoPtr info,
+ unsigned int flags);
+
#endif /* QEMU_MONITOR_TEXT_H */
--
1.7.1
13 years, 1 month
[libvirt] [PATCH 2/8] Add Block IO Throttle support setting to the remote driver
by Lei Li
Support Block IO Throttle setting to remote driver.
Signed-off-by: Zhi Yong Wu <wuzhy(a)linux.vnet.ibm.com>
Signed-off-by: Lei Li <lilei(a)linux.vnet.ibm.com>
---
daemon/remote.c | 42 ++++++++++++++++++++++++++++++++++++++++++
src/remote/remote_driver.c | 38 ++++++++++++++++++++++++++++++++++++++
src/remote/remote_protocol.x | 15 ++++++++++++++-
src/remote_protocol-structs | 12 ++++++++++++
4 files changed, 106 insertions(+), 1 deletions(-)
diff --git a/daemon/remote.c b/daemon/remote.c
index 9d70163..c604556 100644
--- a/daemon/remote.c
+++ b/daemon/remote.c
@@ -1847,6 +1847,48 @@ cleanup:
return rv;
}
+static int
+remoteDispatchDomainSetBlockIoThrottle(virNetServerPtr server ATTRIBUTE_UNUSED,
+ virNetServerClientPtr client ATTRIBUTE_UNUSED,
+ virNetMessageHeaderPtr hdr ATTRIBUTE_UNUSED,
+ virNetMessageErrorPtr rerr,
+ remote_domain_set_block_io_throttle_args *args)
+{
+ virDomainPtr dom = NULL;
+ virDomainBlockIoThrottleInfo tmp;
+ int rv = -1;
+ struct daemonClientPrivate *priv =
+ virNetServerClientGetPrivateData(client);
+
+ if (!priv->conn) {
+ virNetError(VIR_ERR_INTERNAL_ERROR, "%s", _("connection not open"));
+ goto cleanup;
+ }
+
+ if (!(dom = get_nonnull_domain(priv->conn, args->dom)))
+ goto cleanup;
+
+ if (args) {
+ tmp.bps = args->bps;
+ tmp.bps_rd = args->bps_rd;
+ tmp.bps_wr = args->bps_wr;
+ tmp.iops = args->iops;
+ tmp.iops_rd = args->iops_rd;
+ tmp.iops_wr = args->iops_wr;
+ }
+
+ rv = virDomainSetBlockIoThrottle(dom, args->disk, &tmp, args->flags);
+
+ if (rv < 0)
+ goto cleanup;
+
+cleanup:
+ if (rv < 0)
+ virNetMessageSaveError(rerr);
+ if (dom)
+ virDomainFree(dom);
+ return rv;
+}
/*-------------------------------------------------------------*/
diff --git a/src/remote/remote_driver.c b/src/remote/remote_driver.c
index e98ebd7..a2d78f0 100644
--- a/src/remote/remote_driver.c
+++ b/src/remote/remote_driver.c
@@ -2150,6 +2150,43 @@ done:
return rv;
}
+static int remoteDomainSetBlockIoThrottle(virDomainPtr domain,
+ const char *disk,
+ virDomainBlockIoThrottleInfoPtr info,
+ unsigned int flags)
+{
+ int rv = -1;
+ remote_domain_set_block_io_throttle_args args;
+ struct private_data *priv = domain->conn->privateData;
+
+ remoteDriverLock(priv);
+
+ memset(&args, 0, sizeof(args));
+
+ make_nonnull_domain(&args.dom, domain);
+ args.disk = (char *)disk;
+ args.bps = info->bps;
+ args.bps_rd = info->bps_rd;
+ args.bps_wr = info->bps_wr;
+ args.iops = info->iops;
+ args.iops_rd = info->iops_rd;
+ args.iops_wr = info->iops_wr;
+ args.flags = flags;
+
+ if (call(domain->conn, priv, 0, REMOTE_PROC_DOMAIN_SET_BLOCK_IO_THROTTLE,
+ (xdrproc_t) xdr_remote_domain_set_block_io_throttle_args,
+ (char *) &args,
+ (xdrproc_t) xdr_void,
+ (char *) NULL) == -1) {
+ goto done;
+ }
+ rv = 0;
+
+done:
+ remoteDriverUnlock(priv);
+ return rv;
+}
+
/*----------------------------------------------------------------------*/
static virDrvOpenStatus ATTRIBUTE_NONNULL (1)
@@ -4474,6 +4511,7 @@ static virDriver remote_driver = {
.domainGetBlockJobInfo = remoteDomainGetBlockJobInfo, /* 0.9.4 */
.domainBlockJobSetSpeed = remoteDomainBlockJobSetSpeed, /* 0.9.4 */
.domainBlockPull = remoteDomainBlockPull, /* 0.9.4 */
+ .domainSetBlockIoThrottle = remoteDomainSetBlockIoThrottle, /* 0.9.8 */
};
static virNetworkDriver network_driver = {
diff --git a/src/remote/remote_protocol.x b/src/remote/remote_protocol.x
index d135653..b467952 100644
--- a/src/remote/remote_protocol.x
+++ b/src/remote/remote_protocol.x
@@ -1073,6 +1073,18 @@ struct remote_domain_block_pull_args {
unsigned int flags;
};
+struct remote_domain_set_block_io_throttle_args {
+ remote_nonnull_domain dom;
+ remote_nonnull_string disk;
+ unsigned hyper bps;
+ unsigned hyper bps_rd;
+ unsigned hyper bps_wr;
+ unsigned hyper iops;
+ unsigned hyper iops_rd;
+ unsigned hyper iops_wr;
+ unsigned int flags;
+};
+
/* Network calls: */
struct remote_num_of_networks_ret {
@@ -2555,7 +2567,8 @@ enum remote_procedure {
REMOTE_PROC_DOMAIN_RESET = 245, /* autogen autogen */
REMOTE_PROC_DOMAIN_SNAPSHOT_NUM_CHILDREN = 246, /* autogen autogen priority:high */
REMOTE_PROC_DOMAIN_SNAPSHOT_LIST_CHILDREN_NAMES = 247, /* autogen autogen priority:high */
- REMOTE_PROC_DOMAIN_EVENT_DISK_CHANGE = 248 /* skipgen skipgen */
+ REMOTE_PROC_DOMAIN_EVENT_DISK_CHANGE = 248, /* skipgen skipgen */
+ REMOTE_PROC_DOMAIN_SET_BLOCK_IO_THROTTLE = 249, /* skipgen skipgen */
/*
* Notice how the entries are grouped in sets of 10 ?
diff --git a/src/remote_protocol-structs b/src/remote_protocol-structs
index 569fcb3..4f8bcf6 100644
--- a/src/remote_protocol-structs
+++ b/src/remote_protocol-structs
@@ -757,6 +757,17 @@ struct remote_domain_block_pull_args {
uint64_t bandwidth;
u_int flags;
};
+struct remote_domain_set_block_io_throttle_args {
+ remote_nonnull_domain dom;
+ remote_nonnull_string disk;
+ uint64_t bps;
+ uint64_t bps_rd;
+ uint64_t bps_wr;
+ uint64_t iops;
+ uint64_t iops_rd;
+ uint64_t iops_wr;
+ u_int flags;
+};
struct remote_num_of_networks_ret {
int num;
};
@@ -1999,4 +2010,5 @@ enum remote_procedure {
REMOTE_PROC_DOMAIN_SNAPSHOT_NUM_CHILDREN = 246,
REMOTE_PROC_DOMAIN_SNAPSHOT_LIST_CHILDREN_NAMES = 247,
REMOTE_PROC_DOMAIN_EVENT_DISK_CHANGE = 248,
+ REMOTE_PROC_DOMAIN_SET_BLOCK_IO_THROTTLE = 249,
};
--
1.7.1
13 years, 1 month
Re: [libvirt] [libvirt PATCHv4 1/2] add DHCP snooping
by Stefan Berger
David Stevens/Beaverton/IBM wrote on 10/27/2011 02:51:18 PM:
> Stefan Berger <stefanb(a)linux.vnet.ibm.com> wrote on 10/25/2011 05:50:09
AM:
>
> > The below algorithm also seems to assume that the VM does not send
> > 802.1Q (VLAN) headers. I remember having had problems when trying to
> > receive 802.1Q headers when the VM's interface is on a bridge and the
> > remote traffic comes through the network. I wonder whether it generally
> > doesn't work. I think at least in the code you should look at the
> > header, check for ETHERTYPE_IPv4 and then use eh_data[0], otherwise
> > either discard it or if ETHERTYPE_VLAN (0x8100) is used read the
> > encapsulated protocol ID and make sure ETHERTYPE_IPv4 is found there
and
> > then use eh_data[4] for further processing.
>
> Stefan,
> I added code similar to what you had, but when trying to test it,
> I realized that this cannot work with the existing filters. It appears
> to me that if a VLAN header is present, that packet won't match any of
> the protocols supported and will be dropped (ETHERTYPE_VLAN won't match
> IPv4, ARP, RARP, etc). If so, then decoding a VLAN DHCP ACK does no good
So that sounds like an ebtables problem then not being able to handle
ethernet packets with a VLAN header.
> because the VM will never see it, and the rules will never even check a
> source IP address for a packet that ebtables won't match as an IP packet.
> Right?
You're right. Implementation-wise I still think you should look at the
Ethernet header and
check for ETHERTYPE_IPV4 to get the offset for the payload and for now skip
all other types
of packets. One could setup VMs on the same host, have their interfaces
connected to a bridge
and have them talk via VLAN and possibly provoke errors in the packet
parser(s).
The conclusion is that VMs sending VLAN traffic themselves is not
supported. If a bridge has
a VLAN interface of the host for sending/receiving VLAN traffic to/from the
physical
network, the filtering still works as expected.
>
> I saw later your post for VLAN filtering. I haven't played with
> vlans much, and especially not with ebtables filtering of vlans. If
> we cannot apply the higher-layer protocol rules without making a
> complete copy of all of them for VLANs, then I'm not sure I see the
> point in having address learning decode VLAN headers.
That's fine then.
> For the "no spoofing" case, allowing all VLAN packets is clearly
> not right, so it appears to me that the current nwfilters simply do
> not support the presence of VLANs.
Yes, VLAN traffic directly from the VM is not supported with the example
filters and has limitations when trying to evaluate the packets. The VLAN
support I posted can serve other purposes.
> I can leave the current (untested) address matching checks in. It
> doesn't hurt the non-VLAN case, if you see some way of adding full VLAN
> no-spoofing support in the future. But unless I'm missing something, it
> doesn't look to me like the VLAN case works at all now and not supporting
> that in DHCP snooping is not a new problem.
Agreed.
Stefan
>
> +-DLS
13 years, 1 month
[libvirt] [libvirt PATCHv4 0/2] DHCP Snooping support for libvirt
by David L Stevens
These patches add DHCP snooping support to libvirt. The learning method for
IP addresses is specified by setting the "ip_learning" variable to one of
"any" [default] (existing IP learning code), "none" (static only addresses)
or "dhcp" (DHCP snooping).
Differences from v3: removed support for multiple IP addresses. This version,
like this existing code, allows only one IP address per interface.
David L Stevens (2):
add DHCP snooping
add leasefile support
examples/xml/nwfilter/no-ip-spoofing.xml | 5 +
src/Makefile.am | 2 +
src/nwfilter/nwfilter_dhcpsnoop.c | 1005 ++++++++++++++++++++++++++++++
src/nwfilter/nwfilter_dhcpsnoop.h | 38 ++
src/nwfilter/nwfilter_driver.c | 5 +
src/nwfilter/nwfilter_gentech_driver.c | 51 ++-
6 files changed, 1093 insertions(+), 13 deletions(-)
create mode 100644 src/nwfilter/nwfilter_dhcpsnoop.c
create mode 100644 src/nwfilter/nwfilter_dhcpsnoop.h
--
1.7.6.4
13 years, 1 month