[libvirt] [PATCH] Allow for URI aliases when connecting to libvirt
by Daniel P. Berrange
From: "Daniel P. Berrange" <berrange(a)redhat.com>
I finally got fed up of typing URIs when using virsh....
This adds support for a libvirt client configuration file
either /etc/libvirt/libvirt.conf for privileged clients,
or $HOME/.libvirt/libvirt.conf for unprivileged clients.
It allows one parameter
uri_aliases = [
"hail=qemu+ssh://root@hail.cloud.example.com/system",
"sleet=qemu+ssh://root@sleet.cloud.example.com/system",
]
Any call to virConnectOpen with a non-NULL URI will first
attempt to match against the uri_aliases list. An application
can disable this by using VIR_CONNECT_NO_ALIASES
* docs/uri.html.in: Document URI aliases
* include/libvirt/libvirt.h.in: Add VIR_CONNECT_NO_ALIASES
* libvirt.spec.in, mingw32-libvirt.spec.in: Add /etc/libvirt/libvirt.conf
* src/Makefile.am: Install default config file
* src/libvirt.c: Add support for URI aliases
* src/remote/remote_driver.c: Don't try to handle URIs
with no scheme and which clearly are not paths
* src/util/conf.c: Don't raise error on virConfFree(NULL)
* src/xen/xen_driver.c: Don't raise error on URIs
with no scheme
---
docs/uri.html.in | 101 ++++++++++++++-------------
include/libvirt/libvirt.h.in | 3 +-
libvirt.spec.in | 1 +
mingw32-libvirt.spec.in | 2 +
src/Makefile.am | 2 +-
src/libvirt.c | 157 ++++++++++++++++++++++++++++++++++++++----
src/libvirt.conf | 13 ++++
src/remote/remote_driver.c | 5 ++
src/util/conf.c | 6 +-
src/xen/xen_driver.c | 12 +---
10 files changed, 223 insertions(+), 79 deletions(-)
create mode 100644 src/libvirt.conf
diff --git a/docs/uri.html.in b/docs/uri.html.in
index e6326b2..5cc4dbf 100644
--- a/docs/uri.html.in
+++ b/docs/uri.html.in
@@ -2,6 +2,8 @@
<html>
<body>
<h1 >Connection URIs</h1>
+
+ <ul id="toc"></ul>
<p>
Since libvirt supports many different kinds of virtualization
(often referred to as "drivers" or "hypervisors"), we need a
@@ -13,41 +15,44 @@ machine over the network.
To this end, libvirt uses URIs as used on the Web and as defined in <a href="http://www.ietf.org/rfc/rfc2396.txt">RFC 2396</a>. This page
documents libvirt URIs.
</p>
- <ul>
- <li>
- <a href="#URI_libvirt">Specifying URIs to libvirt</a>
- </li>
- <li>
- <a href="#URI_virsh">Specifying URIs to virsh, virt-manager and virt-install</a>
- </li>
- <li>
- <a href="#URI_xen">xen:/// URI</a>
- </li>
- <li>
- <a href="#URI_qemu">qemu:///... QEMU and KVM URIs</a>
- </li>
- <li>
- <a href="#URI_remote">Remote URIs</a>
- </li>
- <li>
- <a href="#URI_test">test:///... Test URIs</a>
- </li>
- <li>
- <a href="#URI_legacy">Other & legacy URI formats</a>
- </li>
- </ul>
- <h3>
- <a name="URI_libvirt">Specifying URIs to libvirt</a>
- </h3>
+ <h2><a name="URI_libvirt">Specifying URIs to libvirt</a></h2>
+
<p>
The URI is passed as the <code>name</code> parameter to <a href="html/libvirt-libvirt.html#virConnectOpen"><code>virConnectOpen</code></a> or <a href="html/libvirt-libvirt.html#virConnectOpenReadOnly"><code>virConnectOpenReadOnly</code></a>. For example:
</p>
<pre>
virConnectPtr conn = virConnectOpenReadOnly (<b>"test:///default"</b>);
</pre>
- <h3>
+ <h2>
+ <a name="URI_config">Configuring URI aliases</a>
+ </h2>
+
+ <p>
+To simplify live for administrators, it is possible to setup URI aliases in a
+libvirt client configuration file. The configuration file is <code>/etc/libvirt/libvirt.conf</code>
+for the root user, or <code>$HOME/.libvirt/libvirt.conf</code> for any unprivileged user.
+In this file, the following syntax can be used to setup aliases
+ </p>
+
+<pre>
+uri_aliases = [
+ "hail=qemu+ssh://root@hail.cloud.example.com/system",
+ "sleet=qemu+ssh://root@sleet.cloud.example.com/system",
+]
+</pre>
+
+<p>
+ A URI alias should be a string made up from the characters
+ <code>a-Z, 0-9, _, -</code>. Following the <code>=</code>
+ can be any libvirt URI string, including arbitrary URI parameters.
+ URI aliases will apply to any application opening a libvirt
+ connection, unless it has explicitly passed the <code>VIR_CONNECT_NO_ALIASES</code>
+ parameter to <code>virConnectOpenAuth</code>.
+</p>
+
+ <h2>
<a name="URI_virsh">Specifying URIs to virsh, virt-manager and virt-install</a>
- </h3>
+ </h2>
<p>
In virsh use the <code>-c</code> or <code>--connect</code> option:
</p>
@@ -76,9 +81,9 @@ In virt-install use the <code>--connect=</code><i>URI</i> option:
<pre>
virt-install <b>--connect=test:///default</b> <i>[other options]</i>
</pre>
- <h3>
+ <h2>
<a name="URI_xen">xen:/// URI</a>
- </h3>
+ </h2>
<p>
<i>This section describes a feature which is new in libvirt >
0.2.3. For libvirt ≤ 0.2.3 use <a href="#URI_legacy_xen"><code>"xen"</code></a>.</i>
@@ -87,9 +92,9 @@ virt-install <b>--connect=test:///default</b> <i>[other options]</i>
To access a Xen hypervisor running on the local machine
use the URI <code>xen:///</code>.
</p>
- <h3>
+ <h2>
<a name="URI_qemu">qemu:///... QEMU and KVM URIs</a>
- </h3>
+ </h2>
<p>
To use QEMU support in libvirt you must be running the
<code>libvirtd</code> daemon (named <code>libvirt_qemud</code>
@@ -119,9 +124,9 @@ KVM URIs are identical. You select between qemu, qemu accelerated and
KVM guests in the <a href="format.html#KVM1">guest XML as described
here</a>.
</p>
- <h3>
+ <h2>
<a name="URI_remote">Remote URIs</a>
- </h3>
+ </h2>
<p>
Remote URIs are formed by taking ordinary local URIs and adding a
hostname and/or transport name. As a special case, using a URI
@@ -182,9 +187,9 @@ We refer you to <a href="remote.html#Remote_URI_reference">the libvirt
remote URI reference</a> and <a href="remote.html">full documentation
for libvirt remote support</a>.
</p>
- <h3>
+ <h2>
<a name="URI_test">test:///... Test URIs</a>
- </h3>
+ </h2>
<p>
The test driver is a dummy hypervisor for test purposes.
The URIs supported are:
@@ -196,12 +201,12 @@ host definitions built into the driver. </li>
a set of host definitions held in the named file.
</li>
</ul>
- <h3>
+ <h2>
<a name="URI_legacy">Other & legacy URI formats</a>
- </h3>
- <h4>
+ </h2>
+ <h3>
<a name="URI_NULL">NULL and empty string URIs</a>
- </h4>
+ </h3>
<p>
Libvirt allows you to pass a <code>NULL</code> pointer to
<code>virConnectOpen*</code>. Empty string (<code>""</code>) acts in
@@ -223,9 +228,9 @@ the user to type a URI in directly (if that is appropriate). If your
application wishes to connect specifically to a Xen hypervisor, then
for future proofing it should choose a full <a href="#URI_xen"><code>xen:///</code> URI</a>.
</p>
- <h4>
+ <h3>
<a name="URI_file">File paths (xend-unix-server)</a>
- </h4>
+ </h3>
<p>
If XenD is running and configured in <code>/etc/xen/xend-config.sxp</code>:
</p>
@@ -240,9 +245,9 @@ using a file URI such as:
<pre>
virsh -c ///var/run/xend/xend-socket
</pre>
- <h4>
+ <h3>
<a name="URI_http">Legacy: <code>http://...</code> (xend-http-server)</a>
- </h4>
+ </h3>
<p>
If XenD is running and configured in <code>/etc/xen/xend-config.sxp</code>:
@@ -276,17 +281,17 @@ Notes:
libvirt, only the old-style sexpr interface known in the Xen
documentation as "unix server" or "http server".</li>
</ol>
- <h4>
+ <h3>
<a name="URI_legacy_xen">Legacy: <code>"xen"</code></a>
- </h4>
+ </h3>
<p>
Another legacy URI is to specify name as the string
<code>"xen"</code>. This will continue to refer to the Xen
hypervisor. However you should prefer a full <a href="#URI_xen"><code>xen:///</code> URI</a> in all future code.
</p>
- <h4>
+ <h3>
<a name="URI_legacy_proxy">Legacy: Xen proxy</a>
- </h4>
+ </h3>
<p>
Libvirt continues to support connections to a separately running Xen
proxy daemon. This provides a way to allow non-root users to make a
diff --git a/include/libvirt/libvirt.h.in b/include/libvirt/libvirt.h.in
index c991dfc..6bb27c7 100644
--- a/include/libvirt/libvirt.h.in
+++ b/include/libvirt/libvirt.h.in
@@ -843,7 +843,8 @@ typedef virNodeMemoryStats *virNodeMemoryStatsPtr;
* Flags when opening a connection to a hypervisor
*/
typedef enum {
- VIR_CONNECT_RO = 1, /* A readonly connection */
+ VIR_CONNECT_RO = (1 << 0), /* A readonly connection */
+ VIR_CONNECT_NO_ALIASES = (1 << 1), /* Don't try to resolve URI aliases */
} virConnectFlags;
diff --git a/libvirt.spec.in b/libvirt.spec.in
index 7c63710..d6f4564 100644
--- a/libvirt.spec.in
+++ b/libvirt.spec.in
@@ -1085,6 +1085,7 @@ rm -f $RPM_BUILD_ROOT%{_sysconfdir}/sysctl.d/libvirtd
%defattr(-, root, root)
%doc AUTHORS ChangeLog.gz NEWS README COPYING.LIB TODO
+%config(noreplace) %{_sysconfdir}/libvirt/libvirt.conf
%{_mandir}/man1/virsh.1*
%{_mandir}/man1/virt-xml-validate.1*
%{_mandir}/man1/virt-pki-validate.1*
diff --git a/mingw32-libvirt.spec.in b/mingw32-libvirt.spec.in
index f651d11..f5e0d05 100644
--- a/mingw32-libvirt.spec.in
+++ b/mingw32-libvirt.spec.in
@@ -83,6 +83,8 @@ rm -rf $RPM_BUILD_ROOT
%files
%defattr(-,root,root)
+%config(noreplace) %{_mingw32_sysconfdir}/libvirt/libvirt.conf
+
%{_mingw32_bindir}/libvirt-0.dll
%{_mingw32_bindir}/virsh.exe
%{_mingw32_bindir}/virt-xml-validate
diff --git a/src/Makefile.am b/src/Makefile.am
index 302d395..fccc54d 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -39,7 +39,7 @@ moddir = $(libdir)/libvirt/connection-driver
mod_LTLIBRARIES =
confdir = $(sysconfdir)/libvirt
-conf_DATA =
+conf_DATA = libvirt.conf
augeasdir = $(datadir)/augeas/lenses
augeas_DATA =
diff --git a/src/libvirt.c b/src/libvirt.c
index f07c720..c285e31 100644
--- a/src/libvirt.c
+++ b/src/libvirt.c
@@ -40,6 +40,7 @@
#include "memory.h"
#include "configmake.h"
#include "intprops.h"
+#include "conf.h"
#include "rpc/virnettlscontext.h"
#ifndef WITH_DRIVER_MODULES
@@ -968,6 +969,125 @@ error:
return -1;
}
+static char *
+virConnectConfigFile(void)
+{
+ char *path;
+ if (geteuid() == 0) {
+ if (virAsprintf(&path, "%s/libvirt/libvirt.conf",
+ SYSCONFDIR) < 0)
+ goto no_memory;
+ } else {
+ char *userdir = virGetUserDirectory(geteuid());
+ if (!userdir)
+ goto error;
+
+ if (virAsprintf(&path, "%s/.libvirt/libvirt.conf",
+ userdir) < 0)
+ goto no_memory;
+ }
+
+ return path;
+
+no_memory:
+ virReportOOMError();
+error:
+ return NULL;
+}
+
+static int
+virConnectOpenFindURIAliasMatch(virConfValuePtr value, const char *alias, char **uri)
+{
+ virConfValuePtr entry;
+ if (value->type != VIR_CONF_LIST) {
+ virLibConnError(VIR_ERR_INTERNAL_ERROR, "%s",
+ _("Expected a list for 'uri_aliases' config parameter"));
+ return -1;
+ }
+
+ entry = value->list;
+ while (entry) {
+ char *offset;
+ size_t safe;
+
+ if (entry->type != VIR_CONF_STRING) {
+ virLibConnError(VIR_ERR_INTERNAL_ERROR, "%s",
+ _("Expected a string for 'uri_aliases' config parameter list entry"));
+ return -1;
+ }
+
+ if (!(offset = strchr(entry->str, '='))) {
+ virLibConnError(VIR_ERR_INTERNAL_ERROR,
+ _("Malformed 'uri_aliases' config entry '%s', expected 'alias=uri://host/path'"),
+ entry->str);
+ return -1;
+ }
+
+ safe = strspn(entry->str, "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789_-");
+ if (safe < (offset - entry->str)) {
+ virLibConnError(VIR_ERR_INTERNAL_ERROR,
+ _("Malformed 'uri_aliases' config entry '%s', aliases may only container 'a-Z, 0-9, _, -'"),
+ entry->str);
+ return -1;
+ }
+
+ if (STREQLEN(entry->str, alias, offset-entry->str)) {
+ VIR_DEBUG("Resolved alias '%s' to '%s'",
+ alias, offset+1);
+ if (!(*uri = strdup(offset+1))) {
+ virReportOOMError();
+ return -1;
+ }
+ return 0;
+ }
+
+ entry = entry->next;
+ }
+
+ VIR_DEBUG("No alias found for '%s', passing through to drivers",
+ alias);
+ return 0;
+}
+
+static int
+virConnectOpenResolveURIAlias(const char *alias, char **uri)
+{
+ char *config = NULL;
+ int ret = -1;
+ virConfPtr conf = NULL;
+ virConfValuePtr value = NULL;
+
+ *uri = NULL;
+
+ /* Short circuit to avoid doing URI alias resolution
+ * when it clearly isn't an alias */
+ if (strchr(alias, '/') ||
+ strchr(alias, ':'))
+ return 0;
+
+ if (!(config = virConnectConfigFile()))
+ goto cleanup;
+
+ if (!virFileExists(config)) {
+ ret = 0;
+ goto cleanup;
+ }
+
+ VIR_DEBUG("Loading config file '%s'", config);
+ if (!(conf = virConfReadFile(config, 0)))
+ goto cleanup;
+
+ if ((value = virConfGetValue(conf, "uri_aliases")))
+ ret = virConnectOpenFindURIAliasMatch(value, alias, uri);
+ else
+ ret = 0;
+
+cleanup:
+ virConfFree(conf);
+ VIR_FREE(config);
+ return ret;
+}
+
static virConnectPtr
do_open (const char *name,
virConnectAuthPtr auth,
@@ -998,6 +1118,7 @@ do_open (const char *name,
}
if (name) {
+ char *alias = NULL;
/* Convert xen -> xen:/// for back compat */
if (STRCASEEQ(name, "xen"))
name = "xen:///";
@@ -1008,26 +1129,34 @@ do_open (const char *name,
if (STREQ (name, "xen://"))
name = "xen:///";
- ret->uri = xmlParseURI (name);
+ if (!(flags & VIR_CONNECT_NO_ALIASES) &&
+ virConnectOpenResolveURIAlias(name, &alias) < 0)
+ goto failed;
+
+ ret->uri = xmlParseURI (alias ? alias : name);
if (!ret->uri) {
virLibConnError(VIR_ERR_INVALID_ARG,
- _("could not parse connection URI"));
+ _("could not parse connection URI %s"),
+ alias ? alias : name);
+ VIR_FREE(alias);
goto failed;
}
VIR_DEBUG("name \"%s\" to URI components:\n"
- " scheme %s\n"
- " opaque %s\n"
- " authority %s\n"
- " server %s\n"
- " user %s\n"
- " port %d\n"
- " path %s\n",
- name,
- NULLSTR(ret->uri->scheme), NULLSTR(ret->uri->opaque),
- NULLSTR(ret->uri->authority), NULLSTR(ret->uri->server),
- NULLSTR(ret->uri->user), ret->uri->port,
- NULLSTR(ret->uri->path));
+ " scheme %s\n"
+ " opaque %s\n"
+ " authority %s\n"
+ " server %s\n"
+ " user %s\n"
+ " port %d\n"
+ " path %s\n",
+ alias ? alias : name,
+ NULLSTR(ret->uri->scheme), NULLSTR(ret->uri->opaque),
+ NULLSTR(ret->uri->authority), NULLSTR(ret->uri->server),
+ NULLSTR(ret->uri->user), ret->uri->port,
+ NULLSTR(ret->uri->path));
+
+ VIR_FREE(alias);
} else {
VIR_DEBUG("no name, allowing driver auto-select");
}
diff --git a/src/libvirt.conf b/src/libvirt.conf
new file mode 100644
index 0000000..ffe8c21
--- /dev/null
+++ b/src/libvirt.conf
@@ -0,0 +1,13 @@
+
+#
+# This can be used to setup URI aliases for frequently
+# used connection URIs. Aliases may contain only the
+# characters a-Z, 0-9, _, -.
+#
+# Following the '=' may be any valid libvirt connection
+# URI, including arbitrary parameters
+
+#uri_aliases = [
+# "hail=qemu+ssh://root@hail.cloud.example.com/system",
+# "sleet=qemu+ssh://root@sleet.cloud.example.com/system",
+#]
diff --git a/src/remote/remote_driver.c b/src/remote/remote_driver.c
index 4dc6974..1dea327 100644
--- a/src/remote/remote_driver.c
+++ b/src/remote/remote_driver.c
@@ -313,6 +313,11 @@ doRemoteOpen (virConnectPtr conn,
if (conn->uri) {
if (!conn->uri->scheme) {
/* This is the ///var/lib/xen/xend-socket local path style */
+ if (!conn->uri->path)
+ return VIR_DRV_OPEN_DECLINED;
+ if (conn->uri->path[0] != '/')
+ return VIR_DRV_OPEN_DECLINED;
+
transport = trans_unix;
} else {
transport_str = get_transport_from_scheme (conn->uri->scheme);
diff --git a/src/util/conf.c b/src/util/conf.c
index 00045b5..c8dcc7f 100644
--- a/src/util/conf.c
+++ b/src/util/conf.c
@@ -808,10 +808,8 @@ int
virConfFree(virConfPtr conf)
{
virConfEntryPtr tmp;
- if (conf == NULL) {
- virConfError(NULL, VIR_ERR_INVALID_ARG, __FUNCTION__);
- return(-1);
- }
+ if (conf == NULL)
+ return 0;
tmp = conf->entries;
while (tmp) {
diff --git a/src/xen/xen_driver.c b/src/xen/xen_driver.c
index 9c96fca..0a2267d 100644
--- a/src/xen/xen_driver.c
+++ b/src/xen/xen_driver.c
@@ -296,17 +296,7 @@ xenUnifiedOpen (virConnectPtr conn, virConnectAuthPtr auth, unsigned int flags)
conn->uri->server)
return VIR_DRV_OPEN_DECLINED;
} else {
- /* Special case URI for Xen driver only:
- *
- * Treat a plain path as a Xen UNIX socket path, and give
- * error unless path is absolute
- */
- if (!conn->uri->path || conn->uri->path[0] != '/') {
- xenUnifiedError(VIR_ERR_INTERNAL_ERROR,
- _("unexpected Xen URI path '%s', try ///var/lib/xen/xend-socket"),
- NULLSTR(conn->uri->path));
- return VIR_DRV_OPEN_ERROR;
- }
+ return VIR_DRV_OPEN_DECLINED;
}
}
--
1.7.6.4
13 years, 1 month
[libvirt] [PATCH] Add AHCI support to qemu driver
by Jim Fehlig
Tested with multiple AHCI controllers and multiple disks attached
to a controller. E.g.,
<disk type='file' device='disk'>
<driver name='qemu' type='raw'/>
<source file='/var/lib/libvirt/images/test/disk0.raw'/>
<target dev='sda' bus='sata'/>
<address type='drive' controller='0' bus='0' unit='0'/>
</disk>
<disk type='file' device='disk'>
<driver name='qemu' type='raw'/>
<source file='/var/lib/libvirt/images/test/disk1.raw'/>
<target dev='sdb' bus='sata'/>
<address type='drive' controller='0' bus='0' unit='1'/>
</disk>
<disk type='file' device='disk'>
<driver name='qemu' type='raw'/>
<source file='/var/lib/libvirt/images/test/disk2.raw'/>
<target dev='sdc' bus='sata'/>
<address type='drive' controller='1' bus='0' unit='0'/>
</disk>
<controller type='sata' index='0'>
<address type='pci' domain='0x0000' bus='0x00' slot='0x05' function='0x0'/>
</controller>
<controller type='sata' index='1'>
<address type='pci' domain='0x0000' bus='0x00' slot='0x06' function='0x0'/>
</controller>
---
docs/formatdomain.html.in | 9 +++--
docs/schemas/domaincommon.rng | 1 +
src/conf/domain_conf.c | 14 +++++++++
src/qemu/qemu_capabilities.c | 3 ++
src/qemu/qemu_capabilities.h | 1 +
src/qemu/qemu_command.c | 30 ++++++++++++++++----
.../qemuxml2argv-disk-sata-device.args | 6 ++++
.../qemuxml2argv-disk-sata-device.xml | 25 ++++++++++++++++
tests/qemuxml2argvtest.c | 3 ++
9 files changed, 82 insertions(+), 10 deletions(-)
diff --git a/docs/formatdomain.html.in b/docs/formatdomain.html.in
index 3087d01..b6a0c66 100644
--- a/docs/formatdomain.html.in
+++ b/docs/formatdomain.html.in
@@ -972,11 +972,12 @@
as a device ordering hint. The optional <code>bus</code>
attribute specifies the type of disk device to emulate;
possible values are driver specific, with typical values being
- "ide", "scsi", "virtio", "xen" or "usb". If omitted, the bus type is
- inferred from the style of the device name. eg, a device named 'sda'
- will typically be exported using a SCSI bus.
+ "ide", "scsi", "virtio", "xen", "usb" or "sata". If omitted, the bus
+ type is inferred from the style of the device name. eg, a device named
+ 'sda' will typically be exported using a SCSI bus.
<span class="since">Since 0.0.3; <code>bus</code> attribute since 0.4.3;
- "usb" attribute value since after 0.4.4</span></dd>
+ "usb" attribute value since after 0.4.4; "sata" attribute value since
+ 0.9.7</span></dd>
<dt><code>driver</code></dt>
<dd>
The optional driver element allows specifying further details
diff --git a/docs/schemas/domaincommon.rng b/docs/schemas/domaincommon.rng
index be98be0..675d55d 100644
--- a/docs/schemas/domaincommon.rng
+++ b/docs/schemas/domaincommon.rng
@@ -790,6 +790,7 @@
<value>xen</value>
<value>usb</value>
<value>uml</value>
+ <value>sata</value>
</choice>
</attribute>
</optional>
diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c
index a918679..6a7f296 100644
--- a/src/conf/domain_conf.c
+++ b/src/conf/domain_conf.c
@@ -2157,6 +2157,15 @@ virDomainDiskDefAssignAddress(virCapsPtr caps, virDomainDiskDefPtr def)
def->info.addr.drive.unit = (idx % 2);
break;
+ case VIR_DOMAIN_DISK_BUS_SATA:
+ /* For SATA we define the default mapping to be 6 units
+ * per bus, 1 bus per controller, many controllers */
+ def->info.type = VIR_DOMAIN_DEVICE_ADDRESS_TYPE_DRIVE;
+ def->info.addr.drive.controller = idx / 6;
+ def->info.addr.drive.bus = 0;
+ def->info.addr.drive.unit = idx % 6;
+ break;
+
case VIR_DOMAIN_DISK_BUS_FDC:
/* For FDC we define the default mapping to be 2 units
* per bus, 1 bus per controller, many controllers */
@@ -8675,6 +8684,11 @@ int virDomainDefAddImplicitControllers(virDomainDefPtr def)
VIR_DOMAIN_DISK_BUS_IDE) < 0)
return -1;
+ if (virDomainDefAddDiskControllersForType(def,
+ VIR_DOMAIN_CONTROLLER_TYPE_SATA,
+ VIR_DOMAIN_DISK_BUS_SATA) < 0)
+ return -1;
+
if (virDomainDefMaybeAddVirtioSerialController(def) < 0)
return -1;
diff --git a/src/qemu/qemu_capabilities.c b/src/qemu/qemu_capabilities.c
index 8e20e3f..7122756 100644
--- a/src/qemu/qemu_capabilities.c
+++ b/src/qemu/qemu_capabilities.c
@@ -139,6 +139,7 @@ VIR_ENUM_IMPL(qemuCaps, QEMU_CAPS_LAST,
"no-shutdown",
"cache-unsafe", /* 75 */
+ "ich9-ahci",
);
struct qemu_feature_flags {
@@ -1241,6 +1242,8 @@ qemuCapsParseDeviceStr(const char *str, virBitmapPtr flags)
qemuCapsSet(flags, QEMU_CAPS_USB_REDIR);
if (strstr(str, "name \"usb-hub\""))
qemuCapsSet(flags, QEMU_CAPS_USB_HUB);
+ if (strstr(str, "name \"ich9-ahci\""))
+ qemuCapsSet(flags, QEMU_CAPS_ICH9_AHCI);
/* Prefer -chardev spicevmc (detected earlier) over -device spicevmc */
if (!qemuCapsGet(flags, QEMU_CAPS_CHARDEV_SPICEVMC) &&
diff --git a/src/qemu/qemu_capabilities.h b/src/qemu/qemu_capabilities.h
index ae3de90..1e23451 100644
--- a/src/qemu/qemu_capabilities.h
+++ b/src/qemu/qemu_capabilities.h
@@ -113,6 +113,7 @@ enum qemuCapsFlags {
QEMU_CAPS_NO_SHUTDOWN = 74, /* usable -no-shutdown */
QEMU_CAPS_DRIVE_CACHE_UNSAFE = 75, /* Is cache=unsafe supported? */
+ QEMU_CAPS_ICH9_AHCI = 76, /* -device ich9-ahci */
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 9174a5f..6d6e67d 100644
--- a/src/qemu/qemu_command.c
+++ b/src/qemu/qemu_command.c
@@ -1702,6 +1702,12 @@ qemuBuildDriveDevStr(virDomainDiskDefPtr disk,
disk->info.addr.drive.bus,
disk->info.addr.drive.unit);
break;
+ case VIR_DOMAIN_DISK_BUS_SATA:
+ virBufferAddLit(&opt, "ide-drive");
+ virBufferAsprintf(&opt, ",bus=ahci%d.%d",
+ disk->info.addr.drive.controller,
+ disk->info.addr.drive.unit);
+ break;
case VIR_DOMAIN_DISK_BUS_VIRTIO:
virBufferAddLit(&opt, "virtio-blk-pci");
qemuBuildIoEventFdStr(&opt, disk->ioeventfd, qemuCaps);
@@ -1902,6 +1908,10 @@ qemuBuildControllerDevStr(virDomainControllerDefPtr def,
virBufferAsprintf(&buf, "usb-ccid,id=ccid%d", def->idx);
break;
+ case VIR_DOMAIN_CONTROLLER_TYPE_SATA:
+ virBufferAsprintf(&buf, "ahci,id=ahci%d", def->idx);
+ break;
+
case VIR_DOMAIN_CONTROLLER_TYPE_USB:
if (qemuBuildUSBControllerDevStr(def, qemuCaps, &buf) == -1)
goto error;
@@ -3683,14 +3693,22 @@ qemuBuildCommandLine(virConnectPtr conn,
cont->type == VIR_DOMAIN_CONTROLLER_TYPE_FDC)
continue;
- /* QEMU doesn't implement a SATA driver */
+ /* Only recent QEMU implements a SATA (AHCI) controller */
if (cont->type == VIR_DOMAIN_CONTROLLER_TYPE_SATA) {
- qemuReportError(VIR_ERR_CONFIG_UNSUPPORTED,
- "%s", _("SATA is not supported with this QEMU binary"));
- goto error;
- }
+ if (!qemuCapsGet(qemuCaps, QEMU_CAPS_ICH9_AHCI)) {
+ qemuReportError(VIR_ERR_CONFIG_UNSUPPORTED,
+ "%s", _("SATA is not supported with this QEMU binary"));
+ goto error;
+ } else {
+ char *devstr;
- if (def->controllers[i]->type == VIR_DOMAIN_CONTROLLER_TYPE_USB &&
+ virCommandAddArg(cmd, "-device");
+ if (!(devstr = qemuBuildControllerDevStr(cont, qemuCaps, NULL)))
+ goto error;
+
+ virCommandAddArg(cmd, devstr);
+ }
+ } else if (def->controllers[i]->type == VIR_DOMAIN_CONTROLLER_TYPE_USB &&
def->controllers[i]->model == -1 &&
!qemuCapsGet(qemuCaps, QEMU_CAPS_PIIX3_USB_UHCI)) {
if (usblegacy) {
diff --git a/tests/qemuxml2argvdata/qemuxml2argv-disk-sata-device.args b/tests/qemuxml2argvdata/qemuxml2argv-disk-sata-device.args
new file mode 100644
index 0000000..9908da6
--- /dev/null
+++ b/tests/qemuxml2argvdata/qemuxml2argv-disk-sata-device.args
@@ -0,0 +1,6 @@
+LC_ALL=C PATH=/bin HOME=/home/test USER=test LOGNAME=test /usr/bin/qemu -S -M \
+pc -m 214 -smp 1 -nographic -nodefconfig -nodefaults -monitor \
+unix:/tmp/test-monitor,server,nowait -no-acpi -boot c -device ahci,id=ahci0,\
+bus=pci.0,addr=0x3 -drive file=/dev/HostVG/QEMUGuest1,if=none,\
+id=drive-sata0-0-0 -device ide-drive,bus=ahci0.0,drive=drive-sata0-0-0,\
+id=sata0-0-0 -usb -device virtio-balloon-pci,id=balloon0,bus=pci.0,addr=0x4
diff --git a/tests/qemuxml2argvdata/qemuxml2argv-disk-sata-device.xml b/tests/qemuxml2argvdata/qemuxml2argv-disk-sata-device.xml
new file mode 100644
index 0000000..68a14f2
--- /dev/null
+++ b/tests/qemuxml2argvdata/qemuxml2argv-disk-sata-device.xml
@@ -0,0 +1,25 @@
+<domain type='qemu'>
+ <name>QEMUGuest1</name>
+ <uuid>c7a5fdbd-edaf-9455-926a-d65c16db1809</uuid>
+ <memory>219136</memory>
+ <currentMemory>219136</currentMemory>
+ <vcpu>1</vcpu>
+ <os>
+ <type arch='i686' machine='pc'>hvm</type>
+ <boot dev='hd'/>
+ </os>
+ <clock offset='utc'/>
+ <on_poweroff>destroy</on_poweroff>
+ <on_reboot>restart</on_reboot>
+ <on_crash>destroy</on_crash>
+ <devices>
+ <emulator>/usr/bin/qemu</emulator>
+ <disk type='block' device='disk'>
+ <source dev='/dev/HostVG/QEMUGuest1'/>
+ <target dev='sda' bus='sata'/>
+ <address type='drive' controller='0' bus='0' unit='0'/>
+ </disk>
+ <controller type='sata' index='0'/>
+ <memballoon model='virtio'/>
+ </devices>
+</domain>
diff --git a/tests/qemuxml2argvtest.c b/tests/qemuxml2argvtest.c
index 9e174b3..f298d37 100644
--- a/tests/qemuxml2argvtest.c
+++ b/tests/qemuxml2argvtest.c
@@ -359,6 +359,9 @@ mymain(void)
QEMU_CAPS_DRIVE, QEMU_CAPS_DEVICE, QEMU_CAPS_NODEFCONFIG);
DO_TEST("disk-scsi-device-auto", false,
QEMU_CAPS_DRIVE, QEMU_CAPS_DEVICE, QEMU_CAPS_NODEFCONFIG);
+ DO_TEST("disk-sata-device", false,
+ QEMU_CAPS_DRIVE, QEMU_CAPS_DEVICE,
+ QEMU_CAPS_NODEFCONFIG, QEMU_CAPS_ICH9_AHCI);
DO_TEST("disk-aio", false,
QEMU_CAPS_DRIVE, QEMU_CAPS_DRIVE_AIO,
QEMU_CAPS_DRIVE_CACHE_V2, QEMU_CAPS_DRIVE_FORMAT);
--
1.7.5.4
13 years, 1 month
[libvirt] [RFC] Use libssh2 for ssh transport instead of forking ssh process.
by Peter Krempa
The current state of the ssh transport involves starting the ssh client
process
(command ssh) that communicates using pipes and a socked with the
libvirt client.
Thereafter it behaves as a standard virNetSocket. This configuration has
some
drawbacks, but changing the ssh transport to libssh2 could break some users
configurations.
My concern is, that someone might be using advanced configurations of ssh
done via the ssh config file, and removing this "old" way to do it would
break it.
Libssh2 does not use any configuration files, but is configured using
the API.
The URI scheme we are using now allows to specify configuration of the
transport layer
using parameters. In my opinion, this would be a nice way how to set
configs on a
per-connection basis, but would not take into account default
configurations the users
are familiar with, while using ssh.
Advantages of using libssh2:
- no need to spawn external process and comunicate through pipes (with
all scheduling
benefits)
- multi platform support (should provide ssh support on m$ windows)
- allow to configure transport connection using the uri
- use auth callbacks to query for passwords/passphrases (no ssh-askpass)
- control over error messages
- nicely integrates with virNetSocket, as open socket must be provided
to libssh2 to
work on.
Disadvantages:
- break configurations for users that use advanced ssh configurations in
the ssh client
config file
Possible implementation options:
1.) Add libssh2 support as a new transport option (
qemu+libssh2://user@host/system )
2.) Use libssh2 as the default ssh transport provider and move old ssh
stuff to a new
transport option ( qemu+cmdssh://user@host/system, or similar)
3.) Drop old ssh completly and get mauled by users :/
4.) Leave it in current state.
5.) Add the choice on compile time.
I think, that the most favourable option is 2.) as it retains the old
way for users that
have configured it to work for them, and adding some letters to the uri
would be less
painfull for them and at the same time prefers the new api for new
configurations as
the default. Option 1) includes the risk, that tie change to the new api
would be ignored,
as nearly everybody would not care about changing their URIs even if it
would not break
anything. The two other options (not counting leaving it as-is) are
really bad in my opinion.
I'd like to have your opinions on changing the ssh transport provider.
Thanks.
Peter
13 years, 1 month
[libvirt] [PATCH] virBufferEscapeShell: Fix escaping of single quotes.
by Guido Günther
When checking if we need to escape a single quote we were looking at the
character after the quote instead of at the quote itself.
---
src/util/buf.c | 4 ++--
1 files changed, 2 insertions(+), 2 deletions(-)
diff --git a/src/util/buf.c b/src/util/buf.c
index 7dd9852..2d9499a 100644
--- a/src/util/buf.c
+++ b/src/util/buf.c
@@ -524,13 +524,13 @@ virBufferEscapeShell(virBufferPtr buf, const char *str)
*out++ = '\'';
while (*cur != 0) {
- *out++ = *cur++;
if (*cur == '\'') {
+ *out++ = '\'';
/* Replace literal ' with a close ', a \', and a open ' */
*out++ = '\\';
*out++ = '\'';
- *out++ = '\'';
}
+ *out++ = *cur++;
}
*out++ = '\'';
*out = 0;
--
1.7.6.3
13 years, 1 month
[libvirt] Compiler warnings
by Alex Jia
Hi all,
I meet the following compiler warnings today:
......
CC libvirt_util_la-buf.lo
util/buf.c: In function 'virBufferEscape':
util/buf.c:430: warning: logical '&&' with non-zero constant will always
evaluate as true [-Wlogical-op]
CC libvirt_util_la-command.lo
......
CC libvirt_lxc-buf.o
util/buf.c: In function 'virBufferEscape':
util/buf.c:430: warning: logical '&&' with non-zero constant will always
evaluate as true [-Wlogical-op]
CC libvirt_lxc-command.o
......
Has anybody the same experience?
Thanks,
Alex
13 years, 1 month
[libvirt] [PATCH] compile: Add a missing function 'pciDeviceListFind' to libvirt_private.syms
by Xu He Jie
compile error:
../src/.libs/libvirt_driver_qemu.a(libvirt_driver_qemu_la-qemu_hostdev.o): In function `qemuPrepareHostdevPCIDevices':
/home/soulxu/data/work-code/libvirt/src/qemu/qemu_hostdev.c:183: undefined reference to `pciDeviceListFind'
/home/soulxu/data/work-code/libvirt/src/qemu/qemu_hostdev.c:230: undefined reference to `pciDeviceListFind'
../src/.libs/libvirt_driver_qemu.a(libvirt_driver_qemu_la-qemu_hostdev.o): In function `qemuGetActivePciHostDeviceList':
/home/soulxu/data/work-code/libvirt/src/qemu/qemu_hostdev.c:102: undefined reference to `pciDeviceListFind'
../src/.libs/libvirt_driver_qemu.a(libvirt_driver_qemu_la-qemu_hostdev.o): In function `qemuDomainReAttachHostdevDevices':
/home/soulxu/data/work-code/libvirt/src/qemu/qemu_hostdev.c:370: undefined reference to `pciDeviceListFind'
Signed-off-by: Xu He Jie <xuhj(a)linux.vnet.ibm.com>
---
src/libvirt_private.syms | 1 +
1 files changed, 1 insertions(+), 0 deletions(-)
diff --git a/src/libvirt_private.syms b/src/libvirt_private.syms
index 1e03e33..61f4dc4 100644
--- a/src/libvirt_private.syms
+++ b/src/libvirt_private.syms
@@ -892,6 +892,7 @@ pciDeviceListFree;
pciDeviceListGet;
pciDeviceListNew;
pciDeviceListSteal;
+pciDeviceListFind;
pciDeviceNetName;
pciDeviceReAttachInit;
pciDeviceSetManaged;
--
1.7.4.1
13 years, 1 month
[libvirt] [PATCH] qemu: Relax -no-shutdown check to [0.14.0, 0.15.0]
by Jiri Denemark
The patch that fixes SIGTERM handling with -no-shutdown was taken into
0.15.1 stable release of qemu.
---
src/qemu/qemu_capabilities.c | 4 ++--
1 files changed, 2 insertions(+), 2 deletions(-)
diff --git a/src/qemu/qemu_capabilities.c b/src/qemu/qemu_capabilities.c
index 8f16a49..2f55000 100644
--- a/src/qemu/qemu_capabilities.c
+++ b/src/qemu/qemu_capabilities.c
@@ -1018,9 +1018,9 @@ qemuCapsComputeCmdFlags(const char *help,
/* Do not use -no-shutdown if qemu doesn't support it or SIGTERM handling
* is most likely buggy when used with -no-shutdown (which applies for qemu
- * 0.14.* and <0.15.50)
+ * 0.14.* and 0.15.0)
*/
- if (strstr(help, "-no-shutdown") && (version < 14000 || version >= 15050))
+ if (strstr(help, "-no-shutdown") && (version < 14000 || version > 15000))
qemuCapsSet(flags, QEMU_CAPS_NO_SHUTDOWN);
/*
--
1.7.7
13 years, 1 month
[libvirt] [PATCH] Fix VPATH build
by Jiri Denemark
probes.h is generated in build directory; setting a dependency on
probes.h from source directory doesn't work well in VPATH builds. Caused
by commit 1afcfbdda0cac112faa61f74ec943e46aa43f2f5
---
src/Makefile.am | 2 +-
1 files changed, 1 insertions(+), 1 deletions(-)
diff --git a/src/Makefile.am b/src/Makefile.am
index 510e5ef..87d91ed 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -191,7 +191,7 @@ REMOTE_DRIVER_GENERATED = \
# The remote RPC driver needs probes.h
if WITH_DTRACE
-REMOTE_DRIVER_GENERATED += $(srcdir)/probes.h
+REMOTE_DRIVER_GENERATED += probes.h
endif
REMOTE_PROTOCOL = $(srcdir)/remote/remote_protocol.x
--
1.7.7
13 years, 1 month
[libvirt] [PATCH] qemu: Honor the original properties of PCI device when detaching
by Osier Yang
This patch fixes two problems:
1) The device will be reattached to host even if it's not
managed, as there is a "pciDeviceSetManaged".
2) The device won't be reattached to host with original
driver properly. As it doesn't honor the device original
properties which are maintained by driver->activePciHostdevs.
---
src/qemu/qemu_hotplug.c | 16 ++++++++--------
1 files changed, 8 insertions(+), 8 deletions(-)
diff --git a/src/qemu/qemu_hotplug.c b/src/qemu/qemu_hotplug.c
index bfa524b..f3f0060 100644
--- a/src/qemu/qemu_hotplug.c
+++ b/src/qemu/qemu_hotplug.c
@@ -1956,6 +1956,7 @@ int qemuDomainDetachHostPciDevice(struct qemud_driver *driver,
qemuDomainObjPrivatePtr priv = vm->privateData;
int i, ret;
pciDevice *pci;
+ pciDevice *activePci;
for (i = 0 ; i < vm->def->nhostdevs ; i++) {
if (vm->def->hostdevs[i]->mode != VIR_DOMAIN_HOSTDEV_MODE_SUBSYS ||
@@ -2015,16 +2016,15 @@ int qemuDomainDetachHostPciDevice(struct qemud_driver *driver,
detach->source.subsys.u.pci.bus,
detach->source.subsys.u.pci.slot,
detach->source.subsys.u.pci.function);
- if (!pci)
- ret = -1;
- else {
- pciDeviceSetManaged(pci, detach->managed);
- pciDeviceListDel(driver->activePciHostdevs, pci);
- if (pciResetDevice(pci, driver->activePciHostdevs, NULL) < 0)
+ if (pci) {
+ activePci = pciDeviceListSteal(driver->activePciHostdevs, pci);
+ if (pciResetDevice(activePci, driver->activePciHostdevs, NULL) < 0)
ret = -1;
- pciDeviceReAttachInit(pci);
- qemuReattachPciDevice(pci, driver);
+ qemuReattachPciDevice(activePci, driver);
pciFreeDevice(pci);
+ pciFreeDevice(activePci);
+ } else {
+ ret = -1;
}
if (qemuCapsGet(priv->qemuCaps, QEMU_CAPS_DEVICE) &&
--
1.7.6
13 years, 1 month