[libvirt] [PATCH RFC 3/3] security_dac: Implement {save, load}Status

Michal Privoznik mprivozn at redhat.com
Tue Feb 26 16:08:42 UTC 2013


---
 src/security/security_dac.c | 116 +++++++++++++++++++++++++++++++++++++++++++-
 1 file changed, 115 insertions(+), 1 deletion(-)

diff --git a/src/security/security_dac.c b/src/security/security_dac.c
index 4b8f0a2..f2d8c67 100644
--- a/src/security/security_dac.c
+++ b/src/security/security_dac.c
@@ -42,6 +42,7 @@ struct _virSecurityDACData {
     uid_t user;
     gid_t group;
     bool dynamicOwnership;
+    bool updated; /* has the state changed since last virSecurityDACSaveStatus? */
     virHashTablePtr oldOwners; /* to hold pairs <path, virOldLabelPtr> */
 };
 
@@ -65,6 +66,15 @@ hashDataFree(void *payload, const void *name ATTRIBUTE_UNUSED)
     virOldLabelFree(payload);
 }
 
+static void
+hashDataToXML(void *payload, const void *name, void *data)
+{
+    virOldLabelPtr label = payload;
+
+    virBufferAsprintf(data, "<label path='%s' owner='%s' refCount='%d'/>\n",
+                      (const char *)name, label->owner, label->refCount);
+}
+
 /**
  * virSecurityDACRememberLabel:
  * @priv:   private DAC driver data
@@ -114,7 +124,7 @@ virSecurityDACRememberLabel(virSecurityDACDataPtr priv,
 cleanup:
     VIR_FREE(user);
     VIR_FREE(group);
-    return oldLabel ? oldLabel->refCount : -1;
+    return oldLabel ? priv->updated = true, oldLabel->refCount : -1;
 }
 
 static int parseIds(const char *label, uid_t *uidPtr, gid_t *gidPtr);
@@ -147,6 +157,7 @@ virSecurityDACGetRememberedLabel(virSecurityDACDataPtr priv,
         goto cleanup;
 
     ret = --oldLabel->refCount;
+    priv->updated = true;
 
     if (!ret) {
         ret = parseIds(oldLabel->owner, user, group);
@@ -372,6 +383,106 @@ virSecurityDACClose(virSecurityManagerPtr mgr)
     return 0;
 }
 
+static int
+virSecurityDACSaveStatus(virSecurityManagerPtr mgr,
+                         virBufferPtr *buf,
+                         bool force)
+{
+    virSecurityDACDataPtr priv = virSecurityManagerGetPrivateData(mgr);
+    int ret = -1;
+
+    if (!force && !priv->updated) {
+        *buf = NULL;
+        return 0;
+    }
+
+    priv->updated = false;
+
+    virBufferAddLit(*buf, "<securityDriver>\n");
+    virBufferAddLit(*buf, "  <oldLabel>\n");
+    virBufferAdjustIndent(*buf, 4);
+
+    ret = virHashForEach(priv->oldOwners, hashDataToXML, *buf);
+
+    virBufferAdjustIndent(*buf, -4);
+    virBufferAddLit(*buf, "  </oldLabel>\n");
+    virBufferAddLit(*buf, "</securityDriver>\n");
+    return ret;
+}
+
+static int
+virSecurityDACLoadStatus(virSecurityManagerPtr mgr,
+                         xmlDocPtr doc)
+{
+    virSecurityDACDataPtr priv = virSecurityManagerGetPrivateData(mgr);
+    int i, n, ret = -1;
+    xmlNodePtr *nodes = NULL, root = xmlDocGetRootElement(doc);
+    xmlXPathContextPtr ctxt = NULL;
+    char *path = NULL,*owner = NULL, *refCountStr = NULL;
+    virOldLabelPtr oldLabel = NULL;
+
+    if (!xmlStrEqual(root->name, BAD_CAST "securityDriver")) {
+        virReportError(VIR_ERR_XML_ERROR,
+                       _("unexpected root element <%s>, "
+                         "expecting <securityDriver>"),
+                       root->name);
+        return ret;
+    }
+
+    if (!(ctxt = xmlXPathNewContext(doc))) {
+        virReportOOMError();
+        return ret;
+    }
+
+    ctxt->node = root;
+
+    n = virXPathNodeSet("./oldLabel/label", ctxt, &nodes);
+    if (n < 0)
+        goto cleanup;
+
+    for (i = 0; i < n; i++) {
+        path = virXMLPropString(nodes[i], "path");
+        owner = virXMLPropString(nodes[i], "owner");
+        refCountStr = virXMLPropString(nodes[i], "refCount");
+
+        if (!path || !owner || !refCountStr) {
+            virReportError(VIR_ERR_XML_DETAIL, "%s",
+                           _("Malformed security driver xml"));
+            goto cleanup;
+        }
+        if (VIR_ALLOC(oldLabel) < 0) {
+            virReportOOMError();
+            goto cleanup;
+        }
+
+        if (virStrToLong_i(refCountStr, NULL, 10, &oldLabel->refCount) < 0) {
+            virReportError(VIR_ERR_XML_DETAIL,
+                           _("Malformed refCount attribute: %s"),
+                           refCountStr);
+            goto cleanup;
+        }
+
+        oldLabel->owner = owner;
+        owner = NULL;
+
+        if (virHashUpdateEntry(priv->oldOwners, path, oldLabel) < 0)
+            goto cleanup;
+
+        path = NULL;
+        oldLabel = NULL;
+        VIR_FREE(refCountStr);
+    }
+
+    ret = 0;
+cleanup:
+    virOldLabelFree(oldLabel);
+    VIR_FREE(path);
+    VIR_FREE(owner);
+    VIR_FREE(refCountStr);
+    VIR_FREE(nodes);
+    xmlXPathFreeContext(ctxt);
+    return ret;
+}
 
 static const char * virSecurityDACGetModel(virSecurityManagerPtr mgr ATTRIBUTE_UNUSED)
 {
@@ -1304,6 +1415,9 @@ virSecurityDriver virSecurityDriverDAC = {
     .open                               = virSecurityDACOpen,
     .close                              = virSecurityDACClose,
 
+    .saveStatus                         = virSecurityDACSaveStatus,
+    .loadStatus                         = virSecurityDACLoadStatus,
+
     .getModel                           = virSecurityDACGetModel,
     .getDOI                             = virSecurityDACGetDOI,
 
-- 
1.8.1.4




More information about the libvir-list mailing list