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

[Libvir] Unified Xen patch (third and hopefully final version)




This is the third version of the unified Xen driver patch[1]. It includes Dan's fixes[2] and a minor fix of my own to fix compiles --without-xen. I've checked this and I'm happy with proposing it for inclusion in libvirt.

Rich.

[1] https://www.redhat.com/archives/libvir-list/2007-March/thread.html#00409
[2] https://www.redhat.com/archives/libvir-list/2007-April/msg00007.html

--
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 <unistd.h>
#include <sys/types.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;

  for (i = 0; i < nb_drivers; ++i) {
    int failed_to_open = 1;

    /* Ignore proxy for root */
    if (i == proxy_offset && getuid() == 0)
      continue;

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

    /* If as root, then all drivers must succeed.
       If non-root, then only proxy must succeed */
    if (failed_to_open && (getuid() == 0 || 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__

#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 {
#ifdef WITH_XEN
    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 */
#endif /* WITH_XEN */

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

typedef struct _xenUnifiedPrivate *xenUnifiedPrivatePtr;

#ifdef __cplusplus
}
#endif

#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: proxy/libvirt_proxy.c
===================================================================
RCS file: /data/cvs/libvirt/proxy/libvirt_proxy.c,v
retrieving revision 1.15
diff -u -r1.15 libvirt_proxy.c
--- proxy/libvirt_proxy.c	15 Mar 2007 17:24:57 -0000	1.15
+++ proxy/libvirt_proxy.c	4 Apr 2007 10:14:30 -0000
@@ -25,6 +25,7 @@
 #include "xen_internal.h"
 #include "xend_internal.h"
 #include "xs_internal.h"
+#include "xen_unified.h"
 
 static int fdServer = -1;
 static int debug = 0;
@@ -58,6 +59,23 @@
 proxyInitXen(void) {
     int ret;
     unsigned long xenVersion2;
+    xenUnifiedPrivatePtr priv;
+
+    /* Allocate per-connection private data. */
+    priv = malloc (sizeof *priv);
+    if (!priv) {
+        fprintf(stderr, "Failed to allocate private data\n");
+        return(-1);
+    }
+    conn->privateData = priv;
+
+    priv->handle = -1;
+    priv->xendConfigVersion = -1;
+    priv->type = -1;
+    priv->len = -1;
+    priv->addr = NULL;
+    priv->xshandle = NULL;
+    priv->proxy = -1;
 
     ret = xenHypervisorOpen(conn, NULL, VIR_DRV_OPEN_QUIET);
     if (ret < 0) {
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	4 Apr 2007 10:14:30 -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	4 Apr 2007 10:14:30 -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	4 Apr 2007 10:14:30 -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	4 Apr 2007 10:14:31 -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	4 Apr 2007 10:14:32 -0000
@@ -24,16 +24,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 +61,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 +204,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 +263,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 +338,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 +355,13 @@
 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);
+    if (conn->networkDriver)
+        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 && 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 && 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 && 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 && 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 && 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 && 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 && 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 && 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 && 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 && 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 && 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 && 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 && 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 && 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 && 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	4 Apr 2007 10:14:33 -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	4 Apr 2007 10:14:33 -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	4 Apr 2007 10:14:34 -0000
@@ -48,7 +48,20 @@
 #include "xml.h"
 #include "protocol.h"
 
-
+/**
+ * qemuPrivatePtr:
+ *
+ * Per-connection private data.
+ */
+struct _qemuPrivate {
+    int qemud_fd;               /* Connection to libvirt qemu daemon. */
+};
+struct _qemuNetworkPrivate {
+    int qemud_fd;
+    int shared;
+};
+typedef struct _qemuPrivate *qemuPrivatePtr;
+typedef struct _qemuNetworkPrivate *qemuNetworkPrivatePtr;
 
 static void
 qemuError(virConnectPtr con,
@@ -209,7 +222,8 @@
  * Returns the associated file descriptor or -1 in case of failure
  */
 static int
-qemuOpenClientUNIX(virConnectPtr conn, const char *path, int autostart) {
+qemuOpenClientUNIX(virConnectPtr conn ATTRIBUTE_UNUSED,
+                   const char *path, int autostart) {
     int fd;
     struct sockaddr_un addr;
     int trials = 0;
@@ -217,7 +231,7 @@
  retry:
     fd = socket(PF_UNIX, SOCK_STREAM, 0);
     if (fd < 0) {
-        return(-1);
+        return VIR_DRV_OPEN_ERROR;
     }
 
     /*
@@ -242,12 +256,10 @@
             usleep(5000 * trials * trials);
             goto retry;
         }
-        return (-1);
+        return VIR_DRV_OPEN_ERROR;
     }
 
-    conn->qemud_fd = fd;
-
-    return (0);
+    return fd;
 }
 
 
@@ -256,9 +268,10 @@
  * connection closes.
  */
 static int qemuProcessRequest(virConnectPtr conn,
-                               virDomainPtr dom,
-                               struct qemud_packet *req,
-                               struct qemud_packet *reply) {
+                              int qemud_fd,
+                              virDomainPtr dom,
+                              struct qemud_packet *req,
+                              struct qemud_packet *reply) {
     char *out = (char *)req;
     int outDone = 0;
     int outLeft = sizeof(struct qemud_packet_header) + req->header.dataSize;
@@ -270,7 +283,7 @@
 
     /* Block sending entire outgoing packet */
     while (outLeft) {
-        int got = write(conn->qemud_fd, out+outDone, outLeft);
+        int got = write(qemud_fd, out+outDone, outLeft);
         if (got < 0) {
             return -1;
         }
@@ -280,7 +293,7 @@
 
     /* Block waiting for header to come back */
     while (inLeft) {
-        int done = read(conn->qemud_fd, in+inGot, inLeft);
+        int done = read(qemud_fd, in+inGot, inLeft);
         if (done <= 0) {
             return -1;
         }
@@ -308,7 +321,7 @@
     /* Now block reading in body */
     inLeft = reply->header.dataSize;
     while (inLeft) {
-        int done = read(conn->qemud_fd, in+inGot, inLeft);
+        int done = read(qemud_fd, in+inGot, inLeft);
         if (done <= 0) {
             return -1;
         }
@@ -333,17 +346,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 +364,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 +386,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;
+    }
+
+    /* 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;
     }
 
-    conn->qemud_fd = -1;
-    qemuOpenConnection(conn, uri, flags & VIR_DRV_OPEN_RO ? 1 : 0);
+    ret = qemuOpenConnection(conn, uri, flags & VIR_DRV_OPEN_RO ? 1 : 0);
     xmlFreeURI(uri);
 
-    if (conn->qemud_fd < 0) {
-        return -1;
+    if (ret < 0) {
+        free (priv);
+        conn->privateData = NULL;
+        return VIR_DRV_OPEN_ERROR;
     }
 
-    return 0;
+    priv->qemud_fd = ret;
+
+    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;
 }
 
@@ -416,11 +449,12 @@
 static int qemuGetVersion(virConnectPtr conn,
                           unsigned long *hvVer) {
     struct qemud_packet req, reply;
+    qemuPrivatePtr priv = (qemuPrivatePtr) conn->privateData;
 
     req.header.type = QEMUD_PKT_GET_VERSION;
     req.header.dataSize = 0;
 
-    if (qemuProcessRequest(conn, NULL, &req, &reply) < 0) {
+    if (qemuProcessRequest(conn, priv->qemud_fd, NULL, &req, &reply) < 0) {
         return -1;
     }
 
@@ -432,11 +466,12 @@
 static int qemuNodeGetInfo(virConnectPtr conn,
                            virNodeInfoPtr info) {
     struct qemud_packet req, reply;
+    qemuPrivatePtr priv = (qemuPrivatePtr) conn->privateData;
 
     req.header.type = QEMUD_PKT_GET_NODEINFO;
     req.header.dataSize = 0;
 
-    if (qemuProcessRequest(conn, NULL, &req, &reply) < 0) {
+    if (qemuProcessRequest(conn, priv->qemud_fd, NULL, &req, &reply) < 0) {
         return -1;
     }
 
@@ -457,6 +492,7 @@
 {
     struct qemud_packet req, reply;
     char *xml;
+    qemuPrivatePtr priv = (qemuPrivatePtr) conn->privateData;
 
     /* Punt the request across to the daemon, because the daemon
      * has tables describing available architectures.
@@ -464,7 +500,7 @@
     req.header.type = QEMUD_PKT_GET_CAPABILITIES;
     req.header.dataSize = 0;
 
-    if (qemuProcessRequest(conn, NULL, &req, &reply) < 0) {
+    if (qemuProcessRequest(conn, priv->qemud_fd, NULL, &req, &reply) < 0) {
         return NULL;
     }
 
@@ -481,11 +517,12 @@
 
 static int qemuNumOfDomains(virConnectPtr conn) {
     struct qemud_packet req, reply;
+    qemuPrivatePtr priv = (qemuPrivatePtr) conn->privateData;
 
     req.header.type = QEMUD_PKT_NUM_DOMAINS;
     req.header.dataSize = 0;
 
-    if (qemuProcessRequest(conn, NULL, &req, &reply) < 0) {
+    if (qemuProcessRequest(conn, priv->qemud_fd, NULL, &req, &reply) < 0) {
         return -1;
     }
 
@@ -498,11 +535,12 @@
                            int maxids) {
     struct qemud_packet req, reply;
     int i, nDomains;
+    qemuPrivatePtr priv = (qemuPrivatePtr) conn->privateData;
 
     req.header.type = QEMUD_PKT_LIST_DOMAINS;
     req.header.dataSize = 0;
 
-    if (qemuProcessRequest(conn, NULL, &req, &reply) < 0) {
+    if (qemuProcessRequest(conn, priv->qemud_fd, NULL, &req, &reply) < 0) {
         return -1;
     }
 
@@ -524,6 +562,7 @@
     struct qemud_packet req, reply;
     virDomainPtr dom;
     int len = strlen(xmlDesc);
+    qemuPrivatePtr priv = (qemuPrivatePtr) conn->privateData;
 
     if (len > (QEMUD_MAX_XML_LEN-1)) {
         return NULL;
@@ -534,7 +573,7 @@
     strcpy(req.data.domainCreateRequest.xml, xmlDesc);
     req.data.domainCreateRequest.xml[QEMUD_MAX_XML_LEN-1] = '\0';
 
-    if (qemuProcessRequest(conn, NULL, &req, &reply) < 0) {
+    if (qemuProcessRequest(conn, priv->qemud_fd, NULL, &req, &reply) < 0) {
         return NULL;
     }
 
@@ -554,12 +593,13 @@
                                          int id) {
     struct qemud_packet req, reply;
     virDomainPtr dom;
+    qemuPrivatePtr priv = (qemuPrivatePtr) conn->privateData;
 
     req.header.type = QEMUD_PKT_DOMAIN_LOOKUP_BY_ID;
     req.header.dataSize = sizeof(req.data.domainLookupByIDRequest);
     req.data.domainLookupByIDRequest.id = id;
 
-    if (qemuProcessRequest(conn, NULL, &req, &reply) < 0) {
+    if (qemuProcessRequest(conn, priv->qemud_fd, NULL, &req, &reply) < 0) {
         return NULL;
     }
 
@@ -579,12 +619,13 @@
                                            const unsigned char *uuid) {
     struct qemud_packet req, reply;
     virDomainPtr dom;
+    qemuPrivatePtr priv = (qemuPrivatePtr) conn->privateData;
 
     req.header.type = QEMUD_PKT_DOMAIN_LOOKUP_BY_UUID;
     req.header.dataSize = sizeof(req.data.domainLookupByUUIDRequest);
     memmove(req.data.domainLookupByUUIDRequest.uuid, uuid, QEMUD_UUID_RAW_LEN);
 
-    if (qemuProcessRequest(conn, NULL, &req, &reply) < 0) {
+    if (qemuProcessRequest(conn, priv->qemud_fd, NULL, &req, &reply) < 0) {
         return NULL;
     }
 
@@ -604,6 +645,7 @@
                                            const char *name) {
     struct qemud_packet req, reply;
     virDomainPtr dom;
+    qemuPrivatePtr priv = (qemuPrivatePtr) conn->privateData;
 
     if (strlen(name) > (QEMUD_MAX_NAME_LEN-1))
         return NULL;
@@ -612,7 +654,7 @@
     req.header.dataSize = sizeof(req.data.domainLookupByNameRequest);
     strcpy(req.data.domainLookupByNameRequest.name, name);
 
-    if (qemuProcessRequest(conn, NULL, &req, &reply) < 0) {
+    if (qemuProcessRequest(conn, priv->qemud_fd, NULL, &req, &reply) < 0) {
         return NULL;
     }
 
@@ -627,12 +669,13 @@
 
 static int qemuDestroyDomain(virDomainPtr domain) {
     struct qemud_packet req, reply;
+    qemuPrivatePtr priv = (qemuPrivatePtr) domain->conn->privateData;
 
     req.header.type = QEMUD_PKT_DOMAIN_DESTROY;
     req.header.dataSize = sizeof(req.data.domainDestroyRequest);
     req.data.domainDestroyRequest.id = domain->id;
 
-    if (qemuProcessRequest(domain->conn, NULL, &req, &reply) < 0) {
+    if (qemuProcessRequest(domain->conn, priv->qemud_fd, NULL, &req, &reply) < 0) {
         return -1;
     }
 
@@ -643,28 +686,30 @@
     return qemuDestroyDomain(domain);
 }
 
-static int qemuResumeDomain(virDomainPtr domain ATTRIBUTE_UNUSED) {
+static int qemuResumeDomain(virDomainPtr domain) {
     struct qemud_packet req, reply;
+    qemuPrivatePtr priv = (qemuPrivatePtr) domain->conn->privateData;
 
     req.header.type = QEMUD_PKT_DOMAIN_RESUME;
     req.header.dataSize = sizeof(req.data.domainResumeRequest);
     req.data.domainResumeRequest.id = domain->id;
 
-    if (qemuProcessRequest(domain->conn, NULL, &req, &reply) < 0) {
+    if (qemuProcessRequest(domain->conn, priv->qemud_fd, NULL, &req, &reply) < 0) {
         return -1;
     }
 
     return 0;
 }
 
-static int qemuPauseDomain(virDomainPtr domain ATTRIBUTE_UNUSED) {
+static int qemuPauseDomain(virDomainPtr domain) {
     struct qemud_packet req, reply;
+    qemuPrivatePtr priv = (qemuPrivatePtr) domain->conn->privateData;
 
     req.header.type = QEMUD_PKT_DOMAIN_SUSPEND;
     req.header.dataSize = sizeof(req.data.domainSuspendRequest);
     req.data.domainSuspendRequest.id = domain->id;
 
-    if (qemuProcessRequest(domain->conn, NULL, &req, &reply) < 0) {
+    if (qemuProcessRequest(domain->conn, priv->qemud_fd, NULL, &req, &reply) < 0) {
         return -1;
     }
 
@@ -674,12 +719,13 @@
 static int qemuGetDomainInfo(virDomainPtr domain,
                              virDomainInfoPtr info) {
     struct qemud_packet req, reply;
+    qemuPrivatePtr priv = (qemuPrivatePtr) domain->conn->privateData;
 
     req.header.type = QEMUD_PKT_DOMAIN_GET_INFO;
     req.header.dataSize = sizeof(req.data.domainGetInfoRequest);
     memmove(req.data.domainGetInfoRequest.uuid, domain->uuid, QEMUD_UUID_RAW_LEN);
 
-    if (qemuProcessRequest(domain->conn, NULL, &req, &reply) < 0) {
+    if (qemuProcessRequest(domain->conn, priv->qemud_fd, NULL, &req, &reply) < 0) {
         return -1;
     }
 
@@ -710,12 +756,13 @@
 
 static char *qemuDomainDumpXML(virDomainPtr domain, int flags ATTRIBUTE_UNUSED) {
     struct qemud_packet req, reply;
+    qemuPrivatePtr priv = (qemuPrivatePtr) domain->conn->privateData;
 
     req.header.type = QEMUD_PKT_DUMP_XML;
     req.header.dataSize = sizeof(req.data.domainDumpXMLRequest);
     memmove(req.data.domainDumpXMLRequest.uuid, domain->uuid, QEMUD_UUID_RAW_LEN);
 
-    if (qemuProcessRequest(domain->conn, NULL, &req, &reply) < 0) {
+    if (qemuProcessRequest(domain->conn, priv->qemud_fd, NULL, &req, &reply) < 0) {
         return NULL;
     }
 
@@ -735,11 +782,12 @@
 
 static int qemuNumOfDefinedDomains(virConnectPtr conn) {
     struct qemud_packet req, reply;
+    qemuPrivatePtr priv = (qemuPrivatePtr) conn->privateData;
 
     req.header.type = QEMUD_PKT_NUM_DEFINED_DOMAINS;
     req.header.dataSize = 0;
 
-    if (qemuProcessRequest(conn, NULL, &req, &reply) < 0) {
+    if (qemuProcessRequest(conn, priv->qemud_fd, NULL, &req, &reply) < 0) {
         return -1;
     }
 
@@ -751,11 +799,12 @@
                                   int maxnames){
     struct qemud_packet req, reply;
     int i, nDomains;
+    qemuPrivatePtr priv = (qemuPrivatePtr) conn->privateData;
 
     req.header.type = QEMUD_PKT_LIST_DEFINED_DOMAINS;
     req.header.dataSize = 0;
 
-    if (qemuProcessRequest(conn, NULL, &req, &reply) < 0) {
+    if (qemuProcessRequest(conn, priv->qemud_fd, NULL, &req, &reply) < 0) {
         return -1;
     }
 
@@ -773,12 +822,13 @@
 
 static int qemuDomainCreate(virDomainPtr dom) {
     struct qemud_packet req, reply;
+    qemuPrivatePtr priv = (qemuPrivatePtr) dom->conn->privateData;
 
     req.header.type = QEMUD_PKT_DOMAIN_START;
     req.header.dataSize = sizeof(req.data.domainStartRequest);
     memcpy(req.data.domainStartRequest.uuid, dom->uuid, QEMUD_UUID_RAW_LEN);
 
-    if (qemuProcessRequest(dom->conn, NULL, &req, &reply) < 0) {
+    if (qemuProcessRequest(dom->conn, priv->qemud_fd, NULL, &req, &reply) < 0) {
         return -1;
     }
 
@@ -791,6 +841,7 @@
     struct qemud_packet req, reply;
     virDomainPtr dom;
     int len = strlen(xml);
+    qemuPrivatePtr priv = (qemuPrivatePtr) conn->privateData;
 
     if (len > (QEMUD_MAX_XML_LEN-1)) {
         return NULL;
@@ -801,7 +852,7 @@
     strcpy(req.data.domainDefineRequest.xml, xml);
     req.data.domainDefineRequest.xml[QEMUD_MAX_XML_LEN-1] = '\0';
 
-    if (qemuProcessRequest(conn, NULL, &req, &reply) < 0) {
+    if (qemuProcessRequest(conn, priv->qemud_fd, NULL, &req, &reply) < 0) {
         return NULL;
     }
 
@@ -819,12 +870,13 @@
 static int qemuUndefine(virDomainPtr dom) {
     struct qemud_packet req, reply;
     int ret = 0;
+    qemuPrivatePtr priv = (qemuPrivatePtr) dom->conn->privateData;
 
     req.header.type = QEMUD_PKT_DOMAIN_UNDEFINE;
     req.header.dataSize = sizeof(req.data.domainUndefineRequest);
     memcpy(req.data.domainUndefineRequest.uuid, dom->uuid, QEMUD_UUID_RAW_LEN);
 
-    if (qemuProcessRequest(dom->conn, NULL, &req, &reply) < 0) {
+    if (qemuProcessRequest(dom->conn, priv->qemud_fd, NULL, &req, &reply) < 0) {
         ret = -1;
         goto cleanup;
     }
@@ -839,12 +891,13 @@
 static int qemuDomainGetAutostart(virDomainPtr dom,
                                   int *autostart) {
     struct qemud_packet req, reply;
+    qemuPrivatePtr priv = (qemuPrivatePtr) dom->conn->privateData;
 
     req.header.type = QEMUD_PKT_DOMAIN_GET_AUTOSTART;
     req.header.dataSize = sizeof(req.data.domainGetAutostartRequest);
     memmove(req.data.domainGetAutostartRequest.uuid, dom->uuid, QEMUD_UUID_RAW_LEN);
 
-    if (qemuProcessRequest(dom->conn, NULL, &req, &reply) < 0) {
+    if (qemuProcessRequest(dom->conn, priv->qemud_fd, NULL, &req, &reply) < 0) {
         return -1;
     }
 
@@ -856,13 +909,14 @@
 static int qemuDomainSetAutostart(virDomainPtr dom,
                                   int autostart) {
     struct qemud_packet req, reply;
+    qemuPrivatePtr priv = (qemuPrivatePtr) dom->conn->privateData;
 
     req.header.type = QEMUD_PKT_DOMAIN_SET_AUTOSTART;
     req.header.dataSize = sizeof(req.data.domainSetAutostartRequest);
     req.data.domainSetAutostartRequest.autostart = (autostart != 0);
     memmove(req.data.domainSetAutostartRequest.uuid, dom->uuid, QEMUD_UUID_RAW_LEN);
 
-    if (qemuProcessRequest(dom->conn, NULL, &req, &reply) < 0) {
+    if (qemuProcessRequest(dom->conn, priv->qemud_fd, NULL, &req, &reply) < 0) {
         return -1;
     }
 
@@ -870,37 +924,62 @@
 }
 
 static int qemuNetworkOpen(virConnectPtr conn,
-                           const char *name,
+                           const char *name ATTRIBUTE_UNUSED,
                            int flags) {
-    xmlURIPtr uri = NULL;
-    int ret = -1;
+    qemuNetworkPrivatePtr netpriv = NULL;
+
+    if (!(netpriv = malloc(sizeof(struct _qemuNetworkPrivate)))) {
+        qemuError (conn, NULL, VIR_ERR_NO_MEMORY, __FUNCTION__);
+        return VIR_DRV_OPEN_ERROR;
+    }
 
-    if (conn->qemud_fd != -1)
+    if (!strcmp(conn->driver->name, "QEMU")) {
+        /* QEMU driver is active - just re-use existing connection */
+        qemuPrivatePtr priv = (qemuPrivatePtr) conn->privateData;
+        netpriv->qemud_fd = priv->qemud_fd;
+        netpriv->shared = 1;
+        conn->networkPrivateData = netpriv;
         return 0;
+    } else {
+        /* Non-QEMU driver is active - open a new connection */
+        const char *drvname = geteuid() == 0 ? "qemu:///system" : "qemu://session";
+        xmlURIPtr uri = xmlParseURI(drvname);
+        int ret = qemuOpenConnection(conn, uri, flags & VIR_DRV_OPEN_RO ? 1 : 0);
+        xmlFreeURI(uri);
 
-    if (name)
-        uri = xmlParseURI(name);
+        if (ret < 0) {
+            free(netpriv);
+            return ret;
+        } else {
+            netpriv->qemud_fd = ret;
+            netpriv->shared = 0;
+            conn->networkPrivateData = netpriv;
+            return 0;
+        }
+    }
+}
 
-    if (uri && uri->scheme && !strcmp(uri->scheme, "qemu"))
-        ret = qemuOpen(conn, name, flags);
-    else if (geteuid() == 0)
-        ret = qemuOpen(conn, "qemu:///system", flags);
-    else
-        ret = qemuOpen(conn, "qemu:///session", flags);
+static int
+qemuNetworkClose (virConnectPtr conn)
+{
+    qemuNetworkPrivatePtr netpriv = (qemuNetworkPrivatePtr) conn->networkPrivateData;
 
-    if (uri)
-        xmlFreeURI(uri);
+    if (!netpriv->shared)
+        close(netpriv->qemud_fd);
+    free(netpriv);
+    conn->networkPrivateData = NULL;
 
-    return ret;
+    return 0;
 }
 
 static int qemuNumOfNetworks(virConnectPtr conn) {
     struct qemud_packet req, reply;
+    qemuNetworkPrivatePtr priv = (qemuNetworkPrivatePtr) conn->networkPrivateData;
 
     req.header.type = QEMUD_PKT_NUM_NETWORKS;
     req.header.dataSize = 0;
 
-    if (qemuProcessRequest(conn, NULL, &req, &reply) < 0) {
+    if (qemuProcessRequest(conn, priv->qemud_fd, NULL, &req, &reply) < 0) {
         return -1;
     }
 
@@ -912,11 +991,12 @@
                             int maxnames) {
     struct qemud_packet req, reply;
     int i, nNetworks;
+    qemuNetworkPrivatePtr priv = (qemuNetworkPrivatePtr) conn->networkPrivateData;
 
     req.header.type = QEMUD_PKT_LIST_NETWORKS;
     req.header.dataSize = 0;
 
-    if (qemuProcessRequest(conn, NULL, &req, &reply) < 0) {
+    if (qemuProcessRequest(conn, priv->qemud_fd, NULL, &req, &reply) < 0) {
         return -1;
     }
 
@@ -934,11 +1014,12 @@
 
 static int qemuNumOfDefinedNetworks(virConnectPtr conn) {
     struct qemud_packet req, reply;
+    qemuNetworkPrivatePtr priv = (qemuNetworkPrivatePtr) conn->networkPrivateData;
 
     req.header.type = QEMUD_PKT_NUM_DEFINED_NETWORKS;
     req.header.dataSize = 0;
 
-    if (qemuProcessRequest(conn, NULL, &req, &reply) < 0) {
+    if (qemuProcessRequest(conn, priv->qemud_fd, NULL, &req, &reply) < 0) {
         return -1;
     }
 
@@ -950,11 +1031,12 @@
                                    int maxnames) {
     struct qemud_packet req, reply;
     int i, nNetworks;
+    qemuNetworkPrivatePtr priv = (qemuNetworkPrivatePtr) conn->networkPrivateData;
 
     req.header.type = QEMUD_PKT_LIST_DEFINED_NETWORKS;
     req.header.dataSize = 0;
 
-    if (qemuProcessRequest(conn, NULL, &req, &reply) < 0) {
+    if (qemuProcessRequest(conn, priv->qemud_fd, NULL, &req, &reply) < 0) {
         return -1;
     }
 
@@ -974,12 +1056,13 @@
                                              const unsigned char *uuid) {
     struct qemud_packet req, reply;
     virNetworkPtr network;
+    qemuNetworkPrivatePtr priv = (qemuNetworkPrivatePtr) conn->networkPrivateData;
 
     req.header.type = QEMUD_PKT_NETWORK_LOOKUP_BY_UUID;
     req.header.dataSize = sizeof(req.data.networkLookupByUUIDRequest);
     memmove(req.data.networkLookupByUUIDRequest.uuid, uuid, QEMUD_UUID_RAW_LEN);
 
-    if (qemuProcessRequest(conn, NULL, &req, &reply) < 0) {
+    if (qemuProcessRequest(conn, priv->qemud_fd, NULL, &req, &reply) < 0) {
         return NULL;
     }
 
@@ -997,6 +1080,7 @@
                                              const char *name) {
     struct qemud_packet req, reply;
     virNetworkPtr network;
+    qemuNetworkPrivatePtr priv = (qemuNetworkPrivatePtr) conn->networkPrivateData;
 
     if (strlen(name) > (QEMUD_MAX_NAME_LEN-1))
         return NULL;
@@ -1005,7 +1089,7 @@
     req.header.dataSize = sizeof(req.data.networkLookupByNameRequest);
     strcpy(req.data.networkLookupByNameRequest.name, name);
 
-    if (qemuProcessRequest(conn, NULL, &req, &reply) < 0) {
+    if (qemuProcessRequest(conn, priv->qemud_fd, NULL, &req, &reply) < 0) {
         return NULL;
     }
 
@@ -1022,6 +1106,7 @@
     struct qemud_packet req, reply;
     virNetworkPtr network;
     int len = strlen(xmlDesc);
+    qemuNetworkPrivatePtr priv = (qemuNetworkPrivatePtr) conn->networkPrivateData;
 
     if (len > (QEMUD_MAX_XML_LEN-1)) {
         return NULL;
@@ -1032,7 +1117,7 @@
     strcpy(req.data.networkCreateRequest.xml, xmlDesc);
     req.data.networkCreateRequest.xml[QEMUD_MAX_XML_LEN-1] = '\0';
 
-    if (qemuProcessRequest(conn, NULL, &req, &reply) < 0) {
+    if (qemuProcessRequest(conn, priv->qemud_fd, NULL, &req, &reply) < 0) {
         return NULL;
     }
 
@@ -1052,6 +1137,7 @@
     struct qemud_packet req, reply;
     virNetworkPtr network;
     int len = strlen(xml);
+    qemuNetworkPrivatePtr priv = (qemuNetworkPrivatePtr) conn->networkPrivateData;
 
     if (len > (QEMUD_MAX_XML_LEN-1)) {
         return NULL;
@@ -1062,7 +1148,7 @@
     strcpy(req.data.networkDefineRequest.xml, xml);
     req.data.networkDefineRequest.xml[QEMUD_MAX_XML_LEN-1] = '\0';
 
-    if (qemuProcessRequest(conn, NULL, &req, &reply) < 0) {
+    if (qemuProcessRequest(conn, priv->qemud_fd, NULL, &req, &reply) < 0) {
         return NULL;
     }
 
@@ -1079,12 +1165,13 @@
 static int qemuNetworkUndefine(virNetworkPtr network) {
     struct qemud_packet req, reply;
     int ret = 0;
+    qemuNetworkPrivatePtr priv = (qemuNetworkPrivatePtr) network->conn->networkPrivateData;
 
     req.header.type = QEMUD_PKT_NETWORK_UNDEFINE;
     req.header.dataSize = sizeof(req.data.networkUndefineRequest);
     memcpy(req.data.networkUndefineRequest.uuid, network->uuid, QEMUD_UUID_RAW_LEN);
 
-    if (qemuProcessRequest(network->conn, NULL, &req, &reply) < 0) {
+    if (qemuProcessRequest(network->conn, priv->qemud_fd, NULL, &req, &reply) < 0) {
         ret = -1;
         goto cleanup;
     }
@@ -1098,12 +1185,13 @@
 
 static int qemuNetworkCreate(virNetworkPtr network) {
     struct qemud_packet req, reply;
+    qemuNetworkPrivatePtr priv = (qemuNetworkPrivatePtr) network->conn->networkPrivateData;
 
     req.header.type = QEMUD_PKT_NETWORK_START;
     req.header.dataSize = sizeof(req.data.networkStartRequest);
     memcpy(req.data.networkStartRequest.uuid, network->uuid, QEMUD_UUID_RAW_LEN);
 
-    if (qemuProcessRequest(network->conn, NULL, &req, &reply) < 0) {
+    if (qemuProcessRequest(network->conn, priv->qemud_fd, NULL, &req, &reply) < 0) {
         return -1;
     }
 
@@ -1112,12 +1200,13 @@
 
 static int qemuNetworkDestroy(virNetworkPtr network) {
     struct qemud_packet req, reply;
+    qemuNetworkPrivatePtr priv = (qemuNetworkPrivatePtr) network->conn->networkPrivateData;
 
     req.header.type = QEMUD_PKT_NETWORK_DESTROY;
     req.header.dataSize = sizeof(req.data.networkDestroyRequest);
     memcpy(req.data.networkDestroyRequest.uuid, network->uuid, QEMUD_UUID_RAW_LEN);
 
-    if (qemuProcessRequest(network->conn, NULL, &req, &reply) < 0) {
+    if (qemuProcessRequest(network->conn, priv->qemud_fd, NULL, &req, &reply) < 0) {
         return -1;
     }
 
@@ -1126,12 +1215,13 @@
 
 static char * qemuNetworkDumpXML(virNetworkPtr network, int flags ATTRIBUTE_UNUSED) {
     struct qemud_packet req, reply;
+    qemuNetworkPrivatePtr priv = (qemuNetworkPrivatePtr) network->conn->networkPrivateData;
 
     req.header.type = QEMUD_PKT_NETWORK_DUMP_XML;
     req.header.dataSize = sizeof(req.data.networkDumpXMLRequest);
     memmove(req.data.networkDumpXMLRequest.uuid, network->uuid, QEMUD_UUID_RAW_LEN);
 
-    if (qemuProcessRequest(network->conn, NULL, &req, &reply) < 0) {
+    if (qemuProcessRequest(network->conn, priv->qemud_fd, NULL, &req, &reply) < 0) {
         return NULL;
     }
 
@@ -1142,12 +1232,13 @@
 
 static char * qemuNetworkGetBridgeName(virNetworkPtr network) {
     struct qemud_packet req, reply;
+    qemuNetworkPrivatePtr priv = (qemuNetworkPrivatePtr) network->conn->networkPrivateData;
 
     req.header.type = QEMUD_PKT_NETWORK_GET_BRIDGE_NAME;
     req.header.dataSize = sizeof(req.data.networkGetBridgeNameRequest);
     memmove(req.data.networkGetBridgeNameRequest.uuid, network->uuid, QEMUD_UUID_RAW_LEN);
 
-    if (qemuProcessRequest(network->conn, NULL, &req, &reply) < 0) {
+    if (qemuProcessRequest(network->conn, priv->qemud_fd, NULL, &req, &reply) < 0) {
         return NULL;
     }
 
@@ -1159,12 +1250,13 @@
 static int qemuNetworkGetAutostart(virNetworkPtr network,
                                    int *autostart) {
     struct qemud_packet req, reply;
+    qemuNetworkPrivatePtr priv = (qemuNetworkPrivatePtr) network->conn->networkPrivateData;
 
     req.header.type = QEMUD_PKT_NETWORK_GET_AUTOSTART;
     req.header.dataSize = sizeof(req.data.networkGetAutostartRequest);
     memmove(req.data.networkGetAutostartRequest.uuid, network->uuid, QEMUD_UUID_RAW_LEN);
 
-    if (qemuProcessRequest(network->conn, NULL, &req, &reply) < 0) {
+    if (qemuProcessRequest(network->conn, priv->qemud_fd, NULL, &req, &reply) < 0) {
         return -1;
     }
 
@@ -1176,13 +1268,14 @@
 static int qemuNetworkSetAutostart(virNetworkPtr network,
                                    int autostart) {
     struct qemud_packet req, reply;
+    qemuNetworkPrivatePtr priv = (qemuNetworkPrivatePtr) network->conn->networkPrivateData;
 
     req.header.type = QEMUD_PKT_NETWORK_SET_AUTOSTART;
     req.header.dataSize = sizeof(req.data.networkSetAutostartRequest);
     req.data.networkSetAutostartRequest.autostart = (autostart != 0);
     memmove(req.data.networkSetAutostartRequest.uuid, network->uuid, QEMUD_UUID_RAW_LEN);
 
-    if (qemuProcessRequest(network->conn, NULL, &req, &reply) < 0) {
+    if (qemuProcessRequest(network->conn, priv->qemud_fd, NULL, &req, &reply) < 0) {
         return -1;
     }
 
@@ -1237,7 +1330,7 @@
 
 static virNetworkDriver qemuNetworkDriver = {
     qemuNetworkOpen, /* open */
-    qemuClose, /* close */
+    qemuNetworkClose, /* close */
     qemuNumOfNetworks, /* numOfNetworks */
     qemuListNetworks, /* listNetworks */
     qemuNumOfDefinedNetworks, /* numOfDefinedNetworks */
@@ -1260,9 +1353,15 @@
  *
  * Registers QEmu/KVM in libvirt driver system
  */
-void qemuRegister(void) {
-    virRegisterDriver(&qemuDriver);
-    virRegisterNetworkDriver(&qemuNetworkDriver);
+int
+qemuRegister (void)
+{
+    if (virRegisterDriver(&qemuDriver) == -1)
+        return -1;
+    if (virRegisterNetworkDriver(&qemuNetworkDriver) == -1)
+        return -1;
+
+    return 0;
 }
 #endif /* WITH_QEMU */
 
Index: src/qemu_internal.h
===================================================================
RCS file: /data/cvs/libvirt/src/qemu_internal.h,v
retrieving revision 1.1
diff -u -r1.1 qemu_internal.h
--- src/qemu_internal.h	14 Feb 2007 01:40:09 -0000	1.1
+++ src/qemu_internal.h	4 Apr 2007 10:14:34 -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	4 Apr 2007 10:14:35 -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	4 Apr 2007 10:14:35 -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	4 Apr 2007 10:14:36 -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;
@@ -1187,7 +1188,7 @@
 
     if (initialized) {
         if (hypervisor_version == -1)
-            return(-1);
+            return (-1);
         return(0);
     }
     initialized = 1;
@@ -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 ((name != NULL) && (strcasecmp(name, "xen")))
-        return(-1);
+        if (xenHypervisorInit() == -1)
+            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)
+        return -1;
 
-    if ((conn == NULL) || (conn->handle < 0) ||
+    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)
+        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_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) ||
-        (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_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)
+        return -1;
 
-    if ((domain == NULL) || (domain->conn == NULL) ||
-        (domain->conn->handle < 0) || (domain->id < 0) ||
-        (nvcpus < 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	4 Apr 2007 10:14:36 -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	4 Apr 2007 10:14:39 -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	4 Apr 2007 10:14:39 -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	4 Apr 2007 10:14:41 -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	4 Apr 2007 10:14:41 -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	4 Apr 2007 10:14:41 -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	4 Apr 2007 10:14:41 -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	4 Apr 2007 10:14:41 -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]