[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] Libvirt multi queue support
by Naor Shlomo
Hello experts,
Could anyone please tell me if Multi Queue it fully supported in Libvirt and if so what version contains it?
Thanks,
Naor
8 years, 5 months
[libvirt] [PATCH/RFC] Add missing delta from Ubuntu to apparmor profiles
by Stefan Bader
This had been on the Debian package list before but its time to take
this onwards. So the goal would be to have one set to rule them all
(when using apparmor) and drop the seperate set of definitions which
exist at least in the Ubuntu packaging.
Right now the patch would be at a state which adds all missing files
and rules to the current examples in libvirt and installs them when
using --with-apparmor-profiles.
One problem seems to be that some of the definitions might cause
parse failures on certain versions of apparmor. I checked this morning
and this looks a bit hairy. So some apparmor 2.8 versions potentially
have issues, but not all apparmor 2.8 are the same (gah).
I could imagine (but John, we really could use some guidance here ;))
that at least some changes could be related to version 2.8.95~2430:
+ debian/patches/mediate-signals.patch,
debian/patches/change-signal-syntax.patch: Parse signal rules with
apparmor_parser. See the apparmor.d(5) man page for syntax details.
+ debian/patches/change-ptrace-syntax.patch,
debian/patches/mediate-ptrace.patch: Parse ptrace rules with
apparmor_parser. See the apparmor.d(5) man page for syntax details.
But, regardless of the when, the apparmor rules maybe need a way to handle
versioned features of the parser. One proposal was to comment out problematic
rules and allow the packager to re-enable things. Maybe going one step
further and have some pre-processing that handles version based sections
(like #if (APPARMOR_VERSION >= xxx)).
So that is where we stand. Ideas are very welcome.
-Stefan
---
>From aec5cf8cc30c80492a37856626264c3d4c27a31f Mon Sep 17 00:00:00 2001
From: Stefan Bader <stefan.bader(a)canonical.com>
Date: Thu, 18 Sep 2014 14:15:17 +0200
Subject: [PATCH] Add missing delta from Ubuntu to apparmor profiles
This fixes up the upstream profiles and would allow to drop apparmor
related delta from the Ubuntu package.
Thanks to Serge Hallyn for the Makefile.am install hook that allows
to rename the local file.
Signed-off-by: Stefan Bader <stefan.bader(a)canonical.com>
---
examples/apparmor/Makefile.am | 10 ++++++++
examples/apparmor/libvirt-lxc | 15 +++++++++++-
examples/apparmor/libvirt-qemu | 31 +++++++++++++++++++++++-
examples/apparmor/local-usr.sbin.libvirtd | 2 ++
examples/apparmor/usr.lib.libvirt.virt-aa-helper | 25 ++++++++++++++++---
examples/apparmor/usr.sbin.libvirtd | 17 ++++++++++++-
6 files changed, 94 insertions(+), 6 deletions(-)
create mode 100644 examples/apparmor/local-usr.sbin.libvirtd
diff --git a/examples/apparmor/Makefile.am b/examples/apparmor/Makefile.am
index 7a20e16..aa46cb9 100644
--- a/examples/apparmor/Makefile.am
+++ b/examples/apparmor/Makefile.am
@@ -20,6 +20,7 @@ EXTRA_DIST= \
libvirt-qemu \
libvirt-lxc \
usr.lib.libvirt.virt-aa-helper \
+ local-usr.sbin.libvirtd \
usr.sbin.libvirtd
if WITH_APPARMOR_PROFILES
@@ -29,6 +30,15 @@ apparmor_DATA = \
usr.sbin.libvirtd \
$(NULL)
+localdir = $(apparmordir)/local
+local_DATA = \
+ local-usr.sbin.libvirtd \
+ $(NULL)
+
+install-data-hook:
+ mv $(DESTDIR)$(localdir)/local-usr.sbin.libvirtd \
+ $(DESTDIR)$(localdir)/usr.sbin.libvirtd
+
abstractionsdir = $(apparmordir)/abstractions
abstractions_DATA = \
libvirt-qemu \
diff --git a/examples/apparmor/libvirt-lxc b/examples/apparmor/libvirt-lxc
index 4bfb503..4705e0a 100644
--- a/examples/apparmor/libvirt-lxc
+++ b/examples/apparmor/libvirt-lxc
@@ -1,12 +1,18 @@
-# Last Modified: Fri Feb 7 13:01:36 2014
+# Last Modified: Thu, 18 Sep 2014 13:56:49 +0200
#include <abstractions/base>
umount,
+ dbus,
+ signal,
+ ptrace,
# ignore DENIED message on / remount
deny mount options=(ro, remount) -> /,
+ # support use of cgmanager proxy
+ mount options=(move) /sys/fs/cgroup/cgmanager/ -> /sys/fs/cgroup/cgmanager.lower/,
+
# allow tmpfs mounts everywhere
mount fstype=tmpfs,
@@ -33,8 +39,15 @@
mount fstype=fusectl -> /sys/fs/fuse/connections/,
mount fstype=securityfs -> /sys/kernel/security/,
mount fstype=debugfs -> /sys/kernel/debug/,
+ deny mount fstype=debugfs -> /var/lib/ureadahead/debugfs/,
mount fstype=proc -> /proc/,
mount fstype=sysfs -> /sys/,
+
+ mount options=(rw nosuid nodev noexec remount) -> /sys/,
+ mount options=(rw remount) -> /sys/kernel/security/,
+ mount options=(rw remount) -> /sys/fs/pstore/,
+ mount options=(ro remount) -> /sys/fs/pstore/,
+
deny /sys/firmware/efi/efivars/** rwklx,
deny /sys/kernel/security/** rwklx,
diff --git a/examples/apparmor/libvirt-qemu b/examples/apparmor/libvirt-qemu
index c6de6dd..b69e64c 100644
--- a/examples/apparmor/libvirt-qemu
+++ b/examples/apparmor/libvirt-qemu
@@ -1,4 +1,4 @@
-# Last Modified: Wed Sep 3 21:52:03 2014
+# Last Modified: Thu, 18 Sep 2014 16:41:21 +0200
#include <abstractions/base>
#include <abstractions/consoles>
@@ -13,15 +13,22 @@
capability setgid,
capability setuid,
+ # this is needed with libcap-ng support, however it breaks a lot of things
+ # atm, so just silence the denial until libcap-ng works right. LP: #522845
+ deny capability setpcap,
+
network inet stream,
network inet6 stream,
/dev/net/tun rw,
+ /dev/tap* rw,
/dev/kvm rw,
/dev/ptmx rw,
/dev/kqemu rw,
@{PROC}/*/status r,
@{PROC}/sys/kernel/cap_last_cap r,
+ owner @{PROC}/*/auxv r,
+ @{PROC}/sys/vm/overcommit_memory r,
# For hostdev access. The actual devices will be added dynamically
/sys/bus/usb/devices/ r,
@@ -38,6 +45,9 @@
/dev/snd/* rw,
capability ipc_lock,
# spice
+ /usr/bin/qemu-system-i386-spice rmix,
+ /usr/bin/qemu-system-x86_64-spice rmix,
+ /{dev,run}/shm/ r,
owner /{dev,run}/shm/spice.* rw,
# 'kill' is not required for sound and is a security risk. Do not enable
# unless you absolutely need it.
@@ -73,6 +83,7 @@
# the various binaries
/usr/bin/kvm rmix,
/usr/bin/qemu rmix,
+ /usr/bin/qemu-system-aarch64 rmix,
/usr/bin/qemu-system-arm rmix,
/usr/bin/qemu-system-cris rmix,
/usr/bin/qemu-system-i386 rmix,
@@ -91,6 +102,7 @@
/usr/bin/qemu-system-sparc rmix,
/usr/bin/qemu-system-sparc64 rmix,
/usr/bin/qemu-system-x86_64 rmix,
+ /usr/bin/qemu-system-x86_64-spice rmix,
/usr/bin/qemu-alpha rmix,
/usr/bin/qemu-arm rmix,
/usr/bin/qemu-armeb rmix,
@@ -117,6 +129,16 @@
/bin/dash rmix,
/bin/dd rmix,
/bin/cat rmix,
+ /etc/pki/CA/ r,
+ /etc/pki/CA/* r,
+ /etc/pki/libvirt/ r,
+ /etc/pki/libvirt/** r,
+
+ # for rbd
+ /etc/ceph/ceph.conf r,
+
+ # for access to hugepages
+ owner "/run/hugepages/kvm/libvirt/qemu/**" rw,
# for usb access
/dev/bus/usb/ r,
@@ -124,6 +146,13 @@
/sys/bus/ r,
/sys/class/ r,
+ signal (receive) peer=/usr/sbin/libvirtd,
+ ptrace (tracedby) peer=/usr/sbin/libvirtd,
+
+ # for ppc device-tree access
+ @{PROC}/device-tree/ r,
+ @{PROC}/device-tree/** r,
+
/usr/{lib,libexec}/qemu-bridge-helper Cx -> qemu_bridge_helper,
# child profile for bridge helper process
profile qemu_bridge_helper {
diff --git a/examples/apparmor/local-usr.sbin.libvirtd b/examples/apparmor/local-usr.sbin.libvirtd
new file mode 100644
index 0000000..6e19f20
--- /dev/null
+++ b/examples/apparmor/local-usr.sbin.libvirtd
@@ -0,0 +1,2 @@
+# Site-specific additions and overrides for usr.sbin.libvirtd.
+# For more details, please see /etc/apparmor.d/local/README.
diff --git a/examples/apparmor/usr.lib.libvirt.virt-aa-helper b/examples/apparmor/usr.lib.libvirt.virt-aa-helper
index bceaaff..4df86b0 100644
--- a/examples/apparmor/usr.lib.libvirt.virt-aa-helper
+++ b/examples/apparmor/usr.lib.libvirt.virt-aa-helper
@@ -1,8 +1,9 @@
-# Last Modified: Mon Apr 5 15:10:27 2010
+# Last Modified: Thu, 18 Sep 2014 14:05:36 +0200
#include <tunables/global>
/usr/lib/libvirt/virt-aa-helper {
#include <abstractions/base>
+ #include <abstractions/user-tmp>
# needed for searching directories
capability dac_override,
@@ -19,6 +20,12 @@
# for hostdev
/sys/devices/ r,
/sys/devices/** r,
+ /sys/bus/usb/devices/ r,
+ /sys/bus/usb/devices/** r,
+ deny /dev/sd* r,
+ deny /dev/dm-* r,
+ deny /dev/mapper/ r,
+ deny /dev/mapper/* r,
/usr/lib/libvirt/virt-aa-helper mr,
/sbin/apparmor_parser Ux,
@@ -26,8 +33,11 @@
/etc/apparmor.d/libvirt/* r,
/etc/apparmor.d/libvirt/libvirt-[0-9a-f]*-[0-9a-f]*-[0-9a-f]*-[0-9a-f]*-[0-9a-f]* rw,
- # for backingstore -- allow access to non-hidden files in @{HOME} as well
- # as storage pools
+ # For backingstore, virt-aa-helper needs to peek inside the disk image, so
+ # allow access to non-hidden files in @{HOME} as well as storage pools, and
+ # removable media and filesystems, and certain file extentions. A
+ # virt-aa-helper failure when checking a disk for backinsgstore is non-fatal
+ # (but obviously the backingstore won't be added).
audit deny @{HOME}/.* mrwkl,
audit deny @{HOME}/.*/ rw,
audit deny @{HOME}/.*/** mrwkl,
@@ -35,8 +45,17 @@
audit deny @{HOME}/bin/** mrwkl,
@{HOME}/ r,
@{HOME}/** r,
+ @{HOME}/.Private/** mrwlk,
+ @{HOMEDIRS}/.ecryptfs/*/.Private/** mrwlk,
+
/var/lib/libvirt/images/ r,
/var/lib/libvirt/images/** r,
+ /var/lib/nova/images/** r,
+ /var/lib/nova/instances/_base/** r,
+ /var/lib/nova/instances/snapshots/** r,
+ /var/lib/eucalyptus/instances/**/disk* r,
+ /var/lib/eucalyptus/instances/**/loader* r,
+ /var/lib/uvtool/libvirt/images/** r,
/{media,mnt,opt,srv}/** r,
/**.img r,
diff --git a/examples/apparmor/usr.sbin.libvirtd b/examples/apparmor/usr.sbin.libvirtd
index 3011eff..814b4d81 100644
--- a/examples/apparmor/usr.sbin.libvirtd
+++ b/examples/apparmor/usr.sbin.libvirtd
@@ -1,10 +1,12 @@
-# Last Modified: Mon Apr 5 15:03:58 2010
+# Last Modified: Tue, 23 Sep 2014 09:28:07 +0200
#include <tunables/global>
@{LIBVIRT}="libvirt"
/usr/sbin/libvirtd {
#include <abstractions/base>
#include <abstractions/dbus>
+ # Site-specific additions and overrides. See local/README for details.
+ #include <local/usr.sbin.libvirtd>
capability kill,
capability net_admin,
@@ -23,6 +25,7 @@
capability setpcap,
capability mknod,
capability fsetid,
+ capability ipc_lock,
capability audit_write,
# Needed for vfio
@@ -33,6 +36,12 @@
network inet6 stream,
network inet6 dgram,
network packet dgram,
+ network netlink,
+
+ dbus bus=system,
+ signal,
+ ptrace,
+ unix,
# Very lenient profile for libvirtd since we want to first focus on confining
# the guests. Guests will have a very restricted profile.
@@ -45,6 +54,12 @@
/usr/sbin/* PUx,
/lib/udev/scsi_id PUx,
/usr/lib/xen-common/bin/xen-toolstack PUx,
+ /usr/lib/xen-*/bin/pygrub PUx,
+ /usr/lib/xen-*/bin/libxl-save-helper PUx,
+
+ # Required by nwfilter_ebiptables_driver.c:ebiptablesWriteToTempFile() to
+ # write and run an ebtables script.
+ /var/lib/libvirt/virtd* ixr,
# force the use of virt-aa-helper
audit deny /sbin/apparmor_parser rwxl,
--
1.9.1
8 years, 6 months
[libvirt] [PATCH v2 0/8] Add support for fetching statistics of completed jobs
by Jiri Denemark
Using virDomainGetJobStats, we can monitor running jobs but sometimes it
may be useful to get statistics about a job that already finished, for
example, to get the final amount of data transferred during migration or
to get an idea about total downtime. This is what the following patches
are about.
Version 2:
- changed according to John's review (see individual patches for
details)
Jiri Denemark (8):
Refactor job statistics
qemu: Avoid incrementing jobs_queued if virTimeMillisNow fails
Add support for fetching statistics of completed jobs
qemu: Silence coverity on optional migration stats
virsh: Add support for completed job stats
qemu: Transfer migration statistics to destination
qemu: Recompute downtime and total time when migration completes
qemu: Transfer recomputed stats back to source
include/libvirt/libvirt.h.in | 11 ++
src/libvirt.c | 11 +-
src/qemu/qemu_domain.c | 189 ++++++++++++++++++++++++++-
src/qemu/qemu_domain.h | 32 ++++-
src/qemu/qemu_driver.c | 130 ++++--------------
src/qemu/qemu_migration.c | 304 ++++++++++++++++++++++++++++++++++++-------
src/qemu/qemu_monitor_json.c | 10 +-
src/qemu/qemu_process.c | 9 +-
tools/virsh-domain.c | 27 +++-
tools/virsh.pod | 10 +-
10 files changed, 557 insertions(+), 176 deletions(-)
--
2.1.0
8 years, 6 months
[libvirt] Assert with libvirt + xen hvm
by CloudPatch Staff
We're hitting an assert whenever we try to create an HVM instance under Xen
via libvirtd.
System is running on Gentoo, package information as follows:
app-emulation/xen-4.5.0 USE="api debug flask hvm pam pygrub python qemu
screen"
app-emulation/xen-tools-4.5.0 USE="api debug flask hvm pam pygrub python
qemu screen"
app-emulation/libvirt-1.2.11-r2:0/1.2.11 USE="caps libvirtd lvm macvtap nls
qemu udev vepa virtualbox xen"
The following commands are run in parallel:
vmmachine ~ # libvirtd --listen
2015-01-22 16:33:13.596+0000: 2620: info : libvirt version: 1.2.11
2015-01-22 16:33:13.596+0000: 2620: error : udevGetDMIData:1607 : Failed to
get udev device for syspath '/sys/devices/virtual/dmi/id' or
'/sys/class/dmi/id'
libvirtd: libxl_fork.c:350: sigchld_installhandler_core: Assertion
`((void)"application must negotiate with libxl about SIGCHLD",
!(sigchld_saved_action.sa_flags & 4) &&
(sigchld_saved_action.__sigaction_handler.sa_handler == ((__sighandler_t)
0) || sigchld_saved_action.__sigaction_handler.sa_handler ==
((__sighandler_t) 1)))' failed.
Aborted
vmmachine ~ # VIRSH_DEBUG=0 virsh create xml
create: file(optdata): xml
libvirt: XML-RPC error : End of file while reading data: Input/output error
error: Failed to create domain from xml
error: End of file while reading data: Input/output error
libvirt: Domain Config error : Requested operation is not valid: A
different callback was requested
9 years
[libvirt] [java] [PATCH 0/6] Fix JNA wrapping, fix memory leaks and wrap security model / label function
by Claudio Bley
Hi.
First and foremost, this series fixes a few mistakes in the wrapping
code found by inspecting the org.libvirt.jna.Libvirt interface and the
corresponding C types of the XML API file.
The last two patches add two missing functions introduced in libvirt
0.6.1.
At the end of the day, this means libvirt-java has gained full
coverage of the libvirt functions up to and including version
0.8.5. Yay!
Claudio Bley (6):
JNA: fix wrong return type void vs. int
JNA: add CString class and fix memory leaks
JNA: simplify freeing memory for C strings
Use the CString class for Arrays of CStrings too
Implement Domain.getSecurityLabel and add SecurityLabel class
Implement Connect.getSecurityModel and add SecurityModel class
src/main/java/org/libvirt/Connect.java | 74 +++++++++--------
src/main/java/org/libvirt/Device.java | 9 +-
src/main/java/org/libvirt/Domain.java | 57 ++++++-------
src/main/java/org/libvirt/DomainSnapshot.java | 8 +-
src/main/java/org/libvirt/Interface.java | 7 +-
src/main/java/org/libvirt/Library.java | 44 +++-------
src/main/java/org/libvirt/Network.java | 14 +---
src/main/java/org/libvirt/NetworkFilter.java | 2 +-
src/main/java/org/libvirt/Secret.java | 2 +-
src/main/java/org/libvirt/SecurityLabel.java | 49 +++++++++++
src/main/java/org/libvirt/SecurityModel.java | 37 +++++++++
src/main/java/org/libvirt/StoragePool.java | 9 +-
src/main/java/org/libvirt/StorageVol.java | 16 +---
src/main/java/org/libvirt/jna/CString.java | 85 +++++++++++++++++++
src/main/java/org/libvirt/jna/Libvirt.java | 114 +++++++++++++++++---------
15 files changed, 343 insertions(+), 184 deletions(-)
create mode 100644 src/main/java/org/libvirt/SecurityLabel.java
create mode 100644 src/main/java/org/libvirt/SecurityModel.java
create mode 100644 src/main/java/org/libvirt/jna/CString.java
--
2.2.2
9 years, 4 months
[libvirt] [PATCH] Fix virCgroupGetPercpuStats with non-continuous present CPUs
by Ján Tomko
Per-cpu stats are only shown for present CPUs in the cgroups,
but we were only parsing the largest CPU number from
/sys/devices/system/cpu/present and looking for stats even for
non-present CPUs.
This resulted in:
internal error: cpuacct parse error
---
cfg.mk | 2 +-
src/nodeinfo.c | 17 +++++++++++++++++
src/nodeinfo.h | 1 +
src/util/vircgroup.c | 24 ++++++++++++++++++------
tests/vircgroupmock.c | 44 ++++++++++++++++++++++++++++++++++++++------
tests/vircgrouptest.c | 47 +++++++++++++++++++++++++++++++++++------------
6 files changed, 110 insertions(+), 25 deletions(-)
diff --git a/cfg.mk b/cfg.mk
index 21f83c3..70612f8 100644
--- a/cfg.mk
+++ b/cfg.mk
@@ -1095,7 +1095,7 @@ exclude_file_name_regexp--sc_prohibit_asprintf = \
^(bootstrap.conf$$|src/util/virstring\.[ch]$$|tests/vircgroupmock\.c$$)
exclude_file_name_regexp--sc_prohibit_strdup = \
- ^(docs/|examples/|src/util/virstring\.c|tests/virnetserverclientmock.c$$)
+ ^(docs/|examples/|src/util/virstring\.c|tests/vir(netserverclient|cgroup)mock.c$$)
exclude_file_name_regexp--sc_prohibit_close = \
(\.p[yl]$$|\.spec\.in$$|^docs/|^(src/util/virfile\.c|src/libvirt-stream\.c|tests/vir(cgroup|pci)mock\.c)$$)
diff --git a/src/nodeinfo.c b/src/nodeinfo.c
index 3c22ebc..3a27c22 100644
--- a/src/nodeinfo.c
+++ b/src/nodeinfo.c
@@ -1242,6 +1242,23 @@ nodeGetCPUCount(void)
}
virBitmapPtr
+nodeGetPresentCPUBitmap(void)
+{
+ int max_present;
+
+ if ((max_present = nodeGetCPUCount()) < 0)
+ return NULL;
+
+#ifdef __linux__
+ if (virFileExists(SYSFS_SYSTEM_PATH "/cpu/present"))
+ return linuxParseCPUmap(max_present, SYSFS_SYSTEM_PATH "/cpu/present");
+#endif
+ virReportError(VIR_ERR_NO_SUPPORT, "%s",
+ _("non-continuous host cpu numbers not implemented on this platform"));
+ return NULL;
+}
+
+virBitmapPtr
nodeGetCPUBitmap(int *max_id ATTRIBUTE_UNUSED)
{
#ifdef __linux__
diff --git a/src/nodeinfo.h b/src/nodeinfo.h
index a993c63..047bd5c 100644
--- a/src/nodeinfo.h
+++ b/src/nodeinfo.h
@@ -43,6 +43,7 @@ int nodeGetCellsFreeMemory(unsigned long long *freeMems,
int nodeGetMemory(unsigned long long *mem,
unsigned long long *freeMem);
+virBitmapPtr nodeGetPresentCPUBitmap(void);
virBitmapPtr nodeGetCPUBitmap(int *max_id);
int nodeGetCPUCount(void);
diff --git a/src/util/vircgroup.c b/src/util/vircgroup.c
index fe34290..e65617a 100644
--- a/src/util/vircgroup.c
+++ b/src/util/vircgroup.c
@@ -2985,7 +2985,8 @@ static int
virCgroupGetPercpuVcpuSum(virCgroupPtr group,
unsigned int nvcpupids,
unsigned long long *sum_cpu_time,
- unsigned int num)
+ size_t nsum,
+ virBitmapPtr cpumap)
{
int ret = -1;
size_t i;
@@ -2995,7 +2996,7 @@ virCgroupGetPercpuVcpuSum(virCgroupPtr group,
for (i = 0; i < nvcpupids; i++) {
char *pos;
unsigned long long tmp;
- size_t j;
+ ssize_t j;
if (virCgroupNewVcpu(group, i, false, &group_vcpu) < 0)
goto cleanup;
@@ -3004,7 +3005,9 @@ virCgroupGetPercpuVcpuSum(virCgroupPtr group,
goto cleanup;
pos = buf;
- for (j = 0; j < num; j++) {
+ for (j = virBitmapNextSetBit(cpumap, -1);
+ j >= 0 && j < nsum;
+ j = virBitmapNextSetBit(cpumap, j)) {
if (virStrToLong_ull(pos, &pos, 10, &tmp) < 0) {
virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
_("cpuacct parse error"));
@@ -3042,6 +3045,7 @@ virCgroupGetPercpuStats(virCgroupPtr group,
virTypedParameterPtr ent;
int param_idx;
unsigned long long cpu_time;
+ virBitmapPtr cpumap = NULL;
/* return the number of supported params */
if (nparams == 0 && ncpus != 0) {
@@ -3052,9 +3056,11 @@ virCgroupGetPercpuStats(virCgroupPtr group,
}
/* To parse account file, we need to know how many cpus are present. */
- if ((total_cpus = nodeGetCPUCount()) < 0)
+ if (!(cpumap = nodeGetPresentCPUBitmap()))
return rv;
+ total_cpus = virBitmapSize(cpumap);
+
if (ncpus == 0)
return total_cpus;
@@ -3077,7 +3083,11 @@ virCgroupGetPercpuStats(virCgroupPtr group,
need_cpus = MIN(total_cpus, start_cpu + ncpus);
for (i = 0; i < need_cpus; i++) {
- if (virStrToLong_ull(pos, &pos, 10, &cpu_time) < 0) {
+ bool present;
+ ignore_value(virBitmapGetBit(cpumap, i, &present));
+ if (!present) {
+ cpu_time = 0;
+ } else if (virStrToLong_ull(pos, &pos, 10, &cpu_time) < 0) {
virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
_("cpuacct parse error"));
goto cleanup;
@@ -3097,7 +3107,8 @@ virCgroupGetPercpuStats(virCgroupPtr group,
if (VIR_ALLOC_N(sum_cpu_time, need_cpus) < 0)
goto cleanup;
- if (virCgroupGetPercpuVcpuSum(group, nvcpupids, sum_cpu_time, need_cpus) < 0)
+ if (virCgroupGetPercpuVcpuSum(group, nvcpupids, sum_cpu_time, need_cpus,
+ cpumap) < 0)
goto cleanup;
for (i = start_cpu; i < need_cpus; i++) {
@@ -3113,6 +3124,7 @@ virCgroupGetPercpuStats(virCgroupPtr group,
rv = param_idx + 1;
cleanup:
+ virBitmapFree(cpumap);
VIR_FREE(sum_cpu_time);
VIR_FREE(buf);
return rv;
diff --git a/tests/vircgroupmock.c b/tests/vircgroupmock.c
index 6e0a0e7..f2fee7d 100644
--- a/tests/vircgroupmock.c
+++ b/tests/vircgroupmock.c
@@ -51,6 +51,8 @@ const char *fakedevicedir1 = FAKEDEVDIR1;
# define SYSFS_PREFIX "/not/really/sys/fs/cgroup/"
+# define SYSFS_CPU_PRESENT "/sys/devices/system/cpu/present"
+# define SYSFS_CPU_PRESENT_MOCKED "devices_system_cpu_present"
/*
* The plan:
@@ -215,7 +217,15 @@ static int make_controller(const char *path, mode_t mode)
"user 216687025\n"
"system 43421396\n");
MAKE_FILE("cpuacct.usage", "2787788855799582\n");
- MAKE_FILE("cpuacct.usage_percpu", "1413142688153030 1374646168910542\n");
+ MAKE_FILE("cpuacct.usage_percpu",
+ "7059492996 0 0 0 0 0 0 0 4180532496 0 0 0 0 0 0 0 "
+ "1957541268 0 0 0 0 0 0 0 2065932204 0 0 0 0 0 0 0 "
+ "18228689414 0 0 0 0 0 0 0 4245525148 0 0 0 0 0 0 0 "
+ "2911161568 0 0 0 0 0 0 0 1407758136 0 0 0 0 0 0 0 "
+ "1836807700 0 0 0 0 0 0 0 1065296618 0 0 0 0 0 0 0 "
+ "2046213266 0 0 0 0 0 0 0 747889778 0 0 0 0 0 0 0 "
+ "709566900 0 0 0 0 0 0 0 444777342 0 0 0 0 0 0 0 "
+ "5683512916 0 0 0 0 0 0 0 635751356 0 0 0 0 0 0 0\n");
} else if (STRPREFIX(controller, "cpuset")) {
MAKE_FILE("cpuset.cpu_exclusive", "1\n");
if (STREQ(controller, "cpuset"))
@@ -431,6 +441,9 @@ static void init_sysfs(void)
MAKE_CONTROLLER("blkio");
MAKE_CONTROLLER("memory");
MAKE_CONTROLLER("freezer");
+
+ if (make_file(fakesysfsdir, SYSFS_CPU_PRESENT_MOCKED, "8-23,48-159\n") < 0)
+ abort();
}
@@ -623,21 +636,27 @@ int __xstat(int ver, const char *path, struct stat *sb)
int stat(const char *path, struct stat *sb)
{
+ char *newpath = NULL;
int ret;
init_syms();
- if (STRPREFIX(path, SYSFS_PREFIX)) {
+ if (STREQ(path, SYSFS_CPU_PRESENT)) {
+ init_sysfs();
+ if (asprintf(&newpath, "%s/%s",
+ fakesysfsdir,
+ SYSFS_CPU_PRESENT_MOCKED) < 0) {
+ errno = ENOMEM;
+ return -1;
+ }
+ } else if (STRPREFIX(path, SYSFS_PREFIX)) {
init_sysfs();
- char *newpath;
if (asprintf(&newpath, "%s/%s",
fakesysfsdir,
path + strlen(SYSFS_PREFIX)) < 0) {
errno = ENOMEM;
return -1;
}
- ret = realstat(newpath, sb);
- free(newpath);
} else if (STRPREFIX(path, fakedevicedir0)) {
sb->st_mode = S_IFBLK;
sb->st_rdev = makedev(8, 0);
@@ -647,8 +666,11 @@ int stat(const char *path, struct stat *sb)
sb->st_rdev = makedev(9, 0);
return 0;
} else {
- ret = realstat(path, sb);
+ if (!(newpath = strdup(path)))
+ return -1;
}
+ ret = realstat(newpath, sb);
+ free(newpath);
return ret;
}
@@ -682,6 +704,16 @@ int open(const char *path, int flags, ...)
init_syms();
+ if (STREQ(path, SYSFS_CPU_PRESENT)) {
+ init_sysfs();
+ if (asprintf(&newpath, "%s/%s",
+ fakesysfsdir,
+ SYSFS_CPU_PRESENT_MOCKED) < 0) {
+ errno = ENOMEM;
+ return -1;
+ }
+ }
+
if (STRPREFIX(path, SYSFS_PREFIX)) {
init_sysfs();
if (asprintf(&newpath, "%s/%s",
diff --git a/tests/vircgrouptest.c b/tests/vircgrouptest.c
index 35ac0c0..b65ea3f 100644
--- a/tests/vircgrouptest.c
+++ b/tests/vircgrouptest.c
@@ -538,12 +538,35 @@ static int testCgroupGetPercpuStats(const void *args ATTRIBUTE_UNUSED)
virCgroupPtr cgroup = NULL;
size_t i;
int rv, ret = -1;
- virTypedParameter params[2];
+ virTypedParameterPtr params = NULL;
+# define EXPECTED_NCPUS 160
- // TODO: mock nodeGetCPUCount() as well & check 2nd cpu, too
unsigned long long expected[] = {
- 1413142688153030ULL
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 7059492996, 0, 0, 0, 0, 0, 0, 0,
+ 4180532496, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 1957541268, 0, 0, 0, 0, 0, 0, 0,
+ 2065932204, 0, 0, 0, 0, 0, 0, 0,
+ 18228689414, 0, 0, 0, 0, 0, 0, 0,
+ 4245525148, 0, 0, 0, 0, 0, 0, 0,
+ 2911161568, 0, 0, 0, 0, 0, 0, 0,
+ 1407758136, 0, 0, 0, 0, 0, 0, 0,
+ 1836807700, 0, 0, 0, 0, 0, 0, 0,
+ 1065296618, 0, 0, 0, 0, 0, 0, 0,
+ 2046213266, 0, 0, 0, 0, 0, 0, 0,
+ 747889778, 0, 0, 0, 0, 0, 0, 0,
+ 709566900, 0, 0, 0, 0, 0, 0, 0,
+ 444777342, 0, 0, 0, 0, 0, 0, 0,
+ 5683512916, 0, 0, 0, 0, 0, 0, 0,
+ 635751356, 0, 0, 0, 0, 0, 0, 0,
};
+ verify(ARRAY_CARDINALITY(expected) == EXPECTED_NCPUS);
+
+ if (VIR_ALLOC_N(params, EXPECTED_NCPUS) < 0)
+ goto cleanup;
if ((rv = virCgroupNewPartition("/virtualmachines", true,
(1 << VIR_CGROUP_CONTROLLER_CPU) |
@@ -553,37 +576,37 @@ static int testCgroupGetPercpuStats(const void *args ATTRIBUTE_UNUSED)
goto cleanup;
}
- if (nodeGetCPUCount() < 1) {
+ if (nodeGetCPUCount() != EXPECTED_NCPUS) {
fprintf(stderr, "Unexpected: nodeGetCPUCount() yields: %d\n", nodeGetCPUCount());
goto cleanup;
}
if ((rv = virCgroupGetPercpuStats(cgroup,
params,
- 2, 0, 1, 0)) < 0) {
+ 1, 0, EXPECTED_NCPUS, 0)) < 0) {
fprintf(stderr, "Failed call to virCgroupGetPercpuStats for /virtualmachines cgroup: %d\n", -rv);
goto cleanup;
}
- for (i = 0; i < ARRAY_CARDINALITY(expected); i++) {
+ for (i = 0; i < EXPECTED_NCPUS; i++) {
if (!STREQ(params[i].field, VIR_DOMAIN_CPU_STATS_CPUTIME)) {
fprintf(stderr,
- "Wrong parameter name value from virCgroupGetPercpuStats (is: %s)\n",
- params[i].field);
+ "Wrong parameter name value from virCgroupGetPercpuStats at %zu (is: %s)\n",
+ i, params[i].field);
goto cleanup;
}
if (params[i].type != VIR_TYPED_PARAM_ULLONG) {
fprintf(stderr,
- "Wrong parameter value type from virCgroupGetPercpuStats (is: %d)\n",
- params[i].type);
+ "Wrong parameter value type from virCgroupGetPercpuStats at %zu (is: %d)\n",
+ i, params[i].type);
goto cleanup;
}
if (params[i].value.ul != expected[i]) {
fprintf(stderr,
- "Wrong value from virCgroupGetMemoryUsage (expected %llu)\n",
- params[i].value.ul);
+ "Wrong value from virCgroupGetMemoryUsage at %zu (expected %llu)\n",
+ i, params[i].value.ul);
goto cleanup;
}
}
--
2.0.4
9 years, 7 months
[libvirt] securityselinuxlabeltest test fails on v1.2.5
by Scott Sullivan
I am trying to build v1.2.5-maint, however I have one test failing
causing the build to fail:
TEST: securityselinuxlabeltest
!!!. 4 FAIL
PASS: virsh-undefine
=======================================
1 of 112 tests failed
Please report to libvir-list(a)redhat.com
=======================================
make[2]: *** [check-TESTS] Error 1
make[2]: Leaving directory `/home/rpmbuild/packages/libvirt/tests'
make[1]: *** [check-am] Error 2
make[1]: Leaving directory `/home/rpmbuild/packages/libvirt/tests'
make: *** [check-recursive] Error 1
error: Bad exit status from /var/tmp/rpm-tmp.UGNUaq (%build)
Is anyone else having this problem? Im building on CentOS 6.5. Im happy
to provide any further information as needed.
9 years, 7 months
[libvirt] [PATCH] LXC: create a bind mount for sysfs when enable userns but disable netns
by Chen Hanxiao
kernel commit 7dc5dbc879bd0779924b5132a48b731a0bc04a1e
forbid us doing a fresh mount for sysfs
when enable userns but disable netns.
This patch will create a bind mount in this senario.
Signed-off-by: Chen Hanxiao <chenhanxiao(a)cn.fujitsu.com>
---
src/lxc/lxc_container.c | 44 +++++++++++++++++++++++++++++++++-----------
1 file changed, 33 insertions(+), 11 deletions(-)
diff --git a/src/lxc/lxc_container.c b/src/lxc/lxc_container.c
index 4d89677..8a27215 100644
--- a/src/lxc/lxc_container.c
+++ b/src/lxc/lxc_container.c
@@ -815,10 +815,13 @@ static int lxcContainerSetReadOnly(void)
}
-static int lxcContainerMountBasicFS(bool userns_enabled)
+static int lxcContainerMountBasicFS(bool userns_enabled,
+ bool netns_disabled)
{
size_t i;
int rc = -1;
+ char* mnt_src = NULL;
+ int mnt_mflags;
VIR_DEBUG("Mounting basic filesystems");
@@ -826,8 +829,25 @@ static int lxcContainerMountBasicFS(bool userns_enabled)
bool bindOverReadonly;
virLXCBasicMountInfo const *mnt = &lxcBasicMounts[i];
+ /* When enable userns but disable netns, kernel will
+ * forbid us doing a new fresh mount for sysfs.
+ * So we had to do a bind mount for sysfs instead.
+ */
+ if (userns_enabled && netns_disabled &&
+ STREQ(mnt->src, "sysfs")) {
+ if (VIR_STRDUP(mnt_src, "/sys") < 0) {
+ goto cleanup;
+ }
+ mnt_mflags = MS_NOSUID|MS_NOEXEC|MS_NODEV|MS_RDONLY|MS_BIND;
+ } else {
+ if (VIR_STRDUP(mnt_src, mnt->src) < 0) {
+ goto cleanup;
+ }
+ mnt_mflags = mnt->mflags;
+ }
+
VIR_DEBUG("Processing %s -> %s",
- mnt->src, mnt->dst);
+ mnt_src, mnt->dst);
if (mnt->skipUnmounted) {
char *hostdir;
@@ -856,7 +876,7 @@ static int lxcContainerMountBasicFS(bool userns_enabled)
if (virFileMakePath(mnt->dst) < 0) {
virReportSystemError(errno,
_("Failed to mkdir %s"),
- mnt->src);
+ mnt_src);
goto cleanup;
}
@@ -867,24 +887,24 @@ static int lxcContainerMountBasicFS(bool userns_enabled)
* we mount the filesystem in read-write mode initially, and then do a
* separate read-only bind mount on top of that.
*/
- bindOverReadonly = !!(mnt->mflags & MS_RDONLY);
+ bindOverReadonly = !!(mnt_mflags & MS_RDONLY);
VIR_DEBUG("Mount %s on %s type=%s flags=%x",
- mnt->src, mnt->dst, mnt->type, mnt->mflags & ~MS_RDONLY);
- if (mount(mnt->src, mnt->dst, mnt->type, mnt->mflags & ~MS_RDONLY, NULL) < 0) {
+ mnt_src, mnt->dst, mnt->type, mnt_mflags & ~MS_RDONLY);
+ if (mount(mnt_src, mnt->dst, mnt->type, mnt_mflags & ~MS_RDONLY, NULL) < 0) {
virReportSystemError(errno,
_("Failed to mount %s on %s type %s flags=%x"),
- mnt->src, mnt->dst, NULLSTR(mnt->type),
- mnt->mflags & ~MS_RDONLY);
+ mnt_src, mnt->dst, NULLSTR(mnt->type),
+ mnt_mflags & ~MS_RDONLY);
goto cleanup;
}
if (bindOverReadonly &&
- mount(mnt->src, mnt->dst, NULL,
+ mount(mnt_src, mnt->dst, NULL,
MS_BIND|MS_REMOUNT|MS_RDONLY, NULL) < 0) {
virReportSystemError(errno,
_("Failed to re-mount %s on %s flags=%x"),
- mnt->src, mnt->dst,
+ mnt_src, mnt->dst,
MS_BIND|MS_REMOUNT|MS_RDONLY);
goto cleanup;
}
@@ -893,6 +913,7 @@ static int lxcContainerMountBasicFS(bool userns_enabled)
rc = 0;
cleanup:
+ VIR_FREE(mnt_src);
VIR_DEBUG("rc=%d", rc);
return rc;
}
@@ -1643,7 +1664,8 @@ static int lxcContainerSetupPivotRoot(virDomainDefPtr vmDef,
goto cleanup;
/* Mounts the core /proc, /sys, etc filesystems */
- if (lxcContainerMountBasicFS(vmDef->idmap.nuidmap) < 0)
+ if (lxcContainerMountBasicFS(vmDef->idmap.nuidmap,
+ !vmDef->nnets) < 0)
goto cleanup;
/* Ensure entire root filesystem (except /.oldroot) is readonly */
--
1.9.0
9 years, 8 months