[libvirt] [PATCH 10/17] virudev: Introduce virUdevMgrLookupLabels

Michal Privoznik mprivozn at redhat.com
Wed Oct 26 12:36:57 UTC 2016


This is the cherry on the top. For given device all its security
labels are fetched.

Signed-off-by: Michal Privoznik <mprivozn at redhat.com>
---
 src/libvirt_private.syms |  1 +
 src/util/virudev.c       | 43 +++++++++++++++++++++++
 src/util/virudev.h       |  4 +++
 tests/virudevtest.c      | 91 ++++++++++++++++++++++++++++++++++++++++++++++++
 4 files changed, 139 insertions(+)

diff --git a/src/libvirt_private.syms b/src/libvirt_private.syms
index 3369600..a0de4e9 100644
--- a/src/libvirt_private.syms
+++ b/src/libvirt_private.syms
@@ -2577,6 +2577,7 @@ virTypedParamsValidate;
 virUdevMgrAddLabel;
 virUdevMgrDumpFile;
 virUdevMgrDumpStr;
+virUdevMgrLookupLabels;
 virUdevMgrNew;
 virUdevMgrNewFromFile;
 virUdevMgrNewFromStr;
diff --git a/src/util/virudev.c b/src/util/virudev.c
index d60fbf9..9940f5f 100644
--- a/src/util/virudev.c
+++ b/src/util/virudev.c
@@ -300,6 +300,49 @@ virUdevMgrAddLabel(virUdevMgrPtr mgr,
 
 
 int
+virUdevMgrLookupLabels(virUdevMgrPtr mgr,
+                       const char *device,
+                       virSecurityDeviceLabelDefPtr **seclabels,
+                       size_t *nseclabels)
+{
+    int ret = -1;
+    udevSeclabelPtr list;
+    size_t i;
+
+    virObjectLock(mgr);
+
+    if (!(list = virHashLookup(mgr->labels, device))) {
+        *seclabels = NULL;
+        *nseclabels = 0;
+        ret = 0;
+        goto cleanup;
+    }
+
+    if (VIR_ALLOC_N(*seclabels, list->nseclabels) < 0)
+        goto cleanup;
+
+    *nseclabels = list->nseclabels;
+
+    for (i = 0; i < list->nseclabels; i++) {
+        if (!((*seclabels)[i] = virSecurityDeviceLabelDefCopy(list->seclabels[i])))
+            goto cleanup;
+    }
+
+    ret = 0;
+ cleanup:
+    virObjectUnlock(mgr);
+    if (ret < 0) {
+        if (*seclabels) {
+            for (i = 0; i < *nseclabels; i++)
+                virSecurityDeviceLabelDefFree((*seclabels)[i]);
+            VIR_FREE(*seclabels);
+        }
+    }
+    return ret;
+}
+
+
+int
 virUdevMgrRemoveAllLabels(virUdevMgrPtr mgr,
                           const char *device)
 {
diff --git a/src/util/virudev.h b/src/util/virudev.h
index 82b2b4f..4e286bb 100644
--- a/src/util/virudev.h
+++ b/src/util/virudev.h
@@ -37,6 +37,10 @@ int virUdevMgrAddLabel(virUdevMgrPtr mgr,
                        const virSecurityDeviceLabelDef *seclabel);
 int virUdevMgrRemoveAllLabels(virUdevMgrPtr mgr,
                               const char *device);
+int virUdevMgrLookupLabels(virUdevMgrPtr mgr,
+                           const char *device,
+                           virSecurityDeviceLabelDefPtr **seclabels,
+                           size_t *nseclabels);
 
 char *virUdevMgrDumpStr(virUdevMgrPtr mgr);
 
diff --git a/tests/virudevtest.c b/tests/virudevtest.c
index c395741..36a9077 100644
--- a/tests/virudevtest.c
+++ b/tests/virudevtest.c
@@ -124,6 +124,76 @@ testParse(const void *opaque)
 
 
 static int
+testLookup(const void *opaque)
+{
+    const struct testUdevData *data = opaque;
+    virUdevMgrPtr mgr = NULL;
+    int ret = -1;
+    const char * const *tmp;
+    char *filename = NULL;
+    virSecurityDeviceLabelDefPtr *seclabels = NULL;
+    size_t i, nseclabels = 0;
+
+    if (virAsprintf(&filename, "%s/virudevtestdata/%s.json",
+                    abs_srcdir, data->file) < 0)
+        goto cleanup;
+
+    if (!(mgr = virUdevMgrNewFromFile(filename)))
+        goto cleanup;
+
+    tmp = data->labels;
+    while (*tmp) {
+        const char *device;
+        const char *model;
+        const char *label;
+
+        device = *tmp;
+        if (!++tmp) {
+            virReportError(VIR_ERR_INTERNAL_ERROR, "%s", "Invalid seclabels list");
+            goto cleanup;
+        }
+        model = *tmp;
+        if (!++tmp) {
+            virReportError(VIR_ERR_INTERNAL_ERROR, "%s", "Invalid seclabels list");
+            goto cleanup;
+        }
+        label = *tmp;
+        tmp++;
+
+        if (virUdevMgrLookupLabels(mgr, device, &seclabels, &nseclabels) < 0)
+            goto cleanup;
+
+        for (i = 0; i < nseclabels; i++) {
+            virSecurityDeviceLabelDefPtr seclabel = seclabels[i];
+
+            if (STREQ(seclabel->model, model) &&
+                STREQ(seclabel->label, label))
+                break;
+        }
+
+        if (i == nseclabels) {
+            virReportError(VIR_ERR_INTERNAL_ERROR, "%s", "Label not found");
+            goto cleanup;
+        }
+
+        for (i = 0; i < nseclabels; i++)
+            virSecurityDeviceLabelDefFree(seclabels[i]);
+        VIR_FREE(seclabels);
+        nseclabels = 0;
+    }
+
+    ret = 0;
+ cleanup:
+    for (i = 0; i < nseclabels; i++)
+        virSecurityDeviceLabelDefFree(seclabels[i]);
+    VIR_FREE(seclabels);
+    VIR_FREE(filename);
+    virObjectUnref(mgr);
+    return ret;
+}
+
+
+static int
 mymain(void)
 {
     int ret = 0;
@@ -147,6 +217,16 @@ mymain(void)
             ret = -1;                                               \
     } while (0)
 
+#define DO_TEST_LOOKUP(filename, ...)                               \
+    do {                                                            \
+        const char *labels[] = {__VA_ARGS__, NULL};                 \
+        struct testUdevData data = {                                \
+            .file = filename, .labels = labels,                     \
+        };                                                          \
+        if (virTestRun("Lookup " filename, testLookup, &data) < 0)  \
+            ret = -1;                                               \
+    } while (0)
+
     DO_TEST_DUMP("empty", NULL);
     DO_TEST_DUMP("simple-selinux",
                  "/dev/sda", "selinux", "someSELinuxLabel");
@@ -163,6 +243,17 @@ mymain(void)
     DO_TEST_PARSE("simple-dac");
     DO_TEST_PARSE("complex");
 
+    DO_TEST_LOOKUP("empty", NULL);
+    DO_TEST_LOOKUP("simple-selinux",
+                   "/dev/sda", "selinux", "someSELinuxLabel");
+    DO_TEST_LOOKUP("simple-dac",
+                   "/dev/sda", "dac", "someDACLabel");
+    DO_TEST_LOOKUP("complex",
+                   "/dev/sda", "dac",     "someDACLabel",
+                   "/dev/sda", "selinux", "someSELinuxLabel",
+                   "/dev/sdb", "dac",     "otherDACLabel",
+                   "/dev/sdb", "selinux", "otherSELinuxLabel");
+
     return ret == 0 ? EXIT_SUCCESS : EXIT_FAILURE;
 }
 
-- 
2.8.4




More information about the libvir-list mailing list