[libvirt] [PATCH 0/5] Add support for turning off offloading for virtio-net
by Ján Tomko
Ján Tomko (5):
conf: split out virtio net driver formatting
Add virSwitch to data types
conf: remove redundant local variable
conf: add options for disabling segment offloading
qemu: wire up virtio-net segment offloading options
docs/formatdomain.html.in | 27 ++++
docs/schemas/basictypes.rng | 6 +
docs/schemas/domaincommon.rng | 25 +++
src/conf/domain_conf.c | 176 ++++++++++++++++-----
src/conf/domain_conf.h | 5 +
src/qemu/qemu_command.c | 20 +++
.../qemuxml2argv-net-virtio-disable-offloads.args | 8 +
.../qemuxml2argv-net-virtio-disable-offloads.xml | 32 ++++
tests/qemuxml2argvtest.c | 2 +
tests/qemuxml2xmltest.c | 1 +
10 files changed, 262 insertions(+), 40 deletions(-)
create mode 100644 tests/qemuxml2argvdata/qemuxml2argv-net-virtio-disable-offloads.args
create mode 100644 tests/qemuxml2argvdata/qemuxml2argv-net-virtio-disable-offloads.xml
--
1.8.5.5
10 years, 1 month
[libvirt] [PATCH v2 0/2] Expose UEFI binary path
by Michal Privoznik
This is practically reworked v1 from Cole.
Cole Robinson (1):
domaincaps: Expose UEFI binary path, if it exists
Michal Privoznik (1):
qemu_capabilities: Change virQEMUCapsFillDomainCaps signature
docs/formatdomaincaps.html.in | 6 ++
docs/schemas/domaincaps.rng | 17 ++++--
src/conf/domain_capabilities.c | 29 ++++++++++
src/conf/domain_capabilities.h | 8 +++
src/qemu/qemu_capabilities.c | 53 +++++++++++++----
src/qemu/qemu_capabilities.h | 9 ++-
src/qemu/qemu_driver.c | 7 ++-
tests/domaincapsschemadata/domaincaps-full.xml | 2 +
.../domaincaps-qemu_1.6.50-1.xml | 1 +
tests/domaincapstest.c | 66 ++++++++++++++++++----
10 files changed, 167 insertions(+), 31 deletions(-)
--
1.8.5.5
10 years, 1 month
Re: [libvirt] [Qemu-devel] migration: qemu-coroutine-lock.c:141: qemu_co_mutex_unlock: Assertion `mutex->locked == 1' failed
by Eric Blake
[adding libvirt list]
On 09/17/2014 09:04 AM, Stefan Hajnoczi wrote:
> On Wed, Sep 17, 2014 at 10:25 AM, Paolo Bonzini <pbonzini(a)redhat.com> wrote:
>> -----BEGIN PGP SIGNED MESSAGE-----
>> Hash: SHA1
>>
>> Il 17/09/2014 11:06, Stefan Hajnoczi ha scritto:
>>> I think the fundamental problem here is that the mirror block job
>>> on the source host does not synchronize with live migration.
>>>
>>> Remember the mirror block job iterates on the dirty bitmap
>>> whenever it feels like.
>>>
>>> There is no guarantee that the mirror block job has quiesced before
>>> migration handover takes place, right?
>>
>> Libvirt does that. Migration is started only once storage mirroring
>> is out of the bulk phase, and the handover looks like:
>>
>> 1) migration completes
>>
>> 2) because the source VM is stopped, the disk has quiesced on the source
>
> But the mirror block job might still be writing out dirty blocks.
>
>> 3) libvirt sends block-job-complete
>
> No, it sends block-job-cancel after the source QEMU's migration has
> completed. See the qemuMigrationCancelDriveMirror() call in
> src/qemu/qemu_migration.c:qemuMigrationRun().
>
>> 4) libvirt receives BLOCK_JOB_COMPLETED. The disk has now quiesced on
>> the destination as well.
>
> I don't see where this happens in the libvirt source code. Libvirt
> doesn't care about block job events for drive-mirror during migration.
>
> And that's why there could still be I/O going on (since
> block-job-cancel is asynchronous).
>
>> 5) the VM is started on the destination
>>
>> 6) the NBD server is stopped on the destination and the source VM is quit.
>>
>> It is actually a feature that storage migration is completed
>> asynchronously with respect to RAM migration. The problem is that
>> qcow2_invalidate_cache happens between (3) and (5), and it doesn't
>> like the concurrent I/O received by the NBD server.
>
> I agree that qcow2_invalidate_cache() (and any other invalidate cache
> implementations) need to allow concurrent I/O requests.
>
> Either I'm misreading the libvirt code or libvirt is not actually
> ensuring that the block job on the source has cancelled/completed
> before the guest is resumed on the destination. So I think there is
> still a bug, maybe Eric can verify this?
You may indeed be correct that libvirt is not waiting long enough for
the block job to be gone on the source before resuming on the
destination. I didn't write that particular code, so I'm cc'ing the
libvirt list, but I can try and take a look into it, since it's related
to code I've recently touched in getting libvirt to support active layer
block commit.
--
Eric Blake eblake redhat com +1-919-301-3266
Libvirt virtualization library http://libvirt.org
10 years, 1 month
[libvirt] [PATCH v2] rpc: make daemon spawning a bit more intelligent
by Martin Kletzander
This way it behaves more like the daemon itself does (acquiring a
pidfile, deleting the socket before binding, etc.).
Resolves: https://bugzilla.redhat.com/show_bug.cgi?id=927369
Resolves: https://bugzilla.redhat.com/show_bug.cgi?id=1138604
Signed-off-by: Martin Kletzander <mkletzan(a)redhat.com>
---
src/rpc/virnetsocket.c | 65 +++++++++++++++++++++++++++++++++++++++++++-------
1 file changed, 57 insertions(+), 8 deletions(-)
diff --git a/src/rpc/virnetsocket.c b/src/rpc/virnetsocket.c
index 80aeddf..7be1492 100644
--- a/src/rpc/virnetsocket.c
+++ b/src/rpc/virnetsocket.c
@@ -51,9 +51,11 @@
#include "virlog.h"
#include "virfile.h"
#include "virthread.h"
+#include "virpidfile.h"
#include "virprobe.h"
#include "virprocess.h"
#include "virstring.h"
+#include "dirname.h"
#include "passfd.h"
#if WITH_SSH2
@@ -541,7 +543,10 @@ int virNetSocketNewConnectUNIX(const char *path,
const char *binary,
virNetSocketPtr *retsock)
{
+ char *binname = NULL;
+ char *pidpath = NULL;
int fd, passfd = -1;
+ int pidfd = -1;
virSocketAddr localAddr;
virSocketAddr remoteAddr;
@@ -580,16 +585,47 @@ int virNetSocketNewConnectUNIX(const char *path,
goto error;
}
+ if (!(binname = last_component(binary)) || binname[0] == '\0') {
+ virReportError(VIR_ERR_INTERNAL_ERROR,
+ _("Cannot determine basename for binary '%s'"),
+ binary);
+ goto error;
+ }
+
+ if (virPidFileConstructPath(false, NULL, binname, &pidpath) < 0)
+ goto error;
+
+ pidfd = virPidFileAcquirePath(pidpath, false, getpid());
+ VIR_FREE(pidpath);
+ if (pidfd < 0) {
+ /*
+ * This can happen in a very rare case of two clients spawning two
+ * daemons at the same time, and the error in the logs that gets
+ * reset here can be a clue to some future debugging.
+ */
+ virResetLastError();
+ spawnDaemon = false;
+ goto retry;
+ }
+
if ((passfd = socket(PF_UNIX, SOCK_STREAM, 0)) < 0) {
virReportSystemError(errno, "%s", _("Failed to create socket"));
goto error;
}
/*
- * We have to fork() here, because umask() is set
- * per-process, chmod() is racy and fchmod() has undefined
- * behaviour on sockets according to POSIX, so it doesn't
- * work outside Linux.
+ * We already even acquired the pidfile, so no one else should be using
+ * @path right now. So we're OK to unlink it and paying attention to
+ * the return value makes no real sense here. Only if it's not an
+ * abstract socket, of course.
+ */
+ if (path[0] != '@')
+ unlink(path);
+
+ /*
+ * We have to fork() here, because umask() is set per-process, chmod()
+ * is racy and fchmod() has undefined behaviour on sockets according to
+ * POSIX, so it doesn't work outside Linux.
*/
if ((pid = virFork()) < 0)
goto error;
@@ -607,12 +643,15 @@ int virNetSocketNewConnectUNIX(const char *path,
if (status != EXIT_SUCCESS) {
/*
- * OK, so the subprocces failed to bind() the socket. This may mean
- * that another daemon was starting at the same time and succeeded
- * with its bind(). So we'll try connecting again, but this time
- * without spawning the daemon.
+ * OK, so the child failed to bind() the socket. This may mean that
+ * another daemon was starting at the same time and succeeded with
+ * its bind() (even though it should not happen because we using a
+ * pidfile for the race). So we'll try connecting again, but this
+ * time without spawning the daemon.
*/
spawnDaemon = false;
+ VIR_FORCE_CLOSE(pidfd);
+ VIR_FORCE_CLOSE(passfd);
goto retry;
}
@@ -629,6 +668,12 @@ int virNetSocketNewConnectUNIX(const char *path,
goto error;
}
+ /*
+ * Do we need to eliminate the super-rare race here any more? It would
+ * need incorporating the following VIR_FORCE_CLOSE() into a
+ * virCommandHook inside a virNetSocketForkDaemon().
+ */
+ VIR_FORCE_CLOSE(pidfd);
if (virNetSocketForkDaemon(binary, passfd) < 0)
goto error;
}
@@ -645,8 +690,12 @@ int virNetSocketNewConnectUNIX(const char *path,
return 0;
error:
+ if (pidfd > 0)
+ virPidFileDeletePath(pidpath);
+ VIR_FREE(pidpath);
VIR_FORCE_CLOSE(fd);
VIR_FORCE_CLOSE(passfd);
+ VIR_FORCE_CLOSE(pidfd);
if (spawnDaemon)
unlink(path);
return -1;
--
2.1.0
10 years, 1 month
[libvirt] [PATCH] domaincaps: Expose UEFI binary path, if it exists
by Cole Robinson
Check to see if the UEFI binary mentioned in qemu.conf actually
exists, and if so expose it in domcapabilities like
<loader ...>
<value>/path/to/ovmf</value>
</loader>
We introduce some generic domcaps infrastructure for handling
a dynamic list of string values, it may be of use for future bits.
---
docs/formatdomaincaps.html.in | 6 ++++
docs/schemas/domaincaps.rng | 17 ++++++---
src/conf/domain_capabilities.c | 23 ++++++++++++
src/conf/domain_capabilities.h | 8 +++++
src/qemu/qemu_driver.c | 24 +++++++++++++
tests/domaincapsschemadata/domaincaps-full.xml | 1 +
tests/domaincapstest.c | 49 +++++++++++++++++++++-----
7 files changed, 115 insertions(+), 13 deletions(-)
diff --git a/docs/formatdomaincaps.html.in b/docs/formatdomaincaps.html.in
index 34d746d..6959dfe 100644
--- a/docs/formatdomaincaps.html.in
+++ b/docs/formatdomaincaps.html.in
@@ -105,6 +105,7 @@
...
<os supported='yes'>
<loader supported='yes'>
+ <value>/usr/share/OVMF/OVMF_CODE.fd</value>
<enum name='type'>
<value>rom</value>
<value>pflash</value>
@@ -122,6 +123,11 @@
<p>For the <code>loader</code> element, the following can occur:</p>
<dl>
+ <dt>value</dt>
+ <dd>List of known loader paths. Currently this is only used
+ to advertise known locations of OVMF binaries for qemu. Binaries
+ will only be listed if they actually exist on disk.</dd>
+
<dt>type</dt>
<dd>Whether loader is a typical BIOS (<code>rom</code>) or
an UEFI binary (<code>pflash</code>). This refers to
diff --git a/docs/schemas/domaincaps.rng b/docs/schemas/domaincaps.rng
index ad8d966..dfdb9b9 100644
--- a/docs/schemas/domaincaps.rng
+++ b/docs/schemas/domaincaps.rng
@@ -46,6 +46,9 @@
<define name='loader'>
<element name='loader'>
+ <optional>
+ <ref name='value'/>
+ </optional>
<ref name='supported'/>
<ref name='enum'/>
</element>
@@ -85,6 +88,14 @@
</element>
</define>
+ <define name='value'>
+ <zeroOrMore>
+ <element name='value'>
+ <text/>
+ </element>
+ </zeroOrMore>
+ </define>
+
<define name='supported'>
<attribute name='supported'>
<choice>
@@ -100,11 +111,7 @@
<attribute name='name'>
<text/>
</attribute>
- <zeroOrMore>
- <element name='value'>
- <text/>
- </element>
- </zeroOrMore>
+ <ref name='value'/>
</element>
</zeroOrMore>
</define>
diff --git a/src/conf/domain_capabilities.c b/src/conf/domain_capabilities.c
index 5a3c8e7..44e422a 100644
--- a/src/conf/domain_capabilities.c
+++ b/src/conf/domain_capabilities.c
@@ -46,6 +46,15 @@ static int virDomainCapsOnceInit(void)
VIR_ONCE_GLOBAL_INIT(virDomainCaps)
+static void
+virDomainCapsValuesFree(virDomainCapsValuesPtr values)
+{
+ size_t i;
+
+ for (i = 0; i < values->nvalues; i++) {
+ VIR_FREE(values->values[i]);
+ }
+}
static void
virDomainCapsDispose(void *obj)
@@ -54,6 +63,8 @@ virDomainCapsDispose(void *obj)
VIR_FREE(caps->path);
VIR_FREE(caps->machine);
+
+ virDomainCapsValuesFree(&caps->os.loader.values);
}
@@ -156,6 +167,17 @@ virDomainCapsEnumFormat(virBufferPtr buf,
return ret;
}
+static void
+virDomainCapsValuesFormat(virBufferPtr buf,
+ virDomainCapsValuesPtr values)
+{
+ size_t i;
+
+ for (i = 0; i < values->nvalues; i++) {
+ virBufferAsprintf(buf, "<value>%s</value>\n", values->values[i]);
+ }
+}
+
#define FORMAT_PROLOGUE(item) \
do { \
virBufferAsprintf(buf, "<" #item " supported='%s'%s\n", \
@@ -185,6 +207,7 @@ virDomainCapsLoaderFormat(virBufferPtr buf,
{
FORMAT_PROLOGUE(loader);
+ virDomainCapsValuesFormat(buf, &loader->values);
ENUM_PROCESS(loader, type, virDomainLoaderTypeToString);
ENUM_PROCESS(loader, readonly, virTristateBoolTypeToString);
diff --git a/src/conf/domain_capabilities.h b/src/conf/domain_capabilities.h
index 768646b..3d5aaa3 100644
--- a/src/conf/domain_capabilities.h
+++ b/src/conf/domain_capabilities.h
@@ -37,6 +37,13 @@ struct _virDomainCapsEnum {
unsigned int values; /* Bitmask of values supported in the corresponding enum */
};
+typedef struct _virDomainCapsValues virDomainCapsValues;
+typedef virDomainCapsValues *virDomainCapsValuesPtr;
+struct _virDomainCapsValues {
+ char **values; /* raw string values */
+ size_t nvalues; /* number of strings */
+};
+
typedef struct _virDomainCapsDevice virDomainCapsDevice;
typedef virDomainCapsDevice *virDomainCapsDevicePtr;
struct _virDomainCapsDevice {
@@ -47,6 +54,7 @@ typedef struct _virDomainCapsLoader virDomainCapsLoader;
typedef virDomainCapsLoader *virDomainCapsLoaderPtr;
struct _virDomainCapsLoader {
virDomainCapsDevice device;
+ virDomainCapsValues values;
virDomainCapsEnum type; /* Info about virDomainLoader */
virDomainCapsEnum readonly; /* Info about readonly:virTristateBool */
};
diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c
index 6008aeb..4dd9d14 100644
--- a/src/qemu/qemu_driver.c
+++ b/src/qemu/qemu_driver.c
@@ -17282,6 +17282,8 @@ qemuConnectGetDomainCapabilities(virConnectPtr conn,
int virttype; /* virDomainVirtType */
virDomainCapsPtr domCaps = NULL;
int arch = virArchFromHost(); /* virArch */
+ virQEMUDriverConfigPtr cfg = NULL;
+ size_t i;
virCheckFlags(0, ret);
@@ -17356,8 +17358,30 @@ qemuConnectGetDomainCapabilities(virConnectPtr conn,
virQEMUCapsFillDomainCaps(domCaps, qemuCaps);
+ cfg = virQEMUDriverGetConfig(driver);
+ for (i = 0; i < cfg->nloader; i++) {
+ char *filename = cfg->loader[i];
+
+ if (access(filename, F_OK) == 0) {
+ if (VIR_REALLOC_N(domCaps->os.loader.values.values,
+ domCaps->os.loader.values.nvalues + 1) < 0) {
+ goto cleanup;
+ }
+ domCaps->os.loader.values.nvalues++;
+
+ if (VIR_STRDUP(domCaps->os.loader.values.values[
+ domCaps->os.loader.values.nvalues - 1],
+ filename) < 0) {
+ goto cleanup;
+ }
+ } else {
+ VIR_DEBUG("loader filename=%s doesn't exist", filename);
+ }
+ }
+
ret = virDomainCapsFormat(domCaps);
cleanup:
+ virObjectUnref(cfg);
virObjectUnref(domCaps);
virObjectUnref(qemuCaps);
return ret;
diff --git a/tests/domaincapsschemadata/domaincaps-full.xml b/tests/domaincapsschemadata/domaincaps-full.xml
index 9722772..e7f41d7 100644
--- a/tests/domaincapsschemadata/domaincaps-full.xml
+++ b/tests/domaincapsschemadata/domaincaps-full.xml
@@ -6,6 +6,7 @@
<vcpu max='255'/>
<os supported='yes'>
<loader supported='yes'>
+ <value>/foo/test</value>
<enum name='type'>
<value>rom</value>
<value>pflash</value>
diff --git a/tests/domaincapstest.c b/tests/domaincapstest.c
index f240643..ddc4d02 100644
--- a/tests/domaincapstest.c
+++ b/tests/domaincapstest.c
@@ -28,16 +28,37 @@
#define VIR_FROM_THIS VIR_FROM_NONE
-typedef void (*virDomainCapsFill)(virDomainCapsPtr domCaps,
- void *opaque);
+typedef int (*virDomainCapsFill)(virDomainCapsPtr domCaps,
+ void *opaque);
#define SET_ALL_BITS(x) \
memset(&(x.values), 0xff, sizeof(x.values))
-static void
+static int
+fillValues(virDomainCapsValuesPtr values)
+{
+ int ret = -1;
+
+ if (VIR_ALLOC_N(values->values, 1) < 0) {
+ goto cleanup;
+ }
+ values->nvalues = 1;
+
+ if (VIR_STRDUP(values->values[0], "/foo/test") < 0) {
+ goto cleanup;
+ }
+
+ ret = 0;
+ cleanup:
+ return ret;
+}
+
+static int
fillAll(virDomainCapsPtr domCaps,
void *opaque ATTRIBUTE_UNUSED)
{
+ int ret = -1;
+
virDomainCapsOSPtr os = &domCaps->os;
virDomainCapsLoaderPtr loader = &os->loader;
virDomainCapsDeviceDiskPtr disk = &domCaps->disk;
@@ -49,6 +70,9 @@ fillAll(virDomainCapsPtr domCaps,
loader->device.supported = true;
SET_ALL_BITS(loader->type);
SET_ALL_BITS(loader->readonly);
+ if (fillValues(&loader->values) < 0) {
+ goto cleanup;
+ }
disk->device.supported = true;
SET_ALL_BITS(disk->diskDevice);
@@ -60,12 +84,16 @@ fillAll(virDomainCapsPtr domCaps,
SET_ALL_BITS(hostdev->subsysType);
SET_ALL_BITS(hostdev->capsType);
SET_ALL_BITS(hostdev->pciBackend);
+
+ ret = 0;
+ cleanup:
+ return ret;
}
#ifdef WITH_QEMU
# include "testutilsqemu.h"
-static void
+static int
fillQemuCaps(virDomainCapsPtr domCaps,
void *opaque)
{
@@ -82,6 +110,8 @@ fillQemuCaps(virDomainCapsPtr domCaps,
VIR_DOMAIN_HOSTDEV_PCI_BACKEND_DEFAULT,
VIR_DOMAIN_HOSTDEV_PCI_BACKEND_KVM,
VIR_DOMAIN_HOSTDEV_PCI_BACKEND_VFIO);
+
+ return 0;
}
#endif /* WITH_QEMU */
@@ -94,16 +124,19 @@ buildVirDomainCaps(const char *emulatorbin,
virDomainCapsFill fillFunc,
void *opaque)
{
- virDomainCapsPtr domCaps;
+ virDomainCapsPtr domCaps, ret = NULL;
if (!(domCaps = virDomainCapsNew(emulatorbin, machine, arch, type)))
goto cleanup;
- if (fillFunc)
- fillFunc(domCaps, opaque);
+ if (fillFunc && fillFunc(domCaps, opaque) < 0) {
+ virObjectUnref(domCaps);
+ goto cleanup;
+ }
+ ret = domCaps;
cleanup:
- return domCaps;
+ return ret;
}
struct test_virDomainCapsFormatData {
--
2.1.0
10 years, 1 month
[libvirt] [PATCH 1/1] qemu: Add support for multiple versions of 'pseries' machine type
by Pradipta Kr. Banerjee
qemu: Add support for multiple versions of 'pseries' machine type
qemu for IBM Power processor architecture is adding functionality for
supporting multiple 'pseries' machine type versions, each with different
capabilities. This patch is for supporting the same
Signed-off-by: Pradipta Kr. Banerjee <bpradip(a)in.ibm.com>
---
src/qemu/qemu_command.c | 18 +++++++++---------
1 file changed, 9 insertions(+), 9 deletions(-)
diff --git a/src/qemu/qemu_command.c b/src/qemu/qemu_command.c
index e5270bd..3bc3a3f 100644
--- a/src/qemu/qemu_command.c
+++ b/src/qemu/qemu_command.c
@@ -706,7 +706,7 @@ qemuSetSCSIControllerModel(virDomainDefPtr def,
}
} else {
if ((def->os.arch == VIR_ARCH_PPC64) &&
- STREQ(def->os.machine, "pseries")) {
+ STRPREFIX(def->os.machine, "pseries")) {
*model = VIR_DOMAIN_CONTROLLER_MODEL_SCSI_IBMVSCSI;
} else if (virQEMUCapsGet(qemuCaps, QEMU_CAPS_SCSI_LSI)) {
*model = VIR_DOMAIN_CONTROLLER_MODEL_SCSI_LSILOGIC;
@@ -1253,7 +1253,7 @@ int qemuDomainAssignSpaprVIOAddresses(virDomainDefPtr def,
for (i = 0; i < def->nserials; i++) {
if (def->serials[i]->deviceType == VIR_DOMAIN_CHR_DEVICE_TYPE_SERIAL &&
(def->os.arch == VIR_ARCH_PPC64) &&
- STREQ(def->os.machine, "pseries"))
+ STRPREFIX(def->os.machine, "pseries"))
def->serials[i]->info.type = VIR_DOMAIN_DEVICE_ADDRESS_TYPE_SPAPRVIO;
if (qemuAssignSpaprVIOAddress(def, &def->serials[i]->info,
VIO_ADDR_SERIAL) < 0)
@@ -1262,7 +1262,7 @@ int qemuDomainAssignSpaprVIOAddresses(virDomainDefPtr def,
if (def->nvram) {
if (def->os.arch == VIR_ARCH_PPC64 &&
- STREQ(def->os.machine, "pseries"))
+ STRPREFIX(def->os.machine, "pseries"))
def->nvram->info.type = VIR_DOMAIN_DEVICE_ADDRESS_TYPE_SPAPRVIO;
if (qemuAssignSpaprVIOAddress(def, &def->nvram->info,
VIO_ADDR_NVRAM) < 0)
@@ -9454,7 +9454,7 @@ qemuBuildCommandLine(virConnectPtr conn,
if (def->nvram) {
if (def->os.arch == VIR_ARCH_PPC64 &&
- STREQ(def->os.machine, "pseries")) {
+ STRPREFIX(def->os.machine, "pseries")) {
if (!virQEMUCapsGet(qemuCaps, QEMU_CAPS_DEVICE_NVRAM)) {
virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
_("nvram device is not supported by "
@@ -9571,7 +9571,7 @@ qemuBuildSerialChrDeviceStr(char **deviceStr,
{
virBuffer cmd = VIR_BUFFER_INITIALIZER;
- if ((arch == VIR_ARCH_PPC64) && STREQ(machine, "pseries")) {
+ if ((arch == VIR_ARCH_PPC64) && STRPREFIX(machine, "pseries")) {
if (serial->deviceType == VIR_DOMAIN_CHR_DEVICE_TYPE_SERIAL &&
serial->info.type == VIR_DOMAIN_DEVICE_ADDRESS_TYPE_SPAPRVIO) {
virBufferAsprintf(&cmd, "spapr-vty,chardev=char%s",
@@ -9994,7 +9994,7 @@ qemuParseCommandLineDisk(virDomainXMLOptionPtr xmlopt,
goto error;
if (((dom->os.arch == VIR_ARCH_PPC64) &&
- dom->os.machine && STREQ(dom->os.machine, "pseries")))
+ dom->os.machine && STRPREFIX(dom->os.machine, "pseries")))
def->bus = VIR_DOMAIN_DISK_BUS_SCSI;
else
def->bus = VIR_DOMAIN_DISK_BUS_IDE;
@@ -10087,7 +10087,7 @@ qemuParseCommandLineDisk(virDomainXMLOptionPtr xmlopt,
if (STREQ(values[i], "ide")) {
def->bus = VIR_DOMAIN_DISK_BUS_IDE;
if (((dom->os.arch == VIR_ARCH_PPC64) &&
- dom->os.machine && STREQ(dom->os.machine, "pseries"))) {
+ dom->os.machine && STRPREFIX(dom->os.machine, "pseries"))) {
virReportError(VIR_ERR_INTERNAL_ERROR,
_("pseries systems do not support ide devices '%s'"), val);
goto error;
@@ -11332,7 +11332,7 @@ qemuParseCommandLine(virCapsPtr qemuCaps,
if (STREQ(arg, "-cdrom")) {
disk->device = VIR_DOMAIN_DISK_DEVICE_CDROM;
if (((def->os.arch == VIR_ARCH_PPC64) &&
- def->os.machine && STREQ(def->os.machine, "pseries")))
+ def->os.machine && STRPREFIX(def->os.machine, "pseries")))
disk->bus = VIR_DOMAIN_DISK_BUS_SCSI;
if (VIR_STRDUP(disk->dst, "hdc") < 0)
goto error;
@@ -11348,7 +11348,7 @@ qemuParseCommandLine(virCapsPtr qemuCaps,
else
disk->bus = VIR_DOMAIN_DISK_BUS_SCSI;
if (((def->os.arch == VIR_ARCH_PPC64) &&
- def->os.machine && STREQ(def->os.machine, "pseries")))
+ def->os.machine && STRPREFIX(def->os.machine, "pseries")))
disk->bus = VIR_DOMAIN_DISK_BUS_SCSI;
}
if (VIR_STRDUP(disk->dst, arg + 1) < 0)
--
1.9.3
10 years, 1 month
[libvirt] [PATCH V2] libxl: support hvm direct kernel boot
by Chunyan Liu
Xen libxl can support Xen HVM direct kernel boot now. To support
Xen HVM direct kernel boot in libvirt, it still needs some changes
to libvirt code: accept HVM direct kernel boot related configuration
in xml, parse those info into virDomainDefPtr, and fill in related
parts of libxl_domain_build_info, so that libxl can handle. This
patch is just to do this.
Signed-off-by: Chunyan Liu <cyliu(a)suse.com>
---
Changes:
- fix Jim's comments
src/libxl/libxl_conf.c | 18 +++++++++++++++
src/xenconfig/xen_common.c | 57 ++++++++++++++++++++++++++++++++++------------
2 files changed, 60 insertions(+), 15 deletions(-)
diff --git a/src/libxl/libxl_conf.c b/src/libxl/libxl_conf.c
index acba69c..a5bda64 100644
--- a/src/libxl/libxl_conf.c
+++ b/src/libxl/libxl_conf.c
@@ -704,6 +704,15 @@ libxlMakeDomBuildInfo(virDomainDefPtr def,
if (VIR_STRDUP(b_info->u.hvm.boot, bootorder) < 0)
goto error;
+#ifdef LIBXL_HAVE_BUILDINFO_KERNEL
+ if (VIR_STRDUP(b_info->cmdline, def->os.cmdline) < 0)
+ goto error;
+ if (VIR_STRDUP(b_info->kernel, def->os.kernel) < 0)
+ goto error;
+ if (VIR_STRDUP(b_info->ramdisk, def->os.initrd) < 0)
+ goto error;
+#endif
+
if (def->nserials) {
if (def->nserials > 1) {
virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
@@ -748,6 +757,14 @@ libxlMakeDomBuildInfo(virDomainDefPtr def,
virStringSplit(def->os.bootloaderArgs, " \t\n", 0)))
goto error;
}
+#ifdef LIBXL_HAVE_BUILDINFO_KERNEL
+ if (VIR_STRDUP(b_info->cmdline, def->os.cmdline) < 0)
+ goto error;
+ if (VIR_STRDUP(b_info->kernel, def->os.kernel) < 0)
+ goto error;
+ if (VIR_STRDUP(b_info->ramdisk, def->os.initrd) < 0)
+ goto error;
+#else
if (VIR_STRDUP(b_info->u.pv.cmdline, def->os.cmdline) < 0)
goto error;
if (def->os.kernel) {
@@ -758,6 +775,7 @@ libxlMakeDomBuildInfo(virDomainDefPtr def,
}
if (VIR_STRDUP(b_info->u.pv.ramdisk, def->os.initrd) < 0)
goto error;
+#endif
}
return 0;
diff --git a/src/xenconfig/xen_common.c b/src/xenconfig/xen_common.c
index 32954f3..3cf7553 100644
--- a/src/xenconfig/xen_common.c
+++ b/src/xenconfig/xen_common.c
@@ -39,6 +39,9 @@
#include "virstring.h"
#include "xen_common.h"
+#if WITH_LIBXL
+# include <libxl.h>
+#endif
/*
* Convenience method to grab a long int from the config file object
@@ -1053,6 +1056,27 @@ xenParseGeneralMeta(virConfPtr conf, virDomainDefPtr def, virCapsPtr caps)
return 0;
}
+static int
+xenParseCmdline(virConfPtr conf, virDomainDefPtr def)
+{
+ const char *extra, *root;
+
+ if (xenConfigGetString(conf, "extra", &extra, NULL) < 0)
+ return -1;
+
+ if (xenConfigGetString(conf, "root", &root, NULL) < 0)
+ return -1;
+
+ if (root) {
+ if (virAsprintf(&def->os.cmdline, "root=%s %s", root, extra) < 0)
+ return -1;
+ } else {
+ if (VIR_STRDUP(def->os.cmdline, extra) < 0)
+ return -1;
+ }
+
+ return 0;
+}
static int
xenParseOS(virConfPtr conf, virDomainDefPtr def)
@@ -1065,9 +1089,25 @@ xenParseOS(virConfPtr conf, virDomainDefPtr def)
if (STREQ(def->os.type, "hvm")) {
const char *boot;
+#ifdef LIBXL_HAVE_BUILDINFO_KERNEL
+ if (xenConfigCopyStringOpt(conf, "kernel", &def->os.kernel) < 0)
+ return -1;
+
+ if (def->os.kernel && strstr(def->os.kernel, "hvmloader")) {
+ /* 'kernel' set to 'hvmloader' will be ignored in libxl */
+ VIR_FREE(def->os.kernel);
+ }
+
+ if (xenConfigCopyStringOpt(conf, "ramdisk", &def->os.initrd) < 0)
+ return -1;
+
+ if (xenParseCmdline(conf, def) < 0)
+ return -1;
+#else
if (VIR_ALLOC(def->os.loader) < 0 ||
- xenConfigCopyString(conf, "kernel", &def->os.loader->path) < 0)
+ xenConfigCopyStringOpt(conf, "kernel", &def->os.loader->path) < 0)
return -1;
+#endif
if (xenConfigGetString(conf, "boot", &boot, "c") < 0)
return -1;
@@ -1091,8 +1131,6 @@ xenParseOS(virConfPtr conf, virDomainDefPtr def)
def->os.nBootDevs++;
}
} else {
- const char *extra, *root;
-
if (xenConfigCopyStringOpt(conf, "bootloader", &def->os.bootloader) < 0)
return -1;
if (xenConfigCopyStringOpt(conf, "bootargs", &def->os.bootloaderArgs) < 0)
@@ -1104,19 +1142,8 @@ xenParseOS(virConfPtr conf, virDomainDefPtr def)
if (xenConfigCopyStringOpt(conf, "ramdisk", &def->os.initrd) < 0)
return -1;
- if (xenConfigGetString(conf, "extra", &extra, NULL) < 0)
+ if (xenParseCmdline(conf, def) < 0)
return -1;
-
- if (xenConfigGetString(conf, "root", &root, NULL) < 0)
- return -1;
-
- if (root) {
- if (virAsprintf(&def->os.cmdline, "root=%s %s", root, extra) < 0)
- return -1;
- } else {
- if (VIR_STRDUP(def->os.cmdline, extra) < 0)
- return -1;
- }
}
return 0;
--
1.8.5.2
10 years, 1 month
[libvirt] [PATCH] qemu: time: Report errors if agent command fails
by Peter Krempa
Commit b606bbb4 broke reporting of errors when setting of guest time
fails via the guest agent as the return value is not checked and later
overwritten by the return value qemuMonitorRTCResetReinjection();
Fix this by checking the return value before resetting the RTC
reinjection.
---
src/qemu/qemu_driver.c | 3 +++
1 file changed, 3 insertions(+)
diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c
index 6008aeb..15ad64d 100644
--- a/src/qemu/qemu_driver.c
+++ b/src/qemu/qemu_driver.c
@@ -17134,6 +17134,9 @@ qemuDomainSetTime(virDomainPtr dom,
rv = qemuAgentSetTime(priv->agent, seconds, nseconds, rtcSync);
qemuDomainObjExitAgent(vm);
+ if (rv < 0)
+ goto endjob;
+
if (!virDomainObjIsActive(vm)) {
virReportError(VIR_ERR_OPERATION_INVALID,
"%s", _("domain is not running"));
--
2.1.0
10 years, 1 month
[libvirt] [PATCH] util: storage: Copy driver type when initializing chain element
by Peter Krempa
virStorageSourceInitChainElement initializes a new storage chain element
for use as a new disk source. If the new element doesn't contain the
driver name, copy it from the old source.
This fixes issue where a disk would forget the driver after a snapshot.
Resolves: https://bugzilla.redhat.com/show_bug.cgi?id=1140984
---
src/util/virstoragefile.c | 4 ++++
1 file changed, 4 insertions(+)
diff --git a/src/util/virstoragefile.c b/src/util/virstoragefile.c
index 13056a7..960aa23 100644
--- a/src/util/virstoragefile.c
+++ b/src/util/virstoragefile.c
@@ -1927,6 +1927,10 @@ virStorageSourceInitChainElement(virStorageSourcePtr newelem,
virStorageSourceSeclabelsCopy(newelem, old) < 0)
goto cleanup;
+ if (!newelem->driverName &&
+ VIR_STRDUP(newelem->driverName, old->driverName) < 0)
+ goto cleanup;
+
newelem->shared = old->shared;
newelem->readonly = old->readonly;
--
2.1.0
10 years, 1 month
[libvirt] [PATCH] domaincaps: Expose UEFI capability
by Michal Privoznik
As of 542899168c38 we learned libvirt to use UEFI for domains.
However, management applications may firstly query if libvirt
supports it. And this is where virConnectGetDomainCapabilities()
API comes handy.
Signed-off-by: Michal Privoznik <mprivozn(a)redhat.com>
---
docs/formatdomaincaps.html.in | 40 ++++++++++++++++++++++
docs/schemas/domaincaps.rng | 21 ++++++++++++
src/conf/domain_capabilities.c | 28 +++++++++++++++
src/conf/domain_capabilities.h | 16 +++++++++
src/qemu/qemu_capabilities.c | 38 ++++++++++++++++++++
tests/domaincapsschemadata/domaincaps-basic.xml | 1 +
tests/domaincapsschemadata/domaincaps-full.xml | 13 +++++++
.../domaincaps-qemu_1.6.50-1.xml | 12 +++++++
tests/domaincapstest.c | 8 +++++
9 files changed, 177 insertions(+)
diff --git a/docs/formatdomaincaps.html.in b/docs/formatdomaincaps.html.in
index 66b6017..34d746d 100644
--- a/docs/formatdomaincaps.html.in
+++ b/docs/formatdomaincaps.html.in
@@ -93,6 +93,46 @@
<dd>The maximum number of supported virtual CPUs</dd>
</dl>
+ <h3><a name="elementsOSBIOS">BIOS bootloader</a></h3>
+
+ <p>Sometimes users might want to tweak some BIOS knobs or use
+ UEFI. For cases like that, <a
+ href="formatdomain.html#elementsOSBIOS"><code>os</code></a>
+ element exposes what values can be passed to its children.</p>
+
+<pre>
+<domainCapabilities>
+ ...
+ <os supported='yes'>
+ <loader supported='yes'>
+ <enum name='type'>
+ <value>rom</value>
+ <value>pflash</value>
+ </enum>
+ <enum name='readonly'>
+ <value>yes</value>
+ <value>no</value>
+ </enum>
+ </loader>
+ </os>
+ ...
+<domainCapabilities>
+</pre>
+
+ <p>For the <code>loader</code> element, the following can occur:</p>
+
+ <dl>
+ <dt>type</dt>
+ <dd>Whether loader is a typical BIOS (<code>rom</code>) or
+ an UEFI binary (<code>pflash</code>). This refers to
+ <code>type</code> attribute of the <loader/>
+ element.</dd>
+
+ <dt>readonly</dt>
+ <dd>Options for the <code>readonly</code> attribute of the
+ <loader/> element.</dd>
+ </dl>
+
<h3><a name="elementsDevices">Devices</a></h3>
<p>
diff --git a/docs/schemas/domaincaps.rng b/docs/schemas/domaincaps.rng
index 627b699..ad8d966 100644
--- a/docs/schemas/domaincaps.rng
+++ b/docs/schemas/domaincaps.rng
@@ -26,6 +26,9 @@
<ref name='vcpu'/>
</optional>
<optional>
+ <ref name='os'/>
+ </optional>
+ <optional>
<ref name='devices'/>
</optional>
</interleave>
@@ -41,6 +44,24 @@
</element>
</define>
+ <define name='loader'>
+ <element name='loader'>
+ <ref name='supported'/>
+ <ref name='enum'/>
+ </element>
+ </define>
+
+ <define name='os'>
+ <element name='os'>
+ <interleave>
+ <ref name='supported'/>
+ <optional>
+ <ref name='loader'/>
+ </optional>
+ </interleave>
+ </element>
+ </define>
+
<define name='devices'>
<element name='devices'>
<interleave>
diff --git a/src/conf/domain_capabilities.c b/src/conf/domain_capabilities.c
index df190eb..5a3c8e7 100644
--- a/src/conf/domain_capabilities.c
+++ b/src/conf/domain_capabilities.c
@@ -178,6 +178,32 @@ virDomainCapsEnumFormat(virBufferPtr buf,
#capsEnum, valToStr); \
} while (0)
+
+static void
+virDomainCapsLoaderFormat(virBufferPtr buf,
+ virDomainCapsLoaderPtr loader)
+{
+ FORMAT_PROLOGUE(loader);
+
+ ENUM_PROCESS(loader, type, virDomainLoaderTypeToString);
+ ENUM_PROCESS(loader, readonly, virTristateBoolTypeToString);
+
+ FORMAT_EPILOGUE(loader);
+}
+
+static void
+virDomainCapsOSFormat(virBufferPtr buf,
+ virDomainCapsOSPtr os)
+{
+ virDomainCapsLoaderPtr loader = &os->loader;
+
+ FORMAT_PROLOGUE(os);
+
+ virDomainCapsLoaderFormat(buf, loader);
+
+ FORMAT_EPILOGUE(os);
+}
+
static void
virDomainCapsDeviceDiskFormat(virBufferPtr buf,
virDomainCapsDeviceDiskPtr const disk)
@@ -225,6 +251,8 @@ virDomainCapsFormatInternal(virBufferPtr buf,
if (caps->maxvcpus)
virBufferAsprintf(buf, "<vcpu max='%d'/>\n", caps->maxvcpus);
+ virDomainCapsOSFormat(buf, &caps->os);
+
virBufferAddLit(buf, "<devices>\n");
virBufferAdjustIndent(buf, 2);
diff --git a/src/conf/domain_capabilities.h b/src/conf/domain_capabilities.h
index 731e66f..768646b 100644
--- a/src/conf/domain_capabilities.h
+++ b/src/conf/domain_capabilities.h
@@ -43,6 +43,21 @@ struct _virDomainCapsDevice {
bool supported; /* true if <devtype> is supported by hypervisor */
};
+typedef struct _virDomainCapsLoader virDomainCapsLoader;
+typedef virDomainCapsLoader *virDomainCapsLoaderPtr;
+struct _virDomainCapsLoader {
+ virDomainCapsDevice device;
+ virDomainCapsEnum type; /* Info about virDomainLoader */
+ virDomainCapsEnum readonly; /* Info about readonly:virTristateBool */
+};
+
+typedef struct _virDomainCapsOS virDomainCapsOS;
+typedef virDomainCapsOS *virDomainCapsOSPtr;
+struct _virDomainCapsOS {
+ virDomainCapsDevice device;
+ virDomainCapsLoader loader; /* Info about virDomainLoaderDef */
+};
+
typedef struct _virDomainCapsDeviceDisk virDomainCapsDeviceDisk;
typedef virDomainCapsDeviceDisk *virDomainCapsDeviceDiskPtr;
struct _virDomainCapsDeviceDisk {
@@ -75,6 +90,7 @@ struct _virDomainCaps {
/* Some machine specific info */
int maxvcpus;
+ virDomainCapsOS os;
virDomainCapsDeviceDisk disk;
virDomainCapsDeviceHostdev hostdev;
/* add new domain devices here */
diff --git a/src/qemu/qemu_capabilities.c b/src/qemu/qemu_capabilities.c
index 81ada48..9f8868d 100644
--- a/src/qemu/qemu_capabilities.c
+++ b/src/qemu/qemu_capabilities.c
@@ -3609,6 +3609,42 @@ virQEMUCapsGetDefaultMachine(virQEMUCapsPtr qemuCaps)
static void
+virQEMUCapsFillDomainLoaderCaps(virQEMUCapsPtr qemuCaps,
+ virDomainCapsLoaderPtr loader,
+ virArch arch)
+{
+ loader->device.supported = true;
+
+ VIR_DOMAIN_CAPS_ENUM_SET(loader->type,
+ VIR_DOMAIN_LOADER_TYPE_ROM);
+
+ if (arch == VIR_ARCH_X86_64 &&
+ virQEMUCapsGet(qemuCaps, QEMU_CAPS_DRIVE) &&
+ virQEMUCapsGet(qemuCaps, QEMU_CAPS_DRIVE_FORMAT))
+ VIR_DOMAIN_CAPS_ENUM_SET(loader->type,
+ VIR_DOMAIN_LOADER_TYPE_PFLASH);
+
+
+ if (virQEMUCapsGet(qemuCaps, QEMU_CAPS_DRIVE_READONLY))
+ VIR_DOMAIN_CAPS_ENUM_SET(loader->readonly,
+ VIR_TRISTATE_BOOL_YES,
+ VIR_TRISTATE_BOOL_NO);
+}
+
+
+static void
+virQEMUCapsFillDomainOSCaps(virQEMUCapsPtr qemuCaps,
+ virDomainCapsOSPtr os,
+ virArch arch)
+{
+ virDomainCapsLoaderPtr loader = &os->loader;
+
+ os->device.supported = true;
+ virQEMUCapsFillDomainLoaderCaps(qemuCaps, loader, arch);
+}
+
+
+static void
virQEMUCapsFillDomainDeviceDiskCaps(virQEMUCapsPtr qemuCaps,
virDomainCapsDeviceDiskPtr disk)
{
@@ -3686,12 +3722,14 @@ void
virQEMUCapsFillDomainCaps(virDomainCapsPtr domCaps,
virQEMUCapsPtr qemuCaps)
{
+ virDomainCapsOSPtr os = &domCaps->os;
virDomainCapsDeviceDiskPtr disk = &domCaps->disk;
virDomainCapsDeviceHostdevPtr hostdev = &domCaps->hostdev;
int maxvcpus = virQEMUCapsGetMachineMaxCpus(qemuCaps, domCaps->machine);
domCaps->maxvcpus = maxvcpus;
+ virQEMUCapsFillDomainOSCaps(qemuCaps, os, domCaps->arch);
virQEMUCapsFillDomainDeviceDiskCaps(qemuCaps, disk);
virQEMUCapsFillDomainDeviceHostdevCaps(qemuCaps, hostdev);
}
diff --git a/tests/domaincapsschemadata/domaincaps-basic.xml b/tests/domaincapsschemadata/domaincaps-basic.xml
index 9963519..6171393 100644
--- a/tests/domaincapsschemadata/domaincaps-basic.xml
+++ b/tests/domaincapsschemadata/domaincaps-basic.xml
@@ -3,6 +3,7 @@
<domain>uml</domain>
<machine>my-machine-type</machine>
<arch>x86_64</arch>
+ <os supported='no'/>
<devices>
<disk supported='no'/>
<hostdev supported='no'/>
diff --git a/tests/domaincapsschemadata/domaincaps-full.xml b/tests/domaincapsschemadata/domaincaps-full.xml
index 58dd4cb..9722772 100644
--- a/tests/domaincapsschemadata/domaincaps-full.xml
+++ b/tests/domaincapsschemadata/domaincaps-full.xml
@@ -4,6 +4,19 @@
<machine>my-machine-type</machine>
<arch>x86_64</arch>
<vcpu max='255'/>
+ <os supported='yes'>
+ <loader supported='yes'>
+ <enum name='type'>
+ <value>rom</value>
+ <value>pflash</value>
+ </enum>
+ <enum name='readonly'>
+ <value>default</value>
+ <value>yes</value>
+ <value>no</value>
+ </enum>
+ </loader>
+ </os>
<devices>
<disk supported='yes'>
<enum name='diskDevice'>
diff --git a/tests/domaincapsschemadata/domaincaps-qemu_1.6.50-1.xml b/tests/domaincapsschemadata/domaincaps-qemu_1.6.50-1.xml
index 8b63993..568cecb 100644
--- a/tests/domaincapsschemadata/domaincaps-qemu_1.6.50-1.xml
+++ b/tests/domaincapsschemadata/domaincaps-qemu_1.6.50-1.xml
@@ -3,6 +3,18 @@
<domain>kvm</domain>
<machine>pc-1.2</machine>
<arch>x86_64</arch>
+ <os supported='yes'>
+ <loader supported='yes'>
+ <enum name='type'>
+ <value>rom</value>
+ <value>pflash</value>
+ </enum>
+ <enum name='readonly'>
+ <value>yes</value>
+ <value>no</value>
+ </enum>
+ </loader>
+ </os>
<devices>
<disk supported='yes'>
<enum name='diskDevice'>
diff --git a/tests/domaincapstest.c b/tests/domaincapstest.c
index 78197e2..f240643 100644
--- a/tests/domaincapstest.c
+++ b/tests/domaincapstest.c
@@ -38,10 +38,18 @@ static void
fillAll(virDomainCapsPtr domCaps,
void *opaque ATTRIBUTE_UNUSED)
{
+ virDomainCapsOSPtr os = &domCaps->os;
+ virDomainCapsLoaderPtr loader = &os->loader;
virDomainCapsDeviceDiskPtr disk = &domCaps->disk;
virDomainCapsDeviceHostdevPtr hostdev = &domCaps->hostdev;
domCaps->maxvcpus = 255;
+ os->device.supported = true;
+
+ loader->device.supported = true;
+ SET_ALL_BITS(loader->type);
+ SET_ALL_BITS(loader->readonly);
+
disk->device.supported = true;
SET_ALL_BITS(disk->diskDevice);
SET_ALL_BITS(disk->bus);
--
1.8.5.5
10 years, 1 month