]> git.ipfire.org Git - thirdparty/libvirt.git/commitdiff
Tue Jun 26 12:40:00 BST 2007 Richard W.M. Jones <rjones@redhat.com>
authorRichard W.M. Jones <rjones@redhat.com>
Tue, 26 Jun 2007 11:42:46 +0000 (11:42 +0000)
committerRichard W.M. Jones <rjones@redhat.com>
Tue, 26 Jun 2007 11:42:46 +0000 (11:42 +0000)
* include/libvirt/libvirt.h.in, src/libvirt.c: (and numerous
  other files) Added support for virConnectGetHostname
  and virConnectGetURI calls.

25 files changed:
ChangeLog
include/libvirt/libvirt.h
include/libvirt/libvirt.h.in
qemud/remote.c
qemud/remote_dispatch_localvars.h
qemud/remote_dispatch_proc_switch.h
qemud/remote_dispatch_prototypes.h
qemud/remote_protocol.c
qemud/remote_protocol.h
qemud/remote_protocol.x
src/driver.h
src/internal.h
src/libvirt.c
src/libvirt_sym.version
src/proxy_internal.c
src/qemu_internal.c
src/remote_internal.c
src/test.c
src/virsh.c
src/xen_internal.c
src/xen_unified.c
src/xen_unified.h
src/xend_internal.c
src/xm_internal.c
src/xs_internal.c

index 426ca509cd75e82e0efe6d0f728292da1da759cd..cbc76d2b7944dac635315c9809a77f7e87077170 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,9 @@
+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,
index f73354136613b0ba5588eef9a2e56798ab5c1c21..3995c4bab2a0827244469b2eedeba4b919550ecb 100644 (file)
@@ -272,6 +272,10 @@ int                        virConnectClose         (virConnectPtr conn);
 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 9f5e07099957cfa4004f9f3c692ca204cf97835e..9f332e44e658c7378abb3a88e5703d7e732dbc90 100644 (file)
@@ -272,6 +272,10 @@ int                        virConnectClose         (virConnectPtr conn);
 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 f204326bb935f08e0f2e6df299e10d795b443375..e53e883e5d49764c6083d79c9739a0fd4ae43c08 100644 (file)
@@ -459,6 +459,22 @@ remoteDispatchGetVersion (struct qemud_client *client,
     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,
index a7a00e727565277ba88235fb1ab45c840990b272..f782cfd6e280b2b67406d316fb34f4f1b6f962a4 100644 (file)
@@ -20,6 +20,7 @@ remote_domain_get_os_type_ret lv_remote_domain_get_os_type_ret;
 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;
index e00c897357c3b388a4f634906304910b9b96a45d..b501d2c7703b9efd2a0db31a7af6e029e8a48101 100644 (file)
@@ -245,6 +245,12 @@ case REMOTE_PROC_GET_CAPABILITIES:
        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;
index 67e01d76ce07a6900575b7f35adfc5e31f6a634b..05344f6351d20efc39843252d9bf1312011d9e5c 100644 (file)
@@ -36,6 +36,7 @@ static int remoteDispatchDomainShutdown (struct qemud_client *client, remote_mes
 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);
index ddbf3451398b054a64e5c728974996923e9eb50c..aa3350753039ec015ba29d9a34101f28efcd9f0e 100644 (file)
@@ -195,6 +195,15 @@ xdr_remote_get_version_ret (XDR *xdrs, remote_get_version_ret *objp)
        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)
 {
index ee3d1b098185ae5e8564bb84d2654b1c2d0c5f1f..51376143cfaf782bf0a4c49c062d873ca086b8c2 100644 (file)
@@ -105,6 +105,11 @@ struct remote_get_version_ret {
 };
 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;
 };
@@ -626,6 +631,7 @@ enum remote_procedure {
        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;
 
@@ -669,6 +675,7 @@ extern  bool_t xdr_remote_sched_param (XDR *, remote_sched_param*);
 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*);
@@ -769,6 +776,7 @@ extern bool_t xdr_remote_sched_param ();
 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 ();
index 6343f7aebba2436e65d4e1aab691171c53150374..4470f557cf9ce7b059c262150f94a23e842cd5c2 100644 (file)
@@ -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 e3ed93b32b6ac0eca2b5711dd6d6708ee05305cc..077a4b4a4be22483ffb024e505edb4c26f24983a 100644 (file)
@@ -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 51f5349d7820a563bd9734395e9a7227ac7ecf98..a0a074de52dba8b70f16717b867d607a22856f40 100644 (file)
@@ -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 f50c91926fc51eaa4bbc614e5e940f82dfae6ffe..e473e533bf1ff364c4fce096f2e05991aef0325b 100644 (file)
@@ -465,6 +465,63 @@ virConnectGetVersion(virConnectPtr conn, unsigned long *hvVer)
     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
index 9b9f18954221feafde88e0b428bee2bb09f6293b..01441491e7c4dd6486be491fa060e2eed578b9b0 100644 (file)
@@ -6,6 +6,8 @@
        virConnectClose;
        virConnectGetType;
        virConnectGetVersion;
+       virConnectGetHostname;
+       virConnectGetURI;
        virDomainGetConnect;
        virConnectListDomains;
        virConnectNumOfDomains;
index 7f2ed69d9f213e53bba41c823325ac782f7dcdec..eca93176d2cc6c7c961cfc77a80ec74b36342438 100644 (file)
@@ -53,6 +53,8 @@ virDriver xenProxyDriver = {
     xenProxyClose, /* close */
     NULL, /* type */
     xenProxyGetVersion, /* version */
+    NULL, /* hostname */
+    NULL, /* URI */
     NULL, /* getMaxVcpus */
     xenProxyNodeGetInfo, /* nodeGetInfo */
     xenProxyGetCapabilities, /* getCapabilities */
index 644e2b09b8a62b3c22f1f90caf184a4e4f73b5f6..367f71eb41f5e090c8aa4f130668a7150a9aa731 100644 (file)
@@ -1023,13 +1023,16 @@ static int qemuNetworkOpen(virConnectPtr conn,
         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 conn,
 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;
 }
@@ -1380,6 +1386,8 @@ static virDriver qemuDriver = {
     qemuClose, /* close */
     NULL, /* type */
     qemuGetVersion, /* version */
+    NULL, /* hostname */
+    NULL, /* URI */
     NULL, /* getMaxVcpus */
     qemuNodeGetInfo, /* nodeGetInfo */
     qemuGetCapabilities, /* getCapabilities */
index 21bc0631f73acb84a598f97f7eaef372f398fd91..31db7a1a80d8ecdf527b7bfa7c7548f676d950b7 100644 (file)
@@ -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 char *uri_str, int flags)
         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 char *uri_str, int flags)
         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, unsigned long *hvVer)
     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 723d7e7ad8866c71d6c718b79795a7232617c44c..2a1cc58ba2213b77c05c684f5e9f46e16565a07f 100644 (file)
  */
 
 #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 ATTRIBUTE_UNUSED,
     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 0362bf7892b3877a3b922e5bf03e5859254f324b..9e837beaf5b6934deef66cc708298149805429a6 100644 (file)
@@ -2588,7 +2588,65 @@ cmdVersion(vshControl * ctl, vshCmd * cmd ATTRIBUTE_UNUSED)
 }
 
 /*
- * "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 36c1374cf9156dc0fe99c9b076f61da3ef8bd0f8..75a6c4d43d6d65a4eca32a36cc14fc0ac60f078f 100644 (file)
@@ -597,6 +597,8 @@ virDriver xenHypervisorDriver = {
     xenHypervisorClose, /* close */
     xenHypervisorGetType, /* type */
     xenHypervisorGetVersion, /* version */
+    NULL, /* hostname */
+    NULL, /* URI */
     xenHypervisorGetMaxVcpus, /* getMaxVcpus */
     NULL, /* nodeGetInfo */
     xenHypervisorGetCapabilities, /* getCapabilities */
index cc10a4fe5e2e66112efd44f58e2753514d8c7b82..ba1e7606fe025b947386756f359e019ee9ec9df7 100644 (file)
@@ -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, const char *name, int flags)
     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, const char *name, int flags)
         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, unsigned long *hvVer)
     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 815722b03deebc158b8316192414ab0e61362d03..f17ec5cbd3c015649c177864aab30658a844800d 100644 (file)
@@ -50,6 +50,9 @@ struct _xenUnifiedPrivate {
      * xen_unified.c.
      */
     int opened[XEN_UNIFIED_NR_DRIVERS];
+
+    /* Canonical URI. */
+    char *name;
 };
 
 typedef struct _xenUnifiedPrivate *xenUnifiedPrivatePtr;
index 7885484be183d5ea0310d3ef9738715bfa21f656..27abafa03fb622c14ba32d3e7e828ce5c9f4f792 100644 (file)
@@ -73,6 +73,8 @@ virDriver xenDaemonDriver = {
     xenDaemonClose, /* close */
     xenDaemonGetType, /* type */
     xenDaemonGetVersion, /* version */
+    NULL, /* hostname */
+    NULL, /* URI */
     NULL, /* getMaxVcpus */
     xenDaemonNodeGetInfo, /* nodeGetInfo */
     NULL, /* getCapabilities */
index e44fd2232e0d5aa8c7286fd9c65ce5c30c089e5c..04fd6611a76cbbd4ad7963168d953f3634665b72 100644 (file)
@@ -81,6 +81,8 @@ virDriver xenXMDriver = {
     xenXMClose, /* close */
     xenXMGetType, /* type */
     NULL, /* version */
+    NULL, /* hostname */
+    NULL, /* URI */
     NULL, /* getMaxVcpus */
     NULL, /* nodeGetInfo */
     NULL, /* getCapabilities */
index ace3ee0a27f5bcfe69c64bebc3d6bc2cb62ed10a..264959cb13a85a1cc537567026b2408d16ac0bae 100644 (file)
@@ -46,6 +46,8 @@ virDriver xenStoreDriver = {
     xenStoreClose, /* close */
     NULL, /* type */
     NULL, /* version */
+    NULL, /* hostname */
+    NULL, /* URI */
     NULL, /* getMaxVcpus */
     NULL, /* nodeGetInfo */
     NULL, /* getCapabilities */