[libvirt] [PATCH 05/20] Secret manipulation step 5: RPC client

Miloslav Trmač mitr at redhat.com
Sun Aug 16 20:47:58 UTC 2009


Changes since the second submission:
- Update for the changed public API
- s/secret_id/uuid/g
- use "unsigned char *" for secret value
---
 src/datatypes.h       |    1 +
 src/remote_internal.c |  323 +++++++++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 324 insertions(+), 0 deletions(-)

diff --git a/src/datatypes.h b/src/datatypes.h
index 56c3777..aa60b63 100644
--- a/src/datatypes.h
+++ b/src/datatypes.h
@@ -140,6 +140,7 @@ struct _virConnect {
     void *            interfacePrivateData;
     void *            storagePrivateData;
     void *            devMonPrivateData;
+    void *            secretPrivateData;
 
     /*
      * The lock mutex must be acquired before accessing/changing
diff --git a/src/remote_internal.c b/src/remote_internal.c
index a58b768..d661fe2 100644
--- a/src/remote_internal.c
+++ b/src/remote_internal.c
@@ -221,11 +221,13 @@ static virInterfacePtr get_nonnull_interface (virConnectPtr conn, remote_nonnull
 static virStoragePoolPtr get_nonnull_storage_pool (virConnectPtr conn, remote_nonnull_storage_pool pool);
 static virStorageVolPtr get_nonnull_storage_vol (virConnectPtr conn, remote_nonnull_storage_vol vol);
 static virNodeDevicePtr get_nonnull_node_device (virConnectPtr conn, remote_nonnull_node_device dev);
+static virSecretPtr get_nonnull_secret (virConnectPtr conn, remote_nonnull_secret secret);
 static void make_nonnull_domain (remote_nonnull_domain *dom_dst, virDomainPtr dom_src);
 static void make_nonnull_network (remote_nonnull_network *net_dst, virNetworkPtr net_src);
 static void make_nonnull_interface (remote_nonnull_interface *interface_dst, virInterfacePtr interface_src);
 static void make_nonnull_storage_pool (remote_nonnull_storage_pool *pool_dst, virStoragePoolPtr vol_src);
 static void make_nonnull_storage_vol (remote_nonnull_storage_vol *vol_dst, virStorageVolPtr vol_src);
+static void make_nonnull_secret (remote_nonnull_secret *secret_dst, virSecretPtr secret_src);
 void remoteDomainEventFired(int watch, int fd, int event, void *data);
 static void remoteDomainQueueEvent(virConnectPtr conn, XDR *xdr);
 void remoteDomainEventQueueFlush(int timer, void *opaque);
@@ -6319,6 +6321,300 @@ done:
     return rv;
 }
 
+static virDrvOpenStatus
+remoteSecretOpen (virConnectPtr conn,
+                  virConnectAuthPtr auth,
+                  int flags)
+{
+    if (inside_daemon)
+        return VIR_DRV_OPEN_DECLINED;
+
+    if (conn &&
+        conn->driver &&
+        STREQ (conn->driver->name, "remote")) {
+        struct private_data *priv;
+
+        /* If we're here, the remote driver is already
+         * in use due to a) a QEMU uri, or b) a remote
+         * URI. So we can re-use existing connection
+         */
+        priv = conn->privateData;
+        remoteDriverLock(priv);
+        priv->localUses++;
+        conn->secretPrivateData = priv;
+        remoteDriverUnlock(priv);
+        return VIR_DRV_OPEN_SUCCESS;
+    } else if (conn->networkDriver &&
+               STREQ (conn->networkDriver->name, "remote")) {
+        struct private_data *priv = conn->networkPrivateData;
+        remoteDriverLock(priv);
+        conn->secretPrivateData = priv;
+        priv->localUses++;
+        remoteDriverUnlock(priv);
+        return VIR_DRV_OPEN_SUCCESS;
+    } else {
+        /* Using a non-remote driver, so we need to open a
+         * new connection for secret APIs, forcing it to
+         * use the UNIX transport.
+         */
+        struct private_data *priv;
+        int ret;
+        ret = remoteOpenSecondaryDriver(conn,
+                                        auth,
+                                        flags,
+                                        &priv);
+        if (ret == VIR_DRV_OPEN_SUCCESS)
+            conn->secretPrivateData = priv;
+        return ret;
+    }
+}
+
+static int
+remoteSecretClose (virConnectPtr conn)
+{
+    int rv = 0;
+    struct private_data *priv = conn->secretPrivateData;
+
+    conn->secretPrivateData = NULL;
+    remoteDriverLock(priv);
+    priv->localUses--;
+    if (!priv->localUses) {
+        rv = doRemoteClose(conn, priv);
+        remoteDriverUnlock(priv);
+        virMutexDestroy(&priv->lock);
+        VIR_FREE(priv);
+    }
+    if (priv)
+        remoteDriverUnlock(priv);
+    return rv;
+}
+
+static int
+remoteSecretNumOfSecrets (virConnectPtr conn)
+{
+    int rv = -1;
+    remote_num_of_secrets_ret ret;
+    struct private_data *priv = conn->secretPrivateData;
+
+    remoteDriverLock (priv);
+
+    memset (&ret, 0, sizeof (ret));
+    if (call (conn, priv, 0, REMOTE_PROC_NUM_OF_SECRETS,
+              (xdrproc_t) xdr_void, (char *) NULL,
+              (xdrproc_t) xdr_remote_num_of_secrets_ret, (char *) &ret) == -1)
+        goto done;
+
+    rv = ret.num;
+
+done:
+    remoteDriverUnlock (priv);
+    return rv;
+}
+
+static int
+remoteSecretListSecrets (virConnectPtr conn, char **uuids, int maxuuids)
+{
+    int rv = -1;
+    int i;
+    remote_list_secrets_args args;
+    remote_list_secrets_ret ret;
+    struct private_data *priv = conn->secretPrivateData;
+
+    remoteDriverLock(priv);
+
+    if (maxuuids > REMOTE_SECRET_UUID_LIST_MAX) {
+        errorf (conn, VIR_ERR_RPC, _("too many remote secret UUIDs: %d > %d"),
+                maxuuids, REMOTE_SECRET_UUID_LIST_MAX);
+        goto done;
+    }
+    args.maxuuids = maxuuids;
+
+    memset (&ret, 0, sizeof ret);
+    if (call (conn, priv, 0, REMOTE_PROC_LIST_SECRETS,
+              (xdrproc_t) xdr_remote_list_secrets_args, (char *) &args,
+              (xdrproc_t) xdr_remote_list_secrets_ret, (char *) &ret) == -1)
+        goto done;
+
+    if (ret.uuids.uuids_len > maxuuids) {
+        errorf (conn, VIR_ERR_RPC, _("too many remote secret UUIDs: %d > %d"),
+                ret.uuids.uuids_len, maxuuids);
+        goto cleanup;
+    }
+
+    /* This call is caller-frees.  However xdr_free will free up both the
+     * names and the list of pointers, so we have to strdup the
+     * names here.
+     */
+    for (i = 0; i < ret.uuids.uuids_len; ++i)
+        uuids[i] = strdup (ret.uuids.uuids_val[i]);
+
+    rv = ret.uuids.uuids_len;
+
+cleanup:
+    xdr_free ((xdrproc_t) xdr_remote_list_secrets_ret, (char *) &ret);
+
+done:
+    remoteDriverUnlock(priv);
+    return rv;
+}
+
+static virSecretPtr
+remoteSecretLookupByUUIDString (virConnectPtr conn, const char *uuid)
+{
+    virSecretPtr rv = NULL;
+    remote_secret_lookup_by_uuid_string_args args;
+    remote_secret_lookup_by_uuid_string_ret ret;
+    struct private_data *priv = conn->secretPrivateData;
+
+    remoteDriverLock (priv);
+
+    args.uuid = (char *) uuid;
+
+    memset (&ret, 0, sizeof (ret));
+    if (call (conn, priv, 0, REMOTE_PROC_SECRET_LOOKUP_BY_UUID_STRING,
+              (xdrproc_t) xdr_remote_secret_lookup_by_uuid_string_args, (char *) &args,
+              (xdrproc_t) xdr_remote_secret_lookup_by_uuid_string_ret, (char *) &ret) == -1)
+        goto done;
+
+    rv = get_nonnull_secret (conn, ret.secret);
+    xdr_free ((xdrproc_t) xdr_remote_secret_lookup_by_uuid_string_ret,
+              (char *) &ret);
+
+done:
+    remoteDriverUnlock (priv);
+    return rv;
+}
+
+static virSecretPtr
+remoteSecretDefineXML (virConnectPtr conn, const char *xml)
+{
+    virSecretPtr rv = NULL;
+    remote_secret_define_xml_args args;
+    remote_secret_lookup_by_uuid_string_ret ret;
+    struct private_data *priv = conn->secretPrivateData;
+
+    remoteDriverLock (priv);
+
+    args.xml = (char *) xml;
+
+    memset (&ret, 0, sizeof (ret));
+    if (call (conn, priv, 0, REMOTE_PROC_SECRET_DEFINE_XML,
+              (xdrproc_t) xdr_remote_secret_define_xml_args, (char *) &args,
+              (xdrproc_t) xdr_remote_secret_define_xml_ret, (char *) &ret) == -1)
+        goto done;
+
+    rv = get_nonnull_secret (conn, ret.secret);
+    xdr_free ((xdrproc_t) xdr_remote_secret_lookup_by_uuid_string_ret,
+              (char *) &ret);
+
+done:
+    remoteDriverUnlock (priv);
+    return rv;
+}
+
+static char *
+remoteSecretGetXMLDesc (virSecretPtr secret)
+{
+    char *rv = NULL;
+    remote_secret_get_xml_desc_args args;
+    remote_secret_get_xml_desc_ret ret;
+    struct private_data *priv = secret->conn->secretPrivateData;
+
+    remoteDriverLock (priv);
+
+    make_nonnull_secret (&args.secret, secret);
+
+    memset (&ret, 0, sizeof (ret));
+    if (call (secret->conn, priv, 0, REMOTE_PROC_SECRET_GET_XML_DESC,
+              (xdrproc_t) xdr_remote_secret_get_xml_desc_args, (char *) &args,
+              (xdrproc_t) xdr_remote_secret_get_xml_desc_ret, (char *) &ret) == -1)
+        goto done;
+
+    /* Caller frees. */
+    rv = ret.xml;
+
+done:
+    remoteDriverUnlock (priv);
+    return rv;
+}
+
+static int
+remoteSecretSetValue (virSecretPtr secret, const unsigned char *value,
+                      size_t value_size)
+{
+    int rv = -1;
+    remote_secret_set_value_args args;
+    struct private_data *priv = secret->conn->secretPrivateData;
+
+    remoteDriverLock (priv);
+
+    make_nonnull_secret (&args.secret, secret);
+    args.value.value_len = value_size;
+    args.value.value_val = (char *) value;
+
+    if (call (secret->conn, priv, 0, REMOTE_PROC_SECRET_SET_VALUE,
+              (xdrproc_t) xdr_remote_secret_set_value_args, (char *) &args,
+              (xdrproc_t) xdr_void, (char *) NULL) == -1)
+        goto done;
+
+    rv = 0;
+
+done:
+    remoteDriverUnlock (priv);
+    return rv;
+}
+
+static unsigned char *
+remoteSecretGetValue (virSecretPtr secret, size_t *value_size,
+                      /* If the call goes over a socket, it's not internal */
+                      bool libvirt_internal_call ATTRIBUTE_UNUSED)
+{
+    unsigned char *rv = NULL;
+    remote_secret_get_value_args args;
+    remote_secret_get_value_ret ret;
+    struct private_data *priv = secret->conn->secretPrivateData;
+
+    remoteDriverLock (priv);
+
+    make_nonnull_secret (&args.secret, secret);
+
+    memset (&ret, 0, sizeof (ret));
+    if (call (secret->conn, priv, 0, REMOTE_PROC_SECRET_GET_VALUE,
+              (xdrproc_t) xdr_remote_secret_get_value_args, (char *) &args,
+              (xdrproc_t) xdr_remote_secret_get_value_ret, (char *) &ret) == -1)
+        goto done;
+
+    *value_size = ret.value.value_len;
+    rv = (unsigned char *) ret.value.value_val; /* Caller frees. */
+
+done:
+    remoteDriverUnlock (priv);
+    return rv;
+}
+
+static int
+remoteSecretUndefine (virSecretPtr secret)
+{
+    int rv = -1;
+    remote_secret_undefine_args args;
+    struct private_data *priv = secret->conn->secretPrivateData;
+
+    remoteDriverLock (priv);
+
+    make_nonnull_secret (&args.secret, secret);
+
+    if (call (secret->conn, priv, 0, REMOTE_PROC_SECRET_UNDEFINE,
+              (xdrproc_t) xdr_remote_secret_undefine_args, (char *) &args,
+              (xdrproc_t) xdr_void, (char *) NULL) == -1)
+        goto done;
+
+    rv = 0;
+
+done:
+    remoteDriverUnlock (priv);
+    return rv;
+}
+
 /*----------------------------------------------------------------------*/
 
 
@@ -7415,6 +7711,12 @@ get_nonnull_node_device (virConnectPtr conn, remote_nonnull_node_device dev)
     return virGetNodeDevice(conn, dev.name);
 }
 
+static virSecretPtr
+get_nonnull_secret (virConnectPtr conn, remote_nonnull_secret secret)
+{
+    return virGetSecret(conn, secret.uuid);
+}
+
 /* Make remote_nonnull_domain and remote_nonnull_network. */
 static void
 make_nonnull_domain (remote_nonnull_domain *dom_dst, virDomainPtr dom_src)
@@ -7454,6 +7756,12 @@ make_nonnull_storage_vol (remote_nonnull_storage_vol *vol_dst, virStorageVolPtr
     vol_dst->key = vol_src->key;
 }
 
+static void
+make_nonnull_secret (remote_nonnull_secret *secret_dst, virSecretPtr secret_src)
+{
+    secret_dst->uuid = secret_src->uuid;
+}
+
 /*----------------------------------------------------------------------*/
 
 unsigned long remoteVersion(void)
@@ -7607,6 +7915,20 @@ static virStorageDriver storage_driver = {
     .volGetPath = remoteStorageVolGetPath,
 };
 
+static virSecretDriver secret_driver = {
+    .name = "remote",
+    .open = remoteSecretOpen,
+    .close = remoteSecretClose,
+    .numOfSecrets = remoteSecretNumOfSecrets,
+    .listSecrets = remoteSecretListSecrets,
+    .lookupByUUIDString = remoteSecretLookupByUUIDString,
+    .defineXML = remoteSecretDefineXML,
+    .getXMLDesc = remoteSecretGetXMLDesc,
+    .setValue = remoteSecretSetValue,
+    .getValue = remoteSecretGetValue,
+    .undefine = remoteSecretUndefine
+};
+
 static virDeviceMonitor dev_monitor = {
     .name = "remote",
     .open = remoteDevMonOpen,
@@ -7644,6 +7966,7 @@ remoteRegister (void)
     if (virRegisterInterfaceDriver (&interface_driver) == -1) return -1;
     if (virRegisterStorageDriver (&storage_driver) == -1) return -1;
     if (virRegisterDeviceMonitor (&dev_monitor) == -1) return -1;
+    if (virRegisterSecretDriver (&secret_driver) == -1) return -1;
 #ifdef WITH_LIBVIRTD
     if (virRegisterStateDriver (&state_driver) == -1) return -1;
 #endif
-- 
1.6.2.5




More information about the libvir-list mailing list