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

[libvirt] [PATCH 2/4] API: Add api to set and get domain metadata



This patch adds API to modify domain metadata for running and stopped
domains. The api supports changing description, title as well as the
newly added <metadata> element. The API has support for storing data in
the metadata element using xml namespaces.

* include/libvirt/libvirt.h.in
* src/libvirt_public.syms
        - add function headers
        - add enum to select metadata to operate on
        - export functions
* src/libvirt.c
        - add public api implementation
* src/driver.h
        - add driver support
* src/remote/remote_driver.c
* src/remote/remote_protocol.x
        - wire up the remote protocol
* include/libvirt/virterror.h
* src/util/virterror.c
        - add a new error message note that metadata for domain are
        missing
---
This is a major rework based on Eric's and Daniels comments.

 include/libvirt/libvirt.h.in |   25 ++++++++
 include/libvirt/virterror.h  |    1 +
 src/driver.h                 |   15 +++++
 src/libvirt.c                |  125 ++++++++++++++++++++++++++++++++++++++++++
 src/libvirt_public.syms      |    2 +
 src/remote/remote_driver.c   |    2 +
 src/remote/remote_protocol.x |   25 ++++++++-
 src/util/virterror.c         |    6 ++
 8 files changed, 200 insertions(+), 1 deletions(-)

diff --git a/include/libvirt/libvirt.h.in b/include/libvirt/libvirt.h.in
index 9a51c4f..ab6b90d 100644
--- a/include/libvirt/libvirt.h.in
+++ b/include/libvirt/libvirt.h.in
@@ -1474,12 +1474,37 @@ int                     virDomainGetMaxVcpus    (virDomainPtr domain);
 int                     virDomainGetSecurityLabel (virDomainPtr domain,
                                                    virSecurityLabelPtr seclabel);

+typedef enum {
+    VIR_DOMAIN_METADATA_DESCRIPTION = 0, /* Operate on <description> */
+    VIR_DOMAIN_METADATA_TITLE       = 1, /* Operate on <title> */
+    VIR_DOMAIN_METADATA_ELEMENT     = 2, /* Operate on <metadata> */
+
+#ifdef VIR_ENUM_SENTINELS
+    VIR_DOMAIN_METADATA_LAST
+#endif
+} virDomainMetadataType;
+
 /**
  * VIR_DOMAIN_TITLE_LENGTH:
  *
  * Maximum length of the string in the title field.
  */
 #define VIR_DOMAIN_TITLE_LENGTH 40
+
+int
+virDomainSetMetadata(virDomainPtr domain,
+                     int type,
+                     const char *metadata,
+                     const char *key,
+                     const char *uri,
+                     unsigned int flags);
+
+char *
+virDomainGetMetadata(virDomainPtr domain,
+                     int type,
+                     const char *uri,
+                     unsigned int flags);
+
 /*
  * XML domain description
  */
diff --git a/include/libvirt/virterror.h b/include/libvirt/virterror.h
index e896d67..4395637 100644
--- a/include/libvirt/virterror.h
+++ b/include/libvirt/virterror.h
@@ -243,6 +243,7 @@ typedef enum {
                                            risky domain snapshot revert */
     VIR_ERR_OPERATION_ABORTED = 78,     /* operation on a domain was
                                            canceled/aborted by user */
+    VIR_ERR_NO_DOMAIN_METADATA = 79,    /* The metadata is not present */
 } virErrorNumber;

 /**
diff --git a/src/driver.h b/src/driver.h
index df2aa60..153a5eb 100644
--- a/src/driver.h
+++ b/src/driver.h
@@ -797,6 +797,19 @@ typedef int
     (*virDrvDomainShutdownFlags)(virDomainPtr domain,
                                  unsigned int flags);

+typedef int
+    (*virDrvDomainSetMetadata)(virDomainPtr dom,
+                               int type,
+                               const char *metadata,
+                               const char *key,
+                               const char *uri,
+                               unsigned int flags);
+
+typedef char *
+    (*virDrvDomainGetMetadata)(virDomainPtr dom,
+                               int type,
+                               const char *uri,
+                               unsigned int flags);

 /**
  * _virDriver:
@@ -967,6 +980,8 @@ struct _virDriver {
     virDrvNodeSuspendForDuration nodeSuspendForDuration;
     virDrvDomainSetBlockIoTune domainSetBlockIoTune;
     virDrvDomainGetBlockIoTune domainGetBlockIoTune;
+    virDrvDomainSetMetadata domainSetMetadata;
+    virDrvDomainGetMetadata domainGetMetadata;
 };

 typedef int
diff --git a/src/libvirt.c b/src/libvirt.c
index e9d638b..d1a59de 100644
--- a/src/libvirt.c
+++ b/src/libvirt.c
@@ -8826,6 +8826,131 @@ error:
 }

 /**
+ * virDomainSetMetadata:
+ * @domain: a domain object
+ * @type: type of description, from virDomainMetadataType
+ * @metadata: new metadata text
+ * @key: XML namespace key, or NULL
+ * @uri: XML namespace URI, or NULL
+ * @flags: bitwise-OR of virDomainModificationImpact
+ *
+ * Sets the appropriate domain element given by @type to the
+ * value of @description.  A @type of VIR_DOMAIN_METADATA_DESCRIPTION
+ * is free-form text; VIR_DOMAIN_METADATA_TITLE is free-form but
+ * length-limited to 40 bytes. For these two options @key and @uri are
+ * irelevant and can be set to NULL.
+ *
+ * For type VIR_DOMAIN_METADATA_ELEMENT @metadata  must be well-formed
+ * XML belonging to namespace defined by @uri with local name @key.
+ *
+ * Passing NULL for @metadata says to remove that element from the
+ * domain XML (passing the empty string leaves the element present).
+ *
+ * The resulting metadata will be present in virDomainGetXMLDesc(),
+ * as well as quick access through virDomainGetMetadata().
+ *
+ * @flags controls whether the live domain, persistent configuration,
+ * or both will be modified.
+ *
+ * Returns 0 on success, -1 in case of failure.
+ */
+int
+virDomainSetMetadata(virDomainPtr domain,
+                     int type,
+                     const char *metadata,
+                     const char *key,
+                     const char *uri,
+                     unsigned int flags)
+{
+    virConnectPtr conn;
+
+    VIR_DOMAIN_DEBUG(domain, "type=%d, metadata=%p, key=%p, uri=%p flags=%x",
+                     type, metadata, key, uri, flags);
+
+    if (!VIR_IS_CONNECTED_DOMAIN(domain)) {
+        virLibDomainError(VIR_ERR_INVALID_DOMAIN, __FUNCTION__);
+        goto error;
+    }
+
+    conn = domain->conn;
+
+   if (conn->flags & VIR_CONNECT_RO) {
+        virLibDomainError(VIR_ERR_OPERATION_DENIED, __FUNCTION__);
+        goto error;
+    }
+
+    if (conn->driver->domainSetMetadata) {
+        int ret;
+        ret = conn->driver->domainSetMetadata(domain, type, metadata, key, uri,
+                                              flags);
+        if (ret < 0)
+            goto error;
+        return ret;
+    }
+
+    virLibConnError(VIR_ERR_NO_SUPPORT, __FUNCTION__);
+
+error:
+    virDispatchError(domain->conn);
+    return -1;
+}
+
+/**
+ * virDomainGetMetadata:
+ * @domain: a domain object
+ * @type: type of description, from virDomainMetadataType
+ * @uri: XML namespace identifier
+ * @flags: bitwise-OR of virDomainModificationImpact
+ *
+ * Retrieves the appropriate domain element given by @type.
+ * If VIR_DOMAIN_METADATA_ELEMENT is requested parameter @uri
+ * must be set to the name of the namespace the requested elements
+ * belong to.
+ *
+ * If an element of the domain XML is not present, the resulting
+ * error will be VIR_ERR_NO_DOMAIN_METADATA.  This method forms
+ * a shortcut for seeing information from virDomainSetMetadata()
+ * without having to go through virDomainGetXMLDesc().
+ *
+ * @flags controls whether the live domain or persistent
+ * configuration will be queried.
+ *
+ * Returns the metadata string on success (caller must free),
+ * or NULL in case of failure.
+ */
+char *
+virDomainGetMetadata(virDomainPtr domain,
+                     int type,
+                     const char *uri,
+                     unsigned int flags)
+{
+    virConnectPtr conn;
+
+    VIR_DOMAIN_DEBUG(domain, "type=%d, uri=%p, flags=%x",
+                     type, uri, flags);
+
+    if (!VIR_IS_CONNECTED_DOMAIN(domain)) {
+        virLibDomainError(VIR_ERR_INVALID_DOMAIN, __FUNCTION__);
+        goto error;
+    }
+
+    conn = domain->conn;
+
+    if (conn->driver->domainGetMetadata) {
+        char *ret;
+        if (!(ret = conn->driver->domainGetMetadata(domain, type, uri, flags)))
+            goto error;
+        return ret;
+    }
+
+    virLibConnError(VIR_ERR_NO_SUPPORT, __FUNCTION__);
+
+error:
+    virDispatchError(domain->conn);
+    return NULL;
+}
+
+/**
  * virNodeGetSecurityModel:
  * @conn: a connection object
  * @secmodel: pointer to a virSecurityModel structure
diff --git a/src/libvirt_public.syms b/src/libvirt_public.syms
index 1340b0c..f71ba22 100644
--- a/src/libvirt_public.syms
+++ b/src/libvirt_public.syms
@@ -520,6 +520,8 @@ LIBVIRT_0.9.10 {
     global:
         virDomainShutdownFlags;
         virStorageVolWipePattern;
+        virDomainSetMetadata;
+        virDomainGetMetadata;
 } LIBVIRT_0.9.9;

 # .... define new API here using predicted next version number ....
diff --git a/src/remote/remote_driver.c b/src/remote/remote_driver.c
index f79f53e..c70f5a6 100644
--- a/src/remote/remote_driver.c
+++ b/src/remote/remote_driver.c
@@ -4751,6 +4751,8 @@ static virDriver remote_driver = {
     .domainGetBlockIoTune = remoteDomainGetBlockIoTune, /* 0.9.8 */
     .domainSetNumaParameters = remoteDomainSetNumaParameters, /* 0.9.9 */
     .domainGetNumaParameters = remoteDomainGetNumaParameters, /* 0.9.9 */
+    .domainSetMetadata = remoteDomainSetMetadata, /* 0.9.10 */
+    .domainGetMetadata = remoteDomainGetMetadata, /* 0.9.10 */
 };

 static virNetworkDriver network_driver = {
diff --git a/src/remote/remote_protocol.x b/src/remote/remote_protocol.x
index 0f354bb..b4d2035 100644
--- a/src/remote/remote_protocol.x
+++ b/src/remote/remote_protocol.x
@@ -1096,6 +1096,26 @@ struct remote_domain_set_autostart_args {
     int autostart;
 };

+struct remote_domain_set_metadata_args {
+    remote_nonnull_domain dom;
+    int type;
+    remote_string metadata;
+    remote_string key;
+    remote_string uri;
+    unsigned int flags;
+};
+
+struct remote_domain_get_metadata_args {
+    remote_nonnull_domain dom;
+    int type;
+    remote_string uri;
+    unsigned int flags;
+};
+
+struct remote_domain_get_metadata_ret {
+    remote_string metadata;
+};
+
 struct remote_domain_block_job_abort_args {
     remote_nonnull_domain dom;
     remote_nonnull_string path;
@@ -2667,7 +2687,10 @@ enum remote_procedure {
     REMOTE_PROC_DOMAIN_SET_INTERFACE_PARAMETERS = 256, /* autogen autogen */
     REMOTE_PROC_DOMAIN_GET_INTERFACE_PARAMETERS = 257, /* skipgen skipgen */
     REMOTE_PROC_DOMAIN_SHUTDOWN_FLAGS = 258, /* autogen autogen */
-    REMOTE_PROC_STORAGE_VOL_WIPE_PATTERN = 259 /* autogen autogen */
+    REMOTE_PROC_STORAGE_VOL_WIPE_PATTERN = 259, /* autogen autogen */
+    REMOTE_PROC_DOMAIN_SET_METADATA = 260, /* autogen autogen */
+
+    REMOTE_PROC_DOMAIN_GET_METADATA = 261 /* autogen autogen */

     /*
      * Notice how the entries are grouped in sets of 10 ?
diff --git a/src/util/virterror.c b/src/util/virterror.c
index 85eec8d..5bcfe79 100644
--- a/src/util/virterror.c
+++ b/src/util/virterror.c
@@ -1220,6 +1220,12 @@ virErrorMsg(virErrorNumber error, const char *info)
             else
                 errmsg = _("operation aborted: %s");
             break;
+        case VIR_ERR_NO_DOMAIN_METADATA:
+            if (info == NULL)
+                errmsg = _("metadata not found");
+            else
+                errmsg = _("metadata not found");
+            break;
     }
     return (errmsg);
 }
-- 
1.7.3.4


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