[libvirt] [libvirt-designer 1/3] Fix 'dependancy' typo in README file
by Christophe Fergeau
---
README | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/README b/README
index ed39b9d..b7ca356 100644
--- a/README
+++ b/README
@@ -24,7 +24,7 @@ Or to install into a private user specific location
make
make install
-The following mandatory dependancies are required in order to
+The following mandatory dependencies are required in order to
build libvirt-designer
libvirt-gconfig >= 0.1.3 (part of libvirt-glib project releases)
--
1.8.1.4
11 years, 7 months
[libvirt] [PATCH] qemu: Fix setting of memory tunables
by Peter Krempa
Refactoring done in 19c6ad9ac7e7eb2fd3c8262bff5f087b508ad07f didn't
correctly take into account the order cgroup limit modification needs to
be done in. This resulted into errors when decreasing the limits.
The operations need to take place in this order:
decrease hard limit
change swap hard limit
or
change swap hard limit
increase hard limit
This patch also fixes the check if the hard_limit is less than
swap_hard_limit to print better error messages. For this purpose I
introduced a helper function virCompareLimitUlong to compare limit
values where value of 0 is equal to unlimited. Additionally the check is
now applied also when the user does not provide all of the tunables
through the API and in that case the currently set values are used.
This patch resolves:
https://bugzilla.redhat.com/show_bug.cgi?id=950478
---
src/libvirt_private.syms | 1 +
src/qemu/qemu_driver.c | 95 ++++++++++++++++++++++++------------------------
src/util/virutil.c | 12 ++++++
src/util/virutil.h | 2 +
4 files changed, 63 insertions(+), 47 deletions(-)
diff --git a/src/libvirt_private.syms b/src/libvirt_private.syms
index 30fdcd7..ec644ee 100644
--- a/src/libvirt_private.syms
+++ b/src/libvirt_private.syms
@@ -1835,6 +1835,7 @@ safezero;
virArgvToString;
virAsprintf;
virBuildPathInternal;
+virCompareLimitUlong;
virDirCreate;
virDoubleToStr;
virEnumFromString;
diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c
index cee5557..a174fb0 100644
--- a/src/qemu/qemu_driver.c
+++ b/src/qemu/qemu_driver.c
@@ -7103,11 +7103,11 @@ qemuDomainSetMemoryParameters(virDomainPtr dom,
virDomainDefPtr persistentDef = NULL;
virDomainObjPtr vm = NULL;
unsigned long long swap_hard_limit;
- unsigned long long memory_hard_limit;
- unsigned long long memory_soft_limit;
+ unsigned long long hard_limit = 0;
+ unsigned long long soft_limit = 0;
bool set_swap_hard_limit = false;
- bool set_memory_hard_limit = false;
- bool set_memory_soft_limit = false;
+ bool set_hard_limit = false;
+ bool set_soft_limit = false;
virQEMUDriverConfigPtr cfg = NULL;
int ret = -1;
int rc;
@@ -7157,62 +7157,63 @@ qemuDomainSetMemoryParameters(virDomainPtr dom,
set_ ## VALUE = true;
VIR_GET_LIMIT_PARAMETER(VIR_DOMAIN_MEMORY_SWAP_HARD_LIMIT, swap_hard_limit)
- VIR_GET_LIMIT_PARAMETER(VIR_DOMAIN_MEMORY_HARD_LIMIT, memory_hard_limit)
- VIR_GET_LIMIT_PARAMETER(VIR_DOMAIN_MEMORY_SOFT_LIMIT, memory_soft_limit)
+ VIR_GET_LIMIT_PARAMETER(VIR_DOMAIN_MEMORY_HARD_LIMIT, hard_limit)
+ VIR_GET_LIMIT_PARAMETER(VIR_DOMAIN_MEMORY_SOFT_LIMIT, soft_limit)
#undef VIR_GET_LIMIT_PARAMETER
+ /* Swap hard limit must be greater than hard limit.
+ * Note that limit of 0 denotes unlimited */
+ if (set_swap_hard_limit || set_hard_limit) {
+ unsigned long long mem_limit = vm->def->mem.hard_limit;
+ unsigned long long swap_limit = vm->def->mem.swap_hard_limit;
- /* It will fail if hard limit greater than swap hard limit anyway */
- if (set_swap_hard_limit && set_memory_hard_limit &&
- memory_hard_limit > swap_hard_limit) {
- virReportError(VIR_ERR_INVALID_ARG, "%s",
- _("memory hard_limit tunable value must be lower than "
- "swap_hard_limit"));
- goto cleanup;
- }
+ if (set_swap_hard_limit)
+ swap_limit = swap_hard_limit;
- if (set_swap_hard_limit) {
- if (flags & VIR_DOMAIN_AFFECT_LIVE) {
- if ((rc = virCgroupSetMemSwapHardLimit(priv->cgroup, swap_hard_limit)) < 0) {
- virReportSystemError(-rc, "%s",
- _("unable to set memory swap_hard_limit tunable"));
- goto cleanup;
- }
- vm->def->mem.swap_hard_limit = swap_hard_limit;
+ if (set_hard_limit)
+ mem_limit = hard_limit;
+
+ if (virCompareLimitUlong(mem_limit, swap_limit) > 0) {
+ virReportError(VIR_ERR_INVALID_ARG, "%s",
+ _("memory hard_limit tunable value must be lower "
+ "than swap_hard_limit"));
+ goto cleanup;
}
+ }
- if (flags & VIR_DOMAIN_AFFECT_CONFIG)
- persistentDef->mem.swap_hard_limit = swap_hard_limit;
+#define QEMU_SET_MEM_PARAMETER(FUNC, VALUE) \
+ if (set_ ## VALUE) { \
+ if (flags & VIR_DOMAIN_AFFECT_LIVE) { \
+ if ((rc = FUNC(priv->cgroup, VALUE)) < 0) { \
+ virReportSystemError(-rc, _("unable to set memory %s tunable"), \
+ #VALUE); \
+ \
+ goto cleanup; \
+ } \
+ vm->def->mem.VALUE = VALUE; \
+ } \
+ \
+ if (flags & VIR_DOMAIN_AFFECT_CONFIG) \
+ persistentDef->mem.VALUE = VALUE; \
}
- if (set_memory_hard_limit) {
- if (flags & VIR_DOMAIN_AFFECT_LIVE) {
- if ((rc = virCgroupSetMemoryHardLimit(priv->cgroup, memory_hard_limit)) < 0) {
- virReportSystemError(-rc, "%s",
- _("unable to set memory hard_limit tunable"));
- goto cleanup;
- }
- vm->def->mem.hard_limit = memory_hard_limit;
- }
+ /* Soft limit doesn't clash with the others */
+ QEMU_SET_MEM_PARAMETER(virCgroupSetMemorySoftLimit, soft_limit);
- if (flags & VIR_DOMAIN_AFFECT_CONFIG)
- persistentDef->mem.hard_limit = memory_hard_limit;
+ /* set hard limit before swap hard limit if decreasing it */
+ if (virCompareLimitUlong(vm->def->mem.hard_limit, hard_limit) > 0) {
+ QEMU_SET_MEM_PARAMETER(virCgroupSetMemoryHardLimit, hard_limit);
+ /* inhibit changing the limit a second time */
+ set_hard_limit = false;
}
- if (set_memory_soft_limit) {
- if (flags & VIR_DOMAIN_AFFECT_LIVE) {
- if ((rc = virCgroupSetMemorySoftLimit(priv->cgroup, memory_soft_limit)) < 0) {
- virReportSystemError(-rc, "%s",
- _("unable to set memory soft_limit tunable"));
- goto cleanup;
- }
- vm->def->mem.soft_limit = memory_soft_limit;
- }
+ QEMU_SET_MEM_PARAMETER(virCgroupSetMemSwapHardLimit, swap_hard_limit);
- if (flags & VIR_DOMAIN_AFFECT_CONFIG)
- persistentDef->mem.soft_limit = memory_soft_limit;
- }
+ /* otherwise increase it after swap hard limit */
+ QEMU_SET_MEM_PARAMETER(virCgroupSetMemoryHardLimit, hard_limit);
+
+#undef QEMU_SET_MEM_PARAMETER
if (flags & VIR_DOMAIN_AFFECT_CONFIG &&
virDomainSaveConfig(cfg->configDir, persistentDef) < 0)
diff --git a/src/util/virutil.c b/src/util/virutil.c
index 9cc3672..491a004 100644
--- a/src/util/virutil.c
+++ b/src/util/virutil.c
@@ -3832,3 +3832,15 @@ virFindFCHostCapableVport(const char *sysfs_prefix ATTRIBUTE_UNUSED)
}
#endif /* __linux__ */
+
+int
+virCompareLimitUlong(unsigned long long a, unsigned long b)
+{
+ if (a == b)
+ return 0;
+
+ if (a == 0 || a > b)
+ return 1;
+
+ return -1;
+}
diff --git a/src/util/virutil.h b/src/util/virutil.h
index 7b37d65..39033db 100644
--- a/src/util/virutil.h
+++ b/src/util/virutil.h
@@ -324,4 +324,6 @@ char *virGetFCHostNameByWWN(const char *sysfs_prefix,
char *virFindFCHostCapableVport(const char *sysfs_prefix);
+int virCompareLimitUlong(unsigned long long a, unsigned long b);
+
#endif /* __VIR_UTIL_H__ */
--
1.8.1.5
11 years, 7 months
[libvirt] Add UID/GID support to virt-sandbox-service
by dwalsh@redhat.com
This patch set is adding support for UID/GID/USERNAME/USERDIR for use with openshift
containers
Also fixes virt-sandbox-service to not complain if the destdir has been precreated.
Finally we also do not want excess processes running withing containers (/bin/sh).
[sandbox PATCH 1/3] Add UID/GID support for use with interactive
[sandbox PATCH 2/3] Only create the destination path if it does not
[sandbox PATCH 3/3] Do not run a shell within a lxc container by
11 years, 7 months
[libvirt] [PATCH] rpc: message related sizes enlarged
by Viktor Mihajlovski
From: Daniel Hansel <daniel.hansel(a)linux.vnet.ibm.com>
We have seen an issue on s390x platform where domain XMLs larger than 1MB
were used. The define command was finished successfully. The dumpxml command
was not successful (i.e. could not encode message payload).
Enlarged message related sizes (e.g. maximum string size, message size, etc.)
to handle larger system configurations used on s390x platform.
Signed-off-by: Daniel Hansel <daniel.hansel(a)linux.vnet.ibm.com>
Signed-off-by: Viktor Mihajlovski <mihajlov(a)linux.vnet.ibm.com>
---
src/remote/remote_protocol.x | 6 +++---
src/rpc/virnetprotocol.x | 6 +++---
2 files changed, 6 insertions(+), 6 deletions(-)
diff --git a/src/remote/remote_protocol.x b/src/remote/remote_protocol.x
index b957b8e..d492bf3 100644
--- a/src/remote/remote_protocol.x
+++ b/src/remote/remote_protocol.x
@@ -65,7 +65,7 @@
* This is an arbitrary limit designed to stop the decoder from trying
* to allocate unbounded amounts of memory when fed with a bad message.
*/
-const REMOTE_STRING_MAX = 1048576;
+const REMOTE_STRING_MAX = 4194304;
/* A long string, which may NOT be NULL. */
typedef string remote_nonnull_string<REMOTE_STRING_MAX>;
@@ -160,13 +160,13 @@ const REMOTE_DOMAIN_SNAPSHOT_LIST_NAMES_MAX = 1024;
* Note applications need to be aware of this limit and issue multiple
* requests for large amounts of data.
*/
-const REMOTE_DOMAIN_BLOCK_PEEK_BUFFER_MAX = 1048576;
+const REMOTE_DOMAIN_BLOCK_PEEK_BUFFER_MAX = 4194304;
/* Maximum length of a memory peek buffer message.
* Note applications need to be aware of this limit and issue multiple
* requests for large amounts of data.
*/
-const REMOTE_DOMAIN_MEMORY_PEEK_BUFFER_MAX = 1048576;
+const REMOTE_DOMAIN_MEMORY_PEEK_BUFFER_MAX = 4194304;
/*
* Maximum length of a security label list.
diff --git a/src/rpc/virnetprotocol.x b/src/rpc/virnetprotocol.x
index eb2e81d..7d5557c 100644
--- a/src/rpc/virnetprotocol.x
+++ b/src/rpc/virnetprotocol.x
@@ -45,13 +45,13 @@
/*----- Data types. -----*/
/* Maximum total message size (serialised). */
-const VIR_NET_MESSAGE_MAX = 4194304;
+const VIR_NET_MESSAGE_MAX = 16777216;
/* Size of struct virNetMessageHeader (serialised)*/
const VIR_NET_MESSAGE_HEADER_MAX = 24;
/* Size of message payload */
-const VIR_NET_MESSAGE_PAYLOAD_MAX = 4194280;
+const VIR_NET_MESSAGE_PAYLOAD_MAX = 16777192;
/* Size of message length field. Not counted in VIR_NET_MESSAGE_MAX */
const VIR_NET_MESSAGE_LEN_MAX = 4;
@@ -60,7 +60,7 @@ const VIR_NET_MESSAGE_LEN_MAX = 4;
* This is an arbitrary limit designed to stop the decoder from trying
* to allocate unbounded amounts of memory when fed with a bad message.
*/
-const VIR_NET_MESSAGE_STRING_MAX = 1048576;
+const VIR_NET_MESSAGE_STRING_MAX = 4194304;
/* Limit on number of File Descriptors allowed to be
* passed per message
--
1.7.9.5
11 years, 7 months
[libvirt] [PATCH] Replace more cases of /system with /machine
by Daniel P. Berrange
From: "Daniel P. Berrange" <berrange(a)redhat.com>
The change in commit aed4986322fe77bdf718e31a0587d00f04f3d97a
was incomplete, missing a couple of cases of /system. This
caused failure to start VMs.
Pushed under trivial rule
Signed-off-by: Daniel P. Berrange <berrange(a)redhat.com>
---
src/lxc/lxc_cgroup.c | 2 +-
src/qemu/qemu_cgroup.c | 2 +-
2 files changed, 2 insertions(+), 2 deletions(-)
diff --git a/src/lxc/lxc_cgroup.c b/src/lxc/lxc_cgroup.c
index 7311489..4a661da 100644
--- a/src/lxc/lxc_cgroup.c
+++ b/src/lxc/lxc_cgroup.c
@@ -557,7 +557,7 @@ virCgroupPtr virLXCCgroupCreate(virDomainDefPtr def, bool startup)
/* We only auto-create the default partition. In other
* cases we expec the sysadmin/app to have done so */
rc = virCgroupNewPartition(def->resource->partition,
- STREQ(def->resource->partition, "/system"),
+ STREQ(def->resource->partition, "/machine"),
-1,
&parent);
if (rc != 0) {
diff --git a/src/qemu/qemu_cgroup.c b/src/qemu/qemu_cgroup.c
index 3a58f24..891984a 100644
--- a/src/qemu/qemu_cgroup.c
+++ b/src/qemu/qemu_cgroup.c
@@ -256,7 +256,7 @@ int qemuInitCgroup(virQEMUDriverPtr driver,
/* We only auto-create the default partition. In other
* cases we expec the sysadmin/app to have done so */
rc = virCgroupNewPartition(vm->def->resource->partition,
- STREQ(vm->def->resource->partition, "/system"),
+ STREQ(vm->def->resource->partition, "/machine"),
cfg->cgroupControllers,
&parent);
if (rc != 0) {
--
1.8.1.4
11 years, 7 months
[libvirt] virCommandProcessIO: hangs on poll()
by wangxiaojun
recent qemu (git resp) with param like:
#>qemu-kvm -S -no-user-config -nodefaults -nographic -M none -qmp
monarg -pidfile pidfile
will just hangs forever. no any output or errors .
and when libvirt Try to get caps via QMP qemuCaps. it run above command.
so virCommandProcessIO call poll() will be hangs forever.
i patch the libvirt (git resp) with :
diff --git a/src/qemu/qemu_capabilities.c b/src/qemu/qemu_capabilities.c
index 50712b0..915edaa 100644
--- a/src/qemu/qemu_capabilities.c
+++ b/src/qemu/qemu_capabilities.c
@@ -2377,7 +2377,6 @@ virQEMUCapsInitQMP(virQEMUCapsPtr qemuCaps,
virCommandClearCaps(cmd);
virCommandSetGID(cmd, runGid);
virCommandSetUID(cmd, runUid);
-
if (virCommandRun(cmd, &status) < 0)
goto cleanup;
diff --git a/src/util/vircommand.c b/src/util/vircommand.c
index ac56a63..84738f9 100644
--- a/src/util/vircommand.c
+++ b/src/util/vircommand.c
@@ -1824,6 +1824,7 @@ virCommandProcessIO(virCommandPtr cmd)
int i;
struct pollfd fds[3];
int nfds = 0;
+ int pfds = 0;
if (cmd->inpipe != -1) {
fds[nfds].fd = cmd->inpipe;
@@ -1846,8 +1847,8 @@ virCommandProcessIO(virCommandPtr cmd)
if (nfds == 0)
break;
-
- if (poll(fds, nfds, -1) < 0) {
+ pfds = poll(fds, nfds, -1);
+ if ( pfds< 0) {
if (errno == EAGAIN || errno == EINTR)
continue;
virReportSystemError(errno, "%s",
@@ -1855,10 +1856,22 @@ virCommandProcessIO(virCommandPtr cmd)
goto cleanup;
}
- for (i = 0; i < nfds ; i++) {
- if (fds[i].revents & (POLLIN | POLLHUP | POLLERR) &&
+ for (i = 0; i < pfds ; i++) {
+ if (fds[i].revents & (POLLHUP | POLLRDHUP | POLLERR |
POLLNVAL))
+ {
+ if (fds[i].fd == errfd) {
+ VIR_DEBUG("hangup on stderr");
+ } else if (fds[i].fd == outfd) {
+ VIR_DEBUG("hangup on stdout");
+ } else {
+ VIR_DEBUG("hangup on stdin");
+ }
+ errfd = -1;
+ }
+
+ if (fds[i].revents & (POLLIN | POLLHUP | POLLRDHUP |
POLLERR | POLLNVAL) &&
(fds[i].fd == errfd || fds[i].fd == outfd)) {
- char data[1024];
+ char data[1024*2];
char **buf;
size_t *len;
int done;
So everythings is OK.
i use gentoo OS. qemu git source and libvirt git source.
11 years, 7 months
[libvirt] [PATCH] rng: tighten up domain <controller> schema
by Laine Stump
The rng schema for <controller> had been non-specific about which
types of controllers allowed which models, and also allowed the
num_queues attribute (since that hasn't been released yet, should we
rename it to "numQueues"?) and <master> subelement to be included for
any controller type. In reality, half of the models are allowed only
for type='scsi', and the other half only for type='usb', num_queues is
allowed only for type='scsi', and <master> only for type='usb'.
This patch makes a separate <group> for type='scsi' and type='usb',
with each group allowing only the appropriate model values, and
allowing num_queue and <master> only when appropriate.
<interleave> also hadn't been specified, forcing a specific order of
subelements, which should never be done. (Note that the <interleave>
had to surround the main element attributes that are in the <group>
subelements, due to one of the <group>s containing a subelement).
---
docs/schemas/domaincommon.rng | 145 +++++++++++++++++++++++-------------------
1 file changed, 81 insertions(+), 64 deletions(-)
diff --git a/docs/schemas/domaincommon.rng b/docs/schemas/domaincommon.rng
index c96a247..26523a7 100644
--- a/docs/schemas/domaincommon.rng
+++ b/docs/schemas/domaincommon.rng
@@ -1402,80 +1402,97 @@
</define>
<define name="controller">
<element name="controller">
- <choice>
- <group>
- <optional>
+ <attribute name="index">
+ <ref name="unsignedInt"/>
+ </attribute>
+ <interleave>
+ <optional>
+ <ref name="alias"/>
+ </optional>
+ <optional>
+ <ref name="address"/>
+ </optional>
+ <choice>
+ <!-- fdc/ide/sata/ccid have only the common attributes -->
+ <group>
<attribute name="type">
<choice>
<value>fdc</value>
<value>ide</value>
- <value>scsi</value>
<value>sata</value>
<value>ccid</value>
- <value>usb</value>
</choice>
</attribute>
- </optional>
- </group>
- <!-- virtio-serial can have 2 additional attributes -->
- <group>
- <attribute name="type">
- <value>virtio-serial</value>
- </attribute>
- <optional>
- <attribute name="ports">
- <ref name="unsignedInt"/>
+ </group>
+ <!-- scsi has an optional attribute "model" -->
+ <group>
+ <attribute name="type">
+ <value>scsi</value>
</attribute>
- </optional>
- <optional>
- <attribute name="vectors">
- <ref name="unsignedInt"/>
+ <optional>
+ <attribute name="model">
+ <choice>
+ <value>auto</value>
+ <value>buslogic</value>
+ <value>lsilogic</value>
+ <value>lsisas1068</value>
+ <value>vmpvscsi</value>
+ <value>ibmvscsi</value>
+ <value>virtio-scsi</value>
+ <value>lsisas1078</value>
+ </choice>
+ </attribute>
+ </optional>
+ <optional>
+ <attribute name="num_queues">
+ <ref name="unsignedInt"/>
+ </attribute>
+ </optional>
+ </group>
+ <!-- usb has an optional attribute "model", and optional subelement "master" -->
+ <group>
+ <attribute name="type">
+ <value>usb</value>
</attribute>
- </optional>
- </group>
- </choice>
- <attribute name="index">
- <ref name="unsignedInt"/>
- </attribute>
- <optional>
- <attribute name="model">
- <choice>
- <value>auto</value>
- <value>buslogic</value>
- <value>lsilogic</value>
- <value>lsisas1068</value>
- <value>vmpvscsi</value>
- <value>ibmvscsi</value>
- <value>virtio-scsi</value>
- <value>lsisas1078</value>
- <value>piix3-uhci</value>
- <value>piix4-uhci</value>
- <value>ehci</value>
- <value>ich9-ehci1</value>
- <value>ich9-uhci1</value>
- <value>ich9-uhci2</value>
- <value>ich9-uhci3</value>
- <value>vt82c686b-uhci</value>
- <value>pci-ohci</value>
- <value>nec-xhci</value>
- <value>none</value>
- </choice>
- </attribute>
- </optional>
- <optional>
- <attribute name="num_queues">
- <ref name="unsignedInt"/>
- </attribute>
- </optional>
- <optional>
- <ref name="usbmaster"/>
- </optional>
- <optional>
- <ref name="alias"/>
- </optional>
- <optional>
- <ref name="address"/>
- </optional>
+ <optional>
+ <attribute name="model">
+ <choice>
+ <value>piix3-uhci</value>
+ <value>piix4-uhci</value>
+ <value>ehci</value>
+ <value>ich9-ehci1</value>
+ <value>ich9-uhci1</value>
+ <value>ich9-uhci2</value>
+ <value>ich9-uhci3</value>
+ <value>vt82c686b-uhci</value>
+ <value>pci-ohci</value>
+ <value>nec-xhci</value>
+ <value>none</value>
+ </choice>
+ </attribute>
+ </optional>
+ <optional>
+ <ref name="usbmaster"/>
+ </optional>
+ </group>
+ <!-- virtio-serial has optional "ports" and "vectors" -->
+ <group>
+ <attribute name="type">
+ <value>virtio-serial</value>
+ </attribute>
+ <optional>
+ <attribute name="ports">
+ <ref name="unsignedInt"/>
+ </attribute>
+ </optional>
+ <optional>
+ <attribute name="vectors">
+ <ref name="unsignedInt"/>
+ </attribute>
+ </optional>
+ </group>
+ </choice>
+ </interleave>
</element>
</define>
<define name="filesystem">
--
1.7.11.7
11 years, 7 months
[libvirt] [PATCH v1 00/12] Multiple TX queue support
by Michal Privoznik
Kernel and subsequently QEMU learned multiple transmit queues a while ago. The
feature has a nice advantage, it alloes a single guest to transmit multiple
flows of network data using multiple CPUs simultaneously which increase traffic
bandwidth. A lot.
The documentation how to use this is available at [1] or [2].
1: https://git.kernel.org/cgit/linux/kernel/git/davem/net-next.git/tree/Docu...
2: http://git.qemu.org/?p=qemu.git;a=blob;f=qemu-options.hx;hb=HEAD#l1363
Michal Privoznik (12):
Introduce /domain/devices/interface/driver/@queues attribute
qemu: Move interface cmd line construction into a separate function
qemu: Make qemuMonitorAddHostNetwork to pass multiple FDs
qemu: Make qemuMonitorAddHostNetwork to pass multiple FDs
qemu: Adapt command line generation to multiqueue net
util: Learn virNetDevTapCreate multiqueue network
qemu: Allow multiple vhost-net openings
qemu: Rework qemuNetworkIfaceConnect
qemu: Adapt qemuDomainAttachNetDevice to multiqueue net
qemu: Change qemuOpenVhostNet return value
qemu: Adapt qemuBuildInterfaceCommandLine to to multiqueue net
qemu: Enable multiqueue network
docs/formatdomain.html.in | 11 +-
docs/schemas/domaincommon.rng | 5 +
src/conf/domain_conf.c | 15 +
src/conf/domain_conf.h | 1 +
src/network/bridge_driver.c | 2 +-
src/qemu/qemu_command.c | 527 +++++++++++++--------
src/qemu/qemu_command.h | 13 +-
src/qemu/qemu_domain.c | 27 +-
src/qemu/qemu_hotplug.c | 99 ++--
src/qemu/qemu_monitor.c | 78 +--
src/qemu/qemu_monitor.h | 8 +-
src/uml/uml_conf.c | 5 +-
src/util/virnetdevtap.c | 105 ++--
src/util/virnetdevtap.h | 2 +
tests/qemuxml2argvdata/qemuxml2argv-event_idx.xml | 2 +-
.../qemuxml2argv-net-virtio-device.xml | 2 +-
.../qemuxml2argvdata/qemuxml2argv-vhost_queues.xml | 50 ++
tests/qemuxml2argvdata/qemuxml2argv-virtio-lun.xml | 2 +-
tests/qemuxml2xmltest.c | 1 +
19 files changed, 616 insertions(+), 339 deletions(-)
create mode 100644 tests/qemuxml2argvdata/qemuxml2argv-vhost_queues.xml
--
1.8.1.5
11 years, 7 months
[libvirt] [PATCH v3] qemu: Implement CPUs check against machine type's cpu-max
by Michal Novotny
Implement check whether (maximum) vCPUs doesn't exceed machine
type's cpu-max settings.
On older versions of QEMU the check is disabled.
Signed-off-by: Michal Novotny <minovotn(a)redhat.com>
---
src/qemu/qemu_capabilities.c | 38 +++++++++++++++++++++++++++++++++++++-
src/qemu/qemu_capabilities.h | 3 ++-
src/qemu/qemu_monitor.h | 1 +
src/qemu/qemu_monitor_json.c | 7 +++++++
src/qemu/qemu_process.c | 27 +++++++++++++++++++++++++++
5 files changed, 74 insertions(+), 2 deletions(-)
diff --git a/src/qemu/qemu_capabilities.c b/src/qemu/qemu_capabilities.c
index d10c8aa..bbfe85f 100644
--- a/src/qemu/qemu_capabilities.c
+++ b/src/qemu/qemu_capabilities.c
@@ -243,6 +243,7 @@ struct _virQEMUCaps {
size_t nmachineTypes;
char **machineTypes;
char **machineAliases;
+ int *machineMaxCpus;
};
struct _virQEMUCapsCache {
@@ -322,6 +323,7 @@ virQEMUCapsSetDefaultMachine(virQEMUCapsPtr qemuCaps,
{
char *name = qemuCaps->machineTypes[defIdx];
char *alias = qemuCaps->machineAliases[defIdx];
+ int cpu_max = qemuCaps->machineMaxCpus[defIdx];
memmove(qemuCaps->machineTypes + 1,
qemuCaps->machineTypes,
@@ -329,8 +331,12 @@ virQEMUCapsSetDefaultMachine(virQEMUCapsPtr qemuCaps,
memmove(qemuCaps->machineAliases + 1,
qemuCaps->machineAliases,
sizeof(qemuCaps->machineAliases[0]) * defIdx);
+ memmove(qemuCaps->machineMaxCpus + 1,
+ qemuCaps->machineMaxCpus,
+ sizeof(qemuCaps->machineMaxCpus[0]) * defIdx);
qemuCaps->machineTypes[0] = name;
qemuCaps->machineAliases[0] = alias;
+ qemuCaps->machineMaxCpus[0] = cpu_max;
}
/* Format is:
@@ -377,7 +383,8 @@ virQEMUCapsParseMachineTypesStr(const char *output,
}
if (VIR_REALLOC_N(qemuCaps->machineTypes, qemuCaps->nmachineTypes + 1) < 0 ||
- VIR_REALLOC_N(qemuCaps->machineAliases, qemuCaps->nmachineTypes + 1) < 0) {
+ VIR_REALLOC_N(qemuCaps->machineAliases, qemuCaps->nmachineTypes + 1) < 0 ||
+ VIR_REALLOC_N(qemuCaps->machineMaxCpus, qemuCaps->nmachineTypes + 1) < 0) {
VIR_FREE(name);
VIR_FREE(canonical);
goto no_memory;
@@ -390,6 +397,8 @@ virQEMUCapsParseMachineTypesStr(const char *output,
qemuCaps->machineTypes[qemuCaps->nmachineTypes-1] = name;
qemuCaps->machineAliases[qemuCaps->nmachineTypes-1] = NULL;
}
+ /* Value 0 means "unknown" as it's not exposed by QEMU binary */
+ qemuCaps->machineMaxCpus[qemuCaps->nmachineTypes-1] = 0;
} while ((p = next));
@@ -1718,6 +1727,8 @@ virQEMUCapsPtr virQEMUCapsNewCopy(virQEMUCapsPtr qemuCaps)
goto no_memory;
if (VIR_ALLOC_N(ret->machineAliases, qemuCaps->nmachineTypes) < 0)
goto no_memory;
+ if (VIR_ALLOC_N(ret->machineMaxCpus, qemuCaps->nmachineTypes) < 0)
+ goto no_memory;
ret->nmachineTypes = qemuCaps->nmachineTypes;
for (i = 0 ; i < qemuCaps->nmachineTypes ; i++) {
if (!(ret->machineTypes[i] = strdup(qemuCaps->machineTypes[i])))
@@ -1725,6 +1736,7 @@ virQEMUCapsPtr virQEMUCapsNewCopy(virQEMUCapsPtr qemuCaps)
if (qemuCaps->machineAliases[i] &&
!(ret->machineAliases[i] = strdup(qemuCaps->machineAliases[i])))
goto no_memory;
+ ret->machineMaxCpus[i] = qemuCaps->machineMaxCpus[i];
}
return ret;
@@ -1923,6 +1935,25 @@ const char *virQEMUCapsGetCanonicalMachine(virQEMUCapsPtr qemuCaps,
}
+int virQEMUCapsGetMachineMaxCpus(virQEMUCapsPtr qemuCaps,
+ const char *name)
+{
+ size_t i;
+
+ if (!name)
+ return 0;
+
+ for (i = 0 ; i < qemuCaps->nmachineTypes ; i++) {
+ if (!qemuCaps->machineMaxCpus[i])
+ continue;
+ if (STREQ(qemuCaps->machineTypes[i], name))
+ return qemuCaps->machineMaxCpus[i];
+ }
+
+ return 0;
+}
+
+
static int
virQEMUCapsProbeQMPCommands(virQEMUCapsPtr qemuCaps,
qemuMonitorPtr mon)
@@ -2073,6 +2104,10 @@ virQEMUCapsProbeQMPMachineTypes(virQEMUCapsPtr qemuCaps,
virReportOOMError();
goto cleanup;
}
+ if (VIR_ALLOC_N(qemuCaps->machineMaxCpus, nmachines) < 0) {
+ virReportOOMError();
+ goto cleanup;
+ }
for (i = 0 ; i < nmachines ; i++) {
if (machines[i]->alias) {
@@ -2087,6 +2122,7 @@ virQEMUCapsProbeQMPMachineTypes(virQEMUCapsPtr qemuCaps,
}
if (machines[i]->isDefault)
defIdx = i;
+ qemuCaps->machineMaxCpus[i] = machines[i]->cpu_max;
}
qemuCaps->nmachineTypes = nmachines;
diff --git a/src/qemu/qemu_capabilities.h b/src/qemu/qemu_capabilities.h
index 4e76799..bd97e8d 100644
--- a/src/qemu/qemu_capabilities.h
+++ b/src/qemu/qemu_capabilities.h
@@ -223,7 +223,8 @@ size_t virQEMUCapsGetMachineTypes(virQEMUCapsPtr qemuCaps,
char ***names);
const char *virQEMUCapsGetCanonicalMachine(virQEMUCapsPtr qemuCaps,
const char *name);
-
+int virQEMUCapsGetMachineMaxCpus(virQEMUCapsPtr qemuCaps,
+ const char *name);
int virQEMUCapsGetMachineTypesCaps(virQEMUCapsPtr qemuCaps,
size_t *nmachines,
virCapsGuestMachinePtr **machines);
diff --git a/src/qemu/qemu_monitor.h b/src/qemu/qemu_monitor.h
index f39f009..c097953 100644
--- a/src/qemu/qemu_monitor.h
+++ b/src/qemu/qemu_monitor.h
@@ -650,6 +650,7 @@ struct _qemuMonitorMachineInfo {
char *name;
bool isDefault;
char *alias;
+ int cpu_max;
};
int qemuMonitorGetMachines(qemuMonitorPtr mon,
diff --git a/src/qemu/qemu_monitor_json.c b/src/qemu/qemu_monitor_json.c
index 6fdd650..adbd865 100644
--- a/src/qemu/qemu_monitor_json.c
+++ b/src/qemu/qemu_monitor_json.c
@@ -4024,6 +4024,13 @@ int qemuMonitorJSONGetMachines(qemuMonitorPtr mon,
goto cleanup;
}
}
+
+ if (virJSONValueObjectHasKey(child, "cpu-max") &&
+ virJSONValueObjectGetNumberInt(child, "cpu-max", &info->cpu_max) < 0) {
+ virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
+ _("query-machines reply has malformed 'cpu-max' data"));
+ goto cleanup;
+ }
}
ret = n;
diff --git a/src/qemu/qemu_process.c b/src/qemu/qemu_process.c
index ce9f501..9eae8f6 100644
--- a/src/qemu/qemu_process.c
+++ b/src/qemu/qemu_process.c
@@ -3266,6 +3266,30 @@ qemuSetUnprivSGIO(virDomainDiskDefPtr disk)
return ret;
}
+static bool
+qemuValidateCpuMax(virDomainDefPtr def, virQEMUCapsPtr qemuCaps)
+{
+ int cpu_max;
+
+ cpu_max = virQEMUCapsGetMachineMaxCpus(qemuCaps, def->os.machine);
+ if (!cpu_max)
+ return true;
+
+ if (def->vcpus > cpu_max) {
+ virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
+ "%s", _("CPUs greater than specified machine type limit"));
+ return false;
+ }
+
+ if (def->maxvcpus > cpu_max) {
+ virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
+ "%s", _("Maximum CPUs greater than specified machine type limit"));
+ return false;
+ }
+
+ return true;
+}
+
int qemuProcessStart(virConnectPtr conn,
virQEMUDriverPtr driver,
virDomainObjPtr vm,
@@ -3481,6 +3505,9 @@ int qemuProcessStart(virConnectPtr conn,
vm->def->emulator)))
goto cleanup;
+ if (!qemuValidateCpuMax(vm->def, priv->qemuCaps))
+ goto cleanup;
+
if (qemuAssignDeviceAliases(vm->def, priv->qemuCaps) < 0)
goto cleanup;
--
1.7.11.7
11 years, 7 months