[PATCH] Add virConnectGetHostname and virConnectGetURI calls, virsh commands, and some related fixes

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

 



This patch adds two calls:

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

and:

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

It also fixes a kind of accidental memory leak which turns out not to be a memory leak. In the current version of libvirt CVS, when using remote connections, remote's private data is not freed by remote_internal.c. However it turns out that it _is_ freed by qemuNetworkClose. Obviously some confusion there, but this patch fixes that. (Fixing that is a dependency of this patch, which is why the two are done together in one patch).

I've added "virsh hostname" and "virsh uri" commands:

$ src/virsh -c test:///default uri
test:///default

$ src/virsh -c test:///default hostname
localhost.localdomain

(Yeah, I haven't set the hostname on this machine ...)

I've updated the Xen, test and remote drivers to support the calls. However I didn't update qemu because of Dan's big changes to qemu. Once we have decided whether to put in Dan's changes, I'll go back and implement this for qemu. (I'm actually not sure I would need to implement them, if remote supports the calls already).

I haven't updated the Python bindings, but will do so next.

I decided not to implement the proposed virConnectGetTransport call because I think it needs more thought. It would obviously be useful to find out whether the current connection is local or remote, encrypted or unencrypted, authenticated or unauthenticated, because all of these things could be usefully communicated back to the user by icons in virt-manager. Simply returning the transport name doesn't really do this. The user might also want to find out _how_ the session is encrypted (what TLS parameters are in use), and again a simple string can't do that.

Before applying this patch you will need to do:

  rm qemud/remote_dispatch_localvars.h \
    qemud/remote_dispatch_proc_switch.h \
    qemud/remote_dispatch_prototypes.h \
    qemud/remote_protocol.c \
    qemud/remote_protocol.h

and after applying you will need to do:

  make -C qemud remote_protocol.c

Rich.

--
Emerging Technologies, Red Hat - http://et.redhat.com/~rjones/
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. 03798903
Index: include/libvirt/libvirt.h
===================================================================
RCS file: /data/cvs/libvirt/include/libvirt/libvirt.h,v
retrieving revision 1.47
diff -u -p -r1.47 libvirt.h
--- include/libvirt/libvirt.h	25 Jun 2007 15:56:18 -0000	1.47
+++ include/libvirt/libvirt.h	26 Jun 2007 09:50:51 -0000
@@ -272,6 +272,10 @@ int			virConnectClose		(virConnectPtr co
 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.
  */
Index: include/libvirt/libvirt.h.in
===================================================================
RCS file: /data/cvs/libvirt/include/libvirt/libvirt.h.in,v
retrieving revision 1.29
diff -u -p -r1.29 libvirt.h.in
--- include/libvirt/libvirt.h.in	25 Jun 2007 15:56:18 -0000	1.29
+++ include/libvirt/libvirt.h.in	26 Jun 2007 09:50:52 -0000
@@ -272,6 +272,10 @@ int			virConnectClose		(virConnectPtr co
 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.
  */
Index: qemud/remote.c
===================================================================
RCS file: /data/cvs/libvirt/qemud/remote.c,v
retrieving revision 1.3
diff -u -p -r1.3 remote.c
--- qemud/remote.c	25 Jun 2007 08:23:10 -0000	1.3
+++ qemud/remote.c	26 Jun 2007 09:50:53 -0000
@@ -460,6 +460,22 @@ remoteDispatchGetVersion (struct qemud_c
 }
 
 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_get_max_vcpus_args *args,
Index: qemud/remote_protocol.x
===================================================================
RCS file: /data/cvs/libvirt/qemud/remote_protocol.x,v
retrieving revision 1.2
diff -u -p -r1.2 remote_protocol.x
--- qemud/remote_protocol.x	22 Jun 2007 13:16:10 -0000	1.2
+++ qemud/remote_protocol.x	26 Jun 2007 09:50:53 -0000
@@ -178,6 +178,10 @@ struct remote_get_version_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.
@@ -605,7 +609,8 @@ enum remote_procedure {
     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. */
Index: src/driver.h
===================================================================
RCS file: /data/cvs/libvirt/src/driver.h,v
retrieving revision 1.28
diff -u -p -r1.28 driver.h
--- src/driver.h	11 Jun 2007 11:43:41 -0000	1.28
+++ src/driver.h	26 Jun 2007 09:50:53 -0000
@@ -54,6 +54,10 @@ typedef const char *
 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);
@@ -199,6 +203,8 @@ struct _virDriver {
 	virDrvClose			close;
 	virDrvGetType			type;
 	virDrvGetVersion		version;
+    virDrvGetHostname       getHostname;
+    virDrvGetURI            getURI;
 	virDrvGetMaxVcpus		getMaxVcpus;
 	virDrvNodeGetInfo		nodeGetInfo;
 	virDrvGetCapabilities		getCapabilities;
Index: src/internal.h
===================================================================
RCS file: /data/cvs/libvirt/src/internal.h,v
retrieving revision 1.43
diff -u -p -r1.43 internal.h
--- src/internal.h	22 Jun 2007 11:42:22 -0000	1.43
+++ src/internal.h	26 Jun 2007 09:50:54 -0000
@@ -34,6 +34,8 @@ extern "C" {
 /* 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:
Index: src/libvirt.c
===================================================================
RCS file: /data/cvs/libvirt/src/libvirt.c,v
retrieving revision 1.79
diff -u -p -r1.79 libvirt.c
--- src/libvirt.c	25 Jun 2007 15:56:18 -0000	1.79
+++ src/libvirt.c	26 Jun 2007 09:50:55 -0000
@@ -466,6 +466,63 @@ virConnectGetVersion(virConnectPtr conn,
 }
 
 /**
+ * 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
  * @type: value of the 'type' attribute in the <domain> element
Index: src/libvirt_sym.version
===================================================================
RCS file: /data/cvs/libvirt/src/libvirt_sym.version,v
retrieving revision 1.22
diff -u -p -r1.22 libvirt_sym.version
--- src/libvirt_sym.version	25 Jun 2007 15:56:18 -0000	1.22
+++ src/libvirt_sym.version	26 Jun 2007 09:50:55 -0000
@@ -6,6 +6,8 @@
 	virConnectClose;
 	virConnectGetType;
 	virConnectGetVersion;
+	virConnectGetHostname;
+	virConnectGetURI;
 	virDomainGetConnect;
 	virConnectListDomains;
 	virConnectNumOfDomains;
Index: src/proxy_internal.c
===================================================================
RCS file: /data/cvs/libvirt/src/proxy_internal.c,v
retrieving revision 1.30
diff -u -p -r1.30 proxy_internal.c
--- src/proxy_internal.c	15 Jun 2007 15:24:20 -0000	1.30
+++ src/proxy_internal.c	26 Jun 2007 09:50:56 -0000
@@ -53,6 +53,8 @@ virDriver xenProxyDriver = {
     xenProxyClose, /* close */
     NULL, /* type */
     xenProxyGetVersion, /* version */
+    NULL, /* hostname */
+    NULL, /* URI */
     NULL, /* getMaxVcpus */
     xenProxyNodeGetInfo, /* nodeGetInfo */
     xenProxyGetCapabilities, /* getCapabilities */
Index: src/qemu_internal.c
===================================================================
RCS file: /data/cvs/libvirt/src/qemu_internal.c,v
retrieving revision 1.28
diff -u -p -r1.28 qemu_internal.c
--- src/qemu_internal.c	20 Jun 2007 17:25:39 -0000	1.28
+++ src/qemu_internal.c	26 Jun 2007 09:50:57 -0000
@@ -1023,13 +1023,16 @@ static int qemuNetworkOpen(virConnectPtr
         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";
@@ -1052,12 +1055,15 @@ static int qemuNetworkOpen(virConnectPtr
 static int
 qemuNetworkClose (virConnectPtr conn)
 {
-    qemuNetworkPrivatePtr netpriv = (qemuNetworkPrivatePtr) conn->networkPrivateData;
-
-    if (!netpriv->shared)
-        close(netpriv->qemud_fd);
-    free(netpriv);
-    conn->networkPrivateData = NULL;
+    if (STRNEQ (conn->driver->name, "remote")) {
+        qemuNetworkPrivatePtr netpriv =
+            (qemuNetworkPrivatePtr) conn->networkPrivateData;
+
+        if (!netpriv->shared)
+            close(netpriv->qemud_fd);
+        free(netpriv);
+        conn->networkPrivateData = NULL;
+    }
 
     return 0;
 }
@@ -1380,6 +1386,8 @@ static virDriver qemuDriver = {
     qemuClose, /* close */
     NULL, /* type */
     qemuGetVersion, /* version */
+    NULL, /* hostname */
+    NULL, /* URI */
     NULL, /* getMaxVcpus */
     qemuNodeGetInfo, /* nodeGetInfo */
     qemuGetCapabilities, /* getCapabilities */
Index: src/remote_internal.c
===================================================================
RCS file: /data/cvs/libvirt/src/remote_internal.c,v
retrieving revision 1.7
diff -u -p -r1.7 remote_internal.c
--- src/remote_internal.c	25 Jun 2007 13:05:03 -0000	1.7
+++ src/remote_internal.c	26 Jun 2007 09:50:59 -0000
@@ -58,6 +58,7 @@ struct private_data {
     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)                                       \
@@ -148,19 +149,23 @@ remoteOpen (virConnectPtr conn, const ch
         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) {
@@ -456,6 +461,14 @@ remoteOpen (virConnectPtr conn, const ch
         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);
 
@@ -931,6 +944,13 @@ remoteClose (virConnectPtr conn)
     /* 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;
 }
 
@@ -977,6 +997,39 @@ remoteVersion (virConnectPtr conn, unsig
     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)
 {
@@ -2604,6 +2657,8 @@ static virDriver driver = {
     .close = remoteClose,
 	.type = remoteType,
 	.version = remoteVersion,
+    .getHostname = remoteGetHostname,
+    .getURI = remoteGetURI,
 	.getMaxVcpus = remoteGetMaxVcpus,
 	.nodeGetInfo = remoteNodeGetInfo,
     .getCapabilities = remoteGetCapabilities,
Index: src/test.c
===================================================================
RCS file: /data/cvs/libvirt/src/test.c,v
retrieving revision 1.35
diff -u -p -r1.35 test.c
--- src/test.c	25 Jun 2007 13:26:02 -0000	1.35
+++ src/test.c	26 Jun 2007 09:51:00 -0000
@@ -22,9 +22,13 @@
  */
 
 #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>
@@ -42,6 +46,8 @@ int testOpen(virConnectPtr conn,
 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);
@@ -96,6 +102,8 @@ static virDriver testDriver = {
     testClose, /* close */
     NULL, /* type */
     testGetVersion, /* version */
+    testGetHostname, /* hostname */
+    testGetURI, /* URI */
     NULL, /* getMaxVcpus */
     testNodeGetInfo, /* nodeGetInfo */
     testGetCapabilities, /* getCapabilities */
@@ -140,6 +148,7 @@ static virDriver testDriver = {
 /* Per-connection private data. */
 struct _testPrivate {
     int handle;
+    char *path;
 };
 typedef struct _testPrivate *testPrivatePtr;
 
@@ -748,12 +757,17 @@ int testOpen(virConnectPtr conn,
     }
 
     /* 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,
@@ -792,6 +806,7 @@ int testClose(virConnectPtr conn)
         memset (con, 0, sizeof *con); // RWMJ - why?
     }
 
+    free (priv->path);
     free (priv);
     return 0;
 }
@@ -803,6 +818,38 @@ int testGetVersion(virConnectPtr conn AT
     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)
 {
Index: src/virsh.c
===================================================================
RCS file: /data/cvs/libvirt/src/virsh.c,v
retrieving revision 1.88
diff -u -p -r1.88 virsh.c
--- src/virsh.c	20 Jun 2007 17:22:09 -0000	1.88
+++ src/virsh.c	26 Jun 2007 09:51:02 -0000
@@ -2588,7 +2588,65 @@ cmdVersion(vshControl * ctl, vshCmd * cm
 }
 
 /*
- * "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>"},
@@ -3330,6 +3388,7 @@ static vshCmdDef commands[] = {
     {"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},
@@ -3355,6 +3414,7 @@ static vshCmdDef commands[] = {
     {"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},
Index: src/xen_internal.c
===================================================================
RCS file: /data/cvs/libvirt/src/xen_internal.c,v
retrieving revision 1.80
diff -u -p -r1.80 xen_internal.c
--- src/xen_internal.c	22 Jun 2007 11:42:22 -0000	1.80
+++ src/xen_internal.c	26 Jun 2007 09:51:04 -0000
@@ -597,6 +597,8 @@ virDriver xenHypervisorDriver = {
     xenHypervisorClose, /* close */
     xenHypervisorGetType, /* type */
     xenHypervisorGetVersion, /* version */
+    NULL, /* hostname */
+    NULL, /* URI */
     xenHypervisorGetMaxVcpus, /* getMaxVcpus */
     NULL, /* nodeGetInfo */
     xenHypervisorGetCapabilities, /* getCapabilities */
Index: src/xen_unified.c
===================================================================
RCS file: /data/cvs/libvirt/src/xen_unified.c,v
retrieving revision 1.13
diff -u -p -r1.13 xen_unified.c
--- src/xen_unified.c	25 Jun 2007 08:23:10 -0000	1.13
+++ src/xen_unified.c	26 Jun 2007 09:51:05 -0000
@@ -28,6 +28,7 @@
 #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>
@@ -129,13 +130,20 @@ xenUnifiedOpen (virConnectPtr conn, cons
     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;
@@ -165,6 +173,11 @@ xenUnifiedOpen (virConnectPtr conn, cons
         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;
         }
     }
@@ -185,6 +198,7 @@ xenUnifiedClose (virConnectPtr conn)
         if (priv->opened[i] && drivers[i]->close)
             (void) drivers[i]->close (conn);
 
+    free (priv->name);
     free (conn->privateData);
     conn->privateData = NULL;
 
@@ -222,6 +236,43 @@ xenUnifiedVersion (virConnectPtr conn, u
     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)
 {
@@ -850,6 +901,8 @@ static virDriver xenUnifiedDriver = {
     .close 			= xenUnifiedClose,
     .type 			= xenUnifiedType,
     .version 			= xenUnifiedVersion,
+    .getHostname    = xenUnifiedGetHostname,
+    .getURI         = xenUnifiedGetURI,
     .getMaxVcpus 			= xenUnifiedGetMaxVcpus,
     .nodeGetInfo 			= xenUnifiedNodeGetInfo,
     .getCapabilities 		= xenUnifiedGetCapabilities,
Index: src/xen_unified.h
===================================================================
RCS file: /data/cvs/libvirt/src/xen_unified.h,v
retrieving revision 1.3
diff -u -p -r1.3 xen_unified.h
--- src/xen_unified.h	30 Apr 2007 16:57:15 -0000	1.3
+++ src/xen_unified.h	26 Jun 2007 09:51:05 -0000
@@ -50,6 +50,9 @@ struct _xenUnifiedPrivate {
      * xen_unified.c.
      */
     int opened[XEN_UNIFIED_NR_DRIVERS];
+
+    /* Canonical URI. */
+    char *name;
 };
 
 typedef struct _xenUnifiedPrivate *xenUnifiedPrivatePtr;
Index: src/xend_internal.c
===================================================================
RCS file: /data/cvs/libvirt/src/xend_internal.c,v
retrieving revision 1.123
diff -u -p -r1.123 xend_internal.c
--- src/xend_internal.c	21 Jun 2007 15:49:09 -0000	1.123
+++ src/xend_internal.c	26 Jun 2007 09:51:07 -0000
@@ -73,6 +73,8 @@ virDriver xenDaemonDriver = {
     xenDaemonClose, /* close */
     xenDaemonGetType, /* type */
     xenDaemonGetVersion, /* version */
+    NULL, /* hostname */
+    NULL, /* URI */
     NULL, /* getMaxVcpus */
     xenDaemonNodeGetInfo, /* nodeGetInfo */
     NULL, /* getCapabilities */
Index: src/xm_internal.c
===================================================================
RCS file: /data/cvs/libvirt/src/xm_internal.c,v
retrieving revision 1.31
diff -u -p -r1.31 xm_internal.c
--- src/xm_internal.c	15 Jun 2007 15:24:20 -0000	1.31
+++ src/xm_internal.c	26 Jun 2007 09:51:08 -0000
@@ -81,6 +81,8 @@ virDriver xenXMDriver = {
     xenXMClose, /* close */
     xenXMGetType, /* type */
     NULL, /* version */
+    NULL, /* hostname */
+    NULL, /* URI */
     NULL, /* getMaxVcpus */
     NULL, /* nodeGetInfo */
     NULL, /* getCapabilities */
Index: src/xs_internal.c
===================================================================
RCS file: /data/cvs/libvirt/src/xs_internal.c,v
retrieving revision 1.43
diff -u -p -r1.43 xs_internal.c
--- src/xs_internal.c	5 Jun 2007 12:06:09 -0000	1.43
+++ src/xs_internal.c	26 Jun 2007 09:51:09 -0000
@@ -46,6 +46,8 @@ virDriver xenStoreDriver = {
     xenStoreClose, /* close */
     NULL, /* type */
     NULL, /* version */
+    NULL, /* hostname */
+    NULL, /* URI */
     NULL, /* getMaxVcpus */
     NULL, /* nodeGetInfo */
     NULL, /* getCapabilities */

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


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