Don't mess up labelling of /dev/net/tun (bz #1141879)
pflash/nvram support for UEFI/OVMF
This commit is contained in:
parent
622cf0d642
commit
3ec523d168
@ -1,6 +1,6 @@
|
||||
From 28b27787c5bb545df3c178fef682151c45b66784 Mon Sep 17 00:00:00 2001
|
||||
From b2735463b886ac88027cec0ff1a4dbaa4f8be739 Mon Sep 17 00:00:00 2001
|
||||
From: Martin Kletzander <mkletzan@redhat.com>
|
||||
Date: Mon, 8 Sep 2014 07:46:39 +0200
|
||||
Date: Sun, 7 Sep 2014 20:41:11 +0200
|
||||
Subject: [PATCH] rpc: make daemon spawning a bit more intelligent
|
||||
|
||||
This way it behaves more like the daemon itself does (acquiring a
|
||||
@ -10,12 +10,13 @@ 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@redhat.com>
|
||||
(cherry picked from commit bd9ad91a4036649645fffb1598213339263478de)
|
||||
---
|
||||
src/rpc/virnetsocket.c | 57 ++++++++++++++++++++++++++++++++++++++++++++------
|
||||
1 file changed, 51 insertions(+), 6 deletions(-)
|
||||
src/rpc/virnetsocket.c | 67 ++++++++++++++++++++++++++++++++++++++++++++------
|
||||
1 file changed, 59 insertions(+), 8 deletions(-)
|
||||
|
||||
diff --git a/src/rpc/virnetsocket.c b/src/rpc/virnetsocket.c
|
||||
index 306c9ea..fa9ba99 100644
|
||||
index 306c9ea..5feccf6 100644
|
||||
--- a/src/rpc/virnetsocket.c
|
||||
+++ b/src/rpc/virnetsocket.c
|
||||
@@ -51,9 +51,11 @@
|
||||
@ -41,7 +42,7 @@ index 306c9ea..fa9ba99 100644
|
||||
virSocketAddr localAddr;
|
||||
virSocketAddr remoteAddr;
|
||||
|
||||
@@ -583,16 +588,45 @@ int virNetSocketNewConnectUNIX(const char *path,
|
||||
@@ -583,16 +588,46 @@ int virNetSocketNewConnectUNIX(const char *path,
|
||||
goto error;
|
||||
}
|
||||
|
||||
@ -55,7 +56,8 @@ index 306c9ea..fa9ba99 100644
|
||||
+ if (virPidFileConstructPath(false, NULL, binname, &pidpath) < 0)
|
||||
+ goto error;
|
||||
+
|
||||
+ if ((pidfd = virPidFileAcquirePath(pidpath, false, getpid())) < 0) {
|
||||
+ pidfd = virPidFileAcquirePath(pidpath, false, getpid());
|
||||
+ 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
|
||||
@ -76,7 +78,7 @@ index 306c9ea..fa9ba99 100644
|
||||
- * 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 noone else should be using
|
||||
+ * 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.
|
||||
@ -91,19 +93,28 @@ index 306c9ea..fa9ba99 100644
|
||||
*/
|
||||
if ((pid = virFork()) < 0)
|
||||
goto error;
|
||||
@@ -612,8 +646,9 @@ int virNetSocketNewConnectUNIX(const char *path,
|
||||
@@ -610,12 +645,16 @@ 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
|
||||
- * 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.
|
||||
+ * 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.
|
||||
+ * 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;
|
||||
+ virPidFileDeletePath(pidpath);
|
||||
+ VIR_FORCE_CLOSE(pidfd);
|
||||
+ VIR_FORCE_CLOSE(passfd);
|
||||
goto retry;
|
||||
@@ -632,6 +667,12 @@ int virNetSocketNewConnectUNIX(const char *path,
|
||||
}
|
||||
|
||||
@@ -632,6 +671,12 @@ int virNetSocketNewConnectUNIX(const char *path,
|
||||
goto error;
|
||||
}
|
||||
|
||||
@ -116,11 +127,16 @@ index 306c9ea..fa9ba99 100644
|
||||
if (virNetSocketForkDaemon(binary, passfd) < 0)
|
||||
goto error;
|
||||
}
|
||||
@@ -648,8 +689,12 @@ int virNetSocketNewConnectUNIX(const char *path,
|
||||
@@ -645,11 +690,17 @@ int virNetSocketNewConnectUNIX(const char *path,
|
||||
if (!(*retsock = virNetSocketNew(&localAddr, &remoteAddr, true, fd, -1, 0)))
|
||||
goto error;
|
||||
|
||||
+ VIR_FREE(pidpath);
|
||||
+
|
||||
return 0;
|
||||
|
||||
error:
|
||||
+ if (pidfd > 0)
|
||||
+ if (pidfd >= 0)
|
||||
+ virPidFileDeletePath(pidpath);
|
||||
+ VIR_FREE(pidpath);
|
||||
VIR_FORCE_CLOSE(fd);
|
||||
|
@ -1,4 +1,4 @@
|
||||
From 2950887a9e7800e0421dadb0b9c348adb087deca Mon Sep 17 00:00:00 2001
|
||||
From d437ccd8fef17c2bb119e98a034bdc56ff9425b2 Mon Sep 17 00:00:00 2001
|
||||
From: Cole Robinson <crobinso@redhat.com>
|
||||
Date: Mon, 15 Sep 2014 14:49:35 -0400
|
||||
Subject: [PATCH] spec: Don't build wireshark on f21 (non upstream)
|
||||
|
@ -1,4 +1,4 @@
|
||||
From 09f0ff32b8925131c058de768751d3368f47a722 Mon Sep 17 00:00:00 2001
|
||||
From abb9c206877a937c2a509ec534c190b27c0b0e55 Mon Sep 17 00:00:00 2001
|
||||
From: Jiri Denemark <jdenemar@redhat.com>
|
||||
Date: Wed, 3 Sep 2014 10:51:14 +0200
|
||||
Subject: [PATCH] spec: Fix preun script for daemon
|
||||
|
@ -0,0 +1,98 @@
|
||||
From c414cb524bdbc3555a5332fe75b40f8cf3ded0f4 Mon Sep 17 00:00:00 2001
|
||||
From: Michal Privoznik <mprivozn@redhat.com>
|
||||
Date: Thu, 18 Sep 2014 15:17:29 +0200
|
||||
Subject: [PATCH] virSecuritySELinuxSetTapFDLabel: Temporarily revert to old
|
||||
behavior
|
||||
|
||||
https://bugzilla.redhat.com/show_bug.cgi?id=1141879
|
||||
|
||||
A long time ago I've implemented support for so called multiqueue
|
||||
net. The idea was to let guest network traffic be processed by
|
||||
multiple host CPUs and thus increasing performance. However, this
|
||||
behavior is enabled by QEMU via special ioctl() iterated over the
|
||||
all tap FDs passed in by libvirt. Unfortunately, SELinux comes in
|
||||
and disallows the ioctl() call because the /dev/net/tun has label
|
||||
system_u:object_r:tun_tap_device_t:s0 and 'attach_queue' ioctl()
|
||||
is not allowed on tun_tap_device_t type. So after discussion with
|
||||
a SELinux developer we've decided that the FDs passed to the QEMU
|
||||
should be labelled with svirt_t type and SELinux policy will
|
||||
allow the ioctl(). Therefore I've made a patch
|
||||
(cf976d9dcf4e592261b14f03572) that does exactly this. The patch
|
||||
was fixed then by a4431931393aeb1ac5893f121151fa3df4fde612 and
|
||||
b635b7a1af0e64754016d758376f382470bc11e7. However, things are not
|
||||
that easy - even though the API to label FD is called
|
||||
(fsetfilecon_raw) the underlying file is labelled too! So
|
||||
effectively we are mangling /dev/net/tun label. Yes, that broke
|
||||
dozen of other application from openvpn, or boxes, to qemu
|
||||
running other domains.
|
||||
|
||||
The best solution would be if SELinux provides a way to label an
|
||||
FD only, which could be then labeled when passed to the qemu.
|
||||
However that's a long path to go and we should fix this
|
||||
regression AQAP. So I went to talk to the SELinux developer again
|
||||
and we agreed on temporary solution that:
|
||||
|
||||
1) All the three patches are reverted
|
||||
2) SELinux temporarily allows 'attach_queue' on the
|
||||
tun_tap_device_t
|
||||
|
||||
Signed-off-by: Michal Privoznik <mprivozn@redhat.com>
|
||||
(cherry picked from commit ba7468dbb13f552a9177d01ea8bad155f9877bc3)
|
||||
---
|
||||
src/security/security_selinux.c | 34 ++++++++++++++++++++++++++++++++--
|
||||
1 file changed, 32 insertions(+), 2 deletions(-)
|
||||
|
||||
diff --git a/src/security/security_selinux.c b/src/security/security_selinux.c
|
||||
index e8c13db..c078cab 100644
|
||||
--- a/src/security/security_selinux.c
|
||||
+++ b/src/security/security_selinux.c
|
||||
@@ -2330,17 +2330,47 @@ virSecuritySELinuxSetImageFDLabel(virSecurityManagerPtr mgr ATTRIBUTE_UNUSED,
|
||||
}
|
||||
|
||||
static int
|
||||
-virSecuritySELinuxSetTapFDLabel(virSecurityManagerPtr mgr ATTRIBUTE_UNUSED,
|
||||
+virSecuritySELinuxSetTapFDLabel(virSecurityManagerPtr mgr,
|
||||
virDomainDefPtr def,
|
||||
int fd)
|
||||
{
|
||||
+ struct stat buf;
|
||||
+ security_context_t fcon = NULL;
|
||||
virSecurityLabelDefPtr secdef;
|
||||
+ char *str = NULL;
|
||||
+ int rc = -1;
|
||||
|
||||
secdef = virDomainDefGetSecurityLabelDef(def, SECURITY_SELINUX_NAME);
|
||||
if (!secdef || !secdef->label)
|
||||
return 0;
|
||||
|
||||
- return virSecuritySELinuxFSetFilecon(fd, secdef->imagelabel);
|
||||
+ if (fstat(fd, &buf) < 0) {
|
||||
+ virReportSystemError(errno, _("cannot stat tap fd %d"), fd);
|
||||
+ goto cleanup;
|
||||
+ }
|
||||
+
|
||||
+ if ((buf.st_mode & S_IFMT) != S_IFCHR) {
|
||||
+ virReportError(VIR_ERR_INTERNAL_ERROR,
|
||||
+ _("tap fd %d is not character device"), fd);
|
||||
+ goto cleanup;
|
||||
+ }
|
||||
+
|
||||
+ if (getContext(mgr, "/dev/tap.*", buf.st_mode, &fcon) < 0) {
|
||||
+ virReportError(VIR_ERR_INTERNAL_ERROR,
|
||||
+ _("cannot lookup default selinux label for tap fd %d"), fd);
|
||||
+ goto cleanup;
|
||||
+ }
|
||||
+
|
||||
+ if (!(str = virSecuritySELinuxContextAddRange(secdef->label, fcon))) {
|
||||
+ goto cleanup;
|
||||
+ } else {
|
||||
+ rc = virSecuritySELinuxFSetFilecon(fd, str);
|
||||
+ }
|
||||
+
|
||||
+ cleanup:
|
||||
+ freecon(fcon);
|
||||
+ VIR_FREE(str);
|
||||
+ return rc;
|
||||
}
|
||||
|
||||
static char *
|
1296
0011-conf-Extend-loader-and-introduce-nvram.patch
Normal file
1296
0011-conf-Extend-loader-and-introduce-nvram.patch
Normal file
File diff suppressed because it is too large
Load Diff
222
0012-qemu-Implement-extended-loader-and-nvram.patch
Normal file
222
0012-qemu-Implement-extended-loader-and-nvram.patch
Normal file
@ -0,0 +1,222 @@
|
||||
From ac0859aae7162255848effdc560368266845dfce Mon Sep 17 00:00:00 2001
|
||||
From: Michal Privoznik <mprivozn@redhat.com>
|
||||
Date: Thu, 7 Aug 2014 13:50:00 +0200
|
||||
Subject: [PATCH] qemu: Implement extended loader and nvram
|
||||
|
||||
QEMU now supports UEFI with the following command line:
|
||||
|
||||
-drive file=/usr/share/OVMF/OVMF_CODE.fd,if=pflash,format=raw,unit=0,readonly=on \
|
||||
-drive file=/usr/share/OVMF/OVMF_VARS.fd,if=pflash,format=raw,unit=1 \
|
||||
|
||||
where the first line reflects <loader> and the second one <nvram>.
|
||||
Moreover, these two lines obsolete the -bios argument.
|
||||
|
||||
Note that UEFI is unusable without ACPI. This is handled properly now.
|
||||
Among with this extension, the variable file is expected to be
|
||||
writable and hence we need security drivers to label it.
|
||||
|
||||
Signed-off-by: Michal Privoznik <mprivozn@redhat.com>
|
||||
Acked-by: Laszlo Ersek <lersek@redhat.com>
|
||||
(cherry picked from commit 542899168c382610dbad9a597d27ef3d7c699f68)
|
||||
---
|
||||
src/qemu/qemu_command.c | 94 +++++++++++++++++++++-
|
||||
src/security/security_dac.c | 8 ++
|
||||
src/security/security_selinux.c | 8 ++
|
||||
.../qemuxml2argvdata/qemuxml2argv-bios-nvram.args | 10 +++
|
||||
tests/qemuxml2argvtest.c | 2 +
|
||||
5 files changed, 118 insertions(+), 4 deletions(-)
|
||||
create mode 100644 tests/qemuxml2argvdata/qemuxml2argv-bios-nvram.args
|
||||
|
||||
diff --git a/src/qemu/qemu_command.c b/src/qemu/qemu_command.c
|
||||
index 3cb2e0b..718533b 100644
|
||||
--- a/src/qemu/qemu_command.c
|
||||
+++ b/src/qemu/qemu_command.c
|
||||
@@ -7370,6 +7370,94 @@ qemuBuildChrDeviceCommandLine(virCommandPtr cmd,
|
||||
return 0;
|
||||
}
|
||||
|
||||
+static int
|
||||
+qemuBuildDomainLoaderCommandLine(virCommandPtr cmd,
|
||||
+ virDomainDefPtr def,
|
||||
+ virQEMUCapsPtr qemuCaps)
|
||||
+{
|
||||
+ int ret = -1;
|
||||
+ virDomainLoaderDefPtr loader = def->os.loader;
|
||||
+ virBuffer buf = VIR_BUFFER_INITIALIZER;
|
||||
+ int unit = 0;
|
||||
+
|
||||
+ if (!loader)
|
||||
+ return 0;
|
||||
+
|
||||
+ switch ((virDomainLoader) loader->type) {
|
||||
+ case VIR_DOMAIN_LOADER_TYPE_ROM:
|
||||
+ virCommandAddArg(cmd, "-bios");
|
||||
+ virCommandAddArg(cmd, loader->path);
|
||||
+ break;
|
||||
+
|
||||
+ case VIR_DOMAIN_LOADER_TYPE_PFLASH:
|
||||
+ /* UEFI is supported only for x86_64 currently */
|
||||
+ if (def->os.arch != VIR_ARCH_X86_64) {
|
||||
+ virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
|
||||
+ _("pflash is not supported for %s guest architecture"),
|
||||
+ virArchToString(def->os.arch));
|
||||
+ goto cleanup;
|
||||
+ }
|
||||
+
|
||||
+ if (!virQEMUCapsGet(qemuCaps, QEMU_CAPS_DRIVE)) {
|
||||
+ virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
|
||||
+ _("this QEMU binary doesn't support -drive"));
|
||||
+ goto cleanup;
|
||||
+ }
|
||||
+ if (!virQEMUCapsGet(qemuCaps, QEMU_CAPS_DRIVE_FORMAT)) {
|
||||
+ virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
|
||||
+ _("this QEMU binary doesn't support passing "
|
||||
+ "drive format"));
|
||||
+ goto cleanup;
|
||||
+ }
|
||||
+ if (virQEMUCapsGet(qemuCaps, QEMU_CAPS_NO_ACPI) &&
|
||||
+ def->features[VIR_DOMAIN_FEATURE_ACPI] != VIR_TRISTATE_SWITCH_ON) {
|
||||
+ virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
|
||||
+ _("ACPI must be enabled in order to use UEFI"));
|
||||
+ goto cleanup;
|
||||
+ }
|
||||
+
|
||||
+ virBufferAsprintf(&buf,
|
||||
+ "file=%s,if=pflash,format=raw,unit=%d",
|
||||
+ loader->path, unit);
|
||||
+ unit++;
|
||||
+
|
||||
+ if (loader->readonly) {
|
||||
+ if (!virQEMUCapsGet(qemuCaps, QEMU_CAPS_DRIVE_READONLY)) {
|
||||
+ virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
|
||||
+ _("this qemu doesn't support passing "
|
||||
+ "readonly attribute"));
|
||||
+ goto cleanup;
|
||||
+ }
|
||||
+
|
||||
+ virBufferAsprintf(&buf, ",readonly=%s",
|
||||
+ virTristateSwitchTypeToString(loader->readonly));
|
||||
+ }
|
||||
+
|
||||
+ virCommandAddArg(cmd, "-drive");
|
||||
+ virCommandAddArgBuffer(cmd, &buf);
|
||||
+
|
||||
+ if (loader->nvram) {
|
||||
+ virBufferFreeAndReset(&buf);
|
||||
+ virBufferAsprintf(&buf,
|
||||
+ "file=%s,if=pflash,format=raw,unit=%d",
|
||||
+ loader->nvram, unit);
|
||||
+
|
||||
+ virCommandAddArg(cmd, "-drive");
|
||||
+ virCommandAddArgBuffer(cmd, &buf);
|
||||
+ }
|
||||
+ break;
|
||||
+
|
||||
+ case VIR_DOMAIN_LOADER_TYPE_LAST:
|
||||
+ /* nada */
|
||||
+ break;
|
||||
+ }
|
||||
+
|
||||
+ ret = 0;
|
||||
+ cleanup:
|
||||
+ virBufferFreeAndReset(&buf);
|
||||
+ return ret;
|
||||
+}
|
||||
+
|
||||
qemuBuildCommandLineCallbacks buildCommandLineCallbacks = {
|
||||
.qemuGetSCSIDeviceSgName = virSCSIDeviceGetSgName,
|
||||
};
|
||||
@@ -7525,10 +7613,8 @@ qemuBuildCommandLine(virConnectPtr conn,
|
||||
virCommandAddArg(cmd, "-enable-nesting");
|
||||
}
|
||||
|
||||
- if (def->os.loader) {
|
||||
- virCommandAddArg(cmd, "-bios");
|
||||
- virCommandAddArg(cmd, def->os.loader->path);
|
||||
- }
|
||||
+ if (qemuBuildDomainLoaderCommandLine(cmd, def, qemuCaps) < 0)
|
||||
+ goto error;
|
||||
|
||||
/* Set '-m MB' based on maxmem, because the lower 'memory' limit
|
||||
* is set post-startup using the balloon driver. If balloon driver
|
||||
diff --git a/src/security/security_dac.c b/src/security/security_dac.c
|
||||
index e62828e..e398d2c 100644
|
||||
--- a/src/security/security_dac.c
|
||||
+++ b/src/security/security_dac.c
|
||||
@@ -960,6 +960,10 @@ virSecurityDACRestoreSecurityAllLabel(virSecurityManagerPtr mgr,
|
||||
rc = -1;
|
||||
}
|
||||
|
||||
+ if (def->os.loader && def->os.loader->nvram &&
|
||||
+ virSecurityDACRestoreSecurityFileLabel(def->os.loader->nvram) < 0)
|
||||
+ rc = -1;
|
||||
+
|
||||
if (def->os.kernel &&
|
||||
virSecurityDACRestoreSecurityFileLabel(def->os.kernel) < 0)
|
||||
rc = -1;
|
||||
@@ -1036,6 +1040,10 @@ virSecurityDACSetSecurityAllLabel(virSecurityManagerPtr mgr,
|
||||
if (virSecurityDACGetImageIds(secdef, priv, &user, &group))
|
||||
return -1;
|
||||
|
||||
+ if (def->os.loader && def->os.loader->nvram &&
|
||||
+ virSecurityDACSetOwnership(def->os.loader->nvram, user, group) < 0)
|
||||
+ return -1;
|
||||
+
|
||||
if (def->os.kernel &&
|
||||
virSecurityDACSetOwnership(def->os.kernel, user, group) < 0)
|
||||
return -1;
|
||||
diff --git a/src/security/security_selinux.c b/src/security/security_selinux.c
|
||||
index c078cab..a409c19 100644
|
||||
--- a/src/security/security_selinux.c
|
||||
+++ b/src/security/security_selinux.c
|
||||
@@ -1911,6 +1911,10 @@ virSecuritySELinuxRestoreSecurityAllLabel(virSecurityManagerPtr mgr,
|
||||
mgr) < 0)
|
||||
rc = -1;
|
||||
|
||||
+ if (def->os.loader && def->os.loader->nvram &&
|
||||
+ virSecuritySELinuxRestoreSecurityFileLabel(mgr, def->os.loader->nvram) < 0)
|
||||
+ rc = -1;
|
||||
+
|
||||
if (def->os.kernel &&
|
||||
virSecuritySELinuxRestoreSecurityFileLabel(mgr, def->os.kernel) < 0)
|
||||
rc = -1;
|
||||
@@ -2294,6 +2298,10 @@ virSecuritySELinuxSetSecurityAllLabel(virSecurityManagerPtr mgr,
|
||||
mgr) < 0)
|
||||
return -1;
|
||||
|
||||
+ if (def->os.loader && def->os.loader->nvram &&
|
||||
+ virSecuritySELinuxSetFilecon(def->os.loader->nvram, data->content_context) < 0)
|
||||
+ return -1;
|
||||
+
|
||||
if (def->os.kernel &&
|
||||
virSecuritySELinuxSetFilecon(def->os.kernel, data->content_context) < 0)
|
||||
return -1;
|
||||
diff --git a/tests/qemuxml2argvdata/qemuxml2argv-bios-nvram.args b/tests/qemuxml2argvdata/qemuxml2argv-bios-nvram.args
|
||||
new file mode 100644
|
||||
index 0000000..b51e8f3
|
||||
--- /dev/null
|
||||
+++ b/tests/qemuxml2argvdata/qemuxml2argv-bios-nvram.args
|
||||
@@ -0,0 +1,10 @@
|
||||
+LC_ALL=C PATH=/bin HOME=/home/test USER=test LOGNAME=test QEMU_AUDIO_DRV=none \
|
||||
+/usr/bin/qemu -S -M pc \
|
||||
+-drive file=/usr/share/OVMF/OVMF_CODE.fd,if=pflash,format=raw,unit=0,readonly=on \
|
||||
+-drive file=/usr/share/OVMF/OVMF_VARS.fd,if=pflash,format=raw,unit=1 \
|
||||
+-m 1024 -smp 1 -nographic -nodefaults \
|
||||
+-monitor unix:/tmp/test-monitor,server,nowait -boot c -usb \
|
||||
+-drive file=/dev/HostVG/QEMUGuest1,if=none,id=drive-ide0-0-0,format=raw \
|
||||
+-device ide-drive,bus=ide.0,unit=0,drive=drive-ide0-0-0,id=ide0-0-0 \
|
||||
+-serial pty -device usb-tablet,id=input0 \
|
||||
+-device virtio-balloon-pci,id=balloon0,bus=pci.0,addr=0x3
|
||||
diff --git a/tests/qemuxml2argvtest.c b/tests/qemuxml2argvtest.c
|
||||
index 3feb2fe..5c28253 100644
|
||||
--- a/tests/qemuxml2argvtest.c
|
||||
+++ b/tests/qemuxml2argvtest.c
|
||||
@@ -642,6 +642,8 @@ mymain(void)
|
||||
DO_TEST_FAILURE("reboot-timeout-enabled", NONE);
|
||||
|
||||
DO_TEST("bios", QEMU_CAPS_DEVICE, QEMU_CAPS_SGA);
|
||||
+ DO_TEST("bios-nvram", QEMU_CAPS_DEVICE, QEMU_CAPS_DRIVE,
|
||||
+ QEMU_CAPS_DRIVE_FORMAT, QEMU_CAPS_DRIVE_READONLY);
|
||||
DO_TEST("clock-utc", QEMU_CAPS_NODEFCONFIG, QEMU_CAPS_DEVICE);
|
||||
DO_TEST("clock-localtime", NONE);
|
||||
DO_TEST("clock-localtime-basis-localtime", QEMU_CAPS_RTC);
|
579
0013-qemu-Automatically-create-NVRAM-store.patch
Normal file
579
0013-qemu-Automatically-create-NVRAM-store.patch
Normal file
@ -0,0 +1,579 @@
|
||||
From e2354416fdccb9649f080cdf912c5dc16d0eb578 Mon Sep 17 00:00:00 2001
|
||||
From: Michal Privoznik <mprivozn@redhat.com>
|
||||
Date: Thu, 7 Aug 2014 16:59:21 +0200
|
||||
Subject: [PATCH] qemu: Automatically create NVRAM store
|
||||
|
||||
When using split UEFI image, it may come handy if libvirt manages per
|
||||
domain _VARS file automatically. While the _CODE file is RO and can be
|
||||
shared among multiple domains, you certainly don't want to do that on
|
||||
the _VARS file. This latter one needs to be per domain. So at the
|
||||
domain startup process, if it's determined that domain needs _VARS
|
||||
file it's copied from this master _VARS file. The location of the
|
||||
master file is configurable in qemu.conf.
|
||||
|
||||
Temporary, on per domain basis the location of master NVRAM file can
|
||||
be overridden by this @template attribute I'm inventing to the
|
||||
<nvram/> element. All it does is holding path to the master NVRAM file
|
||||
from which local copy is created. If that's the case, the map in
|
||||
qemu.conf is not consulted.
|
||||
|
||||
Signed-off-by: Michal Privoznik <mprivozn@redhat.com>
|
||||
Acked-by: Laszlo Ersek <lersek@redhat.com>
|
||||
(cherry picked from commit 742b08e30fd503bc992e864828cbabd7e6a099ec)
|
||||
---
|
||||
docs/formatdomain.html.in | 11 +-
|
||||
docs/schemas/domaincommon.rng | 9 +-
|
||||
libvirt.spec.in | 2 +
|
||||
src/Makefile.am | 1 +
|
||||
src/conf/domain_conf.c | 11 +-
|
||||
src/conf/domain_conf.h | 1 +
|
||||
src/qemu/libvirtd_qemu.aug | 3 +
|
||||
src/qemu/qemu.conf | 14 +++
|
||||
src/qemu/qemu_conf.c | 94 ++++++++++++++
|
||||
src/qemu/qemu_conf.h | 5 +
|
||||
src/qemu/qemu_process.c | 137 +++++++++++++++++++++
|
||||
src/qemu/test_libvirtd_qemu.aug.in | 3 +
|
||||
tests/domainschemadata/domain-bios-nvram-empty.xml | 40 ++++++
|
||||
13 files changed, 325 insertions(+), 6 deletions(-)
|
||||
create mode 100644 tests/domainschemadata/domain-bios-nvram-empty.xml
|
||||
|
||||
diff --git a/docs/formatdomain.html.in b/docs/formatdomain.html.in
|
||||
index 757035a..a2ea758 100644
|
||||
--- a/docs/formatdomain.html.in
|
||||
+++ b/docs/formatdomain.html.in
|
||||
@@ -103,7 +103,7 @@
|
||||
<os>
|
||||
<type>hvm</type>
|
||||
<loader readonly='on' type='rom'>/usr/lib/xen/boot/hvmloader</loader>
|
||||
- <nvram>/var/lib/libvirt/nvram/guest_VARS.fd</nvram>
|
||||
+ <nvram template='/usr/share/OVMF/OVMF_VARS.fd'>/var/lib/libvirt/nvram/guest_VARS.fd</nvram>
|
||||
<boot dev='hd'/>
|
||||
<boot dev='cdrom'/>
|
||||
<bootmenu enable='yes' timeout='3000'/>
|
||||
@@ -142,9 +142,12 @@
|
||||
<code>pflash</code>.</dd>
|
||||
<dt><code>nvram</code></dt>
|
||||
<dd>Some UEFI firmwares may want to use a non-volatile memory to store
|
||||
- some variables. In the host, this is represented as a file and the
|
||||
- path to the file is stored in this element. <span class="since">Since
|
||||
- 1.2.8</span></dd>
|
||||
+ some variables. In the host, this is represented as a file and the path
|
||||
+ to the file is stored in this element. Moreover, when the domain is
|
||||
+ started up libvirt copies so called master NVRAM store file defined
|
||||
+ in <code>qemu.conf</code>. If needed, the <code>template</code>
|
||||
+ attribute can be used to per domain override map of master NVRAM stores
|
||||
+ from the config file. <span class="since">Since 1.2.8</span></dd>
|
||||
<dt><code>boot</code></dt>
|
||||
<dd>The <code>dev</code> attribute takes one of the values "fd", "hd",
|
||||
"cdrom" or "network" and is used to specify the next boot device
|
||||
diff --git a/docs/schemas/domaincommon.rng b/docs/schemas/domaincommon.rng
|
||||
index 5d9c21c..6ae940a 100644
|
||||
--- a/docs/schemas/domaincommon.rng
|
||||
+++ b/docs/schemas/domaincommon.rng
|
||||
@@ -263,7 +263,14 @@
|
||||
</optional>
|
||||
<optional>
|
||||
<element name="nvram">
|
||||
- <ref name="absFilePath"/>
|
||||
+ <optional>
|
||||
+ <attribute name="template">
|
||||
+ <ref name="absFilePath"/>
|
||||
+ </attribute>
|
||||
+ </optional>
|
||||
+ <optional>
|
||||
+ <ref name="absFilePath"/>
|
||||
+ </optional>
|
||||
</element>
|
||||
</optional>
|
||||
<optional>
|
||||
diff --git a/libvirt.spec.in b/libvirt.spec.in
|
||||
index 6129f00..935b8c8 100644
|
||||
--- a/libvirt.spec.in
|
||||
+++ b/libvirt.spec.in
|
||||
@@ -1970,6 +1970,7 @@ exit 0
|
||||
%dir %attr(0750, %{qemu_user}, %{qemu_group}) %{_localstatedir}/lib/libvirt/qemu/
|
||||
%dir %attr(0750, %{qemu_user}, %{qemu_group}) %{_localstatedir}/lib/libvirt/qemu/channel/
|
||||
%dir %attr(0750, %{qemu_user}, %{qemu_group}) %{_localstatedir}/lib/libvirt/qemu/channel/target/
|
||||
+%dir %attr(0750, %{qemu_user}, %{qemu_group}) %{_localstatedir}/lib/libvirt/qemu/nvram/
|
||||
%dir %attr(0750, %{qemu_user}, %{qemu_group}) %{_localstatedir}/cache/libvirt/qemu/
|
||||
%{_datadir}/augeas/lenses/libvirtd_qemu.aug
|
||||
%{_datadir}/augeas/lenses/tests/test_libvirtd_qemu.aug
|
||||
@@ -2072,6 +2073,7 @@ exit 0
|
||||
%dir %attr(0750, %{qemu_user}, %{qemu_group}) %{_localstatedir}/lib/libvirt/qemu/
|
||||
%dir %attr(0750, %{qemu_user}, %{qemu_group}) %{_localstatedir}/lib/libvirt/qemu/channel/
|
||||
%dir %attr(0750, %{qemu_user}, %{qemu_group}) %{_localstatedir}/lib/libvirt/qemu/channel/target/
|
||||
+%dir %attr(0750, %{qemu_user}, %{qemu_group}) %{_localstatedir}/lib/libvirt/qemu/nvram/
|
||||
%dir %attr(0750, %{qemu_user}, %{qemu_group}) %{_localstatedir}/cache/libvirt/qemu/
|
||||
%{_datadir}/augeas/lenses/libvirtd_qemu.aug
|
||||
%{_datadir}/augeas/lenses/tests/test_libvirtd_qemu.aug
|
||||
diff --git a/src/Makefile.am b/src/Makefile.am
|
||||
index 46e411e..fa741a8 100644
|
||||
--- a/src/Makefile.am
|
||||
+++ b/src/Makefile.am
|
||||
@@ -2679,6 +2679,7 @@ endif WITH_SANLOCK
|
||||
if WITH_QEMU
|
||||
$(MKDIR_P) "$(DESTDIR)$(localstatedir)/lib/libvirt/qemu"
|
||||
$(MKDIR_P) "$(DESTDIR)$(localstatedir)/lib/libvirt/qemu/channel/target"
|
||||
+ $(MKDIR_P) "$(DESTDIR)$(localstatedir)/lib/libvirt/qemu/nvram"
|
||||
$(MKDIR_P) "$(DESTDIR)$(localstatedir)/run/libvirt/qemu"
|
||||
$(MKDIR_P) "$(DESTDIR)$(localstatedir)/cache/libvirt/qemu"
|
||||
$(MKDIR_P) "$(DESTDIR)$(localstatedir)/log/libvirt/qemu"
|
||||
diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c
|
||||
index 6ee5c17..84f5f1d 100644
|
||||
--- a/src/conf/domain_conf.c
|
||||
+++ b/src/conf/domain_conf.c
|
||||
@@ -2023,6 +2023,7 @@ virDomainLoaderDefFree(virDomainLoaderDefPtr loader)
|
||||
|
||||
VIR_FREE(loader->path);
|
||||
VIR_FREE(loader->nvram);
|
||||
+ VIR_FREE(loader->templt);
|
||||
VIR_FREE(loader);
|
||||
}
|
||||
|
||||
@@ -12768,6 +12769,7 @@ virDomainDefParseXML(xmlDocPtr xml,
|
||||
goto error;
|
||||
|
||||
def->os.loader->nvram = virXPathString("string(./os/nvram[1])", ctxt);
|
||||
+ def->os.loader->templt = virXPathString("string(./os/nvram[1]/@template)", ctxt);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -17866,7 +17868,14 @@ virDomainLoaderDefFormat(virBufferPtr buf,
|
||||
virBufferAsprintf(buf, " type='%s'>", type);
|
||||
|
||||
virBufferEscapeString(buf, "%s</loader>\n", loader->path);
|
||||
- virBufferEscapeString(buf, "<nvram>%s</nvram>\n", loader->nvram);
|
||||
+ if (loader->nvram || loader->templt) {
|
||||
+ virBufferAddLit(buf, "<nvram");
|
||||
+ virBufferEscapeString(buf, " template='%s'", loader->templt);
|
||||
+ if (loader->nvram)
|
||||
+ virBufferEscapeString(buf, ">%s</nvram>\n", loader->nvram);
|
||||
+ else
|
||||
+ virBufferAddLit(buf, "/>\n");
|
||||
+ }
|
||||
}
|
||||
|
||||
static bool
|
||||
diff --git a/src/conf/domain_conf.h b/src/conf/domain_conf.h
|
||||
index c97a10c..3316fb6 100644
|
||||
--- a/src/conf/domain_conf.h
|
||||
+++ b/src/conf/domain_conf.h
|
||||
@@ -1644,6 +1644,7 @@ struct _virDomainLoaderDef {
|
||||
int readonly; /* enum virTristateBool */
|
||||
virDomainLoader type;
|
||||
char *nvram; /* path to non-volatile RAM */
|
||||
+ char *templt; /* user override of path to master nvram */
|
||||
};
|
||||
|
||||
void virDomainLoaderDefFree(virDomainLoaderDefPtr loader);
|
||||
diff --git a/src/qemu/libvirtd_qemu.aug b/src/qemu/libvirtd_qemu.aug
|
||||
index e7db7fe..62951da 100644
|
||||
--- a/src/qemu/libvirtd_qemu.aug
|
||||
+++ b/src/qemu/libvirtd_qemu.aug
|
||||
@@ -88,6 +88,8 @@ module Libvirtd_qemu =
|
||||
|
||||
let log_entry = bool_entry "log_timestamp"
|
||||
|
||||
+ let nvram_entry = str_array_entry "nvram"
|
||||
+
|
||||
(* Each entry in the config is one of the following ... *)
|
||||
let entry = vnc_entry
|
||||
| spice_entry
|
||||
@@ -100,6 +102,7 @@ module Libvirtd_qemu =
|
||||
| rpc_entry
|
||||
| network_entry
|
||||
| log_entry
|
||||
+ | nvram_entry
|
||||
|
||||
let comment = [ label "#comment" . del /#[ \t]*/ "# " . store /([^ \t\n][^\n]*)?/ . del /\n/ "\n" ]
|
||||
let empty = [ label "#empty" . eol ]
|
||||
diff --git a/src/qemu/qemu.conf b/src/qemu/qemu.conf
|
||||
index 7bbbe09..79bba36 100644
|
||||
--- a/src/qemu/qemu.conf
|
||||
+++ b/src/qemu/qemu.conf
|
||||
@@ -487,3 +487,17 @@
|
||||
# Defaults to 1.
|
||||
#
|
||||
#log_timestamp = 0
|
||||
+
|
||||
+
|
||||
+# Location of master nvram file
|
||||
+#
|
||||
+# When a domain is configured to use UEFI instead of standard
|
||||
+# BIOS it may use a separate storage for UEFI variables. If
|
||||
+# that's the case libvirt creates the variable store per domain
|
||||
+# using this master file as image. Each UEFI firmware can,
|
||||
+# however, have different variables store. Therefore the nvram is
|
||||
+# a list of strings when a single item is in form of:
|
||||
+# ${PATH_TO_UEFI_FW}:${PATH_TO_UEFI_VARS}.
|
||||
+# Later, when libvirt creates per domain variable store, this
|
||||
+# list is searched for the master image.
|
||||
+#nvram = [ "/usr/share/OVMF/OVMF_CODE.fd:/usr/share/OVMF/OVMF_VARS.fd" ]
|
||||
diff --git a/src/qemu/qemu_conf.c b/src/qemu/qemu_conf.c
|
||||
index e2ec54f..ac10b64 100644
|
||||
--- a/src/qemu/qemu_conf.c
|
||||
+++ b/src/qemu/qemu_conf.c
|
||||
@@ -107,6 +107,9 @@ void qemuDomainCmdlineDefFree(qemuDomainCmdlineDefPtr def)
|
||||
VIR_FREE(def);
|
||||
}
|
||||
|
||||
+#define VIR_QEMU_LOADER_FILE_PATH "/usr/share/OVMF/OVMF_CODE.fd"
|
||||
+#define VIR_QEMU_NVRAM_FILE_PATH "/usr/share/OVMF/OVMF_VARS.fd"
|
||||
+
|
||||
virQEMUDriverConfigPtr virQEMUDriverConfigNew(bool privileged)
|
||||
{
|
||||
virQEMUDriverConfigPtr cfg;
|
||||
@@ -255,6 +258,15 @@ virQEMUDriverConfigPtr virQEMUDriverConfigNew(bool privileged)
|
||||
|
||||
cfg->logTimestamp = true;
|
||||
|
||||
+ if (VIR_ALLOC_N(cfg->loader, 1) < 0 ||
|
||||
+ VIR_ALLOC_N(cfg->nvram, 1) < 0)
|
||||
+ goto error;
|
||||
+ cfg->nloader = 1;
|
||||
+
|
||||
+ if (VIR_STRDUP(cfg->loader[0], VIR_QEMU_LOADER_FILE_PATH) < 0 ||
|
||||
+ VIR_STRDUP(cfg->nvram[0], VIR_QEMU_NVRAM_FILE_PATH) < 0)
|
||||
+ goto error;
|
||||
+
|
||||
return cfg;
|
||||
|
||||
error:
|
||||
@@ -305,6 +317,14 @@ static void virQEMUDriverConfigDispose(void *obj)
|
||||
virStringFreeList(cfg->securityDriverNames);
|
||||
|
||||
VIR_FREE(cfg->lockManagerName);
|
||||
+
|
||||
+ while (cfg->nloader) {
|
||||
+ VIR_FREE(cfg->loader[cfg->nloader - 1]);
|
||||
+ VIR_FREE(cfg->nvram[cfg->nloader - 1]);
|
||||
+ cfg->nloader--;
|
||||
+ }
|
||||
+ VIR_FREE(cfg->loader);
|
||||
+ VIR_FREE(cfg->nvram);
|
||||
}
|
||||
|
||||
|
||||
@@ -328,6 +348,43 @@ virQEMUDriverConfigHugeTLBFSInit(virHugeTLBFSPtr hugetlbfs,
|
||||
}
|
||||
|
||||
|
||||
+static int
|
||||
+virQEMUDriverConfigNVRAMParse(const char *str,
|
||||
+ char **loader,
|
||||
+ char **nvram)
|
||||
+{
|
||||
+ int ret = -1;
|
||||
+ char **token;
|
||||
+
|
||||
+ if (!(token = virStringSplit(str, ":", 0)))
|
||||
+ goto cleanup;
|
||||
+
|
||||
+ if (token[0]) {
|
||||
+ virSkipSpaces((const char **) &token[0]);
|
||||
+ if (token[1])
|
||||
+ virSkipSpaces((const char **) &token[1]);
|
||||
+ }
|
||||
+
|
||||
+ /* Exactly two tokens are expected */
|
||||
+ if (!token[0] || !token[1] || token[2] ||
|
||||
+ STREQ(token[0], "") || STREQ(token[1], "")) {
|
||||
+ virReportError(VIR_ERR_CONF_SYNTAX,
|
||||
+ _("Invalid nvram format: '%s'"),
|
||||
+ str);
|
||||
+ goto cleanup;
|
||||
+ }
|
||||
+
|
||||
+ if (VIR_STRDUP(*loader, token[0]) < 0 ||
|
||||
+ VIR_STRDUP(*nvram, token[1]) < 0)
|
||||
+ goto cleanup;
|
||||
+
|
||||
+ ret = 0;
|
||||
+ cleanup:
|
||||
+ virStringFreeList(token);
|
||||
+ return ret;
|
||||
+}
|
||||
+
|
||||
+
|
||||
int virQEMUDriverConfigLoadFile(virQEMUDriverConfigPtr cfg,
|
||||
const char *filename)
|
||||
{
|
||||
@@ -654,6 +711,43 @@ int virQEMUDriverConfigLoadFile(virQEMUDriverConfigPtr cfg,
|
||||
|
||||
GET_VALUE_BOOL("log_timestamp", cfg->logTimestamp);
|
||||
|
||||
+ if ((p = virConfGetValue(conf, "nvram"))) {
|
||||
+ size_t len;
|
||||
+ virConfValuePtr pp;
|
||||
+
|
||||
+ CHECK_TYPE("nvram", VIR_CONF_LIST);
|
||||
+
|
||||
+ while (cfg->nloader) {
|
||||
+ VIR_FREE(cfg->loader[cfg->nloader - 1]);
|
||||
+ VIR_FREE(cfg->nvram[cfg->nloader - 1]);
|
||||
+ cfg->nloader--;
|
||||
+ }
|
||||
+ VIR_FREE(cfg->loader);
|
||||
+ VIR_FREE(cfg->nvram);
|
||||
+
|
||||
+ /* Calc length and check items */
|
||||
+ for (len = 0, pp = p->list; pp; len++, pp = pp->next) {
|
||||
+ if (pp->type != VIR_CONF_STRING) {
|
||||
+ virReportError(VIR_ERR_CONF_SYNTAX, "%s",
|
||||
+ _("nvram must be a list of strings"));
|
||||
+ goto cleanup;
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ if (len &&
|
||||
+ (VIR_ALLOC_N(cfg->loader, len) < 0 ||
|
||||
+ VIR_ALLOC_N(cfg->nvram, len) < 0))
|
||||
+ goto cleanup;
|
||||
+ cfg->nloader = len;
|
||||
+
|
||||
+ for (i = 0, pp = p->list; pp; i++, pp = pp->next) {
|
||||
+ if (virQEMUDriverConfigNVRAMParse(pp->str,
|
||||
+ &cfg->loader[i],
|
||||
+ &cfg->nvram[i]) < 0)
|
||||
+ goto cleanup;
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
ret = 0;
|
||||
|
||||
cleanup:
|
||||
diff --git a/src/qemu/qemu_conf.h b/src/qemu/qemu_conf.h
|
||||
index ae7ac56..1f521e5 100644
|
||||
--- a/src/qemu/qemu_conf.h
|
||||
+++ b/src/qemu/qemu_conf.h
|
||||
@@ -172,6 +172,11 @@ struct _virQEMUDriverConfig {
|
||||
int migrationPortMax;
|
||||
|
||||
bool logTimestamp;
|
||||
+
|
||||
+ /* Pairs of loader:nvram paths. The list is @nloader items long */
|
||||
+ char **loader;
|
||||
+ char **nvram;
|
||||
+ size_t nloader;
|
||||
};
|
||||
|
||||
/* Main driver state */
|
||||
diff --git a/src/qemu/qemu_process.c b/src/qemu/qemu_process.c
|
||||
index f68dfbe..5b120d4 100644
|
||||
--- a/src/qemu/qemu_process.c
|
||||
+++ b/src/qemu/qemu_process.c
|
||||
@@ -67,6 +67,7 @@
|
||||
#include "virstring.h"
|
||||
#include "virhostdev.h"
|
||||
#include "storage/storage_driver.h"
|
||||
+#include "configmake.h"
|
||||
|
||||
#define VIR_FROM_THIS VIR_FROM_QEMU
|
||||
|
||||
@@ -3734,6 +3735,135 @@ qemuProcessVerifyGuestCPU(virQEMUDriverPtr driver,
|
||||
}
|
||||
|
||||
|
||||
+static int
|
||||
+qemuPrepareNVRAM(virQEMUDriverConfigPtr cfg,
|
||||
+ virDomainDefPtr def,
|
||||
+ bool migrated)
|
||||
+{
|
||||
+ int ret = -1;
|
||||
+ int srcFD = -1;
|
||||
+ int dstFD = -1;
|
||||
+ virDomainLoaderDefPtr loader = def->os.loader;
|
||||
+ bool generated = false;
|
||||
+ bool created = false;
|
||||
+
|
||||
+ /* Unless domain has RO loader of pflash type, we have
|
||||
+ * nothing to do here. If the loader is RW then it's not
|
||||
+ * using split code and vars feature, so no nvram file needs
|
||||
+ * to be created. */
|
||||
+ if (!loader || loader->type != VIR_DOMAIN_LOADER_TYPE_PFLASH ||
|
||||
+ loader->readonly != VIR_TRISTATE_SWITCH_ON)
|
||||
+ return 0;
|
||||
+
|
||||
+ /* If the nvram path is configured already, there's nothing
|
||||
+ * we need to do. Unless we are starting the destination side
|
||||
+ * of migration in which case nvram is configured in the
|
||||
+ * domain XML but the file doesn't exist yet. Moreover, after
|
||||
+ * the migration is completed, qemu will invoke a
|
||||
+ * synchronization write into the nvram file so we don't have
|
||||
+ * to take care about transmitting the real data on the other
|
||||
+ * side. */
|
||||
+ if (loader->nvram && !migrated)
|
||||
+ return 0;
|
||||
+
|
||||
+ /* Autogenerate nvram path if needed.*/
|
||||
+ if (!loader->nvram) {
|
||||
+ if (virAsprintf(&loader->nvram,
|
||||
+ "%s/lib/libvirt/qemu/nvram/%s_VARS.fd",
|
||||
+ LOCALSTATEDIR, def->name) < 0)
|
||||
+ goto cleanup;
|
||||
+
|
||||
+ generated = true;
|
||||
+ }
|
||||
+
|
||||
+ if (!virFileExists(loader->nvram)) {
|
||||
+ const char *master_nvram_path = loader->templt;
|
||||
+ ssize_t r;
|
||||
+
|
||||
+ if (!loader->templt) {
|
||||
+ size_t i;
|
||||
+ for (i = 0; i < cfg->nloader; i++) {
|
||||
+ if (STREQ(cfg->loader[i], loader->path)) {
|
||||
+ master_nvram_path = cfg->nvram[i];
|
||||
+ break;
|
||||
+ }
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ if (!master_nvram_path) {
|
||||
+ virReportError(VIR_ERR_OPERATION_FAILED,
|
||||
+ _("unable to find any master var store for "
|
||||
+ "loader: %s"), loader->path);
|
||||
+ goto cleanup;
|
||||
+ }
|
||||
+
|
||||
+ if ((srcFD = virFileOpenAs(master_nvram_path, O_RDONLY,
|
||||
+ 0, -1, -1, 0)) < 0) {
|
||||
+ virReportSystemError(-srcFD,
|
||||
+ _("Failed to open file '%s'"),
|
||||
+ master_nvram_path);
|
||||
+ goto cleanup;
|
||||
+ }
|
||||
+ if ((dstFD = virFileOpenAs(loader->nvram,
|
||||
+ O_WRONLY | O_CREAT | O_EXCL,
|
||||
+ S_IRUSR | S_IWUSR,
|
||||
+ cfg->user, cfg->group, 0)) < 0) {
|
||||
+ virReportSystemError(-dstFD,
|
||||
+ _("Failed to create file '%s'"),
|
||||
+ loader->nvram);
|
||||
+ goto cleanup;
|
||||
+ }
|
||||
+ created = true;
|
||||
+
|
||||
+ do {
|
||||
+ char buf[1024];
|
||||
+
|
||||
+ if ((r = saferead(srcFD, buf, sizeof(buf))) < 0) {
|
||||
+ virReportSystemError(errno,
|
||||
+ _("Unable to read from file '%s'"),
|
||||
+ master_nvram_path);
|
||||
+ goto cleanup;
|
||||
+ }
|
||||
+
|
||||
+ if (safewrite(dstFD, buf, r) < 0) {
|
||||
+ virReportSystemError(errno,
|
||||
+ _("Unable to write to file '%s'"),
|
||||
+ loader->nvram);
|
||||
+ goto cleanup;
|
||||
+ }
|
||||
+ } while (r);
|
||||
+
|
||||
+ if (VIR_CLOSE(srcFD) < 0) {
|
||||
+ virReportSystemError(errno,
|
||||
+ _("Unable to close file '%s'"),
|
||||
+ master_nvram_path);
|
||||
+ goto cleanup;
|
||||
+ }
|
||||
+ if (VIR_CLOSE(dstFD) < 0) {
|
||||
+ virReportSystemError(errno,
|
||||
+ _("Unable to close file '%s'"),
|
||||
+ loader->nvram);
|
||||
+ goto cleanup;
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ ret = 0;
|
||||
+ cleanup:
|
||||
+ /* We successfully generated the nvram path, but failed to
|
||||
+ * copy the file content. Roll back. */
|
||||
+ if (ret < 0) {
|
||||
+ if (created)
|
||||
+ unlink(loader->nvram);
|
||||
+ if (generated)
|
||||
+ VIR_FREE(loader->nvram);
|
||||
+ }
|
||||
+
|
||||
+ VIR_FORCE_CLOSE(srcFD);
|
||||
+ VIR_FORCE_CLOSE(dstFD);
|
||||
+ return ret;
|
||||
+}
|
||||
+
|
||||
+
|
||||
int qemuProcessStart(virConnectPtr conn,
|
||||
virQEMUDriverPtr driver,
|
||||
virDomainObjPtr vm,
|
||||
@@ -3802,6 +3932,13 @@ int qemuProcessStart(virConnectPtr conn,
|
||||
if (!(caps = virQEMUDriverGetCapabilities(driver, false)))
|
||||
goto cleanup;
|
||||
|
||||
+ /* Some things, paths, ... are generated here and we want them to persist.
|
||||
+ * Fill them in prior to setting the domain def as transient. */
|
||||
+ VIR_DEBUG("Generating paths");
|
||||
+
|
||||
+ if (qemuPrepareNVRAM(cfg, vm->def, migrateFrom) < 0)
|
||||
+ goto cleanup;
|
||||
+
|
||||
/* Do this upfront, so any part of the startup process can add
|
||||
* runtime state to vm->def that won't be persisted. This let's us
|
||||
* report implicit runtime defaults in the XML, like vnc listen/socket
|
||||
diff --git a/src/qemu/test_libvirtd_qemu.aug.in b/src/qemu/test_libvirtd_qemu.aug.in
|
||||
index 7796acc..d2bc2c0 100644
|
||||
--- a/src/qemu/test_libvirtd_qemu.aug.in
|
||||
+++ b/src/qemu/test_libvirtd_qemu.aug.in
|
||||
@@ -74,3 +74,6 @@ module Test_libvirtd_qemu =
|
||||
{ "migration_port_min" = "49152" }
|
||||
{ "migration_port_max" = "49215" }
|
||||
{ "log_timestamp" = "0" }
|
||||
+{ "nvram"
|
||||
+ { "1" = "/usr/share/OVMF/OVMF_CODE.fd:/usr/share/OVMF/OVMF_VARS.fd" }
|
||||
+}
|
||||
diff --git a/tests/domainschemadata/domain-bios-nvram-empty.xml b/tests/domainschemadata/domain-bios-nvram-empty.xml
|
||||
new file mode 100644
|
||||
index 0000000..e7643f3
|
||||
--- /dev/null
|
||||
+++ b/tests/domainschemadata/domain-bios-nvram-empty.xml
|
||||
@@ -0,0 +1,40 @@
|
||||
+<domain type='qemu'>
|
||||
+ <name>test-bios</name>
|
||||
+ <uuid>362d1fc1-df7d-193e-5c18-49a71bd1da66</uuid>
|
||||
+ <memory unit='KiB'>1048576</memory>
|
||||
+ <currentMemory unit='KiB'>1048576</currentMemory>
|
||||
+ <vcpu placement='static'>1</vcpu>
|
||||
+ <os>
|
||||
+ <type arch='x86_64' machine='pc'>hvm</type>
|
||||
+ <loader readonly='yes' type='pflash'>/usr/share/OVMF/OVMF_CODE.fd</loader>
|
||||
+ <nvram template='/usr/share/OVMF/OVMF_VARS.fd'/>
|
||||
+ <boot dev='hd'/>
|
||||
+ <bootmenu enable='yes'/>
|
||||
+ </os>
|
||||
+ <features>
|
||||
+ <acpi/>
|
||||
+ </features>
|
||||
+ <clock offset='utc'/>
|
||||
+ <on_poweroff>destroy</on_poweroff>
|
||||
+ <on_reboot>restart</on_reboot>
|
||||
+ <on_crash>restart</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='usb' index='0'/>
|
||||
+ <controller type='ide' index='0'/>
|
||||
+ <controller type='pci' index='0' model='pci-root'/>
|
||||
+ <serial type='pty'>
|
||||
+ <target port='0'/>
|
||||
+ </serial>
|
||||
+ <console type='pty'>
|
||||
+ <target type='serial' port='0'/>
|
||||
+ </console>
|
||||
+ <input type='tablet' bus='usb'/>
|
||||
+ <memballoon model='virtio'/>
|
||||
+ </devices>
|
||||
+</domain>
|
53
0014-nvram-Fix-permissions.patch
Normal file
53
0014-nvram-Fix-permissions.patch
Normal file
@ -0,0 +1,53 @@
|
||||
From 884ef00a28244b34d66ada97c8ddd3e7d7ea8ff1 Mon Sep 17 00:00:00 2001
|
||||
From: Michal Privoznik <mprivozn@redhat.com>
|
||||
Date: Thu, 11 Sep 2014 12:09:04 +0200
|
||||
Subject: [PATCH] nvram: Fix permissions
|
||||
|
||||
I've noticed two problem with the automatically created NVRAM varstore
|
||||
file. The first, even though I run qemu as root:root for some reason I
|
||||
get Permission denied when trying to open the _VARS.fd file. The
|
||||
problem is, the upper directory misses execute permissions, which in
|
||||
combination with us dropping some capabilities result in EPERM.
|
||||
|
||||
The next thing is, that if I switch SELinux to enforcing mode, I get
|
||||
another EPERM because the vars file is not labeled correctly. It is
|
||||
passed to qemu as disk and hence should be labelled as disk. QEMU may
|
||||
write to it eventually, so this is different to kernel or initrd.
|
||||
|
||||
Signed-off-by: Michal Privoznik <mprivozn@redhat.com>
|
||||
(cherry picked from commit 37d8c75fad297891b80086b125046ed3990eaf59)
|
||||
---
|
||||
libvirt.spec.in | 2 +-
|
||||
src/security/security_selinux.c | 5 ++++-
|
||||
2 files changed, 5 insertions(+), 2 deletions(-)
|
||||
|
||||
diff --git a/libvirt.spec.in b/libvirt.spec.in
|
||||
index 935b8c8..3cd7b2e 100644
|
||||
--- a/libvirt.spec.in
|
||||
+++ b/libvirt.spec.in
|
||||
@@ -1970,7 +1970,7 @@ exit 0
|
||||
%dir %attr(0750, %{qemu_user}, %{qemu_group}) %{_localstatedir}/lib/libvirt/qemu/
|
||||
%dir %attr(0750, %{qemu_user}, %{qemu_group}) %{_localstatedir}/lib/libvirt/qemu/channel/
|
||||
%dir %attr(0750, %{qemu_user}, %{qemu_group}) %{_localstatedir}/lib/libvirt/qemu/channel/target/
|
||||
-%dir %attr(0750, %{qemu_user}, %{qemu_group}) %{_localstatedir}/lib/libvirt/qemu/nvram/
|
||||
+%dir %attr(0711, %{qemu_user}, %{qemu_group}) %{_localstatedir}/lib/libvirt/qemu/nvram/
|
||||
%dir %attr(0750, %{qemu_user}, %{qemu_group}) %{_localstatedir}/cache/libvirt/qemu/
|
||||
%{_datadir}/augeas/lenses/libvirtd_qemu.aug
|
||||
%{_datadir}/augeas/lenses/tests/test_libvirtd_qemu.aug
|
||||
diff --git a/src/security/security_selinux.c b/src/security/security_selinux.c
|
||||
index a409c19..b9efbc5 100644
|
||||
--- a/src/security/security_selinux.c
|
||||
+++ b/src/security/security_selinux.c
|
||||
@@ -2298,8 +2298,11 @@ virSecuritySELinuxSetSecurityAllLabel(virSecurityManagerPtr mgr,
|
||||
mgr) < 0)
|
||||
return -1;
|
||||
|
||||
+ /* This is different than kernel or initrd. The nvram store
|
||||
+ * is really a disk, qemu can read and write to it. */
|
||||
if (def->os.loader && def->os.loader->nvram &&
|
||||
- virSecuritySELinuxSetFilecon(def->os.loader->nvram, data->content_context) < 0)
|
||||
+ secdef && secdef->imagelabel &&
|
||||
+ virSecuritySELinuxSetFilecon(def->os.loader->nvram, secdef->imagelabel) < 0)
|
||||
return -1;
|
||||
|
||||
if (def->os.kernel &&
|
148
0015-virDomainUndefineFlags-Allow-NVRAM-unlinking.patch
Normal file
148
0015-virDomainUndefineFlags-Allow-NVRAM-unlinking.patch
Normal file
@ -0,0 +1,148 @@
|
||||
From 03c156e5d54b311291101ca21690b586222be276 Mon Sep 17 00:00:00 2001
|
||||
From: Michal Privoznik <mprivozn@redhat.com>
|
||||
Date: Thu, 11 Sep 2014 13:17:11 +0200
|
||||
Subject: [PATCH] virDomainUndefineFlags: Allow NVRAM unlinking
|
||||
|
||||
When a domain is undefined, there are options to remove it's
|
||||
managed save state or snapshots. However, there's another file
|
||||
that libvirt creates per domain: the NVRAM variable store file.
|
||||
Make sure that the file is not left behind if the domain is
|
||||
undefined.
|
||||
|
||||
Signed-off-by: Michal Privoznik <mprivozn@redhat.com>
|
||||
(cherry picked from commit 273b6581ca8dae11e6ff40e3d13813fdbb37d41b)
|
||||
---
|
||||
include/libvirt/libvirt.h.in | 2 ++
|
||||
src/qemu/qemu_driver.c | 20 +++++++++++++++++++-
|
||||
tools/virsh-domain.c | 20 ++++++++++++++++----
|
||||
tools/virsh.pod | 6 +++++-
|
||||
4 files changed, 42 insertions(+), 6 deletions(-)
|
||||
|
||||
diff --git a/include/libvirt/libvirt.h.in b/include/libvirt/libvirt.h.in
|
||||
index a64f597..8996231 100644
|
||||
--- a/include/libvirt/libvirt.h.in
|
||||
+++ b/include/libvirt/libvirt.h.in
|
||||
@@ -2257,6 +2257,8 @@ typedef enum {
|
||||
VIR_DOMAIN_UNDEFINE_SNAPSHOTS_METADATA = (1 << 1), /* If last use of domain,
|
||||
then also remove any
|
||||
snapshot metadata */
|
||||
+ VIR_DOMAIN_UNDEFINE_NVRAM = (1 << 2), /* Also remove any
|
||||
+ nvram file */
|
||||
|
||||
/* Future undefine control flags should come here. */
|
||||
} virDomainUndefineFlagsValues;
|
||||
diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c
|
||||
index 239a300..588eba4 100644
|
||||
--- a/src/qemu/qemu_driver.c
|
||||
+++ b/src/qemu/qemu_driver.c
|
||||
@@ -6402,7 +6402,8 @@ qemuDomainUndefineFlags(virDomainPtr dom,
|
||||
virQEMUDriverConfigPtr cfg = NULL;
|
||||
|
||||
virCheckFlags(VIR_DOMAIN_UNDEFINE_MANAGED_SAVE |
|
||||
- VIR_DOMAIN_UNDEFINE_SNAPSHOTS_METADATA, -1);
|
||||
+ VIR_DOMAIN_UNDEFINE_SNAPSHOTS_METADATA |
|
||||
+ VIR_DOMAIN_UNDEFINE_NVRAM, -1);
|
||||
|
||||
if (!(vm = qemuDomObjFromDomain(dom)))
|
||||
return -1;
|
||||
@@ -6451,6 +6452,23 @@ qemuDomainUndefineFlags(virDomainPtr dom,
|
||||
}
|
||||
}
|
||||
|
||||
+ if (!virDomainObjIsActive(vm) &&
|
||||
+ vm->def->os.loader && vm->def->os.loader->nvram &&
|
||||
+ virFileExists(vm->def->os.loader->nvram)) {
|
||||
+ if (!(flags & VIR_DOMAIN_UNDEFINE_NVRAM)) {
|
||||
+ virReportError(VIR_ERR_OPERATION_INVALID, "%s",
|
||||
+ _("cannot delete inactive domain with nvram"));
|
||||
+ goto cleanup;
|
||||
+ }
|
||||
+
|
||||
+ if (unlink(vm->def->os.loader->nvram) < 0) {
|
||||
+ virReportSystemError(errno,
|
||||
+ _("failed to remove nvram: %s"),
|
||||
+ vm->def->os.loader->nvram);
|
||||
+ goto cleanup;
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
if (virDomainDeleteConfig(cfg->configDir, cfg->autostartDir, vm) < 0)
|
||||
goto cleanup;
|
||||
|
||||
diff --git a/tools/virsh-domain.c b/tools/virsh-domain.c
|
||||
index c75cd73..d84db51 100644
|
||||
--- a/tools/virsh-domain.c
|
||||
+++ b/tools/virsh-domain.c
|
||||
@@ -3038,6 +3038,10 @@ static const vshCmdOptDef opts_undefine[] = {
|
||||
.type = VSH_OT_BOOL,
|
||||
.help = N_("remove all domain snapshot metadata, if inactive")
|
||||
},
|
||||
+ {.name = "nvram",
|
||||
+ .type = VSH_OT_BOOL,
|
||||
+ .help = N_("remove nvram file, if inactive")
|
||||
+ },
|
||||
{.name = NULL}
|
||||
};
|
||||
|
||||
@@ -3060,6 +3064,7 @@ cmdUndefine(vshControl *ctl, const vshCmd *cmd)
|
||||
bool snapshots_metadata = vshCommandOptBool(cmd, "snapshots-metadata");
|
||||
bool wipe_storage = vshCommandOptBool(cmd, "wipe-storage");
|
||||
bool remove_all_storage = vshCommandOptBool(cmd, "remove-all-storage");
|
||||
+ bool nvram = vshCommandOptBool(cmd, "nvram");
|
||||
/* Positive if these items exist. */
|
||||
int has_managed_save = 0;
|
||||
int has_snapshots_metadata = 0;
|
||||
@@ -3103,6 +3108,9 @@ cmdUndefine(vshControl *ctl, const vshCmd *cmd)
|
||||
flags |= VIR_DOMAIN_UNDEFINE_SNAPSHOTS_METADATA;
|
||||
snapshots_safe = true;
|
||||
}
|
||||
+ if (nvram) {
|
||||
+ flags |= VIR_DOMAIN_UNDEFINE_NVRAM;
|
||||
+ }
|
||||
|
||||
if (!(dom = vshCommandOptDomain(ctl, cmd, &name)))
|
||||
return false;
|
||||
@@ -3293,11 +3301,15 @@ cmdUndefine(vshControl *ctl, const vshCmd *cmd)
|
||||
* VIR_DOMAIN_UNDEFINE_MANAGED_SAVE in 0.9.4, the
|
||||
* VIR_DOMAIN_UNDEFINE_SNAPSHOTS_METADATA flag was not present
|
||||
* until 0.9.5; skip to piecewise emulation if we couldn't prove
|
||||
- * above that the new API is safe. */
|
||||
- if (managed_save_safe && snapshots_safe) {
|
||||
+ * above that the new API is safe.
|
||||
+ * Moreover, only the newer UndefineFlags() API understands
|
||||
+ * the VIR_DOMAIN_UNDEFINE_NVRAM flag. So if user has
|
||||
+ * specified --nvram we must use the Flags() API. */
|
||||
+ if ((managed_save_safe && snapshots_safe) || nvram) {
|
||||
rc = virDomainUndefineFlags(dom, flags);
|
||||
- if (rc == 0 || (last_error->code != VIR_ERR_NO_SUPPORT &&
|
||||
- last_error->code != VIR_ERR_INVALID_ARG))
|
||||
+ if (rc == 0 || nvram ||
|
||||
+ (last_error->code != VIR_ERR_NO_SUPPORT &&
|
||||
+ last_error->code != VIR_ERR_INVALID_ARG))
|
||||
goto out;
|
||||
vshResetLibvirtError();
|
||||
}
|
||||
diff --git a/tools/virsh.pod b/tools/virsh.pod
|
||||
index ea9267e..a9fad73 100644
|
||||
--- a/tools/virsh.pod
|
||||
+++ b/tools/virsh.pod
|
||||
@@ -2058,7 +2058,7 @@ Output the device used for the TTY console of the domain. If the information
|
||||
is not available the processes will provide an exit code of 1.
|
||||
|
||||
=item B<undefine> I<domain> [I<--managed-save>] [I<--snapshots-metadata>]
|
||||
-[ {I<--storage> B<volumes> | I<--remove-all-storage>} I<--wipe-storage>]
|
||||
+[I<--nvram>] [ {I<--storage> B<volumes> | I<--remove-all-storage>} I<--wipe-storage>]
|
||||
|
||||
Undefine a domain. If the domain is running, this converts it to a
|
||||
transient domain, without stopping it. If the domain is inactive,
|
||||
@@ -2074,6 +2074,10 @@ domain. Without the flag, attempts to undefine an inactive domain with
|
||||
snapshot metadata will fail. If the domain is active, this flag is
|
||||
ignored.
|
||||
|
||||
+The I<--nvram> flag ensures no nvram (/domain/os/nvram/) file is
|
||||
+left behind. If the domain has an nvram file and the flag is
|
||||
+omitted, the undefine will fail.
|
||||
+
|
||||
The I<--storage> flag takes a parameter B<volumes>, which is a comma separated
|
||||
list of volume target names or source paths of storage volumes to be removed
|
||||
along with the undefined domain. Volumes can be undefined and thus removed only
|
@ -0,0 +1,32 @@
|
||||
From 2b30f114b796aee6f92eb13244f8cd42ef523bfe Mon Sep 17 00:00:00 2001
|
||||
From: Michal Privoznik <mprivozn@redhat.com>
|
||||
Date: Fri, 12 Sep 2014 13:18:32 +0200
|
||||
Subject: [PATCH] formatdomain: Update <loader/> example to match the rest
|
||||
|
||||
At the beginning when I was inventing <loader/> attributes and
|
||||
<nvram/> I've introduced this @readonly attribute to the loader
|
||||
element. It accepted values 'on' and 'off'. However, later, during the
|
||||
review process, that has changed to 'yes' and 'no', but the example
|
||||
XML snippet wasn't updated, so while the description is correct, the
|
||||
example isn't.
|
||||
|
||||
Reported-by: Laszlo Ersek <lersek@redhat.com>
|
||||
Signed-off-by: Michal Privoznik <mprivozn@redhat.com>
|
||||
(cherry picked from commit dcf7d0423c1ad79e45df4ddd1cb619603cf221e7)
|
||||
---
|
||||
docs/formatdomain.html.in | 2 +-
|
||||
1 file changed, 1 insertion(+), 1 deletion(-)
|
||||
|
||||
diff --git a/docs/formatdomain.html.in b/docs/formatdomain.html.in
|
||||
index a2ea758..5081be3 100644
|
||||
--- a/docs/formatdomain.html.in
|
||||
+++ b/docs/formatdomain.html.in
|
||||
@@ -102,7 +102,7 @@
|
||||
...
|
||||
<os>
|
||||
<type>hvm</type>
|
||||
- <loader readonly='on' type='rom'>/usr/lib/xen/boot/hvmloader</loader>
|
||||
+ <loader readonly='yes' type='rom'>/usr/lib/xen/boot/hvmloader</loader>
|
||||
<nvram template='/usr/share/OVMF/OVMF_VARS.fd'>/var/lib/libvirt/nvram/guest_VARS.fd</nvram>
|
||||
<boot dev='hd'/>
|
||||
<boot dev='cdrom'/>
|
338
0017-domaincaps-Expose-UEFI-capability.patch
Normal file
338
0017-domaincaps-Expose-UEFI-capability.patch
Normal file
@ -0,0 +1,338 @@
|
||||
From 2c4e9da2b46d55fda49b20ae48dbdd4e63209565 Mon Sep 17 00:00:00 2001
|
||||
From: Michal Privoznik <mprivozn@redhat.com>
|
||||
Date: Tue, 16 Sep 2014 14:47:47 +0200
|
||||
Subject: [PATCH] domaincaps: Expose UEFI capability
|
||||
|
||||
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@redhat.com>
|
||||
(cherry picked from commit 4f76621c0edb895431a6fc30c026865dbf1c1316)
|
||||
---
|
||||
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 c70a1a8..c999ee4 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);
|
192
0018-qemu_capabilities-Change-virQEMUCapsFillDomainCaps-s.patch
Normal file
192
0018-qemu_capabilities-Change-virQEMUCapsFillDomainCaps-s.patch
Normal file
@ -0,0 +1,192 @@
|
||||
From 103a146b669a778238485425f4eb69a5a1f5c747 Mon Sep 17 00:00:00 2001
|
||||
From: Michal Privoznik <mprivozn@redhat.com>
|
||||
Date: Wed, 17 Sep 2014 11:33:35 +0200
|
||||
Subject: [PATCH] qemu_capabilities: Change virQEMUCapsFillDomainCaps signature
|
||||
|
||||
Up till now the virQEMUCapsFillDomainCaps() was type of void as
|
||||
there was no way for it to fail. This is, however, going to
|
||||
change in the next commit.
|
||||
|
||||
Signed-off-by: Michal Privoznik <mprivozn@redhat.com>
|
||||
(cherry picked from commit 2b2e4a7acff5574dd82bfbd61a638270f6be54ef)
|
||||
---
|
||||
src/qemu/qemu_capabilities.c | 25 ++++++++++++++++---------
|
||||
src/qemu/qemu_capabilities.h | 4 ++--
|
||||
src/qemu/qemu_driver.c | 3 ++-
|
||||
tests/domaincapstest.c | 19 ++++++++++++-------
|
||||
4 files changed, 32 insertions(+), 19 deletions(-)
|
||||
|
||||
diff --git a/src/qemu/qemu_capabilities.c b/src/qemu/qemu_capabilities.c
|
||||
index c999ee4..d2e5f47 100644
|
||||
--- a/src/qemu/qemu_capabilities.c
|
||||
+++ b/src/qemu/qemu_capabilities.c
|
||||
@@ -3608,7 +3608,7 @@ virQEMUCapsGetDefaultMachine(virQEMUCapsPtr qemuCaps)
|
||||
}
|
||||
|
||||
|
||||
-static void
|
||||
+static int
|
||||
virQEMUCapsFillDomainLoaderCaps(virQEMUCapsPtr qemuCaps,
|
||||
virDomainCapsLoaderPtr loader,
|
||||
virArch arch)
|
||||
@@ -3629,10 +3629,11 @@ virQEMUCapsFillDomainLoaderCaps(virQEMUCapsPtr qemuCaps,
|
||||
VIR_DOMAIN_CAPS_ENUM_SET(loader->readonly,
|
||||
VIR_TRISTATE_BOOL_YES,
|
||||
VIR_TRISTATE_BOOL_NO);
|
||||
+ return 0;
|
||||
}
|
||||
|
||||
|
||||
-static void
|
||||
+static int
|
||||
virQEMUCapsFillDomainOSCaps(virQEMUCapsPtr qemuCaps,
|
||||
virDomainCapsOSPtr os,
|
||||
virArch arch)
|
||||
@@ -3640,11 +3641,13 @@ virQEMUCapsFillDomainOSCaps(virQEMUCapsPtr qemuCaps,
|
||||
virDomainCapsLoaderPtr loader = &os->loader;
|
||||
|
||||
os->device.supported = true;
|
||||
- virQEMUCapsFillDomainLoaderCaps(qemuCaps, loader, arch);
|
||||
+ if (virQEMUCapsFillDomainLoaderCaps(qemuCaps, loader, arch) < 0)
|
||||
+ return -1;
|
||||
+ return 0;
|
||||
}
|
||||
|
||||
|
||||
-static void
|
||||
+static int
|
||||
virQEMUCapsFillDomainDeviceDiskCaps(virQEMUCapsPtr qemuCaps,
|
||||
virDomainCapsDeviceDiskPtr disk)
|
||||
{
|
||||
@@ -3667,10 +3670,11 @@ virQEMUCapsFillDomainDeviceDiskCaps(virQEMUCapsPtr qemuCaps,
|
||||
|
||||
if (virQEMUCapsGet(qemuCaps, QEMU_CAPS_DEVICE_USB_STORAGE))
|
||||
VIR_DOMAIN_CAPS_ENUM_SET(disk->bus, VIR_DOMAIN_DISK_BUS_USB);
|
||||
+ return 0;
|
||||
}
|
||||
|
||||
|
||||
-static void
|
||||
+static int
|
||||
virQEMUCapsFillDomainDeviceHostdevCaps(virQEMUCapsPtr qemuCaps,
|
||||
virDomainCapsDeviceHostdevPtr hostdev)
|
||||
{
|
||||
@@ -3715,10 +3719,11 @@ virQEMUCapsFillDomainDeviceHostdevCaps(virQEMUCapsPtr qemuCaps,
|
||||
VIR_DOMAIN_HOSTDEV_PCI_BACKEND_DEFAULT,
|
||||
VIR_DOMAIN_HOSTDEV_PCI_BACKEND_KVM);
|
||||
}
|
||||
+ return 0;
|
||||
}
|
||||
|
||||
|
||||
-void
|
||||
+int
|
||||
virQEMUCapsFillDomainCaps(virDomainCapsPtr domCaps,
|
||||
virQEMUCapsPtr qemuCaps)
|
||||
{
|
||||
@@ -3729,7 +3734,9 @@ virQEMUCapsFillDomainCaps(virDomainCapsPtr domCaps,
|
||||
|
||||
domCaps->maxvcpus = maxvcpus;
|
||||
|
||||
- virQEMUCapsFillDomainOSCaps(qemuCaps, os, domCaps->arch);
|
||||
- virQEMUCapsFillDomainDeviceDiskCaps(qemuCaps, disk);
|
||||
- virQEMUCapsFillDomainDeviceHostdevCaps(qemuCaps, hostdev);
|
||||
+ if (virQEMUCapsFillDomainOSCaps(qemuCaps, os, domCaps->arch) < 0 ||
|
||||
+ virQEMUCapsFillDomainDeviceDiskCaps(qemuCaps, disk) < 0 ||
|
||||
+ virQEMUCapsFillDomainDeviceHostdevCaps(qemuCaps, hostdev) < 0)
|
||||
+ return -1;
|
||||
+ return 0;
|
||||
}
|
||||
diff --git a/src/qemu/qemu_capabilities.h b/src/qemu/qemu_capabilities.h
|
||||
index 0980c00..828bba3 100644
|
||||
--- a/src/qemu/qemu_capabilities.h
|
||||
+++ b/src/qemu/qemu_capabilities.h
|
||||
@@ -324,7 +324,7 @@ int virQEMUCapsInitGuestFromBinary(virCapsPtr caps,
|
||||
virQEMUCapsPtr kvmbinCaps,
|
||||
virArch guestarch);
|
||||
|
||||
-void virQEMUCapsFillDomainCaps(virDomainCapsPtr domCaps,
|
||||
- virQEMUCapsPtr qemuCaps);
|
||||
+int virQEMUCapsFillDomainCaps(virDomainCapsPtr domCaps,
|
||||
+ virQEMUCapsPtr qemuCaps);
|
||||
|
||||
#endif /* __QEMU_CAPABILITIES_H__*/
|
||||
diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c
|
||||
index 588eba4..9c1644c 100644
|
||||
--- a/src/qemu/qemu_driver.c
|
||||
+++ b/src/qemu/qemu_driver.c
|
||||
@@ -17205,7 +17205,8 @@ qemuConnectGetDomainCapabilities(virConnectPtr conn,
|
||||
if (!(domCaps = virDomainCapsNew(emulatorbin, machine, arch, virttype)))
|
||||
goto cleanup;
|
||||
|
||||
- virQEMUCapsFillDomainCaps(domCaps, qemuCaps);
|
||||
+ if (virQEMUCapsFillDomainCaps(domCaps, qemuCaps) < 0)
|
||||
+ goto cleanup;
|
||||
|
||||
ret = virDomainCapsFormat(domCaps);
|
||||
cleanup:
|
||||
diff --git a/tests/domaincapstest.c b/tests/domaincapstest.c
|
||||
index f240643..0c4b09f 100644
|
||||
--- a/tests/domaincapstest.c
|
||||
+++ b/tests/domaincapstest.c
|
||||
@@ -28,13 +28,13 @@
|
||||
|
||||
#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
|
||||
fillAll(virDomainCapsPtr domCaps,
|
||||
void *opaque ATTRIBUTE_UNUSED)
|
||||
{
|
||||
@@ -60,18 +60,20 @@ fillAll(virDomainCapsPtr domCaps,
|
||||
SET_ALL_BITS(hostdev->subsysType);
|
||||
SET_ALL_BITS(hostdev->capsType);
|
||||
SET_ALL_BITS(hostdev->pciBackend);
|
||||
+ return 0;
|
||||
}
|
||||
|
||||
|
||||
#ifdef WITH_QEMU
|
||||
# include "testutilsqemu.h"
|
||||
-static void
|
||||
+static int
|
||||
fillQemuCaps(virDomainCapsPtr domCaps,
|
||||
void *opaque)
|
||||
{
|
||||
virQEMUCapsPtr qemuCaps = (virQEMUCapsPtr) opaque;
|
||||
|
||||
- virQEMUCapsFillDomainCaps(domCaps, qemuCaps);
|
||||
+ if (virQEMUCapsFillDomainCaps(domCaps, qemuCaps) < 0)
|
||||
+ return -1;
|
||||
|
||||
/* The function above tries to query host's KVM & VFIO capabilities by
|
||||
* calling qemuHostdevHostSupportsPassthroughLegacy() and
|
||||
@@ -82,6 +84,7 @@ 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 */
|
||||
|
||||
@@ -99,8 +102,10 @@ buildVirDomainCaps(const char *emulatorbin,
|
||||
if (!(domCaps = virDomainCapsNew(emulatorbin, machine, arch, type)))
|
||||
goto cleanup;
|
||||
|
||||
- if (fillFunc)
|
||||
- fillFunc(domCaps, opaque);
|
||||
+ if (fillFunc && fillFunc(domCaps, opaque) < 0) {
|
||||
+ virObjectUnref(domCaps);
|
||||
+ domCaps = NULL;
|
||||
+ }
|
||||
|
||||
cleanup:
|
||||
return domCaps;
|
444
0019-domaincaps-Expose-UEFI-binary-path-if-it-exists.patch
Normal file
444
0019-domaincaps-Expose-UEFI-binary-path-if-it-exists.patch
Normal file
@ -0,0 +1,444 @@
|
||||
From 64041dc7d34d7af3fd611d194bf2ab56729a13fa Mon Sep 17 00:00:00 2001
|
||||
From: Michal Privoznik <mprivozn@redhat.com>
|
||||
Date: Tue, 16 Sep 2014 19:52:54 -0400
|
||||
Subject: [PATCH] domaincaps: Expose UEFI binary path, if it exists
|
||||
|
||||
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.
|
||||
|
||||
Signed-off-by: Michal Privoznik <mprivozn@redhat.com>
|
||||
(cherry picked from commit f05b6a918e283929f5d837cd1668cdcdb3834b9a)
|
||||
---
|
||||
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 | 32 +++++++++++---
|
||||
src/qemu/qemu_capabilities.h | 7 +++-
|
||||
src/qemu/qemu_driver.c | 6 ++-
|
||||
tests/domaincapsschemadata/domaincaps-full.xml | 2 +
|
||||
.../domaincaps-qemu_1.6.50-1.xml | 1 +
|
||||
tests/domaincapstest.c | 49 +++++++++++++++++++---
|
||||
10 files changed, 140 insertions(+), 17 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..f4a555f 100644
|
||||
--- a/docs/schemas/domaincaps.rng
|
||||
+++ b/docs/schemas/domaincaps.rng
|
||||
@@ -47,6 +47,9 @@
|
||||
<define name='loader'>
|
||||
<element name='loader'>
|
||||
<ref name='supported'/>
|
||||
+ <optional>
|
||||
+ <ref name='value'/>
|
||||
+ </optional>
|
||||
<ref name='enum'/>
|
||||
</element>
|
||||
</define>
|
||||
@@ -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..7c59912 100644
|
||||
--- a/src/conf/domain_capabilities.c
|
||||
+++ b/src/conf/domain_capabilities.c
|
||||
@@ -48,12 +48,28 @@ VIR_ONCE_GLOBAL_INIT(virDomainCaps)
|
||||
|
||||
|
||||
static void
|
||||
+virDomainCapsStringValuesFree(virDomainCapsStringValuesPtr values)
|
||||
+{
|
||||
+ size_t i;
|
||||
+
|
||||
+ if (!values || !values->values)
|
||||
+ return;
|
||||
+
|
||||
+ for (i = 0; i < values->nvalues; i++)
|
||||
+ VIR_FREE(values->values[i]);
|
||||
+ VIR_FREE(values->values);
|
||||
+}
|
||||
+
|
||||
+
|
||||
+static void
|
||||
virDomainCapsDispose(void *obj)
|
||||
{
|
||||
virDomainCapsPtr caps = obj;
|
||||
|
||||
VIR_FREE(caps->path);
|
||||
VIR_FREE(caps->machine);
|
||||
+
|
||||
+ virDomainCapsStringValuesFree(&caps->os.loader.values);
|
||||
}
|
||||
|
||||
|
||||
@@ -156,6 +172,18 @@ virDomainCapsEnumFormat(virBufferPtr buf,
|
||||
return ret;
|
||||
}
|
||||
|
||||
+
|
||||
+static void
|
||||
+virDomainCapsStringValuesFormat(virBufferPtr buf,
|
||||
+ virDomainCapsStringValuesPtr values)
|
||||
+{
|
||||
+ size_t i;
|
||||
+
|
||||
+ for (i = 0; i < values->nvalues; i++)
|
||||
+ virBufferEscapeString(buf, "<value>%s</value>\n", values->values[i]);
|
||||
+}
|
||||
+
|
||||
+
|
||||
#define FORMAT_PROLOGUE(item) \
|
||||
do { \
|
||||
virBufferAsprintf(buf, "<" #item " supported='%s'%s\n", \
|
||||
@@ -185,6 +213,7 @@ virDomainCapsLoaderFormat(virBufferPtr buf,
|
||||
{
|
||||
FORMAT_PROLOGUE(loader);
|
||||
|
||||
+ virDomainCapsStringValuesFormat(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..597ac75 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 _virDomainCapsStringValues virDomainCapsStringValues;
|
||||
+typedef virDomainCapsStringValues *virDomainCapsStringValuesPtr;
|
||||
+struct _virDomainCapsStringValues {
|
||||
+ 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;
|
||||
+ virDomainCapsStringValues values; /* Info about values for the element */
|
||||
virDomainCapsEnum type; /* Info about virDomainLoader */
|
||||
virDomainCapsEnum readonly; /* Info about readonly:virTristateBool */
|
||||
};
|
||||
diff --git a/src/qemu/qemu_capabilities.c b/src/qemu/qemu_capabilities.c
|
||||
index d2e5f47..651bacd 100644
|
||||
--- a/src/qemu/qemu_capabilities.c
|
||||
+++ b/src/qemu/qemu_capabilities.c
|
||||
@@ -3611,10 +3611,30 @@ virQEMUCapsGetDefaultMachine(virQEMUCapsPtr qemuCaps)
|
||||
static int
|
||||
virQEMUCapsFillDomainLoaderCaps(virQEMUCapsPtr qemuCaps,
|
||||
virDomainCapsLoaderPtr loader,
|
||||
- virArch arch)
|
||||
+ virArch arch,
|
||||
+ virQEMUDriverConfigPtr cfg)
|
||||
{
|
||||
+ size_t i;
|
||||
+
|
||||
loader->device.supported = true;
|
||||
|
||||
+ if (VIR_ALLOC_N(loader->values.values, cfg->nloader) < 0)
|
||||
+ return -1;
|
||||
+
|
||||
+ for (i = 0; i < cfg->nloader; i++) {
|
||||
+ const char *filename = cfg->loader[i];
|
||||
+
|
||||
+ if (!virFileExists(filename)) {
|
||||
+ VIR_DEBUG("loader filename=%s does not exist", filename);
|
||||
+ continue;
|
||||
+ }
|
||||
+
|
||||
+ if (VIR_STRDUP(loader->values.values[loader->values.nvalues],
|
||||
+ filename) < 0)
|
||||
+ return -1;
|
||||
+ loader->values.nvalues++;
|
||||
+ }
|
||||
+
|
||||
VIR_DOMAIN_CAPS_ENUM_SET(loader->type,
|
||||
VIR_DOMAIN_LOADER_TYPE_ROM);
|
||||
|
||||
@@ -3636,12 +3656,13 @@ virQEMUCapsFillDomainLoaderCaps(virQEMUCapsPtr qemuCaps,
|
||||
static int
|
||||
virQEMUCapsFillDomainOSCaps(virQEMUCapsPtr qemuCaps,
|
||||
virDomainCapsOSPtr os,
|
||||
- virArch arch)
|
||||
+ virArch arch,
|
||||
+ virQEMUDriverConfigPtr cfg)
|
||||
{
|
||||
virDomainCapsLoaderPtr loader = &os->loader;
|
||||
|
||||
os->device.supported = true;
|
||||
- if (virQEMUCapsFillDomainLoaderCaps(qemuCaps, loader, arch) < 0)
|
||||
+ if (virQEMUCapsFillDomainLoaderCaps(qemuCaps, loader, arch, cfg) < 0)
|
||||
return -1;
|
||||
return 0;
|
||||
}
|
||||
@@ -3725,7 +3746,8 @@ virQEMUCapsFillDomainDeviceHostdevCaps(virQEMUCapsPtr qemuCaps,
|
||||
|
||||
int
|
||||
virQEMUCapsFillDomainCaps(virDomainCapsPtr domCaps,
|
||||
- virQEMUCapsPtr qemuCaps)
|
||||
+ virQEMUCapsPtr qemuCaps,
|
||||
+ virQEMUDriverConfigPtr cfg)
|
||||
{
|
||||
virDomainCapsOSPtr os = &domCaps->os;
|
||||
virDomainCapsDeviceDiskPtr disk = &domCaps->disk;
|
||||
@@ -3734,7 +3756,7 @@ virQEMUCapsFillDomainCaps(virDomainCapsPtr domCaps,
|
||||
|
||||
domCaps->maxvcpus = maxvcpus;
|
||||
|
||||
- if (virQEMUCapsFillDomainOSCaps(qemuCaps, os, domCaps->arch) < 0 ||
|
||||
+ if (virQEMUCapsFillDomainOSCaps(qemuCaps, os, domCaps->arch, cfg) < 0 ||
|
||||
virQEMUCapsFillDomainDeviceDiskCaps(qemuCaps, disk) < 0 ||
|
||||
virQEMUCapsFillDomainDeviceHostdevCaps(qemuCaps, hostdev) < 0)
|
||||
return -1;
|
||||
diff --git a/src/qemu/qemu_capabilities.h b/src/qemu/qemu_capabilities.h
|
||||
index 828bba3..cf69e59 100644
|
||||
--- a/src/qemu/qemu_capabilities.h
|
||||
+++ b/src/qemu/qemu_capabilities.h
|
||||
@@ -324,7 +324,12 @@ int virQEMUCapsInitGuestFromBinary(virCapsPtr caps,
|
||||
virQEMUCapsPtr kvmbinCaps,
|
||||
virArch guestarch);
|
||||
|
||||
+/* Forward declaration */
|
||||
+typedef struct _virQEMUDriverConfig virQEMUDriverConfig;
|
||||
+typedef virQEMUDriverConfig *virQEMUDriverConfigPtr;
|
||||
+
|
||||
int virQEMUCapsFillDomainCaps(virDomainCapsPtr domCaps,
|
||||
- virQEMUCapsPtr qemuCaps);
|
||||
+ virQEMUCapsPtr qemuCaps,
|
||||
+ virQEMUDriverConfigPtr cfg);
|
||||
|
||||
#endif /* __QEMU_CAPABILITIES_H__*/
|
||||
diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c
|
||||
index 9c1644c..0d895c6 100644
|
||||
--- a/src/qemu/qemu_driver.c
|
||||
+++ b/src/qemu/qemu_driver.c
|
||||
@@ -17133,12 +17133,15 @@ qemuConnectGetDomainCapabilities(virConnectPtr conn,
|
||||
int virttype; /* virDomainVirtType */
|
||||
virDomainCapsPtr domCaps = NULL;
|
||||
int arch = virArchFromHost(); /* virArch */
|
||||
+ virQEMUDriverConfigPtr cfg = NULL;
|
||||
|
||||
virCheckFlags(0, ret);
|
||||
|
||||
if (virConnectGetDomainCapabilitiesEnsureACL(conn) < 0)
|
||||
return ret;
|
||||
|
||||
+ cfg = virQEMUDriverGetConfig(driver);
|
||||
+
|
||||
if (qemuHostdevHostSupportsPassthroughLegacy())
|
||||
virttype = VIR_DOMAIN_VIRT_KVM;
|
||||
else
|
||||
@@ -17205,11 +17208,12 @@ qemuConnectGetDomainCapabilities(virConnectPtr conn,
|
||||
if (!(domCaps = virDomainCapsNew(emulatorbin, machine, arch, virttype)))
|
||||
goto cleanup;
|
||||
|
||||
- if (virQEMUCapsFillDomainCaps(domCaps, qemuCaps) < 0)
|
||||
+ if (virQEMUCapsFillDomainCaps(domCaps, qemuCaps, cfg) < 0)
|
||||
goto cleanup;
|
||||
|
||||
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..96202bc 100644
|
||||
--- a/tests/domaincapsschemadata/domaincaps-full.xml
|
||||
+++ b/tests/domaincapsschemadata/domaincaps-full.xml
|
||||
@@ -6,6 +6,8 @@
|
||||
<vcpu max='255'/>
|
||||
<os supported='yes'>
|
||||
<loader supported='yes'>
|
||||
+ <value>/foo/bar</value>
|
||||
+ <value>/tmp/my_path</value>
|
||||
<enum name='type'>
|
||||
<value>rom</value>
|
||||
<value>pflash</value>
|
||||
diff --git a/tests/domaincapsschemadata/domaincaps-qemu_1.6.50-1.xml b/tests/domaincapsschemadata/domaincaps-qemu_1.6.50-1.xml
|
||||
index 568cecb..346ef65 100644
|
||||
--- a/tests/domaincapsschemadata/domaincaps-qemu_1.6.50-1.xml
|
||||
+++ b/tests/domaincapsschemadata/domaincaps-qemu_1.6.50-1.xml
|
||||
@@ -5,6 +5,7 @@
|
||||
<arch>x86_64</arch>
|
||||
<os supported='yes'>
|
||||
<loader supported='yes'>
|
||||
+ <value>/usr/share/OVMF/OVMF_CODE.fd</value>
|
||||
<enum name='type'>
|
||||
<value>rom</value>
|
||||
<value>pflash</value>
|
||||
diff --git a/tests/domaincapstest.c b/tests/domaincapstest.c
|
||||
index 0c4b09f..8543963 100644
|
||||
--- a/tests/domaincapstest.c
|
||||
+++ b/tests/domaincapstest.c
|
||||
@@ -34,6 +34,27 @@ typedef int (*virDomainCapsFill)(virDomainCapsPtr domCaps,
|
||||
#define SET_ALL_BITS(x) \
|
||||
memset(&(x.values), 0xff, sizeof(x.values))
|
||||
|
||||
+static int ATTRIBUTE_SENTINEL
|
||||
+fillStringValues(virDomainCapsStringValuesPtr values, ...)
|
||||
+{
|
||||
+ int ret = 0;
|
||||
+ va_list list;
|
||||
+ const char *str;
|
||||
+
|
||||
+ va_start(list, values);
|
||||
+ while ((str = va_arg(list, const char *))) {
|
||||
+ if (VIR_REALLOC_N(values->values, values->nvalues + 1) < 0 ||
|
||||
+ VIR_STRDUP(values->values[values->nvalues], str) < 0) {
|
||||
+ ret = -1;
|
||||
+ break;
|
||||
+ }
|
||||
+ values->nvalues++;
|
||||
+ }
|
||||
+ va_end(list);
|
||||
+
|
||||
+ return ret;
|
||||
+}
|
||||
+
|
||||
static int
|
||||
fillAll(virDomainCapsPtr domCaps,
|
||||
void *opaque ATTRIBUTE_UNUSED)
|
||||
@@ -49,6 +70,11 @@ fillAll(virDomainCapsPtr domCaps,
|
||||
loader->device.supported = true;
|
||||
SET_ALL_BITS(loader->type);
|
||||
SET_ALL_BITS(loader->readonly);
|
||||
+ if (fillStringValues(&loader->values,
|
||||
+ "/foo/bar",
|
||||
+ "/tmp/my_path",
|
||||
+ NULL) < 0)
|
||||
+ return -1;
|
||||
|
||||
disk->device.supported = true;
|
||||
SET_ALL_BITS(disk->diskDevice);
|
||||
@@ -66,13 +92,21 @@ fillAll(virDomainCapsPtr domCaps,
|
||||
|
||||
#ifdef WITH_QEMU
|
||||
# include "testutilsqemu.h"
|
||||
+
|
||||
+struct fillQemuCapsData {
|
||||
+ virQEMUCapsPtr qemuCaps;
|
||||
+ virQEMUDriverConfigPtr cfg;
|
||||
+};
|
||||
+
|
||||
static int
|
||||
fillQemuCaps(virDomainCapsPtr domCaps,
|
||||
void *opaque)
|
||||
{
|
||||
- virQEMUCapsPtr qemuCaps = (virQEMUCapsPtr) opaque;
|
||||
+ struct fillQemuCapsData *data = (struct fillQemuCapsData *) opaque;
|
||||
+ virQEMUCapsPtr qemuCaps = data->qemuCaps;
|
||||
+ virQEMUDriverConfigPtr cfg = data->cfg;
|
||||
|
||||
- if (virQEMUCapsFillDomainCaps(domCaps, qemuCaps) < 0)
|
||||
+ if (virQEMUCapsFillDomainCaps(domCaps, qemuCaps, cfg) < 0)
|
||||
return -1;
|
||||
|
||||
/* The function above tries to query host's KVM & VFIO capabilities by
|
||||
@@ -97,7 +131,7 @@ buildVirDomainCaps(const char *emulatorbin,
|
||||
virDomainCapsFill fillFunc,
|
||||
void *opaque)
|
||||
{
|
||||
- virDomainCapsPtr domCaps;
|
||||
+ virDomainCapsPtr domCaps, ret = NULL;
|
||||
|
||||
if (!(domCaps = virDomainCapsNew(emulatorbin, machine, arch, type)))
|
||||
goto cleanup;
|
||||
@@ -107,8 +141,9 @@ buildVirDomainCaps(const char *emulatorbin,
|
||||
domCaps = NULL;
|
||||
}
|
||||
|
||||
+ ret = domCaps;
|
||||
cleanup:
|
||||
- return domCaps;
|
||||
+ return ret;
|
||||
}
|
||||
|
||||
struct test_virDomainCapsFormatData {
|
||||
@@ -182,13 +217,16 @@ mymain(void)
|
||||
|
||||
#ifdef WITH_QEMU
|
||||
|
||||
+ virQEMUDriverConfigPtr cfg = virQEMUDriverConfigNew(false);
|
||||
+
|
||||
# define DO_TEST_QEMU(Filename, QemuCapsFile, Emulatorbin, Machine, Arch, Type, ...) \
|
||||
do { \
|
||||
const char *capsPath = abs_srcdir "/qemucapabilitiesdata/" QemuCapsFile ".caps"; \
|
||||
virQEMUCapsPtr qemuCaps = qemuTestParseCapabilities(capsPath); \
|
||||
+ struct fillQemuCapsData fillData = {.qemuCaps = qemuCaps, .cfg = cfg}; \
|
||||
struct test_virDomainCapsFormatData data = {.filename = Filename, \
|
||||
.emulatorbin = Emulatorbin, .machine = Machine, .arch = Arch, \
|
||||
- .type = Type, .fillFunc = fillQemuCaps, .opaque = qemuCaps}; \
|
||||
+ .type = Type, .fillFunc = fillQemuCaps, .opaque = &fillData}; \
|
||||
if (!qemuCaps) { \
|
||||
fprintf(stderr, "Unable to build qemu caps from %s\n", capsPath); \
|
||||
ret = -1; \
|
||||
@@ -199,6 +237,7 @@ mymain(void)
|
||||
DO_TEST_QEMU("qemu_1.6.50-1", "caps_1.6.50-1", "/usr/bin/qemu-system-x86_64",
|
||||
"pc-1.2", VIR_ARCH_X86_64, VIR_DOMAIN_VIRT_KVM);
|
||||
|
||||
+ virObjectUnref(cfg);
|
||||
#endif /* WITH_QEMU */
|
||||
|
||||
return ret;
|
@ -0,0 +1,40 @@
|
||||
From 6fcd1ae861279589172783c4937367685469f265 Mon Sep 17 00:00:00 2001
|
||||
From: Michal Privoznik <mprivozn@redhat.com>
|
||||
Date: Wed, 17 Sep 2014 17:17:03 +0200
|
||||
Subject: [PATCH] domaincapstest: Run cleanly on systems missing OVMF firmware
|
||||
|
||||
As of f05b6a918e28 the test produces the list of paths that can
|
||||
be passed to <loader/> and libvirt knows about them. However,
|
||||
during the process of generating the list the paths are checked
|
||||
for their presence. This may produce different results on
|
||||
different systems. Therefore, the path - if missing - is
|
||||
added to pretend it's there.
|
||||
|
||||
Signed-off-by: Michal Privoznik <mprivozn@redhat.com>
|
||||
(cherry picked from commit b3f42da6b77644107bcbaf720d7ed9cef5c798a2)
|
||||
---
|
||||
tests/domaincapstest.c | 11 +++++++++++
|
||||
1 file changed, 11 insertions(+)
|
||||
|
||||
diff --git a/tests/domaincapstest.c b/tests/domaincapstest.c
|
||||
index 8543963..067ad4d 100644
|
||||
--- a/tests/domaincapstest.c
|
||||
+++ b/tests/domaincapstest.c
|
||||
@@ -118,6 +118,17 @@ fillQemuCaps(virDomainCapsPtr domCaps,
|
||||
VIR_DOMAIN_HOSTDEV_PCI_BACKEND_DEFAULT,
|
||||
VIR_DOMAIN_HOSTDEV_PCI_BACKEND_KVM,
|
||||
VIR_DOMAIN_HOSTDEV_PCI_BACKEND_VFIO);
|
||||
+
|
||||
+ /* Moreover, as of f05b6a918e28 we are expecting to see
|
||||
+ * OVMF_CODE.fd file which may not exists everywhere. */
|
||||
+ if (!domCaps->os.loader.values.nvalues) {
|
||||
+ virDomainCapsLoaderPtr loader = &domCaps->os.loader;
|
||||
+
|
||||
+ if (fillStringValues(&loader->values,
|
||||
+ "/usr/share/OVMF/OVMF_CODE.fd",
|
||||
+ NULL) < 0)
|
||||
+ return -1;
|
||||
+ }
|
||||
return 0;
|
||||
}
|
||||
#endif /* WITH_QEMU */
|
36
libvirt.spec
36
libvirt.spec
@ -366,7 +366,7 @@
|
||||
Summary: Library providing a simple virtualization API
|
||||
Name: libvirt
|
||||
Version: 1.2.8
|
||||
Release: 3%{?dist}%{?extra_release}
|
||||
Release: 4%{?dist}%{?extra_release}
|
||||
License: LGPLv2+
|
||||
Group: Development/Libraries
|
||||
BuildRoot: %{_tmppath}/%{name}-%{version}-%{release}-root
|
||||
@ -382,7 +382,6 @@ Source: http://libvirt.org/sources/%{?mainturl}libvirt-%{version}.tar.gz
|
||||
Patch0001: 0001-network-try-to-eliminate-default-network-conflict-du.patch
|
||||
Patch0002: 0002-network-detect-conflicting-route-even-if-it-is-the-f.patch
|
||||
# Fix directory creation at session daemon startup (bz #1139672)
|
||||
# (Patch 5 is posted but not in git as of 2014-09-15)
|
||||
Patch0003: 0003-rpc-reformat-the-flow-to-make-a-bit-more-sense.patch
|
||||
Patch0004: 0004-remove-redundant-pidfile-path-constructions.patch
|
||||
Patch0005: 0005-util-fix-potential-leak-in-error-codepath.patch
|
||||
@ -393,6 +392,19 @@ Patch0007: 0007-rpc-make-daemon-spawning-a-bit-more-intelligent.patch
|
||||
Patch0008: 0008-spec-Don-t-build-wireshark-on-f21-non-upstream.patch
|
||||
# Fix preun script (bz #1142367)
|
||||
Patch0009: 0009-spec-Fix-preun-script-for-daemon.patch
|
||||
# Don't mess up labelling of /dev/net/tun (bz #1141879)
|
||||
Patch0010: 0010-virSecuritySELinuxSetTapFDLabel-Temporarily-revert-t.patch
|
||||
# pflash/nvram support for UEFI/OVMF
|
||||
Patch0011: 0011-conf-Extend-loader-and-introduce-nvram.patch
|
||||
Patch0012: 0012-qemu-Implement-extended-loader-and-nvram.patch
|
||||
Patch0013: 0013-qemu-Automatically-create-NVRAM-store.patch
|
||||
Patch0014: 0014-nvram-Fix-permissions.patch
|
||||
Patch0015: 0015-virDomainUndefineFlags-Allow-NVRAM-unlinking.patch
|
||||
Patch0016: 0016-formatdomain-Update-loader-example-to-match-the-rest.patch
|
||||
Patch0017: 0017-domaincaps-Expose-UEFI-capability.patch
|
||||
Patch0018: 0018-qemu_capabilities-Change-virQEMUCapsFillDomainCaps-s.patch
|
||||
Patch0019: 0019-domaincaps-Expose-UEFI-binary-path-if-it-exists.patch
|
||||
Patch0020: 0020-domaincapstest-Run-cleanly-on-systems-missing-OVMF-f.patch
|
||||
|
||||
%if %{with_libvirtd}
|
||||
Requires: libvirt-daemon = %{version}-%{release}
|
||||
@ -1223,7 +1235,6 @@ driver
|
||||
%patch0001 -p1
|
||||
%patch0002 -p1
|
||||
# Fix directory creation at session daemon startup (bz #1139672)
|
||||
# (Patch 5 is posted but not in git as of 2014-09-15)
|
||||
%patch0003 -p1
|
||||
%patch0004 -p1
|
||||
%patch0005 -p1
|
||||
@ -1234,6 +1245,19 @@ driver
|
||||
%patch0008 -p1
|
||||
# Fix preun script (bz #1142367)
|
||||
%patch0009 -p1
|
||||
# Don't mess up labelling of /dev/net/tun (bz #1141879)
|
||||
%patch0010 -p1
|
||||
# pflash/nvram support for UEFI/OVMF
|
||||
%patch0011 -p1
|
||||
%patch0012 -p1
|
||||
%patch0013 -p1
|
||||
%patch0014 -p1
|
||||
%patch0015 -p1
|
||||
%patch0016 -p1
|
||||
%patch0017 -p1
|
||||
%patch0018 -p1
|
||||
%patch0019 -p1
|
||||
%patch0020 -p1
|
||||
|
||||
%build
|
||||
%if ! %{with_xen}
|
||||
@ -2004,6 +2028,7 @@ exit 0
|
||||
%dir %attr(0750, %{qemu_user}, %{qemu_group}) %{_localstatedir}/lib/libvirt/qemu/
|
||||
%dir %attr(0750, %{qemu_user}, %{qemu_group}) %{_localstatedir}/lib/libvirt/qemu/channel/
|
||||
%dir %attr(0750, %{qemu_user}, %{qemu_group}) %{_localstatedir}/lib/libvirt/qemu/channel/target/
|
||||
%dir %attr(0711, %{qemu_user}, %{qemu_group}) %{_localstatedir}/lib/libvirt/qemu/nvram/
|
||||
%dir %attr(0750, %{qemu_user}, %{qemu_group}) %{_localstatedir}/cache/libvirt/qemu/
|
||||
%{_datadir}/augeas/lenses/libvirtd_qemu.aug
|
||||
%{_datadir}/augeas/lenses/tests/test_libvirtd_qemu.aug
|
||||
@ -2106,6 +2131,7 @@ exit 0
|
||||
%dir %attr(0750, %{qemu_user}, %{qemu_group}) %{_localstatedir}/lib/libvirt/qemu/
|
||||
%dir %attr(0750, %{qemu_user}, %{qemu_group}) %{_localstatedir}/lib/libvirt/qemu/channel/
|
||||
%dir %attr(0750, %{qemu_user}, %{qemu_group}) %{_localstatedir}/lib/libvirt/qemu/channel/target/
|
||||
%dir %attr(0750, %{qemu_user}, %{qemu_group}) %{_localstatedir}/lib/libvirt/qemu/nvram/
|
||||
%dir %attr(0750, %{qemu_user}, %{qemu_group}) %{_localstatedir}/cache/libvirt/qemu/
|
||||
%{_datadir}/augeas/lenses/libvirtd_qemu.aug
|
||||
%{_datadir}/augeas/lenses/tests/test_libvirtd_qemu.aug
|
||||
@ -2309,6 +2335,10 @@ exit 0
|
||||
%doc examples/systemtap
|
||||
|
||||
%changelog
|
||||
* Thu Sep 18 2014 Cole Robinson <crobinso@redhat.com> - 1.2.8-4
|
||||
- Don't mess up labelling of /dev/net/tun (bz #1141879)
|
||||
- pflash/nvram support for UEFI/OVMF
|
||||
|
||||
* Wed Sep 17 2014 Cole Robinson <crobinso@redhat.com> - 1.2.8-3
|
||||
- Fix preun script (bz #1142367)
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user