* include/libvirt/libvirt.h, include/libvirt/libvirt.h.in: Add
virSecretGetUsageType, virSecretGetUsageID and virLookupSecretByUsage
* python/generator.py: Mark virSecretGetUsageType, virSecretGetUsageID
as not throwing exceptions
* qemud/remote.c: Implement dispatch for virLookupSecretByUsage
* qemud/remote_protocol.x: Add usage type & ID as attributes of
remote_nonnull_secret. Add RPC calls for new public APIs
* qemud/remote_dispatch_args.h, qemud/remote_dispatch_prototypes.h,
qemud/remote_dispatch_ret.h, qemud/remote_dispatch_table.h,
qemud/remote_protocol.c, qemud/remote_protocol.h: Re-generate
* src/datatypes.c, src/datatypes.h: Add usageType and usageID as
properties of virSecretPtr
* src/driver.h: Add virLookupSecretByUsage driver entry point
* src/libvirt.c: Implement virSecretGetUsageType, virSecretGetUsageID
and virLookupSecretByUsage
* src/libvirt_public.syms: Export virSecretGetUsageType, virSecretGetUsageID
and virLookupSecretByUsage
* src/remote_internal.c: Implement virLookupSecretByUsage entry
* src/secret_conf.c, src/secret_conf.h: Remove the
virSecretUsageType enum, now in public API. Make volume
path mandatory when parsing XML
* src/secret_driver.c: Enforce usage uniqueness when defining secrets.
Implement virSecretLookupByUsage api method
* src/virsh.c: Include usage for secret-list command
---
include/libvirt/libvirt.h | 11 ++
include/libvirt/libvirt.h.in | 11 ++
python/generator.py | 2 +
qemud/remote.c | 24 ++++-
qemud/remote_dispatch_args.h | 1 +
qemud/remote_dispatch_prototypes.h | 7 +
qemud/remote_dispatch_ret.h | 1 +
qemud/remote_dispatch_table.h | 5 +
qemud/remote_protocol.c | 24 ++++
qemud/remote_protocol.h | 18 +++
qemud/remote_protocol.x | 14 ++-
src/datatypes.c | 14 ++-
src/datatypes.h | 6 +-
src/driver.h | 5 +
src/libvirt.c | 94 +++++++++++++++
src/libvirt_public.syms | 3 +
src/remote_internal.c | 33 +++++-
src/secret_conf.c | 7 +-
src/secret_conf.h | 6 -
src/secret_driver.c | 231 +++++++++++++++++++++++-------------
src/virsh.c | 28 ++++-
21 files changed, 448 insertions(+), 97 deletions(-)
diff --git a/include/libvirt/libvirt.h b/include/libvirt/libvirt.h
index eadf420..5527600 100644
--- a/include/libvirt/libvirt.h
+++ b/include/libvirt/libvirt.h
@@ -1462,6 +1462,12 @@ void virEventRegisterImpl(virEventAddHandleFunc addHandle,
typedef struct _virSecret virSecret;
typedef virSecret *virSecretPtr;
+typedef enum {
+ VIR_SECRET_USAGE_TYPE_NONE = 0,
+ VIR_SECRET_USAGE_TYPE_VOLUME = 1,
+ /* Expect more owner types later... */
+} virSecretUsageType;
+
virConnectPtr virSecretGetConnect (virSecretPtr secret);
int virConnectNumOfSecrets (virConnectPtr conn);
int virConnectListSecrets (virConnectPtr conn,
@@ -1471,6 +1477,9 @@ virSecretPtr virSecretLookupByUUID(virConnectPtr conn,
const unsigned char *uuid);
virSecretPtr virSecretLookupByUUIDString(virConnectPtr conn,
const char *uuid);
+virSecretPtr virSecretLookupByUsage(virConnectPtr conn,
+ int usageType,
+ const char *usageID);
virSecretPtr virSecretDefineXML (virConnectPtr conn,
const char *xml,
unsigned int flags);
@@ -1478,6 +1487,8 @@ int virSecretGetUUID (virSecretPtr
secret,
unsigned char *buf);
int virSecretGetUUIDString (virSecretPtr secret,
char *buf);
+int virSecretGetUsageType (virSecretPtr secret);
+const char * virSecretGetUsageID (virSecretPtr secret);
char * virSecretGetXMLDesc (virSecretPtr secret,
unsigned int flags);
int virSecretSetValue (virSecretPtr secret,
diff --git a/include/libvirt/libvirt.h.in b/include/libvirt/libvirt.h.in
index 1391af8..6028d5f 100644
--- a/include/libvirt/libvirt.h.in
+++ b/include/libvirt/libvirt.h.in
@@ -1462,6 +1462,12 @@ void virEventRegisterImpl(virEventAddHandleFunc addHandle,
typedef struct _virSecret virSecret;
typedef virSecret *virSecretPtr;
+typedef enum {
+ VIR_SECRET_USAGE_TYPE_NONE = 0,
+ VIR_SECRET_USAGE_TYPE_VOLUME = 1,
+ /* Expect more owner types later... */
+} virSecretUsageType;
+
virConnectPtr virSecretGetConnect (virSecretPtr secret);
int virConnectNumOfSecrets (virConnectPtr conn);
int virConnectListSecrets (virConnectPtr conn,
@@ -1471,6 +1477,9 @@ virSecretPtr virSecretLookupByUUID(virConnectPtr conn,
const unsigned char *uuid);
virSecretPtr virSecretLookupByUUIDString(virConnectPtr conn,
const char *uuid);
+virSecretPtr virSecretLookupByUsage(virConnectPtr conn,
+ int usageType,
+ const char *usageID);
virSecretPtr virSecretDefineXML (virConnectPtr conn,
const char *xml,
unsigned int flags);
@@ -1478,6 +1487,8 @@ int virSecretGetUUID (virSecretPtr
secret,
unsigned char *buf);
int virSecretGetUUIDString (virSecretPtr secret,
char *buf);
+int virSecretGetUsageType (virSecretPtr secret);
+const char * virSecretGetUsageID (virSecretPtr secret);
char * virSecretGetXMLDesc (virSecretPtr secret,
unsigned int flags);
int virSecretSetValue (virSecretPtr secret,
diff --git a/python/generator.py b/python/generator.py
index c25ff55..ad9c544 100755
--- a/python/generator.py
+++ b/python/generator.py
@@ -669,6 +669,8 @@ functions_noexcept = {
'virStorageVolGetkey': True,
'virNodeDeviceGetName': True,
'virNodeDeviceGetParent': True,
+ 'virSecretGetUsageType': True,
+ 'virSecretGetUsageID': True,
}
reference_keepers = {
diff --git a/qemud/remote.c b/qemud/remote.c
index a9fcc58..17426cd 100644
--- a/qemud/remote.c
+++ b/qemud/remote.c
@@ -4778,6 +4778,26 @@ remoteDispatchSecretUndefine (struct qemud_server *server
ATTRIBUTE_UNUSED,
return 0;
}
+static int
+remoteDispatchSecretLookupByUsage (struct qemud_server *server ATTRIBUTE_UNUSED,
+ struct qemud_client *client ATTRIBUTE_UNUSED,
+ virConnectPtr conn, remote_error *err,
+ remote_secret_lookup_by_usage_args *args,
+ remote_secret_lookup_by_usage_ret *ret)
+{
+ virSecretPtr secret;
+
+ secret = virSecretLookupByUsage (conn, args->usageType, args->usageID);
+ if (secret == NULL) {
+ remoteDispatchConnError (err, conn);
+ return -1;
+ }
+
+ make_nonnull_secret (&ret->secret, secret);
+ virSecretFree (secret);
+ return 0;
+}
+
/*----- Helpers. -----*/
@@ -4828,7 +4848,7 @@ get_nonnull_storage_vol (virConnectPtr conn,
remote_nonnull_storage_vol vol)
static virSecretPtr
get_nonnull_secret (virConnectPtr conn, remote_nonnull_secret secret)
{
- return virGetSecret (conn, BAD_CAST secret.uuid);
+ return virGetSecret (conn, BAD_CAST secret.uuid, secret.usageType, secret.usageID);
}
/* Make remote_nonnull_domain and remote_nonnull_network. */
@@ -4880,4 +4900,6 @@ static void
make_nonnull_secret (remote_nonnull_secret *secret_dst, virSecretPtr secret_src)
{
memcpy (secret_dst->uuid, secret_src->uuid, VIR_UUID_BUFLEN);
+ secret_dst->usageType = secret_src->usageType;
+ secret_dst->usageID = strdup (secret_src->usageID);
}
diff --git a/qemud/remote_dispatch_args.h b/qemud/remote_dispatch_args.h
index 9f37963..95f668a 100644
--- a/qemud/remote_dispatch_args.h
+++ b/qemud/remote_dispatch_args.h
@@ -124,3 +124,4 @@
remote_secret_set_value_args val_remote_secret_set_value_args;
remote_secret_get_value_args val_remote_secret_get_value_args;
remote_secret_undefine_args val_remote_secret_undefine_args;
+ remote_secret_lookup_by_usage_args val_remote_secret_lookup_by_usage_args;
diff --git a/qemud/remote_dispatch_prototypes.h b/qemud/remote_dispatch_prototypes.h
index 7773cd9..0605542 100644
--- a/qemud/remote_dispatch_prototypes.h
+++ b/qemud/remote_dispatch_prototypes.h
@@ -807,6 +807,13 @@ static int remoteDispatchSecretGetXmlDesc(
remote_error *err,
remote_secret_get_xml_desc_args *args,
remote_secret_get_xml_desc_ret *ret);
+static int remoteDispatchSecretLookupByUsage(
+ struct qemud_server *server,
+ struct qemud_client *client,
+ virConnectPtr conn,
+ remote_error *err,
+ remote_secret_lookup_by_usage_args *args,
+ remote_secret_lookup_by_usage_ret *ret);
static int remoteDispatchSecretLookupByUuid(
struct qemud_server *server,
struct qemud_client *client,
diff --git a/qemud/remote_dispatch_ret.h b/qemud/remote_dispatch_ret.h
index 15d3386..6ced13a 100644
--- a/qemud/remote_dispatch_ret.h
+++ b/qemud/remote_dispatch_ret.h
@@ -105,3 +105,4 @@
remote_secret_define_xml_ret val_remote_secret_define_xml_ret;
remote_secret_get_xml_desc_ret val_remote_secret_get_xml_desc_ret;
remote_secret_get_value_ret val_remote_secret_get_value_ret;
+ remote_secret_lookup_by_usage_ret val_remote_secret_lookup_by_usage_ret;
diff --git a/qemud/remote_dispatch_table.h b/qemud/remote_dispatch_table.h
index 07e36bb..6b5df80 100644
--- a/qemud/remote_dispatch_table.h
+++ b/qemud/remote_dispatch_table.h
@@ -737,3 +737,8 @@
.args_filter = (xdrproc_t) xdr_remote_secret_undefine_args,
.ret_filter = (xdrproc_t) xdr_void,
},
+{ /* SecretLookupByUsage => 147 */
+ .fn = (dispatch_fn) remoteDispatchSecretLookupByUsage,
+ .args_filter = (xdrproc_t) xdr_remote_secret_lookup_by_usage_args,
+ .ret_filter = (xdrproc_t) xdr_remote_secret_lookup_by_usage_ret,
+},
diff --git a/qemud/remote_protocol.c b/qemud/remote_protocol.c
index b6666a1..1d2d242 100644
--- a/qemud/remote_protocol.c
+++ b/qemud/remote_protocol.c
@@ -109,6 +109,10 @@ xdr_remote_nonnull_secret (XDR *xdrs, remote_nonnull_secret *objp)
if (!xdr_remote_uuid (xdrs, objp->uuid))
return FALSE;
+ if (!xdr_int (xdrs, &objp->usageType))
+ return FALSE;
+ if (!xdr_remote_nonnull_string (xdrs, &objp->usageID))
+ return FALSE;
return TRUE;
}
@@ -2674,6 +2678,26 @@ xdr_remote_secret_undefine_args (XDR *xdrs,
remote_secret_undefine_args *objp)
}
bool_t
+xdr_remote_secret_lookup_by_usage_args (XDR *xdrs, remote_secret_lookup_by_usage_args
*objp)
+{
+
+ if (!xdr_int (xdrs, &objp->usageType))
+ return FALSE;
+ if (!xdr_remote_nonnull_string (xdrs, &objp->usageID))
+ return FALSE;
+ return TRUE;
+}
+
+bool_t
+xdr_remote_secret_lookup_by_usage_ret (XDR *xdrs, remote_secret_lookup_by_usage_ret
*objp)
+{
+
+ if (!xdr_remote_nonnull_secret (xdrs, &objp->secret))
+ return FALSE;
+ return TRUE;
+}
+
+bool_t
xdr_remote_procedure (XDR *xdrs, remote_procedure *objp)
{
diff --git a/qemud/remote_protocol.h b/qemud/remote_protocol.h
index 4b73ee1..ceaf82c 100644
--- a/qemud/remote_protocol.h
+++ b/qemud/remote_protocol.h
@@ -87,6 +87,8 @@ typedef struct remote_nonnull_node_device remote_nonnull_node_device;
struct remote_nonnull_secret {
remote_uuid uuid;
+ int usageType;
+ remote_nonnull_string usageID;
};
typedef struct remote_nonnull_secret remote_nonnull_secret;
@@ -1513,6 +1515,17 @@ struct remote_secret_undefine_args {
remote_nonnull_secret secret;
};
typedef struct remote_secret_undefine_args remote_secret_undefine_args;
+
+struct remote_secret_lookup_by_usage_args {
+ int usageType;
+ remote_nonnull_string usageID;
+};
+typedef struct remote_secret_lookup_by_usage_args remote_secret_lookup_by_usage_args;
+
+struct remote_secret_lookup_by_usage_ret {
+ remote_nonnull_secret secret;
+};
+typedef struct remote_secret_lookup_by_usage_ret remote_secret_lookup_by_usage_ret;
#define REMOTE_PROGRAM 0x20008086
#define REMOTE_PROTOCOL_VERSION 1
@@ -1663,6 +1676,7 @@ enum remote_procedure {
REMOTE_PROC_SECRET_SET_VALUE = 144,
REMOTE_PROC_SECRET_GET_VALUE = 145,
REMOTE_PROC_SECRET_UNDEFINE = 146,
+ REMOTE_PROC_SECRET_LOOKUP_BY_USAGE = 147,
};
typedef enum remote_procedure remote_procedure;
@@ -1939,6 +1953,8 @@ extern bool_t xdr_remote_secret_set_value_args (XDR *,
remote_secret_set_value_
extern bool_t xdr_remote_secret_get_value_args (XDR *, remote_secret_get_value_args*);
extern bool_t xdr_remote_secret_get_value_ret (XDR *, remote_secret_get_value_ret*);
extern bool_t xdr_remote_secret_undefine_args (XDR *, remote_secret_undefine_args*);
+extern bool_t xdr_remote_secret_lookup_by_usage_args (XDR *,
remote_secret_lookup_by_usage_args*);
+extern bool_t xdr_remote_secret_lookup_by_usage_ret (XDR *,
remote_secret_lookup_by_usage_ret*);
extern bool_t xdr_remote_procedure (XDR *, remote_procedure*);
extern bool_t xdr_remote_message_type (XDR *, remote_message_type*);
extern bool_t xdr_remote_message_status (XDR *, remote_message_status*);
@@ -2191,6 +2207,8 @@ extern bool_t xdr_remote_secret_set_value_args ();
extern bool_t xdr_remote_secret_get_value_args ();
extern bool_t xdr_remote_secret_get_value_ret ();
extern bool_t xdr_remote_secret_undefine_args ();
+extern bool_t xdr_remote_secret_lookup_by_usage_args ();
+extern bool_t xdr_remote_secret_lookup_by_usage_ret ();
extern bool_t xdr_remote_procedure ();
extern bool_t xdr_remote_message_type ();
extern bool_t xdr_remote_message_status ();
diff --git a/qemud/remote_protocol.x b/qemud/remote_protocol.x
index 5712d98..29abdb7 100644
--- a/qemud/remote_protocol.x
+++ b/qemud/remote_protocol.x
@@ -189,6 +189,8 @@ struct remote_nonnull_node_device {
/* A secret which may not be null. */
struct remote_nonnull_secret {
remote_uuid uuid;
+ int usageType;
+ remote_nonnull_string usageID;
};
/* A domain or network which may be NULL. */
@@ -1338,6 +1340,15 @@ struct remote_secret_undefine_args {
remote_nonnull_secret secret;
};
+struct remote_secret_lookup_by_usage_args {
+ int usageType;
+ remote_nonnull_string usageID;
+};
+
+struct remote_secret_lookup_by_usage_ret {
+ remote_nonnull_secret secret;
+};
+
/*----- Protocol. -----*/
/* Define the program number, protocol version and procedure numbers here. */
@@ -1505,7 +1516,8 @@ enum remote_procedure {
REMOTE_PROC_SECRET_GET_XML_DESC = 143,
REMOTE_PROC_SECRET_SET_VALUE = 144,
REMOTE_PROC_SECRET_GET_VALUE = 145,
- REMOTE_PROC_SECRET_UNDEFINE = 146
+ REMOTE_PROC_SECRET_UNDEFINE = 146,
+ REMOTE_PROC_SECRET_LOOKUP_BY_USAGE = 147
};
diff --git a/src/datatypes.c b/src/datatypes.c
index b0067f6..d7cf2ee 100644
--- a/src/datatypes.c
+++ b/src/datatypes.c
@@ -1170,12 +1170,13 @@ virUnrefNodeDevice(virNodeDevicePtr dev) {
* Returns a pointer to the secret, or NULL in case of failure
*/
virSecretPtr
-virGetSecret(virConnectPtr conn, const unsigned char *uuid)
+virGetSecret(virConnectPtr conn, const unsigned char *uuid,
+ int usageType, const char *usageID)
{
virSecretPtr ret = NULL;
char uuidstr[VIR_UUID_STRING_BUFLEN];
- if (!VIR_IS_CONNECT(conn) || uuid == NULL) {
+ if (!VIR_IS_CONNECT(conn) || uuid == NULL || usageID == NULL) {
virLibConnError(NULL, VIR_ERR_INVALID_ARG, __FUNCTION__);
return NULL;
}
@@ -1193,7 +1194,12 @@ virGetSecret(virConnectPtr conn, const unsigned char *uuid)
ret->magic = VIR_SECRET_MAGIC;
ret->conn = conn;
memcpy(&(ret->uuid[0]), uuid, VIR_UUID_BUFLEN);
-
+ ret->usageType = usageType;
+ if (!(ret->usageID = strdup(usageID))) {
+ virMutexUnlock(&conn->lock);
+ virReportOOMError(conn);
+ goto error;
+ }
if (virHashAddEntry(conn->secrets, uuidstr, ret) < 0) {
virMutexUnlock(&conn->lock);
virLibConnError(conn, VIR_ERR_INTERNAL_ERROR,
@@ -1208,6 +1214,7 @@ virGetSecret(virConnectPtr conn, const unsigned char *uuid)
error:
if (ret != NULL) {
+ VIR_FREE(ret->usageID);
VIR_FREE(ret->uuid);
VIR_FREE(ret);
}
@@ -1239,6 +1246,7 @@ virReleaseSecret(virSecretPtr secret) {
conn = NULL;
}
+ VIR_FREE(secret->usageID);
secret->magic = -1;
VIR_FREE(secret);
diff --git a/src/datatypes.h b/src/datatypes.h
index 5319308..a33c365 100644
--- a/src/datatypes.h
+++ b/src/datatypes.h
@@ -256,6 +256,8 @@ struct _virSecret {
int refs; /* reference count */
virConnectPtr conn; /* pointer back to the connection */
unsigned char uuid[VIR_UUID_BUFLEN]; /* the domain unique identifier */
+ int usageType; /* the type of usage */
+ char *usageID; /* the usage's unique identifier */
};
@@ -296,7 +298,9 @@ virNodeDevicePtr virGetNodeDevice(virConnectPtr conn,
int virUnrefNodeDevice(virNodeDevicePtr dev);
virSecretPtr virGetSecret(virConnectPtr conn,
- const unsigned char *uuid);
+ const unsigned char *uuid,
+ int usageType,
+ const char *usageID);
int virUnrefSecret(virSecretPtr secret);
#endif
diff --git a/src/driver.h b/src/driver.h
index 9f197d9..d4f972f 100644
--- a/src/driver.h
+++ b/src/driver.h
@@ -822,6 +822,10 @@ typedef virSecretPtr
(*virDrvSecretLookupByUUID) (virConnectPtr conn,
const unsigned char *uuid);
typedef virSecretPtr
+ (*virDrvSecretLookupByUsage) (virConnectPtr conn,
+ int usageType,
+ const char *usageID);
+typedef virSecretPtr
(*virDrvSecretDefineXML) (virConnectPtr conn,
const char *xml,
unsigned int flags);
@@ -867,6 +871,7 @@ struct _virSecretDriver {
virDrvSecretNumOfSecrets numOfSecrets;
virDrvSecretListSecrets listSecrets;
virDrvSecretLookupByUUID lookupByUUID;
+ virDrvSecretLookupByUsage lookupByUsage;
virDrvSecretDefineXML defineXML;
virDrvSecretGetXMLDesc getXMLDesc;
virDrvSecretSetValue setValue;
diff --git a/src/libvirt.c b/src/libvirt.c
index 7a915fa..1563ce5 100644
--- a/src/libvirt.c
+++ b/src/libvirt.c
@@ -8913,6 +8913,53 @@ error:
/**
+ * virSecretLookupByUsage:
+ * @conn: pointer to the hypervisor connection
+ * @usageType: the type of secret usage
+ * @usageID: identifier of the object using the secret
+ *
+ * Try to lookup a secret on the given hypervisor based on its usage
+ *
+ * Returns a new secret object or NULL in case of failure. If the
+ * secret cannot be found, then VIR_ERR_NO_SECRET error is raised.
+ */
+virSecretPtr
+virSecretLookupByUsage(virConnectPtr conn,
+ int usageType,
+ const char *usageID)
+{
+ DEBUG("conn=%p, usageType=%d usageID=%s", conn, usageType,
NULLSTR(usageID));
+
+ virResetLastError();
+
+ if (!VIR_IS_CONNECT(conn)) {
+ virLibConnError(NULL, VIR_ERR_INVALID_CONN, __FUNCTION__);
+ return (NULL);
+ }
+ if (usageID == NULL) {
+ virLibConnError(conn, VIR_ERR_INVALID_ARG, __FUNCTION__);
+ goto error;
+ }
+
+ if (conn->secretDriver &&
+ conn->secretDriver->lookupByUsage) {
+ virSecretPtr ret;
+ ret = conn->secretDriver->lookupByUsage (conn, usageType, usageID);
+ if (!ret)
+ goto error;
+ return ret;
+ }
+
+ virLibConnError (conn, VIR_ERR_NO_SUPPORT, __FUNCTION__);
+
+error:
+ /* Copy to connection error object for back compatability */
+ virSetConnError(conn);
+ return NULL;
+}
+
+
+/**
* virSecretDefineXML:
* @conn: virConnect connection
* @xml: XML describing the secret.
@@ -9036,6 +9083,53 @@ error:
return -1;
}
+/**
+ * virSecretGetUsageType:
+ * @secret: a secret object
+ *
+ * Get the type of object which uses this secret
+ *
+ * Returns a positive integer identifying the type of object,
+ * or -1 upon error.
+ */
+int
+virSecretGetUsageType(virSecretPtr secret)
+{
+ DEBUG("secret=%p", secret);
+
+ virResetLastError();
+
+ if (!VIR_IS_SECRET(secret)) {
+ virLibSecretError(NULL, VIR_ERR_INVALID_SECRET, __FUNCTION__);
+ return (-1);
+ }
+ return (secret->usageType);
+}
+
+/**
+ * virSecretGetUsageID:
+ * @secret: a secret object
+ *
+ * Get the unique identifier of the object with which this
+ * secret is to be used
+ *
+ * Returns a string identifying the object using the secret,
+ * or NULL upon error
+ */
+const char *
+virSecretGetUsageID(virSecretPtr secret)
+{
+ DEBUG("secret=%p", secret);
+
+ virResetLastError();
+
+ if (!VIR_IS_SECRET(secret)) {
+ virLibSecretError(NULL, VIR_ERR_INVALID_SECRET, __FUNCTION__);
+ return (NULL);
+ }
+ return (secret->usageID);
+}
+
/**
* virSecretGetXMLDesc:
diff --git a/src/libvirt_public.syms b/src/libvirt_public.syms
index c34bbae..cf5be38 100644
--- a/src/libvirt_public.syms
+++ b/src/libvirt_public.syms
@@ -300,9 +300,12 @@ LIBVIRT_0.7.1 {
virConnectListSecrets;
virSecretLookupByUUID;
virSecretLookupByUUIDString;
+ virSecretLookupByUsage;
virSecretDefineXML;
virSecretGetUUID;
virSecretGetUUIDString;
+ virSecretGetUsageType;
+ virSecretGetUsageID;
virSecretGetXMLDesc;
virSecretSetValue;
virSecretGetValue;
diff --git a/src/remote_internal.c b/src/remote_internal.c
index e7f0186..eff268f 100644
--- a/src/remote_internal.c
+++ b/src/remote_internal.c
@@ -6502,6 +6502,34 @@ done:
}
static virSecretPtr
+remoteSecretLookupByUsage (virConnectPtr conn, int usageType, const char *usageID)
+{
+ virSecretPtr rv = NULL;
+ remote_secret_lookup_by_usage_args args;
+ remote_secret_lookup_by_usage_ret ret;
+ struct private_data *priv = conn->secretPrivateData;
+
+ remoteDriverLock (priv);
+
+ args.usageType = usageType;
+ args.usageID = (char *)usageID;
+
+ memset (&ret, 0, sizeof (ret));
+ if (call (conn, priv, 0, REMOTE_PROC_SECRET_LOOKUP_BY_UUID,
+ (xdrproc_t) xdr_remote_secret_lookup_by_usage_args, (char *) &args,
+ (xdrproc_t) xdr_remote_secret_lookup_by_usage_ret, (char *) &ret) ==
-1)
+ goto done;
+
+ rv = get_nonnull_secret (conn, ret.secret);
+ xdr_free ((xdrproc_t) xdr_remote_secret_lookup_by_usage_ret,
+ (char *) &ret);
+
+done:
+ remoteDriverUnlock (priv);
+ return rv;
+}
+
+static virSecretPtr
remoteSecretDefineXML (virConnectPtr conn, const char *xml, unsigned int flags)
{
virSecretPtr rv = NULL;
@@ -7733,7 +7761,7 @@ get_nonnull_node_device (virConnectPtr conn,
remote_nonnull_node_device dev)
static virSecretPtr
get_nonnull_secret (virConnectPtr conn, remote_nonnull_secret secret)
{
- return virGetSecret(conn, BAD_CAST secret.uuid);
+ return virGetSecret(conn, BAD_CAST secret.uuid, secret.usageType, secret.usageID);
}
/* Make remote_nonnull_domain and remote_nonnull_network. */
@@ -7779,6 +7807,8 @@ static void
make_nonnull_secret (remote_nonnull_secret *secret_dst, virSecretPtr secret_src)
{
memcpy (secret_dst->uuid, secret_src->uuid, VIR_UUID_BUFLEN);
+ secret_dst->usageType = secret_src->usageType;
+ secret_dst->usageID = secret_src->usageID;
}
/*----------------------------------------------------------------------*/
@@ -7941,6 +7971,7 @@ static virSecretDriver secret_driver = {
.numOfSecrets = remoteSecretNumOfSecrets,
.listSecrets = remoteSecretListSecrets,
.lookupByUUID = remoteSecretLookupByUUID,
+ .lookupByUsage = remoteSecretLookupByUsage,
.defineXML = remoteSecretDefineXML,
.getXMLDesc = remoteSecretGetXMLDesc,
.setValue = remoteSecretSetValue,
diff --git a/src/secret_conf.c b/src/secret_conf.c
index 51ac13d..21215b2 100644
--- a/src/secret_conf.c
+++ b/src/secret_conf.c
@@ -35,7 +35,7 @@
#define VIR_FROM_THIS VIR_FROM_SECRET
-VIR_ENUM_IMPL(virSecretUsageType, VIR_SECRET_USAGE_TYPE_LAST, "none",
"volume")
+VIR_ENUM_IMPL(virSecretUsageType, VIR_SECRET_USAGE_TYPE_VOLUME + 1, "none",
"volume")
void
virSecretDefFree(virSecretDefPtr def)
@@ -88,6 +88,11 @@ virSecretDefParseUsage(virConnectPtr conn, xmlXPathContextPtr ctxt,
case VIR_SECRET_USAGE_TYPE_VOLUME:
def->usage.volume = virXPathString(conn, "string(./usage/volume)",
ctxt);
+ if (!def->usage.volume) {
+ virSecretReportError(conn, VIR_ERR_INTERNAL_ERROR, "%s",
+ _("volume usage specified, but volume path is
missing"));
+ return -1;
+ }
break;
default:
diff --git a/src/secret_conf.h b/src/secret_conf.h
index 556f5a4..1ecf419 100644
--- a/src/secret_conf.h
+++ b/src/secret_conf.h
@@ -30,12 +30,6 @@
virReportErrorHelper(conn, VIR_FROM_SECRET, code, __FILE__, \
__FUNCTION__, __LINE__, fmt)
-enum virSecretUsageType {
- VIR_SECRET_USAGE_TYPE_NONE = 0, /* default when zero-initialized */
- VIR_SECRET_USAGE_TYPE_VOLUME,
-
- VIR_SECRET_USAGE_TYPE_LAST
-};
VIR_ENUM_DECL(virSecretUsageType)
typedef struct _virSecretDef virSecretDef;
diff --git a/src/secret_driver.c b/src/secret_driver.c
index c1e0c67..a60b1ca 100644
--- a/src/secret_driver.c
+++ b/src/secret_driver.c
@@ -110,57 +110,45 @@ secretFree(virSecretEntryPtr secret)
VIR_FREE(secret);
}
-static virSecretEntryPtr *
-secretFind(virSecretDriverStatePtr driver, const unsigned char *uuid)
+static virSecretEntryPtr
+secretFindByUUID(virSecretDriverStatePtr driver, const unsigned char *uuid)
{
virSecretEntryPtr *pptr, s;
for (pptr = &driver->secrets; *pptr != NULL; pptr = &s->next) {
s = *pptr;
if (memcmp(s->def->uuid, uuid, VIR_UUID_BUFLEN) == 0)
- return pptr;
+ return s;
}
return NULL;
}
static virSecretEntryPtr
-secretCreate(virConnectPtr conn, virSecretDriverStatePtr driver,
- const unsigned char *uuid)
+secretFindByUsage(virSecretDriverStatePtr driver, int usageType, const char *usageID)
{
- virSecretEntryPtr secret = NULL;
+ virSecretEntryPtr *pptr, s;
- if (VIR_ALLOC(secret) < 0 || VIR_ALLOC(secret->def))
- goto no_memory;
- memcpy(secret->def->uuid, uuid, VIR_UUID_BUFLEN);
- listInsert(&driver->secrets, secret);
- return secret;
+ for (pptr = &driver->secrets; *pptr != NULL; pptr = &s->next) {
+ s = *pptr;
- no_memory:
- virReportOOMError(conn);
- secretFree(secret);
- return NULL;
-}
+ if (s->def->usage_type != usageType)
+ continue;
-static virSecretEntryPtr
-secretFindOrCreate(virConnectPtr conn, virSecretDriverStatePtr driver,
- const unsigned char *uuid, bool *created_new)
-{
- virSecretEntryPtr *pptr, secret;
+ switch (usageType) {
+ case VIR_SECRET_USAGE_TYPE_NONE:
+ /* never match this */
+ break;
- pptr = secretFind(driver, uuid);
- if (pptr != NULL) {
- if (created_new != NULL)
- *created_new = false;
- return *pptr;
+ case VIR_SECRET_USAGE_TYPE_VOLUME:
+ if (STREQ(s->def->usage.volume, usageID))
+ return s;
+ break;
+ }
}
-
- secret = secretCreate(conn, driver, uuid);
- if (secret != NULL && created_new != NULL)
- *created_new = true;
- return secret;
+ return NULL;
}
- /* Permament secret storage */
+/* Permament secret storage */
/* Secrets are stored in virSecretDriverStatePtr->directory. Each secret
has virSecretDef stored as XML in "$basename.xml". If a value of the
@@ -609,17 +597,33 @@ cleanup:
return -1;
}
+
+static const char *
+secretUsageIDForDef(virSecretDefPtr def)
+{
+ switch (def->usage_type) {
+ case VIR_SECRET_USAGE_TYPE_NONE:
+ return "none";
+
+ case VIR_SECRET_USAGE_TYPE_VOLUME:
+ return def->usage.volume;
+
+ default:
+ return NULL;
+ }
+}
+
static virSecretPtr
secretLookupByUUID(virConnectPtr conn, const unsigned char *uuid)
{
virSecretDriverStatePtr driver = conn->secretPrivateData;
virSecretPtr ret = NULL;
- virSecretEntryPtr *pptr;
+ virSecretEntryPtr secret;
secretDriverLock(driver);
- pptr = secretFind(driver, uuid);
- if (pptr == NULL) {
+ secret = secretFindByUUID(driver, uuid);
+ if (secret == NULL) {
char uuidstr[VIR_UUID_STRING_BUFLEN];
virUUIDFormat(uuid, uuidstr);
virSecretReportError(conn, VIR_ERR_NO_SECRET,
@@ -627,7 +631,10 @@ secretLookupByUUID(virConnectPtr conn, const unsigned char *uuid)
goto cleanup;
}
- ret = virGetSecret(conn, (*pptr)->def->uuid);
+ ret = virGetSecret(conn,
+ secret->def->uuid,
+ secret->def->usage_type,
+ secretUsageIDForDef(secret->def));
cleanup:
if (1) {
@@ -641,14 +648,41 @@ cleanup:
static virSecretPtr
+secretLookupByUsage(virConnectPtr conn, int usageType, const char *usageID)
+{
+ virSecretDriverStatePtr driver = conn->secretPrivateData;
+ virSecretPtr ret = NULL;
+ virSecretEntryPtr secret;
+
+ secretDriverLock(driver);
+
+ secret = secretFindByUsage(driver, usageType, usageID);
+ if (secret == NULL) {
+ virSecretReportError(conn, VIR_ERR_NO_SECRET,
+ _("no secret with matching usage '%s'"),
usageID);
+ goto cleanup;
+ }
+
+ ret = virGetSecret(conn,
+ secret->def->uuid,
+ secret->def->usage_type,
+ secretUsageIDForDef(secret->def));
+
+cleanup:
+ secretDriverUnlock(driver);
+ return ret;
+}
+
+
+static virSecretPtr
secretDefineXML(virConnectPtr conn, const char *xml,
unsigned int flags ATTRIBUTE_UNUSED)
{
virSecretDriverStatePtr driver = conn->secretPrivateData;
virSecretPtr ret = NULL;
virSecretEntryPtr secret;
- virSecretDefPtr backup, new_attrs;
- bool secret_is_new;
+ virSecretDefPtr backup = NULL;
+ virSecretDefPtr new_attrs;
new_attrs = virSecretDefParseString(conn, xml);
if (new_attrs == NULL)
@@ -656,28 +690,58 @@ secretDefineXML(virConnectPtr conn, const char *xml,
secretDriverLock(driver);
- secret = secretFindOrCreate(conn, driver, new_attrs->uuid,
- &secret_is_new);
- if (secret == NULL)
- goto cleanup;
+ secret = secretFindByUUID(driver, new_attrs->uuid);
+ if (secret == NULL) {
+ /* No existing secret with same UUID, try look for matching usage instead */
+ const char *usageID = secretUsageIDForDef(new_attrs);
+ secret = secretFindByUsage(driver, new_attrs->usage_type, usageID);
+ if (secret) {
+ char uuidstr[VIR_UUID_STRING_BUFLEN];
+ virUUIDFormat(secret->def->uuid, uuidstr);
+ virSecretReportError(conn, VIR_ERR_INTERNAL_ERROR,
+ _("a secret with UUID %s already defined for use
with %s"),
+ uuidstr, usageID);
+ goto cleanup;
+ }
- /* Save old values of the attributes */
- backup = secret->def;
+ /* No existing secret at all, create one */
+ if (VIR_ALLOC(secret) < 0) {
+ virReportOOMError(conn);
+ goto cleanup;
+ }
- if (backup->private && !new_attrs->private) {
- virSecretReportError(conn, VIR_ERR_OPERATION_DENIED, "%s",
- virErrorMsg(VIR_ERR_OPERATION_DENIED, NULL));
- goto cleanup;
+ listInsert(&driver->secrets, secret);
+ secret->def = new_attrs;
+ } else {
+ const char *newUsageID = secretUsageIDForDef(new_attrs);
+ const char *oldUsageID = secretUsageIDForDef(secret->def);
+ if (STRNEQ(oldUsageID, newUsageID)) {
+ char uuidstr[VIR_UUID_STRING_BUFLEN];
+ virUUIDFormat(secret->def->uuid, uuidstr);
+ virSecretReportError(conn, VIR_ERR_INTERNAL_ERROR,
+ _("a secret with UUID %s is already defined for use
with %s"),
+ uuidstr, oldUsageID);
+ goto cleanup;
+ }
+
+ if (secret->def->private && !new_attrs->private) {
+ virSecretReportError(conn, VIR_ERR_INTERNAL_ERROR, "%s",
+ _("cannot change private flag on existing
secret"));
+ goto cleanup;
+ }
+
+ /* Got an existing secret matches attrs, so reuse that */
+ backup = secret->def;
+ secret->def = new_attrs;
}
- secret->def = new_attrs;
if (!new_attrs->ephemeral) {
- if (backup->ephemeral) {
+ if (backup && backup->ephemeral) {
if (secretSaveValue(conn, driver, secret) < 0)
goto restore_backup;
}
if (secretSaveDef(conn, driver, secret) < 0) {
- if (backup->ephemeral) {
+ if (backup && backup->ephemeral) {
char *filename;
/* Undo the secretSaveValue() above; ignore errors */
@@ -688,7 +752,7 @@ secretDefineXML(virConnectPtr conn, const char *xml,
}
goto restore_backup;
}
- } else if (!backup->ephemeral) {
+ } else if (backup && !backup->ephemeral) {
if (secretDeleteSaved(conn, driver, secret) < 0)
goto restore_backup;
}
@@ -696,13 +760,17 @@ secretDefineXML(virConnectPtr conn, const char *xml,
new_attrs = NULL;
virSecretDefFree(backup);
- ret = virGetSecret(conn, secret->def->uuid);
+ ret = virGetSecret(conn,
+ secret->def->uuid,
+ secret->def->usage_type,
+ secretUsageIDForDef(secret->def));
goto cleanup;
restore_backup:
- /* Error - restore previous state and free new attributes */
- secret->def = backup;
- if (secret_is_new) {
+ if (backup) {
+ /* Error - restore previous state and free new attributes */
+ secret->def = backup;
+ } else {
/* "secret" was added to the head of the list above */
if (listUnlink(&driverState->secrets) != secret)
virSecretReportError(conn, VIR_ERR_INTERNAL_ERROR, "%s",
@@ -723,12 +791,12 @@ secretGetXMLDesc(virSecretPtr obj, unsigned int flags
ATTRIBUTE_UNUSED)
{
virSecretDriverStatePtr driver = obj->conn->secretPrivateData;
char *ret = NULL;
- virSecretEntryPtr *pptr;
+ virSecretEntryPtr secret;
secretDriverLock(driver);
- pptr = secretFind(driver, obj->uuid);
- if (pptr == NULL) {
+ secret = secretFindByUUID(driver, obj->uuid);
+ if (secret == NULL) {
char uuidstr[VIR_UUID_STRING_BUFLEN];
virUUIDFormat(obj->uuid, uuidstr);
virSecretReportError(obj->conn, VIR_ERR_NO_SECRET,
@@ -736,7 +804,7 @@ secretGetXMLDesc(virSecretPtr obj, unsigned int flags
ATTRIBUTE_UNUSED)
goto cleanup;
}
- ret = virSecretDefFormat(obj->conn, (*pptr)->def);
+ ret = virSecretDefFormat(obj->conn, secret->def);
cleanup:
secretDriverUnlock(driver);
@@ -752,7 +820,7 @@ secretSetValue(virSecretPtr obj, const unsigned char *value,
int ret = -1;
unsigned char *old_value, *new_value;
size_t old_value_size;
- virSecretEntryPtr secret, *pptr;
+ virSecretEntryPtr secret;
if (VIR_ALLOC_N(new_value, value_size) < 0) {
virReportOOMError(obj->conn);
@@ -761,15 +829,14 @@ secretSetValue(virSecretPtr obj, const unsigned char *value,
secretDriverLock(driver);
- pptr = secretFind(driver, obj->uuid);
- if (pptr == NULL) {
+ secret = secretFindByUUID(driver, obj->uuid);
+ if (secret == NULL) {
char uuidstr[VIR_UUID_STRING_BUFLEN];
virUUIDFormat(obj->uuid, uuidstr);
virSecretReportError(obj->conn, VIR_ERR_NO_SECRET,
_("no secret with matching uuid '%s'"),
uuidstr);
goto cleanup;
}
- secret = *pptr;
old_value = secret->value;
old_value_size = secret->value_size;
@@ -810,19 +877,19 @@ secretGetValue(virSecretPtr obj, size_t *value_size, unsigned int
flags)
{
virSecretDriverStatePtr driver = obj->conn->secretPrivateData;
unsigned char *ret = NULL;
- virSecretEntryPtr *pptr, secret;
+ virSecretEntryPtr secret;
secretDriverLock(driver);
- pptr = secretFind(driver, obj->uuid);
- if (pptr == NULL) {
+ secret = secretFindByUUID(driver, obj->uuid);
+ if (secret == NULL) {
char uuidstr[VIR_UUID_STRING_BUFLEN];
virUUIDFormat(obj->uuid, uuidstr);
virSecretReportError(obj->conn, VIR_ERR_NO_SECRET,
_("no secret with matching uuid '%s'"),
uuidstr);
goto cleanup;
}
- secret = *pptr;
+
if (secret->value == NULL) {
char uuidstr[VIR_UUID_STRING_BUFLEN];
virUUIDFormat(obj->uuid, uuidstr);
@@ -856,12 +923,12 @@ secretUndefine(virSecretPtr obj)
{
virSecretDriverStatePtr driver = obj->conn->secretPrivateData;
int ret = -1;
- virSecretEntryPtr *pptr, secret;
+ virSecretEntryPtr secret;
secretDriverLock(driver);
- pptr = secretFind(driver, obj->uuid);
- if (pptr == NULL) {
+ secret = secretFindByUUID(driver, obj->uuid);
+ if (secret == NULL) {
char uuidstr[VIR_UUID_STRING_BUFLEN];
virUUIDFormat(obj->uuid, uuidstr);
virSecretReportError(obj->conn, VIR_ERR_NO_SECRET,
@@ -869,19 +936,22 @@ secretUndefine(virSecretPtr obj)
goto cleanup;
}
- secret = listUnlink(pptr);
- if (!secret->def->ephemeral) {
- if (secretDeleteSaved(obj->conn, driver, secret) < 0)
- goto restore_backup;
+ if (!secret->def->ephemeral &&
+ secretDeleteSaved(obj->conn, driver, secret) < 0)
+ goto cleanup;
+
+ if (driver->secrets == secret) {
+ driver->secrets = secret->next;
+ } else {
+ virSecretEntryPtr tmp = driver->secrets;
+ while (tmp && tmp->next != secret)
+ tmp = tmp->next;
+ if (tmp)
+ tmp->next = secret->next;
}
secretFree(secret);
ret = 0;
- goto cleanup;
-
-restore_backup:
- /* This may change the order of secrets in the list. We don't care. */
- listInsert(&driver->secrets, secret);
cleanup:
secretDriverUnlock(driver);
@@ -1000,6 +1070,7 @@ static virSecretDriver secretDriver = {
.numOfSecrets = secretNumOfSecrets,
.listSecrets = secretListSecrets,
.lookupByUUID = secretLookupByUUID,
+ .lookupByUsage = secretLookupByUsage,
.defineXML = secretDefineXML,
.getXMLDesc = secretGetXMLDesc,
.setValue = secretSetValue,
diff --git a/src/virsh.c b/src/virsh.c
index 74147da..4825f1c 100644
--- a/src/virsh.c
+++ b/src/virsh.c
@@ -5527,11 +5527,33 @@ cmdSecretList(vshControl *ctl, const vshCmd *cmd
ATTRIBUTE_UNUSED)
qsort(uuids, maxuuids, sizeof(char *), namesorter);
- vshPrintExtra(ctl, "%s\n", _("UUID"));
- vshPrintExtra(ctl, "-----------------------------------------\n");
+ vshPrintExtra(ctl, "%-36s %s\n", _("UUID"),
_("Usage"));
+ vshPrintExtra(ctl,
"-----------------------------------------------------------\n");
for (i = 0; i < maxuuids; i++) {
- vshPrint(ctl, "%-36s\n", uuids[i]);
+ virSecretPtr sec = virSecretLookupByUUIDString(ctl->conn, uuids[i]);
+ const char *usageType = NULL;
+
+ if (!sec) {
+ free(uuids[i]);
+ continue;
+ }
+
+ switch (virSecretGetUsageType(sec)) {
+ case VIR_SECRET_USAGE_TYPE_VOLUME:
+ usageType = _("Volume");
+ break;
+ }
+
+ if (usageType) {
+ vshPrint(ctl, "%-36s %s %s\n",
+ uuids[i], usageType,
+ virSecretGetUsageID(sec));
+ } else {
+ vshPrint(ctl, "%-36s %s\n",
+ uuids[i], _("Unused"));
+ }
+ virSecretFree(sec);
free(uuids[i]);
}
free(uuids);
--
1.6.2.5