[libvirt] [PATCH v2] virsh: Add more human-friendly output of domblkstat command
by Peter Krempa
Users of virsh complain that output of the domblkstat command
is not intuitive enough. This patch adds explanation of fields
returned by this command to the help section for domblkstat and
the man page of virsh. Also a switch --human is added for
domblkstat that prints the fields with more descriptive texts.
https://bugzilla.redhat.com/show_bug.cgi?id=731656
Changes to v1:
-Rebased to current head
---
tools/virsh.c | 52 +++++++++++++++++++++++++++++++++++++++++-----------
tools/virsh.pod | 11 ++++++++++-
2 files changed, 51 insertions(+), 12 deletions(-)
diff --git a/tools/virsh.c b/tools/virsh.c
index c7240e5..09337cb 100644
--- a/tools/virsh.c
+++ b/tools/virsh.c
@@ -1054,13 +1054,21 @@ cleanup:
*/
static const vshCmdInfo info_domblkstat[] = {
{"help", N_("get device block stats for a domain")},
- {"desc", N_("Get device block stats for a running domain.")},
+ {"desc", N_("Get device block stats for a running domain.\n\n"
+ " Explanation of fields:\n"
+ " rd_req - count of read requests\n"
+ " rd_bytes - count of read bytes\n"
+ " wr_req - count of write requests\n"
+ " wr_bytes - count of written bytes\n"
+ " errs - error count")},
{NULL,NULL}
};
static const vshCmdOptDef opts_domblkstat[] = {
{"domain", VSH_OT_DATA, VSH_OFLAG_REQ, N_("domain name, id or uuid")},
{"device", VSH_OT_DATA, VSH_OFLAG_REQ, N_("block device")},
+ {"human", VSH_OT_BOOL, 0, N_("print a more human readable output")},
+
{NULL, 0, 0, NULL}
};
@@ -1070,6 +1078,7 @@ cmdDomblkstat (vshControl *ctl, const vshCmd *cmd)
virDomainPtr dom;
const char *name = NULL, *device = NULL;
struct _virDomainBlockStats stats;
+ int humanReadable = vshCommandOptBool(cmd, "human");
if (!vshConnectionUsability (ctl, ctl->conn))
return false;
@@ -1088,20 +1097,41 @@ cmdDomblkstat (vshControl *ctl, const vshCmd *cmd)
return false;
}
- if (stats.rd_req >= 0)
- vshPrint (ctl, "%s rd_req %lld\n", device, stats.rd_req);
+ if (humanReadable) {
+ /* human friendly output */
+ vshPrint(ctl, N_("Device: %s\n"), device);
+
+ if (stats.rd_req >= 0)
+ vshPrint (ctl, N_("read request count: %lld\n"), stats.rd_req);
+
+ if (stats.rd_bytes >= 0)
+ vshPrint (ctl, N_("number of read bytes: %lld\n"), stats.rd_bytes);
+
+ if (stats.wr_req >= 0)
+ vshPrint (ctl, N_("write request count: %lld\n"), stats.wr_req);
- if (stats.rd_bytes >= 0)
- vshPrint (ctl, "%s rd_bytes %lld\n", device, stats.rd_bytes);
+ if (stats.wr_bytes >= 0)
+ vshPrint (ctl, N_("number of written bytes: %lld\n"), stats.wr_bytes);
- if (stats.wr_req >= 0)
- vshPrint (ctl, "%s wr_req %lld\n", device, stats.wr_req);
+ if (stats.errs >= 0)
+ vshPrint (ctl, N_("error count: %lld\n"), stats.errs);
+ } else {
+ /* script friendly output */
+ if (stats.rd_req >= 0)
+ vshPrint (ctl, "%s rd_req %lld\n", device, stats.rd_req);
+
+ if (stats.rd_bytes >= 0)
+ vshPrint (ctl, "%s rd_bytes %lld\n", device, stats.rd_bytes);
- if (stats.wr_bytes >= 0)
- vshPrint (ctl, "%s wr_bytes %lld\n", device, stats.wr_bytes);
+ if (stats.wr_req >= 0)
+ vshPrint (ctl, "%s wr_req %lld\n", device, stats.wr_req);
- if (stats.errs >= 0)
- vshPrint (ctl, "%s errs %lld\n", device, stats.errs);
+ if (stats.wr_bytes >= 0)
+ vshPrint (ctl, "%s wr_bytes %lld\n", device, stats.wr_bytes);
+
+ if (stats.errs >= 0)
+ vshPrint (ctl, "%s errs %lld\n", device, stats.errs);
+ }
virDomainFree(dom);
return true;
diff --git a/tools/virsh.pod b/tools/virsh.pod
index 30c0721..c333b2a 100644
--- a/tools/virsh.pod
+++ b/tools/virsh.pod
@@ -501,10 +501,19 @@ be lost once the guest stops running, but the snapshot contents still
exist, and a new domain with the same name and UUID can restore the
snapshot metadata with B<snapshot-create>.
-=item B<domblkstat> I<domain> I<block-device>
+=item B<domblkstat> I<domain> I<block-device> [I<--human>]
Get device block stats for a running domain.
+Use I<--human> for a more human readable output.
+
+B<Explanation of fields:>
+ rd_req - count of read requests
+ rd_bytes - count of read bytes
+ wr_req - count of write requests
+ wr_bytes - count of written bytes
+ errs - error count
+
=item B<domifstat> I<domain> I<interface-device>
Get network interface stats for a running domain.
--
1.7.3.4
13 years, 2 months
[libvirt] [PATCH RFC 0/2] XML: Improve XML parse error reporting
by Peter Krempa
First patch modifies the error reporting function on parse errors of XML files.
A new, more informative message is presented to the user, containing filename
of the offending file, error description and context of the error in libxml2
style.
Second patch changes default filenames used while parsing XML strings in memory
to NULL, so that the error reporting function does not print bougus filename.
src/conf/domain_conf.c - change "domain.xml" to NULL
src/security/virt-aa-helper.c - change "domain.xml" to NULL
src/util/xml.c - modify error reporting function
Peter Krempa (2):
XML: Improve XML parsing error messages
XML: Suppress printing "domain.xml" for parse errors on XML strings
src/conf/domain_conf.c | 2 +-
src/security/virt-aa-helper.c | 2 +-
src/util/xml.c | 88 +++++++++++++++++++++++++++++++++++------
3 files changed, 78 insertions(+), 14 deletions(-)
--
1.7.3.4
13 years, 2 months
[libvirt] [PATCH v3 0/5] Virtual interface link state modification
by Peter Krempa
This patchset adds the ability for libvirt users to control interface
link state of the virtual network devices provided by hypervisors.
Modification of the link state is accomplished by adding a new XML
element <link state"up"> or "down" to the domain XML. The corresponding
network interface is thereafter initialised with the desired state.
Live modification of the link state is achieved by calling
virDomainUpdateDeviceFlags containing a modified interface configuration.
Yet, users may modify only link state of an interface.
This feature allows propagation of network topology changes to guests,
testing scenarios in complex virtual networks, etc ...
Future upgrade:
- add support for VirtualBox
Modifications to v2:
- Rebase to curent HEAD
Modifications to v1:
- use virUpdateDeviceFlags instead of dedicated API
- incorporate helpful comments by Eric Blake
https://bugzilla.redhat.com/show_bug.cgi?id=643373
Peter Krempa (5):
link-state: util: Add equality comparision functions for structures
link-state: conf: Add element to XML for controling link state
link-state: qemu: Add monitor handling for link state modification
link-state: qemu: Add net intf modification to virUpdateDeviceFlags
link-state: virsh: Add wrapper commands for changing link state
docs/formatdomain.html.in | 21 +++
docs/schemas/network.rng | 11 ++
src/conf/domain_conf.c | 24 ++++
src/conf/domain_conf.h | 11 ++
src/qemu/qemu_driver.c | 24 ++++
src/qemu/qemu_hotplug.c | 176 ++++++++++++++++++++++++++
src/qemu/qemu_hotplug.h | 8 ++
src/qemu/qemu_monitor.c | 19 +++
src/qemu/qemu_monitor.h | 4 +
src/qemu/qemu_monitor_json.c | 23 ++++
src/qemu/qemu_monitor_json.h | 4 +
src/qemu/qemu_monitor_text.c | 46 +++++++
src/qemu/qemu_monitor_text.h | 4 +
src/qemu/qemu_process.c | 47 +++++++-
src/util/network.c | 62 +++++++++
src/util/network.h | 5 +
tools/virsh.c | 286 ++++++++++++++++++++++++++++++++++++++++++
tools/virsh.pod | 11 ++
18 files changed, 785 insertions(+), 1 deletions(-)
--
1.7.3.4
13 years, 2 months
[libvirt] [PATCH] redirdev: allows to specify device address
by Marc-André Lureau
It is important to be able to attach USB redirected devices to a
particular controller (one that supports USB2 for instance).
Without this patch, only the default bus was used.
<redirdev bus='usb' type='spicevmc'>
<address type='usb' bus='0' port='4'/>
</redirdev>
---
docs/formatdomain.html.in | 19 +++++++++++++------
docs/schemas/domaincommon.rng | 3 +++
src/conf/domain_conf.c | 14 ++++++++++++++
tests/qemuxml2argvdata/qemuxml2argv-usb-redir.args | 2 +-
tests/qemuxml2argvdata/qemuxml2argv-usb-redir.xml | 1 +
5 files changed, 32 insertions(+), 7 deletions(-)
diff --git a/docs/formatdomain.html.in b/docs/formatdomain.html.in
index b960381..399388f 100644
--- a/docs/formatdomain.html.in
+++ b/docs/formatdomain.html.in
@@ -1417,14 +1417,21 @@
tunnel; <code>type='tcp'</code>
or <code>type='spicevmc'</code> (which uses the usbredir
channel of a <a href="#elementsGraphics">SPICE graphics
- device</a>) are typical. Further sub-elements, such
- as <code><source></code>, may be required according to
- the given type, although a <code><target></code>
- sub-element is not required (since the consumer of the
- character device is the hypervisor itself, rather than a
- device visible in the guest).</dd>
+ device</a>) are typical.</dd>
</dl>
+ <p>
+ The redirdev element has an optional sub-element
+ <code><address></code> which can tie the device to a
+ particular controller.
+ </p>
+ <p>
+ Further sub-elements, such as <code><source></code>, may
+ be required according to the given type, although
+ a <code><target></code> sub-element is not required (since
+ the consumer of the character device is the hypervisor itself,
+ rather than a device visible in the guest).
+ </p>
<h4><a name="elementsSmartcard">Smartcard devices</a></h4>
diff --git a/docs/schemas/domaincommon.rng b/docs/schemas/domaincommon.rng
index 8e7fd63..02c3c7f 100644
--- a/docs/schemas/domaincommon.rng
+++ b/docs/schemas/domaincommon.rng
@@ -1986,6 +1986,9 @@
<ref name="qemucdevSrcTypeChoice"/>
</attribute>
<ref name="qemucdevSrcDef"/>
+ <optional>
+ <ref name="address"/>
+ </optional>
</element>
</define>
<define name="hostdev">
diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c
index cce9955..706f445 100644
--- a/src/conf/domain_conf.c
+++ b/src/conf/domain_conf.c
@@ -5518,6 +5518,18 @@ virDomainRedirdevDefParseXML(const xmlNodePtr node,
def->source.chr.data.spicevmc = VIR_DOMAIN_CHR_SPICEVMC_USBREDIR;
}
+ if (virDomainDeviceInfoParseXML(node, &def->info, flags) < 0)
+ goto error;
+
+ if (def->bus == VIR_DOMAIN_REDIRDEV_BUS_USB &&
+ def->info.type != VIR_DOMAIN_DEVICE_ADDRESS_TYPE_NONE &&
+ def->info.type != VIR_DOMAIN_DEVICE_ADDRESS_TYPE_USB) {
+ virDomainReportError(VIR_ERR_XML_ERROR, "%s",
+ _("Invalid address for a USB device"));
+ goto error;
+ }
+
+
cleanup:
VIR_FREE(bus);
VIR_FREE(type);
@@ -10274,6 +10286,8 @@ virDomainRedirdevDefFormat(virBufferPtr buf,
virBufferAsprintf(buf, " <redirdev bus='%s'", bus);
if (virDomainChrSourceDefFormat(buf, &def->source.chr, false, flags) < 0)
return -1;
+ if (virDomainDeviceInfoFormat(buf, &def->info, flags) < 0)
+ return -1;
virBufferAddLit(buf, " </redirdev>\n");
return 0;
diff --git a/tests/qemuxml2argvdata/qemuxml2argv-usb-redir.args b/tests/qemuxml2argvdata/qemuxml2argv-usb-redir.args
index 4d4f30a..f6270d5 100644
--- a/tests/qemuxml2argvdata/qemuxml2argv-usb-redir.args
+++ b/tests/qemuxml2argvdata/qemuxml2argv-usb-redir.args
@@ -6,5 +6,5 @@ LC_ALL=C PATH=/bin HOME=/home/test USER=test LOGNAME=test /usr/bin/qemu -S -M pc
-chardev socket,id=charredir0,host=localhost,port=4000 \
-device usb-redir,chardev=charredir0,id=redir0 \
-chardev spicevmc,id=charredir1,name=usbredir \
--device usb-redir,chardev=charredir1,id=redir1 \
+-device usb-redir,chardev=charredir1,id=redir1,bus=usb.0,port=4 \
-device virtio-balloon-pci,id=balloon0,bus=pci.0,multifunction=on,addr=0x3.0x0
diff --git a/tests/qemuxml2argvdata/qemuxml2argv-usb-redir.xml b/tests/qemuxml2argvdata/qemuxml2argv-usb-redir.xml
index c73e569..1dac3fb 100644
--- a/tests/qemuxml2argvdata/qemuxml2argv-usb-redir.xml
+++ b/tests/qemuxml2argvdata/qemuxml2argv-usb-redir.xml
@@ -34,6 +34,7 @@
<protocol type='raw'/>
</redirdev>
<redirdev bus='usb' type='spicevmc'>
+ <address type='usb' bus='0' port='4'/>
</redirdev>
<memballoon model='virtio'/>
</devices>
--
1.7.6
13 years, 2 months
[libvirt] [PATCH 0/8 v2] Report disk latency info
by Osier Yang
This patch series introduces a new API to report the disk latency
related information, which is supported by upstream QEMU just a
few days ago (commit c488c7f649, Thu Aug 25).
Per previous dicussion on the ABI compatiblity, and API design
principle, the new API is defined with style:
int virDomainBlockStatsFlags (virDomainPtr dom,
const char *path,
virTypeParamsPtr params,
int *nparams,
unsigned int flags)
V1 - V2:
* Use virTypedParameter instead of creating a new struct for the
new API.
* Update comments for the API, (Eric's suggestion).
[PATCH 1/8] latency: Define new public API and structure
[PATCH 2/8] latency: Define the internal driver callback
[PATCH 3/8] latency: Implemente the public API
[PATCH 4/8] latency: Wire up the remote protocol
[PATCH 5/8] latency: Update monitor functions for new latency fields
[PATCH 6/8] latency: Implemente internal API for qemu driver
[PATCH 7/8] latency: Expose the new API for Python binding
[PATCH 8/8] latency: Update cmdBlkStats to use new API
Regards,
Osier
13 years, 2 months
[libvirt] [PATCH 1/2] make remote_exec_pexpect return the output of command
by Guannan Ren
*utils/Python/utils.py return 0,child.before intead
*repos/remoteAccess/tcp_setup.py repos/remoteAccess/tls_setup.py
switch over to use new remote_exec_pexpect()
---
repos/remoteAccess/tcp_setup.py | 18 +++++++++---------
repos/remoteAccess/tls_setup.py | 20 ++++++++++----------
utils/Python/utils.py | 4 ++--
3 files changed, 21 insertions(+), 21 deletions(-)
diff --git a/repos/remoteAccess/tcp_setup.py b/repos/remoteAccess/tcp_setup.py
index 8f88810..b3877f7 100644
--- a/repos/remoteAccess/tcp_setup.py
+++ b/repos/remoteAccess/tcp_setup.py
@@ -56,7 +56,7 @@ def sasl_user_add(target_machine, username, password, util, logger):
""" execute saslpasswd2 to add sasl user """
logger.info("add sasl user on server side")
saslpasswd2_add = "echo %s | %s -a libvirt %s" % (password, SASLPASSWD2, username)
- ret = util.remote_exec_pexpect(target_machine, username,
+ ret, output = util.remote_exec_pexpect(target_machine, username,
password, saslpasswd2_add)
if ret:
logger.error("failed to add sasl user")
@@ -70,7 +70,7 @@ def tcp_libvirtd_set(target_machine, username, password,
logger.info("setting libvirtd.conf on libvirt server")
# open libvirtd --listen option
listen_open_cmd = "echo 'LIBVIRTD_ARGS=\"--listen\"' >> %s" % SYSCONFIG_LIBVIRTD
- ret = util.remote_exec_pexpect(target_machine, username,
+ ret, output = util.remote_exec_pexpect(target_machine, username,
password, listen_open_cmd)
if ret:
logger.error("failed to uncomment --listen in %s" % SYSCONFIG_LIBVIRTD)
@@ -79,7 +79,7 @@ def tcp_libvirtd_set(target_machine, username, password,
# set listen_tls
logger.info("set listen_tls to 0 in %s" % LIBVIRTD_CONF)
listen_tls_disable = "echo \"listen_tls = 0\" >> %s" % LIBVIRTD_CONF
- ret = util.remote_exec_pexpect(target_machine, username,
+ ret, output = util.remote_exec_pexpect(target_machine, username,
password, listen_tls_disable)
if ret:
logger.error("failed to set listen_tls to 0 in %s" % LIBVIRTD_CONF)
@@ -89,7 +89,7 @@ def tcp_libvirtd_set(target_machine, username, password,
if listen_tcp == 'enable':
logger.info("enable listen_tcp = 1 in %s" % LIBVIRTD_CONF)
listen_tcp_set = "echo 'listen_tcp = 1' >> %s" % LIBVIRTD_CONF
- ret = util.remote_exec_pexpect(target_machine, username,
+ ret, output = util.remote_exec_pexpect(target_machine, username,
password, listen_tcp_set)
if ret:
logger.error("failed to set listen_tcp in %s" % LIBVIRTD_CONF)
@@ -98,7 +98,7 @@ def tcp_libvirtd_set(target_machine, username, password,
# set auth_tcp
logger.info("set auth_tcp to \"%s\" in %s" % (auth_tcp, LIBVIRTD_CONF))
auth_tcp_set = "echo 'auth_tcp = \"%s\"' >> %s" % (auth_tcp, LIBVIRTD_CONF)
- ret = util.remote_exec_pexpect(target_machine, username,
+ ret, output = util.remote_exec_pexpect(target_machine, username,
password, auth_tcp_set)
if ret:
logger.error("failed to set auth_tcp in %s" % LIBVIRTD_CONF)
@@ -107,7 +107,7 @@ def tcp_libvirtd_set(target_machine, username, password,
# restart remote libvirtd service
libvirtd_restart_cmd = "service libvirtd restart"
logger.info("libvirtd restart")
- ret = util.remote_exec_pexpect(target_machine, username,
+ ret, output = util.remote_exec_pexpect(target_machine, username,
password, libvirtd_restart_cmd)
if ret:
logger.error("failed to restart libvirtd service")
@@ -225,18 +225,18 @@ def tcp_setup_clean(params):
if auth_tcp == 'sasl':
saslpasswd2_delete = "%s -a libvirt -d %s" % (SASLPASSWD2, username)
- ret = util.remote_exec_pexpect(target_machine, username,
+ ret, output = util.remote_exec_pexpect(target_machine, username,
password, saslpasswd2_delete)
if ret:
logger.error("failed to delete sasl user")
libvirtd_conf_retore = "sed -i -n '/^[ #]/p' %s" % LIBVIRTD_CONF
- ret = util.remote_exec_pexpect(target_machine, username,
+ ret, output = util.remote_exec_pexpect(target_machine, username,
password, libvirtd_conf_retore)
if ret:
logger.error("failed to restore %s" % LIBVIRTD_CONF)
sysconfig_libvirtd_restore = "sed -i -n '/^[ #]/p' %s" % SYSCONFIG_LIBVIRTD
- ret = util.remote_exec_pexpect(target_machine, username,
+ ret, output = util.remote_exec_pexpect(target_machine, username,
password, sysconfig_libvirtd_restore)
if ret:
logger.error("failed to restore %s" % SYSCONFIG_LIBVIRTD)
diff --git a/repos/remoteAccess/tls_setup.py b/repos/remoteAccess/tls_setup.py
index 4e7f24e..27bb8a7 100644
--- a/repos/remoteAccess/tls_setup.py
+++ b/repos/remoteAccess/tls_setup.py
@@ -213,7 +213,7 @@ def deliver_cert(target_machine, username, password, pkipath, util, logger):
# mkdir /etc/pki/libvirt/private on remote host
libvirt_priv_cmd = "mkdir -p %s" % PRIVATE_KEY_FOLDER
- ret = util.remote_exec_pexpect(target_machine, username, password, libvirt_priv_cmd)
+ ret, output = util.remote_exec_pexpect(target_machine, username, password, libvirt_priv_cmd)
if ret:
logger.error("failed to make /etc/pki/libvirt/private on %s" % target_machine)
return 1
@@ -257,7 +257,7 @@ def sasl_user_add(target_machine, username, password, util, logger):
""" execute saslpasswd2 to add sasl user """
logger.info("add sasl user on server side")
saslpasswd2_add = "echo %s | %s -a libvirt %s" % (password, SASLPASSWD2, username)
- ret = util.remote_exec_pexpect(target_machine, username,
+ ret, output = util.remote_exec_pexpect(target_machine, username,
password, saslpasswd2_add)
if ret:
logger.error("failed to add sasl user")
@@ -271,7 +271,7 @@ def tls_libvirtd_set(target_machine, username, password,
logger.info("setting libvirtd.conf on tls server")
# open libvirtd --listen option
listen_open_cmd = "echo 'LIBVIRTD_ARGS=\"--listen\"' >> /etc/sysconfig/libvirtd"
- ret = util.remote_exec_pexpect(target_machine, username,
+ ret, output = util.remote_exec_pexpect(target_machine, username,
password, listen_open_cmd)
if ret:
logger.error("failed to uncomment --listen in /etc/sysconfig/libvirtd")
@@ -280,7 +280,7 @@ def tls_libvirtd_set(target_machine, username, password,
if listen_tls == 'disable':
logger.info("set listen_tls to 0 in %s" % LIBVIRTD_CONF)
listen_tls_disable = "echo \"listen_tls = 0\" >> %s" % LIBVIRTD_CONF
- ret = util.remote_exec_pexpect(target_machine, username,
+ ret, output = util.remote_exec_pexpect(target_machine, username,
password, listen_tls_disable)
if ret:
logger.error("failed to set listen_tls to 0 in %s" % LIBVIRTD_CONF)
@@ -289,7 +289,7 @@ def tls_libvirtd_set(target_machine, username, password,
if auth_tls == 'sasl':
logger.info("enable auth_tls = sasl in %s" % LIBVIRTD_CONF)
auth_tls_set = "echo 'auth_tls = \"sasl\"' >> %s" % LIBVIRTD_CONF
- ret = util.remote_exec_pexpect(target_machine, username,
+ ret, output = util.remote_exec_pexpect(target_machine, username,
password, auth_tls_set)
if ret:
logger.error("failed to set auth_tls to sasl in %s" % LIBVIRTD_CONF)
@@ -298,7 +298,7 @@ def tls_libvirtd_set(target_machine, username, password,
# restart remote libvirtd service
libvirtd_restart_cmd = "service libvirtd restart"
logger.info("libvirtd restart")
- ret = util.remote_exec_pexpect(target_machine, username,
+ ret, output = util.remote_exec_pexpect(target_machine, username,
password, libvirtd_restart_cmd)
if ret:
logger.error("failed to restart libvirtd service")
@@ -311,7 +311,7 @@ def iptables_stop(target_machine, username, password, util, logger):
""" This is a temprory method in favor of migration """
logger.info("stop local and remote iptables temprorily")
iptables_stop_cmd = "service iptables stop"
- ret = util.remote_exec_pexpect(target_machine, username,
+ ret, output = util.remote_exec_pexpect(target_machine, username,
password, iptables_stop_cmd)
if ret:
logger.error("failed to stop remote iptables service")
@@ -466,13 +466,13 @@ def tls_setup_clean(params):
util = utils.Utils()
cacert_rm = "rm -f %s/cacert.pem" % CA_FOLDER
- ret = util.remote_exec_pexpect(target_machine, username,
+ ret, output = util.remote_exec_pexpect(target_machine, username,
password, cacert_rm)
if ret:
logger.error("failed to remove cacert.pem on remote machine")
ca_libvirt_rm = "rm -rf %s" % CERTIFICATE_FOLDER
- ret = util.remote_exec_pexpect(target_machine, username,
+ ret, output = util.remote_exec_pexpect(target_machine, username,
password, ca_libvirt_rm)
if ret:
logger.error("failed to remove libvirt folder")
@@ -482,7 +482,7 @@ def tls_setup_clean(params):
if auth_tls == 'sasl':
saslpasswd2_delete = "%s -a libvirt -d %s" % (SASLPASSWD2, username)
- ret = util.remote_exec_pexpect(target_machine, username,
+ ret, output = util.remote_exec_pexpect(target_machine, username,
password, saslpasswd2_delete)
if ret:
logger.error("failed to delete sasl user")
diff --git a/utils/Python/utils.py b/utils/Python/utils.py
index 6787e87..d521254 100644
--- a/utils/Python/utils.py
+++ b/utils/Python/utils.py
@@ -406,10 +406,10 @@ class Utils(object):
child.sendline(password)
elif index == 2:
child.close()
- return 0
+ return 0, child.before
elif index == 3:
child.close()
- return 1
+ return 1, ""
return 0
--
1.7.1
13 years, 2 months
[libvirt] [test-API][PATCH 1/2] Remove cases/migrate.conf testcases and create a set of migration testcases
by Guannan Ren
*cases/migrate.conf remove it.
*cases/migration/* create a new set of migraion testcases with
tcp, tls and sasl combination
It's huge, so I send the header of commit here.
---
cases/migrate.conf | 97 ----
cases/migration/ssh_persistent_paused_no_dst.conf | 459 +++++++++++++++++++
.../migration/ssh_persistent_paused_with_dst.conf | 459 +++++++++++++++++++
cases/migration/ssh_persistent_running_no_dst.conf | 435 ++++++++++++++++++
.../migration/ssh_persistent_running_with_dst.conf | 435 ++++++++++++++++++
cases/migration/ssh_transient_paused_no_dst.conf | 403 +++++++++++++++++
cases/migration/ssh_transient_paused_with_dst.conf | 403 +++++++++++++++++
cases/migration/ssh_transient_running_no_dst.conf | 388 ++++++++++++++++
.../migration/ssh_transient_running_with_dst.conf | 382 ++++++++++++++++
cases/migration/tcp_persistent_paused_no_dst.conf | 471 ++++++++++++++++++++
.../migration/tcp_persistent_paused_with_dst.conf | 471 ++++++++++++++++++++
cases/migration/tcp_persistent_running_no_dst.conf | 447 +++++++++++++++++++
.../migration/tcp_persistent_running_with_dst.conf | 447 +++++++++++++++++++
.../tcp_sasl_persistent_paused_no_dst.conf | 167 +++++++
.../tcp_sasl_persistent_paused_with_dst.conf | 168 +++++++
.../tcp_sasl_persistent_running_no_dst.conf | 159 +++++++
.../tcp_sasl_persistent_running_with_dst.conf | 159 +++++++
.../tcp_sasl_transient_paused_no_dst.conf | 151 +++++++
.../tcp_sasl_transient_paused_with_dst.conf | 151 +++++++
.../tcp_sasl_transient_running_no_dst.conf | 143 ++++++
.../tcp_sasl_transient_running_with_dst.conf | 143 ++++++
cases/migration/tcp_transient_paused_no_dst.conf | 415 +++++++++++++++++
cases/migration/tcp_transient_paused_with_dst.conf | 415 +++++++++++++++++
cases/migration/tcp_transient_running_no_dst.conf | 400 +++++++++++++++++
.../migration/tcp_transient_running_with_dst.conf | 394 ++++++++++++++++
cases/migration/tls_persistent_paused_no_dst.conf | 471 ++++++++++++++++++++
.../migration/tls_persistent_paused_with_dst.conf | 471 ++++++++++++++++++++
cases/migration/tls_persistent_running_no_dst.conf | 447 +++++++++++++++++++
.../migration/tls_persistent_running_with_dst.conf | 447 +++++++++++++++++++
.../tls_sasl_persistent_paused_no_dst.conf | 167 +++++++
.../tls_sasl_persistent_paused_with_dst.conf | 167 +++++++
.../tls_sasl_persistent_running_no_dst.conf | 159 +++++++
.../tls_sasl_persistent_running_with_dst.conf | 159 +++++++
.../tls_sasl_transient_paused_no_dst.conf | 151 +++++++
.../tls_sasl_transient_paused_with_dst.conf | 151 +++++++
.../tls_sasl_transient_running_no_dst.conf | 143 ++++++
.../tls_sasl_transient_running_with_dst.conf | 143 ++++++
cases/migration/tls_transient_paused_no_dst.conf | 415 +++++++++++++++++
cases/migration/tls_transient_paused_with_dst.conf | 415 +++++++++++++++++
cases/migration/tls_transient_running_no_dst.conf | 400 +++++++++++++++++
.../migration/tls_transient_running_with_dst.conf | 394 ++++++++++++++++
41 files changed, 12765 insertions(+), 97 deletions(-)
delete mode 100644 cases/migrate.conf
create mode 100644 cases/migration/ssh_persistent_paused_no_dst.conf
create mode 100644 cases/migration/ssh_persistent_paused_with_dst.conf
create mode 100644 cases/migration/ssh_persistent_running_no_dst.conf
create mode 100644 cases/migration/ssh_persistent_running_with_dst.conf
create mode 100644 cases/migration/ssh_transient_paused_no_dst.conf
create mode 100644 cases/migration/ssh_transient_paused_with_dst.conf
create mode 100644 cases/migration/ssh_transient_running_no_dst.conf
create mode 100644 cases/migration/ssh_transient_running_with_dst.conf
create mode 100644 cases/migration/tcp_persistent_paused_no_dst.conf
create mode 100644 cases/migration/tcp_persistent_paused_with_dst.conf
create mode 100644 cases/migration/tcp_persistent_running_no_dst.conf
create mode 100644 cases/migration/tcp_persistent_running_with_dst.conf
create mode 100644 cases/migration/tcp_sasl_persistent_paused_no_dst.conf
create mode 100644 cases/migration/tcp_sasl_persistent_paused_with_dst.conf
create mode 100644 cases/migration/tcp_sasl_persistent_running_no_dst.conf
create mode 100644 cases/migration/tcp_sasl_persistent_running_with_dst.conf
create mode 100644 cases/migration/tcp_sasl_transient_paused_no_dst.conf
create mode 100644 cases/migration/tcp_sasl_transient_paused_with_dst.conf
create mode 100644 cases/migration/tcp_sasl_transient_running_no_dst.conf
create mode 100644 cases/migration/tcp_sasl_transient_running_with_dst.conf
create mode 100644 cases/migration/tcp_transient_paused_no_dst.conf
create mode 100644 cases/migration/tcp_transient_paused_with_dst.conf
create mode 100644 cases/migration/tcp_transient_running_no_dst.conf
create mode 100644 cases/migration/tcp_transient_running_with_dst.conf
create mode 100644 cases/migration/tls_persistent_paused_no_dst.conf
create mode 100644 cases/migration/tls_persistent_paused_with_dst.conf
create mode 100644 cases/migration/tls_persistent_running_no_dst.conf
create mode 100644 cases/migration/tls_persistent_running_with_dst.conf
create mode 100644 cases/migration/tls_sasl_persistent_paused_no_dst.conf
create mode 100644 cases/migration/tls_sasl_persistent_paused_with_dst.conf
create mode 100644 cases/migration/tls_sasl_persistent_running_no_dst.conf
create mode 100644 cases/migration/tls_sasl_persistent_running_with_dst.conf
create mode 100644 cases/migration/tls_sasl_transient_paused_no_dst.conf
create mode 100644 cases/migration/tls_sasl_transient_paused_with_dst.conf
create mode 100644 cases/migration/tls_sasl_transient_running_no_dst.conf
create mode 100644 cases/migration/tls_sasl_transient_running_with_dst.conf
create mode 100644 cases/migration/tls_transient_paused_no_dst.conf
create mode 100644 cases/migration/tls_transient_paused_with_dst.conf
create mode 100644 cases/migration/tls_transient_running_no_dst.conf
create mode 100644 cases/migration/tls_transient_running_with_dst.conf
13 years, 2 months
[libvirt] [PATCH 0/3] Libvirt RPC dispatching and unresponsive QEMU
by Michal Privoznik
If there is an unresponsive qemu process and libvirt access
it's monitor, it will not get any response and this thread will
block indefinitely, until the qemu process resumes or it's destroyed.
If users continues executing APIs against that domain, libvirt will
run out of worker threads and hangs (if those APIs will access
monitor as well). Although, they will timeout in approx 30 seconds,
which will free some workers, during that time is libvirt unable to
process any request. Even worse - if the number of unresponsive qemu
exceeds the size of worker thread pool, libvirt will hangs forever,
and even restarting the daemon will not make it any better.
This patch set heals the daemon on several levels, so nothing from
written above will cause it to hangs:
1. RPC dispatching - all APIs are now annotated as 'high' or 'low'
priority. Then a special thread pool is created. Low priority
APIs will be still placed into usual pool, but high priority
can be placed into this new pool if the former has no free worker.
Which APIs should be marked high and which low? The splitting
presented here is my guessing. It is not something written in stone,
but from the logic of things it is not safe to annotate any
API which is NOT guaranteed to end in reasonable small time as
high priority call.
2. Job queue size limit - this sets bound on the number of threads
blocked by a stuck qemu. Okay, there exists timeout on this,
but if user application continue dispatching low priority calls
it can still consume all (low priority) worker threads and therefore
affect other users/VMs. Even if they timeout in approx 30 secs.
3. Run monitor re-connect in a separate thread per VM.
If libvirtd is restarted, it tries to reconnect to all running
qemu processes. This is potentially risky - one stuck qemu
block daemon startup. However, putting the monitor startup code
into one thread per VM allows libvirtd to startup, accept client
connections and work with all VMs which monitor was successfully
re-opened. Unresponsive qemu will hold job until we open the monitor.
So clever user application can destroy such domain. All APIs
requiring job will just fail in acquiring lock.
Michal Privoznik (3):
daemon: Create priority workers pool
qemu: Introduce job queue size limit
qemu: Deal with stucked qemu on daemon startup
daemon/libvirtd.aug | 1 +
daemon/libvirtd.c | 10 +-
daemon/libvirtd.conf | 6 +
daemon/remote.c | 26 ++
daemon/remote.h | 2 +
src/qemu/libvirtd_qemu.aug | 1 +
src/qemu/qemu.conf | 7 +
src/qemu/qemu_conf.c | 4 +
src/qemu/qemu_conf.h | 2 +
src/qemu/qemu_domain.c | 17 ++
src/qemu/qemu_domain.h | 2 +
src/qemu/qemu_driver.c | 23 +--
src/qemu/qemu_process.c | 89 ++++++-
src/remote/qemu_protocol.x | 13 +-
src/remote/remote_protocol.x | 544 +++++++++++++++++++++---------------------
src/rpc/gendispatch.pl | 48 ++++-
src/rpc/virnetserver.c | 32 +++-
src/rpc/virnetserver.h | 6 +-
src/util/threadpool.c | 38 ++-
src/util/threadpool.h | 1 +
20 files changed, 554 insertions(+), 318 deletions(-)
--
1.7.3.4
13 years, 2 months
[libvirt] [PATCH v2] Source control for storage pool
by Lei Li
Fix bug #611823 storage driver should prohibit pools with duplicate underlying
storage.
Add API virStoragePoolSourceFindDuplicate() to do uniqueness check based on
source location infomation for pool type.
Signed-off-by: Lei Li <lilei(a)linux.vnet.ibm.com>
---
src/conf/storage_conf.c | 80 ++++++++++++++++++++++++++++++++++++++++++
src/conf/storage_conf.h | 5 +++
src/libvirt_private.syms | 2 +
src/storage/storage_driver.c | 6 +++
4 files changed, 93 insertions(+), 0 deletions(-)
diff --git a/src/conf/storage_conf.c b/src/conf/storage_conf.c
index 8d14e87..1e7da69 100644
--- a/src/conf/storage_conf.c
+++ b/src/conf/storage_conf.c
@@ -1311,6 +1311,21 @@ virStoragePoolObjFindByName(virStoragePoolObjListPtr pools,
return NULL;
}
+virStoragePoolObjPtr
+virStoragePoolSourceFindDuplicateDevices(virStoragePoolObjPtr pool,
+ virStoragePoolDefPtr def) {
+ unsigned int i, j;
+
+ for (i = 0; i < pool->def->source.ndevice; i++) {
+ for (j = 0; j < def->source.ndevice; j++) {
+ if (STREQ(pool->def->source.devices[i].path, def->source.devices[j].path))
+ return pool;
+ }
+ }
+
+ return NULL;
+}
+
void
virStoragePoolObjClearVols(virStoragePoolObjPtr pool)
{
@@ -1701,6 +1716,71 @@ cleanup:
return ret;
}
+int virStoragePoolSourceFindDuplicate(virStoragePoolObjListPtr pools,
+ virStoragePoolDefPtr def)
+{
+ int i;
+ int ret = 1;
+ virStoragePoolObjPtr pool = NULL;
+ virStoragePoolObjPtr matchpool = NULL;
+
+ /* Check the pool list for duplicate underlying storage */
+ for (i = 0; i < pools->count; i++) {
+ pool = pools->objs[i];
+ if (def->type != pool->def->type)
+ continue;
+
+ virStoragePoolObjLock(pool);
+
+ switch (pool->def->type) {
+ case VIR_STORAGE_POOL_DIR:
+ if (STREQ(pool->def->target.path, def->target.path))
+ matchpool = pool;
+ break;
+ case VIR_STORAGE_POOL_NETFS:
+ if ((STREQ(pool->def->source.dir, def->source.dir)) \
+ && (STREQ(pool->def->source.host.name, def->source.host.name)))
+ matchpool = pool;
+ break;
+ case VIR_STORAGE_POOL_SCSI:
+ if (STREQ(pool->def->source.adapter, def->source.adapter))
+ matchpool = pool;
+ break;
+ case VIR_STORAGE_POOL_ISCSI:
+ {
+ matchpool = virStoragePoolSourceFindDuplicateDevices(pool, def);
+ if (matchpool) {
+ if (STREQ(matchpool->def->source.host.name, def->source.host.name)) {
+ if ((matchpool->def->source.initiator.iqn) && (def->source.initiator.iqn)) {
+ if (STREQ(matchpool->def->source.initiator.iqn, def->source.initiator.iqn))
+ break;
+ matchpool = NULL;
+ }
+ break;
+ }
+ matchpool = NULL;
+ }
+ break;
+ }
+ case VIR_STORAGE_POOL_FS:
+ case VIR_STORAGE_POOL_LOGICAL:
+ case VIR_STORAGE_POOL_DISK:
+ matchpool = virStoragePoolSourceFindDuplicateDevices(pool, def);
+ break;
+ default:
+ break;
+ }
+ virStoragePoolObjUnlock(pool);
+ }
+
+ if (matchpool) {
+ virStorageReportError(VIR_ERR_OPERATION_FAILED,
+ _("Storage source conflict with pool: '%s'"),
+ matchpool->def->name);
+ ret = -1;
+ }
+ return ret;
+}
void virStoragePoolObjLock(virStoragePoolObjPtr obj)
{
diff --git a/src/conf/storage_conf.h b/src/conf/storage_conf.h
index 271441a..d115a15 100644
--- a/src/conf/storage_conf.h
+++ b/src/conf/storage_conf.h
@@ -335,6 +335,8 @@ virStoragePoolObjPtr virStoragePoolObjFindByUUID(virStoragePoolObjListPtr pools,
const unsigned char *uuid);
virStoragePoolObjPtr virStoragePoolObjFindByName(virStoragePoolObjListPtr pools,
const char *name);
+virStoragePoolObjPtr virStoragePoolSourceFindDuplicateDevices(virStoragePoolObjPtr pool,
+ virStoragePoolDefPtr def);
virStorageVolDefPtr virStorageVolDefFindByKey(virStoragePoolObjPtr pool,
const char *key);
@@ -388,6 +390,9 @@ int virStoragePoolObjIsDuplicate(virStoragePoolObjListPtr pools,
virStoragePoolDefPtr def,
unsigned int check_active);
+int virStoragePoolSourceFindDuplicate(virStoragePoolObjListPtr pools,
+ virStoragePoolDefPtr def);
+
void virStoragePoolObjLock(virStoragePoolObjPtr obj);
void virStoragePoolObjUnlock(virStoragePoolObjPtr obj);
diff --git a/src/libvirt_private.syms b/src/libvirt_private.syms
index 9f03e30..316eb7e 100644
--- a/src/libvirt_private.syms
+++ b/src/libvirt_private.syms
@@ -947,7 +947,9 @@ virStoragePoolObjClearVols;
virStoragePoolObjDeleteDef;
virStoragePoolObjFindByName;
virStoragePoolObjFindByUUID;
+virStoragePoolSourceFindDuplicateDevices;
virStoragePoolObjIsDuplicate;
+virStoragePoolSourceFindDuplicate;
virStoragePoolObjListFree;
virStoragePoolObjLock;
virStoragePoolObjRemove;
diff --git a/src/storage/storage_driver.c b/src/storage/storage_driver.c
index 68cac1f..c05b74e 100644
--- a/src/storage/storage_driver.c
+++ b/src/storage/storage_driver.c
@@ -536,6 +536,9 @@ storagePoolCreate(virConnectPtr conn,
if (virStoragePoolObjIsDuplicate(&driver->pools, def, 1) < 0)
goto cleanup;
+ if (virStoragePoolSourceFindDuplicate(&driver->pools, def) < 0)
+ goto cleanup;
+
if ((backend = virStorageBackendForType(def->type)) == NULL)
goto cleanup;
@@ -589,6 +592,9 @@ storagePoolDefine(virConnectPtr conn,
if (virStoragePoolObjIsDuplicate(&driver->pools, def, 0) < 0)
goto cleanup;
+ if (virStoragePoolSourceFindDuplicate(&driver->pools, def) < 0)
+ goto cleanup;
+
if (virStorageBackendForType(def->type) == NULL)
goto cleanup;
--
1.7.1
13 years, 2 months
[libvirt] [PATCH 1/3] PIIX3 USB controller is on function 2
by Marc-André Lureau
Current code reserves slot 1 function 2 even if there is a user
defined PIIX3 USB controller there.
---
src/qemu/qemu_command.c | 3 ++-
1 files changed, 2 insertions(+), 1 deletions(-)
diff --git a/src/qemu/qemu_command.c b/src/qemu/qemu_command.c
index 6ff1b2c..e4bdb57 100644
--- a/src/qemu/qemu_command.c
+++ b/src/qemu/qemu_command.c
@@ -1181,7 +1181,8 @@ qemuAssignDevicePCISlots(virDomainDefPtr def, qemuDomainPCIAddressSetPtr addrs)
* hardcoded slot=1, multifunction device
*/
for (function = 0; function < QEMU_PCI_ADDRESS_LAST_FUNCTION; function++) {
- if (function == 1 && (reservedIDE || reservedUSB))
+ if ((function == 1 && reservedIDE) ||
+ (function == 2 && reservedUSB))
/* we have reserved this pci address */
continue;
--
1.7.6
13 years, 2 months