[libvirt] Supporting vhost-net and macvtap in libvirt for QEMU
by Anthony Liguori
Disclaimer: I am neither an SR-IOV nor a vhost-net expert, but I've CC'd
people that are who can throw tomatoes at me for getting bits wrong :-)
I wanted to start a discussion about supporting vhost-net in libvirt.
vhost-net has not yet been merged into qemu but I expect it will be soon
so it's a good time to start this discussion.
There are two modes worth supporting for vhost-net in libvirt. The
first mode is where vhost-net backs to a tun/tap device. This is
behaves in very much the same way that -net tap behaves in qemu today.
Basically, the difference is that the virtio backend is in the kernel
instead of in qemu so there should be some performance improvement.
Current, libvirt invokes qemu with -net tap,fd=X where X is an already
open fd to a tun/tap device. I suspect that after we merge vhost-net,
libvirt could support vhost-net in this mode by just doing -net
vhost,fd=X. I think the only real question for libvirt is whether to
provide a user visible switch to use vhost or to just always use vhost
when it's available and it makes sense. Personally, I think the later
makes sense.
The more interesting invocation of vhost-net though is one where the
vhost-net device backs directly to a physical network card. In this
mode, vhost should get considerably better performance than the current
implementation. I don't know the syntax yet, but I think it's
reasonable to assume that it will look something like -net
tap,dev=eth0. The effect will be that eth0 is dedicated to the guest.
On most modern systems, there is a small number of network devices so
this model is not all that useful except when dealing with SR-IOV
adapters. In that case, each physical device can be exposed as many
virtual devices (VFs). There are a few restrictions here though. The
biggest is that currently, you can only change the number of VFs by
reloading a kernel module so it's really a parameter that must be set at
startup time.
I think there are a few ways libvirt could support vhost-net in this
second mode. The simplest would be to introduce a new tag similar to
<source network='br0'>. In fact, if you probed the device type for the
network parameter, you could probably do something like <source
network='eth0'> and have it Just Work.
Another model would be to have libvirt see an SR-IOV adapter as a
network pool whereas it handled all of the VF management. Considering
how inflexible SR-IOV is today, I'm not sure whether this is the best model.
Has anyone put any more thought into this problem or how this should be
modeled in libvirt? Michael, could you share your current thinking for
-net syntax?
--
Regards,
Anthony Liguori
1 year
[libvirt] [PATCH 0/4] Multiple problems with saving to block devices
by Daniel P. Berrange
This patch series makes it possible to save to a block device,
instead of a plain file. There were multiple problems
- WHen save failed, we might de-reference a NULL pointer
- When save failed, we unlinked the device node !!
- The approach of using >> to append, doesn't work with block devices
- CGroups was blocking QEMU access to the block device when enabled
One remaining problem is not in libvirt, but rather QEMU. The QEMU
exec: based migration often fails to detect failure of the command
and will thus hang forever attempting a migration that'll never
succeed! Fortunately you can now work around this in libvirt using
the virsh domjobabort command
11 years, 7 months
[libvirt] [PATCHv4 00/51] another round of snapshot patches
by Eric Blake
I think I've addressed most findings from round 3 - by implementing
the ability to redefine a snapshot, it becomes possible to restore
snapshot hierarchy when recreating a transient domain by the same
name. New goodies in this round: several bug fixes, add virsh
snapshot-edit, drop undefine --snapshots-full (you can only remove
snapshot metadata on undefine). I tested as I went, but this went
through so many rebases that there may be some nasties that snuck
in; but I wanted to get this posted now. I also know that I'm
missing at least one major feature requested in the v3 review:
namely, transient domains _should_ auto-remove snapshot metadata
files when they halt, but right now aren't doing that.
v3 was at:
https://www.redhat.com/archives/libvir-list/2011-August/msg01132.html
Also available here:
git fetch git://repo.or.cz/libvirt/ericb.git snapshot
or browse online at:
http://repo.or.cz/w/libvirt/ericb.git/shortlog/refs/heads/snapshot
I'm also trying to group things by several bugzilla related to
various patches (looks like I still need to create a few):
Eric Blake (51):
https://bugzilla.redhat.com/show_bug.cgi?id=674537
snapshot: fix corner case on OOM during creation
https://bugzilla.redhat.com/show_bug.cgi?id=733762
snapshot: better events when starting paused
snapshot: fine-tune ability to start paused
snapshot: expose --running and --paused in virsh
snapshot: fine-tune qemu saved images starting paused
snapshot: improve reverting to qemu paused snapshots
snapshot: properly revert qemu to offline snapshots
snapshot: fine-tune qemu snapshot revert states
no bug filed yet... should be one about no stale metadata
snapshot: allow deletion of just snapshot metadata
snapshot: add snapshot-list --parent to virsh
https://bugzilla.redhat.com/show_bug.cgi?id=733529
snapshot: speed up snapshot location
snapshot: avoid crash when deleting qemu snapshots
snapshot: track current domain across deletion of children
snapshot: simplify acting on just children
no bug filed yet... should be one about no stale metadata
snapshot: let qemu discard only snapshot metadata
snapshot: identify which snapshots have metadata
snapshot: reflect new dumpxml and list options in virsh
snapshot: identify qemu snapshot roots
snapshot: allow recreation of metadata
snapshot: refactor virsh snapshot creation
snapshot: improve virsh snapshot-create, add snapshot-edit
snapshot: add qemu snapshot creation without metadata
no bug filed yet... should be one about snapshot migration
snapshot: add qemu snapshot redefine support
snapshot: prevent stranding snapshot data on domain destruction
snapshot: teach virsh about new undefine flags
snapshot: refactor some qemu code
snapshot: cache qemu-img location
snapshot: support new undefine flags in qemu
snapshot: prevent migration from stranding snapshot data
https://bugzilla.redhat.com/show_bug.cgi?id=638510
snapshot: refactor domain xml output
snapshot: allow full domain xml in snapshot
snapshot: correctly escape generated xml
snapshot: update rng to support full domain in xml
snapshot: store qemu domain details in xml
snapshot: additions to domain xml for disks
snapshot: reject transient disks where code is not ready
snapshot: introduce new deletion flag
snapshot: expose new delete flag in virsh
snapshot: allow halting after snapshot
snapshot: expose halt-after-creation in virsh
snapshot: wire up new qemu monitor command
snapshot: support extra state in snapshots
snapshot: add <disks> to snapshot xml
snapshot: also support disks by path
snapshot: add virsh domblklist command
snapshot: add flag for requesting disk snapshot
snapshot: wire up disk-only flag to snapshot-create
snapshot: reject unimplemented disk snapshot features
snapshot: make it possible to audit external snapshot
snapshot: wire up live qemu disk snapshots
snapshot: use SELinux and lock manager with external snapshots
docs/formatdomain.html.in | 40 +-
docs/formatsnapshot.html.in | 269 ++-
docs/schemas/Makefile.am | 1 +
docs/schemas/domain.rng | 2555 +-------------------
docs/schemas/{domain.rng => domaincommon.rng} | 32 +-
docs/schemas/domainsnapshot.rng | 84 +-
examples/domain-events/events-c/event-test.c | 37 +-
include/libvirt/libvirt.h.in | 66 +-
src/conf/domain_audit.c | 12 +-
src/conf/domain_audit.h | 4 +-
src/conf/domain_conf.c | 902 ++++++--
src/conf/domain_conf.h | 76 +-
src/esx/esx_driver.c | 38 +-
src/libvirt.c | 256 ++-
src/libvirt_private.syms | 8 +
src/libxl/libxl_conf.c | 5 +
src/libxl/libxl_driver.c | 11 +-
src/qemu/qemu_command.c | 5 +
src/qemu/qemu_conf.h | 1 +
src/qemu/qemu_driver.c | 1532 +++++++++---
src/qemu/qemu_hotplug.c | 18 +-
src/qemu/qemu_migration.c | 48 +-
src/qemu/qemu_migration.h | 2 -
src/qemu/qemu_monitor.c | 24 +
src/qemu/qemu_monitor.h | 4 +
src/qemu/qemu_monitor_json.c | 33 +
src/qemu/qemu_monitor_json.h | 4 +
src/qemu/qemu_monitor_text.c | 40 +
src/qemu/qemu_monitor_text.h | 4 +
src/qemu/qemu_process.c | 11 +-
src/uml/uml_driver.c | 56 +-
src/vbox/vbox_tmpl.c | 43 +-
src/xen/xend_internal.c | 12 +-
src/xenxs/xen_sxpr.c | 5 +
src/xenxs/xen_xm.c | 5 +
tests/domainsnapshotxml2xmlin/disk_snapshot.xml | 16 +
tests/domainsnapshotxml2xmlout/disk_snapshot.xml | 77 +
tests/domainsnapshotxml2xmlout/full_domain.xml | 35 +
.../qemuxml2argv-disk-snapshot.args | 7 +
.../qemuxml2argv-disk-snapshot.xml | 39 +
.../qemuxml2argv-disk-transient.xml | 27 +
tests/qemuxml2argvtest.c | 2 +
tests/virsh-optparse | 20 +
tools/virsh.c | 772 +++++-
tools/virsh.pod | 214 ++-
45 files changed, 3978 insertions(+), 3474 deletions(-)
copy docs/schemas/{domain.rng => domaincommon.rng} (98%)
create mode 100644 tests/domainsnapshotxml2xmlin/disk_snapshot.xml
create mode 100644 tests/domainsnapshotxml2xmlout/disk_snapshot.xml
create mode 100644 tests/domainsnapshotxml2xmlout/full_domain.xml
create mode 100644 tests/qemuxml2argvdata/qemuxml2argv-disk-snapshot.args
create mode 100644 tests/qemuxml2argvdata/qemuxml2argv-disk-snapshot.xml
create mode 100644 tests/qemuxml2argvdata/qemuxml2argv-disk-transient.xml
--
1.7.4.4
12 years
[libvirt] [PATCH] Fix dnsmasq/radvd on bridges not being able to be bound to IPv6 address on "recent" kernels
by Benjamin Cama
Hi,
I hit this problem recently when trying to create a bridge with an IPv6
address on a 3.2 kernel: dnsmasq (and, further, radvd) would not bind to
the given address (resp. interface), waiting 20s and then giving up with
-EADDRNOTAVAIL (resp. exiting immediately with "error parsing or
activating the config file", without libvirt noticing it, BTW). This can
be reproduced with (I think) any kernel >= 2.6.39 and the following XML
(to be used with "virsh net-create"):
<network>
<name>test-bridge</name>
<bridge name='testbr0' />
<ip family='ipv6' address='fd00::1' prefix='64'>
</ip>
</network>
(it happens even when you have an IPv4, too)
The problem is that since commit [1] (which, ironically, was made to
“help IPv6 autoconfiguration”) the linux bridge code makes bridges
behave like “real” devices regarding carrier detection. This makes the
bridges created by libvirt, which are started without any up devices,
stay with the NO-CARRIER flag set, and thus prevents DAD (Duplicate
address detection) from happening, thus letting the IPv6 address flagged
as “tentative”. Such addresses cannot be bound to (see RFC 2462), so
dnsmasq fails binding to it (for radvd, it detects that "interface XXX
is not RUNNING", thus that "interface XXX does not exist, ignoring the
interface" (sic)). It seems that this behavior was enhanced somehow with
commit [2] by avoiding setting NO-CARRIER on empty bridges, but I
couldn't reproduce this behavior on my kernel. Anyway, with the “dummy
tap to set MAC address” trick, this wouldn't work.
To fix this, the idea is to get the bridge's attached device to be up so
that DAD can happen (deactivating DAD altogether is not a good idea, I
think). Currently, libvirt creates a dummy TAP device to set the MAC
address of the bridge, keeping it down. But even if we set this device
up, it is not RUNNING as soon as the tap file descriptor attached to it
is closed, thus still preventing DAD. So, we must modify the API a bit,
so that we can get the fd, keep the tap device persistent, run the
daemons, and close it after DAD has taken place. After that, the bridge
will be flagged NO-CARRIER again, but the daemons will be running, even
if not happy about the device's state (but we don't really care about
the bridge's daemons doing anything when no up interface is connected to
it).
Other solutions that I envisioned were:
* Keeping the *-nic interface up: this would waste an fd for each
bridge during all its life. May be acceptable, I don't really
know.
* Stop using the dummy tap trick, and set the MAC address directly
on the bridge: it is possible since quite some time it seems,
even if then there is the problem of the bridge not being
RUNNING when empty, contrary to what [2] says, so this will need
fixing (and this fix only happened in 3.1, so it wouldn't work
for 2.6.39)
* Using the --interface option of dnsmasq, but I saw somewhere
that it's not used by libvirt for backward compatibility. I am
not sure this would solve this problem, though, as I don't know
how dnsmasq binds itself to it with this option.
This is why this patch does what's described earlier. I see radvd
yelling quite often in the logs when the interface is NO-CARRIER, but
it's ok, it keeps running.
Still, this patch is not exactly correct, as radvd get daemonized “too
soon” most of the time (i.e. when not debugging libvirtd…) and probes
the bridge once it has been set down (even if started before setting it
down), thus failing as before (and libvirt lets it be like that: this
would need some more checking, maybe). One /may/ introduce some delay
between networkStartRadvd() and setting the dummy tap down to solve it,
but it seemed too hackish to me. But I couldn't come with a better
solution. I would welcome suggestions here.
BTW, I removed the “up” argument from virNetDevTapCreateInBridgePort()
and virNetDevTapCreate() as all TAP devices are created up now, and I
fixed a function name in the docstring.
[1]
http://git.kernel.org/?p=linux/kernel/git/torvalds/linux.git;a=commit;h=1...
[2]
http://git.kernel.org/?p=linux/kernel/git/torvalds/linux.git;a=commit;h=b...
---
src/network/bridge_driver.c | 15 ++++++++++++++-
src/qemu/qemu_command.c | 2 +-
src/uml/uml_conf.c | 2 +-
src/util/virnetdevtap.c | 29 +++++++++++++++++------------
src/util/virnetdevtap.h | 7 ++++---
5 files changed, 37 insertions(+), 18 deletions(-)
diff --git a/src/network/bridge_driver.c b/src/network/bridge_driver.c
index 63338a2..a13efe6 100644
--- a/src/network/bridge_driver.c
+++ b/src/network/bridge_driver.c
@@ -62,6 +62,7 @@
#include "virnetdev.h"
#include "virnetdevbridge.h"
#include "virnetdevtap.h"
+#include "virfile.h"
#define NETWORK_PID_DIR LOCALSTATEDIR "/run/libvirt/network"
#define NETWORK_STATE_DIR LOCALSTATEDIR "/lib/libvirt/network"
@@ -1693,6 +1694,7 @@ networkStartNetworkVirtual(struct network_driver *driver,
virErrorPtr save_err = NULL;
virNetworkIpDefPtr ipdef;
char *macTapIfName = NULL;
+ int tapfd = -1;
/* Check to see if any network IP collides with an existing route */
if (networkCheckRouteCollision(network) < 0)
@@ -1714,8 +1716,9 @@ networkStartNetworkVirtual(struct network_driver *driver,
virReportOOMError();
goto err0;
}
+ /* Keep tun fd open and interface up to allow for IPv6 DAD to happen */
if (virNetDevTapCreateInBridgePort(network->def->bridge,
- &macTapIfName, network->def->mac, 0, false, NULL) < 0) {
+ &macTapIfName, network->def->mac, 0, &tapfd, true) < 0) {
VIR_FREE(macTapIfName);
goto err0;
}
@@ -1775,6 +1778,16 @@ networkStartNetworkVirtual(struct network_driver *driver,
if (v6present && networkStartRadvd(network) < 0)
goto err4;
+ /* DAD has happened (dnsmasq waits for it), dnsmasq is now bound to the
+ * bridge's IPv6 address, and radvd to the interface, so we can now set the
+ * dummy tun down.
+ */
+ if (tapfd >= 0) {
+ if (virNetDevSetOnline(macTapIfName, false) < 0)
+ goto err4;
+ VIR_FORCE_CLOSE(tapfd);
+ }
+
if (virNetDevBandwidthSet(network->def->bridge, network->def->bandwidth) < 0) {
networkReportError(VIR_ERR_INTERNAL_ERROR,
_("cannot set bandwidth limits on %s"),
diff --git a/src/qemu/qemu_command.c b/src/qemu/qemu_command.c
index 22dc871..08457e7 100644
--- a/src/qemu/qemu_command.c
+++ b/src/qemu/qemu_command.c
@@ -247,7 +247,7 @@ qemuNetworkIfaceConnect(virDomainDefPtr def,
memcpy(tapmac, net->mac, VIR_MAC_BUFLEN);
tapmac[0] = 0xFE; /* Discourage bridge from using TAP dev MAC */
err = virNetDevTapCreateInBridgePort(brname, &net->ifname, tapmac,
- vnet_hdr, true, &tapfd);
+ vnet_hdr, &tapfd, false);
virDomainAuditNetDevice(def, net, "/dev/net/tun", tapfd >= 0);
if (err < 0) {
if (template_ifname)
diff --git a/src/uml/uml_conf.c b/src/uml/uml_conf.c
index b878622..bd838a6 100644
--- a/src/uml/uml_conf.c
+++ b/src/uml/uml_conf.c
@@ -141,7 +141,7 @@ umlConnectTapDevice(virConnectPtr conn,
memcpy(tapmac, net->mac, VIR_MAC_BUFLEN);
tapmac[0] = 0xFE; /* Discourage bridge from using TAP dev MAC */
if (virNetDevTapCreateInBridgePort(bridge, &net->ifname, tapmac,
- 0, true, NULL) < 0) {
+ 0, NULL, true) < 0) {
if (template_ifname)
VIR_FREE(net->ifname);
goto error;
diff --git a/src/util/virnetdevtap.c b/src/util/virnetdevtap.c
index 2ed53c6..3e2c2cc 100644
--- a/src/util/virnetdevtap.c
+++ b/src/util/virnetdevtap.c
@@ -109,18 +109,21 @@ virNetDevProbeVnetHdr(int tapfd)
* @ifname: the interface name
* @vnet_hr: whether to try enabling IFF_VNET_HDR
* @tapfd: file descriptor return value for the new tap device
+ * @persist: if the device persists after the file descriptor is closed
*
* Creates a tap interface.
* If the @tapfd parameter is supplied, the open tap device file
- * descriptor will be returned, otherwise the TAP device will be made
- * persistent and closed. The caller must use brDeleteTap to remove
- * a persistent TAP devices when it is no longer needed.
+ * descriptor will be returned, otherwise the TAP device will be closed. The
+ * TAP device will persist after closing the file descriptor if @persist is
+ * true. The caller must use virNetDevTapDelete to remove a persistent TAP
+ * devices when it is no longer needed.
*
* Returns 0 in case of success or an errno code in case of failure.
*/
int virNetDevTapCreate(char **ifname,
int vnet_hdr ATTRIBUTE_UNUSED,
- int *tapfd)
+ int *tapfd,
+ bool persist)
{
int fd;
struct ifreq ifr;
@@ -156,7 +159,7 @@ int virNetDevTapCreate(char **ifname,
goto cleanup;
}
- if (!tapfd &&
+ if (persist &&
(errno = ioctl(fd, TUNSETPERSIST, 1))) {
virReportSystemError(errno,
_("Unable to set tap device %s to persistent"),
@@ -249,14 +252,16 @@ int virNetDevTapDelete(const char *ifname ATTRIBUTE_UNUSED)
* @macaddr: desired MAC address (VIR_MAC_BUFLEN long)
* @vnet_hdr: whether to try enabling IFF_VNET_HDR
* @tapfd: file descriptor return value for the new tap device
+ * @persist: if the device persists after the file descriptor is closed
*
* This function creates a new tap device on a bridge. @ifname can be either
* a fixed name or a name template with '%d' for dynamic name allocation.
* in either case the final name for the bridge will be stored in @ifname.
* If the @tapfd parameter is supplied, the open tap device file
- * descriptor will be returned, otherwise the TAP device will be made
- * persistent and closed. The caller must use brDeleteTap to remove
- * a persistent TAP devices when it is no longer needed.
+ * descriptor will be returned, otherwise the TAP device will be closed. The
+ * TAP device will persist after closing the file descriptor if @persist is
+ * true. The caller must use virNetDevTapDelete to remove a persistent TAP
+ * devices when it is no longer needed.
*
* Returns 0 in case of success or -1 on failure
*/
@@ -264,10 +269,10 @@ int virNetDevTapCreateInBridgePort(const char *brname,
char **ifname,
const unsigned char *macaddr,
int vnet_hdr,
- bool up,
- int *tapfd)
+ int *tapfd,
+ bool persist)
{
- if (virNetDevTapCreate(ifname, vnet_hdr, tapfd) < 0)
+ if (virNetDevTapCreate(ifname, vnet_hdr, tapfd, persist) < 0)
return -1;
/* We need to set the interface MAC before adding it
@@ -289,7 +294,7 @@ int virNetDevTapCreateInBridgePort(const char *brname,
if (virNetDevBridgeAddPort(brname, *ifname) < 0)
goto error;
- if (virNetDevSetOnline(*ifname, up) < 0)
+ if (virNetDevSetOnline(*ifname, true) < 0)
goto error;
return 0;
diff --git a/src/util/virnetdevtap.h b/src/util/virnetdevtap.h
index fb35ac5..6aff641 100644
--- a/src/util/virnetdevtap.h
+++ b/src/util/virnetdevtap.h
@@ -27,7 +27,8 @@
int virNetDevTapCreate(char **ifname,
int vnet_hdr,
- int *tapfd)
+ int *tapfd,
+ bool persist)
ATTRIBUTE_NONNULL(1) ATTRIBUTE_RETURN_CHECK;
int virNetDevTapDelete(const char *ifname)
@@ -37,8 +38,8 @@ int virNetDevTapCreateInBridgePort(const char *brname,
char **ifname,
const unsigned char *macaddr,
int vnet_hdr,
- bool up,
- int *tapfd)
+ int *tapfd,
+ bool persist)
ATTRIBUTE_NONNULL(1) ATTRIBUTE_NONNULL(2) ATTRIBUTE_NONNULL(3)
ATTRIBUTE_RETURN_CHECK;
--
Benjamin Cama <benjamin.cama(a)telecom-bretagne.eu>
12 years, 1 month
[libvirt] [PATCHv4] add-vcpu-usage
by Hu Tao
show `vcpu usages' by `virt-top -1'
Before this patch, `virt-top -1' shows total cpu usages
which euqal to `vcpu usages' + `hypervisor usages'. This
patch adds another column for domains showing `vcpu
usages'. An example is:
PHYCPU %CPU example_domain
0 10.4 10.4 0.8
1 1.6 1.6 1.4
2 2.6 2.6 2.6
3 0.0 0.0 0.1
---
virt-top/virt_top.ml | 72 ++++++++++++++++++++++++++++++++++++-------------
1 files changed, 53 insertions(+), 19 deletions(-)
diff --git a/virt-top/virt_top.ml b/virt-top/virt_top.ml
index e2fe554..0dcb170 100644
--- a/virt-top/virt_top.ml
+++ b/virt-top/virt_top.ml
@@ -448,6 +448,7 @@ let collect, clear_pcpu_display_data =
(* Save pcpu_usages structures across redraws too (only for pCPU display). *)
let last_pcpu_usages = Hashtbl.create 13 in
+ let last_vcpu_usages = Hashtbl.create 13 in
let clear_pcpu_display_data () =
(* Clear out pcpu_usages used by PCPUDisplay display_mode
@@ -652,12 +653,17 @@ let collect, clear_pcpu_display_data =
(try
let domid = rd.rd_domid in
let maplen = C.cpumaplen nr_pcpus in
- let cpu_stats = D.get_cpu_stats rd.rd_dom nr_pcpus in
- let rec find_usages_from_stats = function
+ let cpu_stats = D.get_cpu_stats rd.rd_dom false in
+ let rec find_cpu_usages = function
| ("cpu_time", D.TypedFieldUInt64 usages) :: _ -> usages
- | _ :: params -> find_usages_from_stats params
+ | _ :: params -> find_cpu_usages params
| [] -> 0L in
- let pcpu_usages = Array.map find_usages_from_stats cpu_stats in
+ let rec find_vcpu_usages = function
+ | ("vcpu_time", D.TypedFieldUInt64 usages) :: _ -> usages
+ | _ :: params -> find_vcpu_usages params
+ | [] -> 0L in
+
+ let pcpu_usages = Array.map find_cpu_usages cpu_stats in
let maxinfo = rd.rd_info.D.nr_virt_cpu in
let nr_vcpus, vcpu_infos, cpumaps =
D.get_vcpus rd.rd_dom maxinfo maplen in
@@ -669,11 +675,19 @@ let collect, clear_pcpu_display_data =
(* Update last_pcpu_usages. *)
Hashtbl.replace last_pcpu_usages domid pcpu_usages;
- (match prev_pcpu_usages with
- | Some prev_pcpu_usages
+ (* vcpu usages *)
+ let vcpu_usages = Array.map find_vcpu_usages cpu_stats in
+ let prev_vcpu_usages =
+ try Some (Hashtbl.find last_vcpu_usages domid)
+ with Not_found -> None in
+ Hashtbl.replace last_vcpu_usages domid vcpu_usages;
+
+ (match prev_pcpu_usages, prev_vcpu_usages with
+ | Some prev_pcpu_usages, Some prev_vcpu_usages
when Array.length prev_pcpu_usages = Array.length pcpu_usages ->
- Some (domid, name, nr_vcpus, vcpu_infos, pcpu_usages,
- prev_pcpu_usages, cpumaps, maplen)
+ Some (domid, name, nr_vcpus, vcpu_infos, pcpu_usages,
+ prev_pcpu_usages, vcpu_usages, prev_vcpu_usages,
+ cpumaps, maplen)
| _ -> None (* ignore missing / unequal length prev_vcpu_infos *)
);
with
@@ -691,13 +705,24 @@ let collect, clear_pcpu_display_data =
List.iteri (
fun di (domid, name, nr_vcpus, vcpu_infos, pcpu_usages,
- prev_pcpu_usages, cpumaps, maplen) ->
+ prev_pcpu_usages, vcpu_usages, prev_vcpu_usages,
+ cpumaps, maplen) ->
(* Which pCPUs can this dom run on? *)
for p = 0 to Array.length pcpu_usages - 1 do
pcpus.(p).(di) <- pcpu_usages.(p) -^ prev_pcpu_usages.(p)
- done
+ done
) doms;
+ let vcpus = Array.make_matrix nr_pcpus nr_doms 0L in
+ List.iteri (
+ fun di (domid, name, nr_vcpus, vcpu_infos, pcpu_usages,
+ prev_pcpu_usages, vcpu_usages, prev_vcpu_usages,
+ cpumaps, maplen) ->
+ for p = 0 to Array.length vcpu_usages - 1 do
+ vcpus.(p).(di) <- vcpu_usages.(p) -^ prev_vcpu_usages.(p)
+ done
+ ) doms;
+
(* Sum the CPU time used by each pCPU, for the %CPU column. *)
let pcpus_cpu_time = Array.map (
fun row ->
@@ -709,7 +734,7 @@ let collect, clear_pcpu_display_data =
Int64.to_float !cpu_time
) pcpus in
- Some (doms, pcpus, pcpus_cpu_time)
+ Some (doms, pcpus, vcpus, pcpus_cpu_time)
) else
None in
@@ -913,7 +938,7 @@ let redraw =
loop domains_lineno doms
| PCPUDisplay -> (*---------- Showing physical CPUs ----------*)
- let doms, pcpus, pcpus_cpu_time =
+ let doms, pcpus, vcpus, pcpus_cpu_time =
match pcpu_display with
| Some p -> p
| None -> failwith "internal error: no pcpu_display data" in
@@ -922,9 +947,9 @@ let redraw =
let dom_names =
String.concat "" (
List.map (
- fun (_, name, _, _, _, _, _, _) ->
+ fun (_, name, _, _, _, _, _, _, _, _) ->
let len = String.length name in
- let width = max (len+1) 7 in
+ let width = max (len+1) 12 in
pad width name
) doms
) in
@@ -941,18 +966,27 @@ let redraw =
addch ' ';
List.iteri (
- fun di (domid, name, _, _, _, _, _, _) ->
+ fun di (domid, name, _, _, _, _, _, _, _, _) ->
let t = pcpus.(p).(di) in
+ let tv = vcpus.(p).(di) in
let len = String.length name in
- let width = max (len+1) 7 in
- let str =
+ let width = max (len+1) 12 in
+ let str_pcpu =
if t <= 0L then ""
else (
let t = Int64.to_float t in
let percent = 100. *. t /. total_cpu_per_pcpu in
- sprintf "%s " (Show.percent percent)
+ sprintf "%s" (Show.percent percent)
) in
- addstr (pad width str);
+ let str_vcpu =
+ if tv <= 0L then ""
+ else (
+ let tv = Int64.to_float tv in
+ let percent = 100. *. tv /. total_cpu_per_pcpu in
+ sprintf "%s" (Show.percent percent)
+ ) in
+ let str = sprintf "%s %s" str_pcpu str_vcpu in
+ addstr (pad width str);
()
) doms
) pcpus;
--
1.7.1
12 years, 2 months
[libvirt] [PATCH] qemu_agent: support guest-info command
by MATSUDA, Daiki
Currently, libvirt qemu agent supports some QEMU Guest Agent's commands
or use them. But they are not adapted to communication test to the
Domain OS.
So, QEMU Guest Agent provide 'guest-info' command to display its version
and their commands. And I wrote the codes for supporting it.
virsh # guest-agent-info RHEL62_32
Version: 1.1.0
Commands:
guest-network-get-interfaces
guest-suspend-hybrid
guest-suspend-ram
guest-suspend-disk
guest-fsfreeze-thaw
guest-fsfreeze-freeze
guest-fsfreeze-status
guest-file-flush
guest-file-seek
guest-file-write
guest-file-read
guest-file-close
guest-file-open
guest-shutdown
guest-info
guest-ping
guest-sync
guest-sync-delimited
I am sorry that attached patch is against libvirt-0.9.13-rc1, because my
network environment can not access via git and header code is not built
with the problem gnulib...
Regards
MATSUDA Daiki
12 years, 3 months
[libvirt] Stored secrets seem to get corrupted
by Wido den Hollander
Hi,
On one of my systems I'm having troubles with my RBD storage backend.
At first I thought it was a problem with my code, but after trying the
same code on a second machine I'm a bit confused.
The problem is that the storage backend tries to retrieve the value of a
secret and base64 decode it, that fails.
My debug log shows:
debug : virStorageBackendRBDOpenRADOSConn:65 : Using cephx authorization
debug : virStorageBackendRBDOpenRADOSConn:75 : Looking up secret by
UUID: 322bccea-f2ed-4eae-a7e5-d0793ffb162d
debug : virSecretLookupByUUIDString:14128 : conn=0x7fac9c0009c0,
uuidstr=322bccea-f2ed-4eae-a7e5-d0793ffb162d
debug : virSecretLookupByUUID:14086 : conn=0x7fac9c0009c0,
uuid=322bccea-f2ed-4eae-a7e5-d0793ffb162d
debug : virSecretGetValue:14486 : secret=0x7fac94000d30,
value_size=0x7facad481918, flags=0
debug : virStorageBackendRBDOpenRADOSConn:103 : Found cephx key: `I^%
debug : virStorageBackendRBDOpenRADOSConn:135 : Found 1 RADOS cluster
monitors in the pool configuration
debug : virStorageBackendRBDOpenRADOSConn:159 : RADOS mon_host has been
set to: 31.25.100.131:6789,
error : virStorageBackendRBDOpenRADOSConn:171 : internal error failed to
connect to the RADOS monitor on: 31.25.100.131:6789,
It goes wrong at "Found cephx key: <garbage>"
So I figured it had to be something in my code and I went over the code
again, but nothing seemed odd.
I tried the same checkout (tag: 0.9.13-rc1) on a different host (also
Ubuntu 12.04) and that worked.
The secret and pool XML's are the same, but what I found is that the
secret storage on disk seems to go wrong on one machine.
Notice this behavior:
root@stack01:~# virsh secret-set-value
322bccea-f2ed-4eae-a7e5-d0793ffb162d
AQAE+uJPCFpELBAAkTniQvHabBGj0Quwnu2imA==
Secret value set
root@stack01:~# md5sum
/etc/libvirt/secrets/322bccea-f2ed-4eae-a7e5-d0793ffb162d.base64
b4b147bc522828731f1a016bfa72c073
/etc/libvirt/secrets/322bccea-f2ed-4eae-a7e5-d0793ffb162d.base64
root@stack01:~# virsh secret-set-value
322bccea-f2ed-4eae-a7e5-d0793ffb162d
AQAE+uJPCFpELBAAkTniQvHabBGj0Quwnu2imA==
Secret value set
root@stack01:~# md5sum
/etc/libvirt/secrets/322bccea-f2ed-4eae-a7e5-d0793ffb162d.base64
927e2458c32cc3f6754d91694e41333f
/etc/libvirt/secrets/322bccea-f2ed-4eae-a7e5-d0793ffb162d.base64
root@stack01:~#
As you can see, the md5sum of the file changes when I set the value of
the secret to the same.
I tried the same on the other host:
root@stack02:~# virsh secret-set-value
322bccea-f2ed-4eae-a7e5-d0793ffb162d
AQAE+uJPCFpELBAAkTniQvHabBGj0Quwnu2imA==
Secret value set
root@stack02:~# md5sum
/etc/libvirt/secrets/322bccea-f2ed-4eae-a7e5-d0793ffb162d.base64
c30db27f9ebfe3f7903470d4bd542d1d
/etc/libvirt/secrets/322bccea-f2ed-4eae-a7e5-d0793ffb162d.base64
root@stack02:~# virsh secret-set-value
322bccea-f2ed-4eae-a7e5-d0793ffb162d
AQAE+uJPCFpELBAAkTniQvHabBGj0Quwnu2imA==
Secret value set
root@stack02:~# md5sum
/etc/libvirt/secrets/322bccea-f2ed-4eae-a7e5-d0793ffb162d.base64
c30db27f9ebfe3f7903470d4bd542d1d
/etc/libvirt/secrets/322bccea-f2ed-4eae-a7e5-d0793ffb162d.base64
root@stack02:~# virsh secret-set-value
322bccea-f2ed-4eae-a7e5-d0793ffb162d
AQAE+uJPCFpELBAAkTniQvHabBGj0Quwnu2imA==
Secret value set
root@stack02:~# md5sum
/etc/libvirt/secrets/322bccea-f2ed-4eae-a7e5-d0793ffb162d.base64
c30db27f9ebfe3f7903470d4bd542d1d
/etc/libvirt/secrets/322bccea-f2ed-4eae-a7e5-d0793ffb162d.base64
root@stack02:~#
The md5sum stays the same on stack02.
I verified that stack01 isn't out of disk space or out of inodes, those
are in the acceptable values range.
Any suggestions?
For the record, the hosts:
OS: Ubuntu 12.04 x864_64
Kernel: 3.2.0-25-generic
Libvirt commit: 0fce94fe1bd782ac4c33fdd59d13ee37b3437413
Thank you,
Wido
12 years, 3 months
[libvirt] [PATCH v2 0/5] Introduce API for dumping domain IP addresses
by Michal Privoznik
This feature has been requested for a very long time. However,
we had to wait for guest agent to obtain reliable results as
user might create totally different structure of interfaces than
seen from outside (e.g. bonding, virtual interfaces, etc.).
That's the main reason why sniffing for domain traffic can
return bogus results. Fortunately, qemu guest agent implement
requested part for a while so nothing holds us back anymore.
To make matters worse, guest OS can assign whatever name to
an interface and changing MAC inside guest isn't propagated
to the host which in the end see original one.
Therefore, finding correlation between interface within guest
and the host side end is left as exercise for mgmt applications.
This API is called virDomainGetInterfacesAddresses (okay, maybe
too many plurals) and returns a XML document containing all
interesting data.
diff to v1:
-switch from struct to XML doc
Michal Privoznik (5):
Introduce virDomainGetInterfacesAddresses API
virsh: Expose virDomainGetInterfacesAddresses
qemu_agent: Implement 'guest-network-get-interfaces' command handling
qemu: Implement virDomainInterfacesAddresses
python: create example for dumping domain IP addresses
docs/schemas/interfaces.rng | 57 +++++++++++++++++
examples/python/Makefile.am | 2 +-
examples/python/README | 1 +
examples/python/domipaddrs.py | 62 +++++++++++++++++++
include/libvirt/libvirt.h.in | 2 +
src/driver.h | 4 +
src/libvirt.c | 49 +++++++++++++++
src/libvirt_public.syms | 1 +
src/qemu/qemu_agent.c | 135 +++++++++++++++++++++++++++++++++++++++++
src/qemu/qemu_agent.h | 2 +
src/qemu/qemu_driver.c | 68 +++++++++++++++++++++
src/remote/remote_driver.c | 1 +
src/remote/remote_protocol.x | 12 +++-
src/remote_protocol-structs | 8 +++
tools/virsh.c | 41 ++++++++++++
tools/virsh.pod | 9 +++
16 files changed, 452 insertions(+), 2 deletions(-)
create mode 100644 docs/schemas/interfaces.rng
create mode 100644 examples/python/domipaddrs.py
--
1.7.8.5
12 years, 3 months
[libvirt] [Patch v2 0/3] Add QEMU network helper support
by rmarwah@linux.vnet.ibm.com
From: Richa Marwaha <rmarwah(a)linux.vnet.ibm.com>
QEMU has a new feature which allows QEMU to execute under an unprivileged user ID and still be able to
add a tap device to a Linux network bridge. Below is the link to the QEMU patches for the bridge helper
feature:
http://lists.gnu.org/archive/html/qemu-devel/2012-01/msg03562.html
The existing libvirt tap network device support for adding a tap device to a bridge (-netdev tap) works
only when connected to a libvirtd instance running as the privileged system account 'root'.
When connected to a libvirtd instance running as an unprivileged user (ie. using the session URI) creation of
the tap device fails as follows:
error: Failed to start domain F14_64 error: Unable to create tap device vnet%d: Operation not permitted
With this support, creating a tap device in the above scenario will be possible. Additionally, hot attaching
a tap device to a bridge while running when connected to a libvirtd instance running as an unprivileged user
will be possible.
Richa Marwaha (3):
Add -netdev bridge capabilities
Add -netdev bridge support
apparmor: QEMU bridge helper policy updates
examples/apparmor/libvirt-qemu | 21 +++++++++++++-
src/qemu/qemu_capabilities.c | 13 ++++++--
src/qemu/qemu_capabilities.h | 1 +
src/qemu/qemu_command.c | 61 ++++++++++++++++++++++++++++-----------
src/qemu/qemu_command.h | 2 +
src/qemu/qemu_hotplug.c | 31 ++++++++++++++------
6 files changed, 97 insertions(+), 32 deletions(-)
12 years, 3 months