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

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



---
 src/datatypes.h       |    1 +
 src/remote_internal.c |  306 +++++++++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 307 insertions(+), 0 deletions(-)

diff --git a/src/datatypes.h b/src/datatypes.h
index 58a6d32..d17253f 100644
--- a/src/datatypes.h
+++ b/src/datatypes.h
@@ -130,6 +130,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..3272e0d 100644
--- a/src/remote_internal.c
+++ b/src/remote_internal.c
@@ -6319,6 +6319,297 @@ 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 char *
+remoteSecretAllocateID (virConnectPtr conn)
+{
+    char *rv = NULL;
+    remote_secret_allocate_id_ret ret;
+    struct private_data *priv = conn->secretPrivateData;
+
+    remoteDriverLock (priv);
+
+    memset (&ret, 0, sizeof (ret));
+    if (call (conn, priv, 0, REMOTE_PROC_SECRET_ALLOCATE_ID,
+              (xdrproc_t) xdr_void, (char *) NULL,
+              (xdrproc_t) xdr_remote_secret_allocate_id_ret,
+              (char *) &ret) == -1)
+        goto done;
+
+    /* Caller frees this. */
+    rv = ret.secretID;
+
+done:
+    remoteDriverUnlock (priv);
+    return rv;
+}
+
+static int
+remoteSecretSetXML (virConnectPtr conn, const char *secret_id, const char *xml)
+{
+    int rv = -1;
+    remote_secret_set_xml_args args;
+    struct private_data *priv = conn->secretPrivateData;
+
+    remoteDriverLock (priv);
+
+    args.secretID = (char *) secret_id;
+    args.xml = (char *) xml;
+
+    if (call (conn, priv, 0, REMOTE_PROC_SECRET_SET_XML,
+              (xdrproc_t) xdr_remote_secret_set_xml_args, (char *) &args,
+              (xdrproc_t) xdr_void, (char *) NULL) == -1)
+        goto done;
+
+    rv = 0;
+
+done:
+    remoteDriverUnlock (priv);
+    return rv;
+}
+
+static char *
+remoteSecretGetXML (virConnectPtr conn, const char *secret_id)
+{
+    char *rv = NULL;
+    remote_secret_get_xml_args args;
+    remote_secret_get_xml_ret ret;
+    struct private_data *priv = conn->secretPrivateData;
+
+    remoteDriverLock (priv);
+
+    args.secretID = (char *) secret_id;
+
+    memset (&ret, 0, sizeof (ret));
+    if (call (conn, priv, 0, REMOTE_PROC_SECRET_GET_XML,
+              (xdrproc_t) xdr_remote_secret_get_xml_args, (char *) &args,
+              (xdrproc_t) xdr_remote_secret_get_xml_ret, (char *) &ret) == -1)
+        goto done;
+
+    /* Caller frees. */
+    rv = ret.xml;
+
+done:
+    remoteDriverUnlock (priv);
+    return rv;
+}
+
+static int
+remoteSecretSetValue (virConnectPtr conn, const char *secret_id,
+                      const void *secret, size_t secret_size)
+{
+    int rv = -1;
+    remote_secret_set_value_args args;
+    struct private_data *priv = conn->secretPrivateData;
+
+    remoteDriverLock (priv);
+
+    args.secretID = (char *) secret_id;
+    args.value.value_len = secret_size;
+    args.value.value_val = (char *) secret;
+
+    if (call (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 void *
+remoteSecretGetValue (virConnectPtr conn, const char *secret_id,
+                      size_t *secret_size,
+                      /* If the call goes over a socket, it's not internal */
+                      bool libvirt_internal_call ATTRIBUTE_UNUSED)
+{
+    void *rv = NULL;
+    remote_secret_get_value_args args;
+    remote_secret_get_value_ret ret;
+    struct private_data *priv = conn->secretPrivateData;
+
+    remoteDriverLock (priv);
+
+    args.secretID = (char *) secret_id;
+
+    memset (&ret, 0, sizeof (ret));
+    if (call (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;
+
+    *secret_size = ret.value.value_len;
+    rv = ret.value.value_val; /* Caller frees. */
+
+done:
+    remoteDriverUnlock (priv);
+    return rv;
+}
+
+static int
+remoteSecretDelete (virConnectPtr conn, const char *secret_id)
+{
+    int rv = -1;
+    remote_secret_delete_args args;
+    struct private_data *priv = conn->secretPrivateData;
+
+    remoteDriverLock (priv);
+
+    args.secretID = (char *) secret_id;
+
+    if (call (conn, priv, 0, REMOTE_PROC_SECRET_DELETE,
+              (xdrproc_t) xdr_remote_secret_delete_args, (char *) &args,
+              (xdrproc_t) xdr_void, (char *) NULL) == -1)
+        goto done;
+
+    rv = 0;
+
+done:
+    remoteDriverUnlock (priv);
+    return rv;
+}
+
+static int
+remoteSecretNumOfSecrets (virConnectPtr conn)
+{
+    int rv = -1;
+    remote_secret_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_SECRET_NUM_OF_SECRETS,
+              (xdrproc_t) xdr_void, (char *) NULL,
+              (xdrproc_t) xdr_remote_secret_num_of_secrets_ret,
+              (char *) &ret) == -1)
+        goto done;
+
+    rv = ret.num;
+
+done:
+    remoteDriverUnlock (priv);
+    return rv;
+}
+
+static int
+remoteSecretListSecrets (virConnectPtr conn, char **ids, int maxids)
+{
+    int rv = -1;
+    int i;
+    remote_secret_list_secrets_args args;
+    remote_secret_list_secrets_ret ret;
+    struct private_data *priv = conn->secretPrivateData;
+
+    remoteDriverLock(priv);
+
+    if (maxids > REMOTE_SECRET_ID_LIST_MAX) {
+        errorf (conn, VIR_ERR_RPC, _("too many remote secret IDs: %d > %d"),
+                maxids, REMOTE_SECRET_ID_LIST_MAX);
+        goto done;
+    }
+    args.maxids = maxids;
+
+    memset (&ret, 0, sizeof ret);
+    if (call (conn, priv, 0, REMOTE_PROC_SECRET_LIST_SECRETS,
+              (xdrproc_t) xdr_remote_secret_list_secrets_args, (char *) &args,
+              (xdrproc_t) xdr_remote_secret_list_secrets_ret,
+              (char *) &ret) == -1)
+        goto done;
+
+    if (ret.ids.ids_len > maxids) {
+        errorf (conn, VIR_ERR_RPC, _("too many remote secret IDs: %d > %d"),
+                ret.ids.ids_len, maxids);
+        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.ids.ids_len; ++i)
+        ids[i] = strdup (ret.ids.ids_val[i]);
+
+    rv = ret.ids.ids_len;
+
+cleanup:
+    xdr_free ((xdrproc_t) xdr_remote_secret_list_secrets_ret, (char *) &ret);
+
+done:
+    remoteDriverUnlock(priv);
+    return rv;
+}
+
 /*----------------------------------------------------------------------*/
 
 
@@ -7607,6 +7898,20 @@ static virStorageDriver storage_driver = {
     .volGetPath = remoteStorageVolGetPath,
 };
 
+static virSecretDriver secret_driver = {
+    .name = "remote",
+    .open = remoteSecretOpen,
+    .close = remoteSecretClose,
+    .allocateID = remoteSecretAllocateID,
+    .setXML = remoteSecretSetXML,
+    .getXML = remoteSecretGetXML,
+    .setValue = remoteSecretSetValue,
+    .getValue = remoteSecretGetValue,
+    .delete = remoteSecretDelete,
+    .numOfSecrets = remoteSecretNumOfSecrets,
+    .listSecrets = remoteSecretListSecrets
+};
+
 static virDeviceMonitor dev_monitor = {
     .name = "remote",
     .open = remoteDevMonOpen,
@@ -7644,6 +7949,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


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