On Wed, Nov 26, 2008 at 10:08:03PM +0000, Daniel P. Berrange wrote:
When connecting to a local libvirt you can let it automatically
probe
the hypervisor URI if you don't know it ahead of time. This doesn't
work with remote URIs because you need to have something to put in
the URI scheme before the hostname
qemu+ssh://somehost/system
xen+tcp://somehost/system
This is then translated into the URI
qemu:///system
xen:///
It occurred to me that we can trivially enable probing with all existing
libvirtd daemon releases, simply by fixing the client side. All we need
todo is invent a new generic URI scheme, and convert that to empty string
This patch adds a 'remote' URI scheme, usable like this
remote+ssh://somehost/
remote+tcp://somehost/
remote://somehost/
remote+tls://somehost/
remote+ext://somehost/
In all these styles, the URI passed to the remote daemon is "", causing
it to probe.
As a demonstration, here's an example using virsh and two hosts I have,
one running Xen, the other QEMU
See it automatically choosing QEMU....
$ virsh --connect remote+ssh://root@lettuce/ version
Compiled against library: libvir 0.5.0
Using library: libvir 0.5.0
Running hypervisor: QEMU 0.9.1
And choosing Xen....
$ virsh --connect remote+ssh://root@pumpkin/ version
Compiled against library: libvir 0.5.0
Using library: libvir 0.5.0
Running hypervisor: Xen 3.1.0
This finally makes the Avahi broadcasts useful - they only include
info on the hostname + data transport (SSH, TCP, TLS), not the HV
type. So letting us use auto-probing remotely is the missing link.
NB. we've got a small problem with the virGetVersion() API - it does not
take a connection URI - just a hypervisor type. It then directly checks
the statically declared 'version' field in the virDriverPtr struct.
This no longer works now that some drivers are linked directly into the
libvirt daemon.
I'm thinking that perhaps we can just change the virGetVersion() apis
so that instead of looking in virDriverPtr struct, we just include the
version numbers directly in virGetVersion as a static const lookup
table. Meanwhile, this patch also includes a change to virsh to stop
it calling virGetVersion(), though this hunk instead intended to apply
to CVS.
The attached patch does just this now - we remove the version field from
the virDriverPtr, and just hardwire info for all compiled drivers into
the virGetVersion impl directly, avoiding need to access the drivers
which may not be present.
Daniel
Index: src/driver.h
===================================================================
RCS file: /data/cvs/libvirt/src/driver.h,v
retrieving revision 1.64
diff -u -p -r1.64 driver.h
--- src/driver.h 21 Nov 2008 12:19:22 -0000 1.64
+++ src/driver.h 27 Nov 2008 16:24:19 -0000
@@ -328,7 +328,6 @@ typedef virDomainPtr
struct _virDriver {
int no; /* the number virDrvNo */
const char * name; /* the name of the driver */
- unsigned long ver; /* the version of the backend */
virDrvOpen open;
virDrvClose close;
virDrvDrvSupportsFeature supports_feature;
Index: src/libvirt.c
===================================================================
RCS file: /data/cvs/libvirt/src/libvirt.c,v
retrieving revision 1.180
diff -u -p -r1.180 libvirt.c
--- src/libvirt.c 25 Nov 2008 15:48:19 -0000 1.180
+++ src/libvirt.c 27 Nov 2008 16:24:19 -0000
@@ -734,7 +734,6 @@ int
virGetVersion(unsigned long *libVer, const char *type,
unsigned long *typeVer)
{
- int i;
DEBUG("libVir=%p, type=%s, typeVer=%p", libVer, type, typeVer);
if (!initialized)
@@ -748,15 +747,36 @@ virGetVersion(unsigned long *libVer, con
if (typeVer != NULL) {
if (type == NULL)
type = "Xen";
- for (i = 0;i < virDriverTabCount;i++) {
- if ((virDriverTab[i] != NULL) &&
- (STRCASEEQ(virDriverTab[i]->name, type))) {
- *typeVer = virDriverTab[i]->ver;
- break;
- }
- }
- if (i >= virDriverTabCount) {
- *typeVer = 0;
+ *typeVer = 0;
+#if WITH_XEN
+ if (STRCASEEQ(type, "Xen"))
+ *typeVer = xenUnifiedVersion();
+#endif
+#if WITH_TEST
+ if (STRCASEEQ(type, "Test"))
+ *typeVer = LIBVIR_VERSION_NUMBER;
+#endif
+#if WITH_QEMU
+ if (STRCASEEQ(type, "QEMU"))
+ *typeVer = LIBVIR_VERSION_NUMBER;
+#endif
+#if WITH_LXC
+ if (STRCASEEQ(type, "LXC"))
+ *typeVer = LIBVIR_VERSION_NUMBER;
+#endif
+#if WITH_OPENVZ
+ if (STRCASEEQ(type, "OpenVZ"))
+ *typeVer = LIBVIR_VERSION_NUMBER;
+#endif
+#if WITH_UML
+ if (STRCASEEQ(type, "UML"))
+ *typeVer = LIBVIR_VERSION_NUMBER;
+#endif
+#if WITH_REMOTE
+ if (STRCASEEQ(type, "Remote"))
+ *typeVer = remoteVersion();
+#endif
+ if (*typeVer == 0) {
virLibConnError(NULL, VIR_ERR_NO_SUPPORT, type);
return (-1);
}
Index: src/lxc_driver.c
===================================================================
RCS file: /data/cvs/libvirt/src/lxc_driver.c,v
retrieving revision 1.48
diff -u -p -r1.48 lxc_driver.c
--- src/lxc_driver.c 21 Nov 2008 11:42:51 -0000 1.48
+++ src/lxc_driver.c 27 Nov 2008 16:24:19 -0000
@@ -1232,7 +1232,6 @@ static int lxcGetSchedulerParameters(vir
static virDriver lxcDriver = {
VIR_DRV_LXC, /* the number virDrvNo */
"LXC", /* the name of the driver */
- LIBVIR_VERSION_NUMBER, /* the version of the backend */
lxcOpen, /* open */
lxcClose, /* close */
NULL, /* supports_feature */
Index: src/openvz_driver.c
===================================================================
RCS file: /data/cvs/libvirt/src/openvz_driver.c,v
retrieving revision 1.61
diff -u -p -r1.61 openvz_driver.c
--- src/openvz_driver.c 24 Nov 2008 19:34:21 -0000 1.61
+++ src/openvz_driver.c 27 Nov 2008 16:24:19 -0000
@@ -1087,7 +1087,6 @@ static int openvzNumDefinedDomains(virCo
static virDriver openvzDriver = {
VIR_DRV_OPENVZ,
"OPENVZ",
- LIBVIR_VERSION_NUMBER,
openvzOpen, /* open */
openvzClose, /* close */
NULL, /* supports_feature */
Index: src/qemu_driver.c
===================================================================
RCS file: /data/cvs/libvirt/src/qemu_driver.c,v
retrieving revision 1.160
diff -u -p -r1.160 qemu_driver.c
--- src/qemu_driver.c 21 Nov 2008 12:16:08 -0000 1.160
+++ src/qemu_driver.c 27 Nov 2008 16:24:19 -0000
@@ -3724,7 +3724,6 @@ qemudDomainMigrateFinish2 (virConnectPtr
static virDriver qemuDriver = {
VIR_DRV_QEMU,
"QEMU",
- LIBVIR_VERSION_NUMBER,
qemudOpen, /* open */
qemudClose, /* close */
qemudSupportsFeature, /* supports_feature */
Index: src/remote_internal.c
===================================================================
RCS file: /data/cvs/libvirt/src/remote_internal.c,v
retrieving revision 1.108
diff -u -p -r1.108 remote_internal.c
--- src/remote_internal.c 21 Nov 2008 12:31:04 -0000 1.108
+++ src/remote_internal.c 27 Nov 2008 16:24:20 -0000
@@ -430,28 +430,40 @@ doRemoteOpen (virConnectPtr conn,
/* Construct the original name. */
if (!name) {
- xmlURI tmpuri = {
- .scheme = conn->uri->scheme,
+ if (STREQ(conn->uri->scheme, "remote") ||
+ STRPREFIX(conn->uri->scheme, "remote+")) {
+ /* Allow remote serve to probe */
+ name = strdup("");
+ } else {
+ xmlURI tmpuri = {
+ .scheme = conn->uri->scheme,
#ifdef HAVE_XMLURI_QUERY_RAW
- .query_raw = qparam_get_query (vars),
+ .query_raw = qparam_get_query (vars),
#else
- .query = qparam_get_query (vars),
+ .query = qparam_get_query (vars),
#endif
- .path = conn->uri->path,
- .fragment = conn->uri->fragment,
- };
-
- /* Evil, blank out transport scheme temporarily */
- if (transport_str) {
- assert (transport_str[-1] == '+');
- transport_str[-1] = '\0';
- }
+ .path = conn->uri->path,
+ .fragment = conn->uri->fragment,
+ };
+
+ /* Evil, blank out transport scheme temporarily */
+ if (transport_str) {
+ assert (transport_str[-1] == '+');
+ transport_str[-1] = '\0';
+ }
- name = (char *) xmlSaveUri (&tmpuri);
+ name = (char *) xmlSaveUri (&tmpuri);
- /* Restore transport scheme */
- if (transport_str)
- transport_str[-1] = '+';
+#ifdef HAVE_XMLURI_QUERY_RAW
+ VIR_FREE(tmpuri.query_raw);
+#else
+ VIR_FREE(tmpuri.query);
+#endif
+
+ /* Restore transport scheme */
+ if (transport_str)
+ transport_str[-1] = '+';
+ }
}
free_qparam_set (vars);
@@ -1330,7 +1342,7 @@ remoteType (virConnectPtr conn)
}
static int
-remoteVersion (virConnectPtr conn, unsigned long *hvVer)
+remoteGetVersion (virConnectPtr conn, unsigned long *hvVer)
{
remote_get_version_ret ret;
GET_PRIVATE (conn, -1);
@@ -5300,15 +5312,19 @@ make_nonnull_storage_vol (remote_nonnull
/*----------------------------------------------------------------------*/
+unsigned long remoteVersion(void)
+{
+ return REMOTE_PROTOCOL_VERSION;
+}
+
static virDriver driver = {
.no = VIR_DRV_REMOTE,
.name = "remote",
- .ver = REMOTE_PROTOCOL_VERSION,
.open = remoteOpen,
.close = remoteClose,
.supports_feature = remoteSupportsFeature,
.type = remoteType,
- .version = remoteVersion,
+ .version = remoteGetVersion,
.getHostname = remoteGetHostname,
.getMaxVcpus = remoteGetMaxVcpus,
.nodeGetInfo = remoteNodeGetInfo,
Index: src/remote_internal.h
===================================================================
RCS file: /data/cvs/libvirt/src/remote_internal.h,v
retrieving revision 1.6
diff -u -p -r1.6 remote_internal.h
--- src/remote_internal.h 20 Aug 2008 20:48:36 -0000 1.6
+++ src/remote_internal.h 27 Nov 2008 16:24:20 -0000
@@ -28,6 +28,8 @@
int remoteRegister (void);
+unsigned long remoteVersion(void);
+
#define LIBVIRTD_LISTEN_ADDR NULL
#define LIBVIRTD_TLS_PORT "16514"
#define LIBVIRTD_TCP_PORT "16509"
Index: src/test.c
===================================================================
RCS file: /data/cvs/libvirt/src/test.c,v
retrieving revision 1.96
diff -u -p -r1.96 test.c
--- src/test.c 17 Nov 2008 11:44:51 -0000 1.96
+++ src/test.c 27 Nov 2008 16:24:20 -0000
@@ -2194,7 +2194,6 @@ testStorageVolumeGetPath(virStorageVolPt
static virDriver testDriver = {
VIR_DRV_TEST,
"Test",
- LIBVIR_VERSION_NUMBER,
testOpen, /* open */
testClose, /* close */
NULL, /* supports_feature */
Index: src/uml_driver.c
===================================================================
RCS file: /data/cvs/libvirt/src/uml_driver.c,v
retrieving revision 1.2
diff -u -p -r1.2 uml_driver.c
--- src/uml_driver.c 21 Nov 2008 10:06:28 -0000 1.2
+++ src/uml_driver.c 27 Nov 2008 16:24:20 -0000
@@ -1592,7 +1592,6 @@ found:
static virDriver umlDriver = {
VIR_DRV_UML,
"UML",
- LIBVIR_VERSION_NUMBER,
umlOpen, /* open */
umlClose, /* close */
NULL, /* supports_feature */
Index: src/xen_unified.c
===================================================================
RCS file: /data/cvs/libvirt/src/xen_unified.c,v
retrieving revision 1.65
diff -u -p -r1.65 xen_unified.c
--- src/xen_unified.c 27 Nov 2008 16:16:13 -0000 1.65
+++ src/xen_unified.c 27 Nov 2008 16:24:20 -0000
@@ -392,6 +392,17 @@ xenUnifiedClose (virConnectPtr conn)
return 0;
}
+
+#define HV_VERSION ((DOM0_INTERFACE_VERSION >> 24) * 1000000 + \
+ ((DOM0_INTERFACE_VERSION >> 16) & 0xFF) * 1000 + \
+ (DOM0_INTERFACE_VERSION & 0xFFFF))
+
+unsigned long xenUnifiedVersion(void)
+{
+ return HV_VERSION;
+}
+
+
static const char *
xenUnifiedType (virConnectPtr conn)
{
@@ -416,7 +427,7 @@ xenUnifiedSupportsFeature (virConnectPtr
}
static int
-xenUnifiedVersion (virConnectPtr conn, unsigned long *hvVer)
+xenUnifiedGetVersion (virConnectPtr conn, unsigned long *hvVer)
{
GET_PRIVATE(conn);
int i;
@@ -1366,20 +1377,15 @@ xenUnifiedDomainEventDeregister (virConn
/*----- Register with libvirt.c, and initialise Xen drivers. -----*/
-#define HV_VERSION ((DOM0_INTERFACE_VERSION >> 24) * 1000000 + \
- ((DOM0_INTERFACE_VERSION >> 16) & 0xFF) * 1000 + \
- (DOM0_INTERFACE_VERSION & 0xFFFF))
-
/* The interface which we export upwards to libvirt.c. */
static virDriver xenUnifiedDriver = {
.no = VIR_DRV_XEN_UNIFIED,
.name = "Xen",
- .ver = HV_VERSION,
.open = xenUnifiedOpen,
.close = xenUnifiedClose,
.supports_feature = xenUnifiedSupportsFeature,
.type = xenUnifiedType,
- .version = xenUnifiedVersion,
+ .version = xenUnifiedGetVersion,
.getHostname = xenUnifiedGetHostname,
.getMaxVcpus = xenUnifiedGetMaxVcpus,
.nodeGetInfo = xenUnifiedNodeGetInfo,
Index: src/xen_unified.h
===================================================================
RCS file: /data/cvs/libvirt/src/xen_unified.h,v
retrieving revision 1.19
diff -u -p -r1.19 xen_unified.h
--- src/xen_unified.h 25 Nov 2008 10:44:53 -0000 1.19
+++ src/xen_unified.h 27 Nov 2008 16:24:20 -0000
@@ -185,4 +185,6 @@ void xenUnifiedDomainEventDispatch (xenU
virDomainPtr dom,
int event,
int detail);
+unsigned long xenUnifiedVersion(void);
+
#endif /* __VIR_XEN_UNIFIED_H__ */
--
|: Red Hat, Engineering, London -o-
http://people.redhat.com/berrange/ :|
|:
http://libvirt.org -o-
http://virt-manager.org -o-
http://ovirt.org :|
|:
http://autobuild.org -o-
http://search.cpan.org/~danberr/ :|
|: GnuPG: 7D3B9505 -o- F3C9 553F A1DA 4AC2 5648 23C1 B3DF F742 7D3B 9505 :|