diff --git a/ChangeLog b/ChangeLog index 3d8bb994a2..c24edc6ab4 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,11 @@ +Tue Feb 26 08:02:57 CET 2008 Daniel Veillard + + * src/driver.h src/libvirt.c src/openvz_driver.c src/qemu_driver.c + src/remote_internal.c src/test.c src/util.c src/util.h + src/xen_unified.c: added probe interface at the driver level, + use that to improve default hypervisor selection in the absence + of a given URI when connecting + Mon Feb 25 14:53:59 CET 2008 Daniel Veillard * src/Makefile.am src/util-lib.h: fix done with Jim to allow diff --git a/src/driver.h b/src/driver.h index 4db972b455..6e0df332a6 100644 --- a/src/driver.h +++ b/src/driver.h @@ -69,6 +69,8 @@ typedef enum { #define VIR_DRV_SUPPORTS_FEATURE(drv,conn,feature) \ ((drv)->supports_feature ? (drv)->supports_feature((conn),(feature)) : 0) +typedef const char * + (*virDrvProbe) (void); typedef virDrvOpenStatus (*virDrvOpen) (virConnectPtr conn, xmlURIPtr uri, @@ -277,62 +279,63 @@ typedef unsigned long long * - close */ 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; + int no; /* the number virDrvNo */ + const char * name; /* the name of the driver */ + unsigned long ver; /* the version of the backend */ + virDrvProbe probe; + virDrvOpen open; + virDrvClose close; virDrvSupportsFeature supports_feature; - virDrvGetType type; - virDrvGetVersion version; + virDrvGetType type; + virDrvGetVersion version; virDrvGetHostname getHostname; virDrvGetURI getURI; - virDrvGetMaxVcpus getMaxVcpus; - virDrvNodeGetInfo nodeGetInfo; - virDrvGetCapabilities getCapabilities; - virDrvListDomains listDomains; - virDrvNumOfDomains numOfDomains; - virDrvDomainCreateLinux domainCreateLinux; - virDrvDomainLookupByID domainLookupByID; - virDrvDomainLookupByUUID domainLookupByUUID; - virDrvDomainLookupByName domainLookupByName; - virDrvDomainSuspend domainSuspend; - virDrvDomainResume domainResume; - virDrvDomainShutdown domainShutdown; - virDrvDomainReboot domainReboot; - virDrvDomainDestroy domainDestroy; - virDrvDomainGetOSType domainGetOSType; - virDrvDomainGetMaxMemory domainGetMaxMemory; - virDrvDomainSetMaxMemory domainSetMaxMemory; - virDrvDomainSetMemory domainSetMemory; - virDrvDomainGetInfo domainGetInfo; - virDrvDomainSave domainSave; - virDrvDomainRestore domainRestore; - virDrvDomainCoreDump domainCoreDump; - virDrvDomainSetVcpus domainSetVcpus; - virDrvDomainPinVcpu domainPinVcpu; - virDrvDomainGetVcpus domainGetVcpus; - virDrvDomainGetMaxVcpus domainGetMaxVcpus; - virDrvDomainDumpXML domainDumpXML; - virDrvListDefinedDomains listDefinedDomains; - virDrvNumOfDefinedDomains numOfDefinedDomains; - virDrvDomainCreate domainCreate; - virDrvDomainDefineXML domainDefineXML; - virDrvDomainUndefine domainUndefine; - virDrvDomainAttachDevice domainAttachDevice; - virDrvDomainDetachDevice domainDetachDevice; - virDrvDomainGetAutostart domainGetAutostart; - virDrvDomainSetAutostart domainSetAutostart; - virDrvDomainGetSchedulerType domainGetSchedulerType; - virDrvDomainGetSchedulerParameters domainGetSchedulerParameters; - virDrvDomainSetSchedulerParameters domainSetSchedulerParameters; + virDrvGetMaxVcpus getMaxVcpus; + virDrvNodeGetInfo nodeGetInfo; + virDrvGetCapabilities getCapabilities; + virDrvListDomains listDomains; + virDrvNumOfDomains numOfDomains; + virDrvDomainCreateLinux domainCreateLinux; + virDrvDomainLookupByID domainLookupByID; + virDrvDomainLookupByUUID domainLookupByUUID; + virDrvDomainLookupByName domainLookupByName; + virDrvDomainSuspend domainSuspend; + virDrvDomainResume domainResume; + virDrvDomainShutdown domainShutdown; + virDrvDomainReboot domainReboot; + virDrvDomainDestroy domainDestroy; + virDrvDomainGetOSType domainGetOSType; + virDrvDomainGetMaxMemory domainGetMaxMemory; + virDrvDomainSetMaxMemory domainSetMaxMemory; + virDrvDomainSetMemory domainSetMemory; + virDrvDomainGetInfo domainGetInfo; + virDrvDomainSave domainSave; + virDrvDomainRestore domainRestore; + virDrvDomainCoreDump domainCoreDump; + virDrvDomainSetVcpus domainSetVcpus; + virDrvDomainPinVcpu domainPinVcpu; + virDrvDomainGetVcpus domainGetVcpus; + virDrvDomainGetMaxVcpus domainGetMaxVcpus; + virDrvDomainDumpXML domainDumpXML; + virDrvListDefinedDomains listDefinedDomains; + virDrvNumOfDefinedDomains numOfDefinedDomains; + virDrvDomainCreate domainCreate; + virDrvDomainDefineXML domainDefineXML; + virDrvDomainUndefine domainUndefine; + virDrvDomainAttachDevice domainAttachDevice; + virDrvDomainDetachDevice domainDetachDevice; + virDrvDomainGetAutostart domainGetAutostart; + virDrvDomainSetAutostart domainSetAutostart; + virDrvDomainGetSchedulerType domainGetSchedulerType; + virDrvDomainGetSchedulerParameters domainGetSchedulerParameters; + virDrvDomainSetSchedulerParameters domainSetSchedulerParameters; virDrvDomainMigratePrepare domainMigratePrepare; virDrvDomainMigratePerform domainMigratePerform; virDrvDomainMigrateFinish domainMigrateFinish; virDrvDomainBlockStats domainBlockStats; virDrvDomainInterfaceStats domainInterfaceStats; - virDrvNodeGetCellsFreeMemory nodeGetCellsFreeMemory; - virDrvNodeGetFreeMemory getFreeMemory; + virDrvNodeGetCellsFreeMemory nodeGetCellsFreeMemory; + virDrvNodeGetFreeMemory getFreeMemory; }; typedef int diff --git a/src/libvirt.c b/src/libvirt.c index 897a953bc8..29dba0a7af 100644 --- a/src/libvirt.c +++ b/src/libvirt.c @@ -632,9 +632,47 @@ do_open (const char *name, virConnectPtr ret = NULL; xmlURIPtr uri; - /* Convert NULL or "" to xen:/// for back compat */ - if (!name || name[0] == '\0') - name = "xen:///"; + /* + * If no URI is passed, then check for an environment string if not + * available probe the compiled in drivers to find a default hypervisor + * if detectable. + */ + if (!name || name[0] == '\0') { + char *defname = getenv("LIBVIRT_DEFAULT_URI"); + if (defname && *defname) { + DEBUG("Using LIBVIRT_DEFAULT_URI %s", defname); + name = defname; + } else { + const char *use = NULL; + const char *latest; + int probes = 0; + for (i = 0; i < virNetworkDriverTabCount; i++) { + if ((virDriverTab[i]->probe != NULL) && + ((latest = virDriverTab[i]->probe()) != NULL)) { + probes++; + + DEBUG("Probed %s", latest); + /* + * if running a xen kernel, give it priority over + * QEmu emultation + */ + if (STREQ(latest, "xen:///")) + use = latest; + else if (use == NULL) + use = latest; + } + } + if (use == NULL) { + name = "xen:///"; + DEBUG("Could not probe any hypervisor defaulting to %s", + name); + } else { + name = use; + DEBUG("Using %s as default URI, %d hypervisor found", + use, probes); + } + } + } /* Convert xen -> xen:/// for back compat */ if (!strcasecmp(name, "xen")) diff --git a/src/openvz_driver.c b/src/openvz_driver.c index c1b506a99e..29cb24494e 100644 --- a/src/openvz_driver.c +++ b/src/openvz_driver.c @@ -546,6 +546,15 @@ bail_out5: return ret; } +static const char *openvzProbe(void) +{ +#ifdef __linux__ + if ((getuid() == 0) && (virFileExists("/proc/vz"))) + return("openvz:///"); +#endif + return(NULL); +} + static virDrvOpenStatus openvzOpen(virConnectPtr conn, xmlURIPtr uri, virConnectAuthPtr auth ATTRIBUTE_UNUSED, @@ -694,6 +703,7 @@ static virDriver openvzDriver = { VIR_DRV_OPENVZ, "OPENVZ", LIBVIR_VERSION_NUMBER, + openvzProbe, /* probe */ openvzOpen, /* open */ openvzClose, /* close */ NULL, /* supports_feature */ diff --git a/src/qemu_driver.c b/src/qemu_driver.c index 9a39644245..b711dc1f0f 100644 --- a/src/qemu_driver.c +++ b/src/qemu_driver.c @@ -1388,6 +1388,25 @@ static int qemudMonitorCommand(struct qemud_driver *driver ATTRIBUTE_UNUSED, return -1; } +/** + * qemudProbe: + * + * Probe for the availability of the qemu driver, assume the + * presence of QEmu emulation if the binaries are installed + */ +static const char *qemudProbe(void) +{ + if ((virFileExists("/usr/bin/qemu")) || + (virFileExists("/usr/bin/qemu-kvm")) || + (virFileExists("/usr/bin/xenner"))) { + if (getuid() == 0) { + return("qemu:///system"); + } else { + return("qemu:///session"); + } + } + return(NULL); +} static virDrvOpenStatus qemudOpen(virConnectPtr conn, xmlURIPtr uri, @@ -2859,6 +2878,7 @@ static virDriver qemuDriver = { VIR_DRV_QEMU, "QEMU", LIBVIR_VERSION_NUMBER, + qemudProbe, /* probe */ qemudOpen, /* open */ qemudClose, /* close */ NULL, /* supports_feature */ diff --git a/src/remote_internal.c b/src/remote_internal.c index 9e569ae9a7..11d299ba37 100644 --- a/src/remote_internal.c +++ b/src/remote_internal.c @@ -4599,6 +4599,7 @@ static virDriver driver = { .no = VIR_DRV_REMOTE, .name = "remote", .ver = REMOTE_PROTOCOL_VERSION, + .probe = NULL, .open = remoteOpen, .close = remoteClose, .supports_feature = remoteSupportsFeature, diff --git a/src/test.c b/src/test.c index 1d064d3c41..ce8cea8f8f 100644 --- a/src/test.c +++ b/src/test.c @@ -1939,6 +1939,7 @@ static virDriver testDriver = { VIR_DRV_TEST, "Test", LIBVIR_VERSION_NUMBER, + NULL, /* probe */ testOpen, /* open */ testClose, /* close */ NULL, /* supports_feature */ diff --git a/src/util.c b/src/util.c index 67cb0b816e..da1610a036 100644 --- a/src/util.c +++ b/src/util.c @@ -463,6 +463,15 @@ virFileLinkPointsTo (const char *checkLink ATTRIBUTE_UNUSED, #endif /*! __MINGW32__ */ +int virFileExists(const char *path) +{ + struct stat st; + + if (stat(path, &st) >= 0) + return(1); + return(0); +} + int virFileMakePath(const char *path) { struct stat st; diff --git a/src/util.h b/src/util.h index 23a016de5c..4ababaecf3 100644 --- a/src/util.h +++ b/src/util.h @@ -47,6 +47,9 @@ int virFileHasSuffix(const char *str, int virFileLinkPointsTo(const char *checkLink, const char *checkDest); + +int virFileExists(const char *path); + int virFileMakePath(const char *path); int virFileBuildPath(const char *dir, diff --git a/src/xen_unified.c b/src/xen_unified.c index 8dd82c45ca..50d49b6d3a 100644 --- a/src/xen_unified.c +++ b/src/xen_unified.c @@ -39,6 +39,7 @@ #include "xs_internal.h" #include "xm_internal.h" #include "xml.h" +#include "util.h" #define DEBUG(fmt,...) VIR_DEBUG(__FILE__, fmt,__VA_ARGS__) @@ -217,6 +218,24 @@ done: * in the low level drivers directly. */ +static const char * +xenUnifiedProbe (void) +{ +#ifdef __linux__ + if (virFileExists("/proc/xen")) + return("xen:///"); +#endif +#ifdef __sun__ + FILE *fh; + + if (fh = fopen("/dev/xen/domcaps", "r")) { + fclose(fh); + return("xen:///"); + } +#endif + return(NULL); +} + static int xenUnifiedOpen (virConnectPtr conn, xmlURIPtr uri, virConnectAuthPtr auth, int flags) { @@ -1198,6 +1217,7 @@ static virDriver xenUnifiedDriver = { .no = VIR_DRV_XEN_UNIFIED, .name = "Xen", .ver = HV_VERSION, + .probe = xenUnifiedProbe, .open = xenUnifiedOpen, .close = xenUnifiedClose, .supports_feature = xenUnifiedSupportsFeature,