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 :| -- Libvir-list mailing list Libvir-list@xxxxxxxxxx https://www.redhat.com/mailman/listinfo/libvir-list