[libvirt] [PATCH] build: avoid unsafe functions in libgen.h
by Eric Blake
POSIX says that both basename() and dirname() may return static
storage (aka they are not thread-safe); and that they may but
not must modify their input argument. Furthermore, <libgen.h>
is not available on all platforms. For these reasons, you should
never use these functions in a multi-threaded library.
Gnulib instead recommends a way to avoid the portability nightmare:
gnulib's "dirname.h" provides useful counterparts. The obvious
dir_name() and base_name() are GPL (because they malloc(), but call
exit() on failure) so we can't use them; but the LGPL variants
mdir_name() (malloc's or returns NULL) and last_component (always
points into the incoming string without modifying it, differing
from basename semantics only on corner cases like the empty string
that we shouldn't be hitting in the first place) are already in use
in libvirt. This finishes the swap over to the safe functions.
* cfg.mk (sc_prohibit_libgen): New rule.
* src/util/vircgroup.c: Fix offenders.
* src/parallels/parallels_storage.c (parallelsPoolAddByDomain):
Likewise.
* src/parallels/parallels_network.c (parallelsGetBridgedNetInfo):
Likewise.
* src/node_device/node_device_udev.c (udevProcessSCSIHost)
(udevProcessSCSIDevice): Likewise.
* src/storage/storage_backend_disk.c
(virStorageBackendDiskDeleteVol): Likewise.
* src/util/virpci.c (virPCIGetDeviceAddressFromSysfsLink):
Likewise.
* src/util/virstoragefile.h (_virStorageFileMetadata): Avoid false
positive.
Signed-off-by: Eric Blake <eblake(a)redhat.com>
---
Spotted during a review of Laine's pending work.
cfg.mk | 6 ++++++
src/node_device/node_device_udev.c | 7 ++++---
src/parallels/parallels_network.c | 4 +++-
src/parallels/parallels_storage.c | 8 ++++----
src/storage/storage_backend_disk.c | 5 +++--
src/util/vircgroup.c | 3 +--
src/util/virpci.c | 3 ++-
src/util/virstoragefile.h | 2 +-
8 files changed, 24 insertions(+), 14 deletions(-)
diff --git a/cfg.mk b/cfg.mk
index ebb6613..f0f78f5 100644
--- a/cfg.mk
+++ b/cfg.mk
@@ -493,6 +493,12 @@ sc_prohibit_gethostby:
halt='use getaddrinfo, not gethostby*' \
$(_sc_search_regexp)
+# dirname and basename from <libgen.h> are not required to be thread-safe
+sc_prohibit_libgen:
+ @prohibit='( (base|dir)name *\(|include .libgen\.h)' \
+ halt='use functions from gnulib "dirname.h", not <libgen.h>' \
+ $(_sc_search_regexp)
+
# raw xmlGetProp requires some nasty casts
sc_prohibit_xmlGetProp:
@prohibit='\<xmlGetProp *\(' \
diff --git a/src/node_device/node_device_udev.c b/src/node_device/node_device_udev.c
index 92292be..f98841e 100644
--- a/src/node_device/node_device_udev.c
+++ b/src/node_device/node_device_udev.c
@@ -1,7 +1,7 @@
/*
* node_device_udev.c: node device enumeration - libudev implementation
*
- * Copyright (C) 2009-2012 Red Hat, Inc.
+ * Copyright (C) 2009-2013 Red Hat, Inc.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
@@ -26,6 +26,7 @@
#include <scsi/scsi.h>
#include <c-ctype.h>
+#include "dirname.h"
#include "node_device_udev.h"
#include "virerror.h"
#include "node_device_conf.h"
@@ -653,7 +654,7 @@ static int udevProcessSCSIHost(struct udev_device *device ATTRIBUTE_UNUSED,
union _virNodeDevCapData *data = &def->caps->data;
char *filename = NULL;
- filename = basename(def->sysfs_path);
+ filename = last_component(def->sysfs_path);
if (!STRPREFIX(filename, "host")) {
VIR_ERROR(_("SCSI host found, but its udev name '%s' does "
@@ -774,7 +775,7 @@ static int udevProcessSCSIDevice(struct udev_device *device ATTRIBUTE_UNUSED,
union _virNodeDevCapData *data = &def->caps->data;
char *filename = NULL, *p = NULL;
- filename = basename(def->sysfs_path);
+ filename = last_component(def->sysfs_path);
if (udevStrToLong_ui(filename, &p, 10, &data->scsi.host) == -1) {
goto out;
diff --git a/src/parallels/parallels_network.c b/src/parallels/parallels_network.c
index c61e280..7a9436f 100644
--- a/src/parallels/parallels_network.c
+++ b/src/parallels/parallels_network.c
@@ -2,6 +2,7 @@
* parallels_storage.c: core privconn functions for managing
* Parallels Cloud Server hosts
*
+ * Copyright (C) 2013 Red Hat, Inc.
* Copyright (C) 2012 Parallels, Inc.
*
* This library is free software; you can redistribute it and/or
@@ -23,6 +24,7 @@
#include <config.h>
#include "datatypes.h"
+#include "dirname.h"
#include "viralloc.h"
#include "virerror.h"
#include "md5.h"
@@ -64,7 +66,7 @@ static int parallelsGetBridgedNetInfo(virNetworkDefPtr def, virJSONValuePtr jobj
goto cleanup;
}
- if (!(def->bridge = strdup(basename(bridgePath)))) {
+ if (!(def->bridge = strdup(last_component(bridgePath)))) {
virReportOOMError();
goto cleanup;
}
diff --git a/src/parallels/parallels_storage.c b/src/parallels/parallels_storage.c
index cf2f790..271f370 100644
--- a/src/parallels/parallels_storage.c
+++ b/src/parallels/parallels_storage.c
@@ -2,6 +2,7 @@
* parallels_storage.c: core driver functions for managing
* Parallels Cloud Server hosts
*
+ * Copyright (C) 2013 Red Hat, Inc.
* Copyright (C) 2012 Parallels, Inc.
*
* This library is free software; you can redistribute it and/or
@@ -28,9 +29,9 @@
#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>
-#include <libgen.h>
#include "datatypes.h"
+#include "dirname.h"
#include "viralloc.h"
#include "configmake.h"
#include "virstoragefile.h"
@@ -230,13 +231,12 @@ parallelsPoolAddByDomain(virConnectPtr conn, virDomainObjPtr dom)
virStoragePoolObjPtr pool = NULL;
int j;
- if (!(poolPath = strdup(pdom->home))) {
+ poolPath = mdir_name(pdom->home);
+ if (!poolPath) {
virReportOOMError();
return NULL;
}
- poolPath = dirname(poolPath);
-
for (j = 0; j < pools->count; j++) {
if (STREQ(poolPath, pools->objs[j]->def->target.path)) {
pool = pools->objs[j];
diff --git a/src/storage/storage_backend_disk.c b/src/storage/storage_backend_disk.c
index 40da306..1faf1ae 100644
--- a/src/storage/storage_backend_disk.c
+++ b/src/storage/storage_backend_disk.c
@@ -26,6 +26,7 @@
#include <unistd.h>
#include <stdio.h>
+#include "dirname.h"
#include "virerror.h"
#include "virlog.h"
#include "storage_backend_disk.h"
@@ -728,8 +729,8 @@ virStorageBackendDiskDeleteVol(virConnectPtr conn ATTRIBUTE_UNUSED,
goto cleanup;
}
- dev_name = basename(devpath);
- srcname = basename(pool->def->source.devices[0].path);
+ dev_name = last_component(devpath);
+ srcname = last_component(pool->def->source.devices[0].path);
VIR_DEBUG("dev_name=%s, srcname=%s", dev_name, srcname);
isDevMapperDevice = virIsDevMapperDevice(devpath);
diff --git a/src/util/vircgroup.c b/src/util/vircgroup.c
index 5a2a75c..4c836c7 100644
--- a/src/util/vircgroup.c
+++ b/src/util/vircgroup.c
@@ -1,7 +1,7 @@
/*
* vircgroup.c: methods for managing control cgroups
*
- * Copyright (C) 2010-2012 Red Hat, Inc.
+ * Copyright (C) 2010-2013 Red Hat, Inc.
* Copyright IBM Corp. 2008
*
* This library is free software; you can redistribute it and/or
@@ -37,7 +37,6 @@
#include <sys/stat.h>
#include <sys/types.h>
#include <signal.h>
-#include <libgen.h>
#include <dirent.h>
#define __VIR_CGROUP_ALLOW_INCLUDE_PRIV_H__
diff --git a/src/util/virpci.c b/src/util/virpci.c
index e58010b..5811f22 100644
--- a/src/util/virpci.c
+++ b/src/util/virpci.c
@@ -36,6 +36,7 @@
#include <unistd.h>
#include <stdlib.h>
+#include "dirname.h"
#include "virlog.h"
#include "viralloc.h"
#include "vircommand.h"
@@ -1925,7 +1926,7 @@ virPCIGetDeviceAddressFromSysfsLink(const char *device_link,
return ret;
}
- config_address = basename(device_path);
+ config_address = last_component(device_path);
if (VIR_ALLOC(*bdf) != 0) {
virReportOOMError();
goto out;
diff --git a/src/util/virstoragefile.h b/src/util/virstoragefile.h
index d7b4508..ffe7a54 100644
--- a/src/util/virstoragefile.h
+++ b/src/util/virstoragefile.h
@@ -56,7 +56,7 @@ typedef virStorageFileMetadata *virStorageFileMetadataPtr;
struct _virStorageFileMetadata {
char *backingStore; /* Canonical name (absolute file, or protocol) */
char *backingStoreRaw; /* If file, original name, possibly relative */
- char *directory; /* The directory containing basename(backingStoreRaw) */
+ char *directory; /* The directory containing basename of backingStoreRaw */
int backingStoreFormat; /* enum virStorageFileFormat */
bool backingStoreIsFile;
virStorageFileMetadataPtr backingMeta;
--
1.8.1.4
11 years, 7 months
[libvirt] Error in documentation about memory ballon
by Alexandre Laurent
Hello,
In "Memory Ballon" (
http://www.libvirt.org/formatdomain.html#elementsMemBalloon ) section,
the second XML exemple has an error. Effectively, the documentation
shows the following :
...
<devices>
<watchdog model='virtio'/>
<address type='pci' domain='0x0000' bus='0x00' slot='0x02'
function='0x0'/>
</devices>
</domain>
but it should be
...
<devices>
<memballoon model='virtio'/>
<address type='pci' domain='0x0000' bus='0x00' slot='0x02'
function='0x0'/>
</memballoon>
</devices>
</domain>
Best regards,
11 years, 7 months
[libvirt] [PATCH] qemu: fix build error with older glibc
by Eric Blake
Jim Fehlig reported on IRC that older glibc triggers this warning:
cc1: warnings being treated as errors
qemu/qemu_domain.c: In function 'qemuDomainDefFormatBuf':
qemu/qemu_domain.c:1297: error: declaration of 'remove' shadows a global declaration [-Wshadow]
/usr/include/stdio.h:157: error: shadowed declaration is here [-Wshadow]
make[3]: *** [libvirt_driver_qemu_impl_la-qemu_domain.lo] Error 1
Fix it like we have done in the past (such as commit 2e6322a).
* src/qemu/qemu_domain.c (qemuDomainDefFormatBuf): Avoid shadowing
a function name.
Signed-off-by: Eric Blake <eblake(a)redhat.com>
---
Pushing under the build-breaker rule.
src/qemu/qemu_domain.c | 10 +++++-----
1 file changed, 5 insertions(+), 5 deletions(-)
diff --git a/src/qemu/qemu_domain.c b/src/qemu/qemu_domain.c
index 98ac56f..0ef79cd 100644
--- a/src/qemu/qemu_domain.c
+++ b/src/qemu/qemu_domain.c
@@ -1293,7 +1293,7 @@ qemuDomainDefFormatBuf(virQEMUDriverPtr driver,
if ((flags & VIR_DOMAIN_XML_MIGRATABLE)) {
int i;
- int remove = 0;
+ int toremove = 0;
virDomainControllerDefPtr usb = NULL, pci = NULL;
/* If only the default USB controller is present, we can remove it
@@ -1313,7 +1313,7 @@ qemuDomainDefFormatBuf(virQEMUDriverPtr driver,
if (usb && usb->idx == 0 && usb->model == -1) {
VIR_DEBUG("Removing default USB controller from domain '%s'"
" for migration compatibility", def->name);
- remove++;
+ toremove++;
} else {
usb = NULL;
}
@@ -1334,15 +1334,15 @@ qemuDomainDefFormatBuf(virQEMUDriverPtr driver,
pci->model == VIR_DOMAIN_CONTROLLER_MODEL_PCI_ROOT) {
VIR_DEBUG("Removing default 'pci-root' from domain '%s'"
" for migration compatibility", def->name);
- remove++;
+ toremove++;
} else {
pci = NULL;
}
- if (remove) {
+ if (toremove) {
controllers = def->controllers;
ncontrollers = def->ncontrollers;
- if (VIR_ALLOC_N(def->controllers, ncontrollers - remove) < 0) {
+ if (VIR_ALLOC_N(def->controllers, ncontrollers - toremove) < 0) {
controllers = NULL;
virReportOOMError();
goto cleanup;
--
1.8.1.4
11 years, 7 months
[libvirt] [PATCH] docs: fix memballoon examples
by Ján Tomko
Use a pair of 'memballoon' tags instead of single 'watchdog' one.
Add a few missing colons.
---
Pushed under the trivial rule.
docs/formatdomain.html.in | 9 +++++----
1 file changed, 5 insertions(+), 4 deletions(-)
diff --git a/docs/formatdomain.html.in b/docs/formatdomain.html.in
index 0c0506b..8d43303 100644
--- a/docs/formatdomain.html.in
+++ b/docs/formatdomain.html.in
@@ -4355,7 +4355,7 @@ qemu-kvm -net nic,model=? /dev/null
</p>
<p>
- Example automatically added device with KVM
+ Example: automatically added device with KVM
</p>
<pre>
...
@@ -4365,13 +4365,14 @@ qemu-kvm -net nic,model=? /dev/null
...</pre>
<p>
- Example manually added device with static PCI slot 2 requested
+ Example: manually added device with static PCI slot 2 requested
</p>
<pre>
...
<devices>
- <watchdog model='virtio'/>
- <address type='pci' domain='0x0000' bus='0x00' slot='0x02' function='0x0'/>
+ <memballoon model='virtio'>
+ <address type='pci' domain='0x0000' bus='0x00' slot='0x02' function='0x0'/>
+ </memballoon>
</devices>
</domain></pre>
--
1.8.1.5
11 years, 7 months
[libvirt] [PATCH] conf: reject controllers with duplicate indexes
by Ján Tomko
Reject multiple controllers with the same index,
except for USB controllers.
Multi-function USB controllers can have the same index.
---
src/conf/domain_conf.c | 59 ++++++++++++++++++++++++++++++++++++++++++++++++++
1 file changed, 59 insertions(+)
diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c
index cb69178..b6323fd 100644
--- a/src/conf/domain_conf.c
+++ b/src/conf/domain_conf.c
@@ -2594,6 +2594,63 @@ virDomainDeviceInfoIterate(virDomainDefPtr def,
static int
+virDomainDefRejectDuplicateControllers(virDomainDefPtr def)
+{
+ int max_idx[VIR_DOMAIN_CONTROLLER_TYPE_LAST];
+ virBitmapPtr bitmaps[VIR_DOMAIN_CONTROLLER_TYPE_LAST] = { NULL };
+ virDomainControllerDefPtr cont;
+ size_t nbitmaps = 0;
+ int ret = -1;
+ bool b;
+ int i;
+
+ memset(max_idx, -1, sizeof(max_idx)/sizeof(max_idx[0]));
+
+ for (i = 0; i < def->ncontrollers; i++) {
+ cont = def->controllers[i];
+ if (cont->idx > max_idx[cont->type])
+ max_idx[cont->type] = cont->idx;
+ }
+
+ /* multiple USB controllers with the same index are allowed */
+ max_idx[VIR_DOMAIN_CONTROLLER_TYPE_USB] = -1;
+
+ for (i = 0; i < VIR_DOMAIN_CONTROLLER_TYPE_LAST; i++) {
+ if (max_idx[i] >= 0 && !(bitmaps[i] = virBitmapNew(max_idx[i] + 1)))
+ goto no_memory;
+ nbitmaps++;
+ }
+
+ for (i = 0; i < def->ncontrollers; i++) {
+ cont = def->controllers[i];
+
+ if (max_idx[cont->type] == -1)
+ continue;
+
+ ignore_value(virBitmapGetBit(bitmaps[cont->type], cont->idx, &b));
+ if (b) {
+ virReportError(VIR_ERR_XML_ERROR,
+ _("Multiple '%s' controllers with index '%d'"),
+ virDomainControllerTypeToString(cont->type),
+ cont->idx);
+ goto cleanup;
+ }
+ ignore_value(virBitmapSetBit(bitmaps[cont->type], cont->idx));
+ }
+
+ ret = 0;
+cleanup:
+ for (i = 0; i < nbitmaps; i++)
+ virBitmapFree(bitmaps[i]);
+ return ret;
+
+no_memory:
+ virReportOOMError();
+ goto cleanup;
+}
+
+
+static int
virDomainDefPostParseInternal(virDomainDefPtr def,
virCapsPtr caps ATTRIBUTE_UNUSED)
{
@@ -2673,6 +2730,8 @@ virDomainDefPostParseInternal(virDomainDefPtr def,
}
}
+ if (virDomainDefRejectDuplicateControllers(def) < 0)
+ return -1;
return 0;
no_memory:
--
1.8.1.5
11 years, 7 months
[libvirt] [PATCH] qemu: auto-add pci-root to 'pc-i440*' machines too
by Ján Tomko
Commit b33eb0d missed this machine type.
---
src/qemu/qemu_domain.c | 1 +
1 file changed, 1 insertion(+)
diff --git a/src/qemu/qemu_domain.c b/src/qemu/qemu_domain.c
index 98ac56f..4e88eaf 100644
--- a/src/qemu/qemu_domain.c
+++ b/src/qemu/qemu_domain.c
@@ -687,6 +687,7 @@ qemuDomainDefPostParse(virDomainDefPtr def,
break;
if (!STRPREFIX(def->os.machine, "pc-0.") &&
!STRPREFIX(def->os.machine, "pc-1.") &&
+ !STRPREFIX(def->os.machine, "pc-i440") &&
!STREQ(def->os.machine, "pc") &&
!STRPREFIX(def->os.machine, "rhel"))
break;
--
1.8.1.5
11 years, 7 months
[libvirt] [PATCH] qemu: New XML to disable memory merge at guest startup
by Osier Yang
QEMU introduced command line "-mem-merge=on|off" (defaults to on) to
enable/disable the memory merge (KSM) at guest startup. This exposes
it by new XML:
<memoryBacking>
<nosharepages/>
</memoryBacking>
The XML tag is same with what we used internally for old RHEL.
---
docs/formatdomain.html.in | 13 +++++++---
docs/schemas/domaincommon.rng | 5 ++++
src/conf/domain_conf.c | 20 ++++++++++-----
src/conf/domain_conf.h | 1 +
src/qemu/qemu_capabilities.c | 4 +++
src/qemu/qemu_capabilities.h | 1 +
src/qemu/qemu_command.c | 11 ++++++++
.../qemuxml2argv-nosharepages.args | 4 +++
.../qemuxml2argvdata/qemuxml2argv-nosharepages.xml | 29 ++++++++++++++++++++++
tests/qemuxml2argvtest.c | 1 +
tests/qemuxml2xmltest.c | 1 +
11 files changed, 80 insertions(+), 10 deletions(-)
create mode 100644 tests/qemuxml2argvdata/qemuxml2argv-nosharepages.args
create mode 100644 tests/qemuxml2argvdata/qemuxml2argv-nosharepages.xml
diff --git a/docs/formatdomain.html.in b/docs/formatdomain.html.in
index 0cc56d9..4350610 100644
--- a/docs/formatdomain.html.in
+++ b/docs/formatdomain.html.in
@@ -558,6 +558,7 @@
...
<memoryBacking>
<hugepages/>
+ <nosharepages/>
</memoryBacking>
...
</domain>
@@ -565,10 +566,14 @@
<dl>
<dt><code>memoryBacking</code></dt>
- <dd>The optional <code>memoryBacking</code> element, may have an
- <code>hugepages</code> element set within it. This tells the
- hypervisor that the guest should have its memory allocated using
- hugepages instead of the normal native page size.</dd>
+ <dd>The optional <code>memoryBacking</code> element has two
+ optional elements. The element <code>hugepages</code> tells
+ the hypervisor that the guest should have its memory allocated
+ using hugepages instead of the normal native page size. And the
+ optional element <code>nosharepages</code> tells the hypervisor
+ that share pages (memory merge, KSM) should be disabled on guest
+ startup.
+ </dd>
</dl>
diff --git a/docs/schemas/domaincommon.rng b/docs/schemas/domaincommon.rng
index 468c49c..a1e25ca 100644
--- a/docs/schemas/domaincommon.rng
+++ b/docs/schemas/domaincommon.rng
@@ -495,6 +495,11 @@
<empty/>
</element>
</optional>
+ <optional>
+ <element name="nosharepages">
+ <empty/>
+ </element>
+ </optional>
</element>
</optional>
diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c
index 548368e..231cc41 100644
--- a/src/conf/domain_conf.c
+++ b/src/conf/domain_conf.c
@@ -10018,6 +10018,9 @@ virDomainDefParseXML(xmlDocPtr xml,
if ((node = virXPathNode("./memoryBacking/hugepages", ctxt)))
def->mem.hugepage_backed = true;
+ if ((node = virXPathNode("./memoryBacking/nosharepages", ctxt)))
+ def->mem.nosharepages = true;
+
/* Extract blkio cgroup tunables */
if (virXPathUInt("string(./blkiotune/weight)", ctxt,
&def->blkio.weight) < 0)
@@ -15263,12 +15266,17 @@ virDomainDefFormatInternal(virDomainDefPtr def,
def->mem.swap_hard_limit)
virBufferAddLit(buf, " </memtune>\n");
- if (def->mem.hugepage_backed) {
- virBufferStrcat(buf,
- " <memoryBacking>\n",
- " <hugepages/>\n",
- " </memoryBacking>\n", NULL);
- }
+ if (def->mem.hugepage_backed || def->mem.nosharepages)
+ virBufferAddLit(buf, " <memoryBacking>\n");
+
+ if (def->mem.hugepage_backed)
+ virBufferAddLit(buf, " <hugepages/>\n");
+
+ if (def->mem.nosharepages)
+ virBufferAddLit(buf, " <nosharepages/>\n");
+
+ if (def->mem.hugepage_backed || def->mem.nosharepages)
+ virBufferAddLit(buf, " </memoryBacking>\n");
virBufferAddLit(buf, " <vcpu");
virBufferAsprintf(buf, " placement='%s'",
diff --git a/src/conf/domain_conf.h b/src/conf/domain_conf.h
index f1f01fa..0ba72d5 100644
--- a/src/conf/domain_conf.h
+++ b/src/conf/domain_conf.h
@@ -1811,6 +1811,7 @@ struct _virDomainDef {
unsigned long long max_balloon; /* in kibibytes */
unsigned long long cur_balloon; /* in kibibytes */
bool hugepage_backed;
+ bool nosharepages;
int dump_core; /* enum virDomainMemDump */
unsigned long long hard_limit; /* in kibibytes */
unsigned long long soft_limit; /* in kibibytes */
diff --git a/src/qemu/qemu_capabilities.c b/src/qemu/qemu_capabilities.c
index d10c8aa..e5d89f9 100644
--- a/src/qemu/qemu_capabilities.c
+++ b/src/qemu/qemu_capabilities.c
@@ -220,6 +220,7 @@ VIR_ENUM_IMPL(virQEMUCaps, QEMU_CAPS_LAST,
"machine-usb-opt",
"tpm-passthrough",
"tpm-tis",
+ "mem-merge",
);
struct _virQEMUCaps {
@@ -1082,6 +1083,9 @@ virQEMUCapsComputeCmdFlags(const char *help,
if (strstr(help, "-machine"))
virQEMUCapsSet(qemuCaps, QEMU_CAPS_MACHINE_OPT);
+ if (strstr(help, "-mem-merge"))
+ virQEMUCapsSet(qemuCaps, QEMU_CAPS_MEM_MERGE);
+
/* USB option is supported v1.3.0 onwards */
if (qemuCaps->version >= 1003000)
virQEMUCapsSet(qemuCaps, QEMU_CAPS_MACHINE_USB_OPT);
diff --git a/src/qemu/qemu_capabilities.h b/src/qemu/qemu_capabilities.h
index 4e76799..55ffd35 100644
--- a/src/qemu/qemu_capabilities.h
+++ b/src/qemu/qemu_capabilities.h
@@ -178,6 +178,7 @@ enum virQEMUCapsFlags {
QEMU_CAPS_MACHINE_USB_OPT = 137, /* -machine xxx,usb=on/off */
QEMU_CAPS_DEVICE_TPM_PASSTHROUGH = 138, /* -tpmdev passthrough */
QEMU_CAPS_DEVICE_TPM_TIS = 139, /* -device tpm_tis */
+ QEMU_CAPS_MEM_MERGE = 140, /* Is -mem-merge available? */
QEMU_CAPS_LAST, /* this must always be the last item */
};
diff --git a/src/qemu/qemu_command.c b/src/qemu/qemu_command.c
index 009d42d..bb0ccff 100644
--- a/src/qemu/qemu_command.c
+++ b/src/qemu/qemu_command.c
@@ -5993,6 +5993,17 @@ qemuBuildCommandLine(virConnectPtr conn,
virCommandAddArg(cmd, smp);
VIR_FREE(smp);
+ if (def->mem.nosharepages) {
+ if (virQEMUCapsGet(qemuCaps, QEMU_CAPS_MEM_MERGE)) {
+ virCommandAddArg(cmd, "-mem-merge=off");
+ } else {
+ virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
+ _("the QEMU binary %s does not support to "
+ "disable shared memory"), emulator);
+ goto error;
+ }
+ }
+
if (def->cpu && def->cpu->ncells)
if (qemuBuildNumaArgStr(def, cmd) < 0)
goto error;
diff --git a/tests/qemuxml2argvdata/qemuxml2argv-nosharepages.args b/tests/qemuxml2argvdata/qemuxml2argv-nosharepages.args
new file mode 100644
index 0000000..f9ef1c1
--- /dev/null
+++ b/tests/qemuxml2argvdata/qemuxml2argv-nosharepages.args
@@ -0,0 +1,4 @@
+LC_ALL=C PATH=/bin HOME=/home/test USER=test LOGNAME=test /usr/bin/qemu \
+-S -M pc -m 215 -smp 1 -mem-merge=off -nographic \
+-monitor unix:/tmp/test-monitor,server,nowait -no-acpi \
+-boot c -usb -hda /dev/HostVG/QEMUGuest1 -net none -serial none -parallel none
diff --git a/tests/qemuxml2argvdata/qemuxml2argv-nosharepages.xml b/tests/qemuxml2argvdata/qemuxml2argv-nosharepages.xml
new file mode 100644
index 0000000..57701a0
--- /dev/null
+++ b/tests/qemuxml2argvdata/qemuxml2argv-nosharepages.xml
@@ -0,0 +1,29 @@
+<domain type='qemu'>
+ <name>QEMUGuest1</name>
+ <uuid>c7a5fdbd-edaf-9455-926a-d65c16db1809</uuid>
+ <memory unit='KiB'>219200</memory>
+ <currentMemory unit='KiB'>219200</currentMemory>
+ <memoryBacking>
+ <nosharepages/>
+ </memoryBacking>
+ <vcpu placement='static'>1</vcpu>
+ <os>
+ <type arch='i686' machine='pc'>hvm</type>
+ <boot dev='hd'/>
+ </os>
+ <clock offset='utc'/>
+ <on_poweroff>destroy</on_poweroff>
+ <on_reboot>restart</on_reboot>
+ <on_crash>destroy</on_crash>
+ <devices>
+ <emulator>/usr/bin/qemu</emulator>
+ <disk type='block' device='disk'>
+ <source dev='/dev/HostVG/QEMUGuest1'/>
+ <target dev='hda' bus='ide'/>
+ <address type='drive' controller='0' bus='0' target='0' unit='0'/>
+ </disk>
+ <controller type='ide' index='0'/>
+ <controller type='usb' index='0'/>
+ <memballoon model='virtio'/>
+ </devices>
+</domain>
diff --git a/tests/qemuxml2argvtest.c b/tests/qemuxml2argvtest.c
index 4bf13f0..48aa07e 100644
--- a/tests/qemuxml2argvtest.c
+++ b/tests/qemuxml2argvtest.c
@@ -433,6 +433,7 @@ mymain(void)
DO_TEST("hyperv", NONE);
DO_TEST("hugepages", QEMU_CAPS_MEM_PATH);
+ DO_TEST("nosharepages", QEMU_CAPS_MEM_MERGE);
DO_TEST("disk-cdrom", NONE);
DO_TEST("disk-cdrom-empty", QEMU_CAPS_DRIVE);
DO_TEST("disk-cdrom-tray",
diff --git a/tests/qemuxml2xmltest.c b/tests/qemuxml2xmltest.c
index 7434190..c16f866 100644
--- a/tests/qemuxml2xmltest.c
+++ b/tests/qemuxml2xmltest.c
@@ -157,6 +157,7 @@ mymain(void)
DO_TEST("hyperv");
DO_TEST("hugepages");
+ DO_TEST("nosharepages");
DO_TEST("disk-aio");
DO_TEST("disk-cdrom");
DO_TEST("disk-floppy");
--
1.8.1.4
11 years, 7 months
[libvirt] [PATCH] fix typo introduced by 90430791
by Bamvor Jian Zhang
From: Bamvor Jian Zhang <bamv2005(a)gmail.com>
Signed-off-by: Bamvor Jian Zhang <bjzhang(a)suse.com>
---
src/node_device/node_device_hal.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/src/node_device/node_device_hal.c b/src/node_device/node_device_hal.c
index 4a430dc..63245a9 100644
--- a/src/node_device/node_device_hal.c
+++ b/src/node_device/node_device_hal.c
@@ -764,7 +764,7 @@ static int nodeDeviceClose(virConnectPtr conn ATTRIBUTE_UNUSED)
static virNodeDeviceDriver halNodeDeviceDriver = {
.name = "halNodeDeviceDriver",
.nodeDeviceOpen = nodeDeviceOpen, /* 0.5.0 */
- .nodDeviceClose = nodDeviceClose, /* 0.5.0 */
+ .nodeDeviceClose = nodeDeviceClose, /* 0.5.0 */
.nodeNumOfDevices = nodeNumOfDevices, /* 0.5.0 */
.nodeListDevices = nodeListDevices, /* 0.5.0 */
.connectListAllNodeDevices = nodeListAllNodeDevices, /* 0.10.2 */
--
1.8.1.4
11 years, 7 months
[libvirt] [PATCH] Fix usb master startport parsing
by Martin Kletzander
When all usb controllers connected to the same bus have <master
startport='x'/> specified, none of them have 'id=usb' assigned and
thus qemu fails due to invalid masterport specification (we use 'usb'
for that purpose). Adding a check that at least one of the
controllers is specified without <master startport='x'/> and in case
this happens, don't error out, just emit a warning and fix it within
the first such controller found. This makes UX better by not forcing
them to fix controller definition after removing the only non-master
usb controller.
Signed-off-by: Martin Kletzander <mkletzan(a)redhat.com>
---
src/conf/domain_conf.c | 17 ++++++++++++++---
.../qemuxml2argv-usb-ich9-no-companion.args | 6 ++++++
.../qemuxml2argv-usb-ich9-no-companion.xml | 21 +++++++++++++++++++++
tests/qemuxml2argvtest.c | 3 +++
4 files changed, 44 insertions(+), 3 deletions(-)
create mode 100644 tests/qemuxml2argvdata/qemuxml2argv-usb-ich9-no-companion.args
create mode 100644 tests/qemuxml2argvdata/qemuxml2argv-usb-ich9-no-companion.xml
diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c
index 958b77b..a948cfc 100644
--- a/src/conf/domain_conf.c
+++ b/src/conf/domain_conf.c
@@ -9912,7 +9912,8 @@ virDomainDefParseXML(xmlDocPtr xml,
virHashTablePtr bootHash = NULL;
xmlNodePtr cur;
bool usb_none = false;
- bool usb_other = false;
+ virDomainControllerDefPtr usb_first = NULL;
+ bool usb_master = false;
bool primaryVideo = false;
if (VIR_ALLOC(def) < 0) {
@@ -10855,7 +10856,7 @@ virDomainDefParseXML(xmlDocPtr xml,
/* sanitize handling of "none" usb controller */
if (controller->type == VIR_DOMAIN_CONTROLLER_TYPE_USB) {
if (controller->model == VIR_DOMAIN_CONTROLLER_MODEL_USB_NONE) {
- if (usb_other || usb_none) {
+ if (usb_first || usb_none) {
virDomainControllerDefFree(controller);
virReportError(VIR_ERR_XML_DETAIL, "%s",
_("Can't add another USB controller: "
@@ -10871,14 +10872,24 @@ virDomainDefParseXML(xmlDocPtr xml,
"USB is disabled for this domain"));
goto error;
}
- usb_other = true;
+ usb_first = controller;
}
+
+ if (controller->info.mastertype == VIR_DOMAIN_CONTROLLER_MASTER_NONE)
+ usb_master = true;
}
virDomainControllerInsertPreAlloced(def, controller);
}
VIR_FREE(nodes);
+ if (usb_first && !usb_master) {
+ VIR_WARN("No usb controller specified without master startport, "
+ "omitting startport in first USB controller");
+ usb_first->info.master.usb.startport = 0;
+ usb_first->info.mastertype = VIR_DOMAIN_CONTROLLER_MASTER_NONE;
+ }
+
if (def->virtType == VIR_DOMAIN_VIRT_QEMU ||
def->virtType == VIR_DOMAIN_VIRT_KQEMU ||
def->virtType == VIR_DOMAIN_VIRT_KVM)
diff --git a/tests/qemuxml2argvdata/qemuxml2argv-usb-ich9-no-companion.args b/tests/qemuxml2argvdata/qemuxml2argv-usb-ich9-no-companion.args
new file mode 100644
index 0000000..c97a6d3
--- /dev/null
+++ b/tests/qemuxml2argvdata/qemuxml2argv-usb-ich9-no-companion.args
@@ -0,0 +1,6 @@
+LC_ALL=C PATH=/bin HOME=/home/test USER=test LOGNAME=test /usr/bin/qemu -S -M pc \
+-m 214 -smp 1 -nographic -nodefconfig -nodefaults \
+-chardev socket,id=charmonitor,path=/tmp/test-monitor,server,nowait \
+-mon chardev=charmonitor,id=monitor,mode=readline -no-acpi -boot c \
+-device ich9-usb-uhci2,id=usb,bus=pci.0,addr=0x4 \
+-device virtio-balloon-pci,id=balloon0,bus=pci.0,addr=0x3
diff --git a/tests/qemuxml2argvdata/qemuxml2argv-usb-ich9-no-companion.xml b/tests/qemuxml2argvdata/qemuxml2argv-usb-ich9-no-companion.xml
new file mode 100644
index 0000000..895d932
--- /dev/null
+++ b/tests/qemuxml2argvdata/qemuxml2argv-usb-ich9-no-companion.xml
@@ -0,0 +1,21 @@
+<domain type='qemu'>
+ <name>QEMUGuest1</name>
+ <uuid>c7a5fdbd-edaf-9455-926a-d65c16db1809</uuid>
+ <memory unit='KiB'>219136</memory>
+ <currentMemory unit='KiB'>219136</currentMemory>
+ <vcpu placement='static'>1</vcpu>
+ <os>
+ <type arch='i686' machine='pc'>hvm</type>
+ <boot dev='hd'/>
+ </os>
+ <devices>
+ <emulator>/usr/bin/qemu</emulator>
+ <controller type='usb' index='0' model='ich9-uhci2'>
+ <master startport='2'/>
+ <address type='pci' domain='0x0000' bus='0x00' slot='0x04' function='0'/>
+ </controller>
+ <memballoon model='virtio'>
+ <address type='pci' domain='0x0000' bus='0x00' slot='0x03' function='0'/>
+ </memballoon>
+ </devices>
+</domain>
diff --git a/tests/qemuxml2argvtest.c b/tests/qemuxml2argvtest.c
index f40d002..e485a70 100644
--- a/tests/qemuxml2argvtest.c
+++ b/tests/qemuxml2argvtest.c
@@ -768,6 +768,9 @@ mymain(void)
DO_TEST("usb-ich9-companion",
QEMU_CAPS_CHARDEV, QEMU_CAPS_DEVICE, QEMU_CAPS_NODEFCONFIG,
QEMU_CAPS_PCI_MULTIFUNCTION, QEMU_CAPS_ICH9_USB_EHCI1);
+ DO_TEST("usb-ich9-no-companion",
+ QEMU_CAPS_CHARDEV, QEMU_CAPS_DEVICE, QEMU_CAPS_NODEFCONFIG,
+ QEMU_CAPS_PCI_MULTIFUNCTION, QEMU_CAPS_ICH9_USB_EHCI1);
DO_TEST("usb-hub",
QEMU_CAPS_CHARDEV, QEMU_CAPS_DEVICE, QEMU_CAPS_USB_HUB,
QEMU_CAPS_NODEFCONFIG);
--
1.8.2.1
11 years, 7 months