[libvirt] API Proposal: Block device streaming (V3)
by Adam Litke
Version 2 of the block device streaming API diverged significantly from the original API provided by Qemu. In an effort to provide an API that is designed to work well for the specific task of streaming data to a local device from its backing store I am proposing this: version 3 of the block device streaming API.
Some noteworthy changes from earlier versions:
The offset and length parameters to virDomainStream have been replaced by an iterator type. Manual specification of ranges is outside of the scope of the API and does not add utility. Instead, an iterator is used to perform a series of individual operations in an efficient manner without exposing device format particulars.
I have added a new call virDomainBlockStreamAbort() that can be used to cancel an active stream operation. This is an improvement over the use of flags to override the meaning of virDomainBlockStream().
Block devices are specified by the fully-qualified path to the source file. This information is easier for API users to provide than the block device alias.
All API functions return an int. Rather than returning an unsigned long long, virDomainBlockStream() updates the the iterator (which is passed in by reference) in place.
----- API V3 -----
/*
* Disk Streaming
*/
typedef enum {
/*
* If set, virDomainBlockStream() will begin streaming the entire device
* continuously. The status can be checked and the operation aborted by using
* the functions virDomainGetBlockStreamInfo() and virDomainBlockStreamAbort().
*/
VIR_DOMAIN_BLOCK_STREAM_CONTINUOUS = 1,
} virDomainStreamDiskFlags;
#define VIR_DOMAIN_BLOCK_STREAM_PATH_MAX 1024
/* An iterator for initiating and monitoring block streaming operations */
typedef unsigned long long virDomainBlockStreamCursor;
typedef struct _virDomainBlockStreamInfo virDomainBlockStreamInfo;
struct _virDomainBlockStreamInfo {
char path[VIR_DOMAIN_BLOCK_STREAM_PATH_MAX];
/*
* The following fields provide an indication of streaming progress. @cur
* indicates the current position and will be between 0 and @end. @end is
* the final cursor position for this operation and represents completion. To
* approximate progress, divide @cur by @end.
*/
virDomainBlockStreamCursor cur;
virDomainBlockStreamCursor end;
};
typedef virDomainBlockStreamInfo *virDomainBlockStreamInfoPtr;
/**
* virDomainBlockStream:
* @dom: pointer to domain object
* @path: Fully-qualified filename of disk
* @cursor: pointer to a virDomainBlockStreamCursor, or NULL
* @flags: One of virDomainStreamDiskFlags, or zero
*
* Initate a streaming operation on the named block device associated with the
* given domain. If VIR_DOMAIN_BLOCK_STREAM_CONTINUOUS is specified, the entire
* device will be streamed in the background. Otherwise, the value stored in
* cursor will be used to stream an increment.
*
* Returns -1 in case of failure, 0 when successful. On success and when @flags
* does not contain VIR_DOMAIN_BLOCK_STREAM_CONTINUOUS, the iterator @cursor will
* be updated to the proper value for use in a subsequent call.
*/
int virDomainBlockStream(virDomainPtr dom,
const char *path,
virDomainBlockStreamCursor *cursor,
unsigned int flags);
/**
* virDomainBlockStreamAbort:
* @dom: pointer to domain object
* @path: fully-qualified filename of disk
* @flags: currently unused, for future extension
*
* Cancel a disk streaming operation that has been previously started by a call to
* virDomainBlockStream() with the VIR_DOMAIN_BLOCK_STREAM_CONTINUOUS flag.
*
* Returns -1 in case of failure, 0 when successful.
*/
int virDomainBlockStreamAbort(virDomainPtr dom,
const char *path,
unsigned int flags);
/**
* virDomainGetBlockStreamInfo:
* @dom: pointer to domain object
* @info: pointer to an array of virDomainBlockStreamInfo objects
* @nr_results: Number of results requested
* @flags: currently unused, for future extension
*
* Request information on active block streaming operations for the given domain.
* The caller must supply an allocated array of virDomainBlockStreamInfo objects
* Information about up to @nr_results active streams will be stored in @info.
*
* Returns -1 in case of failure, or the number of results that were stored.
*/
int virDomainGetBlockStreamInfo(virDomainPtr dom,
virDomainBlockStreamInfoPtr info,
unsigned int nr_results,
unsigned int flags);
13 years, 7 months
[libvirt] [numatune PATCH v2] Support NUMA tuning
by Osier Yang
Hi, All
This series adopts Daniel's suggestion on v1, using libnuma but
not invoking numactl to set the NUMA policy. Add support for
"interleave" and "preferred" modes, except the "strict" mode
supported in v1.
The new XML is like:
<numatune>
<memory model="interleave" nodeset="+0-4,8-12"/>
<numatune>
I persist in using the numactl nodeset syntax to represent
the "nodeset", as I think the purpose of adding NUMA tuning
support is to provide the use for NUMA users, keeping the
syntax same as numactl will make them feel better.
Regards
Osier
[PATCH 1/4] numatune: Define XML schema and add docs
[PATCH 2/4] numatune: Support persistent XML for numa tuning
[PATCH 3/4] numatune: Set NUMA policy between fork and exec as a hook
[PATCH 4/4] numatune: Add tests to validate the persistent XML
13 years, 7 months
[libvirt] [PATCH 0/2] fix some migration's bug
by Wen Congyang
Wen Congyang (2):
avoid vm is deleted in qemuDomainMigrateConfirm3()
check whether the vm is paused before setting it offline
src/qemu/qemu_migration.c | 16 +++++++++-------
1 files changed, 9 insertions(+), 7 deletions(-)
13 years, 7 months
[libvirt] [PATCH v2] qemu: Add option to enable/disable IOEventFD feature
by Michal Privoznik
This feature allows QEMU to achieve higher throughput, but is available
only in recent versions. It is accessible via ioeventfd attribute
with accepting values 'on', 'off'. Only experienced users needs to set
this, because QEMU defaults to 'on', meaning higher performance.
Translates into virtio-{blk|net}-pci.ioeventfd option.
---
diff to v1:
- rebase to current HEAD
docs/formatdomain.html.in | 15 ++++++++++++-
docs/schemas/domain.rng | 14 +++++++++++++
src/conf/domain_conf.c | 44 +++++++++++++++++++++++++++++++++++++++++-
src/conf/domain_conf.h | 12 +++++++++++
src/libvirt_private.syms | 2 +
src/qemu/qemu_capabilities.c | 2 +
src/qemu/qemu_capabilities.h | 1 +
src/qemu/qemu_command.c | 23 +++++++++++++++++++++
tests/qemuhelptest.c | 3 +-
9 files changed, 112 insertions(+), 4 deletions(-)
diff --git a/docs/formatdomain.html.in b/docs/formatdomain.html.in
index 989dcf6..a4d7cbd 100644
--- a/docs/formatdomain.html.in
+++ b/docs/formatdomain.html.in
@@ -767,7 +767,7 @@
</disk>
...
<disk type='network'>
- <driver name="qemu" type="raw" io="threads"/>
+ <driver name="qemu" type="raw" io="threads" ioeventfd="on"/>
<source protocol="sheepdog" name="image_name">
<host name="hostname" port="7000"/>
</source>
@@ -851,6 +851,11 @@
policies on I/O; qemu guests support "threads" and
"native". <span class="since">Since 0.8.8</span>
</li>
+ <li>
+ The optional <code>ioeventfd</code> attribute enables or disables
+ IOEventFD feature for virtqueue notify. The value can be either
+ 'on' or 'off'.
+ <span class="since">Since 0.9.2 (QEMU and KVM only)</span>
</ul>
</dd>
<dt><code>boot</code></dt>
@@ -1585,7 +1590,7 @@ qemu-kvm -net nic,model=? /dev/null
<source network='default'/>
<target dev='vnet1'/>
<model type='virtio'/>
- <b><driver name='vhost' txmode='iothread'/></b>
+ <b><driver name='vhost' txmode='iothread' ioeventfd='on'/></b>
</interface>
</devices>
...</pre>
@@ -1636,6 +1641,12 @@ qemu-kvm -net nic,model=? /dev/null
<b>In general you should leave this option alone, unless you
are very certain you know what you are doing.</b>
</dd>
+ <dt><code>ioeventfd</code><code></dt>
+ <dd>
+ This optional attribute allows users to enable or disable IOeventFD
+ feature for virtqueue notify. The value can be either 'on' or 'off'.
+ <span class="since">Since 0.9.2 (QEMU and KVM only)</span>
+ </dd>
</dl>
<h5><a name="elementsNICSTargetOverride">Overriding the target element</a></h5>
diff --git a/docs/schemas/domain.rng b/docs/schemas/domain.rng
index 7163c6e..c3e8e15 100644
--- a/docs/schemas/domain.rng
+++ b/docs/schemas/domain.rng
@@ -735,6 +735,9 @@
<optional>
<ref name="driverIO"/>
</optional>
+ <optional>
+ <ref name="ioeventfd"/>
+ </optional>
<empty/>
</element>
</define>
@@ -774,6 +777,14 @@
</choice>
</attribute>
</define>
+ <define name="ioeventfd">
+ <attribute name="ioeventfd">
+ <choice>
+ <value>on</value>
+ <value>off</value>
+ </choice>
+ </attribute>
+ </define>
<define name="controller">
<element name="controller">
<choice>
@@ -1074,6 +1085,9 @@
</choice>
</attribute>
</optional>
+ <optional>
+ <ref name="ioeventfd"/>
+ </optional>
<empty/>
</element>
</optional>
diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c
index 498438a..2cb8d66 100644
--- a/src/conf/domain_conf.c
+++ b/src/conf/domain_conf.c
@@ -162,6 +162,11 @@ VIR_ENUM_IMPL(virDomainDiskIo, VIR_DOMAIN_DISK_IO_LAST,
"native",
"threads")
+VIR_ENUM_IMPL(virDomainVirtioEventFd, VIR_DOMAIN_VIRTIO_EVENT_FD_LAST,
+ "default",
+ "on",
+ "off")
+
VIR_ENUM_IMPL(virDomainController, VIR_DOMAIN_CONTROLLER_TYPE_LAST,
"ide",
"fdc",
@@ -1901,6 +1906,7 @@ virDomainDiskDefParseXML(virCapsPtr caps,
char *cachetag = NULL;
char *error_policy = NULL;
char *iotag = NULL;
+ char *ioeventfd = NULL;
char *devaddr = NULL;
virStorageEncryptionPtr encryption = NULL;
char *serial = NULL;
@@ -2016,6 +2022,7 @@ virDomainDiskDefParseXML(virCapsPtr caps,
cachetag = virXMLPropString(cur, "cache");
error_policy = virXMLPropString(cur, "error_policy");
iotag = virXMLPropString(cur, "io");
+ ioeventfd = virXMLPropString(cur, "ioeventfd");
} else if (xmlStrEqual(cur->name, BAD_CAST "readonly")) {
def->readonly = 1;
} else if (xmlStrEqual(cur->name, BAD_CAST "shareable")) {
@@ -2152,6 +2159,18 @@ virDomainDiskDefParseXML(virCapsPtr caps,
}
}
+ if (ioeventfd) {
+ int i;
+ if ((i = virDomainVirtioEventFdTypeFromString(ioeventfd)) <= 0) {
+ virDomainReportError(VIR_ERR_CONFIG_UNSUPPORTED,
+ _("unknown disk ioeventfd mode '%s'"),
+ ioeventfd);
+ goto error;
+ }
+ def->ioeventfd = i;
+ }
+
+
if (devaddr) {
if (virDomainParseLegacyDeviceAddress(devaddr,
&def->info.addr.pci) < 0) {
@@ -2214,6 +2233,7 @@ cleanup:
VIR_FREE(cachetag);
VIR_FREE(error_policy);
VIR_FREE(iotag);
+ VIR_FREE(ioeventfd);
VIR_FREE(devaddr);
VIR_FREE(serial);
virStorageEncryptionFree(encryption);
@@ -2601,6 +2621,7 @@ virDomainNetDefParseXML(virCapsPtr caps,
char *model = NULL;
char *backend = NULL;
char *txmode = NULL;
+ char *ioeventfd = NULL;
char *filter = NULL;
char *internal = NULL;
char *devaddr = NULL;
@@ -2690,6 +2711,7 @@ virDomainNetDefParseXML(virCapsPtr caps,
} else if (xmlStrEqual (cur->name, BAD_CAST "driver")) {
backend = virXMLPropString(cur, "name");
txmode = virXMLPropString(cur, "txmode");
+ ioeventfd = virXMLPropString(cur, "ioeventfd");
} else if (xmlStrEqual (cur->name, BAD_CAST "filterref")) {
filter = virXMLPropString(cur, "filter");
VIR_FREE(filterparams);
@@ -2906,6 +2928,17 @@ virDomainNetDefParseXML(virCapsPtr caps,
}
def->driver.virtio.txmode = m;
}
+ if (ioeventfd != NULL) {
+ int i;
+ if ((i = virDomainVirtioEventFdTypeFromString(ioeventfd)) <= 0) {
+ virDomainReportError(VIR_ERR_CONFIG_UNSUPPORTED,
+ _("unknown interface <driver "
+ "ioeventfd='%s'> has been specified"),
+ ioeventfd);
+ goto error;
+ }
+ def->driver.virtio.ioeventfd = i;
+ }
}
if (filter != NULL) {
@@ -2945,6 +2978,7 @@ cleanup:
VIR_FREE(model);
VIR_FREE(backend);
VIR_FREE(txmode);
+ VIR_FREE(ioeventfd);
VIR_FREE(filter);
VIR_FREE(type);
VIR_FREE(internal);
@@ -7006,6 +7040,7 @@ virDomainDiskDefFormat(virBufferPtr buf,
const char *cachemode = virDomainDiskCacheTypeToString(def->cachemode);
const char *error_policy = virDomainDiskErrorPolicyTypeToString(def->error_policy);
const char *iomode = virDomainDiskIoTypeToString(def->iomode);
+ const char *ioeventfd = virDomainVirtioEventFdTypeToString(def->ioeventfd);
if (!type) {
virDomainReportError(VIR_ERR_INTERNAL_ERROR,
@@ -7037,7 +7072,8 @@ virDomainDiskDefFormat(virBufferPtr buf,
" <disk type='%s' device='%s'>\n",
type, device);
- if (def->driverName || def->driverType || def->cachemode) {
+ if (def->driverName || def->driverType || def->cachemode ||
+ def->ioeventfd) {
virBufferAsprintf(buf, " <driver");
if (def->driverName)
virBufferAsprintf(buf, " name='%s'", def->driverName);
@@ -7049,6 +7085,8 @@ virDomainDiskDefFormat(virBufferPtr buf,
virBufferAsprintf(buf, " error_policy='%s'", error_policy);
if (def->iomode)
virBufferAsprintf(buf, " io='%s'", iomode);
+ if (def->ioeventfd)
+ virBufferAsprintf(buf, " ioeventfd='%s'", ioeventfd);
virBufferAsprintf(buf, "/>\n");
}
@@ -7339,6 +7377,10 @@ virDomainNetDefFormat(virBufferPtr buf,
virBufferAsprintf(buf, " txmode='%s'",
virDomainNetVirtioTxModeTypeToString(def->driver.virtio.txmode));
}
+ if (def->driver.virtio.ioeventfd) {
+ virBufferAsprintf(buf, " ioeventfd='%s'",
+ virDomainVirtioEventFdTypeToString(def->driver.virtio.ioeventfd));
+ }
virBufferAddLit(buf, "/>\n");
}
}
diff --git a/src/conf/domain_conf.h b/src/conf/domain_conf.h
index fe42f21..d6b4002 100644
--- a/src/conf/domain_conf.h
+++ b/src/conf/domain_conf.h
@@ -197,6 +197,15 @@ enum virDomainDiskIo {
VIR_DOMAIN_DISK_IO_LAST
};
+enum virDomainVirtioEventFd {
+ VIR_DOMAIN_VIRTIO_EVENT_FD_DEFAULT = 0,
+ VIR_DOMAIN_VIRTIO_EVENT_FD_ON,
+ VIR_DOMAIN_VIRTIO_EVENT_FD_OFF,
+
+ VIR_DOMAIN_VIRTIO_EVENT_FD_LAST
+};
+
+
/* Stores the virtual disk configuration */
typedef struct _virDomainDiskDef virDomainDiskDef;
typedef virDomainDiskDef *virDomainDiskDefPtr;
@@ -216,6 +225,7 @@ struct _virDomainDiskDef {
int error_policy;
int bootIndex;
int iomode;
+ enum virDomainVirtioEventFd ioeventfd;
unsigned int readonly : 1;
unsigned int shared : 1;
virDomainDeviceInfo info;
@@ -351,6 +361,7 @@ struct _virDomainNetDef {
struct {
enum virDomainNetBackendType name; /* which driver backend to use */
enum virDomainNetVirtioTxModeType txmode;
+ enum virDomainVirtioEventFd ioeventfd;
} virtio;
} driver;
union {
@@ -1473,6 +1484,7 @@ VIR_ENUM_DECL(virDomainDiskCache)
VIR_ENUM_DECL(virDomainDiskErrorPolicy)
VIR_ENUM_DECL(virDomainDiskProtocol)
VIR_ENUM_DECL(virDomainDiskIo)
+VIR_ENUM_DECL(virDomainVirtioEventFd)
VIR_ENUM_DECL(virDomainController)
VIR_ENUM_DECL(virDomainControllerModel)
VIR_ENUM_DECL(virDomainFS)
diff --git a/src/libvirt_private.syms b/src/libvirt_private.syms
index acd5af3..cdf1ccb 100644
--- a/src/libvirt_private.syms
+++ b/src/libvirt_private.syms
@@ -351,6 +351,8 @@ virDomainVideoDefaultType;
virDomainVideoTypeFromString;
virDomainVideoTypeToString;
virDomainVirtTypeToString;
+virDomainVirtioEventFdTypeFromString;
+virDomainVirtioEventFdTypeToString;
virDomainWatchdogActionTypeFromString;
virDomainWatchdogActionTypeToString;
virDomainWatchdogModelTypeFromString;
diff --git a/src/qemu/qemu_capabilities.c b/src/qemu/qemu_capabilities.c
index ea55df5..1cd7aa7 100644
--- a/src/qemu/qemu_capabilities.c
+++ b/src/qemu/qemu_capabilities.c
@@ -1202,6 +1202,8 @@ qemuCapsParseDeviceStr(const char *str, virBitmapPtr flags)
qemuCapsSet(flags, QEMU_CAPS_VIRTIO_TX_ALG);
if (strstr(str, "name \"qxl-vga\""))
qemuCapsSet(flags, QEMU_CAPS_DEVICE_QXL_VGA);
+ if (strstr(str, "virtio-blk-pci.ioeventfd"))
+ qemuCapsSet(flags, QEMU_CAPS_VIRTIO_IOEVENTFD);
return 0;
}
diff --git a/src/qemu/qemu_capabilities.h b/src/qemu/qemu_capabilities.h
index ab47f22..56f3998 100644
--- a/src/qemu/qemu_capabilities.h
+++ b/src/qemu/qemu_capabilities.h
@@ -95,6 +95,7 @@ enum qemuCapsFlags {
QEMU_CAPS_DEVICE_SPICEVMC = 57, /* older -device spicevmc*/
QEMU_CAPS_VIRTIO_TX_ALG = 58, /* -device virtio-net-pci,tx=string */
QEMU_CAPS_DEVICE_QXL_VGA = 59, /* Is the primary and vga campatible qxl device named qxl-vga? */
+ QEMU_CAPS_VIRTIO_IOEVENTFD = 60, /* IOEventFD feature: virtio-{net|blk}-pci.ioeventfd=on/off */
QEMU_CAPS_LAST, /* this must always be the last item */
};
diff --git a/src/qemu/qemu_command.c b/src/qemu/qemu_command.c
index 2828823..0729664 100644
--- a/src/qemu/qemu_command.c
+++ b/src/qemu/qemu_command.c
@@ -1169,6 +1169,26 @@ qemuBuildDeviceAddressStr(virBufferPtr buf,
return 0;
}
+static int
+qemuBuildIoEventFdStr(virBufferPtr buf,
+ enum virDomainVirtioEventFd use,
+ virBitmapPtr qemuCaps)
+{
+ if (qemuCapsGet(qemuCaps, QEMU_CAPS_VIRTIO_IOEVENTFD)) {
+ switch (use) {
+ case VIR_DOMAIN_VIRTIO_EVENT_FD_ON:
+ case VIR_DOMAIN_VIRTIO_EVENT_FD_OFF:
+ virBufferAsprintf(buf, ",ioeventfd=%s",
+ virDomainVirtioEventFdTypeToString(use));
+ break;
+ default:
+ /* In other cases (_DEFAULT, _LAST) we don't
+ * want to add anything */
+ break;
+ }
+ }
+ return 0;
+}
#define QEMU_SERIAL_PARAM_ACCEPTED_CHARS \
"abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789-_"
@@ -1434,6 +1454,7 @@ qemuBuildDriveDevStr(virDomainDiskDefPtr disk,
break;
case VIR_DOMAIN_DISK_BUS_VIRTIO:
virBufferAddLit(&opt, "virtio-blk-pci");
+ qemuBuildIoEventFdStr(&opt, disk->ioeventfd, qemuCaps);
qemuBuildDeviceAddressStr(&opt, &disk->info, qemuCaps);
break;
case VIR_DOMAIN_DISK_BUS_USB:
@@ -1656,6 +1677,8 @@ qemuBuildNicDevStr(virDomainNetDefPtr net,
goto error;
}
}
+ if(usingVirtio)
+ qemuBuildIoEventFdStr(&buf, net->driver.virtio.ioeventfd, qemuCaps);
if (vlan == -1)
virBufferAsprintf(&buf, ",netdev=host%s", net->info.alias);
else
diff --git a/tests/qemuhelptest.c b/tests/qemuhelptest.c
index 2522396..387f46c 100644
--- a/tests/qemuhelptest.c
+++ b/tests/qemuhelptest.c
@@ -474,7 +474,8 @@ mymain(void)
QEMU_CAPS_CCID_PASSTHRU,
QEMU_CAPS_CHARDEV_SPICEVMC,
QEMU_CAPS_DEVICE_QXL_VGA,
- QEMU_CAPS_VIRTIO_TX_ALG);
+ QEMU_CAPS_VIRTIO_TX_ALG,
+ QEMU_CAPS_VIRTIO_IOEVENTFD);
return ret == 0 ? EXIT_SUCCESS : EXIT_FAILURE;
}
--
1.7.5.rc3
13 years, 7 months
[libvirt] [PATCHv2 0/6] flush my patch queue
by Eric Blake
I've been building up a grab bag of un-acked patches (a couple
have had reviews, but most have met list silence), so I figured
a repost would help.
Eric Blake (6):
build: update to latest gnulib
build: require newer gettext
virsh: optimize creation of default connection
build: make python optional at configure time
build: silence clang false positive
remote: remove special case for getting version
.gnulib | 2 +-
bootstrap | 12 +-
bootstrap.conf | 2 +-
configure.ac | 37 +++--
daemon/remote_generator.pl | 23 +--
src/libxl/libxl_driver.c | 2 +
src/remote/remote_protocol.x | 4 +-
src/remote_protocol-structs | 4 +-
tools/virsh.c | 429 ++++++++++++++++++++++++------------------
9 files changed, 299 insertions(+), 216 deletions(-)
--
1.7.4.4
13 years, 7 months
[libvirt] [PATCH] Fix QEMU -vnc arg generation with raw IPv6 addresses
by Daniel P. Berrange
Since -vnc uses ':' to separate the address from the port, raw
IPv6 addresses need to be escaped like [addr]:port
* src/qemu/qemu_command.c: Escape raw IPv6 addresses with []
* tests/qemuxml2argvdata/qemuxml2argv-graphics-vnc.args,
tests/qemuxml2argvdata/qemuxml2argv-graphics-vnc.xml: Tweak
to test Ipv6 escaping
---
src/qemu/qemu_command.c | 63 ++++++++++++-------
.../qemuxml2argv-graphics-vnc.args | 2 +-
.../qemuxml2argvdata/qemuxml2argv-graphics-vnc.xml | 2 +-
3 files changed, 42 insertions(+), 25 deletions(-)
diff --git a/src/qemu/qemu_command.c b/src/qemu/qemu_command.c
index 2828823..6fa401f 100644
--- a/src/qemu/qemu_command.c
+++ b/src/qemu/qemu_command.c
@@ -3893,11 +3893,14 @@ qemuBuildCommandLine(virConnectPtr conn,
def->graphics[0]->data.vnc.socket);
} else if (qemuCapsGet(qemuCaps, QEMU_CAPS_VNC_COLON)) {
- if (def->graphics[0]->data.vnc.listenAddr)
- virBufferAdd(&opt, def->graphics[0]->data.vnc.listenAddr, -1);
- else if (driver->vncListen)
- virBufferAdd(&opt, driver->vncListen, -1);
-
+ const char *addr = def->graphics[0]->data.vnc.listenAddr ?
+ def->graphics[0]->data.vnc.listenAddr :
+ driver->vncListen;
+ bool escapeAddr = strchr(addr, ':');
+ if (escapeAddr)
+ virBufferAsprintf(&opt, "[%s]", addr);
+ else
+ virBufferAdd(&opt, addr, -1);
virBufferAsprintf(&opt, ":%d",
def->graphics[0]->data.vnc.port - 5900);
@@ -5734,32 +5737,46 @@ virDomainDefPtr qemuParseCommandLine(virCapsPtr caps,
vnc->type = VIR_DOMAIN_GRAPHICS_TYPE_VNC;
if (STRPREFIX(val, "unix:")) {
+ /* -vnc unix:/some/big/path */
vnc->data.vnc.socket = strdup(val + 5);
if (!vnc->data.vnc.socket) {
VIR_FREE(vnc);
goto no_memory;
}
} else {
- tmp = strchr(val, ':');
- if (tmp) {
- char *opts;
- if (virStrToLong_i(tmp+1, &opts, 10,
- &vnc->data.vnc.port) < 0) {
- VIR_FREE(vnc);
- qemuReportError(VIR_ERR_INTERNAL_ERROR,
- _("cannot parse VNC port '%s'"), tmp+1);
- goto error;
- }
+ /*
+ * -vnc 127.0.0.1:4
+ * -vnc [2001:1:2:3:4:5:1234:1234]:4
+ * -vnc some.host.name:4
+ */
+ char *opts;
+ const char *sep = ":";
+ if (val[0] == '[')
+ sep = "]:";
+ tmp = strstr(val, sep);
+ if (!tmp) {
+ VIR_FREE(vnc);
+ qemuReportError(VIR_ERR_INTERNAL_ERROR,
+ _("missing VNC port number in '%s'"), val);
+ goto error;
+ }
+ if (virStrToLong_i(tmp+strlen(sep), &opts, 10,
+ &vnc->data.vnc.port) < 0) {
+ VIR_FREE(vnc);
+ qemuReportError(VIR_ERR_INTERNAL_ERROR,
+ _("cannot parse VNC port '%s'"), tmp+1);
+ goto error;
+ }
+ if (val[0] == '[')
+ vnc->data.vnc.listenAddr = strndup(val+1, tmp-(val+1));
+ else
vnc->data.vnc.listenAddr = strndup(val, tmp-val);
- if (!vnc->data.vnc.listenAddr) {
- VIR_FREE(vnc);
- goto no_memory;
- }
- vnc->data.vnc.port += 5900;
- vnc->data.vnc.autoport = 0;
- } else {
- vnc->data.vnc.autoport = 1;
+ if (!vnc->data.vnc.listenAddr) {
+ VIR_FREE(vnc);
+ goto no_memory;
}
+ vnc->data.vnc.port += 5900;
+ vnc->data.vnc.autoport = 0;
}
if (VIR_REALLOC_N(def->graphics, def->ngraphics+1) < 0) {
diff --git a/tests/qemuxml2argvdata/qemuxml2argv-graphics-vnc.args b/tests/qemuxml2argvdata/qemuxml2argv-graphics-vnc.args
index 13aa138..2af1540 100644
--- a/tests/qemuxml2argvdata/qemuxml2argv-graphics-vnc.args
+++ b/tests/qemuxml2argvdata/qemuxml2argv-graphics-vnc.args
@@ -1,4 +1,4 @@
LC_ALL=C PATH=/bin HOME=/home/test USER=test LOGNAME=test QEMU_AUDIO_DRV=none \
/usr/bin/qemu -S -M pc -m 214 -smp 1 -monitor unix:/tmp/test-monitor,server,\
nowait -no-acpi -boot c -hda /dev/HostVG/QEMUGuest1 -net none -serial none \
--parallel none -usb -vnc 127.0.0.1:3
+-parallel none -usb -vnc [2001:1:2:3:4:5:1234:1234]:3
diff --git a/tests/qemuxml2argvdata/qemuxml2argv-graphics-vnc.xml b/tests/qemuxml2argvdata/qemuxml2argv-graphics-vnc.xml
index eb6be7d..6304104 100644
--- a/tests/qemuxml2argvdata/qemuxml2argv-graphics-vnc.xml
+++ b/tests/qemuxml2argvdata/qemuxml2argv-graphics-vnc.xml
@@ -21,7 +21,7 @@
</disk>
<controller type='ide' index='0'/>
<input type='mouse' bus='ps2'/>
- <graphics type='vnc' port='5903' autoport='no' listen='127.0.0.1'/>
+ <graphics type='vnc' port='5903' autoport='no' listen='2001:1:2:3:4:5:1234:1234'/>
<video>
<model type='cirrus' vram='9216' heads='1'/>
</video>
--
1.7.4.4
13 years, 7 months
[libvirt] [PATCH 1/4] Fix error messages codes when TypeFromString fails
by Michal Privoznik
---
src/conf/cpu_conf.c | 4 +-
src/conf/domain_conf.c | 100 ++++++++++++++++++-----------------
src/conf/interface_conf.c | 2 +-
src/conf/network_conf.c | 2 +-
src/conf/node_device_conf.c | 4 +-
src/conf/nwfilter_conf.c | 6 +-
src/conf/secret_conf.c | 2 +-
src/conf/storage_conf.c | 2 +-
src/conf/storage_encryption_conf.c | 4 +-
9 files changed, 64 insertions(+), 62 deletions(-)
diff --git a/src/conf/cpu_conf.c b/src/conf/cpu_conf.c
index 98d598a..5b7b363 100644
--- a/src/conf/cpu_conf.c
+++ b/src/conf/cpu_conf.c
@@ -156,7 +156,7 @@ virCPUDefParseXML(const xmlNodePtr node,
VIR_FREE(match);
if (def->match < 0) {
- virCPUReportError(VIR_ERR_INTERNAL_ERROR,
+ virCPUReportError(VIR_ERR_CONFIG_UNSUPPORTED,
"%s", _("Invalid match attribute for CPU specification"));
goto error;
}
@@ -257,7 +257,7 @@ virCPUDefParseXML(const xmlNodePtr node,
VIR_FREE(strpolicy);
if (policy < 0) {
- virCPUReportError(VIR_ERR_INTERNAL_ERROR,
+ virCPUReportError(VIR_ERR_CONFIG_UNSUPPORTED,
"%s", _("Invalid CPU feature policy"));
goto error;
}
diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c
index 3298c80..e7e265c 100644
--- a/src/conf/domain_conf.c
+++ b/src/conf/domain_conf.c
@@ -1707,7 +1707,7 @@ virDomainDeviceInfoParseXML(xmlNodePtr node,
if (type) {
if ((info->type = virDomainDeviceAddressTypeFromString(type)) < 0) {
- virDomainReportError(VIR_ERR_INTERNAL_ERROR,
+ virDomainReportError(VIR_ERR_CONFIG_UNSUPPORTED,
_("unknown address type '%s'"), type);
goto cleanup;
}
@@ -1914,7 +1914,7 @@ virDomainDiskDefParseXML(virCapsPtr caps,
type = virXMLPropString(node, "type");
if (type) {
if ((def->type = virDomainDiskTypeFromString(type)) < 0) {
- virDomainReportError(VIR_ERR_INTERNAL_ERROR,
+ virDomainReportError(VIR_ERR_CONFIG_UNSUPPORTED,
_("unknown disk type '%s'"), type);
goto error;
}
@@ -1947,7 +1947,7 @@ virDomainDiskDefParseXML(virCapsPtr caps,
}
def->protocol = virDomainDiskProtocolTypeFromString(protocol);
if (def->protocol < 0) {
- virDomainReportError(VIR_ERR_INTERNAL_ERROR,
+ virDomainReportError(VIR_ERR_CONFIG_UNSUPPORTED,
_("unknown protocol type '%s'"),
protocol);
goto error;
@@ -2046,7 +2046,7 @@ virDomainDiskDefParseXML(virCapsPtr caps,
device = virXMLPropString(node, "device");
if (device) {
if ((def->device = virDomainDiskDeviceTypeFromString(device)) < 0) {
- virDomainReportError(VIR_ERR_INTERNAL_ERROR,
+ virDomainReportError(VIR_ERR_CONFIG_UNSUPPORTED,
_("unknown disk device '%s'"), device);
goto error;
}
@@ -2094,7 +2094,7 @@ virDomainDiskDefParseXML(virCapsPtr caps,
if (bus) {
if ((def->bus = virDomainDiskBusTypeFromString(bus)) < 0) {
- virDomainReportError(VIR_ERR_INTERNAL_ERROR,
+ virDomainReportError(VIR_ERR_CONFIG_UNSUPPORTED,
_("unknown disk bus type '%s'"), bus);
goto error;
}
@@ -2132,14 +2132,14 @@ virDomainDiskDefParseXML(virCapsPtr caps,
if (cachetag &&
(def->cachemode = virDomainDiskCacheTypeFromString(cachetag)) < 0) {
- virDomainReportError(VIR_ERR_INTERNAL_ERROR,
+ virDomainReportError(VIR_ERR_CONFIG_UNSUPPORTED,
_("unknown disk cache mode '%s'"), cachetag);
goto error;
}
if (error_policy &&
(def->error_policy = virDomainDiskErrorPolicyTypeFromString(error_policy)) < 0) {
- virDomainReportError(VIR_ERR_INTERNAL_ERROR,
+ virDomainReportError(VIR_ERR_CONFIG_UNSUPPORTED,
_("unknown disk error policy '%s'"), error_policy);
goto error;
}
@@ -2147,7 +2147,7 @@ virDomainDiskDefParseXML(virCapsPtr caps,
if (iotag) {
if ((def->iomode = virDomainDiskIoTypeFromString(iotag)) < 0 ||
def->iomode == VIR_DOMAIN_DISK_IO_DEFAULT) {
- virDomainReportError(VIR_ERR_INTERNAL_ERROR,
+ virDomainReportError(VIR_ERR_CONFIG_UNSUPPORTED,
_("unknown disk io mode '%s'"), iotag);
goto error;
}
@@ -2251,7 +2251,7 @@ virDomainControllerDefParseXML(xmlNodePtr node,
type = virXMLPropString(node, "type");
if (type) {
if ((def->type = virDomainControllerTypeFromString(type)) < 0) {
- virDomainReportError(VIR_ERR_INTERNAL_ERROR,
+ virDomainReportError(VIR_ERR_CONFIG_UNSUPPORTED,
_("Unknown controller type '%s'"), type);
goto error;
}
@@ -2269,7 +2269,7 @@ virDomainControllerDefParseXML(xmlNodePtr node,
model = virXMLPropString(node, "model");
if (model) {
if ((def->model = virDomainControllerModelTypeFromString(model)) < 0) {
- virDomainReportError(VIR_ERR_INTERNAL_ERROR,
+ virDomainReportError(VIR_ERR_CONFIG_UNSUPPORTED,
_("Unknown model type '%s'"), model);
goto error;
}
@@ -2359,7 +2359,7 @@ virDomainFSDefParseXML(xmlNodePtr node,
type = virXMLPropString(node, "type");
if (type) {
if ((def->type = virDomainFSTypeFromString(type)) < 0) {
- virDomainReportError(VIR_ERR_INTERNAL_ERROR,
+ virDomainReportError(VIR_ERR_CONFIG_UNSUPPORTED,
_("unknown filesystem type '%s'"), type);
goto error;
}
@@ -2370,7 +2370,7 @@ virDomainFSDefParseXML(xmlNodePtr node,
accessmode = virXMLPropString(node, "accessmode");
if (accessmode) {
if ((def->accessmode = virDomainFSAccessModeTypeFromString(accessmode)) < 0) {
- virDomainReportError(VIR_ERR_INTERNAL_ERROR,
+ virDomainReportError(VIR_ERR_CONFIG_UNSUPPORTED,
_("unknown accessmode '%s'"), accessmode);
goto error;
}
@@ -2622,7 +2622,7 @@ virDomainNetDefParseXML(virCapsPtr caps,
type = virXMLPropString(node, "type");
if (type != NULL) {
if ((int)(def->type = virDomainNetTypeFromString(type)) < 0) {
- virDomainReportError(VIR_ERR_INTERNAL_ERROR,
+ virDomainReportError(VIR_ERR_CONFIG_UNSUPPORTED,
_("unknown interface type '%s'"), type);
goto error;
}
@@ -2834,7 +2834,7 @@ virDomainNetDefParseXML(virCapsPtr caps,
if (mode != NULL) {
int m;
if ((m = virDomainNetdevMacvtapTypeFromString(mode)) < 0) {
- virDomainReportError(VIR_ERR_INTERNAL_ERROR, "%s",
+ virDomainReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
_("Unkown mode has been specified"));
goto error;
}
@@ -2887,7 +2887,7 @@ virDomainNetDefParseXML(virCapsPtr caps,
int name;
if (((name = virDomainNetBackendTypeFromString(backend)) < 0) ||
(name == VIR_DOMAIN_NET_BACKEND_TYPE_DEFAULT)) {
- virDomainReportError(VIR_ERR_INTERNAL_ERROR,
+ virDomainReportError(VIR_ERR_CONFIG_UNSUPPORTED,
_("Unknown interface <driver name='%s'> "
"has been specified"),
backend);
@@ -2899,7 +2899,7 @@ virDomainNetDefParseXML(virCapsPtr caps,
int m;
if (((m = virDomainNetVirtioTxModeTypeFromString(txmode)) < 0) ||
(m == VIR_DOMAIN_NET_VIRTIO_TX_MODE_DEFAULT)) {
- virDomainReportError(VIR_ERR_INTERNAL_ERROR,
+ virDomainReportError(VIR_ERR_CONFIG_UNSUPPORTED,
_("Unknown interface <driver txmode='%s'> "
"has been specified"),
txmode);
@@ -3037,6 +3037,8 @@ virDomainChrDefParseTargetXML(virCapsPtr caps,
if ((def->targetType =
virDomainChrTargetTypeFromString(caps,
def->deviceType, targetType)) < 0) {
+ virDomainReportError(VIR_ERR_CONFIG_UNSUPPORTED,
+ _("unknown type %s"), targetType);
goto error;
}
@@ -3259,7 +3261,7 @@ virDomainChrSourceDefParseXML(virDomainChrSourceDefPtr def,
def->data.tcp.protocol = VIR_DOMAIN_CHR_TCP_PROTOCOL_RAW;
else if ((def->data.tcp.protocol =
virDomainChrTcpProtocolTypeFromString(protocol)) < 0) {
- virDomainReportError(VIR_ERR_INTERNAL_ERROR,
+ virDomainReportError(VIR_ERR_CONFIG_UNSUPPORTED,
_("Unknown protocol '%s'"), protocol);
goto error;
}
@@ -3386,7 +3388,7 @@ virDomainChrDefParseXML(virCapsPtr caps,
if (type == NULL) {
def->source.type = VIR_DOMAIN_CHR_TYPE_PTY;
} else if ((def->source.type = virDomainChrTypeFromString(type)) < 0) {
- virDomainReportError(VIR_ERR_XML_ERROR,
+ virDomainReportError(VIR_ERR_CONFIG_UNSUPPORTED,
_("unknown type presented to host for character device: %s"),
type);
goto error;
@@ -3394,7 +3396,7 @@ virDomainChrDefParseXML(virCapsPtr caps,
nodeName = (const char *) node->name;
if ((def->deviceType = virDomainChrDeviceTypeFromString(nodeName)) < 0) {
- virDomainReportError(VIR_ERR_XML_ERROR,
+ virDomainReportError(VIR_ERR_CONFIG_UNSUPPORTED,
_("unknown character device type: %s"),
nodeName);
}
@@ -3464,7 +3466,7 @@ virDomainSmartcardDefParseXML(xmlNodePtr node,
goto error;
}
if ((def->type = virDomainSmartcardTypeFromString(mode)) < 0) {
- virDomainReportError(VIR_ERR_XML_ERROR,
+ virDomainReportError(VIR_ERR_CONFIG_UNSUPPORTED,
_("unknown smartcard device mode: %s"),
mode);
goto error;
@@ -3526,7 +3528,7 @@ virDomainSmartcardDefParseXML(xmlNodePtr node,
goto error;
}
if ((def->data.passthru.type = virDomainChrTypeFromString(type)) < 0) {
- virDomainReportError(VIR_ERR_XML_ERROR,
+ virDomainReportError(VIR_ERR_CONFIG_UNSUPPORTED,
_("unknown type presented to host for "
"character device: %s"), type);
goto error;
@@ -3594,14 +3596,14 @@ virDomainInputDefParseXML(const char *ostype,
}
if ((def->type = virDomainInputTypeFromString(type)) < 0) {
- virDomainReportError(VIR_ERR_INTERNAL_ERROR,
+ virDomainReportError(VIR_ERR_CONFIG_UNSUPPORTED,
_("unknown input device type '%s'"), type);
goto error;
}
if (bus) {
if ((def->bus = virDomainInputBusTypeFromString(bus)) < 0) {
- virDomainReportError(VIR_ERR_INTERNAL_ERROR,
+ virDomainReportError(VIR_ERR_CONFIG_UNSUPPORTED,
_("unknown input bus type '%s'"), bus);
goto error;
}
@@ -3691,7 +3693,7 @@ virDomainTimerDefParseXML(const xmlNodePtr node,
goto error;
}
if ((def->name = virDomainTimerNameTypeFromString(name)) < 0) {
- virDomainReportError(VIR_ERR_INTERNAL_ERROR,
+ virDomainReportError(VIR_ERR_CONFIG_UNSUPPORTED,
_("unknown timer name '%s'"), name);
goto error;
}
@@ -3713,7 +3715,7 @@ virDomainTimerDefParseXML(const xmlNodePtr node,
tickpolicy = virXMLPropString(node, "tickpolicy");
if (tickpolicy != NULL) {
if ((def->tickpolicy = virDomainTimerTickpolicyTypeFromString(tickpolicy)) < 0) {
- virDomainReportError(VIR_ERR_INTERNAL_ERROR,
+ virDomainReportError(VIR_ERR_CONFIG_UNSUPPORTED,
_("unknown timer tickpolicy '%s'"), tickpolicy);
goto error;
}
@@ -3723,7 +3725,7 @@ virDomainTimerDefParseXML(const xmlNodePtr node,
track = virXMLPropString(node, "track");
if (track != NULL) {
if ((def->track = virDomainTimerTrackTypeFromString(track)) < 0) {
- virDomainReportError(VIR_ERR_INTERNAL_ERROR,
+ virDomainReportError(VIR_ERR_CONFIG_UNSUPPORTED,
_("unknown timer track '%s'"), track);
goto error;
}
@@ -3742,7 +3744,7 @@ virDomainTimerDefParseXML(const xmlNodePtr node,
mode = virXMLPropString(node, "mode");
if (mode != NULL) {
if ((def->mode = virDomainTimerModeTypeFromString(mode)) < 0) {
- virDomainReportError(VIR_ERR_INTERNAL_ERROR,
+ virDomainReportError(VIR_ERR_CONFIG_UNSUPPORTED,
_("unknown timer mode '%s'"), mode);
goto error;
}
@@ -3863,7 +3865,7 @@ virDomainGraphicsDefParseXML(xmlNodePtr node, int flags) {
}
if ((def->type = virDomainGraphicsTypeFromString(type)) < 0) {
- virDomainReportError(VIR_ERR_INTERNAL_ERROR,
+ virDomainReportError(VIR_ERR_CONFIG_UNSUPPORTED,
_("unknown graphics device type '%s'"), type);
goto error;
}
@@ -4052,7 +4054,7 @@ virDomainGraphicsDefParseXML(xmlNodePtr node, int flags) {
}
if ((nameval = virDomainGraphicsSpiceChannelNameTypeFromString(name)) < 0) {
- virDomainReportError(VIR_ERR_INTERNAL_ERROR,
+ virDomainReportError(VIR_ERR_CONFIG_UNSUPPORTED,
_("unknown spice channel name %s"),
name);
VIR_FREE(name);
@@ -4060,7 +4062,7 @@ virDomainGraphicsDefParseXML(xmlNodePtr node, int flags) {
goto error;
}
if ((modeval = virDomainGraphicsSpiceChannelModeTypeFromString(mode)) < 0) {
- virDomainReportError(VIR_ERR_INTERNAL_ERROR,
+ virDomainReportError(VIR_ERR_CONFIG_UNSUPPORTED,
_("unknown spice channel mode %s"),
mode);
VIR_FREE(name);
@@ -4187,7 +4189,7 @@ virDomainSoundDefParseXML(const xmlNodePtr node,
model = virXMLPropString(node, "model");
if ((def->model = virDomainSoundModelTypeFromString(model)) < 0) {
- virDomainReportError(VIR_ERR_INTERNAL_ERROR,
+ virDomainReportError(VIR_ERR_CONFIG_UNSUPPORTED,
_("unknown sound model '%s'"), model);
goto error;
}
@@ -4229,7 +4231,7 @@ virDomainWatchdogDefParseXML(const xmlNodePtr node,
}
def->model = virDomainWatchdogModelTypeFromString (model);
if (def->model < 0) {
- virDomainReportError(VIR_ERR_INTERNAL_ERROR,
+ virDomainReportError(VIR_ERR_CONFIG_UNSUPPORTED,
_("unknown watchdog model '%s'"), model);
goto error;
}
@@ -4240,7 +4242,7 @@ virDomainWatchdogDefParseXML(const xmlNodePtr node,
else {
def->action = virDomainWatchdogActionTypeFromString (action);
if (def->action < 0) {
- virDomainReportError(VIR_ERR_INTERNAL_ERROR,
+ virDomainReportError(VIR_ERR_CONFIG_UNSUPPORTED,
_("unknown watchdog action '%s'"), action);
goto error;
}
@@ -4281,7 +4283,7 @@ virDomainMemballoonDefParseXML(const xmlNodePtr node,
goto error;
}
if ((def->model = virDomainMemballoonModelTypeFromString(model)) < 0) {
- virDomainReportError(VIR_ERR_INTERNAL_ERROR,
+ virDomainReportError(VIR_ERR_CONFIG_UNSUPPORTED,
_("unknown memory balloon model '%s'"), model);
goto error;
}
@@ -4325,7 +4327,7 @@ virSysinfoParseXML(const xmlNodePtr node,
goto error;
}
if ((def->type = virDomainSysinfoTypeFromString(type)) < 0) {
- virDomainReportError(VIR_ERR_INTERNAL_ERROR,
+ virDomainReportError(VIR_ERR_CONFIG_UNSUPPORTED,
_("unknown sysinfo type '%s'"), type);
goto error;
}
@@ -4502,13 +4504,13 @@ virDomainVideoDefParseXML(const xmlNodePtr node,
if (type) {
if ((def->type = virDomainVideoTypeFromString(type)) < 0) {
- virDomainReportError(VIR_ERR_INTERNAL_ERROR,
+ virDomainReportError(VIR_ERR_CONFIG_UNSUPPORTED,
_("unknown video model '%s'"), type);
goto error;
}
} else {
if ((def->type = virDomainVideoDefaultType(dom)) < 0) {
- virDomainReportError(VIR_ERR_INTERNAL_ERROR, "%s",
+ virDomainReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
_("missing video model and cannot determine default"));
goto error;
}
@@ -4516,7 +4518,7 @@ virDomainVideoDefParseXML(const xmlNodePtr node,
if (vram) {
if (virStrToLong_ui(vram, NULL, 10, &def->vram) < 0) {
- virDomainReportError(VIR_ERR_INTERNAL_ERROR,
+ virDomainReportError(VIR_ERR_CONFIG_UNSUPPORTED,
_("cannot parse video ram '%s'"), vram);
goto error;
}
@@ -4526,7 +4528,7 @@ virDomainVideoDefParseXML(const xmlNodePtr node,
if (heads) {
if (virStrToLong_ui(heads, NULL, 10, &def->heads) < 0) {
- virDomainReportError(VIR_ERR_INTERNAL_ERROR,
+ virDomainReportError(VIR_ERR_CONFIG_UNSUPPORTED,
_("cannot parse video heads '%s'"), heads);
goto error;
}
@@ -4739,7 +4741,7 @@ virDomainHostdevDefParseXML(const xmlNodePtr node,
mode = virXMLPropString(node, "mode");
if (mode) {
if ((def->mode=virDomainHostdevModeTypeFromString(mode)) < 0) {
- virDomainReportError(VIR_ERR_INTERNAL_ERROR,
+ virDomainReportError(VIR_ERR_CONFIG_UNSUPPORTED,
_("unknown hostdev mode '%s'"), mode);
goto error;
}
@@ -4750,7 +4752,7 @@ virDomainHostdevDefParseXML(const xmlNodePtr node,
type = virXMLPropString(node, "type");
if (type) {
if ((def->source.subsys.type = virDomainHostdevSubsysTypeFromString(type)) < 0) {
- virDomainReportError(VIR_ERR_INTERNAL_ERROR,
+ virDomainReportError(VIR_ERR_CONFIG_UNSUPPORTED,
_("unknown host device type '%s'"), type);
goto error;
}
@@ -4869,7 +4871,7 @@ virSecurityLabelDefParseXML(const virDomainDefPtr def,
def->seclabel.type = virDomainSeclabelTypeFromString(p);
VIR_FREE(p);
if (def->seclabel.type < 0) {
- virDomainReportError(VIR_ERR_XML_ERROR,
+ virDomainReportError(VIR_ERR_CONFIG_UNSUPPORTED,
"%s", _("invalid security type"));
goto error;
}
@@ -5290,7 +5292,7 @@ virDomainDefParseBootXML(xmlXPathContextPtr ctxt,
goto cleanup;
}
if ((val = virDomainBootTypeFromString(dev)) < 0) {
- virDomainReportError(VIR_ERR_INTERNAL_ERROR,
+ virDomainReportError(VIR_ERR_CONFIG_UNSUPPORTED,
_("unknown boot device '%s'"),
dev);
VIR_FREE(dev);
@@ -5425,7 +5427,7 @@ static virDomainDefPtr virDomainDefParseXML(virCapsPtr caps,
}
if ((def->virtType = virDomainVirtTypeFromString(tmp)) < 0) {
- virDomainReportError(VIR_ERR_INTERNAL_ERROR,
+ virDomainReportError(VIR_ERR_CONFIG_UNSUPPORTED,
_("invalid domain type %s"), tmp);
goto error;
}
@@ -5597,7 +5599,7 @@ static virDomainDefPtr virDomainDefParseXML(virCapsPtr caps,
for (i = 0 ; i < n ; i++) {
int val = virDomainFeatureTypeFromString((const char *)nodes[i]->name);
if (val < 0) {
- virDomainReportError(VIR_ERR_INTERNAL_ERROR,
+ virDomainReportError(VIR_ERR_CONFIG_UNSUPPORTED,
_("unexpected feature %s"),
nodes[i]->name);
goto error;
@@ -6239,7 +6241,7 @@ static virDomainDefPtr virDomainDefParseXML(virCapsPtr caps,
int mode;
if ((mode = virDomainSmbiosModeTypeFromString(tmp)) < 0) {
- virDomainReportError(VIR_ERR_INTERNAL_ERROR,
+ virDomainReportError(VIR_ERR_CONFIG_UNSUPPORTED,
_("unknown smbios mode '%s'"), tmp);
goto error;
}
@@ -6318,7 +6320,7 @@ static virDomainObjPtr virDomainObjParseXML(virCapsPtr caps,
goto error;
}
if ((state = virDomainStateTypeFromString(tmp)) < 0) {
- virDomainReportError(VIR_ERR_INTERNAL_ERROR,
+ virDomainReportError(VIR_ERR_CONFIG_UNSUPPORTED,
_("invalid domain state '%s'"), tmp);
VIR_FREE(tmp);
goto error;
@@ -9170,7 +9172,7 @@ virDomainSnapshotDefPtr virDomainSnapshotDefParseString(const char *xmlStr,
}
def->state = virDomainStateTypeFromString(state);
if (def->state < 0) {
- virDomainReportError(VIR_ERR_INTERNAL_ERROR,
+ virDomainReportError(VIR_ERR_CONFIG_UNSUPPORTED,
_("Invalid state '%s' in domain snapshot XML"),
state);
goto cleanup;
@@ -9521,7 +9523,7 @@ int virDomainDiskDefForeachPath(virDomainDiskDefPtr disk,
formatStr = "raw"; /* Xen compat */
if ((format = virStorageFileFormatTypeFromString(formatStr)) < 0) {
- virDomainReportError(VIR_ERR_INTERNAL_ERROR,
+ virDomainReportError(VIR_ERR_CONFIG_UNSUPPORTED,
_("unknown disk format '%s' for %s"),
disk->driverType, disk->src);
return -1;
diff --git a/src/conf/interface_conf.c b/src/conf/interface_conf.c
index f3848bd..7e9c78f 100644
--- a/src/conf/interface_conf.c
+++ b/src/conf/interface_conf.c
@@ -689,7 +689,7 @@ virInterfaceDefParseXML(xmlXPathContextPtr ctxt, int parentIfType) {
}
type = virInterfaceTypeFromString(tmp);
if (type == -1) {
- virInterfaceReportError(VIR_ERR_XML_ERROR,
+ virInterfaceReportError(VIR_ERR_CONFIG_UNSUPPORTED,
_("unknown interface type %s"), tmp);
VIR_FREE(tmp);
return(NULL);
diff --git a/src/conf/network_conf.c b/src/conf/network_conf.c
index e4765ea..598d01f 100644
--- a/src/conf/network_conf.c
+++ b/src/conf/network_conf.c
@@ -674,7 +674,7 @@ virNetworkDefParseXML(xmlXPathContextPtr ctxt)
tmp = virXPathString("string(./forward[1]/@mode)", ctxt);
if (tmp) {
if ((def->forwardType = virNetworkForwardTypeFromString(tmp)) < 0) {
- virNetworkReportError(VIR_ERR_INTERNAL_ERROR,
+ virNetworkReportError(VIR_ERR_CONFIG_UNSUPPORTED,
_("unknown forwarding type '%s'"), tmp);
VIR_FREE(tmp);
goto error;
diff --git a/src/conf/node_device_conf.c b/src/conf/node_device_conf.c
index dde2921..1675631 100644
--- a/src/conf/node_device_conf.c
+++ b/src/conf/node_device_conf.c
@@ -826,7 +826,7 @@ virNodeDevCapNetParseXML(xmlXPathContextPtr ctxt,
int val = virNodeDevNetCapTypeFromString(tmp);
VIR_FREE(tmp);
if (val < 0) {
- virNodeDeviceReportError(VIR_ERR_INTERNAL_ERROR,
+ virNodeDeviceReportError(VIR_ERR_CONFIG_UNSUPPORTED,
_("invalid network type supplied for '%s'"),
def->name);
goto out;
@@ -1076,7 +1076,7 @@ virNodeDevCapsDefParseXML(xmlXPathContextPtr ctxt,
}
if ((val = virNodeDevCapTypeFromString(tmp)) < 0) {
- virNodeDeviceReportError(VIR_ERR_INTERNAL_ERROR,
+ virNodeDeviceReportError(VIR_ERR_CONFIG_UNSUPPORTED,
_("unknown capability type '%s'"), tmp);
VIR_FREE(tmp);
goto error;
diff --git a/src/conf/nwfilter_conf.c b/src/conf/nwfilter_conf.c
index a32bdb3..d493c77 100644
--- a/src/conf/nwfilter_conf.c
+++ b/src/conf/nwfilter_conf.c
@@ -1891,7 +1891,7 @@ virNWFilterRuleParse(xmlNodePtr node)
}
if ((ret->action = virNWFilterRuleActionTypeFromString(action)) < 0) {
- virNWFilterReportError(VIR_ERR_INTERNAL_ERROR,
+ virNWFilterReportError(VIR_ERR_CONFIG_UNSUPPORTED,
"%s",
_("unknown rule action attribute value"));
goto err_exit;
@@ -1905,7 +1905,7 @@ virNWFilterRuleParse(xmlNodePtr node)
}
if ((ret->tt = virNWFilterRuleDirectionTypeFromString(direction)) < 0) {
- virNWFilterReportError(VIR_ERR_INTERNAL_ERROR,
+ virNWFilterReportError(VIR_ERR_CONFIG_UNSUPPORTED,
"%s",
_("unknown rule direction attribute value"));
goto err_exit;
@@ -2004,7 +2004,7 @@ virNWFilterDefParseXML(xmlXPathContextPtr ctxt) {
if (chain) {
if ((ret->chainsuffix =
virNWFilterChainSuffixTypeFromString(chain)) < 0) {
- virNWFilterReportError(VIR_ERR_INTERNAL_ERROR,
+ virNWFilterReportError(VIR_ERR_CONFIG_UNSUPPORTED,
_("unknown chain suffix '%s'"), chain);
goto cleanup;
}
diff --git a/src/conf/secret_conf.c b/src/conf/secret_conf.c
index 105afbe..c8a8b85 100644
--- a/src/conf/secret_conf.c
+++ b/src/conf/secret_conf.c
@@ -74,7 +74,7 @@ virSecretDefParseUsage(xmlXPathContextPtr ctxt,
}
type = virSecretUsageTypeTypeFromString(type_str);
if (type < 0) {
- virSecretReportError(VIR_ERR_XML_ERROR,
+ virSecretReportError(VIR_ERR_CONFIG_UNSUPPORTED,
_("unknown secret usage type %s"), type_str);
VIR_FREE(type_str);
return -1;
diff --git a/src/conf/storage_conf.c b/src/conf/storage_conf.c
index ca86f19..5f94c01 100644
--- a/src/conf/storage_conf.c
+++ b/src/conf/storage_conf.c
@@ -627,7 +627,7 @@ virStoragePoolDefParseXML(xmlXPathContextPtr ctxt) {
type = virXPathString("string(./@type)", ctxt);
if ((ret->type = virStoragePoolTypeFromString((const char *)type)) < 0) {
- virStorageReportError(VIR_ERR_INTERNAL_ERROR,
+ virStorageReportError(VIR_ERR_CONFIG_UNSUPPORTED,
_("unknown storage pool type %s"), (const char*)type);
goto cleanup;
}
diff --git a/src/conf/storage_encryption_conf.c b/src/conf/storage_encryption_conf.c
index 545efad..0a4d8ba 100644
--- a/src/conf/storage_encryption_conf.c
+++ b/src/conf/storage_encryption_conf.c
@@ -94,7 +94,7 @@ virStorageEncryptionSecretParse(xmlXPathContextPtr ctxt,
}
type = virStorageEncryptionSecretTypeTypeFromString(type_str);
if (type < 0) {
- virStorageReportError(VIR_ERR_XML_ERROR,
+ virStorageReportError(VIR_ERR_CONFIG_UNSUPPORTED,
_("unknown volume encryption secret type %s"),
type_str);
VIR_FREE(type_str);
@@ -148,7 +148,7 @@ virStorageEncryptionParseXML(xmlXPathContextPtr ctxt)
}
format = virStorageEncryptionFormatTypeFromString(format_str);
if (format < 0) {
- virStorageReportError(VIR_ERR_XML_ERROR,
+ virStorageReportError(VIR_ERR_CONFIG_UNSUPPORTED,
_("unknown volume encryption format type %s"),
format_str);
VIR_FREE(format_str);
--
1.7.5.rc3
13 years, 7 months
[libvirt] [PATCH] Use virDomainGetState in migration APIs
by Jiri Denemark
We are only interested in domain state so no need to call
virDomainGetInfo for that.
---
src/libvirt.c | 18 +++++++++---------
1 files changed, 9 insertions(+), 9 deletions(-)
diff --git a/src/libvirt.c b/src/libvirt.c
index ff16c48..3d1b314 100644
--- a/src/libvirt.c
+++ b/src/libvirt.c
@@ -3513,10 +3513,10 @@ virDomainMigrateVersion1 (virDomainPtr domain,
char *uri_out = NULL;
char *cookie = NULL;
int cookielen = 0, ret;
- virDomainInfo info;
+ int state;
- ret = virDomainGetInfo (domain, &info);
- if (ret == 0 && info.state == VIR_DOMAIN_PAUSED) {
+ ret = virDomainGetState(domain, &state, NULL, 0);
+ if (ret == 0 && state == VIR_DOMAIN_PAUSED) {
flags |= VIR_MIGRATE_PAUSED;
}
@@ -3601,7 +3601,7 @@ virDomainMigrateVersion2 (virDomainPtr domain,
char *cookie = NULL;
char *dom_xml = NULL;
int cookielen = 0, ret;
- virDomainInfo info;
+ int state;
virErrorPtr orig_err = NULL;
int cancelled;
@@ -3632,8 +3632,8 @@ virDomainMigrateVersion2 (virDomainPtr domain,
if (!dom_xml)
return NULL;
- ret = virDomainGetInfo (domain, &info);
- if (ret == 0 && info.state == VIR_DOMAIN_PAUSED) {
+ ret = virDomainGetState(domain, &state, NULL, 0);
+ if (ret == 0 && state == VIR_DOMAIN_PAUSED) {
flags |= VIR_MIGRATE_PAUSED;
}
@@ -3732,7 +3732,7 @@ virDomainMigrateVersion3(virDomainPtr domain,
int cookieinlen = 0;
int cookieoutlen = 0;
int ret;
- virDomainInfo info;
+ int state;
virErrorPtr orig_err = NULL;
int cancelled;
@@ -3753,8 +3753,8 @@ virDomainMigrateVersion3(virDomainPtr domain,
if (!dom_xml)
goto done;
- ret = virDomainGetInfo (domain, &info);
- if (ret == 0 && info.state == VIR_DOMAIN_PAUSED) {
+ ret = virDomainGetState(domain, &state, NULL, 0);
+ if (ret == 0 && state == VIR_DOMAIN_PAUSED) {
flags |= VIR_MIGRATE_PAUSED;
}
--
1.7.5.rc3
13 years, 7 months
[libvirt] [PATCH] Fix QEMU migration cookie crash for guests with no graphics
by Daniel P. Berrange
When generating a cookie for a guest with no data, the
QEMU_MIGRATION_COOKIE_GRAPHICS flag was set even if no
graphics data was added. Avoid setting the flag unless
it was needed, also add a safety check for mig->graphics
being non-NULL
* src/qemu/qemu_migration.c: Avoid cookie crash for guest
with no graphics
---
src/qemu/qemu_migration.c | 14 ++++++++------
1 files changed, 8 insertions(+), 6 deletions(-)
diff --git a/src/qemu/qemu_migration.c b/src/qemu/qemu_migration.c
index fcf8f9c..4d7bc38 100644
--- a/src/qemu/qemu_migration.c
+++ b/src/qemu/qemu_migration.c
@@ -252,11 +252,12 @@ qemuMigrationCookieAddGraphics(qemuMigrationCookiePtr mig,
if (dom->def->ngraphics == 1 &&
(dom->def->graphics[0]->type == VIR_DOMAIN_GRAPHICS_TYPE_VNC ||
- dom->def->graphics[0]->type == VIR_DOMAIN_GRAPHICS_TYPE_SPICE) &&
- !(mig->graphics = qemuMigrationCookieGraphicsAlloc(driver, dom->def->graphics[0])))
- return -1;
-
- mig->flags |= QEMU_MIGRATION_COOKIE_GRAPHICS;
+ dom->def->graphics[0]->type == VIR_DOMAIN_GRAPHICS_TYPE_SPICE)) {
+ if (!(mig->graphics =
+ qemuMigrationCookieGraphicsAlloc(driver, dom->def->graphics[0])))
+ return -1;
+ mig->flags |= QEMU_MIGRATION_COOKIE_GRAPHICS;
+ }
return 0;
}
@@ -295,7 +296,8 @@ static void qemuMigrationCookieXMLFormat(virBufferPtr buf,
virBufferEscapeString(buf, " <hostname>%s</hostname>\n", mig->hostname);
virBufferAsprintf(buf, " <hostuuid>%s</hostuuid>\n", hostuuidstr);
- if (mig->flags & QEMU_MIGRATION_COOKIE_GRAPHICS)
+ if ((mig->flags & QEMU_MIGRATION_COOKIE_GRAPHICS) &&
+ mig->graphics)
qemuMigrationCookieGraphicsXMLFormat(buf, mig->graphics);
virBufferAddLit(buf, "</qemu-migration>\n");
--
1.7.4.4
13 years, 7 months
[libvirt] [PATCH] Blank out the 'listenAddr' parameter if empty string
by Daniel P. Berrange
Some bogus apps are generating a VNC/SPICE/RFB listen attribute
with no content. This then causes a failure with the graphics
migration cookie parsing. Blank out the 'listenAddr' parameter
after parsing domain XML if it is the empty string, so the host
default takes over
* src/qemu/qemu_migration.c: Blank out listenAddr parameter
if empty
---
src/conf/domain_conf.c | 13 +++++++++++++
1 files changed, 13 insertions(+), 0 deletions(-)
diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c
index 03f4dc9..15fe9f0 100644
--- a/src/conf/domain_conf.c
+++ b/src/conf/domain_conf.c
@@ -3906,6 +3906,10 @@ virDomainGraphicsDefParseXML(xmlNodePtr node, int flags) {
def->data.vnc.socket = virXMLPropString(node, "socket");
def->data.vnc.keymap = virXMLPropString(node, "keymap");
+ if (def->data.vnc.listenAddr &&
+ STREQ(def->data.vnc.listenAddr, ""))
+ VIR_FREE(def->data.vnc.listenAddr);
+
if (virDomainGraphicsAuthDefParseXML(node, &def->data.vnc.auth) < 0)
goto error;
} else if (def->type == VIR_DOMAIN_GRAPHICS_TYPE_SDL) {
@@ -3970,6 +3974,10 @@ virDomainGraphicsDefParseXML(xmlNodePtr node, int flags) {
}
def->data.rdp.listenAddr = virXMLPropString(node, "listen");
+
+ if (def->data.rdp.listenAddr &&
+ STREQ(def->data.rdp.listenAddr, ""))
+ VIR_FREE(def->data.rdp.listenAddr);
} else if (def->type == VIR_DOMAIN_GRAPHICS_TYPE_DESKTOP) {
char *fullscreen = virXMLPropString(node, "fullscreen");
@@ -4033,6 +4041,11 @@ virDomainGraphicsDefParseXML(xmlNodePtr node, int flags) {
def->data.spice.listenAddr = virXMLPropString(node, "listen");
def->data.spice.keymap = virXMLPropString(node, "keymap");
+
+ if (def->data.spice.listenAddr &&
+ STREQ(def->data.spice.listenAddr, ""))
+ VIR_FREE(def->data.spice.listenAddr);
+
if (virDomainGraphicsAuthDefParseXML(node, &def->data.spice.auth) < 0)
goto error;
--
1.7.4.4
13 years, 7 months