Unified Xen patch (incomplete, for discussion)

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



I've spent the last day or so producing a unified Xen patch. In such a model a connection contains only a single underlying driver, and it is the responsibility of the (unified) Xen driver to try all the different methods it knows.

Attached is an incomplete patch for this, for discussion, plus the two extra files of the unified driver itself (for some reason CVS won't give me a diff including these added files).

Some points to note:

The new structure of the drivers is:

<pre>
  libvirt.c
    |
    +------- xen_unified.c
    |           |
    |           +--- xen_internal.c  (hypervisor)
    |           |
    |           +--- proxy_internal.c * (proxy)
    |           |
    |           +--- xend_internal.c * (XenD)
    |           |
    |           +--- xs_internal.c (XenStore)
    |           |
    |           +--- xm_internal.c * (inactive domains)
    |
    +-------- qemu_internal.c *
    |
    +-------- test.c

* = not updated yet, so these don't compile
</pre>

I haven't renamed the Xen sub-drivers. That's really to make the patch easier to read. There is definitely a case for renaming the drivers more logically to reflect the structure above.

All Xen-specific hacks in libvirt.c have been moved to xen_unified.c

Error handling in the case where a driver doesn't support a libvirt function is now considerably better.

Each driver keeps its private data private.

At the moment xen_unified pretty much does the "try the drivers in a loop until one succeeds" strategy which used to be in libvirt.c. There is a case for making it do direct calls to the "right" driver, but for simplicity I haven't gone that far.

Again for simplicity the Xen sub-drivers still use struct virDriver. They should use their own custom 'struct virXenDriver' or whatever. The effects of this are slight but noticable - some parameters are now no longer used in the sub-drivers, so marked ATTRIBUTE_UNUSED.

There is also a single networkDriver pointer in the connect struct. We should modify the functions to handle the case where this is NULL because we couldn't bring up the network functions (all network functions in this case would just return an error). libvirt in CVS fails to run if libvirtd isn't up.

I won't be able to get back to this before tomorrow afternoon, so plenty of time for discussion!

Rich.

--
Emerging Technologies, Red Hat  http://et.redhat.com/~rjones/
64 Baker Street, London, W1U 7DF     Mobile: +44 7866 314 421

Registered Address: Red Hat UK Ltd, Amberley Place, 107-111 Peascod
Street, Windsor, Berkshire, SI4 1TE, United Kingdom.
Registered in UK and Wales under Company Registration No. 3798903
Directors: Michael Cunningham (USA), Charlie Peters (USA) and David
Owens (Ireland)
/*
 * xen_unified.c: Unified Xen driver.
 *
 * Copyright (C) 2007 Red Hat, Inc.
 *
 * See COPYING.LIB for the License of this software
 *
 * Richard W.M. Jones <rjones@xxxxxxxxxx>
 */

#ifdef WITH_XEN

/* Note:
 *
 * This driver provides a unified interface to the five
 * separate underlying Xen drivers (xen_internal, proxy_internal,
 * xend_internal, xs_internal and xm_internal).  Historically
 * the body of libvirt.c handled the five Xen drivers,
 * and contained Xen-specific code.
 *
 * The interface between Xen drivers and xen_unified is
 * the same as for "ordinary" libvirt drivers (ie. virDriverPtr),
 * however this is just for convenience and may be changed
 * in future.  Libvirt.c should no longer call directly
 * to the five underlying Xen drivers.
 */

#include <stdint.h>
#include <xen/dom0_ops.h>

#include "internal.h"

#include "xen_unified.h"

#include "xen_internal.h"
#include "proxy_internal.h"
#include "xend_internal.h"
#include "xs_internal.h"
#include "xm_internal.h"

/* The five Xen drivers below us. */
static virDriverPtr drivers[] = {
  &xenHypervisorDriver,
  &xenProxyDriver,
  &xenDaemonDriver,
  &xenStoreDriver,
  &xenXMDriver
};
static const int nb_drivers = sizeof drivers / sizeof drivers[0];
static const int hypervisor_offset = 0;
static const int proxy_offset = 1;

/*----- Dispatch functions. -----*/

/* These dispatch functions follow the model used historically
 * by libvirt.c -- trying each low-level Xen driver in turn
 * until one succeeds.  However since we know what low-level
 * drivers can perform which functions, it is probably better
 * in future to optimise these dispatch functions to just call
 * the single function (or small number of appropriate functions)
 * in the low level drivers directly.
 */

static int
xenUnifiedOpen (virConnectPtr conn, const char *name, int flags)
{
  int i, j;

  /* If name == NULL or begins with "xen", then it's for us. */
  if (!name)
    name = "xen";
  if (strncasecmp (name, "xen", 3) != 0)
    return VIR_DRV_OPEN_DECLINED;

  /* All Xen drivers should open OK, except that the proxy is allowed
   * to fail.
   */
  for (i = 0; i < nb_drivers; ++i) {
    int failed_to_open = 1;

    if (drivers[i]->open &&
	drivers[i]->open (conn, name, flags) == VIR_DRV_OPEN_SUCCESS)
      failed_to_open = 0;

    if (failed_to_open && i != proxy_offset) {
      for (j = 0; j < i; ++j)
	drivers[j]->close (conn);
      return VIR_DRV_OPEN_ERROR;
    }
  }

  return VIR_DRV_OPEN_SUCCESS;
}

static int
xenUnifiedClose (virConnectPtr conn)
{
  int i;

  for (i = 0; i < nb_drivers; ++i)
    if (drivers[i]->close)
      (void) drivers[i]->close (conn);

  return 0;
}

static const char *
xenUnifiedType (virConnectPtr conn)
{
  int i;
  const char *ret;

  for (i = 0; i < nb_drivers; ++i)
    if (drivers[i]->type) {
      ret = drivers[i]->type (conn);
      if (ret) return ret;
    }

  return NULL;
}

static int
xenUnifiedVersion (virConnectPtr conn, unsigned long *hvVer)
{
  int i;

  for (i = 0; i < nb_drivers; ++i)
    if (drivers[i]->version &&
	drivers[i]->version (conn, hvVer) == 0)
      return 0;

  return -1;
}

static int
xenUnifiedGetMaxVcpus (virConnectPtr conn, const char *type)
{
  int i;

  if (!type)
    type = "Xen";

  for (i = 0; i < nb_drivers; ++i)
    if (strcmp (drivers[i]->name, type) == 0)
      return drivers[i]->getMaxVcpus (conn, type);

  return -1;
}

static int
xenUnifiedNodeGetInfo (virConnectPtr conn, virNodeInfoPtr info)
{
  int i;

  for (i = 0; i < nb_drivers; ++i)
    if (drivers[i]->nodeGetInfo &&
	drivers[i]->nodeGetInfo (conn, info) == 0)
      return 0;

  return -1;
}

static char *
xenUnifiedGetCapabilities (virConnectPtr conn)
{
  int i;
  char *ret;

  for (i = 0; i < nb_drivers; ++i)
    if (drivers[i]->getCapabilities) {
      ret = drivers[i]->getCapabilities (conn);
      if (ret) return ret;
    }

  return NULL;
}

static int
xenUnifiedListDomains (virConnectPtr conn, int *ids, int maxids)
{
  int i, ret;

  for (i = 0; i < nb_drivers; ++i)
    if (drivers[i]->listDomains) {
      ret = drivers[i]->listDomains (conn, ids, maxids);
      if (ret >= 0) return ret;
    }

  return -1;
}

static int
xenUnifiedNumOfDomains (virConnectPtr conn)
{
  int i, ret;

  for (i = 0; i < nb_drivers; ++i)
    if (drivers[i]->numOfDomains) {
      ret = drivers[i]->numOfDomains (conn);
      if (ret >= 0) return ret;
    }

  return -1;
}

static virDomainPtr
xenUnifiedDomainCreateLinux (virConnectPtr conn,
			     const char *xmlDesc, unsigned int flags)
{
  int i;
  virDomainPtr ret;

  for (i = 0; i < nb_drivers; ++i)
    if (drivers[i]->domainCreateLinux) {
      ret = drivers[i]->domainCreateLinux (conn, xmlDesc, flags);
      if (ret) return ret;
    }

  return NULL;
}

static virDomainPtr
xenUnifiedDomainLookupByID (virConnectPtr conn, int id)
{
  int i;
  virDomainPtr ret;

  for (i = 0; i < nb_drivers; ++i)
    if (drivers[i]->domainLookupByID) {
      ret = drivers[i]->domainLookupByID (conn, id);
      if (ret) return ret;
    }

  return NULL;
}

static virDomainPtr
xenUnifiedDomainLookupByUUID (virConnectPtr conn,
			      const unsigned char *uuid)
{
  int i;
  virDomainPtr ret;

  for (i = 0; i < nb_drivers; ++i)
    if (drivers[i]->domainLookupByUUID) {
      ret = drivers[i]->domainLookupByUUID (conn, uuid);
      if (ret) return ret;
    }

  return NULL;
}

static virDomainPtr
xenUnifiedDomainLookupByName (virConnectPtr conn,
			      const char *name)
{
  int i;
  virDomainPtr ret;

  for (i = 0; i < nb_drivers; ++i)
    if (drivers[i]->domainLookupByName) {
      ret = drivers[i]->domainLookupByName (conn, name);
      if (ret) return ret;
    }

  return NULL;
}

static int
xenUnifiedDomainSuspend (virDomainPtr dom)
{
  int i;

  /* Try non-hypervisor methods first, then hypervisor direct method
   * as a last resort.
   */
  for (i = 0; i < nb_drivers; ++i)
    if (i != hypervisor_offset &&
	drivers[i]->domainSuspend &&
	drivers[i]->domainSuspend (dom) == 0)
      return 0;

  if (drivers[hypervisor_offset]->domainSuspend &&
      drivers[hypervisor_offset]->domainSuspend (dom) == 0)
    return 0;

  return -1;
}

static int
xenUnifiedDomainResume (virDomainPtr dom)
{
  int i;

  /* Try non-hypervisor methods first, then hypervisor direct method
   * as a last resort.
   */
  for (i = 0; i < nb_drivers; ++i)
    if (i != hypervisor_offset &&
	drivers[i]->domainResume &&
	drivers[i]->domainResume (dom) == 0)
      return 0;

  if (drivers[hypervisor_offset]->domainResume &&
      drivers[hypervisor_offset]->domainResume (dom) == 0)
    return 0;

  return -1;
}

static int
xenUnifiedDomainShutdown (virDomainPtr dom)
{
  int i;

  for (i = 0; i < nb_drivers; ++i)
    if (drivers[i]->domainShutdown &&
	drivers[i]->domainShutdown (dom) == 0)
      return 0;

  return -1;
}

static int
xenUnifiedDomainReboot (virDomainPtr dom, unsigned int flags)
{
  int i;

  for (i = 0; i < nb_drivers; ++i)
    if (drivers[i]->domainReboot &&
	drivers[i]->domainReboot (dom, flags) == 0)
      return 0;

  return -1;
}

static int
xenUnifiedDomainDestroy (virDomainPtr dom)
{
  int i;

  /* Try non-hypervisor methods first, then hypervisor direct method
   * as a last resort.
   */
  for (i = 0; i < nb_drivers; ++i)
    if (i != hypervisor_offset &&
	drivers[i]->domainDestroy &&
	drivers[i]->domainDestroy (dom) == 0)
      return 0;

  if (drivers[hypervisor_offset]->domainDestroy &&
      drivers[hypervisor_offset]->domainDestroy (dom) == 0)
    return 0;

  return -1;
}

static char *
xenUnifiedDomainGetOSType (virDomainPtr dom)
{
  int i;
  char *ret;

  for (i = 0; i < nb_drivers; ++i)
    if (drivers[i]->domainGetOSType) {
      ret = drivers[i]->domainGetOSType (dom);
      if (ret) return ret;
    }

  return NULL;
}

static unsigned long
xenUnifiedDomainGetMaxMemory (virDomainPtr dom)
{
  int i;
  unsigned long ret;

  for (i = 0; i < nb_drivers; ++i)
    if (drivers[i]->domainGetMaxMemory) {
      ret = drivers[i]->domainGetMaxMemory (dom);
      if (ret != 0) return ret;
    }

  return 0;
}

static int
xenUnifiedDomainSetMaxMemory (virDomainPtr dom, unsigned long memory)
{
  int i;

  for (i = 0; i < nb_drivers; ++i)
    if (drivers[i]->domainSetMaxMemory &&
	drivers[i]->domainSetMaxMemory (dom, memory) == 0)
      return 0;

  return -1;
}

static int
xenUnifiedDomainSetMemory (virDomainPtr dom, unsigned long memory)
{
  int i;

  for (i = 0; i < nb_drivers; ++i)
    if (drivers[i]->domainSetMemory &&
	drivers[i]->domainSetMemory (dom, memory) == 0)
      return 0;

  return -1;
}

static int
xenUnifiedDomainGetInfo (virDomainPtr dom, virDomainInfoPtr info)
{
  int i;

  for (i = 0; i < nb_drivers; ++i)
    if (drivers[i]->domainGetInfo &&
	drivers[i]->domainGetInfo (dom, info) == 0)
      return 0;

  return -1;
}

static int
xenUnifiedDomainSave (virDomainPtr dom, const char *to)
{
  int i;

  for (i = 0; i < nb_drivers; ++i)
    if (drivers[i]->domainSave &&
	drivers[i]->domainSave (dom, to) == 0)
      return 0;

  return -1;
}

static int
xenUnifiedDomainRestore (virConnectPtr conn, const char *from)
{
  int i;

  for (i = 0; i < nb_drivers; ++i)
    if (drivers[i]->domainRestore &&
	drivers[i]->domainRestore (conn, from) == 0)
      return 0;

  return -1;
}

static int
xenUnifiedDomainCoreDump (virDomainPtr dom, const char *to, int flags)
{
  int i;

  for (i = 0; i < nb_drivers; ++i)
    if (drivers[i]->domainCoreDump &&
	drivers[i]->domainCoreDump (dom, to, flags) == 0)
      return 0;

  return -1;
}

static int
xenUnifiedDomainSetVcpus (virDomainPtr dom, unsigned int nvcpus)
{
  int i;

  /* Try non-hypervisor methods first, then hypervisor direct method
   * as a last resort.
   */
  for (i = 0; i < nb_drivers; ++i)
    if (i != hypervisor_offset &&
	drivers[i]->domainSetVcpus &&
	drivers[i]->domainSetVcpus (dom, nvcpus) == 0)
      return 0;

  if (drivers[hypervisor_offset]->domainSetVcpus &&
      drivers[hypervisor_offset]->domainSetVcpus (dom, nvcpus) == 0)
    return 0;

  return -1;
}

static int
xenUnifiedDomainPinVcpu (virDomainPtr dom, unsigned int vcpu,
			 unsigned char *cpumap, int maplen)
{
  int i;

  for (i = 0; i < nb_drivers; ++i)
    if (drivers[i]->domainPinVcpu &&
	drivers[i]->domainPinVcpu (dom, vcpu, cpumap, maplen) == 0)
      return 0;

  return -1;
}

static int
xenUnifiedDomainGetVcpus (virDomainPtr dom,
			  virVcpuInfoPtr info, int maxinfo,
			  unsigned char *cpumaps, int maplen)
{
  int i;

  for (i = 0; i < nb_drivers; ++i)
    if (drivers[i]->domainGetVcpus &&
	drivers[i]->domainGetVcpus (dom, info, maxinfo, cpumaps, maplen) == 0)
      return 0;

  return -1;
}

static int
xenUnifiedDomainGetMaxVcpus (virDomainPtr dom)
{
  int i, ret;

  for (i = 0; i < nb_drivers; ++i)
    if (drivers[i]->domainGetMaxVcpus) {
      ret = drivers[i]->domainGetMaxVcpus (dom);
      if (ret != 0) return ret;
    }

  return -1;
}

static char *
xenUnifiedDomainDumpXML (virDomainPtr dom, int flags)
{
  int i;
  char *ret;

  for (i = 0; i < nb_drivers; ++i)
    if (drivers[i]->domainDumpXML) {
      ret = drivers[i]->domainDumpXML (dom, flags);
      if (ret) return ret;
    }

  return NULL;
}

static int
xenUnifiedListDefinedDomains (virConnectPtr conn, char **const names,
			      int maxnames)
{
  int i;
  int ret;

  for (i = 0; i < nb_drivers; ++i)
    if (drivers[i]->listDefinedDomains) {
      ret = drivers[i]->listDefinedDomains (conn, names, maxnames);
      if (ret >= 0) return ret;
    }

  return -1;
}

static int
xenUnifiedNumOfDefinedDomains (virConnectPtr conn)
{
  int i;
  int ret;

  for (i = 0; i < nb_drivers; ++i)
    if (drivers[i]->numOfDefinedDomains) {
      ret = drivers[i]->numOfDefinedDomains (conn);
      if (ret >= 0) return ret;
    }

  return -1;
}

static int
xenUnifiedDomainCreate (virDomainPtr dom)
{
  int i;

  for (i = 0; i < nb_drivers; ++i)
    if (drivers[i]->domainCreate &&
	drivers[i]->domainCreate (dom) == 0)
      return 0;

  return -1;
}

static virDomainPtr
xenUnifiedDomainDefineXML (virConnectPtr conn, const char *xml)
{
  int i;
  virDomainPtr ret;

  for (i = 0; i < nb_drivers; ++i)
    if (drivers[i]->domainDefineXML) {
      ret = drivers[i]->domainDefineXML (conn, xml);
      if (ret) return ret;
    }

  return NULL;
}

static int
xenUnifiedDomainUndefine (virDomainPtr dom)
{
  int i;

  for (i = 0; i < nb_drivers; ++i)
    if (drivers[i]->domainUndefine &&
	drivers[i]->domainUndefine (dom) == 0)
      return 0;

  return -1;
}

static int
xenUnifiedDomainAttachDevice (virDomainPtr dom, char *xml)
{
  int i;

  for (i = 0; i < nb_drivers; ++i)
    if (drivers[i]->domainAttachDevice &&
	drivers[i]->domainAttachDevice (dom, xml) == 0)
      return 0;

  return -1;
}

static int
xenUnifiedDomainDetachDevice (virDomainPtr dom, char *xml)
{
  int i;

  for (i = 0; i < nb_drivers; ++i)
    if (drivers[i]->domainDetachDevice &&
	drivers[i]->domainDetachDevice (dom, xml) == 0)
      return 0;

  return -1;
}

static int
xenUnifiedDomainGetAutostart (virDomainPtr dom, int *autostart)
{
  int i;

  for (i = 0; i < nb_drivers; ++i)
    if (drivers[i]->domainGetAutostart &&
	drivers[i]->domainGetAutostart (dom, autostart) == 0)
      return 0;

  return -1;
}

static int
xenUnifiedDomainSetAutostart (virDomainPtr dom, int autostart)
{
  int i;

  for (i = 0; i < nb_drivers; ++i)
    if (drivers[i]->domainSetAutostart &&
	drivers[i]->domainSetAutostart (dom, autostart) == 0)
      return 0;

  return -1;
}

/*----- Register with libvirt.c, and initialise Xen drivers. -----*/

#define 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 = VERSION,
  .open 			= xenUnifiedOpen,
  .close 			= xenUnifiedClose,
  .type 			= xenUnifiedType,
  .version 			= xenUnifiedVersion,
  .getMaxVcpus 			= xenUnifiedGetMaxVcpus,
  .nodeGetInfo 			= xenUnifiedNodeGetInfo,
  .getCapabilities 		= xenUnifiedGetCapabilities,
  .listDomains 			= xenUnifiedListDomains,
  .numOfDomains 		= xenUnifiedNumOfDomains,
  .domainCreateLinux 		= xenUnifiedDomainCreateLinux,
  .domainLookupByID 		= xenUnifiedDomainLookupByID,
  .domainLookupByUUID 		= xenUnifiedDomainLookupByUUID,
  .domainLookupByName 		= xenUnifiedDomainLookupByName,
  .domainSuspend 		= xenUnifiedDomainSuspend,
  .domainResume 		= xenUnifiedDomainResume,
  .domainShutdown 		= xenUnifiedDomainShutdown,
  .domainReboot 		= xenUnifiedDomainReboot,
  .domainDestroy 		= xenUnifiedDomainDestroy,
  .domainGetOSType 		= xenUnifiedDomainGetOSType,
  .domainGetMaxMemory 		= xenUnifiedDomainGetMaxMemory,
  .domainSetMaxMemory 		= xenUnifiedDomainSetMaxMemory,
  .domainSetMemory 		= xenUnifiedDomainSetMemory,
  .domainGetInfo 		= xenUnifiedDomainGetInfo,
  .domainSave 			= xenUnifiedDomainSave,
  .domainRestore 		= xenUnifiedDomainRestore,
  .domainCoreDump 		= xenUnifiedDomainCoreDump,
  .domainSetVcpus 		= xenUnifiedDomainSetVcpus,
  .domainPinVcpu 		= xenUnifiedDomainPinVcpu,
  .domainGetVcpus 		= xenUnifiedDomainGetVcpus,
  .domainGetMaxVcpus 		= xenUnifiedDomainGetMaxVcpus,
  .domainDumpXML 		= xenUnifiedDomainDumpXML,
  .listDefinedDomains 		= xenUnifiedListDefinedDomains,
  .numOfDefinedDomains 		= xenUnifiedNumOfDefinedDomains,
  .domainCreate 		= xenUnifiedDomainCreate,
  .domainDefineXML 		= xenUnifiedDomainDefineXML,
  .domainUndefine 		= xenUnifiedDomainUndefine,
  .domainAttachDevice 		= xenUnifiedDomainAttachDevice,
  .domainDetachDevice 		= xenUnifiedDomainDetachDevice,
  .domainGetAutostart 		= xenUnifiedDomainGetAutostart,
  .domainSetAutostart 		= xenUnifiedDomainSetAutostart,
};

int
xenUnifiedRegister (void)
{
  if (xenHypervisorInit () == -1 ||
      xenProxyInit () == -1 ||
      xenDaemonInit () == -1 ||
      xenStoreInit () == -1 ||
      xenXMInit () == -1)
    return -1;

  return virRegisterDriver (&xenUnifiedDriver);
}

#endif /* WITH_XEN */
/*
 * xen_unified.c: Unified Xen driver.
 *
 * Copyright (C) 2007 Red Hat, Inc.
 *
 * See COPYING.LIB for the License of this software
 *
 * Richard W.M. Jones <rjones@xxxxxxxxxx>
 */

#ifndef __VIR_XEN_UNIFIED_H__
#define __VIR_XEN_UNIFIED_H__
#ifdef WITH_XEN

#ifdef __cplusplus
extern "C" {
#endif

extern int xenUnifiedRegister (void);

#ifdef __cplusplus
}
#endif

#endif /* WITH_XEN */
#endif /* __VIR_XEN_UNIFIED_H__ */
? INSTALL
? compile
? depcomp
? install-sh
? missing
? docs/APIchunk5.html
? docs/APIchunk6.html
? docs/examples/.deps
? src/libvirt_la-xend_internal.loT
Index: src/Makefile.am
===================================================================
RCS file: /data/cvs/libvirt/src/Makefile.am,v
retrieving revision 1.36
diff -u -r1.36 Makefile.am
--- src/Makefile.am	15 Mar 2007 07:43:16 -0000	1.36
+++ src/Makefile.am	28 Mar 2007 16:02:18 -0000
@@ -21,6 +21,7 @@
 		hash.c hash.h					\
 		test.c test.h                                   \
 		xml.c xml.h					\
+		xen_unified.c xen_unified.h			\
 		xen_internal.c xen_internal.h			\
 		xs_internal.c xs_internal.h			\
 		xend_internal.c xend_internal.h			\
Index: src/driver.h
===================================================================
RCS file: /data/cvs/libvirt/src/driver.h,v
retrieving revision 1.24
diff -u -r1.24 driver.h
--- src/driver.h	15 Mar 2007 17:24:57 -0000	1.24
+++ src/driver.h	28 Mar 2007 16:02:18 -0000
@@ -17,13 +17,9 @@
  * List of registered drivers numbers
  */
 typedef enum {
-    VIR_DRV_XEN_HYPERVISOR = 1,
-    VIR_DRV_XEN_STORE = 2,
-    VIR_DRV_XEN_DAEMON = 3,
-    VIR_DRV_TEST = 4,
-    VIR_DRV_XEN_PROXY = 5,
-    VIR_DRV_XEN_XM = 6,
-    VIR_DRV_QEMU = 7
+    VIR_DRV_XEN_UNIFIED = 1,
+    VIR_DRV_TEST = 2,
+    VIR_DRV_QEMU = 3,
 } virDrvNo;
 
 
@@ -32,10 +28,24 @@
     VIR_DRV_OPEN_RO = 2
 } virDrvOpenFlag;
 
-typedef int
-	(*virDrvOpen)			(virConnectPtr conn,
-					 const char *name,
-					 int flags);
+/* Status codes returned from driver open call. */
+typedef enum {
+    /* Opened successfully. */
+    VIR_DRV_OPEN_SUCCESS = 0,
+
+    /* 'name' is not for us. */
+    VIR_DRV_OPEN_DECLINED = -1,
+
+    /* 'name' is for us, but there was some error.  virConnectOpen will
+     * return an error rather than continue probing the other drivers.
+     */
+    VIR_DRV_OPEN_ERROR = -2,
+} virDrvOpenStatus;
+
+typedef virDrvOpenStatus
+    (*virDrvOpen)			(virConnectPtr conn,
+                             const char *name,
+                             int flags);
 typedef int
 	(*virDrvClose)			(virConnectPtr conn);
 typedef const char *
@@ -44,7 +54,7 @@
 	(*virDrvGetVersion)		(virConnectPtr conn,
 					 unsigned long *hvVer);
 typedef int
-	(*virDrvGetMaxVcpus)		(virConnectPtr conn);
+    (*virDrvGetMaxVcpus)		(virConnectPtr conn, const char *type);
 typedef int
 	(*virDrvNodeGetInfo)		(virConnectPtr conn,
 					 virNodeInfoPtr info);
@@ -155,6 +165,12 @@
  *
  * Structure associated to a virtualization driver, defining the various
  * entry points for it.
+ *
+ * All drivers must support the following fields/methods:
+ *  - no
+ *  - name
+ *  - open
+ *  - close
  */
 struct _virDriver {
 	int	       no;	/* the number virDrvNo */
@@ -252,6 +268,10 @@
  *
  * Structure associated to a network virtualization driver, defining the various
  * entry points for it.
+ *
+ * All drivers must support the following fields/methods:
+ *  - open
+ *  - close
  */
 struct _virNetworkDriver {
 	virDrvOpen			open;
Index: src/hash.c
===================================================================
RCS file: /data/cvs/libvirt/src/hash.c,v
retrieving revision 1.19
diff -u -r1.19 hash.c
--- src/hash.c	22 Mar 2007 18:30:57 -0000	1.19
+++ src/hash.c	28 Mar 2007 16:02:18 -0000
@@ -665,9 +665,10 @@
         goto failed;
     }
     ret->magic = VIR_CONNECT_MAGIC;
-    ret->nb_drivers = 0;
-    ret->handle = -1;
-    ret->qemud_fd = -1;
+    ret->driver = NULL;
+    ret->networkDriver = NULL;
+    ret->privateData = NULL;
+    ret->networkPrivateData = NULL;
     ret->domains = virHashCreate(20);
     if (ret->domains == NULL)
         goto failed;
Index: src/internal.h
===================================================================
RCS file: /data/cvs/libvirt/src/internal.h,v
retrieving revision 1.36
diff -u -r1.36 internal.h
--- src/internal.h	19 Mar 2007 14:18:05 -0000	1.36
+++ src/internal.h	28 Mar 2007 16:02:18 -0000
@@ -114,17 +114,32 @@
     unsigned int magic;     /* specific value to check */
 
     int uses;               /* reference count */
-    /* the list of available drivers for that connection */
-    virDriverPtr      drivers[MAX_DRIVERS];
-    int               nb_drivers;
-
-    /* the list of available network drivers */
-    virNetworkDriverPtr networkDrivers[MAX_DRIVERS];
-    int                 nb_network_drivers;
 
+    /* The underlying hypervisor driver and network driver. */
+    virDriverPtr      driver;
+    virNetworkDriverPtr networkDriver;
+
+    /* Private data pointer which can be used by driver and
+     * network driver as they wish.
+     * NB: 'private' is a reserved word in C++.
+     */
+    void *            privateData;
+    void *            networkPrivateData;
+
+    /* Per-connection error. */
+    virError err;           /* the last error */
+    virErrorFunc handler;   /* associated handlet */
+    void *userData;         /* the user data */
+
+    /* misc */
+    xmlMutexPtr hashes_mux;/* a mutex to protect the domain and networks hash tables */
+    virHashTablePtr domains;/* hash table for known domains */
+    virHashTablePtr networks;/* hash table for known domains */
+    int flags;              /* a set of connection flags */
+};
+
+#if 0
     /* extra data needed by drivers */
-    int handle;             /* internal handle used for hypercall */
-    struct xs_handle *xshandle;/* handle to talk to the xenstore */
     int proxy;              /* file descriptor if using the proxy */
     int xendConfigVersion;  /* XenD config version */
 
@@ -136,18 +151,7 @@
     struct sockaddr_in addr_in;     /* the inet address */
 
     int qemud_fd;           /* connection to qemud */
-
-    /* error stuff */
-    virError err;           /* the last error */
-    virErrorFunc handler;   /* associated handlet */
-    void *userData;         /* the user data */
-
-    /* misc */
-    xmlMutexPtr hashes_mux;/* a mutex to protect the domain and networks hash tables */
-    virHashTablePtr domains;/* hash table for known domains */
-    virHashTablePtr networks;/* hash table for known domains */
-    int flags;              /* a set of connection flags */
-};
+#endif
 
 /**
 * virDomainFlags:
Index: src/libvirt.c
===================================================================
RCS file: /data/cvs/libvirt/src/libvirt.c,v
retrieving revision 1.65
diff -u -r1.65 libvirt.c
--- src/libvirt.c	22 Mar 2007 18:30:57 -0000	1.65
+++ src/libvirt.c	28 Mar 2007 16:02:20 -0000
@@ -17,6 +17,7 @@
 #include <sys/types.h>
 #include <sys/stat.h>
 #include <unistd.h>
+#include <alloca.h>
 
 #include <libxml/parser.h>
 #include <libxml/xpath.h>
@@ -24,16 +25,9 @@
 #include "internal.h"
 #include "driver.h"
 
-#ifdef WITH_XEN
-#include <xs.h>
-#include "xen_internal.h"
-#include "xend_internal.h"
-#include "xs_internal.h"
-#include "xm_internal.h"
-#endif
-#include "proxy_internal.h"
 #include "xml.h"
 #include "test.h"
+#include "xen_unified.h"
 #include "qemu_internal.h"
 
 /*
@@ -68,20 +62,17 @@
         return (-1);
 
     /*
-     * Note that the order is important the first ones have a higher priority
+     * Note that the order is important: the first ones have a higher
+     * priority when calling virConnectOpen.
      */
 #ifdef WITH_XEN
-    xenHypervisorRegister();
-    xenProxyRegister();
-    xenDaemonRegister();
-    xenStoreRegister();
-    xenXMRegister();
+    if (xenUnifiedRegister () == -1) return -1;
 #endif
 #ifdef WITH_TEST
-    testRegister();
+    if (testRegister() == -1) return -1;
 #endif
 #ifdef WITH_QEMU
-    qemuRegister();
+    if (qemuRegister() == -1) return -1;
 #endif
 
     return(0);
@@ -214,6 +205,13 @@
 	return(-1);
     }
 
+    if (driver->no < 0) {
+    	virLibConnError
+            (NULL, VIR_ERR_INVALID_ARG,
+             "virRegisterDriver: tried to register an internal Xen driver");
+        return -1;
+    }
+
     virDriverTab[virDriverTabCount] = driver;
     return virDriverTabCount++;
 }
@@ -275,76 +273,69 @@
  *
  * Returns a pointer to the hypervisor connection or NULL in case of error
  */
-virConnectPtr
-virConnectOpen(const char *name)
+static virConnectPtr
+do_open (const char *name, int flags)
 {
-    int i, res, for_xen = 0;
+    int i, res;
     virConnectPtr ret = NULL;
 
     if (!initialized)
         if (virInitialize() < 0)
 	    return NULL;
 
-    if (name == NULL) {
-        name = "Xen";
-	for_xen = 1;
-    } else if (!strncasecmp(name, "xen", 3)) {
-	for_xen = 1;
-    }
-
     ret = virGetConnect();
     if (ret == NULL) {
         virLibConnError(NULL, VIR_ERR_NO_MEMORY, _("allocating connection"));
         goto failed;
     }
 
-    for (i = 0;i < virDriverTabCount;i++) {
-        if ((virDriverTab[i]->open != NULL)) {
-	    res = virDriverTab[i]->open(ret, name, VIR_DRV_OPEN_QUIET);
-	    /*
-	     * For a default connect to Xen make sure we manage to contact
-	     * all related drivers.
-	     */
-	    if ((res < 0) && (for_xen) &&
-	        (!strncasecmp(virDriverTab[i]->name, "xen", 3)) &&
-		(virDriverTab[i]->no != VIR_DRV_XEN_PROXY))
-		goto failed;
-	    if (res == 0)
-	        ret->drivers[ret->nb_drivers++] = virDriverTab[i];
-	}
+    for (i = 0; i < virDriverTabCount; i++) {
+        res = virDriverTab[i]->open (ret, name, flags);
+        if (res == VIR_DRV_OPEN_ERROR) goto failed;
+        else if (res == VIR_DRV_OPEN_SUCCESS) {
+            ret->driver = virDriverTab[i];
+            break;
+        }
     }
 
-    for (i = 0;i < virNetworkDriverTabCount;i++) {
-        if ((virNetworkDriverTab[i]->open != NULL) &&
-	    (res = virNetworkDriverTab[i]->open(ret, name, VIR_DRV_OPEN_QUIET)) == 0) {
-            ret->networkDrivers[ret->nb_network_drivers++] = virNetworkDriverTab[i];
-        }
+    if (!ret->driver) {
+        virLibConnError (NULL, VIR_ERR_NO_SUPPORT, name);
+        goto failed;
     }
 
-    if ((ret->nb_drivers == 0) && (ret->nb_network_drivers == 0)) {
-	/* we failed to find an adequate driver */
-	virLibConnError(NULL, VIR_ERR_NO_SUPPORT, name);
-	goto failed;
+    for (i = 0; i < virNetworkDriverTabCount; i++) {
+        res = virNetworkDriverTab[i]->open (ret, name, flags);
+        if (res == -1) goto failed;
+        else if (res == 0) {
+            ret->networkDriver = virNetworkDriverTab[i];
+            break;
+        }
     }
 
-    return (ret);
+    return ret;
 
 failed:
-    if (ret != NULL) {
-	for (i = 0;i < ret->nb_drivers;i++) {
-	    if ((ret->drivers[i] != NULL) && (ret->drivers[i]->close != NULL))
-	        ret->drivers[i]->close(ret);
-	}
-	for (i = 0;i < ret->nb_network_drivers;i++) {
-	    if ((ret->networkDrivers[i] != NULL) && (ret->networkDrivers[i]->close != NULL))
-	        ret->networkDrivers[i]->close(ret);
-	}
+    if (ret->driver) ret->driver->close (ret);
 	virFreeConnect(ret);
-    }
     return (NULL);
 }
 
 /**
+ * virConnectOpen:
+ * @name: optional argument currently unused, pass NULL
+ *
+ * This function should be called first to get a connection to the 
+ * Hypervisor and xen store
+ *
+ * Returns a pointer to the hypervisor connection or NULL in case of error
+ */
+virConnectPtr
+virConnectOpen (const char *name)
+{
+    return do_open (name, VIR_DRV_OPEN_QUIET);
+}
+
+/**
  * virConnectOpenReadOnly:
  * @name: optional argument currently unused, pass NULL
  *
@@ -357,63 +348,7 @@
 virConnectPtr
 virConnectOpenReadOnly(const char *name)
 {
-    int i, res;
-    virConnectPtr ret = NULL;
-
-    if (!initialized)
-        if (virInitialize() < 0)
-	    return NULL;
-
-    if (name == NULL)
-        name = "Xen";
-
-    ret = virGetConnect();
-    if (ret == NULL) {
-        virLibConnError(NULL, VIR_ERR_NO_MEMORY, _("allocating connection"));
-        goto failed;
-    }
-
-    for (i = 0;i < virDriverTabCount;i++) {
-        if ((virDriverTab[i]->open != NULL)) {
-	    res = virDriverTab[i]->open(ret, name,
-	                                VIR_DRV_OPEN_QUIET | VIR_DRV_OPEN_RO);
-	    if (res == 0)
-	        ret->drivers[ret->nb_drivers++] = virDriverTab[i];
-
-	}
-    }
-    for (i = 0;i < virNetworkDriverTabCount;i++) {
-        if ((virNetworkDriverTab[i]->open != NULL) &&
-	    (res = virNetworkDriverTab[i]->open(ret, name, VIR_DRV_OPEN_QUIET|VIR_DRV_OPEN_RO)) == 0) {
-            ret->networkDrivers[ret->nb_network_drivers++] = virNetworkDriverTab[i];
-        }
-    }
-    if ((ret->nb_drivers == 0) && (ret->nb_network_drivers == 0)) {
-	if (name == NULL)
-	    virLibConnError(NULL, VIR_ERR_NO_CONNECT,
-			    _("Xen Daemon or Xen Store"));
-	else
-	    /* we failed to find an adequate driver */
-	    virLibConnError(NULL, VIR_ERR_NO_SUPPORT, name);
-	goto failed;
-    }
-    ret->flags = VIR_CONNECT_RO;
-
-    return (ret);
-
-failed:
-    if (ret != NULL) {
-	for (i = 0;i < ret->nb_drivers;i++) {
-	    if ((ret->drivers[i] != NULL) && (ret->drivers[i]->close != NULL))
-	        ret->drivers[i]->close(ret);
-	}
-	for (i = 0;i < ret->nb_network_drivers;i++) {
-	    if ((ret->networkDrivers[i] != NULL) && (ret->networkDrivers[i]->close != NULL))
-	        ret->networkDrivers[i]->close(ret);
-	}
-	virFreeConnect(ret);
-    }
-    return (NULL);
+    return do_open (name, VIR_DRV_OPEN_QUIET | VIR_DRV_OPEN_RO);
 }
 
 /**
@@ -430,18 +365,12 @@
 int
 virConnectClose(virConnectPtr conn)
 {
-    int i;
-
     if (!VIR_IS_CONNECT(conn))
         return (-1);
-    for (i = 0;i < conn->nb_drivers;i++) {
-	if ((conn->drivers[i] != NULL) && (conn->drivers[i]->close != NULL))
-	    conn->drivers[i]->close(conn);
-    }
-    for (i = 0;i < conn->nb_network_drivers;i++) {
-	if ((conn->networkDrivers[i] != NULL) && (conn->networkDrivers[i]->close != NULL))
-	    conn->networkDrivers[i]->close(conn);
-    }
+
+    conn->driver->close (conn);
+    conn->networkDriver->close (conn);
+
     if (virFreeConnect(conn) < 0)
         return (-1);
     return (0);
@@ -458,28 +387,18 @@
 const char *
 virConnectGetType(virConnectPtr conn)
 {
-    int i;
     const char *ret;
 
     if (!VIR_IS_CONNECT(conn)) {
         virLibConnError(conn, VIR_ERR_INVALID_CONN, __FUNCTION__);
         return (NULL);
     }
-    for (i = 0;i < conn->nb_drivers;i++) {
-	if ((conn->drivers[i] != NULL) &&
-	    (conn->drivers[i]->type != NULL)) {
-	    ret = conn->drivers[i]->type(conn);
-	    if (ret != NULL)
-	        return(ret);
-	}
-    }
-    for (i = 0;i < conn->nb_drivers;i++) {
-	if ((conn->drivers[i] != NULL) &&
-	    (conn->drivers[i]->name != NULL)) {
-	    return(conn->drivers[i]->name);
-	}
+
+    if (conn->driver->type) {
+        ret = conn->driver->type (conn);
+        if (ret) return ret;
     }
-    return(NULL);
+    return conn->driver->name;
 }
 
 /**
@@ -498,8 +417,6 @@
 int
 virConnectGetVersion(virConnectPtr conn, unsigned long *hvVer)
 {
-    int ret, i;
-
     if (!VIR_IS_CONNECT(conn)) {
         virLibConnError(conn, VIR_ERR_INVALID_CONN, __FUNCTION__);
         return (-1);
@@ -510,16 +427,11 @@
         return (-1);
     }
 
-    for (i = 0;i < conn->nb_drivers;i++) {
-	if ((conn->drivers[i] != NULL) &&
-	    (conn->drivers[i]->version != NULL)) {
-	    ret = conn->drivers[i]->version(conn, hvVer);
-	    if (ret == 0)
-	        return(0);
-	}
-    }
+    if (conn->driver->version)
+        return conn->driver->version (conn, hvVer);
 
-    return (-1);
+    virLibConnError (conn, VIR_ERR_NO_SUPPORT, __FUNCTION__);
+    return -1;
 }
 
 /**
@@ -537,27 +449,16 @@
 virConnectGetMaxVcpus(virConnectPtr conn,
                       const char *type)
 {
-    int ret = -1;
-    int i;
-
     if (!VIR_IS_CONNECT(conn)) {
         virLibConnError(conn, VIR_ERR_INVALID_CONN, __FUNCTION__);
         return (-1);
     }
 
-    if (type == NULL)
-        type = "Xen";
-    for (i = 0;i < MAX_DRIVERS;i++) {
-        if ((virDriverTab[i] != NULL) &&
-           (!strcmp(virDriverTab[i]->name, type))) {
-            ret = conn->drivers[i]->getMaxVcpus(conn);
-            if (ret >= 0)
-                return(ret);
-        }
-    }
-
-    return (-1);
+    if (conn->driver->getMaxVcpus)
+        return conn->driver->getMaxVcpus (conn, type);
 
+    virLibConnError (conn, VIR_ERR_NO_SUPPORT, __FUNCTION__);
+    return -1;
 }
 
 /**
@@ -573,9 +474,6 @@
 int
 virConnectListDomains(virConnectPtr conn, int *ids, int maxids)
 {
-    int ret = -1;
-    int i;
-
     if (!VIR_IS_CONNECT(conn)) {
         virLibConnError(conn, VIR_ERR_INVALID_CONN, __FUNCTION__);
         return (-1);
@@ -586,17 +484,11 @@
         return (-1);
     }
 
-    /* Go though the driver registered entry points */
-    for (i = 0;i < conn->nb_drivers;i++) {
-	if ((conn->drivers[i] != NULL) &&
-	    (conn->drivers[i]->listDomains != NULL)) {
-	    ret = conn->drivers[i]->listDomains(conn, ids, maxids);
-	    if (ret >= 0)
-	        return(ret);
-	}
-    }
+    if (conn->driver->listDomains)
+        return conn->driver->listDomains (conn, ids, maxids);
 
-    return (-1);
+    virLibConnError (conn, VIR_ERR_NO_SUPPORT, __FUNCTION__);
+    return -1;
 }
 
 /**
@@ -610,25 +502,16 @@
 int
 virConnectNumOfDomains(virConnectPtr conn)
 {
-    int ret = -1;
-    int i;
-
     if (!VIR_IS_CONNECT(conn)) {
         virLibConnError(conn, VIR_ERR_INVALID_CONN, __FUNCTION__);
         return (-1);
     }
 
-    /* Go though the driver registered entry points */
-    for (i = 0;i < conn->nb_drivers;i++) {
-	if ((conn->drivers[i] != NULL) &&
-	    (conn->drivers[i]->numOfDomains != NULL)) {
-	    ret = conn->drivers[i]->numOfDomains(conn);
-	    if (ret >= 0)
-	        return(ret);
-	}
-    }
+    if (conn->driver->numOfDomains)
+        return conn->driver->numOfDomains (conn);
 
-    return(-1);
+    virLibConnError (conn, VIR_ERR_NO_SUPPORT, __FUNCTION__);
+    return -1;
 }
 
 /**
@@ -647,9 +530,6 @@
 virDomainCreateLinux(virConnectPtr conn, const char *xmlDesc,
                      unsigned int flags)
 {
-    virDomainPtr ret;
-    int i;
-
     if (!VIR_IS_CONNECT(conn)) {
         virLibConnError(conn, VIR_ERR_INVALID_CONN, __FUNCTION__);
         return (NULL);
@@ -663,15 +543,11 @@
 	return (NULL);
     }
 
-    for (i = 0;i < conn->nb_drivers;i++) {
-	if ((conn->drivers[i] != NULL) &&
-	    (conn->drivers[i]->domainCreateLinux != NULL)) {
-	    ret = conn->drivers[i]->domainCreateLinux(conn, xmlDesc, flags);
-	    if (ret != NULL)
-	        return(ret);
-	}
-    }
-    return(NULL);
+    if (conn->driver->domainCreateLinux)
+        return conn->driver->domainCreateLinux (conn, xmlDesc, flags);
+
+    virLibConnError (conn, VIR_ERR_NO_SUPPORT, __FUNCTION__);
+    return NULL;
 }
 
 
@@ -687,9 +563,6 @@
 virDomainPtr
 virDomainLookupByID(virConnectPtr conn, int id)
 {
-    virDomainPtr ret;
-    int i;
-
     if (!VIR_IS_CONNECT(conn)) {
         virLibConnError(conn, VIR_ERR_INVALID_CONN, __FUNCTION__);
         return (NULL);
@@ -699,17 +572,11 @@
         return (NULL);
     }
 
-    /* Go though the driver registered entry points */
-    for (i = 0;i < conn->nb_drivers;i++) {
-	if ((conn->drivers[i] != NULL) &&
-	    (conn->drivers[i]->domainLookupByID != NULL)) {
-	    ret = conn->drivers[i]->domainLookupByID(conn, id);
-	    if (ret)
-	        return(ret);
-	}
-    }
+    if (conn->driver->domainLookupByID)
+        return conn->driver->domainLookupByID (conn, id);
 
-    return (NULL);
+    virLibConnError (conn, VIR_ERR_NO_SUPPORT, __FUNCTION__);
+    return NULL;
 }
 
 /**
@@ -724,9 +591,6 @@
 virDomainPtr
 virDomainLookupByUUID(virConnectPtr conn, const unsigned char *uuid)
 {
-    virDomainPtr ret;
-    int i;
-
     if (!VIR_IS_CONNECT(conn)) {
         virLibConnError(conn, VIR_ERR_INVALID_CONN, __FUNCTION__);
         return (NULL);
@@ -736,17 +600,11 @@
         return (NULL);
     }
 
-    /* Go though the driver registered entry points */
-    for (i = 0;i < conn->nb_drivers;i++) {
-	if ((conn->drivers[i] != NULL) &&
-	    (conn->drivers[i]->domainLookupByUUID != NULL)) {
-	    ret = conn->drivers[i]->domainLookupByUUID(conn, uuid);
-	    if (ret)
-	        return(ret);
-	}
-    }
+    if (conn->driver->domainLookupByUUID)
+        return conn->driver->domainLookupByUUID (conn, uuid);
 
-    return (NULL);
+    virLibConnError (conn, VIR_ERR_NO_SUPPORT, __FUNCTION__);
+    return NULL;
 }
 
 /**
@@ -810,9 +668,6 @@
 virDomainPtr
 virDomainLookupByName(virConnectPtr conn, const char *name)
 {
-    virDomainPtr ret = NULL;
-    int i;
-
     if (!VIR_IS_CONNECT(conn)) {
         virLibConnError(conn, VIR_ERR_INVALID_CONN, __FUNCTION__);
         return (NULL);
@@ -822,16 +677,11 @@
         return (NULL);
     }
 
-    /* Go though the driver registered entry points */
-    for (i = 0;i < conn->nb_drivers;i++) {
-	if ((conn->drivers[i] != NULL) &&
-	    (conn->drivers[i]->domainLookupByName != NULL)) {
-	    ret = conn->drivers[i]->domainLookupByName(conn, name);
-	    if (ret)
-	        return(ret);
-	}
-    }
-    return (NULL);
+    if (conn->driver->domainLookupByName)
+        return conn->driver->domainLookupByName (conn, name);
+
+    virLibConnError (conn, VIR_ERR_NO_SUPPORT, __FUNCTION__);
+    return NULL;
 }
 
 /**
@@ -849,7 +699,6 @@
 int
 virDomainDestroy(virDomainPtr domain)
 {
-    int i;
     virConnectPtr conn;
 
     if (!VIR_IS_CONNECTED_DOMAIN(domain)) {
@@ -863,29 +712,11 @@
 	return (-1);
     }
 
-    /*
-     * Go though the driver registered entry points but use the 
-     * XEN_HYPERVISOR directly only as a last mechanism
-     */
-    for (i = 0;i < conn->nb_drivers;i++) {
-	if ((conn->drivers[i] != NULL) &&
-	    (conn->drivers[i]->no != VIR_DRV_XEN_HYPERVISOR) &&
-	    (conn->drivers[i]->domainDestroy != NULL)) {
-	    if (conn->drivers[i]->domainDestroy(domain) == 0)
-	        return (0);
-	}
-    }
-    for (i = 0;i < conn->nb_drivers;i++) {
-	if ((conn->drivers[i] != NULL) &&
-	    (conn->drivers[i]->no == VIR_DRV_XEN_HYPERVISOR) &&
-	    (conn->drivers[i]->domainDestroy != NULL)) {
-	    if (conn->drivers[i]->domainDestroy(domain) == 0)
-	        return (0);
-	}
-    }
+    if (conn->driver->domainDestroy)
+        return conn->driver->domainDestroy (domain);
 
-        virLibConnError(conn, VIR_ERR_CALL_FAILED, __FUNCTION__);
-    return (-1);
+    virLibConnError (conn, VIR_ERR_NO_SUPPORT, __FUNCTION__);
+    return -1;
 }
 
 /**
@@ -924,7 +755,6 @@
 int
 virDomainSuspend(virDomainPtr domain)
 {
-    int i;
     virConnectPtr conn;
 
     if (!VIR_IS_CONNECTED_DOMAIN(domain)) {
@@ -938,29 +768,11 @@
 
     conn = domain->conn;
 
-    /*
-     * Go though the driver registered entry points but use the 
-     * XEN_HYPERVISOR directly only as a last mechanism
-     */
-    for (i = 0;i < conn->nb_drivers;i++) {
-	if ((conn->drivers[i] != NULL) &&
-	    (conn->drivers[i]->no != VIR_DRV_XEN_HYPERVISOR) &&
-	    (conn->drivers[i]->domainSuspend != NULL)) {
-	    if (conn->drivers[i]->domainSuspend(domain) == 0)
-	        return (0);
-	}
-    }
-    for (i = 0;i < conn->nb_drivers;i++) {
-	if ((conn->drivers[i] != NULL) &&
-	    (conn->drivers[i]->no == VIR_DRV_XEN_HYPERVISOR) &&
-	    (conn->drivers[i]->domainSuspend != NULL)) {
-	    if (conn->drivers[i]->domainSuspend(domain) == 0)
-	        return (0);
-	}
-    }
+    if (conn->driver->domainSuspend)
+        return conn->driver->domainSuspend (domain);
 
-        virLibConnError(conn, VIR_ERR_CALL_FAILED, __FUNCTION__);
-    return (-1);
+    virLibConnError (conn, VIR_ERR_NO_SUPPORT, __FUNCTION__);
+    return -1;
 }
 
 /**
@@ -976,7 +788,6 @@
 int
 virDomainResume(virDomainPtr domain)
 {
-    int i;
     virConnectPtr conn;
 
     if (!VIR_IS_CONNECTED_DOMAIN(domain)) {
@@ -990,29 +801,11 @@
 
     conn = domain->conn;
 
-    /*
-     * Go though the driver registered entry points but use the 
-     * XEN_HYPERVISOR directly only as a last mechanism
-     */
-    for (i = 0;i < conn->nb_drivers;i++) {
-	if ((conn->drivers[i] != NULL) &&
-	    (conn->drivers[i]->no != VIR_DRV_XEN_HYPERVISOR) &&
-	    (conn->drivers[i]->domainResume != NULL)) {
-	    if (conn->drivers[i]->domainResume(domain) == 0)
-	        return(0);
-	}
-    }
-    for (i = 0;i < conn->nb_drivers;i++) {
-	if ((conn->drivers[i] != NULL) &&
-	    (conn->drivers[i]->no == VIR_DRV_XEN_HYPERVISOR) &&
-	    (conn->drivers[i]->domainResume != NULL)) {
-	    if (conn->drivers[i]->domainResume(domain) == 0)
-	        return(0);
-	}
-    }
+    if (conn->driver->domainResume)
+        return conn->driver->domainResume (domain);
 
-    virLibConnError(conn, VIR_ERR_CALL_FAILED, __FUNCTION__);
-    return (-1);
+    virLibConnError (conn, VIR_ERR_NO_SUPPORT, __FUNCTION__);
+    return -1;
 }
 
 /**
@@ -1030,7 +823,6 @@
 int
 virDomainSave(virDomainPtr domain, const char *to)
 {
-    int ret, i;
     char filepath[4096];
     virConnectPtr conn;
 
@@ -1068,17 +860,11 @@
 
     }
 
-    /* Go though the driver registered entry points */
-    for (i = 0;i < conn->nb_drivers;i++) {
-	if ((conn->drivers[i] != NULL) &&
-	    (conn->drivers[i]->domainSave != NULL)) {
-	    ret = conn->drivers[i]->domainSave(domain, to);
-	    if (ret == 0)
-	        return(0);
-	}
-    }
-    virLibConnError(conn, VIR_ERR_CALL_FAILED, __FUNCTION__);
-    return (-1);
+    if (conn->driver->domainSave)
+        return conn->driver->domainSave (domain, to);
+
+    virLibConnError (conn, VIR_ERR_CALL_FAILED, __FUNCTION__);
+    return -1;
 }
 
 /**
@@ -1093,7 +879,6 @@
 int
 virDomainRestore(virConnectPtr conn, const char *from)
 {
-    int ret, i;
     char filepath[4096];
 
     if (!VIR_IS_CONNECT(conn)) {
@@ -1128,17 +913,11 @@
         from = &filepath[0];
     }
 
-    /* Go though the driver registered entry points */
-    for (i = 0;i < conn->nb_drivers;i++) {
-	if ((conn->drivers[i] != NULL) &&
-	    (conn->drivers[i]->domainSave != NULL)) {
-	    ret = conn->drivers[i]->domainRestore(conn, from);
-	    if (ret == 0)
-	        return(0);
-	}
-    }
-    virLibConnError(conn, VIR_ERR_CALL_FAILED, __FUNCTION__);
-    return (-1);
+    if (conn->driver->domainRestore)
+        return conn->driver->domainRestore (conn, from);
+
+    virLibConnError (conn, VIR_ERR_CALL_FAILED, __FUNCTION__);
+    return -1;
 }
 
 /**
@@ -1156,7 +935,6 @@
 int
 virDomainCoreDump(virDomainPtr domain, const char *to, int flags)
 {
-    int ret, i;
     char filepath[4096];
     virConnectPtr conn;
 
@@ -1194,17 +972,11 @@
 
     }
 
-    /* Go though the driver registered entry points */
-    for (i = 0;i < conn->nb_drivers;i++) {
-	if ((conn->drivers[i] != NULL) &&
-	    (conn->drivers[i]->domainCoreDump != NULL)) {
-	    ret = conn->drivers[i]->domainCoreDump(domain, to, flags);
-	    if (ret == 0)
-	        return(0);
-	}
-    }
-    virLibConnError(conn, VIR_ERR_CALL_FAILED, __FUNCTION__);
-    return (-1);
+    if (conn->driver->domainCoreDump)
+        return conn->driver->domainCoreDump (domain, to, flags);
+
+    virLibConnError (conn, VIR_ERR_CALL_FAILED, __FUNCTION__);
+    return -1;
 }
 
 /**
@@ -1223,7 +995,6 @@
 int
 virDomainShutdown(virDomainPtr domain)
 {
-    int ret = -1, i;
     virConnectPtr conn;
 
     if (!VIR_IS_CONNECTED_DOMAIN(domain)) {
@@ -1237,21 +1008,11 @@
 
     conn = domain->conn;
 
-    /* Go though the driver registered entry points */
-    for (i = 0;i < conn->nb_drivers;i++) {
-	if ((conn->drivers[i] != NULL) &&
-	    (conn->drivers[i]->domainShutdown != NULL)) {
-	    if (conn->drivers[i]->domainShutdown(domain) == 0)
-	        ret = 0;
-	}
-    }
-
-    if (ret != 0) {
-        virLibConnError(conn, VIR_ERR_CALL_FAILED, __FUNCTION__);
-        return (ret);
-    }
+    if (conn->driver->domainShutdown)
+        return conn->driver->domainShutdown (domain);
 
-    return (ret);
+    virLibConnError (conn, VIR_ERR_CALL_FAILED, __FUNCTION__);
+    return -1;
 }
 
 /**
@@ -1268,7 +1029,6 @@
 int
 virDomainReboot(virDomainPtr domain, unsigned int flags)
 {
-    int ret = -1, i;
     virConnectPtr conn;
 
     if (!VIR_IS_CONNECTED_DOMAIN(domain)) {
@@ -1282,21 +1042,11 @@
 
     conn = domain->conn;
 
-    /* Go though the driver registered entry points */
-    for (i = 0;i < conn->nb_drivers;i++) {
-	if ((conn->drivers[i] != NULL) &&
-	    (conn->drivers[i]->domainReboot != NULL)) {
-	    if (conn->drivers[i]->domainReboot(domain, flags) == 0)
-	        ret = 0;
-	}
-    }
-
-    if (ret != 0) {
-        virLibConnError(conn, VIR_ERR_CALL_FAILED, __FUNCTION__);
-        return (ret);
-    }
+    if (conn->driver->domainReboot)
+        return conn->driver->domainReboot (domain, flags);
 
-    return (ret);
+    virLibConnError (conn, VIR_ERR_CALL_FAILED, __FUNCTION__);
+    return -1;
 }
 
 /**
@@ -1342,7 +1092,11 @@
     if (domain->id == 0) {
         memset(uuid, 0, VIR_UUID_BUFLEN);
     } else {
-#ifdef WITH_XEN
+#if 0
+        /* Probably legacy code: It appears that we always fill in
+         * the UUID when creating the virDomain structure, so this
+         * shouldn't be necessary.
+         */
         if ((domain->uuid[0] == 0) && (domain->uuid[1] == 0) &&
             (domain->uuid[2] == 0) && (domain->uuid[3] == 0) &&
             (domain->uuid[4] == 0) && (domain->uuid[5] == 0) &&
@@ -1384,7 +1138,7 @@
     }
     
     if (virDomainGetUUID(domain, &uuid[0]))
-	return (-1);
+        return (-1);
 
     snprintf(buf, VIR_UUID_STRING_BUFLEN,
 	"%02x%02x%02x%02x-%02x%02x-%02x%02x-%02x%02x-%02x%02x%02x%02x%02x%02x",
@@ -1425,24 +1179,20 @@
 char *
 virDomainGetOSType(virDomainPtr domain)
 {
-    char *str = NULL;
-    int i;
+    virConnectPtr conn;
 
     if (!VIR_IS_DOMAIN(domain)) {
         virLibDomainError(domain, VIR_ERR_INVALID_DOMAIN, __FUNCTION__);
         return (NULL);
     }
 
-    for (i = 0;i < domain->conn->nb_drivers;i++) {
-	if ((domain->conn->drivers[i] != NULL) &&
-	    (domain->conn->drivers[i]->domainGetOSType != NULL)) {
-	    str = domain->conn->drivers[i]->domainGetOSType(domain);
-	    if (str != NULL)
-	        break;
-	}
-    }
+    conn = domain->conn;
+
+    if (conn->driver->domainGetOSType)
+        return conn->driver->domainGetOSType (domain);
 
-    return (str);
+    virLibConnError (conn, VIR_ERR_CALL_FAILED, __FUNCTION__);
+    return NULL;
 }
 
 /**
@@ -1458,9 +1208,7 @@
 unsigned long
 virDomainGetMaxMemory(virDomainPtr domain)
 {
-    unsigned long ret = 0;
     virConnectPtr conn;
-    int i;
 
     if (!VIR_IS_CONNECTED_DOMAIN(domain)) {
         virLibDomainError(domain, VIR_ERR_INVALID_DOMAIN, __FUNCTION__);
@@ -1469,20 +1217,11 @@
 
     conn = domain->conn;
 
-    /*
-     * in that case instead of trying only though one method try all availble.
-     * If needed that can be changed back if it's a performcance problem.
-     */
-    for (i = 0;i < conn->nb_drivers;i++) {
-	if ((conn->drivers[i] != NULL) &&
-	    (conn->drivers[i]->domainGetMaxMemory != NULL)) {
-	    ret = conn->drivers[i]->domainGetMaxMemory(domain);
-	    if (ret != 0)
-	        return(ret);
-	}
-    }
-    virLibConnError(conn, VIR_ERR_CALL_FAILED, __FUNCTION__);
-    return (-1);
+    if (conn->driver->domainGetMaxMemory)
+        return conn->driver->domainGetMaxMemory (domain);
+
+    virLibConnError (conn, VIR_ERR_CALL_FAILED, __FUNCTION__);
+    return 0;
 }
 
 /**
@@ -1500,7 +1239,6 @@
 int
 virDomainSetMaxMemory(virDomainPtr domain, unsigned long memory)
 {
-    int ret = -1 , i;
     virConnectPtr conn;
 
     if (domain == NULL) {
@@ -1521,22 +1259,11 @@
     }
     conn = domain->conn;
 
-    /*
-     * in that case instead of trying only though one method try all availble.
-     * If needed that can be changed back if it's a performcance problem.
-     */
-    for (i = 0;i < conn->nb_drivers;i++) {
-	if ((conn->drivers[i] != NULL) &&
-	    (conn->drivers[i]->domainSetMaxMemory != NULL)) {
-	    if (conn->drivers[i]->domainSetMaxMemory(domain, memory) == 0)
-	        ret = 0;
-	}
-    }
-    if (ret != 0) {
-        virLibConnError(conn, VIR_ERR_CALL_FAILED, __FUNCTION__);
-        return (-1);
-    }
-    return (ret);
+    if (conn->driver->domainSetMaxMemory)
+        return conn->driver->domainSetMaxMemory (domain, memory);
+
+    virLibConnError (conn, VIR_ERR_CALL_FAILED, __FUNCTION__);
+    return -1;
 }
 
 /**
@@ -1554,7 +1281,6 @@
 int
 virDomainSetMemory(virDomainPtr domain, unsigned long memory)
 {
-    int ret = -1 , i;
     virConnectPtr conn;
 
     if (domain == NULL) {
@@ -1576,22 +1302,11 @@
 
     conn = domain->conn;
 
-    /*
-     * in that case instead of trying only though one method try all availble.
-     * If needed that can be changed back if it's a performcance problem.
-     */
-    for (i = 0;i < conn->nb_drivers;i++) {
-	if ((conn->drivers[i] != NULL) &&
-	    (conn->drivers[i]->domainSetMemory != NULL)) {
-	    if (conn->drivers[i]->domainSetMemory(domain, memory) == 0)
-	        ret = 0;
-	}
-    }
-    if (ret != 0) {
-        virLibConnError(conn, VIR_ERR_CALL_FAILED, __FUNCTION__);
-        return (-1);
-    }
-    return (ret);
+    if (conn->driver->domainSetMemory)
+        return conn->driver->domainSetMemory (domain, memory);
+
+    virLibConnError (conn, VIR_ERR_CALL_FAILED, __FUNCTION__);
+    return -1;
 }
 
 /**
@@ -1608,7 +1323,7 @@
 int
 virDomainGetInfo(virDomainPtr domain, virDomainInfoPtr info)
 {
-    int i;
+    virConnectPtr conn;
 
     if (!VIR_IS_CONNECTED_DOMAIN(domain)) {
         virLibDomainError(domain, VIR_ERR_INVALID_DOMAIN, __FUNCTION__);
@@ -1621,15 +1336,13 @@
 
     memset(info, 0, sizeof(virDomainInfo));
 
-    for (i = 0;i < domain->conn->nb_drivers;i++) {
-	if ((domain->conn->drivers[i] != NULL) &&
-	    (domain->conn->drivers[i]->domainGetInfo != NULL)) {
-	    if (domain->conn->drivers[i]->domainGetInfo(domain, info) == 0)
-	        return 0;
-	}
-    }
+    conn = domain->conn;
+
+    if (conn->driver->domainGetInfo)
+        return conn->driver->domainGetInfo (domain, info);
 
-    return (-1);
+    virLibConnError (conn, VIR_ERR_CALL_FAILED, __FUNCTION__);
+    return -1;
 }
 
 /**
@@ -1646,8 +1359,8 @@
 char *
 virDomainGetXMLDesc(virDomainPtr domain, int flags)
 {
-    int i;
-    char *ret = NULL;
+    virConnectPtr conn;
+
     if (!VIR_IS_DOMAIN(domain)) {
         virLibDomainError(domain, VIR_ERR_INVALID_DOMAIN, __FUNCTION__);
         return (NULL);
@@ -1657,19 +1370,13 @@
         return (NULL);
     }
 
-    for (i = 0;i < domain->conn->nb_drivers;i++) {
-	if ((domain->conn->drivers[i] != NULL) &&
-	    (domain->conn->drivers[i]->domainDumpXML != NULL)) {
-            ret = domain->conn->drivers[i]->domainDumpXML(domain, flags);
-	    if (ret)
-	        break;
-	}
-    }
-    if (!ret) {
-        virLibConnError(domain->conn, VIR_ERR_CALL_FAILED, __FUNCTION__);
-        return (NULL);
-    }
-    return(ret);
+    conn = domain->conn;
+
+    if (conn->driver->domainDumpXML)
+        return conn->driver->domainDumpXML (domain, flags);
+
+    virLibConnError (conn, VIR_ERR_CALL_FAILED, __FUNCTION__);
+    return NULL;
 }
 
 /**
@@ -1682,10 +1389,8 @@
  * Returns 0 in case of success and -1 in case of failure.
  */
 int
-virNodeGetInfo(virConnectPtr conn, virNodeInfoPtr info) {
-    int i;
-    int ret = -1;
-
+virNodeGetInfo(virConnectPtr conn, virNodeInfoPtr info)
+{
     if (!VIR_IS_CONNECT(conn)) {
         virLibConnError(conn, VIR_ERR_INVALID_CONN, __FUNCTION__);
         return (-1);
@@ -1695,19 +1400,11 @@
         return (-1);
     }
 
-    for (i = 0;i < conn->nb_drivers;i++) {
-	if ((conn->drivers[i] != NULL) &&
-	    (conn->drivers[i]->nodeGetInfo != NULL)) {
-	    ret = conn->drivers[i]->nodeGetInfo(conn, info);
-	    if (ret == 0)
-	        break;
-	}
-    }
-    if (ret != 0) {
-        virLibConnError(conn, VIR_ERR_CALL_FAILED, __FUNCTION__);
-        return (-1);
-    }
-    return(0);
+    if (conn->driver->nodeGetInfo)
+        return conn->driver->nodeGetInfo (conn, info);
+
+    virLibConnError (conn, VIR_ERR_CALL_FAILED, __FUNCTION__);
+    return -1;
 }
 
 /**
@@ -1723,20 +1420,15 @@
 char *
 virConnectGetCapabilities (virConnectPtr conn)
 {
-    int i;
-
     if (!VIR_IS_CONNECT (conn)) {
         virLibConnError (conn, VIR_ERR_INVALID_CONN, __FUNCTION__);
         return NULL;
     }
 
-    for (i = 0; i < conn->nb_drivers; i++) {
-        if (conn->drivers[i] && conn->drivers[i]->getCapabilities) {
-            return conn->drivers[i]->getCapabilities (conn);
-        }
-    }
+    if (conn->driver->getCapabilities)
+        return conn->driver->getCapabilities (conn);
 
-    virLibConnError(conn, VIR_ERR_CALL_FAILED, __FUNCTION__);
+    virLibConnError (conn, VIR_ERR_CALL_FAILED, __FUNCTION__);
     return NULL;
 }
 
@@ -1757,9 +1449,6 @@
  */
 virDomainPtr
 virDomainDefineXML(virConnectPtr conn, const char *xml) {
-    virDomainPtr ret = NULL;
-    int i;
-
     if (!VIR_IS_CONNECT(conn)) {
         virLibConnError(conn, VIR_ERR_INVALID_CONN, __FUNCTION__);
         return (NULL);
@@ -1773,17 +1462,11 @@
         return (NULL);
     }
 
-    /* Go though the driver registered entry points */
-    for (i = 0;i < conn->nb_drivers;i++) {
-	if ((conn->drivers[i] != NULL) &&
-	    (conn->drivers[i]->domainDefineXML != NULL)) {
-            ret = conn->drivers[i]->domainDefineXML(conn, xml);
-	    if (ret)
-	        return(ret);
-	}
-    }
+    if (conn->driver->domainDefineXML)
+        return conn->driver->domainDefineXML (conn, xml);
 
-    return(ret);
+    virLibConnError (conn, VIR_ERR_CALL_FAILED, __FUNCTION__);
+    return NULL;
 }
 
 /**
@@ -1796,7 +1479,6 @@
  */
 int
 virDomainUndefine(virDomainPtr domain) {
-    int ret, i;
     virConnectPtr conn;
 
     if (!VIR_IS_CONNECTED_DOMAIN(domain)) {
@@ -1809,17 +1491,11 @@
 	return (-1);
     }
 
-    /* Go though the driver registered entry points */
-    for (i = 0;i < conn->nb_drivers;i++) {
-	if ((conn->drivers[i] != NULL) &&
-	    (conn->drivers[i]->domainUndefine != NULL)) {
-	    ret = conn->drivers[i]->domainUndefine(domain);
-	    if (ret >= 0)
-	        return(ret);
-	}
-    }
+    if (conn->driver->domainUndefine)
+        return conn->driver->domainUndefine (domain);
 
-    return(-1);
+    virLibConnError (conn, VIR_ERR_CALL_FAILED, __FUNCTION__);
+    return -1;
 }
 
 /**
@@ -1833,25 +1509,16 @@
 int
 virConnectNumOfDefinedDomains(virConnectPtr conn)
 {
-    int ret = -1;
-    int i;
-
     if (!VIR_IS_CONNECT(conn)) {
         virLibConnError(conn, VIR_ERR_INVALID_CONN, __FUNCTION__);
         return (-1);
     }
 
-    /* Go though the driver registered entry points */
-    for (i = 0;i < conn->nb_drivers;i++) {
-	if ((conn->drivers[i] != NULL) &&
-	    (conn->drivers[i]->numOfDefinedDomains != NULL)) {
-	    ret = conn->drivers[i]->numOfDefinedDomains(conn);
-	    if (ret >= 0)
-	        return(ret);
-	}
-    }
+    if (conn->driver->numOfDefinedDomains)
+        return conn->driver->numOfDefinedDomains (conn);
 
-    return(-1);
+    virLibConnError (conn, VIR_ERR_CALL_FAILED, __FUNCTION__);
+    return -1;
 }
 
 /**
@@ -1867,9 +1534,6 @@
 int
 virConnectListDefinedDomains(virConnectPtr conn, char **const names,
                              int maxnames) {
-    int ret = -1;
-    int i;
-
     if (!VIR_IS_CONNECT(conn)) {
         virLibConnError(conn, VIR_ERR_INVALID_CONN, __FUNCTION__);
         return (-1);
@@ -1880,17 +1544,11 @@
         return (-1);
     }
 
-    /* Go though the driver registered entry points */
-    for (i = 0;i < conn->nb_drivers;i++) {
-	if ((conn->drivers[i] != NULL) &&
-	    (conn->drivers[i]->listDefinedDomains != NULL)) {
-	    ret = conn->drivers[i]->listDefinedDomains(conn, names, maxnames);
-	    if (ret >= 0)
-	        return(ret);
-	}
-    }
+    if (conn->driver->listDefinedDomains)
+        return conn->driver->listDefinedDomains (conn, names, maxnames);
 
-    return (-1);
+    virLibConnError (conn, VIR_ERR_CALL_FAILED, __FUNCTION__);
+    return -1;
 }
 
 /**
@@ -1904,8 +1562,8 @@
  */
 int
 virDomainCreate(virDomainPtr domain) {
-    int i, ret = -1;
     virConnectPtr conn;
+
     if (domain == NULL) {
         TODO
 	return (-1);
@@ -1920,15 +1578,11 @@
 	return (-1);
     }
 
-    for (i = 0;i < conn->nb_drivers;i++) {
-	if ((conn->drivers[i] != NULL) &&
-	    (conn->drivers[i]->domainCreate != NULL)) {
-	    ret = conn->drivers[i]->domainCreate(domain);
-	    if (ret == 0)
-	        return(ret);
-	}
-    }
-    return(ret);
+    if (conn->driver->domainCreate)
+        return conn->driver->domainCreate (domain);
+
+    virLibConnError (conn, VIR_ERR_CALL_FAILED, __FUNCTION__);
+    return -1;
 }
 
 /**
@@ -1944,8 +1598,9 @@
  */
 int
 virDomainGetAutostart(virDomainPtr domain,
-                      int *autostart) {
-    int i;
+                      int *autostart)
+{
+    virConnectPtr conn;
 
     if (!VIR_IS_DOMAIN(domain)) {
         virLibDomainError(domain, VIR_ERR_INVALID_DOMAIN, __FUNCTION__);
@@ -1956,14 +1611,13 @@
         return (-1);
     }
 
-    for (i = 0;i < domain->conn->nb_drivers;i++) {
-	if ((domain->conn->drivers[i] != NULL) &&
-	    (domain->conn->drivers[i]->domainGetAutostart != NULL) &&
-            (domain->conn->drivers[i]->domainGetAutostart(domain, autostart) == 0))
-            return (0);
-    }
-    virLibConnError(domain->conn, VIR_ERR_CALL_FAILED, __FUNCTION__);
-    return (-1);
+    conn = domain->conn;
+
+    if (conn->driver->domainGetAutostart)
+        return conn->driver->domainGetAutostart (domain, autostart);
+
+    virLibConnError (conn, VIR_ERR_CALL_FAILED, __FUNCTION__);
+    return -1;
 }
 
 /**
@@ -1978,22 +1632,22 @@
  */
 int
 virDomainSetAutostart(virDomainPtr domain,
-                      int autostart) {
-    int i;
+                      int autostart)
+{
+    virConnectPtr conn;
 
     if (!VIR_IS_DOMAIN(domain)) {
         virLibDomainError(domain, VIR_ERR_INVALID_DOMAIN, __FUNCTION__);
         return (-1);
     }
 
-    for (i = 0;i < domain->conn->nb_drivers;i++) {
-	if ((domain->conn->drivers[i] != NULL) &&
-	    (domain->conn->drivers[i]->domainSetAutostart != NULL) &&
-            (domain->conn->drivers[i]->domainSetAutostart(domain, autostart) == 0))
-            return (0);
-    }
-    virLibConnError(domain->conn, VIR_ERR_CALL_FAILED, __FUNCTION__);
-    return (-1);
+    conn = domain->conn;
+
+    if (conn->driver->domainSetAutostart)
+        return conn->driver->domainSetAutostart (domain, autostart);
+
+    virLibConnError (conn, VIR_ERR_CALL_FAILED, __FUNCTION__);
+    return -1;
 }
 
 /**
@@ -2012,7 +1666,6 @@
 int
 virDomainSetVcpus(virDomainPtr domain, unsigned int nvcpus)
 {
-    int i;
     virConnectPtr conn;
 
     if (domain == NULL) {
@@ -2034,29 +1687,11 @@
     }
     conn = domain->conn;
 
-    /*
-     * Go though the driver registered entry points but use the 
-     * XEN_HYPERVISOR directly only as a last mechanism
-     */
-    for (i = 0;i < conn->nb_drivers;i++) {
-	if ((conn->drivers[i] != NULL) &&
-	    (conn->drivers[i]->no != VIR_DRV_XEN_HYPERVISOR) &&
-	    (conn->drivers[i]->domainSetVcpus != NULL)) {
-	    if (conn->drivers[i]->domainSetVcpus(domain, nvcpus) == 0)
-	        return(0);
-	}
-    }
-    for (i = 0;i < conn->nb_drivers;i++) {
-	if ((conn->drivers[i] != NULL) &&
-	    (conn->drivers[i]->no == VIR_DRV_XEN_HYPERVISOR) &&
-	    (conn->drivers[i]->domainSetVcpus != NULL)) {
-	    if (conn->drivers[i]->domainSetVcpus(domain, nvcpus) == 0)
-	        return(0);
-	}
-    }
+    if (conn->driver->domainSetVcpus)
+        return conn->driver->domainSetVcpus (domain, nvcpus);
 
-    virLibConnError(conn, VIR_ERR_CALL_FAILED, __FUNCTION__);
-    return (-1);
+    virLibConnError (conn, VIR_ERR_CALL_FAILED, __FUNCTION__);
+    return -1;
 }
 
 /**
@@ -2081,7 +1716,6 @@
 virDomainPinVcpu(virDomainPtr domain, unsigned int vcpu,
                  unsigned char *cpumap, int maplen)
 {
-    int i;
     virConnectPtr conn;
 
     if (domain == NULL) {
@@ -2101,21 +1735,14 @@
         virLibDomainError(domain, VIR_ERR_INVALID_ARG, __FUNCTION__);
         return (-1);
     }
+
     conn = domain->conn;
 
-    /*
-     * Go though the driver registered entry points
-     */
-    for (i = 0;i < conn->nb_drivers;i++) {
-	if ((conn->drivers[i] != NULL) &&
-	    (conn->drivers[i]->domainPinVcpu != NULL)) {
-	    if (conn->drivers[i]->domainPinVcpu(domain, vcpu,
-	                                        cpumap, maplen) == 0)
-	        return(0);
-	}
-    }
-    virLibConnError(conn, VIR_ERR_CALL_FAILED, __FUNCTION__);
-    return (-1);
+    if (conn->driver->domainPinVcpu)
+        return conn->driver->domainPinVcpu (domain, vcpu, cpumap, maplen);
+
+    virLibConnError (conn, VIR_ERR_CALL_FAILED, __FUNCTION__);
+    return -1;
 }
 
 /**
@@ -2143,8 +1770,6 @@
 virDomainGetVcpus(virDomainPtr domain, virVcpuInfoPtr info, int maxinfo,
 		  unsigned char *cpumaps, int maplen)
 {
-    int ret;
-    int i;
     virConnectPtr conn;
 
     if (domain == NULL) {
@@ -2163,22 +1788,15 @@
         virLibDomainError(domain, VIR_ERR_INVALID_ARG, __FUNCTION__);
         return (-1);
     }
+
     conn = domain->conn;
 
-    /*
-     * Go though the driver registered entry points
-     */
-    for (i = 0;i < conn->nb_drivers;i++) {
-	if ((conn->drivers[i] != NULL) &&
-	    (conn->drivers[i]->domainGetVcpus != NULL)) {
-	    ret = conn->drivers[i]->domainGetVcpus(domain, info, maxinfo,
-	                                           cpumaps, maplen);
-	    if (ret >= 0)
-	        return(ret);
-	}
-    }
-    virLibConnError(conn, VIR_ERR_CALL_FAILED, __FUNCTION__);
-    return (-1);
+    if (conn->driver->domainGetVcpus)
+        return conn->driver->domainGetVcpus (domain, info, maxinfo,
+                                             cpumaps, maplen);
+
+    virLibConnError (conn, VIR_ERR_CALL_FAILED, __FUNCTION__);
+    return -1;
 }
 
 /**
@@ -2194,9 +1812,8 @@
  * Returns the maximum of virtual CPU or -1 in case of error.
  */
 int
-virDomainGetMaxVcpus(virDomainPtr domain) {
-    int i;
-    int ret = 0;
+virDomainGetMaxVcpus(virDomainPtr domain)
+{
     virConnectPtr conn;
 
     if (!VIR_IS_CONNECTED_DOMAIN(domain)) {
@@ -2206,16 +1823,11 @@
 
     conn = domain->conn;
 
-    for (i = 0;i < conn->nb_drivers;i++) {
-	if ((conn->drivers[i] != NULL) &&
-	    (conn->drivers[i]->domainGetMaxVcpus != NULL)) {
-	    ret = conn->drivers[i]->domainGetMaxVcpus(domain);
-	    if (ret != 0)
-	        return(ret);
-	}
-    }
-    virLibConnError(conn, VIR_ERR_CALL_FAILED, __FUNCTION__);
-    return (-1);
+    if (conn->driver->domainGetMaxVcpus)
+        return conn->driver->domainGetMaxVcpus (domain);
+
+    virLibConnError (conn, VIR_ERR_CALL_FAILED, __FUNCTION__);
+    return -1;
 }
 
 
@@ -2231,8 +1843,6 @@
 int
 virDomainAttachDevice(virDomainPtr domain, char *xml)
 {
-    int ret;
-    int i;
     virConnectPtr conn;
 
     if (!VIR_IS_CONNECTED_DOMAIN(domain)) {
@@ -2245,19 +1855,11 @@
     }
     conn = domain->conn;
 
-    /*
-     * Go though the driver registered entry points
-     */
-    for (i = 0;i < conn->nb_drivers;i++) {
-	if ((conn->drivers[i] != NULL) &&
-	    (conn->drivers[i]->domainAttachDevice != NULL)) {
-	    ret = conn->drivers[i]->domainAttachDevice(domain, xml);
-	    if (ret >= 0)
-	        return(ret);
-	}
-    }
-    virLibConnError(conn, VIR_ERR_CALL_FAILED, __FUNCTION__);
-    return (-1);
+    if (conn->driver->domainAttachDevice)
+        return conn->driver->domainAttachDevice (domain, xml);
+
+    virLibConnError (conn, VIR_ERR_CALL_FAILED, __FUNCTION__);
+    return -1;
 }
 
 /**
@@ -2272,8 +1874,6 @@
 int
 virDomainDetachDevice(virDomainPtr domain, char *xml)
 {
-    int ret;
-    int i;
     virConnectPtr conn;
 
     if (!VIR_IS_CONNECTED_DOMAIN(domain)) {
@@ -2286,19 +1886,11 @@
     }
     conn = domain->conn;
 
-    /*
-     * Go though the driver registered entry points
-     */
-    for (i = 0;i < conn->nb_drivers;i++) {
-	if ((conn->drivers[i] != NULL) &&
-	    (conn->drivers[i]->domainDetachDevice != NULL)) {
-	    ret = conn->drivers[i]->domainDetachDevice(domain, xml);
-	    if (ret >= 0)
-	        return(ret);
-	}
-    }
-    virLibConnError(conn, VIR_ERR_CALL_FAILED, __FUNCTION__);
-    return (-1);
+    if (conn->driver->domainDetachDevice)
+        return conn->driver->domainDetachDevice (domain, xml);
+
+    virLibConnError (conn, VIR_ERR_CALL_FAILED, __FUNCTION__);
+    return -1;
 }
 
 /**
@@ -2312,25 +1904,16 @@
 int
 virConnectNumOfNetworks(virConnectPtr conn)
 {
-    int ret = -1;
-    int i;
-
     if (!VIR_IS_CONNECT(conn)) {
         virLibConnError(conn, VIR_ERR_INVALID_CONN, __FUNCTION__);
         return (-1);
     }
 
-    /* Go though the driver registered entry points */
-    for (i = 0;i < conn->nb_network_drivers;i++) {
-	if ((conn->networkDrivers[i] != NULL) &&
-	    (conn->networkDrivers[i]->numOfNetworks != NULL)) {
-	    ret = conn->networkDrivers[i]->numOfNetworks(conn);
-	    if (ret >= 0)
-	        return(ret);
-	}
-    }
+    if (conn->networkDriver->numOfNetworks)
+        return conn->networkDriver->numOfNetworks (conn);
 
-    return(-1);
+    virLibConnError (conn, VIR_ERR_CALL_FAILED, __FUNCTION__);
+    return -1;
 }
 
 /**
@@ -2346,9 +1929,6 @@
 int
 virConnectListNetworks(virConnectPtr conn, char **const names, int maxnames)
 {
-    int ret = -1;
-    int i;
-
     if (!VIR_IS_CONNECT(conn)) {
         virLibConnError(conn, VIR_ERR_INVALID_CONN, __FUNCTION__);
         return (-1);
@@ -2359,17 +1939,11 @@
         return (-1);
     }
 
-    /* Go though the driver registered entry points */
-    for (i = 0;i < conn->nb_drivers;i++) {
-	if ((conn->networkDrivers[i] != NULL) &&
-	    (conn->networkDrivers[i]->listNetworks != NULL)) {
-	    ret = conn->networkDrivers[i]->listNetworks(conn, names, maxnames);
-	    if (ret >= 0)
-	        return(ret);
-	}
-    }
+    if (conn->networkDriver->listNetworks)
+        return conn->networkDriver->listNetworks (conn, names, maxnames);
 
-    return (-1);
+    virLibConnError (conn, VIR_ERR_CALL_FAILED, __FUNCTION__);
+    return -1;
 }
 
 /**
@@ -2383,25 +1957,16 @@
 int
 virConnectNumOfDefinedNetworks(virConnectPtr conn)
 {
-    int ret = -1;
-    int i;
-
     if (!VIR_IS_CONNECT(conn)) {
         virLibConnError(conn, VIR_ERR_INVALID_CONN, __FUNCTION__);
         return (-1);
     }
 
-    /* Go though the driver registered entry points */
-    for (i = 0;i < conn->nb_drivers;i++) {
-	if ((conn->networkDrivers[i] != NULL) &&
-	    (conn->networkDrivers[i]->numOfDefinedNetworks != NULL)) {
-	    ret = conn->networkDrivers[i]->numOfDefinedNetworks(conn);
-	    if (ret >= 0)
-	        return(ret);
-	}
-    }
+    if (conn->networkDriver->numOfDefinedNetworks)
+        return conn->networkDriver->numOfDefinedNetworks (conn);
 
-    return(-1);
+    virLibConnError (conn, VIR_ERR_CALL_FAILED, __FUNCTION__);
+    return -1;
 }
 
 /**
@@ -2416,10 +1981,8 @@
  */
 int
 virConnectListDefinedNetworks(virConnectPtr conn, char **const names,
-                              int maxnames) {
-    int ret = -1;
-    int i;
-
+                              int maxnames)
+{
     if (!VIR_IS_CONNECT(conn)) {
         virLibConnError(conn, VIR_ERR_INVALID_CONN, __FUNCTION__);
         return (-1);
@@ -2430,17 +1993,12 @@
         return (-1);
     }
 
-    /* Go though the driver registered entry points */
-    for (i = 0;i < conn->nb_drivers;i++) {
-	if ((conn->networkDrivers[i] != NULL) &&
-	    (conn->networkDrivers[i]->listDefinedNetworks != NULL)) {
-	    ret = conn->networkDrivers[i]->listDefinedNetworks(conn, names, maxnames);
-	    if (ret >= 0)
-	        return(ret);
-	}
-    }
+    if (conn->networkDriver->listDefinedNetworks)
+        return conn->networkDriver->listDefinedNetworks (conn,
+                                                         names, maxnames);
 
-    return (-1);
+    virLibConnError (conn, VIR_ERR_CALL_FAILED, __FUNCTION__);
+    return -1;
 }
 
 /**
@@ -2455,9 +2013,6 @@
 virNetworkPtr
 virNetworkLookupByName(virConnectPtr conn, const char *name)
 {
-    virNetworkPtr ret = NULL;
-    int i;
-
     if (!VIR_IS_CONNECT(conn)) {
         virLibConnError(conn, VIR_ERR_INVALID_CONN, __FUNCTION__);
         return (NULL);
@@ -2467,16 +2022,11 @@
         return (NULL);
     }
 
-    /* Go though the driver registered entry points */
-    for (i = 0;i < conn->nb_drivers;i++) {
-	if ((conn->networkDrivers[i] != NULL) &&
-	    (conn->networkDrivers[i]->networkLookupByName != NULL)) {
-	    ret = conn->networkDrivers[i]->networkLookupByName(conn, name);
-	    if (ret)
-	        return(ret);
-	}
-    }
-    return (NULL);
+    if (conn->networkDriver->networkLookupByName)
+        return conn->networkDriver->networkLookupByName (conn, name);
+
+    virLibConnError (conn, VIR_ERR_CALL_FAILED, __FUNCTION__);
+    return NULL;
 }
 
 /**
@@ -2491,9 +2041,6 @@
 virNetworkPtr
 virNetworkLookupByUUID(virConnectPtr conn, const unsigned char *uuid)
 {
-    virNetworkPtr ret;
-    int i;
-
     if (!VIR_IS_CONNECT(conn)) {
         virLibConnError(conn, VIR_ERR_INVALID_CONN, __FUNCTION__);
         return (NULL);
@@ -2503,17 +2050,11 @@
         return (NULL);
     }
 
-    /* Go though the driver registered entry points */
-    for (i = 0;i < conn->nb_drivers;i++) {
-	if ((conn->networkDrivers[i] != NULL) &&
-	    (conn->networkDrivers[i]->networkLookupByUUID != NULL)) {
-	    ret = conn->networkDrivers[i]->networkLookupByUUID(conn, uuid);
-	    if (ret)
-	        return(ret);
-	}
-    }
+    if (conn->networkDriver->networkLookupByUUID)
+        return conn->networkDriver->networkLookupByUUID (conn, uuid);
 
-    return (NULL);
+    virLibConnError (conn, VIR_ERR_CALL_FAILED, __FUNCTION__);
+    return NULL;
 }
 
 /**
@@ -2578,9 +2119,6 @@
 virNetworkPtr
 virNetworkCreateXML(virConnectPtr conn, const char *xmlDesc)
 {
-    virNetworkPtr ret;
-    int i;
-
     if (!VIR_IS_CONNECT(conn)) {
         virLibConnError(conn, VIR_ERR_INVALID_CONN, __FUNCTION__);
         return (NULL);
@@ -2594,15 +2132,11 @@
 	return (NULL);
     }
 
-    for (i = 0;i < conn->nb_drivers;i++) {
-	if ((conn->networkDrivers[i] != NULL) &&
-	    (conn->networkDrivers[i]->networkCreateXML != NULL)) {
-	    ret = conn->networkDrivers[i]->networkCreateXML(conn, xmlDesc);
-	    if (ret != NULL)
-	        return(ret);
-	}
-    }
-    return(NULL);
+    if (conn->networkDriver->networkCreateXML)
+        return conn->networkDriver->networkCreateXML (conn, xmlDesc);
+
+    virLibConnError (conn, VIR_ERR_CALL_FAILED, __FUNCTION__);
+    return NULL;
 }
 
 /**
@@ -2615,10 +2149,8 @@
  * Returns NULL in case of error, a pointer to the network otherwise
  */
 virNetworkPtr
-virNetworkDefineXML(virConnectPtr conn, const char *xml) {
-    virNetworkPtr ret = NULL;
-    int i;
-
+virNetworkDefineXML(virConnectPtr conn, const char *xml)
+{
     if (!VIR_IS_CONNECT(conn)) {
         virLibConnError(conn, VIR_ERR_INVALID_CONN, __FUNCTION__);
         return (NULL);
@@ -2632,17 +2164,11 @@
         return (NULL);
     }
 
-    /* Go though the driver registered entry points */
-    for (i = 0;i < conn->nb_drivers;i++) {
-	if ((conn->networkDrivers[i] != NULL) &&
-	    (conn->networkDrivers[i]->networkDefineXML != NULL)) {
-            ret = conn->networkDrivers[i]->networkDefineXML(conn, xml);
-	    if (ret)
-	        return(ret);
-	}
-    }
+    if (conn->networkDriver->networkDefineXML)
+        return conn->networkDriver->networkDefineXML (conn, xml);
 
-    return(ret);
+    virLibConnError (conn, VIR_ERR_CALL_FAILED, __FUNCTION__);
+    return NULL;
 }
 
 /**
@@ -2655,7 +2181,6 @@
  */
 int
 virNetworkUndefine(virNetworkPtr network) {
-    int ret, i;
     virConnectPtr conn;
 
     if (!VIR_IS_CONNECTED_NETWORK(network)) {
@@ -2668,17 +2193,11 @@
 	return (-1);
     }
 
-    /* Go though the driver registered entry points */
-    for (i = 0;i < conn->nb_drivers;i++) {
-	if ((conn->networkDrivers[i] != NULL) &&
-	    (conn->networkDrivers[i]->networkUndefine != NULL)) {
-	    ret = conn->networkDrivers[i]->networkUndefine(network);
-	    if (ret >= 0)
-	        return(ret);
-	}
-    }
+    if (conn->networkDriver->networkUndefine)
+        return conn->networkDriver->networkUndefine (network);
 
-    return(-1);
+    virLibConnError (conn, VIR_ERR_CALL_FAILED, __FUNCTION__);
+    return -1;
 }
 
 /**
@@ -2691,8 +2210,8 @@
  * Returns 0 in case of success, -1 in case of error
  */
 int
-virNetworkCreate(virNetworkPtr network) {
-    int i, ret = -1;
+virNetworkCreate(virNetworkPtr network)
+{
     virConnectPtr conn;
     if (network == NULL) {
         TODO
@@ -2708,15 +2227,11 @@
 	return (-1);
     }
 
-    for (i = 0;i < conn->nb_drivers;i++) {
-	if ((conn->networkDrivers[i] != NULL) &&
-	    (conn->networkDrivers[i]->networkCreate != NULL)) {
-	    ret = conn->networkDrivers[i]->networkCreate(network);
-	    if (ret == 0)
-	        return(ret);
-	}
-    }
-    return(ret);
+    if (conn->networkDriver->networkCreate)
+        return conn->networkDriver->networkCreate (network);
+
+    virLibConnError (conn, VIR_ERR_CALL_FAILED, __FUNCTION__);
+    return -1;
 }
 
 /**
@@ -2734,7 +2249,6 @@
 int
 virNetworkDestroy(virNetworkPtr network)
 {
-    int i;
     virConnectPtr conn;
 
     if (!VIR_IS_CONNECTED_NETWORK(network)) {
@@ -2748,19 +2262,11 @@
 	return (-1);
     }
 
-    /*
-     * Go though the driver registered entry points
-     */
-    for (i = 0;i < conn->nb_drivers;i++) {
-	if ((conn->networkDrivers[i] != NULL) &&
-	    (conn->networkDrivers[i]->networkDestroy != NULL)) {
-	    if (conn->networkDrivers[i]->networkDestroy(network) == 0)
-	        return (0);
-	}
-    }
+    if (conn->networkDriver->networkDestroy)
+        return conn->networkDriver->networkDestroy (network);
 
-    virLibConnError(conn, VIR_ERR_CALL_FAILED, __FUNCTION__);
-    return (-1);
+    virLibConnError (conn, VIR_ERR_CALL_FAILED, __FUNCTION__);
+    return -1;
 }
 
 /**
@@ -2879,8 +2385,8 @@
 char *
 virNetworkGetXMLDesc(virNetworkPtr network, int flags)
 {
-    int i;
-    char *ret = NULL;
+    virConnectPtr conn;
+
     if (!VIR_IS_NETWORK(network)) {
         virLibNetworkError(network, VIR_ERR_INVALID_NETWORK, __FUNCTION__);
         return (NULL);
@@ -2890,19 +2396,13 @@
         return (NULL);
     }
 
-    for (i = 0;i < network->conn->nb_network_drivers;i++) {
-	if ((network->conn->networkDrivers[i] != NULL) &&
-	    (network->conn->networkDrivers[i]->networkDumpXML != NULL)) {
-            ret = network->conn->networkDrivers[i]->networkDumpXML(network, flags);
-	    if (ret)
-	        break;
-	}
-    }
-    if (!ret) {
-        virLibConnError(network->conn, VIR_ERR_CALL_FAILED, __FUNCTION__);
-        return (NULL);
-    }
-    return(ret);
+    conn = network->conn;
+
+    if (conn->networkDriver->networkDumpXML)
+        return conn->networkDriver->networkDumpXML (network, flags);
+
+    virLibConnError (conn, VIR_ERR_CALL_FAILED, __FUNCTION__);
+    return NULL;
 }
 
 /**
@@ -2918,26 +2418,20 @@
 char *
 virNetworkGetBridgeName(virNetworkPtr network)
 {
-    int i;
-    char *ret = NULL;
+    virConnectPtr conn;
+
     if (!VIR_IS_NETWORK(network)) {
         virLibNetworkError(network, VIR_ERR_INVALID_NETWORK, __FUNCTION__);
         return (NULL);
     }
 
-    for (i = 0;i < network->conn->nb_network_drivers;i++) {
-	if ((network->conn->networkDrivers[i] != NULL) &&
-	    (network->conn->networkDrivers[i]->networkGetBridgeName != NULL)) {
-            ret = network->conn->networkDrivers[i]->networkGetBridgeName(network);
-	    if (ret)
-	        break;
-	}
-    }
-    if (!ret) {
-        virLibConnError(network->conn, VIR_ERR_CALL_FAILED, __FUNCTION__);
-        return (NULL);
-    }
-    return(ret);
+    conn = network->conn;
+
+    if (conn->networkDriver->networkGetBridgeName)
+        return conn->networkDriver->networkGetBridgeName (network);
+
+    virLibConnError (conn, VIR_ERR_CALL_FAILED, __FUNCTION__);
+    return NULL;
 }
 
 /**
@@ -2953,8 +2447,9 @@
  */
 int
 virNetworkGetAutostart(virNetworkPtr network,
-                       int *autostart) {
-    int i;
+                       int *autostart)
+{
+    virConnectPtr conn;
 
     if (!VIR_IS_NETWORK(network)) {
         virLibNetworkError(network, VIR_ERR_INVALID_NETWORK, __FUNCTION__);
@@ -2965,14 +2460,13 @@
         return (-1);
     }
 
-    for (i = 0;i < network->conn->nb_network_drivers;i++) {
-	if ((network->conn->networkDrivers[i] != NULL) &&
-	    (network->conn->networkDrivers[i]->networkGetAutostart != NULL) &&
-            (network->conn->networkDrivers[i]->networkGetAutostart(network, autostart) == 0))
-            return (0);
-    }
-    virLibConnError(network->conn, VIR_ERR_CALL_FAILED, __FUNCTION__);
-    return (-1);
+    conn = network->conn;
+
+    if (conn->networkDriver->networkGetAutostart)
+        return conn->networkDriver->networkGetAutostart (network, autostart);
+
+    virLibConnError (conn, VIR_ERR_CALL_FAILED, __FUNCTION__);
+    return -1;
 }
 
 /**
@@ -2987,22 +2481,22 @@
  */
 int
 virNetworkSetAutostart(virNetworkPtr network,
-                       int autostart) {
-    int i;
+                       int autostart)
+{
+    virConnectPtr conn;
 
     if (!VIR_IS_NETWORK(network)) {
         virLibNetworkError(network, VIR_ERR_INVALID_NETWORK, __FUNCTION__);
         return (-1);
     }
 
-    for (i = 0;i < network->conn->nb_network_drivers;i++) {
-	if ((network->conn->networkDrivers[i] != NULL) &&
-	    (network->conn->networkDrivers[i]->networkSetAutostart != NULL) &&
-            (network->conn->networkDrivers[i]->networkSetAutostart(network, autostart) == 0))
-            return (0);
-    }
-    virLibConnError(network->conn, VIR_ERR_CALL_FAILED, __FUNCTION__);
-    return (-1);
+    conn = network->conn;
+
+    if (conn->networkDriver->networkSetAutostart)
+        return conn->networkDriver->networkSetAutostart (network, autostart);
+
+    virLibConnError (conn, VIR_ERR_CALL_FAILED, __FUNCTION__);
+    return -1;
 }
 
 /*
Index: src/proxy_internal.c
===================================================================
RCS file: /data/cvs/libvirt/src/proxy_internal.c,v
retrieving revision 1.24
diff -u -r1.24 proxy_internal.c
--- src/proxy_internal.c	15 Mar 2007 17:24:57 -0000	1.24
+++ src/proxy_internal.c	28 Mar 2007 16:02:21 -0000
@@ -43,7 +43,7 @@
 static char *xenProxyDomainGetOSType(virDomainPtr domain);
 
 static virDriver xenProxyDriver = {
-    VIR_DRV_XEN_PROXY,
+    -1,
     "XenProxy",
     0,
     xenProxyOpen, /* open */
Index: src/proxy_internal.h
===================================================================
RCS file: /data/cvs/libvirt/src/proxy_internal.h,v
retrieving revision 1.6
diff -u -r1.6 proxy_internal.h
--- src/proxy_internal.h	15 Mar 2007 17:24:57 -0000	1.6
+++ src/proxy_internal.h	28 Mar 2007 16:02:21 -0000
@@ -84,10 +84,9 @@
 };
 typedef struct _virProxyFullPacket virProxyFullPacket;
 typedef  virProxyFullPacket *virProxyFullPacketPtr;
-/*
- * Functions callable from libvirt library
- */
-void xenProxyRegister(void);
+
+extern virDriver xenProxyDriver;
+int xenProxyInit (void);
 
 #ifdef __cplusplus
 }
Index: src/qemu_internal.c
===================================================================
RCS file: /data/cvs/libvirt/src/qemu_internal.c,v
retrieving revision 1.19
diff -u -r1.19 qemu_internal.c
--- src/qemu_internal.c	15 Mar 2007 18:23:00 -0000	1.19
+++ src/qemu_internal.c	28 Mar 2007 16:02:21 -0000
@@ -1260,9 +1260,15 @@
  *
  * Registers QEmu/KVM in libvirt driver system
  */
-void qemuRegister(void) {
-    virRegisterDriver(&qemuDriver);
-    virRegisterNetworkDriver(&qemuNetworkDriver);
+int
+qemuRegister (void)
+{
+    if (virRegisterDriver(&qemuDriver) == -1)
+        return -1;
+    if (virRegisterNetworkDriver(&qemuNetworkDriver) == -1)
+        return -1;
+
+    return 0;
 }
 #endif /* WITH_QEMU */
 
Index: src/qemu_internal.h
===================================================================
RCS file: /data/cvs/libvirt/src/qemu_internal.h,v
retrieving revision 1.1
diff -u -r1.1 qemu_internal.h
--- src/qemu_internal.h	14 Feb 2007 01:40:09 -0000	1.1
+++ src/qemu_internal.h	28 Mar 2007 16:02:21 -0000
@@ -30,7 +30,7 @@
 extern "C" {
 #endif
 
-    void qemuRegister(void);
+int qemuRegister(void);
 
 #ifdef __cplusplus
 }
Index: src/test.c
===================================================================
RCS file: /data/cvs/libvirt/src/test.c,v
retrieving revision 1.25
diff -u -r1.25 test.c
--- src/test.c	16 Mar 2007 15:03:21 -0000	1.25
+++ src/test.c	28 Mar 2007 16:02:23 -0000
@@ -134,6 +134,12 @@
     NULL, /* domainSetAutostart */
 };
 
+/* Per-connection private data. */
+struct _testPrivate {
+    int handle;
+};
+typedef struct _testPrivate *testPrivatePtr;
+
 typedef struct _testDev {
     char name[20];
     virDeviceMode mode;
@@ -244,9 +250,10 @@
  *
  * Registers the test driver
  */
-void testRegister(void)
+int
+testRegister(void)
 {
-    virRegisterDriver(&testDriver);
+    return virRegisterDriver(&testDriver);
 }
 
 static int testLoadDomain(virConnectPtr conn,
@@ -268,6 +275,7 @@
     virDomainRestart onReboot = VIR_DOMAIN_RESTART;
     virDomainRestart onPoweroff = VIR_DOMAIN_DESTROY;
     virDomainRestart onCrash = VIR_DOMAIN_RENAME_RESTART;
+    testPrivatePtr priv;
 
     if (gettimeofday(&tv, NULL) < 0) {
         testError(conn, NULL, VIR_ERR_INTERNAL_ERROR, _("getting time of day"));
@@ -336,9 +344,6 @@
     if (obj)
         xmlXPathFreeObject(obj);
 
-
-
-
     obj = xmlXPathEval(BAD_CAST "string(/domain/vcpu[1])", ctxt);
     if ((obj == NULL) || (obj->type != XPATH_STRING) ||
         (obj->stringval == NULL) || (obj->stringval[0] == 0)) {
@@ -386,7 +391,8 @@
     if (obj)
         xmlXPathFreeObject(obj);
 
-    con = &node->connections[conn->handle];
+    priv = (testPrivatePtr) conn->privateData;
+    con = &node->connections[priv->handle];
 
     for (i = 0 ; i < MAX_DOMAINS ; i++) {
         if (!con->domains[i].active) {
@@ -479,13 +485,14 @@
                            int connid) {
     int u;
     struct timeval tv;
+    testPrivatePtr priv = (testPrivatePtr) conn->privateData;
 
     if (gettimeofday(&tv, NULL) < 0) {
         testError(NULL, NULL, VIR_ERR_INTERNAL_ERROR, _("getting time of day"));
         return (-1);
     }
 
-    conn->handle = connid;
+    priv->handle = connid;
     node->connections[connid].active = 1;
     memmove(&node->connections[connid].nodeInfo, &defaultNodeInfo, sizeof(defaultNodeInfo));
 
@@ -538,6 +545,7 @@
     xmlXPathContextPtr ctxt = NULL;
     xmlXPathObjectPtr obj = NULL;
     virNodeInfoPtr nodeInfo;
+    testPrivatePtr priv = (testPrivatePtr) conn->privateData;
 
     if ((fd = open(file, O_RDONLY)) < 0) {
         testError(NULL, NULL, VIR_ERR_INTERNAL_ERROR, _("loading host definition file"));
@@ -565,7 +573,7 @@
         goto error;
     }
 
-    conn->handle = connid;
+    priv->handle = connid;
     node->connections[connid].active = 1;
     node->connections[connid].numDomains = 0;
     memmove(&node->connections[connid].nodeInfo, &defaultNodeInfo, sizeof(defaultNodeInfo));
@@ -732,7 +740,9 @@
 static int getDomainIndex(virDomainPtr domain) {
     int i;
     testCon *con;
-    con = &node->connections[domain->conn->handle];
+    testPrivatePtr priv = (testPrivatePtr) domain->conn->privateData;
+
+    con = &node->connections[priv->handle];
     for (i = 0 ; i < MAX_DOMAINS ; i++) {
         if (domain->id >= 0) {
             if (domain->id == con->domains[i].id)
@@ -776,6 +786,13 @@
         return (-1);
     }
 
+    /* Allocate per-connection private data. */
+    conn->privateData = malloc (sizeof (struct _testPrivate));
+    if (!conn->privateData) {
+        testError(NULL, NULL, VIR_ERR_NO_MEMORY, _("allocating private data"));
+        return (-1);
+    }
+
     if (!strcmp(uri->path, "/default")) {
         ret = testOpenDefault(conn,
                               connid);
@@ -787,14 +804,17 @@
 
     xmlFreeURI(uri);
 
+    if (ret == -1) free (conn->privateData);
+
     return (ret);
 }
 
 int testClose(virConnectPtr conn)
 {
-    testCon *con = &node->connections[conn->handle];
+    testPrivatePtr priv = (testPrivatePtr) conn->privateData;
+    testCon *con = &node->connections[priv->handle];
     con->active = 0;
-    conn->handle = -1;
+    free (priv);
     memset(con, 0, sizeof(testCon));
     return (0);
 }
@@ -809,7 +829,8 @@
 int testNodeGetInfo(virConnectPtr conn,
                     virNodeInfoPtr info)
 {
-    testCon *con = &node->connections[conn->handle];
+    testPrivatePtr priv = (testPrivatePtr) conn->privateData;
+    testCon *con = &node->connections[priv->handle];
     memcpy(info, &con->nodeInfo, sizeof(virNodeInfo));
     return (0);
 }
@@ -854,7 +875,8 @@
 int testNumOfDomains(virConnectPtr conn)
 {
     int numActive = 0, i;
-    testCon *con = &node->connections[conn->handle];
+    testPrivatePtr priv = (testPrivatePtr) conn->privateData;
+    testCon *con = &node->connections[priv->handle];
     for (i = 0 ; i < MAX_DOMAINS ; i++) {
         if (!con->domains[i].active ||
             con->domains[i].info.state == VIR_DOMAIN_SHUTOFF)
@@ -871,6 +893,7 @@
     testCon *con;
     int domid, handle = -1, i;
     virDomainPtr dom;
+    testPrivatePtr priv;
 
     if (!VIR_IS_CONNECT(conn)) {
         testError(conn, NULL, VIR_ERR_INVALID_CONN, __FUNCTION__);
@@ -884,8 +907,10 @@
         testError(conn, NULL, VIR_ERR_OPERATION_DENIED, __FUNCTION__);
         return (NULL);
     }
+
+    priv = (testPrivatePtr) conn->privateData;
   
-    con = &node->connections[conn->handle];
+    con = &node->connections[priv->handle];
 
     if (con->numDomains == MAX_DOMAINS) {
         testError(NULL, NULL, VIR_ERR_INTERNAL_ERROR, _("too many domains"));
@@ -914,7 +939,8 @@
 virDomainPtr testLookupDomainByID(virConnectPtr conn,
                                   int id)
 {
-    testCon *con = &node->connections[conn->handle];
+    testPrivatePtr priv = (testPrivatePtr) conn->privateData;
+    testCon *con = &node->connections[priv->handle];
     virDomainPtr dom;
     int i, idx = -1;
 
@@ -942,7 +968,8 @@
 virDomainPtr testLookupDomainByUUID(virConnectPtr conn,
                                     const unsigned char *uuid)
 {
-    testCon *con = &node->connections[conn->handle];
+    testPrivatePtr priv = (testPrivatePtr) conn->privateData;
+    testCon *con = &node->connections[priv->handle];
     virDomainPtr dom = NULL;
     int i, idx = -1;
     for (i = 0 ; i < MAX_DOMAINS ; i++) {
@@ -966,7 +993,8 @@
 virDomainPtr testLookupDomainByName(virConnectPtr conn,
                                     const char *name)
 {
-    testCon *con = &node->connections[conn->handle];
+    testPrivatePtr priv = (testPrivatePtr) conn->privateData;
+    testCon *con = &node->connections[priv->handle];
     virDomainPtr dom = NULL;
     int i, idx = -1;
     for (i = 0 ; i < MAX_DOMAINS ; i++) {
@@ -991,7 +1019,8 @@
                      int *ids,
                      int maxids)
 {
-    testCon *con = &node->connections[conn->handle];
+    testPrivatePtr priv = (testPrivatePtr) conn->privateData;
+    testCon *con = &node->connections[priv->handle];
     int n, i;
 
     for (i = 0, n = 0 ; i < MAX_DOMAINS && n < maxids ; i++) {
@@ -1007,6 +1036,8 @@
 {
     testCon *con;
     int domidx;
+    testPrivatePtr priv;
+
     if ((domain == NULL) || (domain->conn == NULL) || (domain->name == NULL) ||
         ((domidx = getDomainIndex(domain)) < 0)) {
         testError((domain ? domain->conn : NULL), domain, VIR_ERR_INVALID_ARG,
@@ -1018,7 +1049,9 @@
         return (-1);
     }
 
-    con = &node->connections[domain->conn->handle];
+    priv = (testPrivatePtr) domain->conn->privateData;
+
+    con = &node->connections[priv->handle];
     con->domains[domidx].active = 0;
     return (0);
 }
@@ -1027,6 +1060,8 @@
 {
     testCon *con;
     int domidx;
+    testPrivatePtr priv;
+
     if ((domain == NULL) || (domain->conn == NULL) || (domain->name == NULL) ||
         ((domidx = getDomainIndex(domain)) < 0)) {
         testError((domain ? domain->conn : NULL), domain, VIR_ERR_INVALID_ARG,
@@ -1038,7 +1073,9 @@
         return (-1);
     }
 
-    con = &node->connections[domain->conn->handle];
+    priv = (testPrivatePtr) domain->conn->privateData;
+
+    con = &node->connections[priv->handle];
     con->domains[domidx].info.state = VIR_DOMAIN_RUNNING;
     return (0);
 }
@@ -1047,6 +1084,8 @@
 {
     testCon *con;\
     int domidx;
+    testPrivatePtr priv;
+
     if ((domain == NULL) || (domain->conn == NULL) || (domain->name == NULL) ||
         ((domidx = getDomainIndex(domain)) < 0)) {
         testError((domain ? domain->conn : NULL), domain, VIR_ERR_INVALID_ARG,
@@ -1058,7 +1097,9 @@
         return (-1);
     }
 
-    con = &node->connections[domain->conn->handle];
+    priv = (testPrivatePtr) domain->conn->privateData;
+
+    con = &node->connections[priv->handle];
     con->domains[domidx].info.state = VIR_DOMAIN_PAUSED;
     return (0);
 }
@@ -1072,6 +1113,8 @@
     testCon *con;
     int domidx;
     struct timeval tv;
+    testPrivatePtr priv;
+
     if ((domain == NULL) || (domain->conn == NULL) || (domain->name == NULL) ||
         ((domidx = getDomainIndex(domain)) < 0)) {
         testError((domain ? domain->conn : NULL), domain, VIR_ERR_INVALID_ARG,
@@ -1083,7 +1126,9 @@
         return (-1);
     }
 
-    con = &node->connections[domain->conn->handle];
+    priv = (testPrivatePtr) domain->conn->privateData;
+
+    con = &node->connections[priv->handle];
 
     if (gettimeofday(&tv, NULL) < 0) {
         testError(NULL, NULL, VIR_ERR_INTERNAL_ERROR, _("getting time of day"));
@@ -1103,6 +1148,8 @@
     testCon *con;
     int domidx;
     struct timeval tv;
+    testPrivatePtr priv;
+
     if ((domain == NULL) || (domain->conn == NULL) || (domain->name == NULL) ||
         ((domidx = getDomainIndex(domain)) < 0)) {
         testError((domain ? domain->conn : NULL), domain, VIR_ERR_INVALID_ARG,
@@ -1114,7 +1161,8 @@
         return (-1);
     }
 
-    con = &node->connections[domain->conn->handle];
+    priv = (testPrivatePtr) domain->conn->privateData;
+    con = &node->connections[priv->handle];
 
     if (gettimeofday(&tv, NULL) < 0) {
         testError(NULL, NULL, VIR_ERR_INTERNAL_ERROR, _("getting time of day"));
@@ -1158,6 +1206,8 @@
     struct timeval tv;
     testCon *con;
     int domidx;
+    testPrivatePtr priv;
+
     if ((domain == NULL) || (domain->conn == NULL) || (domain->name == NULL) ||
         ((domidx = getDomainIndex(domain)) < 0)) {
         testError((domain ? domain->conn : NULL), domain, VIR_ERR_INVALID_ARG,
@@ -1165,7 +1215,8 @@
         return (-1);
     }
 
-    con = &node->connections[domain->conn->handle];
+    priv = (testPrivatePtr) domain->conn->privateData;
+    con = &node->connections[priv->handle];
 
     if (gettimeofday(&tv, NULL) < 0) {
         testError(NULL, NULL, VIR_ERR_INTERNAL_ERROR, _("getting time of day"));
@@ -1189,6 +1240,8 @@
 unsigned long testGetMaxMemory(virDomainPtr domain) {
     testCon *con;
     int domidx;
+    testPrivatePtr priv;
+
     if ((domain == NULL) || (domain->conn == NULL) || (domain->name == NULL) ||
         ((domidx = getDomainIndex(domain)) < 0)) {
         testError((domain ? domain->conn : NULL), domain, VIR_ERR_INVALID_ARG,
@@ -1196,7 +1249,8 @@
         return (-1);
     }
 
-    con = &node->connections[domain->conn->handle];
+    priv = (testPrivatePtr) domain->conn->privateData;
+    con = &node->connections[priv->handle];
     return con->domains[domidx].info.maxMem;
 }
 
@@ -1205,6 +1259,8 @@
 {
     testCon *con;
     int domidx;
+    testPrivatePtr priv;
+
     if ((domain == NULL) || (domain->conn == NULL) || (domain->name == NULL) ||
         ((domidx = getDomainIndex(domain)) < 0)) {
         testError((domain ? domain->conn : NULL), domain, VIR_ERR_INVALID_ARG,
@@ -1216,7 +1272,8 @@
         return (-1);
     }
 
-    con = &node->connections[domain->conn->handle];
+    priv = (testPrivatePtr) domain->conn->privateData;
+    con = &node->connections[priv->handle];
     /* XXX validate not over host memory wrt to other domains */
     con->domains[domidx].info.maxMem = memory;
     return (0);
@@ -1227,6 +1284,8 @@
 {
     testCon *con;
     int domidx;
+    testPrivatePtr priv;
+
     if ((domain == NULL) || (domain->conn == NULL) || (domain->name == NULL) ||
         ((domidx = getDomainIndex(domain)) < 0)) {
         testError((domain ? domain->conn : NULL), domain, VIR_ERR_INVALID_ARG,
@@ -1238,7 +1297,8 @@
         return (-1);
     }
 
-    con = &node->connections[domain->conn->handle];
+    priv = (testPrivatePtr) domain->conn->privateData;
+    con = &node->connections[priv->handle];
 
     if (memory > con->domains[domidx].info.maxMem) {
         testError(domain->conn, domain, VIR_ERR_INVALID_ARG, __FUNCTION__);
@@ -1253,6 +1313,8 @@
                  unsigned int nrCpus) {
     testCon *con;
     int domidx;
+    testPrivatePtr priv;
+
     if ((domain == NULL) || (domain->conn == NULL) || (domain->name == NULL) ||
         ((domidx = getDomainIndex(domain)) < 0)) {
         testError((domain ? domain->conn : NULL), domain, VIR_ERR_INVALID_ARG,
@@ -1264,7 +1326,8 @@
         return (-1);
     }
 
-    con = &node->connections[domain->conn->handle];
+    priv = (testPrivatePtr) domain->conn->privateData;
+    con = &node->connections[priv->handle];
 
     /* We allow more cpus in guest than host */
     if (nrCpus > 32) {
@@ -1283,6 +1346,8 @@
     unsigned char *uuid;
     testCon *con;
     int domidx;
+    testPrivatePtr priv;
+
     if ((domain == NULL) || (domain->conn == NULL) || (domain->name == NULL) ||
         ((domidx = getDomainIndex(domain)) < 0)) {
         testError((domain ? domain->conn : NULL), domain, VIR_ERR_INVALID_ARG,
@@ -1290,7 +1355,8 @@
         return (NULL);
     }
 
-    con = &node->connections[domain->conn->handle];
+    priv = (testPrivatePtr) domain->conn->privateData;
+    con = &node->connections[priv->handle];
 
     if (!(buf = virBufferNew(4000))) {
         return (NULL);
@@ -1323,7 +1389,8 @@
 
 int testNumOfDefinedDomains(virConnectPtr conn) {
     int numInactive = 0, i;
-    testCon *con = &node->connections[conn->handle];
+    testPrivatePtr priv = (testPrivatePtr) conn->privateData;
+    testCon *con = &node->connections[priv->handle];
     for (i = 0 ; i < MAX_DOMAINS ; i++) {
         if (!con->domains[i].active ||
             con->domains[i].info.state != VIR_DOMAIN_SHUTOFF)
@@ -1336,7 +1403,8 @@
 int testListDefinedDomains(virConnectPtr conn,
                            char **const names,
                            int maxnames) {
-    testCon *con = &node->connections[conn->handle];
+    testPrivatePtr priv = (testPrivatePtr) conn->privateData;
+    testCon *con = &node->connections[priv->handle];
     int n = 0, i;
 
     for (i = 0, n = 0 ; i < MAX_DOMAINS && n < maxnames ; i++) {
@@ -1375,6 +1443,8 @@
 int testDomainCreate(virDomainPtr domain) {
     testCon *con;
     int domidx;
+    testPrivatePtr priv;
+
     if ((domain == NULL) || (domain->conn == NULL) || (domain->name == NULL) ||
         ((domidx = getDomainIndex(domain)) < 0)) {
         testError((domain ? domain->conn : NULL), domain, VIR_ERR_INVALID_ARG,
@@ -1382,7 +1452,8 @@
         return (-1);
     }
 
-    con = &node->connections[domain->conn->handle];
+    priv = (testPrivatePtr) domain->conn->privateData;
+    con = &node->connections[priv->handle];
 
     if (con->domains[domidx].info.state != VIR_DOMAIN_SHUTOFF) {
         testError(domain->conn, domain, VIR_ERR_INTERNAL_ERROR,
@@ -1399,6 +1470,8 @@
 int testDomainUndefine(virDomainPtr domain) {
     testCon *con;
     int domidx;
+    testPrivatePtr priv;
+
     if ((domain == NULL) || (domain->conn == NULL) || (domain->name == NULL) ||
         ((domidx = getDomainIndex(domain)) < 0)) {
         testError((domain ? domain->conn : NULL), domain, VIR_ERR_INVALID_ARG,
@@ -1406,7 +1479,8 @@
         return (-1);
     }
 
-    con = &node->connections[domain->conn->handle];
+    priv = (testPrivatePtr) domain->conn->privateData;
+    con = &node->connections[priv->handle];
 
     if (con->domains[domidx].info.state != VIR_DOMAIN_SHUTOFF) {
         testError(domain->conn, domain, VIR_ERR_INTERNAL_ERROR,
Index: src/test.h
===================================================================
RCS file: /data/cvs/libvirt/src/test.h,v
retrieving revision 1.6
diff -u -r1.6 test.h
--- src/test.h	18 Jan 2007 21:08:21 -0000	1.6
+++ src/test.h	28 Mar 2007 16:02:23 -0000
@@ -30,7 +30,7 @@
 extern "C" {
 #endif
 
-    void testRegister(void);
+int testRegister(void);
 
 #ifdef __cplusplus
 }
Index: src/xen_internal.c
===================================================================
RCS file: /data/cvs/libvirt/src/xen_internal.c,v
retrieving revision 1.69
diff -u -r1.69 xen_internal.c
--- src/xen_internal.c	28 Mar 2007 08:48:53 -0000	1.69
+++ src/xen_internal.c	28 Mar 2007 16:02:24 -0000
@@ -431,13 +431,21 @@
 #define XEN_HYPERVISOR_SOCKET "/proc/xen/privcmd"
 
 #ifndef PROXY
+/* Per-connection private data. */
+struct _xenHypervisorPrivate {
+    int handle;
+};
+typedef struct _xenHypervisorPrivate *xenHypervisorPrivatePtr;
+#endif
+
+#ifndef PROXY
 static const char * xenHypervisorGetType(virConnectPtr conn);
 static unsigned long xenHypervisorGetMaxMemory(virDomainPtr domain);
 #endif
 
 #ifndef PROXY
-static virDriver xenHypervisorDriver = {
-    VIR_DRV_XEN_HYPERVISOR,
+virDriver xenHypervisorDriver = {
+    -1,
     "Xen",
     (DOM0_INTERFACE_VERSION >> 24) * 1000000 +
     ((DOM0_INTERFACE_VERSION >> 16) & 0xFF) * 1000 +
@@ -446,7 +454,7 @@
     xenHypervisorClose, /* close */
     xenHypervisorGetType, /* type */
     xenHypervisorGetVersion, /* version */
-    xenHypervisorNumOfMaxVcpus, /* getMaxVcpus */
+    xenHypervisorGetMaxVcpus, /* getMaxVcpus */
     NULL, /* nodeGetInfo */
     xenHypervisorGetCapabilities, /* getCapabilities */
     xenHypervisorListDomains, /* listDomains */
@@ -1176,7 +1184,7 @@
  * Initialize the hypervisor layer. Try to detect the kind of interface
  * used i.e. pre or post changeset 10277
  */
-static int
+int
 xenHypervisorInit(void)
 {
     int fd, ret, cmd, errcode;
@@ -1232,7 +1240,7 @@
     ret = open(XEN_HYPERVISOR_SOCKET, O_RDWR);
     if (ret < 0) {
         hypervisor_version = -1;
-        return (-1);
+        return(-1);
     }
     fd = ret;
 
@@ -1295,7 +1303,7 @@
     ipt = malloc(sizeof(virVcpuInfo));
     if (ipt == NULL){
 #ifdef DEBUG
-        fprintf(stderr, "Memory allocation failed at xenHypervisorIniti()\n");
+        fprintf(stderr, "Memory allocation failed at xenHypervisorInit()\n");
 #endif
         return(-1);
     }
@@ -1357,21 +1365,6 @@
     return(0);
 }
 
-#ifndef PROXY
-/**
- * xenHypervisorRegister:
- *
- * Registers the xenHypervisor driver
- */
-void xenHypervisorRegister(void)
-{
-    if (initialized == 0)
-        xenHypervisorInit();
-
-    virRegisterDriver(&xenHypervisorDriver);
-}
-#endif /* !PROXY */
-
 /**
  * xenHypervisorOpen:
  * @conn: pointer to the connection block
@@ -1383,25 +1376,31 @@
  * Returns 0 or -1 in case of error.
  */
 int
-xenHypervisorOpen(virConnectPtr conn, const char *name, int flags)
+xenHypervisorOpen(virConnectPtr conn,
+                  const char *name ATTRIBUTE_UNUSED, int flags)
 {
     int ret;
+    xenHypervisorPrivatePtr priv;
 
     if (initialized == 0)
-        xenHypervisorInit();
+        if (xenHypervisorInit() == -1)
+            return -1;
 
-    if ((name != NULL) && (strcasecmp(name, "xen")))
-        return(-1);
+    priv = conn->privateData = malloc (sizeof (struct _xenHypervisorPrivate));
+    if (conn->privateData == NULL)
+        return -1;
 
-    conn->handle = -1;
+    priv->handle = -1;
 
     ret = open(XEN_HYPERVISOR_SOCKET, O_RDWR);
     if (ret < 0) {
         if (!(flags & VIR_DRV_OPEN_QUIET))
             virXenError(VIR_ERR_NO_XEN, XEN_HYPERVISOR_SOCKET, 0);
+        free (conn->privateData);
         return (-1);
     }
-    conn->handle = ret;
+
+    priv->handle = ret;
 
     return(0);
 }
@@ -1418,13 +1417,22 @@
 xenHypervisorClose(virConnectPtr conn)
 {
     int ret;
+    xenHypervisorPrivatePtr priv;
 
-    if ((conn == NULL) || (conn->handle < 0))
+    if (conn == NULL)
         return (-1);
 
-    ret = close(conn->handle);
+    priv = (xenHypervisorPrivatePtr) conn->privateData;
+
+    if (priv->handle < 0)
+        return -1;
+
+    ret = close(priv->handle);
     if (ret < 0)
         return (-1);
+
+    free (priv);
+
     return (0);
 }
 
@@ -1463,7 +1471,12 @@
 int
 xenHypervisorGetVersion(virConnectPtr conn, unsigned long *hvVer)
 {
-    if ((conn == NULL) || (conn->handle < 0) || (hvVer == NULL))
+    xenHypervisorPrivatePtr priv;
+
+    if (conn == NULL)
+        return -1;
+    priv = (xenHypervisorPrivatePtr) conn->privateData;
+    if (priv->handle < 0 || hvVer == NULL)
         return (-1);
     *hvVer = (hv_version >> 16) * 1000000 + (hv_version & 0xFFFF) * 1000;
     return(0);
@@ -1778,8 +1791,12 @@
     int ret, nbids;
     static int last_maxids = 2;
     int maxids = last_maxids;
+    xenHypervisorPrivatePtr priv;
 
-    if ((conn == NULL) || (conn->handle < 0))
+    if (conn == NULL)
+        return -1;
+    priv = (xenHypervisorPrivatePtr) conn->privateData;
+    if (priv->handle < 0)
         return (-1);
 
  retry:
@@ -1791,7 +1808,7 @@
 
     XEN_GETDOMAININFOLIST_CLEAR(dominfos, maxids);
 
-    ret = virXen_getdomaininfolist(conn->handle, 0, maxids, &dominfos);
+    ret = virXen_getdomaininfolist(priv->handle, 0, maxids, &dominfos);
 
     XEN_GETDOMAININFOLIST_FREE(dominfos);
 
@@ -1824,8 +1841,13 @@
 {
     xen_getdomaininfolist dominfos;
     int ret, nbids, i;
+    xenHypervisorPrivatePtr priv;
 
-    if ((conn == NULL) || (conn->handle < 0) ||
+    if (conn == NULL)
+        return -1;
+
+    priv = (xenHypervisorPrivatePtr) conn->privateData;
+    if (priv->handle < 0 ||
         (ids == NULL) || (maxids < 1))
         return (-1);
 
@@ -1838,7 +1860,7 @@
     XEN_GETDOMAININFOLIST_CLEAR(dominfos, maxids);
     memset(ids, 0, maxids * sizeof(int));
 
-    ret = virXen_getdomaininfolist(conn->handle, 0, maxids, &dominfos);
+    ret = virXen_getdomaininfolist(priv->handle, 0, maxids, &dominfos);
 
     if (ret < 0) {
         XEN_GETDOMAININFOLIST_FREE(dominfos);
@@ -1860,14 +1882,20 @@
 }
 
 /**
- * xenHypervisorNumOfMaxVcpus:
+ * xenHypervisorGetMaxVcpus:
  *
  * Returns the maximum of CPU defined by Xen.
  */
 int
-xenHypervisorNumOfMaxVcpus(virConnectPtr conn)
+xenHypervisorGetMaxVcpus(virConnectPtr conn,
+                         const char *type ATTRIBUTE_UNUSED)
 {
-    if ((conn == NULL) || (conn->handle < 0))
+    xenHypervisorPrivatePtr priv;
+
+    if (conn == NULL)
+        return -1;
+    priv = (xenHypervisorPrivatePtr) conn->privateData;
+    if (priv->handle < 0)
         return (-1);
 
     return MAX_VIRT_CPUS;
@@ -1886,11 +1914,16 @@
 unsigned long
 xenHypervisorGetDomMaxMemory(virConnectPtr conn, int id)
 {
+    xenHypervisorPrivatePtr priv;
     xen_getdomaininfo dominfo;
     int ret;
 
-    if ((conn == NULL) || (conn->handle < 0))
-        return (0);
+    if (conn == NULL)
+        return 0;
+
+    priv = (xenHypervisorPrivatePtr) conn->privateData;
+    if (priv->handle < 0)
+        return 0;
 
     if (kb_per_pages == 0) {
         kb_per_pages = sysconf(_SC_PAGESIZE) / 1024;
@@ -1900,7 +1933,7 @@
 
     XEN_GETDOMAININFO_CLEAR(dominfo);
 
-    ret = virXen_getdomaininfo(conn->handle, id, &dominfo);
+    ret = virXen_getdomaininfo(priv->handle, id, &dominfo);
 
     if ((ret < 0) || (XEN_GETDOMAININFO_DOMAIN(dominfo) != id))
         return (0);
@@ -1922,8 +1955,13 @@
 static unsigned long
 xenHypervisorGetMaxMemory(virDomainPtr domain)
 {
-    if ((domain == NULL) || (domain->conn == NULL) ||
-        (domain->conn->handle < 0) || (domain->id < 0))
+    xenHypervisorPrivatePtr priv;
+
+    if ((domain == NULL) || (domain->conn == NULL))
+        return 0;
+
+    priv = (xenHypervisorPrivatePtr) domain->conn->privateData;
+    if (priv->handle < 0 || domain->id < 0)
         return (0);
 
     return(xenHypervisorGetDomMaxMemory(domain->conn, domain->id));
@@ -1943,6 +1981,7 @@
 int
 xenHypervisorGetDomInfo(virConnectPtr conn, int id, virDomainInfoPtr info)
 {
+    xenHypervisorPrivatePtr priv;
     xen_getdomaininfo dominfo;
     int ret;
     uint32_t domain_flags, domain_state, domain_shutdown_cause;
@@ -1953,13 +1992,17 @@
 	    kb_per_pages = 4;
     }
 
-    if ((conn == NULL) || (conn->handle < 0) || (info == NULL))
+    if (conn == NULL)
+        return -1;
+
+    priv = (xenHypervisorPrivatePtr) conn->privateData;
+    if (priv->handle < 0 || info == NULL)
         return (-1);
 
     memset(info, 0, sizeof(virDomainInfo));
     XEN_GETDOMAININFO_CLEAR(dominfo);
 
-    ret = virXen_getdomaininfo(conn->handle, id, &dominfo);
+    ret = virXen_getdomaininfo(priv->handle, id, &dominfo);
 
     if ((ret < 0) || (XEN_GETDOMAININFO_DOMAIN(dominfo) != id))
         return (-1);
@@ -2020,8 +2063,13 @@
 int
 xenHypervisorGetDomainInfo(virDomainPtr domain, virDomainInfoPtr info)
 {
-    if ((domain == NULL) || (domain->conn == NULL) ||
-        (domain->conn->handle < 0) || (info == NULL) ||
+    xenHypervisorPrivatePtr priv;
+
+    if ((domain == NULL) || (domain->conn == NULL))
+        return -1;
+
+    priv = (xenHypervisorPrivatePtr) domain->conn->privateData;
+    if (priv->handle < 0 || info == NULL ||
         (domain->id < 0))
         return (-1);
 
@@ -2042,12 +2090,16 @@
 xenHypervisorPauseDomain(virDomainPtr domain)
 {
     int ret;
+    xenHypervisorPrivatePtr priv;
 
-    if ((domain == NULL) || (domain->conn == NULL) ||
-        (domain->conn->handle < 0) || (domain->id < 0))
+    if ((domain == NULL) || (domain->conn == NULL))
+        return -1;
+
+    priv = (xenHypervisorPrivatePtr) domain->conn->privateData;
+    if (priv->handle < 0 || domain->id < 0)
         return (-1);
 
-    ret = virXen_pausedomain(domain->conn->handle, domain->id);
+    ret = virXen_pausedomain(priv->handle, domain->id);
     if (ret < 0)
         return (-1);
     return (0);
@@ -2065,12 +2117,16 @@
 xenHypervisorResumeDomain(virDomainPtr domain)
 {
     int ret;
+    xenHypervisorPrivatePtr priv;
 
-    if ((domain == NULL) || (domain->conn == NULL) ||
-        (domain->conn->handle < 0) || (domain->id < 0))
+    if ((domain == NULL) || (domain->conn == NULL))
+        return -1;
+
+    priv = (xenHypervisorPrivatePtr) domain->conn->privateData;
+    if (priv->handle < 0 || domain->id < 0)
         return (-1);
 
-    ret = virXen_unpausedomain(domain->conn->handle, domain->id);
+    ret = virXen_unpausedomain(priv->handle, domain->id);
     if (ret < 0)
         return (-1);
     return (0);
@@ -2088,12 +2144,16 @@
 xenHypervisorDestroyDomain(virDomainPtr domain)
 {
     int ret;
+    xenHypervisorPrivatePtr priv;
+
+    if (domain == NULL || domain->conn == NULL)
+        return -1;
 
-    if ((domain == NULL) || (domain->conn == NULL) ||
-        (domain->conn->handle < 0) || (domain->id < 0))
+    priv = (xenHypervisorPrivatePtr) domain->conn->privateData;
+    if (priv->handle < 0 || domain->id < 0)
         return (-1);
 
-    ret = virXen_destroydomain(domain->conn->handle, domain->id);
+    ret = virXen_destroydomain(priv->handle, domain->id);
     if (ret < 0)
         return (-1);
     return (0);
@@ -2112,12 +2172,16 @@
 xenHypervisorSetMaxMemory(virDomainPtr domain, unsigned long memory)
 {
     int ret;
+    xenHypervisorPrivatePtr priv;
 
-    if ((domain == NULL) || (domain->conn == NULL) ||
-        (domain->conn->handle < 0) || (domain->id < 0))
+    if (domain == NULL || domain->conn == NULL)
+        return -1;
+
+    priv = (xenHypervisorPrivatePtr) domain->conn->privateData;
+    if (priv->handle < 0 || domain->id < 0)
         return (-1);
 
-    ret = virXen_setmaxmem(domain->conn->handle, domain->id, memory);
+    ret = virXen_setmaxmem(priv->handle, domain->id, memory);
     if (ret < 0)
         return (-1);
     return (0);
@@ -2139,13 +2203,16 @@
 xenHypervisorSetVcpus(virDomainPtr domain, unsigned int nvcpus)
 {
     int ret;
+    xenHypervisorPrivatePtr priv;
+
+    if (domain == NULL || domain->conn == NULL)
+        return -1;
 
-    if ((domain == NULL) || (domain->conn == NULL) ||
-        (domain->conn->handle < 0) || (domain->id < 0) ||
-        (nvcpus < 1))
+    priv = (xenHypervisorPrivatePtr) domain->conn->privateData;
+    if (priv->handle < 0 || domain->id < 0 || nvcpus < 1)
         return (-1);
 
-    ret = virXen_setmaxvcpus(domain->conn->handle, domain->id, nvcpus);
+    ret = virXen_setmaxvcpus(priv->handle, domain->id, nvcpus);
     if (ret < 0)
         return (-1);
     return (0);
@@ -2168,13 +2235,17 @@
                      unsigned char *cpumap, int maplen)
 {
     int ret;
+    xenHypervisorPrivatePtr priv;
 
-    if ((domain == NULL) || (domain->conn == NULL) ||
-        (domain->conn->handle < 0) || (domain->id < 0) ||
+    if (domain == NULL || domain->conn == NULL)
+        return -1;
+
+    priv = (xenHypervisorPrivatePtr) domain->conn->privateData;
+    if (priv->handle < 0 || (domain->id < 0) ||
         (cpumap == NULL) || (maplen < 1))
         return (-1);
 
-    ret = virXen_setvcpumap(domain->conn->handle, domain->id, vcpu,
+    ret = virXen_setvcpumap(priv->handle, domain->id, vcpu,
                             cpumap, maplen);
     if (ret < 0)
         return (-1);
@@ -2208,12 +2279,15 @@
 {
     xen_getdomaininfo dominfo;
     int ret;
-
+    xenHypervisorPrivatePtr priv;
     virVcpuInfoPtr ipt;
     int nbinfo, i;
 
-    if ((domain == NULL) || (domain->conn == NULL) ||
-        (domain->conn->handle < 0) || (domain->id < 0) ||
+    if (domain == NULL || domain->conn == NULL)
+        return -1;
+
+    priv = (xenHypervisorPrivatePtr) domain->conn->privateData;
+    if (priv->handle < 0 || (domain->id < 0) ||
         (info == NULL) || (maxinfo < 1) ||
         (sizeof(cpumap_t) & 7))
         return (-1);
@@ -2222,7 +2296,7 @@
 
     /* first get the number of virtual CPUs in this domain */
     XEN_GETDOMAININFO_CLEAR(dominfo);
-    ret = virXen_getdomaininfo(domain->conn->handle, domain->id,
+    ret = virXen_getdomaininfo(priv->handle, domain->id,
                                &dominfo);
 
     if ((ret < 0) || (XEN_GETDOMAININFO_DOMAIN(dominfo) != domain->id))
@@ -2235,14 +2309,14 @@
 
     for (i = 0, ipt = info; i < nbinfo; i++, ipt++) {
         if ((cpumaps != NULL) && (i < maxinfo)) {
-            ret = virXen_getvcpusinfo(domain->conn->handle, domain->id, i,
+            ret = virXen_getvcpusinfo(priv->handle, domain->id, i,
                                       ipt,
                                       (unsigned char *)VIR_GET_CPUMAP(cpumaps, maplen, i),
                                       maplen);
             if (ret < 0)
                 return(-1);
         } else {
-            ret = virXen_getvcpusinfo(domain->conn->handle, domain->id, i,
+            ret = virXen_getvcpusinfo(priv->handle, domain->id, i,
                                       ipt, NULL, 0);
             if (ret < 0)
                 return(-1);
@@ -2266,9 +2340,13 @@
     xen_getdomaininfo dominfo;
     int ret;
     int maxcpu;
+    xenHypervisorPrivatePtr priv;
+
+    if (domain == NULL || domain->conn == NULL)
+        return -1;
 
-    if ((domain == NULL) || (domain->conn == NULL) ||
-        (domain->conn->handle < 0))
+    priv = (xenHypervisorPrivatePtr) domain->conn->privateData;
+    if (priv->handle < 0)
         return (-1);
 
     /* inactive domain */
@@ -2276,7 +2354,7 @@
         maxcpu = MAX_VIRT_CPUS;
     } else {
         XEN_GETDOMAININFO_CLEAR(dominfo);
-        ret = virXen_getdomaininfo(domain->conn->handle, domain->id,
+        ret = virXen_getdomaininfo(priv->handle, domain->id,
                                    &dominfo);
 
         if ((ret < 0) || (XEN_GETDOMAININFO_DOMAIN(dominfo) != domain->id))
Index: src/xen_internal.h
===================================================================
RCS file: /data/cvs/libvirt/src/xen_internal.h,v
retrieving revision 1.18
diff -u -r1.18 xen_internal.h
--- src/xen_internal.h	27 Mar 2007 14:45:17 -0000	1.18
+++ src/xen_internal.h	28 Mar 2007 16:02:24 -0000
@@ -15,7 +15,11 @@
 extern "C" {
 #endif
 
-void	xenHypervisorRegister		(void);
+extern virDriver xenHypervisorDriver;
+int	xenHypervisorInit		(void);
+
+/* The following calls are made directly by the Xen proxy: */
+
 int	xenHypervisorOpen		(virConnectPtr conn,
 					 const char *name,
 					 int flags);
@@ -36,7 +40,7 @@
 int	xenHypervisorListDomains	(virConnectPtr conn,
 					 int *ids,
 					 int maxids);
-int	xenHypervisorNumOfMaxVcpus	(virConnectPtr conn);
+  int	xenHypervisorGetMaxVcpus	(virConnectPtr conn, const char *type);
 int	xenHypervisorDestroyDomain	(virDomainPtr domain);
 int	xenHypervisorResumeDomain	(virDomainPtr domain);
 int	xenHypervisorPauseDomain	(virDomainPtr domain);
Index: src/xend_internal.c
===================================================================
RCS file: /data/cvs/libvirt/src/xend_internal.c,v
retrieving revision 1.105
diff -u -r1.105 xend_internal.c
--- src/xend_internal.c	23 Mar 2007 16:15:07 -0000	1.105
+++ src/xend_internal.c	28 Mar 2007 16:02:26 -0000
@@ -61,7 +61,7 @@
 
 #ifndef PROXY
 static virDriver xenDaemonDriver = {
-    VIR_DRV_XEN_DAEMON,
+    -1,
     "XenDaemon",
     (DOM0_INTERFACE_VERSION >> 24) * 1000000 +
     ((DOM0_INTERFACE_VERSION >> 16) & 0xFF) * 1000 +
Index: src/xend_internal.h
===================================================================
RCS file: /data/cvs/libvirt/src/xend_internal.h,v
retrieving revision 1.29
diff -u -r1.29 xend_internal.h
--- src/xend_internal.h	8 Feb 2007 19:10:25 -0000	1.29
+++ src/xend_internal.h	28 Mar 2007 16:02:27 -0000
@@ -177,8 +177,10 @@
 
   char *xend_parse_domain_sexp(virConnectPtr conn,  char *root, int xendConfigVersion);
 
+extern virDriver xenDaemonDriver;
+int xenDaemonInit (void);
+
 /* refactored ones */
-void xenDaemonRegister(void);
 int xenDaemonOpen(virConnectPtr conn, const char *name, int flags);
 int xenDaemonClose(virConnectPtr conn);
 int xenDaemonGetVersion(virConnectPtr conn, unsigned long *hvVer);
Index: src/xm_internal.c
===================================================================
RCS file: /data/cvs/libvirt/src/xm_internal.c,v
retrieving revision 1.22
diff -u -r1.22 xm_internal.c
--- src/xm_internal.c	22 Mar 2007 18:30:58 -0000	1.22
+++ src/xm_internal.c	28 Mar 2007 16:02:29 -0000
@@ -67,7 +67,7 @@
 #define QEMU_IF_SCRIPT "qemu-ifup"
 
 static virDriver xenXMDriver = {
-    VIR_DRV_XEN_XM,
+    -1,
     "XenXM",
     (DOM0_INTERFACE_VERSION >> 24) * 1000000 +
     ((DOM0_INTERFACE_VERSION >> 16) & 0xFF) * 1000 +
Index: src/xm_internal.h
===================================================================
RCS file: /data/cvs/libvirt/src/xm_internal.h,v
retrieving revision 1.3
diff -u -r1.3 xm_internal.h
--- src/xm_internal.h	6 Mar 2007 21:55:44 -0000	1.3
+++ src/xm_internal.h	28 Mar 2007 16:02:29 -0000
@@ -32,7 +32,9 @@
 extern "C" {
 #endif
 
-void xenXMRegister(void);
+extern virDriver xenXMDriver;
+int xenXMInit (void);
+
 int xenXMOpen(virConnectPtr conn, const char *name, int flags);
 int xenXMClose(virConnectPtr conn);
 const char *xenXMGetType(virConnectPtr conn);
Index: src/xs_internal.c
===================================================================
RCS file: /data/cvs/libvirt/src/xs_internal.c,v
retrieving revision 1.37
diff -u -r1.37 xs_internal.c
--- src/xs_internal.c	23 Mar 2007 16:15:07 -0000	1.37
+++ src/xs_internal.c	28 Mar 2007 16:02:29 -0000
@@ -32,11 +32,17 @@
 
 #define XEN_HYPERVISOR_SOCKET "/proc/xen/privcmd"
 
+/* Per-connection private data. */
+struct _xenStorePrivate {
+    struct xs_handle *xshandle; /* handle to talk to the xenstore */
+};
+typedef struct _xenStorePrivate *xenStorePrivatePtr;
+
 #ifndef PROXY
 static char *xenStoreDomainGetOSType(virDomainPtr domain);
 
-static virDriver xenStoreDriver = {
-    VIR_DRV_XEN_STORE,
+virDriver xenStoreDriver = {
+    -1,
     "XenStore",
     (DOM0_INTERFACE_VERSION >> 24) * 1000000 +
     ((DOM0_INTERFACE_VERSION >> 16) & 0xFF) * 1000 +
@@ -84,13 +90,14 @@
 };
 
 /**
- * xenStoreRegister:
+ * xenStoreInit:
  *
- * Registers the xenStore driver
+ * Initialisation.
  */
-void xenStoreRegister(void)
+int
+xenStoreInit ()
 {
-    virRegisterDriver(&xenStoreDriver);
+    return 0;
 }
 #endif /* ! PROXY */
 
@@ -135,11 +142,16 @@
 virConnectDoStoreList(virConnectPtr conn, const char *path,
                       unsigned int *nb)
 {
-    if ((conn == NULL) || (conn->xshandle == NULL) || (path == NULL) ||
-        (nb == NULL))
+    xenStorePrivatePtr priv;
+
+    if (conn == NULL)
+        return NULL;
+
+    priv = (xenStorePrivatePtr) conn->privateData;
+    if (priv->xshandle == NULL || path == NULL || nb == NULL)
         return (NULL);
 
-    return xs_directory(conn->xshandle, 0, path, nb);
+    return xs_directory (priv->xshandle, 0, path, nb);
 }
 #endif /* ! PROXY */
 
@@ -158,14 +170,19 @@
 {
     char s[256];
     unsigned int len = 0;
+    xenStorePrivatePtr priv;
+
+    if (!conn)
+        return NULL;
 
-    if (!conn || conn->xshandle == NULL)
+    priv = (xenStorePrivatePtr) conn->privateData;
+    if (priv->xshandle == NULL)
         return (NULL);
 
     snprintf(s, 255, "/local/domain/%d/%s", domid, path);
     s[255] = 0;
 
-    return xs_read(conn->xshandle, 0, &s[0], &len);
+    return xs_read(priv->xshandle, 0, &s[0], &len);
 }
 
 #ifndef PROXY
@@ -184,12 +201,14 @@
                       const char *value)
 {
     char s[256];
-
+    xenStorePrivatePtr priv;
     int ret = -1;
 
     if (!VIR_IS_CONNECTED_DOMAIN(domain))
         return (-1);
-    if (domain->conn->xshandle == NULL)
+
+    priv = (xenStorePrivatePtr) domain->conn->privateData;
+    if (priv->xshandle == NULL)
         return (-1);
     if (domain->conn->flags & VIR_CONNECT_RO)
         return (-1);
@@ -197,7 +216,7 @@
     snprintf(s, 255, "/local/domain/%d/%s", domain->id, path);
     s[255] = 0;
 
-    if (xs_write(domain->conn->xshandle, 0, &s[0], value, strlen(value)))
+    if (xs_write(priv->xshandle, 0, &s[0], value, strlen(value)))
         ret = 0;
 
     return (ret);
@@ -217,16 +236,19 @@
     char *vm;
     char query[200];
     unsigned int len;
+    xenStorePrivatePtr priv;
 
     if (!VIR_IS_CONNECTED_DOMAIN(domain))
         return (NULL);
-    if (domain->conn->xshandle == NULL)
+
+    priv = (xenStorePrivatePtr) domain->conn->privateData;
+    if (priv->xshandle == NULL)
         return (NULL);
 
     snprintf(query, 199, "/local/domain/%d/vm", virDomainGetID(domain));
     query[199] = 0;
 
-    vm = xs_read(domain->conn->xshandle, 0, &query[0], &len);
+    vm = xs_read(priv->xshandle, 0, &query[0], &len);
 
     return (vm);
 }
@@ -248,16 +270,19 @@
     char s[256];
     char *ret = NULL;
     unsigned int len = 0;
+    xenStorePrivatePtr priv;
 
     if (!VIR_IS_CONNECTED_DOMAIN(domain))
         return (NULL);
-    if (domain->conn->xshandle == NULL)
+
+    priv = (xenStorePrivatePtr) domain->conn->privateData;
+    if (priv->xshandle == NULL)
         return (NULL);
 
     snprintf(s, 255, "%s/%s", vm, name);
     s[255] = 0;
 
-    ret = xs_read(domain->conn->xshandle, 0, &s[0], &len);
+    ret = xs_read(priv->xshandle, 0, &s[0], &len);
 
     return (ret);
 }
@@ -304,24 +329,29 @@
  * Returns 0 or -1 in case of error.
  */
 int
-xenStoreOpen(virConnectPtr conn, const char *name, int flags)
+xenStoreOpen(virConnectPtr conn,
+             const char *name ATTRIBUTE_UNUSED, int flags)
 {
-    if ((name != NULL) && (strcasecmp(name, "xen")))
-        return(-1);
+    xenStorePrivatePtr priv;
+
+    priv = conn->privateData = malloc (sizeof (struct _xenStorePrivate));
+    if (conn->privateData == NULL)
+        return -1;
 
 #ifdef PROXY
-    conn->xshandle = xs_daemon_open_readonly();
+    priv->xshandle = xs_daemon_open_readonly();
 #else
     if (flags & VIR_DRV_OPEN_RO)
-	conn->xshandle = xs_daemon_open_readonly();
+	priv->xshandle = xs_daemon_open_readonly();
     else
-	conn->xshandle = xs_daemon_open();
+	priv->xshandle = xs_daemon_open();
 #endif /* ! PROXY */
 
-    if (conn->xshandle == NULL) {
+    if (priv->xshandle == NULL) {
         if (!(flags & VIR_DRV_OPEN_QUIET))
             virXenStoreError(conn, VIR_ERR_NO_XEN, 
 	                     _("failed to connect to Xen Store"));
+        free (conn->privateData);
         return (-1);
     }
     return (0);
@@ -338,14 +368,19 @@
 int
 xenStoreClose(virConnectPtr conn)
 {
+    xenStorePrivatePtr priv;
+
     if (conn == NULL) {
         virXenStoreError(conn, VIR_ERR_INVALID_ARG, __FUNCTION__);
-	return(-1);
+        return(-1);
     }
-    if (conn->xshandle == NULL)
-	return(-1);
 
-    xs_daemon_close(conn->xshandle);
+    priv = (xenStorePrivatePtr) conn->privateData;
+    if (priv->xshandle == NULL)
+        return(-1);
+
+    xs_daemon_close(priv->xshandle);
+    free (priv);
     return (0);
 }
 
@@ -365,6 +400,7 @@
     char *tmp, **tmp2;
     unsigned int nb_vcpus;
     char request[200];
+    xenStorePrivatePtr priv;
 
     if (!VIR_IS_CONNECTED_DOMAIN(domain))
         return (-1);
@@ -374,8 +410,11 @@
 	                 __FUNCTION__);
 	return(-1);
     }
-    if (domain->conn->xshandle == NULL)
+
+    priv = (xenStorePrivatePtr) domain->conn->privateData;
+    if (priv->xshandle == NULL)
         return(-1);
+
     if (domain->id == -1)
         return(-1);
 
@@ -490,12 +529,19 @@
     unsigned int num;
     char **idlist;
     int ret = -1;
+    xenStorePrivatePtr priv;
 
-    if ((conn == NULL) || (conn->xshandle == NULL)) {
+    if (conn == NULL) {
         virXenStoreError(conn, VIR_ERR_INVALID_ARG, __FUNCTION__);
-	return(-1);
+        return -1;
     }
-    idlist = xs_directory(conn->xshandle, 0, "/local/domain", &num);
+
+    priv = (xenStorePrivatePtr) conn->privateData;
+    if (priv->xshandle == NULL) {
+        virXenStoreError(conn, VIR_ERR_INVALID_ARG, __FUNCTION__);
+        return(-1);
+    }
+    idlist = xs_directory(priv->xshandle, 0, "/local/domain", &num);
     if (idlist) {
         free(idlist);
 	ret = num;
@@ -520,15 +566,18 @@
     unsigned int num, i;
     int ret;
     long id;
+    xenStorePrivatePtr priv;
 
     if ((conn == NULL) || (ids == NULL)) {
         virXenStoreError(conn, VIR_ERR_INVALID_ARG, __FUNCTION__);
 	return(-1);
     }
-    if (conn->xshandle == NULL)
+
+    priv = (xenStorePrivatePtr) conn->privateData;
+    if (priv->xshandle == NULL)
         return(-1);
 
-    idlist = xs_directory(conn->xshandle, 0, "/local/domain", &num);
+    idlist = xs_directory (priv->xshandle, 0, "/local/domain", &num);
     if (idlist == NULL)
 	return(-1);
 
@@ -566,15 +615,18 @@
     char prop[200], *tmp, *path = NULL;
     int found = 0;
     struct xend_domain *xenddomain = NULL;
+    xenStorePrivatePtr priv;
 
     if ((conn == NULL) || (name == NULL)) {
         virXenStoreError(conn, VIR_ERR_INVALID_ARG, __FUNCTION__);
 	return(NULL);
     }
-    if (conn->xshandle == NULL)
+
+    priv = (xenStorePrivatePtr) conn->privateData;
+    if (priv->xshandle == NULL)
         return(NULL);
 
-    idlist = xs_directory(conn->xshandle, 0, "/local/domain", &num);
+    idlist = xs_directory(priv->xshandle, 0, "/local/domain", &num);
     if (idlist == NULL)
 	goto done;
 
@@ -589,7 +641,7 @@
 #endif
 	snprintf(prop, 199, "/local/domain/%s/name", idlist[i]);
 	prop[199] = 0;
-	tmp = xs_read(conn->xshandle, 0, prop, &len);
+	tmp = xs_read(priv->xshandle, 0, prop, &len);
 	if (tmp != NULL) {
 	    found = !strcmp(name, tmp);
 	    free(tmp);
@@ -597,7 +649,7 @@
 		break;
 	}
     }
-    path = xs_get_domain_path(conn->xshandle, (unsigned int) id);
+    path = xs_get_domain_path(priv->xshandle, (unsigned int) id);
 
     if (!found)
         return(NULL);
@@ -764,22 +816,23 @@
     char *vm, *str = NULL;
     char query[200];
     unsigned int len;
+    xenStorePrivatePtr priv;
 
     if (id < 0)
         return(NULL);
 
-
-    if (conn->xshandle == NULL)
+    priv = (xenStorePrivatePtr) domain->conn->privateData;
+    if (priv->xshandle == NULL)
         return (NULL);
 
     snprintf(query, 199, "/local/domain/%d/vm", id);
     query[199] = 0;
 
-    vm = xs_read(conn->xshandle, 0, &query[0], &len);
+    vm = xs_read(priv->xshandle, 0, &query[0], &len);
 
     if (vm) {
         snprintf(query, 199, "%s/image/ostype", vm);
-	str = xs_read(conn->xshandle, 0, &query[0], &len);
+	str = xs_read(priv->xshandle, 0, &query[0], &len);
         free(vm);
     }
     if (str == NULL)
@@ -807,10 +860,13 @@
     char dir[80], path[128], **list = NULL, *val = NULL;
     unsigned int maclen, len, i, num;
     char *ret = NULL;
+    xenStorePrivatePtr priv;
 
     if (id < 0)
         return(NULL);
-    if (conn->xshandle == NULL)
+
+    priv = (xenStorePrivatePtr) conn->privateData;
+    if (priv->xshandle == NULL)
         return (NULL);
     if (mac == NULL)
         return (NULL);
@@ -819,12 +875,12 @@
         return (NULL);
 
     snprintf(dir, sizeof(dir), "/local/domain/0/backend/vif/%d", id);
-    list = xs_directory(conn->xshandle, 0, dir, &num);
+    list = xs_directory(priv->xshandle, 0, dir, &num);
     if (list == NULL)
 	return(NULL);
     for (i = 0; i < num; i++) {
 	snprintf(path, sizeof(path), "%s/%s/%s", dir, list[i], "mac");
-	val = xs_read(conn->xshandle, 0, path, &len);
+	val = xs_read(priv->xshandle, 0, path, &len);
 	if (val == NULL)
 	    break;
 	if ((maclen != len) || memcmp(val, mac, len)) {
Index: src/xs_internal.h
===================================================================
RCS file: /data/cvs/libvirt/src/xs_internal.h,v
retrieving revision 1.8
diff -u -r1.8 xs_internal.h
--- src/xs_internal.h	20 Nov 2006 16:42:16 -0000	1.8
+++ src/xs_internal.h	28 Mar 2007 16:02:29 -0000
@@ -15,7 +15,9 @@
 extern "C" {
 #endif
 
-void		xenStoreRegister	(void);
+extern virDriver xenStoreDriver;
+int xenStoreInit (void);
+
 int		xenStoreOpen		(virConnectPtr conn,
 					 const char *name,
 					 int flags);

Attachment: smime.p7s
Description: S/MIME Cryptographic Signature


[Index of Archives]     [Virt Tools]     [Libvirt Users]     [Lib OS Info]     [Fedora Users]     [Fedora Desktop]     [Fedora SELinux]     [Big List of Linux Books]     [Yosemite News]     [KDE Users]     [Fedora Tools]