These APIs start to implement what was laid out in the module
description. We need to be able to store given security label (on
domain startup, device attach), and then remove all security
labels associated with it (on domain shutdown, device detach).
Signed-off-by: Michal Privoznik <mprivozn(a)redhat.com>
---
src/libvirt_private.syms | 2 +
src/util/virudev.c | 142 ++++++++++++++++++++++++++++++++++++++++++++++-
src/util/virudev.h | 8 +++
3 files changed, 149 insertions(+), 3 deletions(-)
diff --git a/src/libvirt_private.syms b/src/libvirt_private.syms
index 40c5d27..073b00f 100644
--- a/src/libvirt_private.syms
+++ b/src/libvirt_private.syms
@@ -2578,7 +2578,9 @@ virTypedParamsValidate;
# util/virudev.h
+virUdevMgrAddLabel;
virUdevMgrNew;
+virUdevMgrRemoveAllLabels;
# util/viruri.h
diff --git a/src/util/virudev.c b/src/util/virudev.c
index 66b5a58..f4799e7 100644
--- a/src/util/virudev.c
+++ b/src/util/virudev.c
@@ -22,20 +22,101 @@
#include <config.h>
-#include "virudev.h"
+#include "internal.h"
+#include "viralloc.h"
+#include "virhash.h"
#include "virobject.h"
+#include "virudev.h"
+
+#define VIR_FROM_THIS VIR_FROM_SECURITY
struct _virUdevMgr {
virObjectLockable parent;
+ virHashTablePtr labels;
};
+struct _udevSeclabel {
+ virSecurityDeviceLabelDefPtr *seclabels;
+ size_t nseclabels;
+};
+
+typedef struct _udevSeclabel udevSeclabel;
+typedef udevSeclabel *udevSeclabelPtr;
+
static virClassPtr virUdevMgrClass;
+static virSecurityDeviceLabelDefPtr
+udevSeclabelFindByModel(udevSeclabelPtr list,
+ const char *model)
+{
+ size_t i;
+
+ for (i = 0; list && i < list->nseclabels; i++) {
+ if (STREQ(list->seclabels[i]->model, model))
+ return list->seclabels[i];
+ }
+
+ return NULL;
+}
+
+
+static int
+udevSeclabelAppend(udevSeclabelPtr list,
+ const virSecurityDeviceLabelDef *seclabel)
+{
+ virSecurityDeviceLabelDefPtr copy = virSecurityDeviceLabelDefCopy(seclabel);
+ if (VIR_APPEND_ELEMENT_COPY(list->seclabels, list->nseclabels, copy) < 0) {
+ virSecurityDeviceLabelDefFree(copy);
+ return -1;
+ }
+ return 0;
+}
+
+
+static void
+udevSeclabelFree(void *payload,
+ const void *name ATTRIBUTE_UNUSED)
+{
+ udevSeclabelPtr list = payload;
+ size_t i;
+
+ if (!list)
+ return;
+
+ for (i = 0; i < list->nseclabels; i++)
+ virSecurityDeviceLabelDefFree(list->seclabels[i]);
+ VIR_FREE(list->seclabels);
+ VIR_FREE(list);
+}
+
+
+static int
+udevSeclabelUpdate(udevSeclabelPtr list,
+ const virSecurityDeviceLabelDef *seclabel)
+{
+ size_t i;
+
+ for (i = 0; list && i < list->nseclabels; i++) {
+ if (STREQ(list->seclabels[i]->model, seclabel->model)) {
+ virSecurityDeviceLabelDefPtr copy = virSecurityDeviceLabelDefCopy(seclabel);
+ if (!copy)
+ return -1;
+ virSecurityDeviceLabelDefFree(list->seclabels[i]);
+ list->seclabels[i] = copy;
+ return 0;
+ }
+ }
+
+ return -1;
+}
+
+
static void
-virUdevMgrDispose(void *obj ATTRIBUTE_UNUSED)
+virUdevMgrDispose(void *obj)
{
- /* nada */
+ virUdevMgrPtr mgr = obj;
+ virHashFree(mgr->labels);
}
@@ -64,5 +145,60 @@ virUdevMgrPtr virUdevMgrNew(void)
if (!(mgr = virObjectLockableNew(virUdevMgrClass)))
return NULL;
+ if (!(mgr->labels = virHashCreate(10, udevSeclabelFree)))
+ goto error;
+
return mgr;
+
+ error:
+ virObjectUnref(mgr);
+ return NULL;
+}
+
+
+int
+virUdevMgrAddLabel(virUdevMgrPtr mgr,
+ const char *device,
+ const virSecurityDeviceLabelDef *seclabel)
+{
+ int ret = -1;
+ udevSeclabelPtr list;
+
+ virObjectLock(mgr);
+
+ if ((list = virHashLookup(mgr->labels, device))) {
+ virSecurityDeviceLabelDefPtr entry = udevSeclabelFindByModel(list,
seclabel->model);
+
+ if (entry) {
+ udevSeclabelUpdate(list, seclabel);
+ } else {
+ if (udevSeclabelAppend(list, seclabel) < 0)
+ goto cleanup;
+ }
+ } else {
+ if (VIR_ALLOC(list) < 0 ||
+ udevSeclabelAppend(list, seclabel) < 0 ||
+ virHashAddEntry(mgr->labels, device, list) < 0) {
+ udevSeclabelFree(list, NULL);
+ goto cleanup;
+ }
+ }
+
+ ret = 0;
+ cleanup:
+ virObjectUnlock(mgr);
+ return ret;
+}
+
+
+int
+virUdevMgrRemoveAllLabels(virUdevMgrPtr mgr,
+ const char *device)
+{
+ int ret = -1;
+
+ virObjectLock(mgr);
+ ret = virHashRemoveEntry(mgr->labels, device);
+ virObjectUnlock(mgr);
+ return ret;
}
diff --git a/src/util/virudev.h b/src/util/virudev.h
index 28e336f..692b39b 100644
--- a/src/util/virudev.h
+++ b/src/util/virudev.h
@@ -23,9 +23,17 @@
#ifndef __VIR_UDEV_H__
# define __VIR_UDEV_H__
+# include "virseclabel.h"
+
typedef struct _virUdevMgr virUdevMgr;
typedef virUdevMgr *virUdevMgrPtr;
virUdevMgrPtr virUdevMgrNew(void);
+int virUdevMgrAddLabel(virUdevMgrPtr mgr,
+ const char *device,
+ const virSecurityDeviceLabelDef *seclabel);
+int virUdevMgrRemoveAllLabels(virUdevMgrPtr mgr,
+ const char *device);
+
#endif
--
2.8.4