+Tue Jun 26 12:40:00 BST 2007 Richard W.M. Jones <rjones@redhat.com>
+
+ * include/libvirt/libvirt.h.in, src/libvirt.c: (and numerous
+ other files) Added support for virConnectGetHostname
+ and virConnectGetURI calls.
+
Mon Jun 25 16:55:00 BST 2007 Richard W.M. Jones <rjones@redhat.com>
* include/libvirt/libvirt.h.in, src/libvirt.c, src/libvirt_sym.version,
const char * virConnectGetType (virConnectPtr conn);
int virConnectGetVersion (virConnectPtr conn,
unsigned long *hvVer);
+char * virConnectGetHostname (virConnectPtr conn);
+char * virConnectGetURI (virConnectPtr conn);
+
+
/*
* Capabilities of the connection / driver.
*/
const char * virConnectGetType (virConnectPtr conn);
int virConnectGetVersion (virConnectPtr conn,
unsigned long *hvVer);
+char * virConnectGetHostname (virConnectPtr conn);
+char * virConnectGetURI (virConnectPtr conn);
+
+
/*
* Capabilities of the connection / driver.
*/
return 0;
}
+static int
+remoteDispatchGetHostname (struct qemud_client *client,
+ remote_message_header *req,
+ void *args ATTRIBUTE_UNUSED,
+ remote_get_hostname_ret *ret)
+{
+ char *hostname;
+ CHECK_CONN(client);
+
+ hostname = virConnectGetHostname (client->conn);
+ if (hostname == NULL) return -1;
+
+ ret->hostname = hostname;
+ return 0;
+}
+
static int
remoteDispatchGetMaxVcpus (struct qemud_client *client,
remote_message_header *req,
remote_domain_get_autostart_args lv_remote_domain_get_autostart_args;
remote_domain_get_autostart_ret lv_remote_domain_get_autostart_ret;
remote_domain_set_vcpus_args lv_remote_domain_set_vcpus_args;
+remote_get_hostname_ret lv_remote_get_hostname_ret;
remote_domain_get_scheduler_type_args lv_remote_domain_get_scheduler_type_args;
remote_domain_get_scheduler_type_ret lv_remote_domain_get_scheduler_type_ret;
remote_network_undefine_args lv_remote_network_undefine_args;
ret = (char *) &lv_remote_get_capabilities_ret;
memset (&lv_remote_get_capabilities_ret, 0, sizeof lv_remote_get_capabilities_ret);
break;
+case REMOTE_PROC_GET_HOSTNAME:
+ fn = (dispatch_fn) remoteDispatchGetHostname;
+ ret_filter = (xdrproc_t) xdr_remote_get_hostname_ret;
+ ret = (char *) &lv_remote_get_hostname_ret;
+ memset (&lv_remote_get_hostname_ret, 0, sizeof lv_remote_get_hostname_ret);
+ break;
case REMOTE_PROC_GET_MAX_VCPUS:
fn = (dispatch_fn) remoteDispatchGetMaxVcpus;
args_filter = (xdrproc_t) xdr_remote_get_max_vcpus_args;
static int remoteDispatchDomainSuspend (struct qemud_client *client, remote_message_header *req, remote_domain_suspend_args *args, void *ret);
static int remoteDispatchDomainUndefine (struct qemud_client *client, remote_message_header *req, remote_domain_undefine_args *args, void *ret);
static int remoteDispatchGetCapabilities (struct qemud_client *client, remote_message_header *req, void *args, remote_get_capabilities_ret *ret);
+static int remoteDispatchGetHostname (struct qemud_client *client, remote_message_header *req, void *args, remote_get_hostname_ret *ret);
static int remoteDispatchGetMaxVcpus (struct qemud_client *client, remote_message_header *req, remote_get_max_vcpus_args *args, remote_get_max_vcpus_ret *ret);
static int remoteDispatchGetType (struct qemud_client *client, remote_message_header *req, void *args, remote_get_type_ret *ret);
static int remoteDispatchGetVersion (struct qemud_client *client, remote_message_header *req, void *args, remote_get_version_ret *ret);
return TRUE;
}
+bool_t
+xdr_remote_get_hostname_ret (XDR *xdrs, remote_get_hostname_ret *objp)
+{
+
+ if (!xdr_remote_nonnull_string (xdrs, &objp->hostname))
+ return FALSE;
+ return TRUE;
+}
+
bool_t
xdr_remote_get_max_vcpus_args (XDR *xdrs, remote_get_max_vcpus_args *objp)
{
};
typedef struct remote_get_version_ret remote_get_version_ret;
+struct remote_get_hostname_ret {
+ remote_nonnull_string hostname;
+};
+typedef struct remote_get_hostname_ret remote_get_hostname_ret;
+
struct remote_get_max_vcpus_args {
remote_string type;
};
REMOTE_PROC_DOMAIN_GET_SCHEDULER_TYPE = 56,
REMOTE_PROC_DOMAIN_GET_SCHEDULER_PARAMETERS = 57,
REMOTE_PROC_DOMAIN_SET_SCHEDULER_PARAMETERS = 58,
+ REMOTE_PROC_GET_HOSTNAME = 59,
};
typedef enum remote_procedure remote_procedure;
extern bool_t xdr_remote_open_args (XDR *, remote_open_args*);
extern bool_t xdr_remote_get_type_ret (XDR *, remote_get_type_ret*);
extern bool_t xdr_remote_get_version_ret (XDR *, remote_get_version_ret*);
+extern bool_t xdr_remote_get_hostname_ret (XDR *, remote_get_hostname_ret*);
extern bool_t xdr_remote_get_max_vcpus_args (XDR *, remote_get_max_vcpus_args*);
extern bool_t xdr_remote_get_max_vcpus_ret (XDR *, remote_get_max_vcpus_ret*);
extern bool_t xdr_remote_node_get_info_ret (XDR *, remote_node_get_info_ret*);
extern bool_t xdr_remote_open_args ();
extern bool_t xdr_remote_get_type_ret ();
extern bool_t xdr_remote_get_version_ret ();
+extern bool_t xdr_remote_get_hostname_ret ();
extern bool_t xdr_remote_get_max_vcpus_args ();
extern bool_t xdr_remote_get_max_vcpus_ret ();
extern bool_t xdr_remote_node_get_info_ret ();
hyper hv_ver;
};
+struct remote_get_hostname_ret {
+ remote_nonnull_string hostname;
+};
+
struct remote_get_max_vcpus_args {
/* The only backend which supports this call is Xen HV, and
* there the type is ignored so it could be NULL.
REMOTE_PROC_DOMAIN_SAVE = 55,
REMOTE_PROC_DOMAIN_GET_SCHEDULER_TYPE = 56,
REMOTE_PROC_DOMAIN_GET_SCHEDULER_PARAMETERS = 57,
- REMOTE_PROC_DOMAIN_SET_SCHEDULER_PARAMETERS = 58
+ REMOTE_PROC_DOMAIN_SET_SCHEDULER_PARAMETERS = 58,
+ REMOTE_PROC_GET_HOSTNAME = 59
};
/* Custom RPC structure. */
typedef int
(*virDrvGetVersion) (virConnectPtr conn,
unsigned long *hvVer);
+typedef char *
+ (*virDrvGetHostname) (virConnectPtr conn);
+typedef char *
+ (*virDrvGetURI) (virConnectPtr conn);
typedef int
(*virDrvGetMaxVcpus) (virConnectPtr conn,
const char *type);
virDrvClose close;
virDrvGetType type;
virDrvGetVersion version;
+ virDrvGetHostname getHostname;
+ virDrvGetURI getURI;
virDrvGetMaxVcpus getMaxVcpus;
virDrvNodeGetInfo nodeGetInfo;
virDrvGetCapabilities getCapabilities;
/* String equality tests, suggested by Jim Meyering. */
#define STREQ(a,b) (strcmp((a),(b)) == 0)
#define STRCASEEQ(a,b) (strcasecmp((a),(b)) == 0)
+#define STRNEQ(a,b) (strcmp((a),(b)) != 0)
+#define STRCASENEQ(a,b) (strcasecmp((a),(b)) != 0)
/**
* ATTRIBUTE_UNUSED:
return -1;
}
+/**
+ * virConnectGetHostname:
+ * @conn: pointer to a hypervisor connection
+ *
+ * This returns the system hostname on which the hypervisor is
+ * running (the result of the gethostname(2) system call). If
+ * we are connected to a remote system, then this returns the
+ * hostname of the remote system.
+ *
+ * Returns the hostname which must be freed by the caller, or
+ * NULL if there was an error.
+ */
+char *
+virConnectGetHostname (virConnectPtr conn)
+{
+ if (!VIR_IS_CONNECT(conn)) {
+ virLibConnError(conn, VIR_ERR_INVALID_CONN, __FUNCTION__);
+ return NULL;
+ }
+
+ if (conn->driver->getHostname)
+ return conn->driver->getHostname (conn);
+
+ virLibConnError (conn, VIR_ERR_NO_SUPPORT, __FUNCTION__);
+ return NULL;
+}
+
+/**
+ * virConnectGetURI:
+ * @conn: pointer to a hypervisor connection
+ *
+ * This returns the URI (name) of the hypervisor connection.
+ * Normally this is the same as or similar to the string passed
+ * to the virConnectOpen/virConnectOpenReadOnly call, but
+ * the driver may make the URI canonical. If name == NULL
+ * was passed to virConnectOpen, then the driver will return
+ * a non-NULL URI which can be used to connect to the same
+ * hypervisor later.
+ *
+ * Returns the URI string which must be freed by the caller, or
+ * NULL if there was an error.
+ */
+char *
+virConnectGetURI (virConnectPtr conn)
+{
+ if (!VIR_IS_CONNECT(conn)) {
+ virLibConnError(conn, VIR_ERR_INVALID_CONN, __FUNCTION__);
+ return NULL;
+ }
+
+ if (conn->driver->getURI)
+ return conn->driver->getURI (conn);
+
+ virLibConnError (conn, VIR_ERR_NO_SUPPORT, __FUNCTION__);
+ return NULL;
+}
+
/**
* virConnectGetMaxVcpus:
* @conn: pointer to the hypervisor connection
virConnectClose;
virConnectGetType;
virConnectGetVersion;
+ virConnectGetHostname;
+ virConnectGetURI;
virDomainGetConnect;
virConnectListDomains;
virConnectNumOfDomains;
xenProxyClose, /* close */
NULL, /* type */
xenProxyGetVersion, /* version */
+ NULL, /* hostname */
+ NULL, /* URI */
NULL, /* getMaxVcpus */
xenProxyNodeGetInfo, /* nodeGetInfo */
xenProxyGetCapabilities, /* getCapabilities */
return VIR_DRV_OPEN_ERROR;
}
- if (!strcmp(conn->driver->name, "QEMU")) {
+ if (STREQ (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 VIR_DRV_OPEN_SUCCESS;
+ } else if (STREQ (conn->driver->name, "remote")) {
+ /* Remote has its own network driver. */
+ return VIR_DRV_OPEN_SUCCESS;
} else {
/* Non-QEMU driver is active - open a new connection */
const char *drvname = geteuid() == 0 ? "qemu:///system" : "qemu:///session";
static int
qemuNetworkClose (virConnectPtr conn)
{
- qemuNetworkPrivatePtr netpriv = (qemuNetworkPrivatePtr) conn->networkPrivateData;
+ if (STRNEQ (conn->driver->name, "remote")) {
+ qemuNetworkPrivatePtr netpriv =
+ (qemuNetworkPrivatePtr) conn->networkPrivateData;
- if (!netpriv->shared)
- close(netpriv->qemud_fd);
- free(netpriv);
- conn->networkPrivateData = NULL;
+ if (!netpriv->shared)
+ close(netpriv->qemud_fd);
+ free(netpriv);
+ conn->networkPrivateData = NULL;
+ }
return 0;
}
qemuClose, /* close */
NULL, /* type */
qemuGetVersion, /* version */
+ NULL, /* hostname */
+ NULL, /* URI */
NULL, /* getMaxVcpus */
qemuNodeGetInfo, /* nodeGetInfo */
qemuGetCapabilities, /* getCapabilities */
gnutls_session_t session; /* GnuTLS session (if uses_tls != 0). */
char *type; /* Cached return from remoteType. */
int counter; /* Generates serial numbers for RPC. */
+ char *uri; /* Original (remote) URI. */
};
#define GET_PRIVATE(conn,retcode) \
return VIR_DRV_OPEN_ERROR;
}
- /* Return code from this function, and the private data. */
- int retcode = VIR_DRV_OPEN_ERROR;
- struct private_data priv = { .magic = DEAD, .sock = -1 };
+ /* Local variables which we will initialise. These can
+ * get freed in the failed: path.
+ */
char *name = 0, *command = 0, *sockname = 0, *netcat = 0, *username = 0;
- char *server, *port;
+ char *server = 0, *port = 0;
int no_verify = 0;
char **cmd_argv = 0;
+ /* Return code from this function, and the private data. */
+ int retcode = VIR_DRV_OPEN_ERROR;
+ struct private_data priv = { .magic = DEAD, .sock = -1 };
+
/* Remote server defaults to "localhost" if not specified. */
server = strdup (uri->server ? uri->server : "localhost");
if (!server) {
out_of_memory:
- error (NULL, VIR_ERR_NO_MEMORY, "remote_open");
+ error (NULL, VIR_ERR_NO_MEMORY, "duplicating server name");
goto failed;
}
if (uri->port != 0) {
error (NULL, VIR_ERR_NO_MEMORY, "malloc");
goto failed;
}
+ /* Duplicate and save the uri_str. */
+ priv.uri = strdup (uri_str);
+ if (!priv.uri) {
+ error (NULL, VIR_ERR_NO_MEMORY, "allocating priv->uri");
+ free (conn->privateData);
+ goto failed;
+ }
+
priv.magic = MAGIC;
memcpy (conn->privateData, &priv, sizeof priv);
/* See comment for remoteType. */
if (priv->type) free (priv->type);
+ /* Free URI copy. */
+ if (priv->uri) free (priv->uri);
+
+ /* Free private data. */
+ priv->magic = DEAD;
+ free (conn->privateData);
+
return 0;
}
return 0;
}
+static char *
+remoteGetHostname (virConnectPtr conn)
+{
+ remote_get_hostname_ret ret;
+ GET_PRIVATE (conn, NULL);
+
+ memset (&ret, 0, sizeof ret);
+ if (call (conn, priv, 0, REMOTE_PROC_GET_HOSTNAME,
+ (xdrproc_t) xdr_void, (char *) NULL,
+ (xdrproc_t) xdr_remote_get_hostname_ret, (char *) &ret) == -1)
+ return NULL;
+
+ /* Caller frees this. */
+ return ret.hostname;
+}
+
+/* This call is unusual because it doesn't go over RPC. The
+ * full URI is known (only) at the client end of the connection.
+ */
+static char *
+remoteGetURI (virConnectPtr conn)
+{
+ GET_PRIVATE (conn, NULL);
+ char *str;
+
+ str = strdup (priv->uri);
+ if (str == NULL) {
+ error (conn, VIR_ERR_SYSTEM_ERROR, strerror (errno));
+ return NULL;
+ }
+ return str;
+}
+
static int
remoteGetMaxVcpus (virConnectPtr conn, const char *type)
{
.close = remoteClose,
.type = remoteType,
.version = remoteVersion,
+ .getHostname = remoteGetHostname,
+ .getURI = remoteGetURI,
.getMaxVcpus = remoteGetMaxVcpus,
.nodeGetInfo = remoteNodeGetInfo,
.getCapabilities = remoteGetCapabilities,
*/
#ifdef WITH_TEST
+
+#define _GNU_SOURCE /* for asprintf */
+
#include <stdio.h>
#include <string.h>
#include <sys/time.h>
+#include <errno.h>
#include <libxml/parser.h>
#include <libxml/tree.h>
#include <libxml/xpath.h>
int testClose (virConnectPtr conn);
int testGetVersion(virConnectPtr conn,
unsigned long *hvVer);
+char *testGetHostname (virConnectPtr conn);
+char *testGetURI (virConnectPtr conn);
int testNodeGetInfo(virConnectPtr conn,
virNodeInfoPtr info);
char *testGetCapabilities (virConnectPtr conn);
testClose, /* close */
NULL, /* type */
testGetVersion, /* version */
+ testGetHostname, /* hostname */
+ testGetURI, /* URI */
NULL, /* getMaxVcpus */
testNodeGetInfo, /* nodeGetInfo */
testGetCapabilities, /* getCapabilities */
/* Per-connection private data. */
struct _testPrivate {
int handle;
+ char *path;
};
typedef struct _testPrivate *testPrivatePtr;
}
/* Allocate per-connection private data. */
- priv = conn->privateData = malloc (sizeof (struct _testPrivate));
+ priv = conn->privateData = calloc (1, sizeof (struct _testPrivate));
if (!priv) {
testError(NULL, NULL, VIR_ERR_NO_MEMORY, _("allocating private data"));
return VIR_DRV_OPEN_ERROR;
}
priv->handle = -1;
+ priv->path = strdup (uri->path);
+ if (!priv->path) {
+ testError (NULL, NULL, VIR_ERR_NO_MEMORY, _("allocating path"));
+ return VIR_DRV_OPEN_ERROR;
+ }
if (strcmp(uri->path, "/default") == 0) {
ret = testOpenDefault(conn,
memset (con, 0, sizeof *con); // RWMJ - why?
}
+ free (priv->path);
free (priv);
return 0;
}
return (0);
}
+char *
+testGetHostname (virConnectPtr conn)
+{
+ int r;
+ char hostname [HOST_NAME_MAX+1], *str;
+
+ r = gethostname (hostname, HOST_NAME_MAX+1);
+ if (r == -1) {
+ testError (conn, NULL, VIR_ERR_SYSTEM_ERROR, strerror (errno));
+ return NULL;
+ }
+ str = strdup (hostname);
+ if (str == NULL) {
+ testError (conn, NULL, VIR_ERR_SYSTEM_ERROR, strerror (errno));
+ return NULL;
+ }
+ return str;
+}
+
+char *
+testGetURI (virConnectPtr conn)
+{
+ testPrivatePtr priv = (testPrivatePtr) conn->privateData;
+ char *uri;
+
+ if (asprintf (&uri, "test://%s", priv->path) == -1) {
+ testError (conn, NULL, VIR_ERR_SYSTEM_ERROR, strerror (errno));
+ return NULL;
+ }
+ return uri;
+}
+
int testNodeGetInfo(virConnectPtr conn,
virNodeInfoPtr info)
{
}
/*
- * "dumpxml" command
+ * "hostname" command
+ */
+static vshCmdInfo info_hostname[] = {
+ {"syntax", "hostname"},
+ {"help", gettext_noop("print the hypervisor hostname")},
+ {NULL, NULL}
+};
+
+static int
+cmdHostname (vshControl *ctl, vshCmd *cmd ATTRIBUTE_UNUSED)
+{
+ char *hostname;
+
+ if (!vshConnectionUsability(ctl, ctl->conn, TRUE))
+ return FALSE;
+
+ hostname = virConnectGetHostname (ctl->conn);
+ if (hostname == NULL) {
+ vshError(ctl, FALSE, _("failed to get hostname"));
+ return FALSE;
+ }
+
+ vshPrint (ctl, "%s\n", hostname);
+ free (hostname);
+
+ return TRUE;
+}
+
+/*
+ * "uri" command
+ */
+static vshCmdInfo info_uri[] = {
+ {"syntax", "uri"},
+ {"help", gettext_noop("print the hypervisor canonical URI")},
+ {NULL, NULL}
+};
+
+static int
+cmdURI (vshControl *ctl, vshCmd *cmd ATTRIBUTE_UNUSED)
+{
+ char *uri;
+
+ if (!vshConnectionUsability(ctl, ctl->conn, TRUE))
+ return FALSE;
+
+ uri = virConnectGetURI (ctl->conn);
+ if (uri == NULL) {
+ vshError(ctl, FALSE, _("failed to get URI"));
+ return FALSE;
+ }
+
+ vshPrint (ctl, "%s\n", uri);
+ free (uri);
+
+ return TRUE;
+}
+
+/*
+ * "vncdisplay" command
*/
static vshCmdInfo info_vncdisplay[] = {
{"syntax", "vncdisplay <domain>"},
{"domname", cmdDomname, opts_domname, info_domname},
{"domstate", cmdDomstate, opts_domstate, info_domstate},
{"dumpxml", cmdDumpXML, opts_dumpxml, info_dumpxml},
+ {"hostname", cmdHostname, NULL, info_hostname},
{"list", cmdList, opts_list, info_list},
{"net-autostart", cmdNetworkAutostart, opts_network_autostart, info_network_autostart},
{"net-create", cmdNetworkCreate, opts_network_create, info_network_create},
{"setvcpus", cmdSetvcpus, opts_setvcpus, info_setvcpus},
{"suspend", cmdSuspend, opts_suspend, info_suspend},
{"undefine", cmdUndefine, opts_undefine, info_undefine},
+ {"uri", cmdURI, NULL, info_uri},
{"vcpuinfo", cmdVcpuinfo, opts_vcpuinfo, info_vcpuinfo},
{"vcpupin", cmdVcpupin, opts_vcpupin, info_vcpupin},
{"version", cmdVersion, NULL, info_version},
xenHypervisorClose, /* close */
xenHypervisorGetType, /* type */
xenHypervisorGetVersion, /* version */
+ NULL, /* hostname */
+ NULL, /* URI */
xenHypervisorGetMaxVcpus, /* getMaxVcpus */
NULL, /* nodeGetInfo */
xenHypervisorGetCapabilities, /* getCapabilities */
#include <stdint.h>
#include <unistd.h>
#include <string.h>
+#include <errno.h>
#include <sys/types.h>
#include <xen/dom0_ops.h>
#include <libxml/uri.h>
xmlFreeURI(uri);
/* Allocate per-connection private data. */
- priv = malloc (sizeof *priv);
+ priv = calloc (1, sizeof *priv);
if (!priv) {
xenUnifiedError (NULL, VIR_ERR_NO_MEMORY, "allocating private data");
return VIR_DRV_OPEN_ERROR;
}
conn->privateData = priv;
+ priv->name = strdup (name);
+ if (!priv->name) {
+ xenUnifiedError (NULL, VIR_ERR_NO_MEMORY, "allocating priv->name");
+ free (priv);
+ return VIR_DRV_OPEN_ERROR;
+ }
+
priv->handle = -1;
priv->xendConfigVersion = -1;
priv->type = -1;
if (!priv->opened[i] && (getuid() == 0 || i == proxy_offset)) {
for (j = 0; j < i; ++j)
if (priv->opened[j]) drivers[j]->close (conn);
+ free (priv->name);
+ free (priv);
+ /* The assumption is that one of the underlying drivers
+ * has set virterror already.
+ */
return VIR_DRV_OPEN_ERROR;
}
}
if (priv->opened[i] && drivers[i]->close)
(void) drivers[i]->close (conn);
+ free (priv->name);
free (conn->privateData);
conn->privateData = NULL;
return -1;
}
+/* NB: Even if connected to the proxy, we're still on the
+ * same machine.
+ */
+static char *
+xenUnifiedGetHostname (virConnectPtr conn)
+{
+ int r;
+ char hostname [HOST_NAME_MAX+1], *str;
+
+ r = gethostname (hostname, HOST_NAME_MAX+1);
+ if (r == -1) {
+ xenUnifiedError (conn, VIR_ERR_SYSTEM_ERROR, strerror (errno));
+ return NULL;
+ }
+ str = strdup (hostname);
+ if (str == NULL) {
+ xenUnifiedError (conn, VIR_ERR_SYSTEM_ERROR, strerror (errno));
+ return NULL;
+ }
+ return str;
+}
+
+/* The name is recorded (canonicalised) in xenUnifiedOpen. */
+static char *
+xenUnifiedGetURI (virConnectPtr conn)
+{
+ GET_PRIVATE(conn);
+ char *str;
+
+ str = strdup (priv->name);
+ if (str == NULL) {
+ xenUnifiedError (conn, VIR_ERR_SYSTEM_ERROR, strerror (errno));
+ return NULL;
+ }
+ return str;
+}
+
static int
xenUnifiedGetMaxVcpus (virConnectPtr conn, const char *type)
{
.close = xenUnifiedClose,
.type = xenUnifiedType,
.version = xenUnifiedVersion,
+ .getHostname = xenUnifiedGetHostname,
+ .getURI = xenUnifiedGetURI,
.getMaxVcpus = xenUnifiedGetMaxVcpus,
.nodeGetInfo = xenUnifiedNodeGetInfo,
.getCapabilities = xenUnifiedGetCapabilities,
* xen_unified.c.
*/
int opened[XEN_UNIFIED_NR_DRIVERS];
+
+ /* Canonical URI. */
+ char *name;
};
typedef struct _xenUnifiedPrivate *xenUnifiedPrivatePtr;
xenDaemonClose, /* close */
xenDaemonGetType, /* type */
xenDaemonGetVersion, /* version */
+ NULL, /* hostname */
+ NULL, /* URI */
NULL, /* getMaxVcpus */
xenDaemonNodeGetInfo, /* nodeGetInfo */
NULL, /* getCapabilities */
xenXMClose, /* close */
xenXMGetType, /* type */
NULL, /* version */
+ NULL, /* hostname */
+ NULL, /* URI */
NULL, /* getMaxVcpus */
NULL, /* nodeGetInfo */
NULL, /* getCapabilities */
xenStoreClose, /* close */
NULL, /* type */
NULL, /* version */
+ NULL, /* hostname */
+ NULL, /* URI */
NULL, /* getMaxVcpus */
NULL, /* nodeGetInfo */
NULL, /* getCapabilities */