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

[Libvir] Unified Xen patch (second version)



Ignore the just posted "first complete version". It had some stupid stuff going on with connection opens. This version fixes all that, and passes 'make check'.

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, SL4 1TE, United Kingdom.
Registered in England 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 redhat com>
 */

#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;

/**
 * xenUnifiedError:
 * @conn: the connection
 * @error: the error number
 * @info: extra information string
 *
 * Handle an error at the xend daemon interface
 */
static void
xenUnifiedError (virConnectPtr conn, virErrorNumber error, const char *info)
{
    const char *errmsg;

    errmsg = __virErrorMsg (error, info);
    __virRaiseError (conn, NULL, NULL, VIR_FROM_XEN, error, VIR_ERR_ERROR,
		     errmsg, info, NULL, 0, 0, errmsg, info);
}

/*----- 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;
  xenUnifiedPrivatePtr priv;

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

  /* Allocate per-connection private data. */
  priv = malloc (sizeof *priv);
  if (!priv) {
    xenUnifiedError (conn, VIR_ERR_NO_MEMORY, "allocating private data");
    return VIR_DRV_OPEN_ERROR;
  }
  conn->privateData = priv;

  priv->handle = -1;
  priv->xendConfigVersion = -1;
  priv->type = -1;
  priv->len = -1;
  priv->addr = NULL;
  priv->xshandle = NULL;
  priv->proxy = -1;

  /* 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);

  free (conn->privateData);
  conn->privateData = NULL;

  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)
{
  /* Ignore failures here. */
  (void) xenHypervisorInit ();
  (void) xenProxyInit ();
  (void) xenDaemonInit ();
  (void) xenStoreInit ();
  (void) xenXMInit ();

  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 redhat com>
 */

#ifndef __VIR_XEN_UNIFIED_H__
#define __VIR_XEN_UNIFIED_H__
#ifdef WITH_XEN

#include "internal.h"

#ifdef __cplusplus
extern "C" {
#endif

extern int xenUnifiedRegister (void);

/* xenUnifiedPrivatePtr:
 *
 * Per-connection private data, stored in conn->privateData.  All Xen
 * low-level drivers access parts of this structure.
 */
struct _xenUnifiedPrivate {
    int handle;			/* Xen hypervisor handle */

    int xendConfigVersion;      /* XenD config version */

    /* XXX This code is not IPv6 aware. */
    /* connection to xend */
    int type;                   /* PF_UNIX or PF_INET */
    int len;                    /* length of addr */
    struct sockaddr *addr;      /* type of address used */
    struct sockaddr_un addr_un; /* the unix address */
    struct sockaddr_in addr_in; /* the inet address */

    struct xs_handle *xshandle; /* handle to talk to the xenstore */

    int proxy;                  /* fd of proxy. */
};

typedef struct _xenUnifiedPrivate *xenUnifiedPrivatePtr;

#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
? docs/examples/.libs
? tests/xencapstest
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	30 Mar 2007 13:24:51 -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	30 Mar 2007 13:24:51 -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	30 Mar 2007 13:24:52 -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	30 Mar 2007 13:24:52 -0000
@@ -114,30 +114,19 @@
     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;
-
-    /* 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 */
-
-    /* connection to xend */
-    int type;               /* PF_UNIX or PF_INET */
-    int len;                /* lenght of addr */
-    struct sockaddr *addr;  /* type of address used */
-    struct sockaddr_un addr_un;     /* the unix address */
-    struct sockaddr_in addr_in;     /* the inet address */
 
-    int qemud_fd;           /* connection to qemud */
+    /* 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;
 
-    /* error stuff */
+    /* Per-connection error. */
     virError err;           /* the last error */
     virErrorFunc handler;   /* associated handlet */
     void *userData;         /* the user data */
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	30 Mar 2007 13:24:54 -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++;
 }
@@ -266,85 +264,69 @@
     return (0);
 }
 
-/**
- * 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)
+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 +339,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 +356,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 +378,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 +408,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 +418,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 +440,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 +465,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 +475,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 +493,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 +521,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 +534,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 +554,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 +563,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 +582,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 +591,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 +659,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 +668,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 +690,6 @@
 int
 virDomainDestroy(virDomainPtr domain)
 {
-    int i;
     virConnectPtr conn;
 
     if (!VIR_IS_CONNECTED_DOMAIN(domain)) {
@@ -863,29 +703,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 +746,6 @@
 int
 virDomainSuspend(virDomainPtr domain)
 {
-    int i;
     virConnectPtr conn;
 
     if (!VIR_IS_CONNECTED_DOMAIN(domain)) {
@@ -938,29 +759,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 +779,6 @@
 int
 virDomainResume(virDomainPtr domain)
 {
-    int i;
     virConnectPtr conn;
 
     if (!VIR_IS_CONNECTED_DOMAIN(domain)) {
@@ -990,29 +792,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 +814,6 @@
 int
 virDomainSave(virDomainPtr domain, const char *to)
 {
-    int ret, i;
     char filepath[4096];
     virConnectPtr conn;
 
@@ -1068,17 +851,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 +870,6 @@
 int
 virDomainRestore(virConnectPtr conn, const char *from)
 {
-    int ret, i;
     char filepath[4096];
 
     if (!VIR_IS_CONNECT(conn)) {
@@ -1128,17 +904,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 +926,6 @@
 int
 virDomainCoreDump(virDomainPtr domain, const char *to, int flags)
 {
-    int ret, i;
     char filepath[4096];
     virConnectPtr conn;
 
@@ -1194,17 +963,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 +986,6 @@
 int
 virDomainShutdown(virDomainPtr domain)
 {
-    int ret = -1, i;
     virConnectPtr conn;
 
     if (!VIR_IS_CONNECTED_DOMAIN(domain)) {
@@ -1237,21 +999,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 +1020,6 @@
 int
 virDomainReboot(virDomainPtr domain, unsigned int flags)
 {
-    int ret = -1, i;
     virConnectPtr conn;
 
     if (!VIR_IS_CONNECTED_DOMAIN(domain)) {
@@ -1282,21 +1033,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 +1083,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 +1129,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 +1170,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;
 
-    return (str);
+    if (conn->driver->domainGetOSType)
+        return conn->driver->domainGetOSType (domain);
+
+    virLibConnError (conn, VIR_ERR_CALL_FAILED, __FUNCTION__);
+    return NULL;
 }
 
 /**
@@ -1458,9 +1199,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 +1208,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 +1230,6 @@
 int
 virDomainSetMaxMemory(virDomainPtr domain, unsigned long memory)
 {
-    int ret = -1 , i;
     virConnectPtr conn;
 
     if (domain == NULL) {
@@ -1521,22 +1250,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 +1272,6 @@
 int
 virDomainSetMemory(virDomainPtr domain, unsigned long memory)
 {
-    int ret = -1 , i;
     virConnectPtr conn;
 
     if (domain == NULL) {
@@ -1576,22 +1293,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 +1314,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 +1327,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 +1350,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 +1361,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 +1380,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 +1391,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 +1411,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 +1440,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 +1453,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 +1470,6 @@
  */
 int
 virDomainUndefine(virDomainPtr domain) {
-    int ret, i;
     virConnectPtr conn;
 
     if (!VIR_IS_CONNECTED_DOMAIN(domain)) {
@@ -1809,17 +1482,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 +1500,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 +1525,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 +1535,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 +1553,8 @@
  */
 int
 virDomainCreate(virDomainPtr domain) {
-    int i, ret = -1;
     virConnectPtr conn;
+
     if (domain == NULL) {
         TODO
 	return (-1);
@@ -1920,15 +1569,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 +1589,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 +1602,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 +1623,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 +1657,6 @@
 int
 virDomainSetVcpus(virDomainPtr domain, unsigned int nvcpus)
 {
-    int i;
     virConnectPtr conn;
 
     if (domain == NULL) {
@@ -2034,29 +1678,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 +1707,6 @@
 virDomainPinVcpu(virDomainPtr domain, unsigned int vcpu,
                  unsigned char *cpumap, int maplen)
 {
-    int i;
     virConnectPtr conn;
 
     if (domain == NULL) {
@@ -2101,21 +1726,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 +1761,6 @@
 virDomainGetVcpus(virDomainPtr domain, virVcpuInfoPtr info, int maxinfo,
 		  unsigned char *cpumaps, int maplen)
 {
-    int ret;
-    int i;
     virConnectPtr conn;
 
     if (domain == NULL) {
@@ -2163,22 +1779,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 +1803,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 +1814,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 +1834,6 @@
 int
 virDomainAttachDevice(virDomainPtr domain, char *xml)
 {
-    int ret;
-    int i;
     virConnectPtr conn;
 
     if (!VIR_IS_CONNECTED_DOMAIN(domain)) {
@@ -2245,19 +1846,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 +1865,6 @@
 int
 virDomainDetachDevice(virDomainPtr domain, char *xml)
 {
-    int ret;
-    int i;
     virConnectPtr conn;
 
     if (!VIR_IS_CONNECTED_DOMAIN(domain)) {
@@ -2286,19 +1877,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 +1895,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 +1920,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 +1930,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 +1948,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 +1972,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 +1984,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 +2004,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 +2013,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 +2032,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 +2041,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 +2110,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 +2123,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 +2140,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 +2155,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 +2172,6 @@
  */
 int
 virNetworkUndefine(virNetworkPtr network) {
-    int ret, i;
     virConnectPtr conn;
 
     if (!VIR_IS_CONNECTED_NETWORK(network)) {
@@ -2668,17 +2184,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 +2201,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 +2218,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 +2240,6 @@
 int
 virNetworkDestroy(virNetworkPtr network)
 {
-    int i;
     virConnectPtr conn;
 
     if (!VIR_IS_CONNECTED_NETWORK(network)) {
@@ -2748,19 +2253,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 +2376,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 +2387,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 +2409,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 +2438,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 +2451,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 +2472,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	30 Mar 2007 13:24:54 -0000
@@ -21,6 +21,7 @@
 #include "internal.h"
 #include "driver.h"
 #include "proxy_internal.h"
+#include "xen_unified.h"
 
 #define STANDALONE
 
@@ -42,8 +43,8 @@
 static char *xenProxyDomainDumpXML(virDomainPtr domain, int flags);
 static char *xenProxyDomainGetOSType(virDomainPtr domain);
 
-static virDriver xenProxyDriver = {
-    VIR_DRV_XEN_PROXY,
+virDriver xenProxyDriver = {
+    -1,
     "XenProxy",
     0,
     xenProxyOpen, /* open */
@@ -89,14 +90,16 @@
 };
 
 /**
- * xenProxyRegister:
+ * xenProxyInit:
  *
- * Registers the xenHypervisor driver
+ * Initialise the xen proxy driver.
  */
-void xenProxyRegister(void)
+int
+xenProxyInit (void)
 {
-    virRegisterDriver(&xenProxyDriver);
+    return 0;
 }
+
 /************************************************************************
  *									*
  *			Error handling					*
@@ -378,12 +381,29 @@
  * Shutdown the Xen proxy communication layer
  */
 static int
-xenProxyClose(virConnectPtr conn) {
-    if ((conn == NULL) || (conn->proxy < 0))
-        return(-1);
-    virProxyCloseClientSocket(conn->proxy);
-    conn->proxy = -1;
-    return (0);
+xenProxyClose(virConnectPtr conn)
+{
+    xenUnifiedPrivatePtr priv;
+
+    if (conn == NULL) {
+        virProxyError (NULL, VIR_ERR_INVALID_CONN, __FUNCTION__);
+        return -1;
+    }
+
+    priv = (xenUnifiedPrivatePtr) conn->privateData;
+    if (!priv) {
+        virProxyError (NULL, VIR_ERR_INTERNAL_ERROR, __FUNCTION__);
+        return -1;
+    }
+
+    /* Fail silently. */
+    if (priv->proxy == -1)
+        return -1;
+
+    virProxyCloseClientSocket (priv->proxy);
+    priv->proxy = -1;
+
+    return 0;
 }
 
 static int 
@@ -392,9 +412,22 @@
     static int serial = 0;
     int ret;
     virProxyPacketPtr res = NULL;
+    xenUnifiedPrivatePtr priv;
 
-    if ((conn == NULL) || (conn->proxy < 0))
-        return(-1);
+    if (conn == NULL) {
+        virProxyError (NULL, VIR_ERR_INVALID_CONN, __FUNCTION__);
+        return -1;
+    }
+
+    priv = (xenUnifiedPrivatePtr) conn->privateData;
+    if (!priv) {
+        virProxyError (NULL, VIR_ERR_INTERNAL_ERROR, __FUNCTION__);
+        return -1;
+    }
+
+    /* Fail silently. */
+    if (priv->proxy == -1)
+        return -1;
 
     /*
      * normal communication serial numbers are in 0..4095
@@ -404,14 +437,14 @@
         serial = 0;
     request->version = PROXY_PROTO_VERSION;
     request->serial = serial;
-    ret  = virProxyWriteClientSocket(conn->proxy, (const char *) request,
+    ret  = virProxyWriteClientSocket(priv->proxy, (const char *) request,
                                      request->len);
     if (ret < 0)
         return(-1);
 retry:
     if (answer == NULL) {
         /* read in situ */
-	ret  = virProxyReadClientSocket(conn->proxy, (char *) request,
+	ret  = virProxyReadClientSocket(priv->proxy, (char *) request,
 	                                sizeof(virProxyPacket), quiet);
 	if (ret < 0)
 	    return(-1);
@@ -432,7 +465,7 @@
 	}
     } else {
         /* read in packet provided */
-        ret  = virProxyReadClientSocket(conn->proxy, (char *) answer,
+        ret  = virProxyReadClientSocket(priv->proxy, (char *) answer,
 	                                sizeof(virProxyPacket), quiet);
 	if (ret < 0)
 	    return(-1);
@@ -453,7 +486,7 @@
 	    return(-1);
 	}
 	if (res->len > sizeof(virProxyPacket)) {
-	    ret  = virProxyReadClientSocket(conn->proxy,
+	    ret  = virProxyReadClientSocket(priv->proxy,
 	                           (char *) &(answer->extra.arg[0]),
 	                                    res->len - ret, quiet);
 	    if (ret != (int) (res->len - sizeof(virProxyPacket))) {
@@ -495,25 +528,26 @@
  * Returns 0 in case of success, and -1 in case of failure
  */
 int
-xenProxyOpen(virConnectPtr conn, const char *name, int flags)
+xenProxyOpen(virConnectPtr conn, const char *name ATTRIBUTE_UNUSED, int flags)
 {
     virProxyPacket req;
     int ret;
     int fd;
+    xenUnifiedPrivatePtr priv;
     
-    if ((name != NULL) && (strcasecmp(name, "xen")))
-        return(-1);
     if (!(flags & VIR_DRV_OPEN_RO))
         return(-1);
-        
-    conn->proxy = -1;
+
+    priv = (xenUnifiedPrivatePtr) conn->privateData;
+    priv->proxy = -1;
+
     fd = virProxyOpenClientSocket(PROXY_SOCKET_PATH);
     if (fd < 0) {
         if (!(flags & VIR_DRV_OPEN_QUIET))
 	    virProxyError(conn, VIR_ERR_NO_XEN, PROXY_SOCKET_PATH);
-	return(-1);
+        return(-1);
     }
-    conn->proxy = fd;
+    priv->proxy = fd;
 
     memset(&req, 0, sizeof(req));
     req.command = VIR_PROXY_NONE;
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	30 Mar 2007 13:24:54 -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	30 Mar 2007 13:24:55 -0000
@@ -48,7 +48,15 @@
 #include "xml.h"
 #include "protocol.h"
 
-
+/**
+ * qemuPrivatePtr:
+ *
+ * Per-connection private data.
+ */
+struct _qemuPrivate {
+    int qemud_fd;               /* Connection to libvirt qemu daemon. */
+};
+typedef struct _qemuPrivate *qemuPrivatePtr;
 
 static void
 qemuError(virConnectPtr con,
@@ -213,11 +221,12 @@
     int fd;
     struct sockaddr_un addr;
     int trials = 0;
+    qemuPrivatePtr priv = (qemuPrivatePtr) conn->privateData;
 
  retry:
     fd = socket(PF_UNIX, SOCK_STREAM, 0);
     if (fd < 0) {
-        return(-1);
+        return VIR_DRV_OPEN_ERROR;
     }
 
     /*
@@ -242,12 +251,12 @@
             usleep(5000 * trials * trials);
             goto retry;
         }
-        return (-1);
+        return VIR_DRV_OPEN_ERROR;
     }
 
-    conn->qemud_fd = fd;
+    priv->qemud_fd = fd;
 
-    return (0);
+    return VIR_DRV_OPEN_SUCCESS;
 }
 
 
@@ -265,12 +274,13 @@
     char *in = (char *)reply;
     int inGot = 0;
     int inLeft = sizeof(struct qemud_packet_header);
+    qemuPrivatePtr priv = (qemuPrivatePtr) conn->privateData;
 
     /* printf("Send request %d\n", req->header.type); */
 
     /* Block sending entire outgoing packet */
     while (outLeft) {
-        int got = write(conn->qemud_fd, out+outDone, outLeft);
+        int got = write(priv->qemud_fd, out+outDone, outLeft);
         if (got < 0) {
             return -1;
         }
@@ -280,7 +290,7 @@
 
     /* Block waiting for header to come back */
     while (inLeft) {
-        int done = read(conn->qemud_fd, in+inGot, inLeft);
+        int done = read(priv->qemud_fd, in+inGot, inLeft);
         if (done <= 0) {
             return -1;
         }
@@ -308,7 +318,7 @@
     /* Now block reading in body */
     inLeft = reply->header.dataSize;
     while (inLeft) {
-        int done = read(conn->qemud_fd, in+inGot, inLeft);
+        int done = read(priv->qemud_fd, in+inGot, inLeft);
         if (done <= 0) {
             return -1;
         }
@@ -333,17 +343,17 @@
     int autostart = 0;
 
     if (uri->server != NULL) {
-        return -1;
+        return VIR_DRV_OPEN_ERROR;
     }
 
     if (!strcmp(uri->path, "/system")) {
         if (readonly) {
             if (snprintf(path, sizeof(path), "%s/run/libvirt/qemud-sock-ro", LOCAL_STATE_DIR) >= (int)sizeof(path)) {
-                return -1;
+                return VIR_DRV_OPEN_ERROR;
             }
         } else {
             if (snprintf(path, sizeof(path), "%s/run/libvirt/qemud-sock", LOCAL_STATE_DIR) >= (int)sizeof(path)) {
-                return -1;
+                return VIR_DRV_OPEN_ERROR;
             }
         }
     } else if (!strcmp(uri->path, "/session")) {
@@ -351,14 +361,14 @@
         int uid;
 
         if ((uid = geteuid()) < 0) {
-            return -1;
+            return VIR_DRV_OPEN_ERROR;
         }
 
         if (!(pw = getpwuid(uid)))
-            return -1;
+            return VIR_DRV_OPEN_ERROR;
 
         if (snprintf(path, sizeof(path), "@%s/.libvirt/qemud-sock", pw->pw_dir) == sizeof(path)) {
-            return -1;
+            return VIR_DRV_OPEN_ERROR;
         }
         autostart = 1;
     }
@@ -373,42 +383,62 @@
                     const char *name,
                     int flags){
     xmlURIPtr uri;
+    qemuPrivatePtr priv;
+    int ret;
 
     if (!name) {
-        return -1;
+        return VIR_DRV_OPEN_DECLINED;
     }
 
     uri = xmlParseURI(name);
     if (uri == NULL) {
         if (!(flags & VIR_DRV_OPEN_QUIET))
             qemuError(conn, NULL, VIR_ERR_NO_SUPPORT, name);
-        return(-1);
+        return VIR_DRV_OPEN_DECLINED;
     }
 
     if (!uri->scheme ||
         strcmp(uri->scheme, "qemu") ||
         !uri->path) {
         xmlFreeURI(uri);
-        return -1;
+        return VIR_DRV_OPEN_DECLINED;
     }
 
-    conn->qemud_fd = -1;
-    qemuOpenConnection(conn, uri, flags & VIR_DRV_OPEN_RO ? 1 : 0);
+    /* Create per-connection private data. */
+    priv = conn->privateData = malloc (sizeof *priv);
+    if (!priv) {
+        qemuError (conn, NULL, VIR_ERR_NO_MEMORY, __FUNCTION__);
+        return VIR_DRV_OPEN_ERROR;
+    }
+
+    priv->qemud_fd = -1;
+
+    ret = qemuOpenConnection(conn, uri, flags & VIR_DRV_OPEN_RO ? 1 : 0);
     xmlFreeURI(uri);
 
-    if (conn->qemud_fd < 0) {
-        return -1;
+    if (priv->qemud_fd == -1 || ret < 0) {
+        free (priv);
+        conn->privateData = NULL;
+        return VIR_DRV_OPEN_ERROR;
     }
 
-    return 0;
+    return VIR_DRV_OPEN_SUCCESS;
 }
 
 
-static int qemuClose  (virConnectPtr conn) {
-    if (conn->qemud_fd != -1) {
-        close(conn->qemud_fd);
-        conn->qemud_fd = -1;
+static int
+qemuClose (virConnectPtr conn)
+{
+    qemuPrivatePtr priv = (qemuPrivatePtr) conn->privateData;
+
+    if (priv->qemud_fd != -1) {
+        close (priv->qemud_fd);
+        priv->qemud_fd = -1;
     }
+
+    free (priv);
+    conn->privateData = NULL;
+
     return 0;
 }
 
@@ -874,9 +904,10 @@
                            int flags) {
     xmlURIPtr uri = NULL;
     int ret = -1;
+    qemuPrivatePtr priv = (qemuPrivatePtr) conn->privateData;
 
-    if (conn->qemud_fd != -1)
-        return 0;
+    if (priv->qemud_fd != -1)
+        return VIR_DRV_OPEN_SUCCESS;
 
     if (name)
         uri = xmlParseURI(name);
@@ -894,6 +925,16 @@
     return ret;
 }
 
+static int
+qemuNetworkClose (virConnectPtr conn ATTRIBUTE_UNUSED)
+{
+    /* NB: This will fail to close the connection properly
+     * qemuRegister is changed so that it only registers the
+     * network (not the connection driver).
+     */
+    return 0;
+}
+
 static int qemuNumOfNetworks(virConnectPtr conn) {
     struct qemud_packet req, reply;
 
@@ -1237,7 +1278,7 @@
 
 static virNetworkDriver qemuNetworkDriver = {
     qemuNetworkOpen, /* open */
-    qemuClose, /* close */
+    qemuNetworkClose, /* close */
     qemuNumOfNetworks, /* numOfNetworks */
     qemuListNetworks, /* listNetworks */
     qemuNumOfDefinedNetworks, /* numOfDefinedNetworks */
@@ -1260,9 +1301,16 @@
  *
  * Registers QEmu/KVM in libvirt driver system
  */
-void qemuRegister(void) {
-    virRegisterDriver(&qemuDriver);
-    virRegisterNetworkDriver(&qemuNetworkDriver);
+int
+qemuRegister (void)
+{
+    /* NB: See comment in qemuNetworkClose. */
+    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	30 Mar 2007 13:24:55 -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	30 Mar 2007 13:24:56 -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);
+        return VIR_DRV_OPEN_ERROR;
     }
 
-    conn->handle = connid;
+    priv->handle = connid;
     node->connections[connid].active = 1;
     memmove(&node->connections[connid].nodeInfo, &defaultNodeInfo, sizeof(defaultNodeInfo));
 
@@ -538,10 +545,11 @@
     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"));
-        return (-1);
+        return VIR_DRV_OPEN_ERROR;
     }
 
     if (!(xml = xmlReadFd(fd, file, NULL,
@@ -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));
@@ -707,7 +715,7 @@
         xmlFreeDoc(xml);
     if (fd != -1)
         close(fd);
-    return (-1);
+    return VIR_DRV_OPEN_ERROR;
 }
 
 static int getNextConnection(void) {
@@ -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)
@@ -751,31 +761,39 @@
 {
     xmlURIPtr uri;
     int ret, connid;
+    testPrivatePtr priv;
 
-    if (!name) {
-        return (-1);
-    }
+    if (!name)
+        return VIR_DRV_OPEN_DECLINED;
 
     uri = xmlParseURI(name);
     if (uri == NULL) {
         if (!(flags & VIR_DRV_OPEN_QUIET))
             testError(conn, NULL, VIR_ERR_NO_SUPPORT, name);
-        return(-1);
+        return VIR_DRV_OPEN_DECLINED;
     }
 
     if (!uri->scheme ||
         strcmp(uri->scheme, "test") ||
         !uri->path) {
         xmlFreeURI(uri);
-        return (-1);
+        return VIR_DRV_OPEN_DECLINED;
     }
 
 
     if ((connid = getNextConnection()) < 0) {
         testError(NULL, NULL, VIR_ERR_INTERNAL_ERROR, _("too many connections"));
-        return (-1);
+        return VIR_DRV_OPEN_ERROR;
     }
 
+    /* Allocate per-connection private data. */
+    priv = conn->privateData = malloc (sizeof (struct _testPrivate));
+    if (!priv) {
+        testError(NULL, NULL, VIR_ERR_NO_MEMORY, "allocating private data");
+        return VIR_DRV_OPEN_ERROR;
+    }
+    priv->handle = -1;
+
     if (!strcmp(uri->path, "/default")) {
         ret = testOpenDefault(conn,
                               connid);
@@ -787,16 +805,34 @@
 
     xmlFreeURI(uri);
 
+    if (ret < 0) free (conn->privateData);
+
     return (ret);
 }
 
 int testClose(virConnectPtr conn)
 {
-    testCon *con = &node->connections[conn->handle];
-    con->active = 0;
-    conn->handle = -1;
-    memset(con, 0, sizeof(testCon));
-    return (0);
+    testPrivatePtr priv;
+
+    if (!conn) {
+        testError (NULL, NULL, VIR_ERR_INVALID_CONN, __FUNCTION__);
+        return -1;
+    }
+
+    priv = (testPrivatePtr) conn->privateData;
+    if (!priv) {
+        testError (NULL, NULL, VIR_ERR_INVALID_CONN, __FUNCTION__);
+        return -1;
+    }
+
+    if (priv->handle >= 0) {
+        testCon *con = &node->connections[priv->handle];
+        con->active = 0;
+        memset (con, 0, sizeof *con); // RWMJ - why?
+    }
+
+    free (priv);
+    return 0;
 }
 
 int testGetVersion(virConnectPtr conn ATTRIBUTE_UNUSED,
@@ -809,7 +845,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 +891,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 +909,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 +923,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 +955,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 +984,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 +1009,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 +1035,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 +1052,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 +1065,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 +1076,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 +1089,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 +1100,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 +1113,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 +1129,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 +1142,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 +1164,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 +1177,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 +1222,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 +1231,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 +1256,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 +1265,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 +1275,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 +1288,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 +1300,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 +1313,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 +1329,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 +1342,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 +1362,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 +1371,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 +1405,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 +1419,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 +1459,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 +1468,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 +1486,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 +1495,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	30 Mar 2007 13:24:56 -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	30 Mar 2007 13:24:58 -0000
@@ -426,6 +426,7 @@
 
 #include "internal.h"
 #include "driver.h"
+#include "xen_unified.h"
 #include "xen_internal.h"
 
 #define XEN_HYPERVISOR_SOCKET "/proc/xen/privcmd"
@@ -436,8 +437,8 @@
 #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 +447,7 @@
     xenHypervisorClose, /* close */
     xenHypervisorGetType, /* type */
     xenHypervisorGetVersion, /* version */
-    xenHypervisorNumOfMaxVcpus, /* getMaxVcpus */
+    xenHypervisorGetMaxVcpus, /* getMaxVcpus */
     NULL, /* nodeGetInfo */
     xenHypervisorGetCapabilities, /* getCapabilities */
     xenHypervisorListDomains, /* listDomains */
@@ -1176,7 +1177,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 +1233,7 @@
     ret = open(XEN_HYPERVISOR_SOCKET, O_RDWR);
     if (ret < 0) {
         hypervisor_version = -1;
-        return (-1);
+        return(-1);
     }
     fd = ret;
 
@@ -1295,7 +1296,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 +1358,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,17 +1369,17 @@
  * Returns 0 or -1 in case of error.
  */
 int
-xenHypervisorOpen(virConnectPtr conn, const char *name, int flags)
+xenHypervisorOpen(virConnectPtr conn ATTRIBUTE_UNUSED,
+                  const char *name ATTRIBUTE_UNUSED, int flags)
 {
     int ret;
+    xenUnifiedPrivatePtr priv = (xenUnifiedPrivatePtr) conn->privateData;
 
     if (initialized == 0)
-        xenHypervisorInit();
+        if (xenHypervisorInit() == -1)
+            return -1;
 
-    if ((name != NULL) && (strcasecmp(name, "xen")))
-        return(-1);
-
-    conn->handle = -1;
+    priv->handle = -1;
 
     ret = open(XEN_HYPERVISOR_SOCKET, O_RDWR);
     if (ret < 0) {
@@ -1401,7 +1387,8 @@
             virXenError(VIR_ERR_NO_XEN, XEN_HYPERVISOR_SOCKET, 0);
         return (-1);
     }
-    conn->handle = ret;
+
+    priv->handle = ret;
 
     return(0);
 }
@@ -1418,13 +1405,20 @@
 xenHypervisorClose(virConnectPtr conn)
 {
     int ret;
+    xenUnifiedPrivatePtr priv;
 
-    if ((conn == NULL) || (conn->handle < 0))
+    if (conn == NULL)
         return (-1);
 
-    ret = close(conn->handle);
+    priv = (xenUnifiedPrivatePtr) conn->privateData;
+
+    if (priv->handle < 0)
+        return -1;
+
+    ret = close(priv->handle);
     if (ret < 0)
         return (-1);
+
     return (0);
 }
 
@@ -1463,7 +1457,12 @@
 int
 xenHypervisorGetVersion(virConnectPtr conn, unsigned long *hvVer)
 {
-    if ((conn == NULL) || (conn->handle < 0) || (hvVer == NULL))
+    xenUnifiedPrivatePtr priv;
+
+    if (conn == NULL)
+        return -1;
+    priv = (xenUnifiedPrivatePtr) conn->privateData;
+    if (priv->handle < 0 || hvVer == NULL)
         return (-1);
     *hvVer = (hv_version >> 16) * 1000000 + (hv_version & 0xFFFF) * 1000;
     return(0);
@@ -1778,8 +1777,12 @@
     int ret, nbids;
     static int last_maxids = 2;
     int maxids = last_maxids;
+    xenUnifiedPrivatePtr priv;
 
-    if ((conn == NULL) || (conn->handle < 0))
+    if (conn == NULL)
+        return -1;
+    priv = (xenUnifiedPrivatePtr) conn->privateData;
+    if (priv->handle < 0)
         return (-1);
 
  retry:
@@ -1791,7 +1794,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 +1827,13 @@
 {
     xen_getdomaininfolist dominfos;
     int ret, nbids, i;
+    xenUnifiedPrivatePtr priv;
 
-    if ((conn == NULL) || (conn->handle < 0) ||
+    if (conn == NULL)
+        return -1;
+
+    priv = (xenUnifiedPrivatePtr) conn->privateData;
+    if (priv->handle < 0 ||
         (ids == NULL) || (maxids < 1))
         return (-1);
 
@@ -1838,7 +1846,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 +1868,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))
+    xenUnifiedPrivatePtr priv;
+
+    if (conn == NULL)
+        return -1;
+    priv = (xenUnifiedPrivatePtr) conn->privateData;
+    if (priv->handle < 0)
         return (-1);
 
     return MAX_VIRT_CPUS;
@@ -1886,11 +1900,16 @@
 unsigned long
 xenHypervisorGetDomMaxMemory(virConnectPtr conn, int id)
 {
+    xenUnifiedPrivatePtr priv;
     xen_getdomaininfo dominfo;
     int ret;
 
-    if ((conn == NULL) || (conn->handle < 0))
-        return (0);
+    if (conn == NULL)
+        return 0;
+
+    priv = (xenUnifiedPrivatePtr) conn->privateData;
+    if (priv->handle < 0)
+        return 0;
 
     if (kb_per_pages == 0) {
         kb_per_pages = sysconf(_SC_PAGESIZE) / 1024;
@@ -1900,7 +1919,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 +1941,13 @@
 static unsigned long
 xenHypervisorGetMaxMemory(virDomainPtr domain)
 {
-    if ((domain == NULL) || (domain->conn == NULL) ||
-        (domain->conn->handle < 0) || (domain->id < 0))
+    xenUnifiedPrivatePtr priv;
+
+    if ((domain == NULL) || (domain->conn == NULL))
+        return 0;
+
+    priv = (xenUnifiedPrivatePtr) domain->conn->privateData;
+    if (priv->handle < 0 || domain->id < 0)
         return (0);
 
     return(xenHypervisorGetDomMaxMemory(domain->conn, domain->id));
@@ -1943,6 +1967,7 @@
 int
 xenHypervisorGetDomInfo(virConnectPtr conn, int id, virDomainInfoPtr info)
 {
+    xenUnifiedPrivatePtr priv;
     xen_getdomaininfo dominfo;
     int ret;
     uint32_t domain_flags, domain_state, domain_shutdown_cause;
@@ -1953,13 +1978,17 @@
 	    kb_per_pages = 4;
     }
 
-    if ((conn == NULL) || (conn->handle < 0) || (info == NULL))
+    if (conn == NULL)
+        return -1;
+
+    priv = (xenUnifiedPrivatePtr) 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 +2049,13 @@
 int
 xenHypervisorGetDomainInfo(virDomainPtr domain, virDomainInfoPtr info)
 {
-    if ((domain == NULL) || (domain->conn == NULL) ||
-        (domain->conn->handle < 0) || (info == NULL) ||
+    xenUnifiedPrivatePtr priv;
+
+    if ((domain == NULL) || (domain->conn == NULL))
+        return -1;
+
+    priv = (xenUnifiedPrivatePtr) domain->conn->privateData;
+    if (priv->handle < 0 || info == NULL ||
         (domain->id < 0))
         return (-1);
 
@@ -2042,12 +2076,16 @@
 xenHypervisorPauseDomain(virDomainPtr domain)
 {
     int ret;
+    xenUnifiedPrivatePtr priv;
 
-    if ((domain == NULL) || (domain->conn == NULL) ||
-        (domain->conn->handle < 0) || (domain->id < 0))
+    if ((domain == NULL) || (domain->conn == NULL))
+        return -1;
+
+    priv = (xenUnifiedPrivatePtr) 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 +2103,16 @@
 xenHypervisorResumeDomain(virDomainPtr domain)
 {
     int ret;
+    xenUnifiedPrivatePtr priv;
+
+    if ((domain == NULL) || (domain->conn == NULL))
+        return -1;
 
-    if ((domain == NULL) || (domain->conn == NULL) ||
-        (domain->conn->handle < 0) || (domain->id < 0))
+    priv = (xenUnifiedPrivatePtr) 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 +2130,16 @@
 xenHypervisorDestroyDomain(virDomainPtr domain)
 {
     int ret;
+    xenUnifiedPrivatePtr priv;
 
-    if ((domain == NULL) || (domain->conn == NULL) ||
-        (domain->conn->handle < 0) || (domain->id < 0))
+    if (domain == NULL || domain->conn == NULL)
+        return -1;
+
+    priv = (xenUnifiedPrivatePtr) 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 +2158,16 @@
 xenHypervisorSetMaxMemory(virDomainPtr domain, unsigned long memory)
 {
     int ret;
+    xenUnifiedPrivatePtr priv;
+
+    if (domain == NULL || domain->conn == NULL)
+        return -1;
 
-    if ((domain == NULL) || (domain->conn == NULL) ||
-        (domain->conn->handle < 0) || (domain->id < 0))
+    priv = (xenUnifiedPrivatePtr) 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 +2189,16 @@
 xenHypervisorSetVcpus(virDomainPtr domain, unsigned int nvcpus)
 {
     int ret;
+    xenUnifiedPrivatePtr priv;
 
-    if ((domain == NULL) || (domain->conn == NULL) ||
-        (domain->conn->handle < 0) || (domain->id < 0) ||
-        (nvcpus < 1))
+    if (domain == NULL || domain->conn == NULL)
+        return -1;
+
+    priv = (xenUnifiedPrivatePtr) 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 +2221,17 @@
                      unsigned char *cpumap, int maplen)
 {
     int ret;
+    xenUnifiedPrivatePtr priv;
 
-    if ((domain == NULL) || (domain->conn == NULL) ||
-        (domain->conn->handle < 0) || (domain->id < 0) ||
+    if (domain == NULL || domain->conn == NULL)
+        return -1;
+
+    priv = (xenUnifiedPrivatePtr) 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 +2265,15 @@
 {
     xen_getdomaininfo dominfo;
     int ret;
-
+    xenUnifiedPrivatePtr 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 = (xenUnifiedPrivatePtr) domain->conn->privateData;
+    if (priv->handle < 0 || (domain->id < 0) ||
         (info == NULL) || (maxinfo < 1) ||
         (sizeof(cpumap_t) & 7))
         return (-1);
@@ -2222,7 +2282,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 +2295,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 +2326,13 @@
     xen_getdomaininfo dominfo;
     int ret;
     int maxcpu;
+    xenUnifiedPrivatePtr priv;
+
+    if (domain == NULL || domain->conn == NULL)
+        return -1;
 
-    if ((domain == NULL) || (domain->conn == NULL) ||
-        (domain->conn->handle < 0))
+    priv = (xenUnifiedPrivatePtr) domain->conn->privateData;
+    if (priv->handle < 0)
         return (-1);
 
     /* inactive domain */
@@ -2276,7 +2340,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	30 Mar 2007 13:24:58 -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	30 Mar 2007 13:25:00 -0000
@@ -34,6 +34,7 @@
 #include "internal.h"
 #include "sexpr.h"
 #include "xml.h"
+#include "xen_unified.h"
 #include "xend_internal.h"
 #include "xen_internal.h" /* for DOM0_INTERFACE_VERSION */
 #include "xs_internal.h" /* To extract VNC port & Serial console TTY */
@@ -60,8 +61,8 @@
 #endif /* PROXY */
 
 #ifndef PROXY
-static virDriver xenDaemonDriver = {
-    VIR_DRV_XEN_DAEMON,
+virDriver xenDaemonDriver = {
+    -1,
     "XenDaemon",
     (DOM0_INTERFACE_VERSION >> 24) * 1000000 +
     ((DOM0_INTERFACE_VERSION >> 16) & 0xFF) * 1000 +
@@ -109,13 +110,14 @@
 };
 
 /**
- * xenDaemonRegister:
+ * xenDaemonInit:
  *
- * Registers the xenDaemon driver
+ * Initialise the xenDaemon driver.
  */
-void xenDaemonRegister(void)
+int
+xenDaemonInit (void)
 {
-    virRegisterDriver(&xenDaemonDriver);
+    return 0;
 }
 #endif /* !PROXY */
 
@@ -210,8 +212,9 @@
     int s;
     int serrno;
     int no_slow_start = 1;
+    xenUnifiedPrivatePtr priv = (xenUnifiedPrivatePtr) xend->privateData;
 
-    s = socket(xend->type, SOCK_STREAM, 0);
+    s = socket(priv->type, SOCK_STREAM, 0);
     if (s == -1) {
         virXendError(xend, VIR_ERR_INTERNAL_ERROR,
                      "failed to create a socket");
@@ -225,7 +228,7 @@
                sizeof(no_slow_start));
 
 
-    if (connect(s, xend->addr, xend->len) == -1) {
+    if (connect(s, priv->addr, priv->len) == -1) {
         serrno = errno;
         close(s);
         errno = serrno;
@@ -830,21 +833,22 @@
 xenDaemonOpen_unix(virConnectPtr conn, const char *path)
 {
     struct sockaddr_un *addr;
+    xenUnifiedPrivatePtr priv = (xenUnifiedPrivatePtr) conn->privateData;
 
     if ((conn == NULL) || (path == NULL))
         return (-1);
 
-    addr = &conn->addr_un;
+    addr = &priv->addr_un;
     addr->sun_family = AF_UNIX;
     memset(addr->sun_path, 0, sizeof(addr->sun_path));
     strncpy(addr->sun_path, path, sizeof(addr->sun_path));
 
-    conn->len = sizeof(addr->sun_family) + strlen(addr->sun_path);
-    if ((unsigned int) conn->len > sizeof(addr->sun_path))
-        conn->len = sizeof(addr->sun_path);
+    priv->len = sizeof(addr->sun_family) + strlen(addr->sun_path);
+    if ((unsigned int) priv->len > sizeof(addr->sun_path))
+        priv->len = sizeof(addr->sun_path);
 
-    conn->addr = (struct sockaddr *) addr;
-    conn->type = PF_UNIX;
+    priv->addr = (struct sockaddr *) addr;
+    priv->type = PF_UNIX;
 
     return (0);
 }
@@ -866,10 +870,13 @@
 {
     struct in_addr ip;
     struct hostent *pent;
+    xenUnifiedPrivatePtr priv;
 
     if ((conn == NULL) || (host == NULL) || (port <= 0))
         return (-1);
 
+    priv = (xenUnifiedPrivatePtr) conn->privateData;
+
     pent = gethostbyname(host);
     if (pent == NULL) {
         if (inet_aton(host, &ip) == 0) {
@@ -881,13 +888,13 @@
         memcpy(&ip, pent->h_addr_list[0], sizeof(ip));
     }
 
-    conn->len = sizeof(struct sockaddr_in);
-    conn->addr = (struct sockaddr *) &conn->addr_in;
-    conn->type = PF_INET;
-
-    conn->addr_in.sin_family = AF_INET;
-    conn->addr_in.sin_port = htons(port);
-    memcpy(&conn->addr_in.sin_addr, &ip, sizeof(ip));
+    priv->len = sizeof(struct sockaddr_in);
+    priv->addr = (struct sockaddr *) &priv->addr_in;
+    priv->type = PF_INET;
+
+    priv->addr_in.sin_family = AF_INET;
+    priv->addr_in.sin_port = htons(port);
+    memcpy(&priv->addr_in.sin_addr, &ip, sizeof(ip));
 
     return (0);
 }
@@ -1121,12 +1128,15 @@
 xend_detect_config_version(virConnectPtr conn) {
     struct sexpr *root;
     const char *value;
+    xenUnifiedPrivatePtr priv;
 
     if (!VIR_IS_CONNECT(conn)) {
         virXendError(conn, VIR_ERR_INVALID_CONN, __FUNCTION__);
         return (-1);
     }
 
+    priv = (xenUnifiedPrivatePtr) conn->privateData;
+
     root = sexpr_get(conn, "/xend/node/");
     if (root == NULL)
         return (-1);
@@ -1134,14 +1144,14 @@
     value = sexpr_node(root, "node/xend_config_format");
     
     if (value) {
-        conn->xendConfigVersion = strtol(value, NULL, 10);
+        priv->xendConfigVersion = strtol(value, NULL, 10);
     }  else {
         /* Xen prior to 3.0.3 did not have the xend_config_format
            field, and is implicitly version 1. */
-        conn->xendConfigVersion = 1;
+        priv->xendConfigVersion = 1;
     }
     sexpr_free(root);
-    return conn->xendConfigVersion;
+    return priv->xendConfigVersion;
 }
 
 /**
@@ -1804,10 +1814,13 @@
     char uuid[VIR_UUID_BUFLEN];
     const char *name;
     const char *tmp;
+    xenUnifiedPrivatePtr priv;
 
     if ((conn == NULL) || (root == NULL))
         return(NULL);
 
+    priv = (xenUnifiedPrivatePtr) conn->privateData;
+
     dst_uuid = (char *) &uuid[0];
     if (sexpr_uuid(&dst_uuid, root, "domain/uuid") == NULL)
         goto error;
@@ -1824,7 +1837,7 @@
     /* New 3.0.4 XenD will not report a domid for inactive domains,
      * so only error out for old XenD
      */
-    if (!tmp && conn->xendConfigVersion < 3)
+    if (!tmp && priv->xendConfigVersion < 3)
         goto error;
 
     if (tmp)
@@ -1873,79 +1886,85 @@
     int ret;
     unsigned long version;
 
-    if ((name == NULL) || (name[0] == 0) || (!strcasecmp(name, "xen"))) {
-	/*
-	 * try first to open the unix socket
-	 */
-	ret = xenDaemonOpen_unix(conn, "/var/lib/xend/xend-socket");
-	if (ret < 0)
-	    goto try_http;
-	ret = xenDaemonGetVersion(conn, &version);
-	if (ret == 0)
-	    goto done;
+    /* If the name is just "xen" (it might originally have been NULL, see
+     * xenUnifiedOpen) then try default paths and methods to get to the
+     * xend socket.
+     */
+    if (strcasecmp (name, "xen") == 0) {
+        /*
+         * try first to open the unix socket
+         */
+        ret = xenDaemonOpen_unix(conn, "/var/lib/xend/xend-socket");
+        if (ret < 0)
+            goto try_http;
+        ret = xenDaemonGetVersion(conn, &version);
+        if (ret == 0)
+            goto done;
 
-try_http:
+    try_http:
         /*
-	 * try though http on port 8000
-	 */
-	ret = xenDaemonOpen_tcp(conn, "localhost", 8000);
-	if (ret < 0)
-	    goto failed;
-	ret = xenDaemonGetVersion(conn, &version);
-	if (ret < 0)
-	    goto failed;
+         * try though http on port 8000
+         */
+        ret = xenDaemonOpen_tcp(conn, "localhost", 8000);
+        if (ret < 0)
+            goto failed;
+        ret = xenDaemonGetVersion(conn, &version);
+        if (ret < 0)
+            goto failed;
     } else {
         /*
-	 * We were given a connection name, expected to be an URL
-	 */
-	uri = xmlParseURI(name);
-	if (uri == NULL) {
-	    if (!(flags & VIR_DRV_OPEN_QUIET))
-		virXendError(conn, VIR_ERR_NO_SUPPORT, name);
-	    goto failed;
-	}
+         * We were given a connection name, expected to be an URL
+         */
+        uri = xmlParseURI(name);
+        if (uri == NULL) {
+            if (!(flags & VIR_DRV_OPEN_QUIET))
+                virXendError(conn, VIR_ERR_NO_SUPPORT, name);
+            goto failed;
+        }
 
-	if (uri->scheme == NULL) {
-	    /* It should be a file access */
-	    if (uri->path == NULL) {
-		if (!(flags & VIR_DRV_OPEN_QUIET))
-		    virXendError(conn, VIR_ERR_NO_SUPPORT, name);
-	        goto failed;
-	    }
-	    ret = xenDaemonOpen_unix(conn, uri->path);
-	    if (ret < 0)
-	        goto failed;
-
-	    ret = xenDaemonGetVersion(conn, &version);
-	    if (ret < 0)
-		goto failed;
-	} else if (!strcasecmp(uri->scheme, "http")) {
-	    ret = xenDaemonOpen_tcp(conn, uri->server, uri->port);
+        if (uri->scheme == NULL) {
+            /* It should be a file access */
+            if (uri->path == NULL) {
+                if (!(flags & VIR_DRV_OPEN_QUIET))
+                    virXendError(conn, VIR_ERR_NO_SUPPORT, name);
+                goto failed;
+            }
+            ret = xenDaemonOpen_unix(conn, uri->path);
             if (ret < 0)
-	        goto failed;
-	    ret = xenDaemonGetVersion(conn, &version);
-	    if (ret < 0)
-	        goto failed;
-	} else {
-	    if (!(flags & VIR_DRV_OPEN_QUIET))
-		virXendError(conn, VIR_ERR_NO_SUPPORT, name);
-	    goto failed;
-	}
+                goto failed;
+
+            ret = xenDaemonGetVersion(conn, &version);
+            if (ret < 0)
+                goto failed;
+        } else if (!strcasecmp(uri->scheme, "http")) {
+            ret = xenDaemonOpen_tcp(conn, uri->server, uri->port);
+            if (ret < 0)
+                goto failed;
+            ret = xenDaemonGetVersion(conn, &version);
+            if (ret < 0)
+                goto failed;
+        } else {
+            if (!(flags & VIR_DRV_OPEN_QUIET))
+                virXendError(conn, VIR_ERR_NO_SUPPORT, name);
+            goto failed;
+        }
     }
 
-done:
-    /* The XenD config version is used to determine
+ done: 
+   /* The XenD config version is used to determine
      * which APIs / features to activate. Lookup & cache
      * it now to avoid repeated HTTP calls
      */
     if (xend_detect_config_version(conn) < 0) {
-        virXendError(conn, VIR_ERR_INTERNAL_ERROR, "cannot determine xend config version");
+        virXendError(conn, VIR_ERR_INTERNAL_ERROR,
+                     "cannot determine xend config version");
         goto failed;
     }
 
     if (uri != NULL)
         xmlFreeURI(uri);
     return(ret);
+
 failed:
     if (uri != NULL)
         xmlFreeURI(uri);
@@ -1961,12 +1980,12 @@
  * initialized with xenDaemonOpen is no longer needed
  * to free the associated resources.
  *
- * Returns 0 in case of succes, -1 in case of error
+ * Returns 0 in case of success, -1 in case of error
  */
 int
 xenDaemonClose(virConnectPtr conn ATTRIBUTE_UNUSED)
 {
-    return(0);
+    return 0;
 }
 
 /**
@@ -2177,13 +2196,17 @@
 {
     unsigned long ret = 0;
     struct sexpr *root;
+    xenUnifiedPrivatePtr priv;
 
     if ((domain == NULL) || (domain->conn == NULL) || (domain->name == NULL)) {
         virXendError((domain ? domain->conn : NULL), VIR_ERR_INVALID_ARG,
 	             __FUNCTION__);
         return(-1);
     }
-    if (domain->id < 0 && domain->conn->xendConfigVersion < 3)
+
+    priv = (xenUnifiedPrivatePtr) domain->conn->privateData;
+
+    if (domain->id < 0 && priv->xendConfigVersion < 3)
         return(-1);
 
     /* can we ask for a subset ? worth it ? */
@@ -2213,13 +2236,17 @@
 xenDaemonDomainSetMaxMemory(virDomainPtr domain, unsigned long memory)
 {
     char buf[1024];
+    xenUnifiedPrivatePtr priv;
 
     if ((domain == NULL) || (domain->conn == NULL) || (domain->name == NULL)) {
         virXendError((domain ? domain->conn : NULL), VIR_ERR_INVALID_ARG,
 	             __FUNCTION__);
         return(-1);
     }
-    if (domain->id < 0 && domain->conn->xendConfigVersion < 3)
+
+    priv = (xenUnifiedPrivatePtr) domain->conn->privateData;
+
+    if (domain->id < 0 && priv->xendConfigVersion < 3)
         return(-1);
 
     snprintf(buf, sizeof(buf), "%lu", memory >> 10);
@@ -2247,13 +2274,17 @@
 xenDaemonDomainSetMemory(virDomainPtr domain, unsigned long memory)
 {
     char buf[1024];
+    xenUnifiedPrivatePtr priv;
 
     if ((domain == NULL) || (domain->conn == NULL) || (domain->name == NULL)) {
         virXendError((domain ? domain->conn : NULL), VIR_ERR_INVALID_ARG,
 	             __FUNCTION__);
         return(-1);
     }
-    if (domain->id < 0 && domain->conn->xendConfigVersion < 3)
+
+    priv = (xenUnifiedPrivatePtr) domain->conn->privateData;
+
+    if (domain->id < 0 && priv->xendConfigVersion < 3)
         return(-1);
 
     snprintf(buf, sizeof(buf), "%lu", memory >> 10);
@@ -2271,12 +2302,15 @@
 {
     char *ret = NULL;
     struct sexpr *root;
+    xenUnifiedPrivatePtr priv;
 
     root = sexpr_get(conn, "/xend/domain/%d?detail=1", domid);
     if (root == NULL)
         return (NULL);
 
-    ret = xend_parse_sexp_desc(conn, root, conn->xendConfigVersion);
+    priv = (xenUnifiedPrivatePtr) conn->privateData;
+
+    ret = xend_parse_sexp_desc(conn, root, priv->xendConfigVersion);
     sexpr_free(root);
 
     return (ret);
@@ -2287,12 +2321,15 @@
 {
     char *ret = NULL;
     struct sexpr *root;
+    xenUnifiedPrivatePtr priv;
 
     root = sexpr_get(conn, "/xend/domain/%s?detail=1", name);
     if (root == NULL)
         return (NULL);
 
-    ret = xend_parse_sexp_desc(conn, root, conn->xendConfigVersion);
+    priv = (xenUnifiedPrivatePtr) conn->privateData;
+
+    ret = xend_parse_sexp_desc(conn, root, priv->xendConfigVersion);
     sexpr_free(root);
 
     return (ret);
@@ -2312,12 +2349,16 @@
 char *
 xenDaemonDomainDumpXML(virDomainPtr domain, int flags ATTRIBUTE_UNUSED)
 {
+    xenUnifiedPrivatePtr priv;
+
     if ((domain == NULL) || (domain->conn == NULL) || (domain->name == NULL)) {
         virXendError((domain ? domain->conn : NULL), VIR_ERR_INVALID_ARG,
 	             __FUNCTION__);
         return(NULL);
     }
-    if (domain->id < 0 && domain->conn->xendConfigVersion < 3)
+    priv = (xenUnifiedPrivatePtr) domain->conn->privateData;
+
+    if (domain->id < 0 && priv->xendConfigVersion < 3)
         return(NULL);
     if (domain->id < 0)
         return xenDaemonDomainDumpXMLByName(domain->conn, domain->name);
@@ -2341,6 +2382,7 @@
 {
     struct sexpr *root;
     int ret;
+    xenUnifiedPrivatePtr priv;
 
     if ((domain == NULL) || (domain->conn == NULL) || (domain->name == NULL) ||
         (info == NULL)) {
@@ -2348,7 +2390,10 @@
 	             __FUNCTION__);
         return(-1);
     }
-    if (domain->id < 0 && domain->conn->xendConfigVersion < 3)
+
+    priv = (xenUnifiedPrivatePtr) domain->conn->privateData;
+
+    if (domain->id < 0 && priv->xendConfigVersion < 3)
         return(-1);
 
     root = sexpr_get(domain->conn, "/xend/domain/%s?detail=1", domain->name);
@@ -2625,6 +2670,7 @@
 xenDaemonDomainSetVcpus(virDomainPtr domain, unsigned int vcpus)
 {
     char buf[VIR_UUID_BUFLEN];
+    xenUnifiedPrivatePtr priv;
 
     if ((domain == NULL) || (domain->conn == NULL) || (domain->name == NULL)
      || (vcpus < 1)) {
@@ -2632,7 +2678,10 @@
 	             __FUNCTION__);
         return (-1);
     }
-    if (domain->id < 0 && domain->conn->xendConfigVersion < 3)
+
+    priv = (xenUnifiedPrivatePtr) domain->conn->privateData;
+
+    if (domain->id < 0 && priv->xendConfigVersion < 3)
         return(-1);
 
     snprintf(buf, sizeof(buf), "%d", vcpus);
@@ -2790,8 +2839,10 @@
     virDomainPtr ret;
     char *name = NULL;
     int id = -1;
+    xenUnifiedPrivatePtr priv = (xenUnifiedPrivatePtr) conn->privateData;
+
     /* Old approach for xen <= 3.0.3 */
-    if (conn->xendConfigVersion < 3) {
+    if (priv->xendConfigVersion < 3) {
         char **names, **tmp;
         unsigned char ident[VIR_UUID_BUFLEN];
         names = xenDaemonListDomainsOld(conn);
@@ -2871,6 +2922,7 @@
     char *sexpr;
     char *name = NULL;
     virDomainPtr dom = NULL;
+    xenUnifiedPrivatePtr priv;
 
     if (!VIR_IS_CONNECT(conn)) {
         virXendError(conn, VIR_ERR_INVALID_CONN, __FUNCTION__);
@@ -2881,7 +2933,9 @@
         return (NULL);
     }
 
-    sexpr = virDomainParseXMLDesc(conn, xmlDesc, &name, conn->xendConfigVersion);
+    priv = (xenUnifiedPrivatePtr) conn->privateData;
+
+    sexpr = virDomainParseXMLDesc(conn, xmlDesc, &name, priv->xendConfigVersion);
     if ((sexpr == NULL) || (name == NULL)) {
         virXendError(conn, VIR_ERR_XML_ERROR, "domain");
         if (sexpr != NULL)
@@ -2939,6 +2993,7 @@
 {
     char *sexpr, *conf;
     int hvm = 0, ret;
+    xenUnifiedPrivatePtr priv;
 
     if ((domain == NULL) || (domain->conn == NULL) || (domain->name == NULL)) {
         virXendError((domain ? domain->conn : NULL), VIR_ERR_INVALID_ARG,
@@ -2946,9 +3001,11 @@
         return (-1);
     }
 
+    priv = (xenUnifiedPrivatePtr) domain->conn->privateData;
+
     if (strcmp(virDomainGetOSType(domain), "linux"))
         hvm = 1;
-    sexpr = virParseXMLDevice(domain->conn, xml, hvm, domain->conn->xendConfigVersion);
+    sexpr = virParseXMLDevice(domain->conn, xml, hvm, priv->xendConfigVersion);
     if (sexpr == NULL)
         return (-1);
     if (!memcmp(sexpr, "(device ", 8)) {
@@ -2993,6 +3050,7 @@
     char *sexpr;
     char *name = NULL;
     virDomainPtr dom;
+    xenUnifiedPrivatePtr priv;
 
     if (!VIR_IS_CONNECT(conn)) {
         virXendError(conn, VIR_ERR_INVALID_CONN, __FUNCTION__);
@@ -3002,10 +3060,13 @@
         virXendError(conn, VIR_ERR_INVALID_ARG, __FUNCTION__);
         return (NULL);
     }
-    if (conn->xendConfigVersion < 3)
+
+    priv = (xenUnifiedPrivatePtr) conn->privateData;
+
+    if (priv->xendConfigVersion < 3)
         return(NULL);
 
-    sexpr = virDomainParseXMLDesc(conn, xmlDesc, &name, conn->xendConfigVersion);
+    sexpr = virDomainParseXMLDesc(conn, xmlDesc, &name, priv->xendConfigVersion);
     if ((sexpr == NULL) || (name == NULL)) {
         virXendError(conn, VIR_ERR_XML_ERROR, "domain");
         if (sexpr != NULL)
@@ -3034,25 +3095,37 @@
         free(name);
     return (NULL);
 }
-int xenDaemonDomainCreate(virDomainPtr domain) {
+int xenDaemonDomainCreate(virDomainPtr domain)
+{
+    xenUnifiedPrivatePtr priv;
+
     if ((domain == NULL) || (domain->conn == NULL) || (domain->name == NULL)) {
         virXendError((domain ? domain->conn : NULL), VIR_ERR_INVALID_ARG,
 	             __FUNCTION__);
         return(-1);
     }
-    if (domain->conn->xendConfigVersion < 3)
+
+    priv = (xenUnifiedPrivatePtr) domain->conn->privateData;
+
+    if (priv->xendConfigVersion < 3)
         return(-1);
 
     return xend_op(domain->conn, domain->name, "op", "start", NULL);
 }
 
-int xenDaemonDomainUndefine(virDomainPtr domain) {
+int xenDaemonDomainUndefine(virDomainPtr domain)
+{
+    xenUnifiedPrivatePtr priv;
+
     if ((domain == NULL) || (domain->conn == NULL) || (domain->name == NULL)) {
         virXendError((domain ? domain->conn : NULL), VIR_ERR_INVALID_ARG,
 	             __FUNCTION__);
         return(-1);
     }
-    if (domain->conn->xendConfigVersion < 3)
+
+    priv = (xenUnifiedPrivatePtr) domain->conn->privateData;
+
+    if (priv->xendConfigVersion < 3)
         return(-1);
 
     return xend_op(domain->conn, domain->name, "op", "delete", NULL);
@@ -3072,8 +3145,9 @@
     struct sexpr *root = NULL;
     int ret = -1;
     struct sexpr *_for_i, *node;
+    xenUnifiedPrivatePtr priv = (xenUnifiedPrivatePtr) conn->privateData;
 
-    if (conn->xendConfigVersion < 3)
+    if (priv->xendConfigVersion < 3)
         return(-1);
 
     root = sexpr_get(conn, "/xend/domain?state=halted");
@@ -3099,8 +3173,9 @@
     struct sexpr *root = NULL;
     int ret = -1;
     struct sexpr *_for_i, *node;
+    xenUnifiedPrivatePtr priv = (xenUnifiedPrivatePtr) conn->privateData;
 
-    if (conn->xendConfigVersion < 3)
+    if (priv->xendConfigVersion < 3)
         return(-1);
 
     if ((names == NULL) || (maxnames <= 0))
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	30 Mar 2007 13:25:00 -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	30 Mar 2007 13:25:02 -0000
@@ -36,6 +36,7 @@
 #include <libxml/xpath.h>
 
 
+#include "xen_unified.h"
 #include "xm_internal.h"
 #include "xend_internal.h"
 #include "conf.h"
@@ -66,8 +67,8 @@
 #define XEND_PCI_CONFIG_PREFIX "xend-pci-"
 #define QEMU_IF_SCRIPT "qemu-ifup"
 
-static virDriver xenXMDriver = {
-    VIR_DRV_XEN_XM,
+virDriver xenXMDriver = {
+    -1,
     "XenXM",
     (DOM0_INTERFACE_VERSION >> 24) * 1000000 +
     ((DOM0_INTERFACE_VERSION >> 16) & 0xFF) * 1000 +
@@ -127,11 +128,11 @@
                     errmsg, info, NULL, 0, 0, errmsg, info);
 }
 
-void xenXMRegister(void)
+int
+xenXMInit (void)
 {
     char *envConfigDir;
     int safeMode = 0;
-    virRegisterDriver(&xenXMDriver);
 
     /* Disable use of env variable if running setuid */
     if ((geteuid() != getuid()) ||
@@ -145,6 +146,8 @@
     } else {
         strcpy(configDir, XM_CONFIG_DIR);
     }
+
+    return 0;
 }
 
 
@@ -472,12 +475,10 @@
  * We only support a single directory, so repeated calls
  * to open all end up using the same cache of files
  */
-int xenXMOpen(virConnectPtr conn ATTRIBUTE_UNUSED, const char *name, int flags ATTRIBUTE_UNUSED) {
-    if (name &&
-        strcasecmp(name, "xen")) {
-        return (-1);
-    }
-
+int
+xenXMOpen (virConnectPtr conn ATTRIBUTE_UNUSED,
+           const char *name ATTRIBUTE_UNUSED, int flags ATTRIBUTE_UNUSED)
+{
     if (nconnections == 0) {
         configCache = virHashCreate(50);
         if (!configCache)
@@ -584,6 +585,7 @@
     const char *vnclisten = NULL;
     const char *vncpasswd = NULL;
     const char *keymap = NULL;
+    xenUnifiedPrivatePtr priv = (xenUnifiedPrivatePtr) conn->privateData;
 
     if (xenXMConfigGetString(conf, "name", &name) < 0)
         return (NULL);
@@ -798,7 +800,7 @@
         }
     }
 
-    if (hvm && conn->xendConfigVersion == 1) {
+    if (hvm && priv->xendConfigVersion == 1) {
         if (xenXMConfigGetString(conf, "cdrom", &str) == 0) {
             virBufferAdd(buf, "    <disk type='file' device='cdrom'>\n", -1);
             virBufferAdd(buf, "      <driver name='file'/>\n", -1);
@@ -884,7 +886,7 @@
     }
 
     /* HVM guests, or old PV guests use this config format */
-    if (hvm || conn->xendConfigVersion < 3) {
+    if (hvm || priv->xendConfigVersion < 3) {
         if (xenXMConfigGetInt(conf, "vnc", &val) == 0 && val) {
             vnc = 1;
             if (xenXMConfigGetInt(conf, "vncunused", &vncunused) < 0)
@@ -1282,6 +1284,7 @@
     char *sexpr;
     int ret;
     unsigned char uuid[VIR_UUID_BUFLEN];
+    xenUnifiedPrivatePtr priv;
 
     if ((domain == NULL) || (domain->conn == NULL) || (domain->name == NULL)) {
         xenXMError((domain ? domain->conn : NULL), VIR_ERR_INVALID_ARG,
@@ -1297,7 +1300,9 @@
     if (!(xml = xenXMDomainDumpXML(domain, 0)))
         return (-1);
 
-    if (!(sexpr = virDomainParseXMLDesc(domain->conn, xml, NULL, domain->conn->xendConfigVersion))) {
+    priv = (xenUnifiedPrivatePtr) domain->conn->privateData;
+
+    if (!(sexpr = virDomainParseXMLDesc(domain->conn, xml, NULL, priv->xendConfigVersion))) {
         free(xml);
         return (-1);
     }
@@ -1714,6 +1719,7 @@
     xmlChar *prop = NULL;
     virConfPtr conf = NULL;
     int hvm = 0, i;
+    xenUnifiedPrivatePtr priv;
 
     doc = xmlReadDoc((const xmlChar *) xml, "domain.xml", NULL,
                      XML_PARSE_NOENT | XML_PARSE_NONET |
@@ -1778,6 +1784,8 @@
         hvm = 1;
     xmlXPathFreeObject(obj);
 
+    priv = (xenUnifiedPrivatePtr) conn->privateData;
+
     if (hvm) {
         const char *boot = "c";
         if (xenXMConfigSetString(conf, "builder", "hvm") < 0)
@@ -1813,7 +1821,7 @@
                                        "cannot set the apic parameter") < 0)
             goto error;
 
-        if (conn->xendConfigVersion == 1) {
+        if (priv->xendConfigVersion == 1) {
             if (xenXMConfigSetStringFromXPath(conn, conf, ctxt, "cdrom", "string(/domain/devices/disk[ device='cdrom']/source/@file)", 1,
                                               "cannot set the cdrom parameter") < 0)
                 goto error;
@@ -1854,7 +1862,7 @@
 
     }
 
-    if (hvm || conn->xendConfigVersion < 3) {
+    if (hvm || priv->xendConfigVersion < 3) {
         if (xenXMConfigSetIntFromXPath(conn, conf, ctxt, "sdl", "string(count(/domain/devices/graphics[ type='sdl']))", 0, 0,
                                        "cannot set the sdl parameter") < 0)
             goto error;
@@ -1977,7 +1985,7 @@
         for (i = obj->nodesetval->nodeNr -1 ; i >= 0 ; i--) {
             virConfValuePtr thisDisk;
             char *disk = NULL;
-            if (xenXMParseXMLDisk(obj->nodesetval->nodeTab[i], hvm, conn->xendConfigVersion, &disk) < 0)
+            if (xenXMParseXMLDisk(obj->nodesetval->nodeTab[i], hvm, priv->xendConfigVersion, &disk) < 0)
                 goto error;
             if (disk) {
                 if (!(thisDisk = malloc(sizeof(virConfValue)))) {
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	30 Mar 2007 13:25:02 -0000
@@ -27,12 +27,15 @@
 
 #include "libvirt/libvirt.h"
 #include "conf.h"
+#include "internal.h"
 
 #ifdef __cplusplus
 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	30 Mar 2007 13:25:02 -0000
@@ -27,6 +27,7 @@
 
 #include "internal.h"
 #include "driver.h"
+#include "xen_unified.h"
 #include "xs_internal.h"
 #include "xen_internal.h" /* for xenHypervisorCheckID */
 
@@ -35,8 +36,8 @@
 #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 +85,14 @@
 };
 
 /**
- * xenStoreRegister:
+ * xenStoreInit:
  *
- * Registers the xenStore driver
+ * Initialisation.
  */
-void xenStoreRegister(void)
+int
+xenStoreInit ()
 {
-    virRegisterDriver(&xenStoreDriver);
+    return 0;
 }
 #endif /* ! PROXY */
 
@@ -135,11 +137,16 @@
 virConnectDoStoreList(virConnectPtr conn, const char *path,
                       unsigned int *nb)
 {
-    if ((conn == NULL) || (conn->xshandle == NULL) || (path == NULL) ||
-        (nb == NULL))
+    xenUnifiedPrivatePtr priv;
+
+    if (conn == NULL)
+        return NULL;
+
+    priv = (xenUnifiedPrivatePtr) 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 +165,19 @@
 {
     char s[256];
     unsigned int len = 0;
+    xenUnifiedPrivatePtr priv;
+
+    if (!conn)
+        return NULL;
 
-    if (!conn || conn->xshandle == NULL)
+    priv = (xenUnifiedPrivatePtr) 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 +196,14 @@
                       const char *value)
 {
     char s[256];
-
+    xenUnifiedPrivatePtr priv;
     int ret = -1;
 
     if (!VIR_IS_CONNECTED_DOMAIN(domain))
         return (-1);
-    if (domain->conn->xshandle == NULL)
+
+    priv = (xenUnifiedPrivatePtr) domain->conn->privateData;
+    if (priv->xshandle == NULL)
         return (-1);
     if (domain->conn->flags & VIR_CONNECT_RO)
         return (-1);
@@ -197,7 +211,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 +231,19 @@
     char *vm;
     char query[200];
     unsigned int len;
+    xenUnifiedPrivatePtr priv;
 
     if (!VIR_IS_CONNECTED_DOMAIN(domain))
         return (NULL);
-    if (domain->conn->xshandle == NULL)
+
+    priv = (xenUnifiedPrivatePtr) 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 +265,19 @@
     char s[256];
     char *ret = NULL;
     unsigned int len = 0;
+    xenUnifiedPrivatePtr priv;
 
     if (!VIR_IS_CONNECTED_DOMAIN(domain))
         return (NULL);
-    if (domain->conn->xshandle == NULL)
+
+    priv = (xenUnifiedPrivatePtr) 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,21 +324,21 @@
  * 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);
+    xenUnifiedPrivatePtr priv = (xenUnifiedPrivatePtr) conn->privateData;
 
 #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"));
@@ -338,14 +358,18 @@
 int
 xenStoreClose(virConnectPtr conn)
 {
+    xenUnifiedPrivatePtr 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 = (xenUnifiedPrivatePtr) conn->privateData;
+    if (priv->xshandle == NULL)
+        return(-1);
+
+    xs_daemon_close(priv->xshandle);
     return (0);
 }
 
@@ -365,6 +389,7 @@
     char *tmp, **tmp2;
     unsigned int nb_vcpus;
     char request[200];
+    xenUnifiedPrivatePtr priv;
 
     if (!VIR_IS_CONNECTED_DOMAIN(domain))
         return (-1);
@@ -374,8 +399,11 @@
 	                 __FUNCTION__);
 	return(-1);
     }
-    if (domain->conn->xshandle == NULL)
+
+    priv = (xenUnifiedPrivatePtr) domain->conn->privateData;
+    if (priv->xshandle == NULL)
         return(-1);
+
     if (domain->id == -1)
         return(-1);
 
@@ -490,12 +518,19 @@
     unsigned int num;
     char **idlist;
     int ret = -1;
+    xenUnifiedPrivatePtr 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 = (xenUnifiedPrivatePtr) 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 +555,18 @@
     unsigned int num, i;
     int ret;
     long id;
+    xenUnifiedPrivatePtr priv;
 
     if ((conn == NULL) || (ids == NULL)) {
         virXenStoreError(conn, VIR_ERR_INVALID_ARG, __FUNCTION__);
 	return(-1);
     }
-    if (conn->xshandle == NULL)
+
+    priv = (xenUnifiedPrivatePtr) 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 +604,18 @@
     char prop[200], *tmp, *path = NULL;
     int found = 0;
     struct xend_domain *xenddomain = NULL;
+    xenUnifiedPrivatePtr priv;
 
     if ((conn == NULL) || (name == NULL)) {
         virXenStoreError(conn, VIR_ERR_INVALID_ARG, __FUNCTION__);
 	return(NULL);
     }
-    if (conn->xshandle == NULL)
+
+    priv = (xenUnifiedPrivatePtr) 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 +630,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 +638,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 +805,23 @@
     char *vm, *str = NULL;
     char query[200];
     unsigned int len;
+    xenUnifiedPrivatePtr priv;
 
     if (id < 0)
         return(NULL);
 
-
-    if (conn->xshandle == NULL)
+    priv = (xenUnifiedPrivatePtr) 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 +849,13 @@
     char dir[80], path[128], **list = NULL, *val = NULL;
     unsigned int maclen, len, i, num;
     char *ret = NULL;
+    xenUnifiedPrivatePtr priv;
 
     if (id < 0)
         return(NULL);
-    if (conn->xshandle == NULL)
+
+    priv = (xenUnifiedPrivatePtr) conn->privateData;
+    if (priv->xshandle == NULL)
         return (NULL);
     if (mac == NULL)
         return (NULL);
@@ -819,12 +864,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	30 Mar 2007 13:25:02 -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);
Index: tests/xmconfigtest.c
===================================================================
RCS file: /data/cvs/libvirt/tests/xmconfigtest.c,v
retrieving revision 1.3
diff -u -r1.3 xmconfigtest.c
--- tests/xmconfigtest.c	16 Mar 2007 14:55:51 -0000	1.3
+++ tests/xmconfigtest.c	30 Mar 2007 13:25:02 -0000
@@ -25,6 +25,7 @@
 #include <string.h>
 
 #ifdef WITH_XEN
+#include "xen_unified.h"
 #include "xm_internal.h"
 #include "testutils.h"
 #include "internal.h"
@@ -45,8 +46,12 @@
     int ret = -1;
     virConnectPtr conn;
     int wrote = MAX_FILE;
+    void *old_priv;
+    struct _xenUnifiedPrivate priv;
 
     conn = virConnectOpen("test:///default");
+    if (!conn) goto fail;
+    old_priv = conn->privateData;
 
     if (virtTestLoadFile(xml, &xmlPtr, MAX_FILE) < 0)
         goto fail;
@@ -54,8 +59,9 @@
     if (virtTestLoadFile(xmcfg, &xmcfgPtr, MAX_FILE) < 0)
         goto fail;
 
-    /* Yes, a nasty hack, but this is only a test suite */
-    conn->xendConfigVersion = xendConfigVersion;
+    /* Many puppies died to bring you this code. */
+    priv.xendConfigVersion = xendConfigVersion;
+    conn->privateData = &priv;
 
     if (!(conf = xenXMParseXMLToConfig(conn, xmlPtr)))
         goto fail;
@@ -77,7 +83,11 @@
     if (conf)
         virConfFree(conf);
 
-    virConnectClose(conn);
+    if (conn) {
+        conn->privateData = old_priv;
+        virConnectClose(conn);
+    }
+
     return ret;
 }
 
@@ -90,8 +100,12 @@
     virConfPtr conf = NULL;
     int ret = -1;
     virConnectPtr conn;
+    void *old_priv;
+    struct _xenUnifiedPrivate priv;
 
     conn = virConnectOpen("test:///default");
+    if (!conn) goto fail;
+    old_priv = conn->privateData;
 
     if (virtTestLoadFile(xml, &xmlPtr, MAX_FILE) < 0)
         goto fail;
@@ -99,8 +113,9 @@
     if (virtTestLoadFile(xmcfg, &xmcfgPtr, MAX_FILE) < 0)
         goto fail;
 
-    /* Yes, a nasty hack, but this is only a test suite */
-    conn->xendConfigVersion = xendConfigVersion;
+    /* Many puppies died to bring you this code. */
+    priv.xendConfigVersion = xendConfigVersion;
+    conn->privateData = &priv;
 
     if (!(conf = virConfReadMem(xmcfgPtr, strlen(xmcfgPtr))))
         goto fail;
@@ -123,7 +138,11 @@
     if (gotxml)
         free(gotxml);
 
-    virConnectClose(conn);
+    if (conn) {
+        conn->privateData = old_priv;
+        virConnectClose(conn);
+    }
+
     return ret;
 }
 

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


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