This is the cherry on the top. For given device all its security
labels are fetched.
Signed-off-by: Michal Privoznik <mprivozn(a)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 0f08018..037443b 100644
--- a/src/libvirt_private.syms
+++ b/src/libvirt_private.syms
@@ -2581,6 +2581,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