--- 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 -- Libvir-list mailing list Libvir-list@xxxxxxxxxx https://www.redhat.com/mailman/listinfo/libvir-list