[libvirt] [PATCH 0/3] fix some issue around host-passthough cpu model
by Luyao Huang
We support add feature in host-passthough cpu model, but there are
some place need fix.
Luyao Huang (3):
cpu:x86: fix cannot keep cpu feature after migrate/restore
qemu: add a check for non-migratable cpu flags
docs: fix a small xml error in docs
docs/formatdomain.html.in | 2 +-
src/cpu/cpu_x86.c | 9 ++++-----
src/qemu/qemu_migration.c | 2 +-
3 files changed, 6 insertions(+), 7 deletions(-)
--
1.8.3.1
9 years, 6 months
[libvirt] [PATCH v2 0/7] Cleanup flags checking and fix setvcpus
by Pavel Hrdina
The first four patches only cleanup the flags checking in our APIs by
introducing new macros to check exclusive flags and requirements.
Patch 5/7 uses the new macros to do better flags checking for
virDomainSetvcpusFlags API.
Patch 6/7 introduces macro to check virsh options requirements.
The last patch uses the requirement macro to cleanup virsh setvcpus code
and fixes a bug with --maximum option.
Because only the last patch actually fixes a bug issue, I'm not sure whether
this patch series should wait for next release cycle.
Luyao Huang (1):
tools: fix the wrong check when use virsh setvcpus --maximum
Pavel Hrdina (6):
internal: introduce macro helpers to reject exclusive flags
internal: introduce macro helpers to check flag requirements
use new macro helpers to check exclusive flags
use new macro helpers to check flag requirements
qemu: use new macros for setvcpus to check flags and cleanup the code
virsh: introduce new macros to help check flag requirements
src/internal.h | 87 +++++++++++
src/libvirt-domain-snapshot.c | 56 +++-----
src/libvirt-domain.c | 286 +++++++++++--------------------------
src/qemu/qemu_driver.c | 33 +----
src/storage/storage_backend_disk.c | 10 +-
src/storage/storage_backend_fs.c | 11 +-
tools/virsh-domain.c | 30 +---
tools/virsh.h | 52 +++++++
8 files changed, 256 insertions(+), 309 deletions(-)
--
2.0.5
9 years, 6 months
[libvirt] KVM Forum 2015 Call for Participation
by Paolo Bonzini
=================================================================
KVM Forum 2015: Call For Participation
August 19-21, 2015 - Sheraton Seattle - Seattle, WA
(All submissions must be received before midnight May 1, 2015)
=================================================================
KVM is an industry leading open source hypervisor that provides an ideal
platform for datacenter virtualization, virtual desktop infrastructure,
and cloud computing. Once again, it's time to bring together the
community of developers and users that define the KVM ecosystem for
our annual technical conference. We will discuss the current state of
affairs and plan for the future of KVM, its surrounding infrastructure,
and management tools. Mark your calendar and join us in advancing KVM.
http://events.linuxfoundation.org/events/kvm-forum/
This year, the KVM Forum is moving back to North America. We will be
colocated with the Linux Foundation's LinuxCon North America, CloudOpen
North America, ContainerCon and Linux Plumbers Conference events.
Attendees of KVM Forum will also be able to attend a shared hackathon
event with Xen Project Developer Summit on August 18, 2015.
We invite you to lead part of the discussion by submitting a speaking
proposal for KVM Forum 2015.
http://events.linuxfoundation.org/cfp
Suggested topics:
KVM/Kernel
* Scaling and optimizations
* Nested virtualization
* Linux kernel performance improvements
* Resource management (CPU, I/O, memory)
* Hardening and security
* VFIO: SR-IOV, GPU, platform device assignment
* Architecture ports
QEMU
* Management interfaces: QOM and QMP
* New devices, new boards, new architectures
* Scaling and optimizations
* Desktop virtualization and SPICE
* Virtual GPU
* virtio and vhost, including non-Linux or non-virtualized uses
* Hardening and security
* New storage features
* Live migration and fault tolerance
* High availability and continuous backup
* Real-time guest support
* Emulation and TCG
* Firmware: ACPI, UEFI, coreboot, u-Boot, etc.
* Testing
Management and infrastructure
* Managing KVM: Libvirt, OpenStack, oVirt, etc.
* Storage: glusterfs, Ceph, etc.
* Software defined networking: Open vSwitch, OpenDaylight, etc.
* Network Function Virtualization
* Security
* Provisioning
* Performance tuning
===============
SUBMITTING YOUR PROPOSAL
===============
Abstracts due: May 1, 2015
Please submit a short abstract (~150 words) describing your presentation
proposal. Slots vary in length up to 45 minutes. Also include in your
proposal
the proposal type -- one of:
- technical talk
- end-user talk
Submit your proposal here:
http://events.linuxfoundation.org/cfp
Please only use the categories "presentation" and "panel discussion"
You will receive a notification whether or not your presentation proposal
was accepted by May 29, 2015.
Speakers will receive a complimentary pass for the event. In the instance
that your submission has multiple presenters, only the primary speaker for a
proposal will receive a complementary event pass. For panel
discussions, all
panelists will receive a complimentary event pass.
TECHNICAL TALKS
A good technical talk should not just report on what has happened over
the last year; it should present a concrete problem and how it impacts
the user and/or developer community. Whenever applicable, focus on
work that needs to be done, difficulties that haven't yet been solved,
and on decisions that other developers should be aware of. Summarizing
recent developments is okay but it should not be more than a small
portion of the overall talk.
END-USER TALKS
One of the big challenges as developers is to know what, where and how
people actually use our software. We will reserve a few slots for end
users talking about their deployment challenges and achievements.
If you are using KVM in production you are encouraged submit a speaking
proposal. Simply mark it as an end-user talk. As an end user, this is a
unique opportunity to get your input to developers.
HANDS-ON / BOF SESSIONS
We will reserve some time for people to get together and discuss
strategic decisions as well as other topics that are best solved within
smaller groups.
These sessions will be announced during the event. If you are interested
in organizing such a session, please add it to the list at
http://www.linux-kvm.org/page/KVM_Forum_2015_BOF
Let people you think might be interested know about it, and encourage
them to add their names to the wiki page as well. Please try to
add your ideas to the list before KVM Forum starts.
PANEL DISCUSSIONS
If you are proposing a panel discussion, please make sure that you list
all of your potential panelists in your abstract. We will request full
biographies if a panel is accepted.
===============
HOTEL / TRAVEL
===============
KVM Forum 2015 will be taking place at the Sheraton Seattle Hotel. We
are pleased to offer attendees a discounted room rate of US$199/night
(plus applicable taxes) which includes wifi in your guest room.
http://events.linuxfoundation.org/events/kvm-forum/attend/hotel-and-travel
includes further information on the Sheraton Seattle and the discounted
room rate, as well as on transportation and parking options for the hotel.
===============
IMPORTANT DATES
===============
Notification: May 29, 2015
Schedule announced: June 3, 2015
Event dates: August 19-21, 2015
Thank you for your interest in KVM. We're looking forward to your
submissions and seeing you at the KVM Forum 2015 in August!
-your KVM Forum 2015 Program Committee
Please contact us with any questions or comments.
9 years, 7 months
[libvirt] [PATCH] Do not inline virNumaNodeIsAvailable
by Ján Tomko
Explicitly request that virNumaNodeIsAvailable not be inlined.
This fixes the test suite when building with clang (3.5.1).
---
This only leaves the mysterious check-protocol failure.
And too large stack frame size when building the tests with -O0.
src/internal.h | 10 ++++++++++
src/util/virnuma.h | 3 ++-
2 files changed, 12 insertions(+), 1 deletion(-)
diff --git a/src/internal.h b/src/internal.h
index 4d473af..84aa330 100644
--- a/src/internal.h
+++ b/src/internal.h
@@ -139,6 +139,16 @@
# endif
/**
+ * ATTRIBUTE_NOINLINE:
+ *
+ * Macro to indicate a function that cannot be inlined
+ * (e.g. a function that is mocked in the test suite)
+ */
+# ifndef ATTRIBUTE_NOINLINE
+# define ATTRIBUTE_NOINLINE __attribute__((__noinline__))
+# endif
+
+/**
* ATTRIBUTE_SENTINEL:
*
* Macro to check for NULL-terminated varargs lists
diff --git a/src/util/virnuma.h b/src/util/virnuma.h
index 1f3c0ad..4ddcc5a 100644
--- a/src/util/virnuma.h
+++ b/src/util/virnuma.h
@@ -37,7 +37,8 @@ virBitmapPtr virNumaGetHostNodeset(void);
bool virNumaNodesetIsAvailable(virBitmapPtr nodeset);
bool virNumaIsAvailable(void);
int virNumaGetMaxNode(void);
-bool virNumaNodeIsAvailable(int node);
+bool virNumaNodeIsAvailable(int node)
+ ATTRIBUTE_NOINLINE;
int virNumaGetDistances(int node,
int **distances,
int *ndistances);
--
2.0.5
9 years, 7 months
[libvirt] [PATCH] parallels: implement .domainGetMaxMemory
by Dmitry Guryanov
Since we haven't implemented balloon parameters tuning
we can just return amount of memory in this function.
Signed-off-by: Dmitry Guryanov <dguryanov(a)parallels.com>
---
src/parallels/parallels_driver.c | 19 +++++++++++++++++++
1 file changed, 19 insertions(+)
diff --git a/src/parallels/parallels_driver.c b/src/parallels/parallels_driver.c
index 391e927..d13a4e2 100644
--- a/src/parallels/parallels_driver.c
+++ b/src/parallels/parallels_driver.c
@@ -1089,6 +1089,24 @@ parallelsDomainManagedSaveRemove(virDomainPtr domain, unsigned int flags)
return ret;
}
+static unsigned long long
+parallelsDomainGetMaxMemory(virDomainPtr domain)
+{
+ parallelsConnPtr privconn = domain->conn->privateData;
+ virDomainObjPtr dom = NULL;
+ int ret = -1;
+
+ dom = virDomainObjListFindByUUID(privconn->domains, domain->uuid);
+ if (dom == NULL) {
+ parallelsDomNotFoundError(domain);
+ return -1;
+ }
+
+ ret = dom->def->mem.max_balloon;
+ virObjectUnlock(dom);
+ return ret;
+}
+
static virHypervisorDriver parallelsDriver = {
.name = "Parallels",
.connectOpen = parallelsConnectOpen, /* 0.10.0 */
@@ -1133,6 +1151,7 @@ static virHypervisorDriver parallelsDriver = {
.domainHasManagedSaveImage = parallelsDomainHasManagedSaveImage, /* 1.2.13 */
.domainManagedSave = parallelsDomainManagedSave, /* 1.2.14 */
.domainManagedSaveRemove = parallelsDomainManagedSaveRemove, /* 1.2.14 */
+ .domainGetMaxMemory = parallelsDomainGetMaxMemory, /* 1.2.14 */
};
static virConnectDriver parallelsConnectDriver = {
--
2.1.0
9 years, 7 months
[libvirt] [PATCHv2] qemu: Fix issues with maxMemory in qemuDomainSetMemoryFlags()
by Peter Krempa
From: Luyao Huang <lhuang(a)redhat.com>
qemuDomainSetMemoryFlags() would allow to set the initial memory greater
than the <maxMemory> field. While the configuration would not work as
memory hotplug requires NUMA to be enabled and the
qemuDomainSetMemoryFlags() API does not work on NUMA guests this just
fixes a corner case.
The fix is still worth though as it allows to induce an invalid
configuration and make the VM vanish on libvirt restart.
Additionally this tweaks error message to be more accurate.
Signed-off-by: Luyao Huang <lhuang(a)redhat.com>
Signed-off-by: Peter Krempa <pkrempa(a)redhat.com>
---
Version 2 tweaks the error messages to be (possibly) more descriptive.
src/qemu/qemu_driver.c | 10 +++++++++-
1 file changed, 9 insertions(+), 1 deletion(-)
diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c
index 6700fc9..d15931c 100644
--- a/src/qemu/qemu_driver.c
+++ b/src/qemu/qemu_driver.c
@@ -2319,11 +2319,19 @@ static int qemuDomainSetMemoryFlags(virDomainPtr dom, unsigned long newmem,
* is no way to change the individual node sizes with this API */
if (virDomainNumaGetNodeCount(persistentDef->numa) > 0) {
virReportError(VIR_ERR_OPERATION_INVALID, "%s",
- _("maximum memory size of a domain with NUMA "
+ _("initial memory size of a domain with NUMA "
"nodes cannot be modified with this API"));
goto endjob;
}
+ if (persistentDef->mem.max_memory &&
+ persistentDef->mem.max_memory < newmem) {
+ virReportError(VIR_ERR_OPERATION_INVALID, "%s",
+ _("cannot set initial memory size biger than "
+ "the maximum memory size"));
+ goto endjob;
+ }
+
virDomainDefSetMemoryInitial(persistentDef, newmem);
if (persistentDef->mem.cur_balloon > newmem)
--
2.2.2
9 years, 7 months
[libvirt] [PATCH v4 0/9] qemu: Add quorum support to libvirt
by Matthias Gatto
The purpose of these patches is to introduce quorum for libvirt
I've try to follow this proposal:
http://www.redhat.com/archives/libvir-list/2014-May/msg00533.html
This feature ask for 6 task:
1) Allow a _virStorageSource to contain more than one backing store.
Because all the actual libvirt code use the backingStore field
as a pointer and we needs want to change that, I've decide to encapsulate
the backingStore field to simplifie the array manipulation.
2) Add the missing field a quorum need in _virStorageSource and
the VIR_STORAGE_TYPE_QUORUM and VIR_STORAGE_FILE_QUORUM in
their respectives enums.
3) Parse and format the xml
Because a quorum allows to have more than one backing store at the same level
we need to change virDomainDiskDefFormat and virDomainDiskDefParseXML
to call virDomainDiskBackingStoreFormat and virDomainDiskBackingStoreParse
in a loop.
virDomainDiskBackingStoreFormat and virDomainDiskBackingStoreParse can
call themself recursively in a loop because a quorum can contain another
quorum
4) Add nodename
We need to add nodename support in _virStorageSource because qemu
use them for their child.
5) Build qemu string
As for the xml, we have to call the function which create quorum recursively.
But this task have the problem explained here:
http://www.redhat.com/archives/libvir-list/2014-October/msg00529.html
The _virStorageSource missing some informations that can be passed to
a child, and therefore this version of quorum is incomplet.
6) Allow to hotplug/change a disk in a quorum
This part is not present in these patches because for this task
we have to use blockdev-add, and currently libvirt use
device_add for hotpluging that doesn't allow to hotplug quorum childs.
There is 3 way to handle this problem:
1) create a virDomainBlockDevAdd function in libvirt witch call
blockdev-add.
2) use blockdev-add instead of device_add in qemuMonitorJSONAddDevice
3) write a hack which uses blockdev-add when only attaching quorum
(but i'm pretty sure this solution is not the good one)
V2:
-Rebase on master
-Add Documentation
V3:
-Transforme the backingStore field in virStorageSource into
an array of pointer instead of a pointer
-Modify virStorageSourceSetBackingStore to allow it to expand
the backingStore size.
V4:
-Rebase on master
Matthias Gatto (9):
virstoragefile: Add virStorageSourceGetBackingStore
virstoragefile: Always use virStorageSourceGetBackingStore to get
backing store
virstoragefile: Add virStorageSourceSetBackingStore
virstoragefile: Always use virStorageSourceSetBackingStore to set
backing store
virstoragefile: change backingStore to backingStores.
virstoragefile: Add quorum in virstoragefile
domain_conf: Read and Write quorum config
qemu: Add quorum support in qemuBuildDriveDevStr
virstoragefile: Add node-name
docs/formatdomain.html.in | 27 ++++-
docs/schemas/domaincommon.rng | 95 +++++++++++------
docs/schemas/storagecommon.rng | 1 +
docs/schemas/storagevol.rng | 1 +
src/conf/domain_conf.c | 195 ++++++++++++++++++++++++++--------
src/conf/storage_conf.c | 22 ++--
src/libvirt_private.syms | 2 +
src/qemu/qemu_cgroup.c | 4 +-
src/qemu/qemu_command.c | 114 ++++++++++++++++++++
src/qemu/qemu_domain.c | 2 +-
src/qemu/qemu_driver.c | 30 +++---
src/qemu/qemu_migration.c | 1 +
src/security/security_dac.c | 2 +-
src/security/security_selinux.c | 4 +-
src/security/virt-aa-helper.c | 2 +-
src/storage/storage_backend.c | 35 +++---
src/storage/storage_backend_fs.c | 37 ++++---
src/storage/storage_backend_gluster.c | 10 +-
src/storage/storage_backend_logical.c | 15 ++-
src/storage/storage_driver.c | 2 +-
src/util/virstoragefile.c | 116 +++++++++++++++++---
src/util/virstoragefile.h | 13 ++-
tests/virstoragetest.c | 18 ++--
23 files changed, 573 insertions(+), 175 deletions(-)
--
1.8.3.1
9 years, 7 months
[libvirt] Selective block device migration implementation
by Pavel Boldin
Dear Libvirt Developers,
I'm working to implement feature request [1]. The feature request proposes
to enhance `libvirt' code so the API caller can specify which block devices
are to be migrated using e.g. parameters in the `virDomainMigrateToURI3'
call.
There is the following issues:
1. It is obvious to identify devices to be migrated using the
`device_name'. However, these need to be serialized in either 1) a
comma-separated string or in 2) a set of values named like `blockdevice%d'
with `blockdevice' value holding amount of block devices to migrate. What
is the desired approach here? Can block device name contain commas or
should I neglect this possibility?
2. `libvirt' behavior in block devices migration was copied from the
`QEMU' implementation that ignores read-only devices as well. So, `libvirt'
code will need to pass this list to `QEMU' `migrate' QMP command and this
argument should be implemented in the `QEMU'.
Is there any implementation advices from your side?
Pavel
[1] https://bugzilla.redhat.com/show_bug.cgi?id=1203032
9 years, 7 months
[libvirt] [PATCH 0/5] libxl: improve xl config parsing
by Jim Fehlig
This series was inspired by Marek's and Chunyan's patches to add support
for <kernel>, <initrd>, and <cmdline> in Xen HVM domain config
https://www.redhat.com/archives/libvir-list/2015-March/msg00328.html
https://www.redhat.com/archives/libvir-list/2014-September/msg01006.html
Patches 1 and 2 are trivial prep for patch 3, which moves parsing and
formatting of <os> config out of the common code and into the xl and xm
specfic parsing/formatting code. For ease of review, identical copies
of xen{Parse,Format}OS are made in xen_{xl,xm}.c. Changes to the xl
parsing/formatting functions are made in patch 4 and 5.
Changing the order in which config is parsed/formatted has the
unfortunate side affect of requiring corresponding changes to the
test config data files. Patch 3 shoulders that burden.
Jim Fehlig (5):
xenconfig: export xenConfigCopyString
xenconfig: remove redunant parsing of device_model
xenconfig: move <os> parsing/formating to config-specific files
xenconfig: don't use "kernel" for hvmloader
libxl: support HVM direct kernel boot
src/libxl/libxl_conf.c | 9 ++
src/xenconfig/xen_common.c | 146 +----------------
src/xenconfig/xen_common.h | 5 +
src/xenconfig/xen_xl.c | 178 +++++++++++++++++++++
src/xenconfig/xen_xm.c | 141 ++++++++++++++++
tests/testutilsxen.c | 8 +-
.../test-fullvirt-direct-kernel-boot.cfg | 29 ++++
.../test-fullvirt-direct-kernel-boot.xml | 49 ++++++
tests/xlconfigdata/test-fullvirt-multiusb.cfg | 5 +-
tests/xlconfigdata/test-new-disk.cfg | 5 +-
tests/xlconfigdata/test-spice.cfg | 5 +-
tests/xlconfigtest.c | 3 +
tests/xmconfigdata/test-escape-paths.cfg | 6 +-
tests/xmconfigdata/test-fullvirt-force-hpet.cfg | 6 +-
tests/xmconfigdata/test-fullvirt-force-nohpet.cfg | 6 +-
tests/xmconfigdata/test-fullvirt-localtime.cfg | 6 +-
tests/xmconfigdata/test-fullvirt-net-ioemu.cfg | 6 +-
tests/xmconfigdata/test-fullvirt-net-netfront.cfg | 6 +-
tests/xmconfigdata/test-fullvirt-new-cdrom.cfg | 6 +-
tests/xmconfigdata/test-fullvirt-old-cdrom.cfg | 6 +-
tests/xmconfigdata/test-fullvirt-parallel-tcp.cfg | 6 +-
.../test-fullvirt-serial-dev-2-ports.cfg | 6 +-
.../test-fullvirt-serial-dev-2nd-port.cfg | 6 +-
tests/xmconfigdata/test-fullvirt-serial-file.cfg | 6 +-
tests/xmconfigdata/test-fullvirt-serial-null.cfg | 6 +-
tests/xmconfigdata/test-fullvirt-serial-pipe.cfg | 6 +-
tests/xmconfigdata/test-fullvirt-serial-pty.cfg | 6 +-
tests/xmconfigdata/test-fullvirt-serial-stdio.cfg | 6 +-
.../test-fullvirt-serial-tcp-telnet.cfg | 6 +-
tests/xmconfigdata/test-fullvirt-serial-tcp.cfg | 6 +-
tests/xmconfigdata/test-fullvirt-serial-udp.cfg | 6 +-
tests/xmconfigdata/test-fullvirt-serial-unix.cfg | 6 +-
tests/xmconfigdata/test-fullvirt-sound.cfg | 6 +-
tests/xmconfigdata/test-fullvirt-usbmouse.cfg | 6 +-
tests/xmconfigdata/test-fullvirt-usbtablet.cfg | 6 +-
tests/xmconfigdata/test-fullvirt-utc.cfg | 6 +-
tests/xmconfigdata/test-no-source-cdrom.cfg | 6 +-
tests/xmconfigdata/test-paravirt-net-e1000.cfg | 2 +-
tests/xmconfigdata/test-paravirt-net-vifname.cfg | 2 +-
.../test-paravirt-new-pvfb-vncdisplay.cfg | 2 +-
tests/xmconfigdata/test-paravirt-new-pvfb.cfg | 2 +-
.../test-paravirt-old-pvfb-vncdisplay.cfg | 2 +-
tests/xmconfigdata/test-paravirt-old-pvfb.cfg | 2 +-
tests/xmconfigdata/test-paravirt-vcpu.cfg | 2 +-
tests/xmconfigdata/test-pci-devs.cfg | 6 +-
45 files changed, 511 insertions(+), 242 deletions(-)
create mode 100644 tests/xlconfigdata/test-fullvirt-direct-kernel-boot.cfg
create mode 100644 tests/xlconfigdata/test-fullvirt-direct-kernel-boot.xml
--
1.8.4.5
9 years, 7 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