[libvirt] [PATCH 0/4] Add auth and adapter to virsh pool-{create|define}-as
by John Ferlan
Recently while reviewing some documentation for iSCSI authentication
description I found that virsh pool-{create|define}-as did not provide
a mechanism to add the <auth> and/or <adapter> options on the command
line - so I figured adding them would be simple. In the course of doing
this I also noted a few typos on the formatstorage html page and (to
say the last) a fairly incomplete or lacking man page description for
pool-{create|define}-as.
John Ferlan (4):
docs: Fix a couple of typos on the storage pool html
virsh.pod: Fix the pool-define-as and pool-create-as description
virsh: Add auth options for pool-{create|define}-as
virsh: Add adapter options for pool-{create|define}-as
docs/formatstorage.html.in | 4 ++--
tools/virsh-pool.c | 59 ++++++++++++++++++++++++++++++++++++++++++++--
tools/virsh.pod | 53 ++++++++++++++++++++++++++++++++++++-----
3 files changed, 106 insertions(+), 10 deletions(-)
--
1.9.3
9 years, 11 months
[libvirt] [PATCH v2] automatic create tap device with network type ethernet
by Vasiliy Tolstov
If user not specify script in network type ethernet, assume that user
needs simple tap device created with libvirt.
This patch does not need to run external script to create tap device or
add root to qemu process.
Signed-off-by: Vasiliy Tolstov <v.tolstov(a)selfip.ru>
---
src/qemu/qemu_command.c | 86 ++++++++++++++++++++++++++++++++-----------------
src/qemu/qemu_hotplug.c | 10 ++----
src/qemu/qemu_process.c | 4 +++
3 files changed, 62 insertions(+), 38 deletions(-)
diff --git a/src/qemu/qemu_command.c b/src/qemu/qemu_command.c
index 4ed6506..0911c32 100644
--- a/src/qemu/qemu_command.c
+++ b/src/qemu/qemu_command.c
@@ -319,7 +319,7 @@ qemuNetworkIfaceConnect(virDomainDefPtr def,
} else if (actualType == VIR_DOMAIN_NET_TYPE_BRIDGE) {
if (VIR_STRDUP(brname, virDomainNetGetActualBridgeName(net)) < 0)
return ret;
- } else {
+ } else if (actualType != VIR_DOMAIN_NET_TYPE_ETHERNET) {
virReportError(VIR_ERR_INTERNAL_ERROR,
_("Network type %d is not supported"),
virDomainNetGetActualType(net));
@@ -341,30 +341,40 @@ qemuNetworkIfaceConnect(virDomainDefPtr def,
tap_create_flags |= VIR_NETDEV_TAP_CREATE_VNET_HDR;
}
- if (cfg->privileged) {
- if (virNetDevTapCreateInBridgePort(brname, &net->ifname, &net->mac,
- def->uuid, tunpath, tapfd, *tapfdSize,
- virDomainNetGetActualVirtPortProfile(net),
- virDomainNetGetActualVlan(net),
- tap_create_flags) < 0) {
+ if (actualType == VIR_DOMAIN_NET_TYPE_ETHERNET) {
+ if (virNetDevTapCreate(&net->ifname, tunpath, tapfd, *tapfdSize,
+ tap_create_flags) < 0) {
virDomainAuditNetDevice(def, net, tunpath, false);
goto cleanup;
}
- } else {
- if (qemuCreateInBridgePortWithHelper(cfg, brname,
- &net->ifname,
- tapfd, tap_create_flags) < 0) {
- virDomainAuditNetDevice(def, net, tunpath, false);
+ if (virNetDevSetOnline(net->ifname, !!(tap_create_flags & VIR_NETDEV_TAP_CREATE_IFUP)) < 0)
goto cleanup;
+ } else {
+ if (cfg->privileged) {
+ if (virNetDevTapCreateInBridgePort(brname, &net->ifname, &net->mac,
+ def->uuid, tunpath, tapfd, *tapfdSize,
+ virDomainNetGetActualVirtPortProfile(net),
+ virDomainNetGetActualVlan(net),
+ tap_create_flags) < 0) {
+ virDomainAuditNetDevice(def, net, tunpath, false);
+ goto cleanup;
+ }
+ } else {
+ if (qemuCreateInBridgePortWithHelper(cfg, brname,
+ &net->ifname,
+ tapfd, tap_create_flags) < 0) {
+ virDomainAuditNetDevice(def, net, tunpath, false);
+ goto cleanup;
+ }
+ /* qemuCreateInBridgePortWithHelper can only create a single FD */
+ if (*tapfdSize > 1) {
+ VIR_WARN("Ignoring multiqueue network request");
+ *tapfdSize = 1;
+ }
}
- /* qemuCreateInBridgePortWithHelper can only create a single FD */
- if (*tapfdSize > 1) {
- VIR_WARN("Ignoring multiqueue network request");
- *tapfdSize = 1;
- }
- }
- virDomainAuditNetDevice(def, net, tunpath, true);
+ virDomainAuditNetDevice(def, net, tunpath, true);
+ }
if (cfg->macFilter &&
ebtablesAddForwardAllowIn(driver->ebtables,
@@ -4540,18 +4550,32 @@ qemuBuildHostNetStr(virDomainNetDefPtr net,
break;
case VIR_DOMAIN_NET_TYPE_ETHERNET:
- virBufferAddLit(&buf, "tap");
+ virBufferAddLit(&buf, "tap");
+ type_sep = ',';
+ if (net->script) {
if (net->ifname) {
- virBufferAsprintf(&buf, "%cifname=%s", type_sep, net->ifname);
- type_sep = ',';
+ virBufferAsprintf(&buf, "%cifname=%s", type_sep, net->ifname);
+ type_sep = ',';
}
- if (net->script) {
- virBufferAsprintf(&buf, "%cscript=%s", type_sep,
- net->script);
- type_sep = ',';
+ virBufferAsprintf(&buf, "%cscript=%s", type_sep, net->script);
+ type_sep = ',';
+ } else {
+ /* for one tapfd 'fd=' shall be used,
+ * for more than one 'fds=' is the right choice */
+ if (tapfdSize == 1) {
+ virBufferAsprintf(&buf, "%cfd=%s", type_sep, tapfd[0]);
+ } else {
+ virBufferAsprintf(&buf, "%cfds=", type_sep);
+ for (i = 0; i < tapfdSize; i++) {
+ if (i)
+ virBufferAddChar(&buf, ':');
+ virBufferAdd(&buf, tapfd[i], -1);
+ }
}
- is_tap = true;
- break;
+ type_sep = ',';
+ }
+ is_tap = true;
+ break;
case VIR_DOMAIN_NET_TYPE_CLIENT:
virBufferAsprintf(&buf, "socket%cconnect=%s:%d",
@@ -7372,7 +7396,8 @@ qemuBuildInterfaceCommandLine(virCommandPtr cmd,
/* Currently nothing besides TAP devices supports multiqueue. */
if (net->driver.virtio.queues > 0 &&
!(actualType == VIR_DOMAIN_NET_TYPE_NETWORK ||
- actualType == VIR_DOMAIN_NET_TYPE_BRIDGE)) {
+ actualType == VIR_DOMAIN_NET_TYPE_BRIDGE ||
+ actualType == VIR_DOMAIN_NET_TYPE_ETHERNET)) {
virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
_("Multiqueue network is not supported for: %s"),
virDomainNetTypeToString(actualType));
@@ -7380,7 +7405,8 @@ qemuBuildInterfaceCommandLine(virCommandPtr cmd,
}
if (actualType == VIR_DOMAIN_NET_TYPE_NETWORK ||
- actualType == VIR_DOMAIN_NET_TYPE_BRIDGE) {
+ actualType == VIR_DOMAIN_NET_TYPE_BRIDGE ||
+ actualType == VIR_DOMAIN_NET_TYPE_ETHERNET) {
tapfdSize = net->driver.virtio.queues;
if (!tapfdSize)
tapfdSize = 1;
diff --git a/src/qemu/qemu_hotplug.c b/src/qemu/qemu_hotplug.c
index b00fd8f..bf92e4d 100644
--- a/src/qemu/qemu_hotplug.c
+++ b/src/qemu/qemu_hotplug.c
@@ -908,7 +908,8 @@ int qemuDomainAttachNetDevice(virConnectPtr conn,
}
if (actualType == VIR_DOMAIN_NET_TYPE_BRIDGE ||
- actualType == VIR_DOMAIN_NET_TYPE_NETWORK) {
+ actualType == VIR_DOMAIN_NET_TYPE_NETWORK ||
+ actualType == VIR_DOMAIN_NET_TYPE_ETHERNET) {
tapfdSize = vhostfdSize = net->driver.virtio.queues;
if (!tapfdSize)
tapfdSize = vhostfdSize = 1;
@@ -939,13 +940,6 @@ int qemuDomainAttachNetDevice(virConnectPtr conn,
iface_connected = true;
if (qemuOpenVhostNet(vm->def, net, priv->qemuCaps, vhostfd, &vhostfdSize) < 0)
goto cleanup;
- } else if (actualType == VIR_DOMAIN_NET_TYPE_ETHERNET) {
- vhostfdSize = 1;
- if (VIR_ALLOC(vhostfd) < 0)
- goto cleanup;
- *vhostfd = -1;
- if (qemuOpenVhostNet(vm->def, net, priv->qemuCaps, vhostfd, &vhostfdSize) < 0)
- goto cleanup;
}
/* Set Bandwidth */
diff --git a/src/qemu/qemu_process.c b/src/qemu/qemu_process.c
index 382d802..f161e3a 100644
--- a/src/qemu/qemu_process.c
+++ b/src/qemu/qemu_process.c
@@ -5080,6 +5080,10 @@ void qemuProcessStop(virQEMUDriverPtr driver,
cfg->stateDir));
VIR_FREE(net->ifname);
break;
+ case VIR_DOMAIN_NET_TYPE_ETHERNET:
+ ignore_value(virNetDevTapDelete(net->ifname, net->backend.tap));
+ VIR_FREE(net->ifname);
+ break;
case VIR_DOMAIN_NET_TYPE_BRIDGE:
case VIR_DOMAIN_NET_TYPE_NETWORK:
#ifdef VIR_NETDEV_TAP_REQUIRE_MANUAL_CLEANUP
--
2.1.3
9 years, 11 months
[libvirt] [PATCH] qemu: snapshot: Report better error when create internal snapshot with passthrough devices
by Shanzhi Yu
When create internal system checkpoint snapshot, it will not works if
guest has passthrough devices attached. It will report error:
error: operation failed: Error -22 while writing VM
With this patch, it will report erro:
error: Requested operation is not valid: domain has assigned non-USB host devices
Resolves: https://bugzilla.redhat.com/show_bug.cgi?id=874418#c19
---
src/qemu/qemu_driver.c | 3 +++
1 file changed, 3 insertions(+)
diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c
index 5dc62b0..0fdee26 100644
--- a/src/qemu/qemu_driver.c
+++ b/src/qemu/qemu_driver.c
@@ -12902,6 +12902,9 @@ qemuDomainSnapshotCreateActiveInternal(virConnectPtr conn,
}
}
+ if (!qemuMigrationIsAllowed(driver, vm, vm->def, false, false))
+ goto cleanup;
+
if (qemuDomainObjEnterMonitorAsync(driver, vm,
QEMU_ASYNC_JOB_SNAPSHOT) < 0) {
resume = false;
--
1.8.3.1
9 years, 11 months
[libvirt] question about MigrateSetMaxDowntime
by Jim Fehlig
A user asked me about setting max downtime prior to migration, which I thought
could be done similar to MigrateSetMaxSpeed. I was surprised to find that it
can only be set when migration is in progress
# virsh migrate-setmaxdowntime test 1000
error: Requested operation is not valid: domain is not being migrated
Is there any reason this cannot be set prior to migration? Max speed can even
be set on a persistent domain that is not running. I'd be happy to work on a
patch if the only reason is no one has needed this itch scratched.
Regards,
Jim
9 years, 11 months
[libvirt] [PATCH] storage: backend: Log uid/gid when initializing storage file backend
by Peter Krempa
To ease debugging permission problems add uid/gid values to the debug
message when initializing a storage file backend.
---
src/storage/storage_backend_fs.c | 4 ++--
src/storage/storage_backend_gluster.c | 4 ++--
2 files changed, 4 insertions(+), 4 deletions(-)
diff --git a/src/storage/storage_backend_fs.c b/src/storage/storage_backend_fs.c
index 0ee1d09..b831268 100644
--- a/src/storage/storage_backend_fs.c
+++ b/src/storage/storage_backend_fs.c
@@ -1370,9 +1370,9 @@ virStorageFileBackendFileInit(virStorageSourcePtr src)
{
virStorageFileBackendFsPrivPtr priv = NULL;
- VIR_DEBUG("initializing FS storage file %p (%s:%s)", src,
+ VIR_DEBUG("initializing FS storage file %p (%s:%s[%u:%u])", src,
virStorageTypeToString(virStorageSourceGetActualType(src)),
- src->path);
+ src->path, src->drv->uid, src->drv->gid);
if (VIR_ALLOC(priv) < 0)
return -1;
diff --git a/src/storage/storage_backend_gluster.c b/src/storage/storage_backend_gluster.c
index b79b634..9d7b0f5 100644
--- a/src/storage/storage_backend_gluster.c
+++ b/src/storage/storage_backend_gluster.c
@@ -582,9 +582,9 @@ virStorageFileBackendGlusterInit(virStorageSourcePtr src)
hostname = host->name;
- VIR_DEBUG("initializing gluster storage file %p (gluster://%s:%s/%s%s)",
+ VIR_DEBUG("initializing gluster storage file %p (gluster://%s:%s/%s%s)[%u:%u]",
src, hostname, host->port ? host->port : "0",
- NULLSTR(src->volume), src->path);
+ NULLSTR(src->volume), src->path, src->drv->uid, src->drv->gid);
if (!src->volume) {
virReportError(VIR_ERR_INTERNAL_ERROR,
--
2.1.0
9 years, 11 months
[libvirt] [PATCHv2 2/2] security: Add a new func use stat to get process DAC label
by Luyao Huang
When use qemuProcessAttach to attach a qemu process, cannot
get a right DAC label. Add a new func to get process label
via stat func. Do not remove virDomainDefGetSecurityLabelDef
before try to use stat to get process DAC label, because
There are some other func call virSecurityDACGetProcessLabel.
v2 add support freeBSD.
Signed-off-by: Luyao Huang <lhuang(a)redhat.com>
---
src/security/security_dac.c | 95 ++++++++++++++++++++++++++++++++++++++++++++-
1 file changed, 93 insertions(+), 2 deletions(-)
diff --git a/src/security/security_dac.c b/src/security/security_dac.c
index 85253af..89cafa3 100644
--- a/src/security/security_dac.c
+++ b/src/security/security_dac.c
@@ -23,6 +23,11 @@
#include <sys/stat.h>
#include <fcntl.h>
+#ifdef __FreeBSD__
+# include <sys/sysctl.h>
+# include <sys/user.h>
+#endif
+
#include "security_dac.h"
#include "virerror.h"
#include "virfile.h"
@@ -1236,18 +1241,104 @@ virSecurityDACReserveLabel(virSecurityManagerPtr mgr ATTRIBUTE_UNUSED,
return 0;
}
+#ifdef __linux__
+static int
+virSecurityDACGetProcessLabelInternal(pid_t pid,
+ virSecurityLabelPtr seclabel)
+{
+ struct stat sb;
+ char *path = NULL;
+ char *label = NULL;
+ int ret = -1;
+
+ VIR_INFO("Getting DAC user and group on process '%d'", pid);
+
+ if (virAsprintf(&path, "/proc/%d", (int) pid) < 0)
+ goto cleanup;
+
+ if (lstat(path, &sb) < 0)
+ goto cleanup;
+
+ if (virAsprintf(&label, "+%u:+%u",
+ (unsigned int) sb.st_uid,
+ (unsigned int) sb.st_gid) < 0)
+ goto cleanup;
+
+ if (virStrcpy(seclabel->label, label,VIR_SECURITY_LABEL_BUFLEN) == NULL)
+ goto cleanup;
+ ret = 0;
+
+cleanup:
+ VIR_FREE(path);
+ VIR_FREE(label);
+ return ret;
+}
+#elif defined(__FreeBSD__)
+static int
+virSecurityDACGetProcessLabelInternal(pid_t pid,
+ virSecurityLabelPtr seclabel)
+{
+ struct kinfo_proc p;
+ int mib[4];
+ size_t len = 4;
+ char *label = NULL;
+ int ret = -1;
+
+ sysctlnametomib("kern.proc.pid", mib, &len);
+
+ len = sizeof(struct kinfo_proc);
+ mib[3] = pid;
+
+ if (sysctl(mib, 4, &p, &len, NULL, 0) < 0)
+ goto cleanup;
+
+ if (virAsprintf(&label, "+%u:+%u",
+ (unsigned int) p.ki_ruid,
+ (unsigned int) p.ki_rgid) < 0)
+ goto cleanup;
+
+ if (virStrcpy(seclabel->label, label,VIR_SECURITY_LABEL_BUFLEN) == NULL)
+ goto cleanup;
+ ret = 0;
+
+cleanup:
+ VIR_FREE(label);
+ return ret;
+}
+#else
+static int
+virSecurityDACGetProcessLabelInternal(pid_t pid,
+ virSecurityLabelPtr seclabel)
+{
+ return -1;
+}
+#endif
+
static int
virSecurityDACGetProcessLabel(virSecurityManagerPtr mgr ATTRIBUTE_UNUSED,
virDomainDefPtr def,
- pid_t pid ATTRIBUTE_UNUSED,
+ pid_t pid,
virSecurityLabelPtr seclabel)
{
virSecurityLabelDefPtr secdef =
virDomainDefGetSecurityLabelDef(def, SECURITY_DAC_NAME);
- if (!secdef || !seclabel)
+ if (!seclabel)
return -1;
+ if (secdef == NULL) {
+ VIR_DEBUG("missing label for DAC security "
+ "driver in domain %s", def->name);
+
+ if (virSecurityDACGetProcessLabelInternal(pid, seclabel) < 0) {
+ virReportError(VIR_ERR_INTERNAL_ERROR,
+ _("Cannot get process %d DAC label"),pid);
+ return -1;
+ }
+
+ return 0;
+ }
+
if (secdef->label)
ignore_value(virStrcpy(seclabel->label, secdef->label,
VIR_SECURITY_LABEL_BUFLEN));
--
1.8.3.1
9 years, 11 months
[libvirt] [PATCH] networkValidate: Disallow bandwidth in portgroups too
by Michal Privoznik
In one of the previous commits (eafb53fe) we disallowed
network-wide bandwidth to some network types. However, we
forgot about <portgroups/> which can have <bandwidth/> too.
Signed-off-by: Michal Privoznik <mprivozn(a)redhat.com>
---
src/network/bridge_driver.c | 11 +++++++++++
1 file changed, 11 insertions(+)
diff --git a/src/network/bridge_driver.c b/src/network/bridge_driver.c
index 9ccc9f8..1459f04 100644
--- a/src/network/bridge_driver.c
+++ b/src/network/bridge_driver.c
@@ -2711,6 +2711,7 @@ networkValidate(virNetworkDefPtr def,
virPortGroupDefPtr defaultPortGroup = NULL;
virNetworkIpDefPtr ipdef;
bool ipv4def = false, ipv6def = false;
+ bool bandwidthAllowed = true;
/* check for duplicate networks */
if (virNetworkObjIsDuplicate(&driver->networks, def, check_active) < 0)
@@ -2772,6 +2773,7 @@ networkValidate(virNetworkDefPtr def,
virNetworkForwardTypeToString(def->forward.type));
return -1;
}
+ bandwidthAllowed = false;
}
/* We only support dhcp on one IPv4 address and
@@ -2850,6 +2852,15 @@ networkValidate(virNetworkDefPtr def,
}
defaultPortGroup = &def->portGroups[i];
}
+
+ if (def->portGroups[i].bandwidth && !bandwidthAllowed) {
+ virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
+ _("Unsupported <bandwidth> element in network '%s' "
+ "in portgroup '%s' with forward mode='%s'"),
+ def->name, def->portGroups[i].name,
+ virNetworkForwardTypeToString(def->forward.type));
+ return -1;
+ }
}
if (badVlanUse ||
(vlanUsed && !vlanAllowed && !defaultPortGroup)) {
--
2.0.4
9 years, 11 months
[libvirt] [PATCH 00/11] Post-Copy Live Migration Support
by Cristian Klein
Qemu currently implements pre-copy live migration. VM memory pages are
first copied from the source hypervisor to the destination, potentially
multiple times as pages get dirtied during transfer, then VCPU state
is migrated. Unfortunately, if the VM dirties memory faster than the
network bandwidth, then pre-copy cannot finish. `virsh` currently
includes an option to suspend a VM after a timeout, so that migration
may finish, but at the expense of downtime.
A future version of qemu will implement post-copy live migration. The
VCPU state is first migrated to the destination hypervisor, then
memory pages are pulled from the source hypervisor. Post-copy has the
potential to do migration with zero-downtime, despite the VM dirtying
pages fast, with minimum performance impact. On the other hand, while
post-copy is in progress, any network failure would render the VM
unusable, as its memory is partitioned between the source and
destination hypervisor. Therefore, post-copy should only be used when
necessary.
Post-copy migration in qemu will work as follows:
(1) The `x-postcopy-ram` migration capability needs to be set.
(2) Migration is started.
(3) When the user decides so, post-copy migration is activated by
sending the `migrate-start-postcopy` command.
(4) Qemu acknowledges by setting migration status to `postcopy-active`.
This patch series implements two ways to access post-copy functionality:
low-level and high-level. The low-level API implements a mechanism that
basically requires the libvirt user to manually go through the above
steps, by calling migration with `VIR_MIGRATE_ENABLE_POSTCOPY`, then
during migration from a separate thread, call
`virDomainMigrateStartPostCopy`. The choice of when migration should
switch from pre-copy to post-copy is left entirely to the user.
The high-level API implements a policy that automatically triggers post-copy
after one pass of pre-copy, which experiments have shown to minimize
downtime. Using it is also simpler: the user only has to call migration
with `VIR_MIGRATE_POSTCOPY_AFTER_PRECOPY`.
TODO:
- Wait for qemu API to become stable, i.e., drop `x-`
- Wait for qemu to offer notification for migration state change
v4:
- Rename low-level API flag to `VIR_MIGRATE_ENABLE_POSTCOPY`
- Added high-level API flag `VIR_MIGRATE_POSTCOPY_AFTER_PRECOPY`
- Do not introduce a new job type and use migration status instead
- Added both low- and high-level interface to virsh
- Tested with OpenStack Icehouse
Cristian Klein (11):
Added public API for post-copy migration
qemu: added low-level post-copy migration functions
qemu: implemented VIR_MIGRATE_ENABLE_POSTCOPY
qemu: implemented post-copy migration logic
qemu: implement virDomainMigrateStartPostCopy
virsh: added --enable-postcopy and migrate-start-postcopy
virsh: added --postcopy-after to migrate command
qemu: retrieve dirty sync count
qemu: implemented VIR_MIGRATE_POSTCOPY_AFTER_PRECOPY
virsh: added --postcopy-after-precopy to migrate
Revert "Do not allow changing the UUID of a nwfilter"
include/libvirt/libvirt-domain.h | 5 ++
src/conf/nwfilter_conf.c | 11 ---
src/driver-hypervisor.h | 5 ++
src/libvirt-domain.c | 92 +++++++++++++++++++++
src/libvirt_public.syms | 1 +
src/qemu/qemu_driver.c | 60 ++++++++++++++
src/qemu/qemu_migration.c | 169 +++++++++++++++++++++++++++++++++++++--
src/qemu/qemu_migration.h | 4 +-
src/qemu/qemu_monitor.c | 24 +++++-
src/qemu/qemu_monitor.h | 5 ++
src/qemu/qemu_monitor_json.c | 27 ++++++-
src/qemu/qemu_monitor_json.h | 1 +
src/qemu/qemu_monitor_text.c | 1 +
src/remote/remote_driver.c | 1 +
src/remote/remote_protocol.x | 12 ++-
src/remote_protocol-structs | 5 ++
tests/qemumonitorjsontest.c | 1 +
tools/virsh-domain.c | 116 ++++++++++++++++++++++++++-
tools/virsh.pod | 21 +++++
19 files changed, 536 insertions(+), 25 deletions(-)
--
1.9.1
9 years, 11 months
[libvirt] [PATCH] Report original error when QMP probing fails with new QEMU
by Daniel P. Berrange
If probing capabilities via QMP fails, we now have a check
that prevents us falling back to -help parsing. Unfortunately
the error message
"Failed to probe capabilities for /usr/bin/qemu-kvm:
unsupported configuration: QEMU 2.1.2 is too new for help parsing"
is proving rather unhelpful to the user. We need to be telling
them why QMP failed (the root cause), rather than they can't
use -help (the side effect).
To do this we should capture stderr during QMP probing, and
if -help parsing then sees a new QEMU version, we know that
QMP should have worked, and so we can show the messages from
stderr. The message thus becomes
"Failed to probe capabilities for /usr/bin/qemu-kvm:
internal error: QEMU / QMP failed: Could not access
KVM kernel module: No such file or directory
failed to initialize KVM: No such file or directory"
---
src/qemu/qemu_capabilities.c | 37 +++++++++++++++++++++++++++----------
src/qemu/qemu_capabilities.h | 3 ++-
src/qemu/qemu_process.c | 4 ++--
tests/qemuhelptest.c | 2 +-
4 files changed, 32 insertions(+), 14 deletions(-)
diff --git a/src/qemu/qemu_capabilities.c b/src/qemu/qemu_capabilities.c
index d2c046d..f777484 100644
--- a/src/qemu/qemu_capabilities.c
+++ b/src/qemu/qemu_capabilities.c
@@ -1331,7 +1331,8 @@ int virQEMUCapsParseHelpStr(const char *qemu,
unsigned int *version,
bool *is_kvm,
unsigned int *kvm_version,
- bool check_yajl)
+ bool check_yajl,
+ const char *qemuerr)
{
unsigned major, minor, micro;
const char *p = help;
@@ -1392,9 +1393,15 @@ int virQEMUCapsParseHelpStr(const char *qemu,
* using QMP probing.
*/
if (*version >= 1002000) {
- virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
- _("QEMU %u.%u.%u is too new for help parsing"),
- major, minor, micro);
+ if (qemuerr && *qemuerr) {
+ virReportError(VIR_ERR_INTERNAL_ERROR,
+ _("QEMU / QMP failed: %s"),
+ qemuerr);
+ } else {
+ virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
+ _("QEMU %u.%u.%u is too new for help parsing"),
+ major, minor, micro);
+ }
goto cleanup;
}
@@ -2967,7 +2974,7 @@ virQEMUCapsInitCached(virQEMUCapsPtr qemuCaps, const char *cacheDir)
#define QEMU_SYSTEM_PREFIX "qemu-system-"
static int
-virQEMUCapsInitHelp(virQEMUCapsPtr qemuCaps, uid_t runUid, gid_t runGid)
+virQEMUCapsInitHelp(virQEMUCapsPtr qemuCaps, uid_t runUid, gid_t runGid, const char *qemuerr)
{
virCommandPtr cmd = NULL;
bool is_kvm;
@@ -2998,7 +3005,8 @@ virQEMUCapsInitHelp(virQEMUCapsPtr qemuCaps, uid_t runUid, gid_t runGid)
&qemuCaps->version,
&is_kvm,
&qemuCaps->kvmVersion,
- false) < 0)
+ false,
+ qemuerr) < 0)
goto cleanup;
/* x86_64 and i686 support PCI-multibus on all machine types
@@ -3249,7 +3257,8 @@ static int
virQEMUCapsInitQMP(virQEMUCapsPtr qemuCaps,
const char *libDir,
uid_t runUid,
- gid_t runGid)
+ gid_t runGid,
+ char **qemuerr)
{
int ret = -1;
virCommandPtr cmd = NULL;
@@ -3311,13 +3320,16 @@ virQEMUCapsInitQMP(virQEMUCapsPtr qemuCaps,
virCommandSetGID(cmd, runGid);
virCommandSetUID(cmd, runUid);
+ virCommandSetErrorBuffer(cmd, qemuerr);
+
/* Log, but otherwise ignore, non-zero status. */
if (virCommandRun(cmd, &status) < 0)
goto cleanup;
if (status != 0) {
ret = 0;
- VIR_DEBUG("QEMU %s exited with status %d", qemuCaps->binary, status);
+ VIR_DEBUG("QEMU %s exited with status %d: %s",
+ qemuCaps->binary, status, *qemuerr);
goto cleanup;
}
@@ -3366,6 +3378,8 @@ virQEMUCapsInitQMP(virQEMUCapsPtr qemuCaps,
VIR_ERROR(_("Failed to kill process %lld: %s"),
(long long) pid,
virStrerror(errno, ebuf, sizeof(ebuf)));
+
+ VIR_FREE(*qemuerr);
}
if (pidfile) {
unlink(pidfile);
@@ -3406,6 +3420,7 @@ virQEMUCapsPtr virQEMUCapsNewForBinary(const char *binary,
virQEMUCapsPtr qemuCaps;
struct stat sb;
int rv;
+ char *qemuerr = NULL;
if (!(qemuCaps = virQEMUCapsNew()))
goto error;
@@ -3436,13 +3451,13 @@ virQEMUCapsPtr virQEMUCapsNewForBinary(const char *binary,
goto error;
if (rv == 0) {
- if (virQEMUCapsInitQMP(qemuCaps, libDir, runUid, runGid) < 0) {
+ if (virQEMUCapsInitQMP(qemuCaps, libDir, runUid, runGid, &qemuerr) < 0) {
virQEMUCapsLogProbeFailure(binary);
goto error;
}
if (!qemuCaps->usedQMP &&
- virQEMUCapsInitHelp(qemuCaps, runUid, runGid) < 0) {
+ virQEMUCapsInitHelp(qemuCaps, runUid, runGid, qemuerr) < 0) {
virQEMUCapsLogProbeFailure(binary);
goto error;
}
@@ -3451,9 +3466,11 @@ virQEMUCapsPtr virQEMUCapsNewForBinary(const char *binary,
goto error;
}
+ VIR_FREE(qemuerr);
return qemuCaps;
error:
+ VIR_FREE(qemuerr);
virObjectUnref(qemuCaps);
qemuCaps = NULL;
return NULL;
diff --git a/src/qemu/qemu_capabilities.h b/src/qemu/qemu_capabilities.h
index c5542d1..f53b8f4 100644
--- a/src/qemu/qemu_capabilities.h
+++ b/src/qemu/qemu_capabilities.h
@@ -308,7 +308,8 @@ int virQEMUCapsParseHelpStr(const char *qemu,
unsigned int *version,
bool *is_kvm,
unsigned int *kvm_version,
- bool check_yajl);
+ bool check_yajl,
+ const char *qemuerr);
/* Only for use by test suite */
int virQEMUCapsParseDeviceStr(virQEMUCapsPtr qemuCaps, const char *str);
diff --git a/src/qemu/qemu_process.c b/src/qemu/qemu_process.c
index a14b6f7..68777e8 100644
--- a/src/qemu/qemu_process.c
+++ b/src/qemu/qemu_process.c
@@ -3554,12 +3554,12 @@ qemuProcessReconnect(void *opaque)
struct qemuProcessReconnectData *data = opaque;
virQEMUDriverPtr driver = data->driver;
virDomainObjPtr obj = data->obj;
- qemuDomainObjPrivatePtr priv;
+ qemuDomainObjPrivatePtr priv = NULL;
virConnectPtr conn = data->conn;
struct qemuDomainJobObj oldjob;
int state;
int reason;
- virQEMUDriverConfigPtr cfg;
+ virQEMUDriverConfigPtr cfg = NULL;
size_t i;
int ret;
diff --git a/tests/qemuhelptest.c b/tests/qemuhelptest.c
index 0c68367..6d9525c 100644
--- a/tests/qemuhelptest.c
+++ b/tests/qemuhelptest.c
@@ -59,7 +59,7 @@ static int testHelpStrParsing(const void *data)
goto cleanup;
if (virQEMUCapsParseHelpStr("QEMU", help, flags,
- &version, &is_kvm, &kvm_version, false) == -1) {
+ &version, &is_kvm, &kvm_version, false, NULL) == -1) {
if (info->error && virGetLastError()->code == info->error)
ret = 0;
goto cleanup;
--
2.1.0
9 years, 11 months
[libvirt] [PATCH] docs: storage: fix rbd pool indentation
by Cole Robinson
---
Pushed as trivial
docs/storage.html.in | 12 ++++++------
1 file changed, 6 insertions(+), 6 deletions(-)
diff --git a/docs/storage.html.in b/docs/storage.html.in
index 9933548..f920dae 100644
--- a/docs/storage.html.in
+++ b/docs/storage.html.in
@@ -551,12 +551,12 @@
<name>myrbdpool</name>
<source>
<name>rbdpool</name>
- <host name='1.2.3.4' port='6789'/>
- <host name='my.ceph.monitor' port='6789'/>
- <host name='third.ceph.monitor' port='6789'/>
- <auth username='admin' type='ceph'>
- <secret uuid='2ec115d7-3a88-3ceb-bc12-0ac909a6fd87'/>
- </auth>
+ <host name='1.2.3.4' port='6789'/>
+ <host name='my.ceph.monitor' port='6789'/>
+ <host name='third.ceph.monitor' port='6789'/>
+ <auth username='admin' type='ceph'>
+ <secret uuid='2ec115d7-3a88-3ceb-bc12-0ac909a6fd87'/>
+ </auth>
</source>
</pool></pre>
--
2.1.0
9 years, 11 months