[libvirt] [PATCH] qemuDomainFSFreeze: report unless the agent supports mountpoints param
by Tomoki Sekiyama
This patch gives users a nicer error message when the QEMU guest agent is
not new enough to support 'guest-fsfreeze-freeze-list' command, which is
used by qemuDomainFSFreeze() to freeze specified filesystems only.
Before this patch, it was depending on the agent to complain about unknown
command:
# virsh domfsfreeze domain --mountpoint /mnt/point
error: Unable to freeze filesystems
error: internal error: unable to execute QEMU agent command 'guest-
fsfreeze-freeze-list': The command guest-fsfreeze-freeze-list has not been
found
After:
# virsh domfsfreeze domain --mountpoint /mnt/point
error: Unable to freeze filesystems
error: argument unsupported: this version of guest agent doesn't support
specifying mountpoints
Signed-off-by: Tomoki Sekiyama <tomoki.sekiyama(a)hds.com>
---
src/qemu/qemu_agent.c | 79 ++++++++++++++++++++++++++++++++++++++++++++++++-
1 file changed, 78 insertions(+), 1 deletion(-)
diff --git a/src/qemu/qemu_agent.c b/src/qemu/qemu_agent.c
index a10954a..8102b36 100644
--- a/src/qemu/qemu_agent.c
+++ b/src/qemu/qemu_agent.c
@@ -1279,6 +1279,75 @@ void qemuAgentNotifyEvent(qemuAgentPtr mon,
}
}
+static int qemuAgentCommandSupported(qemuAgentPtr mon,
+ const char *cmdname)
+{
+ int ret = -1;
+ size_t i;
+ int ndata;
+ virJSONValuePtr cmd;
+ virJSONValuePtr data;
+ virJSONValuePtr reply = NULL;
+
+ cmd = qemuAgentMakeCommand("guest-info", NULL);
+ if (!cmd)
+ return -1;
+
+ if (qemuAgentCommand(mon, cmd, &reply, false,
+ VIR_DOMAIN_QEMU_AGENT_COMMAND_BLOCK) < 0)
+ goto cleanup;
+
+ if (!(data = virJSONValueObjectGet(reply, "return"))) {
+ virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
+ _("guest-info reply was missing return data"));
+ goto cleanup;
+ }
+
+ if (!(data = virJSONValueObjectGet(data, "supported_commands"))) {
+ virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
+ _("guest-info reply was missing supported_commands"));
+ goto cleanup;
+ }
+
+ if (data->type != VIR_JSON_TYPE_ARRAY) {
+ virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
+ _("guest-info supported_commands was not an array"));
+ goto cleanup;
+ }
+
+ ndata = virJSONValueArraySize(data);
+
+ for (i = 0; i < ndata; i++) {
+ virJSONValuePtr entry = virJSONValueArrayGet(data, i);
+ const char *name;
+
+ if (!entry) {
+ virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
+ _("array element missing in guest-info "
+ "supported_commands"));
+ goto cleanup;
+ }
+
+ if (!(name = virJSONValueObjectGetString(entry, "name"))) {
+ virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
+ _("guest-info supported_commands was missing name"));
+ goto cleanup;
+ }
+
+ if (strcmp(name, cmdname) == 0) {
+ ret = 1;
+ goto cleanup;
+ }
+ }
+
+ ret = 0;
+
+ cleanup:
+ virJSONValueFree(cmd);
+ virJSONValueFree(reply);
+ return ret;
+}
+
VIR_ENUM_DECL(qemuAgentShutdownMode);
VIR_ENUM_IMPL(qemuAgentShutdownMode,
@@ -1346,8 +1415,16 @@ int qemuAgentFSFreeze(qemuAgentPtr mon, const char **mountpoints,
return -1;
if (qemuAgentCommand(mon, cmd, &reply, true,
- VIR_DOMAIN_QEMU_AGENT_COMMAND_BLOCK) < 0)
+ VIR_DOMAIN_QEMU_AGENT_COMMAND_BLOCK) < 0) {
+ if (mountpoints && nmountpoints) {
+ if (qemuAgentCommandSupported(mon,
+ "guest-fsfreeze-freeze-list") == 0)
+ virReportError(VIR_ERR_ARGUMENT_UNSUPPORTED, "%s",
+ _("this version of guest agent doesn't support "
+ "specifying mountpoints"));
+ }
goto cleanup;
+ }
if (virJSONValueObjectGetNumberInt(reply, "return", &ret) < 0) {
virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
10 years, 3 months
[libvirt] [PATCH v2 0/3] OVMF exposure
by Michal Privoznik
diff to v1:
- adapt to new code
- restrict usage to x86_64 qemu guests
- Adapted to Laszlo's suggestion for qemu.conf format
Michal Privoznik (3):
conf: Extend <loader/> and introduce <nvram/>
qemu: Implement extended loader and nvram
qemu: Automatically create NVRAM store
configure.ac | 1 -
docs/formatdomain.html.in | 19 ++-
docs/schemas/domaincommon.rng | 21 ++++
libvirt.spec.in | 2 +
src/Makefile.am | 1 +
src/conf/domain_conf.c | 87 +++++++++++++-
src/conf/domain_conf.h | 22 +++-
src/libvirt_private.syms | 3 +
src/qemu/libvirtd_qemu.aug | 3 +
src/qemu/qemu.conf | 14 +++
src/qemu/qemu_command.c | 97 ++++++++++++++-
src/qemu/qemu_conf.c | 92 +++++++++++++++
src/qemu/qemu_conf.h | 5 +
src/qemu/qemu_process.c | 131 +++++++++++++++++++++
src/qemu/test_libvirtd_qemu.aug.in | 3 +
src/security/security_dac.c | 8 ++
src/security/security_selinux.c | 8 ++
src/security/virt-aa-helper.c | 4 +-
src/vbox/vbox_common.c | 7 +-
src/xenapi/xenapi_driver.c | 3 +-
src/xenxs/xen_sxpr.c | 16 +--
src/xenxs/xen_xm.c | 7 +-
.../qemuxml2argvdata/qemuxml2argv-bios-nvram.args | 10 ++
tests/qemuxml2argvdata/qemuxml2argv-bios-nvram.xml | 40 +++++++
tests/qemuxml2argvtest.c | 2 +
.../qemuxml2xmlout-pci-bridge-many-disks.xml | 2 +-
tests/qemuxml2xmltest.c | 2 +
tests/sexpr2xmldata/sexpr2xml-fv-autoport.xml | 2 +-
tests/sexpr2xmldata/sexpr2xml-fv-empty-kernel.xml | 2 +-
tests/sexpr2xmldata/sexpr2xml-fv-force-hpet.xml | 2 +-
tests/sexpr2xmldata/sexpr2xml-fv-force-nohpet.xml | 2 +-
tests/sexpr2xmldata/sexpr2xml-fv-kernel.xml | 2 +-
tests/sexpr2xmldata/sexpr2xml-fv-legacy-vfb.xml | 2 +-
tests/sexpr2xmldata/sexpr2xml-fv-localtime.xml | 2 +-
tests/sexpr2xmldata/sexpr2xml-fv-net-ioemu.xml | 2 +-
tests/sexpr2xmldata/sexpr2xml-fv-net-netfront.xml | 2 +-
tests/sexpr2xmldata/sexpr2xml-fv-parallel-tcp.xml | 2 +-
.../sexpr2xml-fv-serial-dev-2-ports.xml | 2 +-
.../sexpr2xml-fv-serial-dev-2nd-port.xml | 2 +-
tests/sexpr2xmldata/sexpr2xml-fv-serial-file.xml | 2 +-
tests/sexpr2xmldata/sexpr2xml-fv-serial-null.xml | 2 +-
tests/sexpr2xmldata/sexpr2xml-fv-serial-pipe.xml | 2 +-
tests/sexpr2xmldata/sexpr2xml-fv-serial-pty.xml | 2 +-
tests/sexpr2xmldata/sexpr2xml-fv-serial-stdio.xml | 2 +-
.../sexpr2xml-fv-serial-tcp-telnet.xml | 2 +-
tests/sexpr2xmldata/sexpr2xml-fv-serial-tcp.xml | 2 +-
tests/sexpr2xmldata/sexpr2xml-fv-serial-udp.xml | 2 +-
tests/sexpr2xmldata/sexpr2xml-fv-serial-unix.xml | 2 +-
tests/sexpr2xmldata/sexpr2xml-fv-sound-all.xml | 2 +-
tests/sexpr2xmldata/sexpr2xml-fv-sound.xml | 2 +-
tests/sexpr2xmldata/sexpr2xml-fv-usbmouse.xml | 2 +-
tests/sexpr2xmldata/sexpr2xml-fv-usbtablet.xml | 2 +-
tests/sexpr2xmldata/sexpr2xml-fv-utc.xml | 2 +-
tests/sexpr2xmldata/sexpr2xml-fv-v2.xml | 2 +-
tests/sexpr2xmldata/sexpr2xml-fv.xml | 2 +-
tests/sexpr2xmldata/sexpr2xml-no-source-cdrom.xml | 2 +-
tests/xmconfigdata/test-escape-paths.xml | 2 +-
tests/xmconfigdata/test-fullvirt-force-hpet.xml | 2 +-
tests/xmconfigdata/test-fullvirt-force-nohpet.xml | 2 +-
tests/xmconfigdata/test-fullvirt-localtime.xml | 2 +-
tests/xmconfigdata/test-fullvirt-net-ioemu.xml | 2 +-
tests/xmconfigdata/test-fullvirt-net-netfront.xml | 2 +-
tests/xmconfigdata/test-fullvirt-new-cdrom.xml | 2 +-
tests/xmconfigdata/test-fullvirt-old-cdrom.xml | 2 +-
tests/xmconfigdata/test-fullvirt-parallel-tcp.xml | 2 +-
.../test-fullvirt-serial-dev-2-ports.xml | 2 +-
.../test-fullvirt-serial-dev-2nd-port.xml | 2 +-
tests/xmconfigdata/test-fullvirt-serial-file.xml | 2 +-
tests/xmconfigdata/test-fullvirt-serial-null.xml | 2 +-
tests/xmconfigdata/test-fullvirt-serial-pipe.xml | 2 +-
tests/xmconfigdata/test-fullvirt-serial-pty.xml | 2 +-
tests/xmconfigdata/test-fullvirt-serial-stdio.xml | 2 +-
.../test-fullvirt-serial-tcp-telnet.xml | 2 +-
tests/xmconfigdata/test-fullvirt-serial-tcp.xml | 2 +-
tests/xmconfigdata/test-fullvirt-serial-udp.xml | 2 +-
tests/xmconfigdata/test-fullvirt-serial-unix.xml | 2 +-
tests/xmconfigdata/test-fullvirt-sound.xml | 2 +-
tests/xmconfigdata/test-fullvirt-usbmouse.xml | 2 +-
tests/xmconfigdata/test-fullvirt-usbtablet.xml | 2 +-
tests/xmconfigdata/test-fullvirt-utc.xml | 2 +-
tests/xmconfigdata/test-no-source-cdrom.xml | 2 +-
tests/xmconfigdata/test-pci-devs.xml | 2 +-
82 files changed, 637 insertions(+), 83 deletions(-)
create mode 100644 tests/qemuxml2argvdata/qemuxml2argv-bios-nvram.args
create mode 100644 tests/qemuxml2argvdata/qemuxml2argv-bios-nvram.xml
--
1.8.5.5
10 years, 3 months
[libvirt] Support for kvm=off cpu option
by Alex Williamson
As of QEMU 2.1 we now have a new -cpu option, kvm=on|off which controls
whether we expose KVM as the hypervisor via the MSR hypervisor nodes.
The default is on. The off state is meant to hide kvm from standard
detection routines. This allows us to disable paravirtualization
detection in the guest and can be used to bypass hypervisor checks in
certain guest drivers[1].
How would we like to enable this in libvirt? One option would be a
processor feature, ex:
<feature policy='disable' name='kvm'/>
But since this doesn't map to a cpuid feature, I don't know if that
would be acceptable.
Another option might be to a domain feature, similar to some of the
other hyper-v related flags.
<domain type='kvm'>
<features>
<kvm>
<kvm state='off'>
</kvm>
<hyperv>
<relaxed state='on'>
...
</hyperv>
</features>
...
</domain>
Any other suggestions? Preference? Thanks,
Alex
[1] http://lists.gnu.org/archive/html/qemu-devel/2014-06/msg00302.html
10 years, 3 months
[libvirt] Suboptimal default cpu Cgroup
by Radim Krčmář
Hello,
by default, libvirt with KVM creates a Cgroup hierarchy in 'cpu,cpuacct'
[1], with 'shares' set to 1024 on every level. This raises two points:
1) Every VM is given an equal amount of CPU time. [2]
($CG/machine.slice/*/shares = 1024)
Which means that smaller / less loaded guests are given an advantage.
2) All VMs combined are given 1024 shares. [3]
($CG/machine.slice/shares)
This is made even worse on RHEL7, by sched_autogroup_enabled = 0, so
every other process in the system is given the same amount of CPU as
all VMs combined.
It does not seem to be possible to tune shares and get a good general
behavior, so the best solution I can see is to disable the cpu cgroup
and let users do it when needed. (Keeping all tasks in $CG/tasks.)
Do we want cgroups in the default at all?
(Is OpenStack dealing with these quirks?)
Thanks.
---
1: machine.slice/
machine-qemu\\x2d${name}.scope/
{emulator,vcpu*}/
2: To reproduce, run two guests with > 1 VCPU and execute two spinners
on the first and one on the second.
The result will be 50%/50% CPU assignment between guests; 66%/33%
seems more natural, but it could still be considered as a feature.
3: Run a guest with $n VCPUs and $n spinners in it, and $n spinners in
the host
- RHEL7: 1/($n + 1)% CPU for the guest -- I'd expect 50%/50%.
- Upstream: 50%/50% between guest and host because of autogrouping;
if you run $n more spinners in the host, it will still be 50%/50%,
instead of seemingly more fair 33%/66%. (And you can run spinners
from different groups, so it would be the same as in RHEL7 then.)
And it also works the other way: if the host has $n CPUs, then
$n/2 tasks in the host suffice to minimize VMs' performance,
regardless of the amount of running VCPUs.
10 years, 3 months
[libvirt] [PATCH 1/2] conf: make disk source pool translation generic
by Roman Bogorodskiy
Currently, qemu driver uses qemuTranslateDiskSourcePool()
to translate disk volume information. This function is
general enough and could be used for other drivers as well,
so move it to conf/domain_conf.c along with its helpers.
- qemuTranslateDiskSourcePool: move to conf/domain_conf.c
and rename to virDomainTranslateDiskSourcePool,
- qemuAddISCSIPoolSourceHost: move to conf/domain_conf.c
and rename to virDomainAddISCSIPoolSourceHost,
- qemuTranslateDiskSourcePoolAuth: move to conf/domain_conf.c
and rename to virDomainTranslateDiskSourcePoolAuth,
- Expose virDomainTranslateDiskSourcePool through
libvirt_private.syms,
- Update users of virDomainTranslateDiskSourcePool to use a
new name.
---
src/conf/domain_conf.c | 245 +++++++++++++++++++++++++++++++++++++++++++++++
src/conf/domain_conf.h | 3 +
src/libvirt_private.syms | 1 +
src/qemu/qemu_conf.c | 243 ----------------------------------------------
src/qemu/qemu_conf.h | 3 -
src/qemu/qemu_driver.c | 6 +-
src/qemu/qemu_hotplug.c | 2 +-
src/qemu/qemu_process.c | 4 +-
tests/qemuxml2argvtest.c | 2 +-
9 files changed, 256 insertions(+), 253 deletions(-)
diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c
index 5c762fa..d5f80e0 100644
--- a/src/conf/domain_conf.c
+++ b/src/conf/domain_conf.c
@@ -20045,6 +20045,251 @@ virDomainDiskSourceIsBlockType(virDomainDiskDefPtr def)
}
+static int
+virDomainAddISCSIPoolSourceHost(virDomainDiskDefPtr def,
+ virStoragePoolDefPtr pooldef)
+{
+ int ret = -1;
+ char **tokens = NULL;
+
+ /* Only support one host */
+ if (pooldef->source.nhost != 1) {
+ virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
+ _("Expected exactly 1 host for the storage pool"));
+ goto cleanup;
+ }
+
+ /* iscsi pool only supports one host */
+ def->src->nhosts = 1;
+
+ if (VIR_ALLOC_N(def->src->hosts, def->src->nhosts) < 0)
+ goto cleanup;
+
+ if (VIR_STRDUP(def->src->hosts[0].name, pooldef->source.hosts[0].name) < 0)
+ goto cleanup;
+
+ if (virAsprintf(&def->src->hosts[0].port, "%d",
+ pooldef->source.hosts[0].port ?
+ pooldef->source.hosts[0].port :
+ 3260) < 0)
+ goto cleanup;
+
+ /* iscsi volume has name like "unit:0:0:1" */
+ if (!(tokens = virStringSplit(def->src->srcpool->volume, ":", 0)))
+ goto cleanup;
+
+ if (virStringListLength(tokens) != 4) {
+ virReportError(VIR_ERR_INTERNAL_ERROR,
+ _("unexpected iscsi volume name '%s'"),
+ def->src->srcpool->volume);
+ goto cleanup;
+ }
+
+ /* iscsi pool has only one source device path */
+ if (virAsprintf(&def->src->path, "%s/%s",
+ pooldef->source.devices[0].path,
+ tokens[3]) < 0)
+ goto cleanup;
+
+ /* Storage pool have not supported these 2 attributes yet,
+ * use the defaults.
+ */
+ def->src->hosts[0].transport = VIR_STORAGE_NET_HOST_TRANS_TCP;
+ def->src->hosts[0].socket = NULL;
+
+ def->src->protocol = VIR_STORAGE_NET_PROTOCOL_ISCSI;
+
+ ret = 0;
+
+ cleanup:
+ virStringFreeList(tokens);
+ return ret;
+}
+
+
+static int
+virDomainTranslateDiskSourcePoolAuth(virDomainDiskDefPtr def,
+ virStoragePoolSourcePtr source)
+{
+ int ret = -1;
+
+ /* Only necessary when authentication set */
+ if (!source->auth) {
+ ret = 0;
+ goto cleanup;
+ }
+ def->src->auth = virStorageAuthDefCopy(source->auth);
+ if (!def->src->auth)
+ goto cleanup;
+ ret = 0;
+
+ cleanup:
+ return ret;
+}
+
+
+int
+virDomainTranslateDiskSourcePool(virConnectPtr conn,
+ virDomainDiskDefPtr def)
+{
+ virStoragePoolDefPtr pooldef = NULL;
+ virStoragePoolPtr pool = NULL;
+ virStorageVolPtr vol = NULL;
+ char *poolxml = NULL;
+ virStorageVolInfo info;
+ int ret = -1;
+ virErrorPtr savedError = NULL;
+
+ if (def->src->type != VIR_STORAGE_TYPE_VOLUME)
+ return 0;
+
+ if (!def->src->srcpool)
+ return 0;
+
+ if (!(pool = virStoragePoolLookupByName(conn, def->src->srcpool->pool)))
+ return -1;
+
+ if (virStoragePoolIsActive(pool) != 1) {
+ virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
+ _("storage pool '%s' containing volume '%s' "
+ "is not active"),
+ def->src->srcpool->pool, def->src->srcpool->volume);
+ goto cleanup;
+ }
+
+ if (!(vol = virStorageVolLookupByName(pool, def->src->srcpool->volume)))
+ goto cleanup;
+
+ if (virStorageVolGetInfo(vol, &info) < 0)
+ goto cleanup;
+
+ if (!(poolxml = virStoragePoolGetXMLDesc(pool, 0)))
+ goto cleanup;
+
+ if (!(pooldef = virStoragePoolDefParseString(poolxml)))
+ goto cleanup;
+
+ def->src->srcpool->pooltype = pooldef->type;
+ def->src->srcpool->voltype = info.type;
+
+ if (def->src->srcpool->mode && pooldef->type != VIR_STORAGE_POOL_ISCSI) {
+ virReportError(VIR_ERR_XML_ERROR, "%s",
+ _("disk source mode is only valid when "
+ "storage pool is of iscsi type"));
+ goto cleanup;
+ }
+
+ VIR_FREE(def->src->path);
+ virStorageNetHostDefFree(def->src->nhosts, def->src->hosts);
+ virStorageAuthDefFree(def->src->auth);
+
+ switch ((virStoragePoolType) pooldef->type) {
+ case VIR_STORAGE_POOL_DIR:
+ case VIR_STORAGE_POOL_FS:
+ case VIR_STORAGE_POOL_NETFS:
+ case VIR_STORAGE_POOL_LOGICAL:
+ case VIR_STORAGE_POOL_DISK:
+ case VIR_STORAGE_POOL_SCSI:
+ case VIR_STORAGE_POOL_ZFS:
+ if (!(def->src->path = virStorageVolGetPath(vol)))
+ goto cleanup;
+
+ if (def->startupPolicy && info.type != VIR_STORAGE_VOL_FILE) {
+ virReportError(VIR_ERR_XML_ERROR, "%s",
+ _("'startupPolicy' is only valid for "
+ "'file' type volume"));
+ goto cleanup;
+ }
+
+
+ switch (info.type) {
+ case VIR_STORAGE_VOL_FILE:
+ def->src->srcpool->actualtype = VIR_STORAGE_TYPE_FILE;
+ break;
+
+ case VIR_STORAGE_VOL_DIR:
+ def->src->srcpool->actualtype = VIR_STORAGE_TYPE_DIR;
+ break;
+
+ case VIR_STORAGE_VOL_BLOCK:
+ def->src->srcpool->actualtype = VIR_STORAGE_TYPE_BLOCK;
+ break;
+
+ case VIR_STORAGE_VOL_NETWORK:
+ case VIR_STORAGE_VOL_NETDIR:
+ virReportError(VIR_ERR_INTERNAL_ERROR,
+ _("unexpected storage volume type '%s' "
+ "for storage pool type '%s'"),
+ virStorageVolTypeToString(info.type),
+ virStoragePoolTypeToString(pooldef->type));
+ goto cleanup;
+ }
+
+ break;
+
+ case VIR_STORAGE_POOL_ISCSI:
+ if (def->startupPolicy) {
+ virReportError(VIR_ERR_XML_ERROR, "%s",
+ _("'startupPolicy' is only valid for "
+ "'file' type volume"));
+ goto cleanup;
+ }
+
+ switch (def->src->srcpool->mode) {
+ case VIR_STORAGE_SOURCE_POOL_MODE_DEFAULT:
+ case VIR_STORAGE_SOURCE_POOL_MODE_LAST:
+ def->src->srcpool->mode = VIR_STORAGE_SOURCE_POOL_MODE_HOST;
+ /* fallthrough */
+ case VIR_STORAGE_SOURCE_POOL_MODE_HOST:
+ def->src->srcpool->actualtype = VIR_STORAGE_TYPE_BLOCK;
+ if (!(def->src->path = virStorageVolGetPath(vol)))
+ goto cleanup;
+ break;
+
+ case VIR_STORAGE_SOURCE_POOL_MODE_DIRECT:
+ def->src->srcpool->actualtype = VIR_STORAGE_TYPE_NETWORK;
+ def->src->protocol = VIR_STORAGE_NET_PROTOCOL_ISCSI;
+
+ if (virDomainTranslateDiskSourcePoolAuth(def, &pooldef->source) < 0)
+ goto cleanup;
+
+ if (virDomainAddISCSIPoolSourceHost(def, pooldef) < 0)
+ goto cleanup;
+ break;
+ }
+ break;
+
+ case VIR_STORAGE_POOL_MPATH:
+ case VIR_STORAGE_POOL_RBD:
+ case VIR_STORAGE_POOL_SHEEPDOG:
+ case VIR_STORAGE_POOL_GLUSTER:
+ case VIR_STORAGE_POOL_LAST:
+ virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
+ _("using '%s' pools for backing 'volume' disks "
+ "isn't yet supported"),
+ virStoragePoolTypeToString(pooldef->type));
+ goto cleanup;
+ }
+
+ ret = 0;
+ cleanup:
+ if (ret < 0)
+ savedError = virSaveLastError();
+ if (pool)
+ virStoragePoolFree(pool);
+ if (vol)
+ virStorageVolFree(vol);
+ if (savedError) {
+ virSetError(savedError);
+ virFreeError(savedError);
+ }
+
+ VIR_FREE(poolxml);
+ virStoragePoolDefFree(pooldef);
+ return ret;
+}
+
+
char *
virDomainObjGetMetadata(virDomainObjPtr vm,
int type,
diff --git a/src/conf/domain_conf.h b/src/conf/domain_conf.h
index ff7d640..d745072 100644
--- a/src/conf/domain_conf.h
+++ b/src/conf/domain_conf.h
@@ -2716,6 +2716,9 @@ int virDomainDefFindDevice(virDomainDefPtr def,
bool virDomainDiskSourceIsBlockType(virDomainDiskDefPtr def)
ATTRIBUTE_NONNULL(1);
+int virDomainTranslateDiskSourcePool(virConnectPtr conn,
+ virDomainDiskDefPtr def);
+
void virDomainChrSourceDefClear(virDomainChrSourceDefPtr def);
char *virDomainObjGetMetadata(virDomainObjPtr vm,
diff --git a/src/libvirt_private.syms b/src/libvirt_private.syms
index 08111d4..975c414 100644
--- a/src/libvirt_private.syms
+++ b/src/libvirt_private.syms
@@ -407,6 +407,7 @@ virDomainTPMBackendTypeToString;
virDomainTPMDefFree;
virDomainTPMModelTypeFromString;
virDomainTPMModelTypeToString;
+virDomainTranslateDiskSourcePool;
virDomainVcpuPinAdd;
virDomainVcpuPinDefArrayFree;
virDomainVcpuPinDefCopy;
diff --git a/src/qemu/qemu_conf.c b/src/qemu/qemu_conf.c
index 238d2b1..eef5be1 100644
--- a/src/qemu/qemu_conf.c
+++ b/src/qemu/qemu_conf.c
@@ -1225,249 +1225,6 @@ int qemuDriverAllocateID(virQEMUDriverPtr driver)
return virAtomicIntInc(&driver->nextvmid);
}
-static int
-qemuAddISCSIPoolSourceHost(virDomainDiskDefPtr def,
- virStoragePoolDefPtr pooldef)
-{
- int ret = -1;
- char **tokens = NULL;
-
- /* Only support one host */
- if (pooldef->source.nhost != 1) {
- virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
- _("Expected exactly 1 host for the storage pool"));
- goto cleanup;
- }
-
- /* iscsi pool only supports one host */
- def->src->nhosts = 1;
-
- if (VIR_ALLOC_N(def->src->hosts, def->src->nhosts) < 0)
- goto cleanup;
-
- if (VIR_STRDUP(def->src->hosts[0].name, pooldef->source.hosts[0].name) < 0)
- goto cleanup;
-
- if (virAsprintf(&def->src->hosts[0].port, "%d",
- pooldef->source.hosts[0].port ?
- pooldef->source.hosts[0].port :
- 3260) < 0)
- goto cleanup;
-
- /* iscsi volume has name like "unit:0:0:1" */
- if (!(tokens = virStringSplit(def->src->srcpool->volume, ":", 0)))
- goto cleanup;
-
- if (virStringListLength(tokens) != 4) {
- virReportError(VIR_ERR_INTERNAL_ERROR,
- _("unexpected iscsi volume name '%s'"),
- def->src->srcpool->volume);
- goto cleanup;
- }
-
- /* iscsi pool has only one source device path */
- if (virAsprintf(&def->src->path, "%s/%s",
- pooldef->source.devices[0].path,
- tokens[3]) < 0)
- goto cleanup;
-
- /* Storage pool have not supported these 2 attributes yet,
- * use the defaults.
- */
- def->src->hosts[0].transport = VIR_STORAGE_NET_HOST_TRANS_TCP;
- def->src->hosts[0].socket = NULL;
-
- def->src->protocol = VIR_STORAGE_NET_PROTOCOL_ISCSI;
-
- ret = 0;
-
- cleanup:
- virStringFreeList(tokens);
- return ret;
-}
-
-static int
-qemuTranslateDiskSourcePoolAuth(virDomainDiskDefPtr def,
- virStoragePoolSourcePtr source)
-{
- int ret = -1;
-
- /* Only necessary when authentication set */
- if (!source->auth) {
- ret = 0;
- goto cleanup;
- }
- def->src->auth = virStorageAuthDefCopy(source->auth);
- if (!def->src->auth)
- goto cleanup;
- ret = 0;
-
- cleanup:
- return ret;
-}
-
-
-int
-qemuTranslateDiskSourcePool(virConnectPtr conn,
- virDomainDiskDefPtr def)
-{
- virStoragePoolDefPtr pooldef = NULL;
- virStoragePoolPtr pool = NULL;
- virStorageVolPtr vol = NULL;
- char *poolxml = NULL;
- virStorageVolInfo info;
- int ret = -1;
- virErrorPtr savedError = NULL;
-
- if (def->src->type != VIR_STORAGE_TYPE_VOLUME)
- return 0;
-
- if (!def->src->srcpool)
- return 0;
-
- if (!(pool = virStoragePoolLookupByName(conn, def->src->srcpool->pool)))
- return -1;
-
- if (virStoragePoolIsActive(pool) != 1) {
- virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
- _("storage pool '%s' containing volume '%s' "
- "is not active"),
- def->src->srcpool->pool, def->src->srcpool->volume);
- goto cleanup;
- }
-
- if (!(vol = virStorageVolLookupByName(pool, def->src->srcpool->volume)))
- goto cleanup;
-
- if (virStorageVolGetInfo(vol, &info) < 0)
- goto cleanup;
-
- if (!(poolxml = virStoragePoolGetXMLDesc(pool, 0)))
- goto cleanup;
-
- if (!(pooldef = virStoragePoolDefParseString(poolxml)))
- goto cleanup;
-
- def->src->srcpool->pooltype = pooldef->type;
- def->src->srcpool->voltype = info.type;
-
- if (def->src->srcpool->mode && pooldef->type != VIR_STORAGE_POOL_ISCSI) {
- virReportError(VIR_ERR_XML_ERROR, "%s",
- _("disk source mode is only valid when "
- "storage pool is of iscsi type"));
- goto cleanup;
- }
-
- VIR_FREE(def->src->path);
- virStorageNetHostDefFree(def->src->nhosts, def->src->hosts);
- virStorageAuthDefFree(def->src->auth);
-
- switch ((virStoragePoolType) pooldef->type) {
- case VIR_STORAGE_POOL_DIR:
- case VIR_STORAGE_POOL_FS:
- case VIR_STORAGE_POOL_NETFS:
- case VIR_STORAGE_POOL_LOGICAL:
- case VIR_STORAGE_POOL_DISK:
- case VIR_STORAGE_POOL_SCSI:
- case VIR_STORAGE_POOL_ZFS:
- if (!(def->src->path = virStorageVolGetPath(vol)))
- goto cleanup;
-
- if (def->startupPolicy && info.type != VIR_STORAGE_VOL_FILE) {
- virReportError(VIR_ERR_XML_ERROR, "%s",
- _("'startupPolicy' is only valid for "
- "'file' type volume"));
- goto cleanup;
- }
-
-
- switch (info.type) {
- case VIR_STORAGE_VOL_FILE:
- def->src->srcpool->actualtype = VIR_STORAGE_TYPE_FILE;
- break;
-
- case VIR_STORAGE_VOL_DIR:
- def->src->srcpool->actualtype = VIR_STORAGE_TYPE_DIR;
- break;
-
- case VIR_STORAGE_VOL_BLOCK:
- def->src->srcpool->actualtype = VIR_STORAGE_TYPE_BLOCK;
- break;
-
- case VIR_STORAGE_VOL_NETWORK:
- case VIR_STORAGE_VOL_NETDIR:
- virReportError(VIR_ERR_INTERNAL_ERROR,
- _("unexpected storage volume type '%s' "
- "for storage pool type '%s'"),
- virStorageVolTypeToString(info.type),
- virStoragePoolTypeToString(pooldef->type));
- goto cleanup;
- }
-
- break;
-
- case VIR_STORAGE_POOL_ISCSI:
- if (def->startupPolicy) {
- virReportError(VIR_ERR_XML_ERROR, "%s",
- _("'startupPolicy' is only valid for "
- "'file' type volume"));
- goto cleanup;
- }
-
- switch (def->src->srcpool->mode) {
- case VIR_STORAGE_SOURCE_POOL_MODE_DEFAULT:
- case VIR_STORAGE_SOURCE_POOL_MODE_LAST:
- def->src->srcpool->mode = VIR_STORAGE_SOURCE_POOL_MODE_HOST;
- /* fallthrough */
- case VIR_STORAGE_SOURCE_POOL_MODE_HOST:
- def->src->srcpool->actualtype = VIR_STORAGE_TYPE_BLOCK;
- if (!(def->src->path = virStorageVolGetPath(vol)))
- goto cleanup;
- break;
-
- case VIR_STORAGE_SOURCE_POOL_MODE_DIRECT:
- def->src->srcpool->actualtype = VIR_STORAGE_TYPE_NETWORK;
- def->src->protocol = VIR_STORAGE_NET_PROTOCOL_ISCSI;
-
- if (qemuTranslateDiskSourcePoolAuth(def, &pooldef->source) < 0)
- goto cleanup;
-
- if (qemuAddISCSIPoolSourceHost(def, pooldef) < 0)
- goto cleanup;
- break;
- }
- break;
-
- case VIR_STORAGE_POOL_MPATH:
- case VIR_STORAGE_POOL_RBD:
- case VIR_STORAGE_POOL_SHEEPDOG:
- case VIR_STORAGE_POOL_GLUSTER:
- case VIR_STORAGE_POOL_LAST:
- virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
- _("using '%s' pools for backing 'volume' disks "
- "isn't yet supported"),
- virStoragePoolTypeToString(pooldef->type));
- goto cleanup;
- }
-
- ret = 0;
- cleanup:
- if (ret < 0)
- savedError = virSaveLastError();
- if (pool)
- virStoragePoolFree(pool);
- if (vol)
- virStorageVolFree(vol);
- if (savedError) {
- virSetError(savedError);
- virFreeError(savedError);
- }
-
- VIR_FREE(poolxml);
- virStoragePoolDefFree(pooldef);
- return ret;
-}
-
int
qemuTranslateSnapshotDiskSourcePool(virConnectPtr conn ATTRIBUTE_UNUSED,
diff --git a/src/qemu/qemu_conf.h b/src/qemu/qemu_conf.h
index 90aebef..3276412 100644
--- a/src/qemu/qemu_conf.h
+++ b/src/qemu/qemu_conf.h
@@ -307,9 +307,6 @@ int qemuSetUnprivSGIO(virDomainDeviceDefPtr dev);
int qemuDriverAllocateID(virQEMUDriverPtr driver);
virDomainXMLOptionPtr virQEMUDriverCreateXMLConf(virQEMUDriverPtr driver);
-int qemuTranslateDiskSourcePool(virConnectPtr conn,
- virDomainDiskDefPtr def);
-
int qemuTranslateSnapshotDiskSourcePool(virConnectPtr conn,
virDomainSnapshotDiskDefPtr def);
diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c
index ac0717c..e0411b1 100644
--- a/src/qemu/qemu_driver.c
+++ b/src/qemu/qemu_driver.c
@@ -6635,7 +6635,7 @@ qemuDomainChangeDiskMediaLive(virConnectPtr conn,
virCapsPtr caps = NULL;
int ret = -1;
- if (qemuTranslateDiskSourcePool(conn, disk) < 0)
+ if (virDomainTranslateDiskSourcePool(conn, disk) < 0)
goto end;
if (qemuDomainDetermineDiskChain(driver, vm, disk, false) < 0)
@@ -12581,7 +12581,7 @@ qemuDomainSnapshotPrepareDiskExternal(virConnectPtr conn,
return -1;
if (!active) {
- if (qemuTranslateDiskSourcePool(conn, disk) < 0)
+ if (virDomainTranslateDiskSourcePool(conn, disk) < 0)
return -1;
if (qemuDomainSnapshotPrepareDiskExternalBackingInactive(disk) < 0)
@@ -12639,7 +12639,7 @@ qemuDomainSnapshotPrepareDiskInternal(virConnectPtr conn,
if (active)
return 0;
- if (qemuTranslateDiskSourcePool(conn, disk) < 0)
+ if (virDomainTranslateDiskSourcePool(conn, disk) < 0)
return -1;
actualType = virStorageSourceGetActualType(disk->src);
diff --git a/src/qemu/qemu_hotplug.c b/src/qemu/qemu_hotplug.c
index f7e223a..1d54de6 100644
--- a/src/qemu/qemu_hotplug.c
+++ b/src/qemu/qemu_hotplug.c
@@ -722,7 +722,7 @@ qemuDomainAttachDeviceDiskLive(virConnectPtr conn,
goto end;
}
- if (qemuTranslateDiskSourcePool(conn, disk) < 0)
+ if (virDomainTranslateDiskSourcePool(conn, disk) < 0)
goto end;
if (qemuAddSharedDevice(driver, dev, vm->def->name) < 0)
diff --git a/src/qemu/qemu_process.c b/src/qemu/qemu_process.c
index 13c396f..4ceb54e 100644
--- a/src/qemu/qemu_process.c
+++ b/src/qemu/qemu_process.c
@@ -3321,7 +3321,7 @@ qemuProcessReconnect(void *opaque)
for (i = 0; i < obj->def->ndisks; i++) {
virDomainDeviceDef dev;
- if (qemuTranslateDiskSourcePool(conn, obj->def->disks[i]) < 0)
+ if (virDomainTranslateDiskSourcePool(conn, obj->def->disks[i]) < 0)
goto error;
/* XXX we should be able to restore all data from XML in the future */
@@ -4000,7 +4000,7 @@ int qemuProcessStart(virConnectPtr conn,
* cgroup and security setting.
*/
for (i = 0; i < vm->def->ndisks; i++) {
- if (qemuTranslateDiskSourcePool(conn, vm->def->disks[i]) < 0)
+ if (virDomainTranslateDiskSourcePool(conn, vm->def->disks[i]) < 0)
goto cleanup;
}
diff --git a/tests/qemuxml2argvtest.c b/tests/qemuxml2argvtest.c
index 62b969c..7c3eb7c 100644
--- a/tests/qemuxml2argvtest.c
+++ b/tests/qemuxml2argvtest.c
@@ -351,7 +351,7 @@ static int testCompareXMLToArgvFiles(const char *xml,
}
for (i = 0; i < vmdef->ndisks; i++) {
- if (qemuTranslateDiskSourcePool(conn, vmdef->disks[i]) < 0)
+ if (virDomainTranslateDiskSourcePool(conn, vmdef->disks[i]) < 0)
goto out;
}
--
1.9.0
10 years, 3 months
[libvirt] [PATCH] daemon: Fix driver registration ordering
by Michal Privoznik
There are some stateless drivers which implement subdrivers
(typically vbox and its own network and storage subdrivers). However,
as of ba5f3c7c8ecc10 the vbox driver lives in the daemon, not the
client library. This means, in order for vbox (or any stateless domain
driver) to use its subdrivers, it must register before the general
drivers. Later, when the virConnectOpen function goes through the
subdrivers, stateless drivers are searched first. If the connection
request is aiming at stateless driver, it will be opened. Otherwise
the generic subdriver is opened.
The other change done in this commit is moving interface module load a
bit earlier to match the ordering in case libvirt is built without
driver modules.
Reported-by: Taowei Luo <uaedante(a)gmail.com>
Signed-off-by: Michal Privoznik <mprivozn(a)redhat.com>
---
daemon/libvirtd.c | 31 ++++++++++++++++++-------------
1 file changed, 18 insertions(+), 13 deletions(-)
diff --git a/daemon/libvirtd.c b/daemon/libvirtd.c
index a1f64ad..69baef6 100644
--- a/daemon/libvirtd.c
+++ b/daemon/libvirtd.c
@@ -365,10 +365,15 @@ static void daemonInitialize(void)
{
/*
* Note that the order is important: the first ones have a higher
- * priority when calling virStateInitialize. We must register
- * the network, storage and nodedev drivers before any domain
- * drivers, since their resources must be auto-started before
- * any domains can be auto-started.
+ * priority when calling virStateInitialize. We must register the
+ * network, storage and nodedev drivers before any stateless
+ * domain drivers, since their resources must be auto-started
+ * before any domains can be auto-started. Moreover, some
+ * stateless drivers implement their own subdrivers (e.g. the vbox
+ * driver has its own network and storage subdriers) which need to
+ * have higher priority. Otherwise, when connecting the such
+ * driver generic subdriver may be opened instead of the one
+ * corresponding to the stateless driver.
*/
#ifdef WITH_DRIVER_MODULES
/* We don't care if any of these fail, because the whole point
@@ -376,9 +381,15 @@ static void daemonInitialize(void)
* If they try to open a connection for a module that
* is not loaded they'll get a suitable error at that point
*/
+# ifdef WITH_VBOX
+ virDriverLoadModule("vbox");
+# endif
# ifdef WITH_NETWORK
virDriverLoadModule("network");
# endif
+# ifdef WITH_INTERFACE
+ virDriverLoadModule("interface");
+# endif
# ifdef WITH_STORAGE
virDriverLoadModule("storage");
# endif
@@ -391,9 +402,6 @@ static void daemonInitialize(void)
# ifdef WITH_NWFILTER
virDriverLoadModule("nwfilter");
# endif
-# ifdef WITH_INTERFACE
- virDriverLoadModule("interface");
-# endif
# ifdef WITH_XEN
virDriverLoadModule("xen");
# endif
@@ -409,13 +417,13 @@ static void daemonInitialize(void)
# ifdef WITH_UML
virDriverLoadModule("uml");
# endif
-# ifdef WITH_VBOX
- virDriverLoadModule("vbox");
-# endif
# ifdef WITH_BHYVE
virDriverLoadModule("bhyve");
# endif
#else
+# ifdef WITH_VBOX
+ vboxRegister();
+# endif
# ifdef WITH_NETWORK
networkRegister();
# endif
@@ -449,9 +457,6 @@ static void daemonInitialize(void)
# ifdef WITH_UML
umlRegister();
# endif
-# ifdef WITH_VBOX
- vboxRegister();
-# endif
# ifdef WITH_BHYVE
bhyveRegister();
# endif
--
1.8.5.5
10 years, 3 months
[libvirt] [PATCHv2] qemu: Redundant listen address entry in quest xml
by Erik Skultety
When editing guest's XML (on QEMU), it was possible to add multiple
listen elements into graphics parent element. However QEMU does not
support listening on multiple addresses. Configuration is tested for
multiple 'listen address' and if positive, an error is raised.
---
src/qemu/qemu_process.c | 8 ++++++++
1 file changed, 8 insertions(+)
diff --git a/src/qemu/qemu_process.c b/src/qemu/qemu_process.c
index 9e6a9ae..1810e6c 100644
--- a/src/qemu/qemu_process.c
+++ b/src/qemu/qemu_process.c
@@ -3934,6 +3934,14 @@ int qemuProcessStart(virConnectPtr conn,
}
graphics->listens[0].fromConfig = true;
}
+ /* multiple listen addresses are unsupported configuration in qemu
+ */
+ else if (graphics->nListens > 1) {
+ virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
+ _("QEMU does not support multiple listen "
+ "addresses for a domain."));
+ goto cleanup;
+ }
}
}
--
1.9.3
10 years, 3 months
[libvirt] [PATCH] Error out on missing address in 'server' type interface
by Ján Tomko
It was possible to add the following interface:
<interface type='server'>
<source port='5558'/>
</interface>
Resulting in:
error: internal error Process exited while reading console log output:
char device redirected to /dev/pts/4
2014-08-15T05:59:17.348271Z qemu-kvm: -netdev
socket,listen=(null):5558,id=hostnet0: Device 'socket' could not be
initialized
We already do this check for NET_TYPE_CLIENT and NET_TYPE_MCAST,
do it also for NET_TYPE_SERVER.
https://bugzilla.redhat.com/show_bug.cgi?id=1130390
---
src/conf/domain_conf.c | 11 ++++-------
1 file changed, 4 insertions(+), 7 deletions(-)
diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c
index 5c762fa..7ea628c 100644
--- a/src/conf/domain_conf.c
+++ b/src/conf/domain_conf.c
@@ -7118,13 +7118,10 @@ virDomainNetDefParseXML(virDomainXMLOptionPtr xmlopt,
}
if (address == NULL) {
- if (def->type == VIR_DOMAIN_NET_TYPE_CLIENT ||
- def->type == VIR_DOMAIN_NET_TYPE_MCAST) {
- virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
- _("No <source> 'address' attribute "
- "specified with socket interface"));
- goto error;
- }
+ virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
+ _("No <source> 'address' attribute "
+ "specified with socket interface"));
+ goto error;
} else {
def->data.socket.address = address;
address = NULL;
--
1.8.5.5
10 years, 3 months
[libvirt] [PATCH] network: fix crash when starting a network with no <pf> element
by Laine Stump
Martin Kletzander pointed out in email that my commit 2a193f64
introduced a crash in networkCreateInterfacePool() during startup of
any network that doesn't have a <pf> subelement of its <forward>
element. He also supplied a patch.
http://www.redhat.com/archives/libvir-list/2014-August/msg00655.html
I expanded on that patch by
cleaning uyp now-extraneous checks in the callers of
networkCreateInterfacePool().
Fortunately the offending patch hasn't been in any release, and hasn't
been (to my knowledge) backported to any other branch.
---
src/network/bridge_driver.c | 17 +++++++----------
1 file changed, 7 insertions(+), 10 deletions(-)
diff --git a/src/network/bridge_driver.c b/src/network/bridge_driver.c
index 1ba4c3d..fc4c73d 100644
--- a/src/network/bridge_driver.c
+++ b/src/network/bridge_driver.c
@@ -2196,6 +2196,9 @@ networkCreateInterfacePool(virNetworkDefPtr netdef)
int ret = -1;
size_t i;
+ if (!netdef->forward.npfs || netdef->forward.nifs > 0)
+ return 0;
+
if ((virNetDevGetVirtualFunctions(netdef->forward.pfs->dev,
&vfNames, &virtFns, &numVirtFns)) < 0) {
virReportError(VIR_ERR_INTERNAL_ERROR,
@@ -2204,7 +2207,6 @@ networkCreateInterfacePool(virNetworkDefPtr netdef)
goto cleanup;
}
- netdef->forward.nifs = 0;
if (VIR_ALLOC_N(netdef->forward.ifs, numVirtFns) < 0)
goto cleanup;
@@ -3843,10 +3845,8 @@ networkAllocateActualDevice(virDomainDefPtr dom,
virDomainHostdevSubsysPCIBackendType backend;
iface->data.network.actual->type = actualType = VIR_DOMAIN_NET_TYPE_HOSTDEV;
- if (netdef->forward.npfs > 0 && netdef->forward.nifs <= 0 &&
- networkCreateInterfacePool(netdef) < 0) {
+ if (networkCreateInterfacePool(netdef) < 0)
goto error;
- }
/* pick first dev with 0 connections */
for (i = 0; i < netdef->forward.nifs; i++) {
@@ -3978,10 +3978,8 @@ networkAllocateActualDevice(virDomainDefPtr dom,
} else {
/* pick an interface from the pool */
- if (netdef->forward.npfs > 0 && netdef->forward.nifs == 0 &&
- networkCreateInterfacePool(netdef) < 0) {
+ if (networkCreateInterfacePool(netdef) < 0)
goto error;
- }
/* PASSTHROUGH mode, and PRIVATE Mode + 802.1Qbh both
* require exclusive access to a device, so current
@@ -4149,10 +4147,9 @@ networkNotifyActualDevice(virDomainDefPtr dom,
goto success;
}
- if (netdef->forward.npfs > 0 && netdef->forward.nifs == 0 &&
- networkCreateInterfacePool(netdef) < 0) {
+ if (networkCreateInterfacePool(netdef) < 0)
goto error;
- }
+
if (netdef->forward.nifs == 0) {
virReportError(VIR_ERR_INTERNAL_ERROR,
_("network '%s' uses a direct or hostdev mode, "
--
1.9.3
10 years, 3 months
[libvirt] [PATCH v2 1/1] qemu: Tidy up job handling during live migration
by Sam Bobroff
During a QEMU live migration several warning messages about job
handling could be written to syslog on the destination host:
"entering monitor without asking for a nested job is dangerous"
The messages are written because the job handling during migration
uses hard coded asyncJob values in several places that are incorrect.
This patch passes the required asyncJob value around and prevents
the warnings as well as any issues that the warnings may be referring
to.
Signed-off-by: Sam Bobroff <sam.bobroff(a)au1.ibm.com>
---
v2:
* Handle failures from qemuDomainObjEnterMonitorAsync() rather than
ignoring them.
* Include qemuDomainChangeGraphicsPasswords().
src/qemu/qemu_domain.c | 6 ++++--
src/qemu/qemu_domain.h | 2 +-
src/qemu/qemu_driver.c | 21 ++++++++++++---------
src/qemu/qemu_migration.c | 3 ++-
src/qemu/qemu_process.c | 46 ++++++++++++++++++++++++++++------------------
src/qemu/qemu_process.h | 1 +
6 files changed, 48 insertions(+), 31 deletions(-)
diff --git a/src/qemu/qemu_domain.c b/src/qemu/qemu_domain.c
index 4f63c88..59b2647 100644
--- a/src/qemu/qemu_domain.c
+++ b/src/qemu/qemu_domain.c
@@ -2497,7 +2497,8 @@ qemuDomainDetermineDiskChain(virQEMUDriverPtr driver,
int
qemuDomainUpdateDeviceList(virQEMUDriverPtr driver,
- virDomainObjPtr vm)
+ virDomainObjPtr vm,
+ int asyncJob)
{
qemuDomainObjPrivatePtr priv = vm->privateData;
char **aliases;
@@ -2505,7 +2506,8 @@ qemuDomainUpdateDeviceList(virQEMUDriverPtr driver,
if (!virQEMUCapsGet(priv->qemuCaps, QEMU_CAPS_DEVICE_DEL_EVENT))
return 0;
- qemuDomainObjEnterMonitor(driver, vm);
+ if (qemuDomainObjEnterMonitorAsync(driver, vm, asyncJob) < 0)
+ return -1;
if (qemuMonitorGetDeviceAliases(priv->mon, &aliases) < 0) {
qemuDomainObjExitMonitor(driver, vm);
return -1;
diff --git a/src/qemu/qemu_domain.h b/src/qemu/qemu_domain.h
index 67972b9..8736889 100644
--- a/src/qemu/qemu_domain.h
+++ b/src/qemu/qemu_domain.h
@@ -369,7 +369,7 @@ extern virDomainXMLNamespace virQEMUDriverDomainXMLNamespace;
extern virDomainDefParserConfig virQEMUDriverDomainDefParserConfig;
int qemuDomainUpdateDeviceList(virQEMUDriverPtr driver,
- virDomainObjPtr vm);
+ virDomainObjPtr vm, int asyncJob);
bool qemuDomainDefCheckABIStability(virQEMUDriverPtr driver,
virDomainDefPtr src,
diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c
index 33541d3..b0439d2 100644
--- a/src/qemu/qemu_driver.c
+++ b/src/qemu/qemu_driver.c
@@ -1616,7 +1616,8 @@ static virDomainPtr qemuDomainCreateXML(virConnectPtr conn,
goto cleanup;
}
- if (qemuProcessStart(conn, driver, vm, NULL, -1, NULL, NULL,
+ if (qemuProcessStart(conn, driver, vm, QEMU_ASYNC_JOB_NONE,
+ NULL, -1, NULL, NULL,
VIR_NETDEV_VPORT_PROFILE_OP_CREATE,
start_flags) < 0) {
virDomainAuditStart(vm, "booted", false);
@@ -5446,7 +5447,8 @@ qemuDomainSaveImageStartVM(virConnectPtr conn,
}
/* Set the migration source and start it up. */
- ret = qemuProcessStart(conn, driver, vm, "stdio", *fd, path, NULL,
+ ret = qemuProcessStart(conn, driver, vm, QEMU_ASYNC_JOB_NONE,
+ "stdio", *fd, path, NULL,
VIR_NETDEV_VPORT_PROFILE_OP_RESTORE,
VIR_QEMU_PROCESS_START_PAUSED);
@@ -6143,7 +6145,8 @@ qemuDomainObjStart(virConnectPtr conn,
}
}
- ret = qemuProcessStart(conn, driver, vm, NULL, -1, NULL, NULL,
+ ret = qemuProcessStart(conn, driver, vm, QEMU_ASYNC_JOB_NONE,
+ NULL, -1, NULL, NULL,
VIR_NETDEV_VPORT_PROFILE_OP_CREATE, start_flags);
virDomainAuditStart(vm, "booted", ret >= 0);
if (ret >= 0) {
@@ -6500,7 +6503,7 @@ qemuDomainAttachDeviceLive(virDomainObjPtr vm,
}
if (ret == 0)
- qemuDomainUpdateDeviceList(driver, vm);
+ qemuDomainUpdateDeviceList(driver, vm, QEMU_ASYNC_JOB_NONE);
return ret;
}
@@ -6560,7 +6563,7 @@ qemuDomainDetachDeviceLive(virDomainObjPtr vm,
}
if (ret == 0)
- qemuDomainUpdateDeviceList(driver, vm);
+ qemuDomainUpdateDeviceList(driver, vm, QEMU_ASYNC_JOB_NONE);
return ret;
}
@@ -14101,8 +14104,8 @@ static int qemuDomainRevertToSnapshot(virDomainSnapshotPtr snapshot,
if (config)
virDomainObjAssignDef(vm, config, false, NULL);
- rc = qemuProcessStart(snapshot->domain->conn,
- driver, vm, NULL, -1, NULL, snap,
+ rc = qemuProcessStart(snapshot->domain->conn, driver, vm,
+ QEMU_ASYNC_JOB_NONE, NULL, -1, NULL, snap,
VIR_NETDEV_VPORT_PROFILE_OP_CREATE,
VIR_QEMU_PROCESS_START_PAUSED);
virDomainAuditStart(vm, "from-snapshot", rc >= 0);
@@ -14195,8 +14198,8 @@ static int qemuDomainRevertToSnapshot(virDomainSnapshotPtr snapshot,
if (event)
qemuDomainEventQueue(driver, event);
- rc = qemuProcessStart(snapshot->domain->conn,
- driver, vm, NULL, -1, NULL, NULL,
+ rc = qemuProcessStart(snapshot->domain->conn, driver, vm,
+ QEMU_ASYNC_JOB_NONE, NULL, -1, NULL, NULL,
VIR_NETDEV_VPORT_PROFILE_OP_CREATE,
start_flags);
virDomainAuditStart(vm, "from-snapshot", rc >= 0);
diff --git a/src/qemu/qemu_migration.c b/src/qemu/qemu_migration.c
index 767d840..1c46b34 100644
--- a/src/qemu/qemu_migration.c
+++ b/src/qemu/qemu_migration.c
@@ -2480,7 +2480,8 @@ qemuMigrationPrepareAny(virQEMUDriverPtr driver,
/* Start the QEMU daemon, with the same command-line arguments plus
* -incoming $migrateFrom
*/
- if (qemuProcessStart(dconn, driver, vm, migrateFrom, dataFD[0], NULL, NULL,
+ if (qemuProcessStart(dconn, driver, vm, QEMU_ASYNC_JOB_MIGRATION_IN,
+ migrateFrom, dataFD[0], NULL, NULL,
VIR_NETDEV_VPORT_PROFILE_OP_MIGRATE_IN_START,
VIR_QEMU_PROCESS_START_PAUSED |
VIR_QEMU_PROCESS_START_AUTODESTROY) < 0) {
diff --git a/src/qemu/qemu_process.c b/src/qemu/qemu_process.c
index 8a6b384..690927e 100644
--- a/src/qemu/qemu_process.c
+++ b/src/qemu/qemu_process.c
@@ -1444,7 +1444,8 @@ static qemuMonitorCallbacks monitorCallbacks = {
};
static int
-qemuConnectMonitor(virQEMUDriverPtr driver, virDomainObjPtr vm, int logfd)
+qemuConnectMonitor(virQEMUDriverPtr driver, virDomainObjPtr vm, int asyncJob,
+ int logfd)
{
qemuDomainObjPrivatePtr priv = vm->privateData;
int ret = -1;
@@ -1495,7 +1496,8 @@ qemuConnectMonitor(virQEMUDriverPtr driver, virDomainObjPtr vm, int logfd)
}
- qemuDomainObjEnterMonitor(driver, vm);
+ if (qemuDomainObjEnterMonitorAsync(driver, vm, asyncJob) < 0)
+ goto error;
ret = qemuMonitorSetCapabilities(priv->mon);
if (ret == 0 &&
virQEMUCapsGet(priv->qemuCaps, QEMU_CAPS_MONITOR_JSON))
@@ -1901,6 +1903,7 @@ qemuProcessFindCharDevicePTYs(virDomainObjPtr vm,
static int
qemuProcessWaitForMonitor(virQEMUDriverPtr driver,
virDomainObjPtr vm,
+ int asyncJob,
virQEMUCapsPtr qemuCaps,
off_t pos)
{
@@ -1926,7 +1929,7 @@ qemuProcessWaitForMonitor(virQEMUDriverPtr driver,
}
VIR_DEBUG("Connect monitor to %p '%s'", vm, vm->def->name);
- if (qemuConnectMonitor(driver, vm, logfd) < 0)
+ if (qemuConnectMonitor(driver, vm, asyncJob, logfd) < 0)
goto cleanup;
/* Try to get the pty path mappings again via the monitor. This is much more
@@ -1938,7 +1941,8 @@ qemuProcessWaitForMonitor(virQEMUDriverPtr driver,
goto cleanup;
priv = vm->privateData;
- qemuDomainObjEnterMonitor(driver, vm);
+ if (qemuDomainObjEnterMonitorAsync(driver, vm, asyncJob) < 0)
+ goto cleanup;
ret = qemuMonitorGetPtyPaths(priv->mon, paths);
qemuDomainObjExitMonitor(driver, vm);
@@ -1984,13 +1988,14 @@ qemuProcessWaitForMonitor(virQEMUDriverPtr driver,
static int
qemuProcessDetectVcpuPIDs(virQEMUDriverPtr driver,
- virDomainObjPtr vm)
+ virDomainObjPtr vm, int asyncJob)
{
pid_t *cpupids = NULL;
int ncpupids;
qemuDomainObjPrivatePtr priv = vm->privateData;
- qemuDomainObjEnterMonitor(driver, vm);
+ if (qemuDomainObjEnterMonitorAsync(driver, vm, asyncJob) < 0)
+ return -1;
/* failure to get the VCPU<-> PID mapping or to execute the query
* command will not be treated fatal as some versions of qemu don't
* support this command */
@@ -2213,7 +2218,8 @@ qemuProcessSetEmulatorAffinities(virConnectPtr conn ATTRIBUTE_UNUSED,
static int
qemuProcessInitPasswords(virConnectPtr conn,
virQEMUDriverPtr driver,
- virDomainObjPtr vm)
+ virDomainObjPtr vm,
+ int asyncJob)
{
int ret = 0;
qemuDomainObjPrivatePtr priv = vm->privateData;
@@ -2254,7 +2260,8 @@ qemuProcessInitPasswords(virConnectPtr conn,
goto cleanup;
alias = vm->def->disks[i]->info.alias;
- qemuDomainObjEnterMonitor(driver, vm);
+ if (qemuDomainObjEnterMonitorAsync(driver, vm, asyncJob) < 0)
+ goto cleanup;
ret = qemuMonitorSetDrivePassphrase(priv->mon, alias, secret);
VIR_FREE(secret);
qemuDomainObjExitMonitor(driver, vm);
@@ -3150,7 +3157,7 @@ qemuProcessUpdateDevices(virQEMUDriverPtr driver,
old = priv->qemuDevices;
priv->qemuDevices = NULL;
- if (qemuDomainUpdateDeviceList(driver, vm) < 0)
+ if (qemuDomainUpdateDeviceList(driver, vm, QEMU_ASYNC_JOB_NONE) < 0)
goto cleanup;
if ((tmp = old)) {
@@ -3216,7 +3223,7 @@ qemuProcessReconnect(void *opaque)
virObjectRef(obj);
/* XXX check PID liveliness & EXE path */
- if (qemuConnectMonitor(driver, obj, -1) < 0)
+ if (qemuConnectMonitor(driver, obj, QEMU_ASYNC_JOB_NONE, -1) < 0)
goto error;
/* Failure to connect to agent shouldn't be fatal */
@@ -3655,6 +3662,7 @@ qemuProcessVerifyGuestCPU(virQEMUDriverPtr driver, virDomainObjPtr vm)
int qemuProcessStart(virConnectPtr conn,
virQEMUDriverPtr driver,
virDomainObjPtr vm,
+ int asyncJob,
const char *migrateFrom,
int stdin_fd,
const char *stdin_path,
@@ -4137,7 +4145,7 @@ int qemuProcessStart(virConnectPtr conn,
goto cleanup;
VIR_DEBUG("Waiting for monitor to show up");
- if (qemuProcessWaitForMonitor(driver, vm, priv->qemuCaps, pos) < 0)
+ if (qemuProcessWaitForMonitor(driver, vm, asyncJob, priv->qemuCaps, pos) < 0)
goto cleanup;
/* Failure to connect to agent shouldn't be fatal */
@@ -4160,7 +4168,7 @@ int qemuProcessStart(virConnectPtr conn,
goto cleanup;
VIR_DEBUG("Detecting VCPU PIDs");
- if (qemuProcessDetectVcpuPIDs(driver, vm) < 0)
+ if (qemuProcessDetectVcpuPIDs(driver, vm, asyncJob) < 0)
goto cleanup;
VIR_DEBUG("Setting cgroup for each VCPU (if required)");
@@ -4180,7 +4188,7 @@ int qemuProcessStart(virConnectPtr conn,
goto cleanup;
VIR_DEBUG("Setting any required VM passwords");
- if (qemuProcessInitPasswords(conn, driver, vm) < 0)
+ if (qemuProcessInitPasswords(conn, driver, vm, asyncJob) < 0)
goto cleanup;
/* If we have -device, then addresses are assigned explicitly.
@@ -4195,7 +4203,8 @@ int qemuProcessStart(virConnectPtr conn,
/* qemu doesn't support setting this on the command line, so
* enter the monitor */
VIR_DEBUG("Setting network link states");
- qemuDomainObjEnterMonitor(driver, vm);
+ if (qemuDomainObjEnterMonitorAsync(driver, vm, asyncJob) < 0)
+ goto cleanup;
if (qemuProcessSetLinkStates(vm) < 0) {
qemuDomainObjExitMonitor(driver, vm);
goto cleanup;
@@ -4204,7 +4213,7 @@ int qemuProcessStart(virConnectPtr conn,
qemuDomainObjExitMonitor(driver, vm);
VIR_DEBUG("Fetching list of active devices");
- if (qemuDomainUpdateDeviceList(driver, vm) < 0)
+ if (qemuDomainUpdateDeviceList(driver, vm, asyncJob) < 0)
goto cleanup;
/* Technically, qemuProcessStart can be called from inside
@@ -4219,7 +4228,8 @@ int qemuProcessStart(virConnectPtr conn,
vm->def->mem.cur_balloon);
goto cleanup;
}
- qemuDomainObjEnterMonitor(driver, vm);
+ if (qemuDomainObjEnterMonitorAsync(driver, vm, asyncJob) < 0)
+ goto cleanup;
if (vm->def->memballoon && vm->def->memballoon->period)
qemuMonitorSetMemoryStatsPeriod(priv->mon, vm->def->memballoon->period);
if (qemuMonitorSetBalloon(priv->mon, cur_balloon) < 0) {
@@ -4764,7 +4774,7 @@ int qemuProcessAttach(virConnectPtr conn ATTRIBUTE_UNUSED,
vm->pid = pid;
VIR_DEBUG("Waiting for monitor to show up");
- if (qemuProcessWaitForMonitor(driver, vm, priv->qemuCaps, -1) < 0)
+ if (qemuProcessWaitForMonitor(driver, vm, QEMU_ASYNC_JOB_NONE, priv->qemuCaps, -1) < 0)
goto error;
/* Failure to connect to agent shouldn't be fatal */
@@ -4779,7 +4789,7 @@ int qemuProcessAttach(virConnectPtr conn ATTRIBUTE_UNUSED,
}
VIR_DEBUG("Detecting VCPU PIDs");
- if (qemuProcessDetectVcpuPIDs(driver, vm) < 0)
+ if (qemuProcessDetectVcpuPIDs(driver, vm, QEMU_ASYNC_JOB_NONE) < 0)
goto error;
/* If we have -device, then addresses are assigned explicitly.
diff --git a/src/qemu/qemu_process.h b/src/qemu/qemu_process.h
index 9c78736..5948ea4 100644
--- a/src/qemu/qemu_process.h
+++ b/src/qemu/qemu_process.h
@@ -53,6 +53,7 @@ typedef enum {
int qemuProcessStart(virConnectPtr conn,
virQEMUDriverPtr driver,
virDomainObjPtr vm,
+ int asyncJob,
const char *migrateFrom,
int stdin_fd,
const char *stdin_path,
--
2.0.2.731.g247b4d5
10 years, 3 months