---
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