Introduce a new struct to act as the stateful owner of the
virNWFilterBindingDefPtr objects.
Signed-off-by: Daniel P. Berrangé <berrange(a)redhat.com>
---
src/conf/Makefile.inc.am | 2 +
src/conf/virnwfilterbindingobj.c | 260 +++++++++++++++++++++++++++++++
src/conf/virnwfilterbindingobj.h | 60 +++++++
src/libvirt_private.syms | 10 ++
4 files changed, 332 insertions(+)
create mode 100644 src/conf/virnwfilterbindingobj.c
create mode 100644 src/conf/virnwfilterbindingobj.h
diff --git a/src/conf/Makefile.inc.am b/src/conf/Makefile.inc.am
index f5fb323233..3d55ba688d 100644
--- a/src/conf/Makefile.inc.am
+++ b/src/conf/Makefile.inc.am
@@ -87,6 +87,8 @@ NWFILTER_CONF_SOURCES = \
conf/virnwfilterobj.h \
conf/virnwfilterbindingdef.c \
conf/virnwfilterbindingdef.h \
+ conf/virnwfilterbindingobj.c \
+ conf/virnwfilterbindingobj.h \
$(NULL)
STORAGE_CONF_SOURCES = \
diff --git a/src/conf/virnwfilterbindingobj.c b/src/conf/virnwfilterbindingobj.c
new file mode 100644
index 0000000000..15aaf89b5c
--- /dev/null
+++ b/src/conf/virnwfilterbindingobj.c
@@ -0,0 +1,260 @@
+/*
+ * virnwfilterbindingobj.c: network filter binding XML processing
+ *
+ * Copyright (C) 2018 Red Hat, Inc.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library. If not, see
+ * <
http://www.gnu.org/licenses/>.
+ */
+
+#include <config.h>
+
+#include "viralloc.h"
+#include "virerror.h"
+#include "virstring.h"
+#include "nwfilter_params.h"
+#include "virnwfilterbindingobj.h"
+#include "viruuid.h"
+#include "virfile.h"
+
+
+#define VIR_FROM_THIS VIR_FROM_NWFILTER
+
+static virClassPtr virNWFilterBindingObjClass;
+static void virNWFilterBindingObjDispose(void *obj);
+
+static int virNWFilterBindingObjOnceInit(void)
+{
+ if (!VIR_CLASS_NEW(virNWFilterBindingObj, virClassForObjectLockable()))
+ return -1;
+
+ return 0;
+}
+
+VIR_ONCE_GLOBAL_INIT(virNWFilterBindingObj)
+
+virNWFilterBindingObjPtr
+virNWFilterBindingObjNew(void)
+{
+ if (virNWFilterBindingObjInitialize() < 0)
+ return NULL;
+
+ return virObjectNew(virNWFilterBindingObjClass);
+}
+
+void
+virNWFilterBindingObjDispose(void *obj)
+{
+ virNWFilterBindingObjPtr bobj = obj;
+
+ virNWFilterBindingDefFree(bobj->def);
+}
+
+
+/**
+ * virNWFilterBindingnObjEndAPI:
+ * @obj: binding object
+ *
+ * Finish working with a binding object in an API. This function
+ * clears whatever was left of a domain that was gathered using
+ * virNWFilterBindingObjListFindByPortDev(). Currently that means
+ * only unlocking and decrementing the reference counter of that
+ * object. And in order to make sure the caller does not access
+ * the object, the pointer is cleared.
+ */
+void
+virNWFilterBindingObjEndAPI(virNWFilterBindingObjPtr *obj)
+{
+ if (!*obj)
+ return;
+
+ virObjectUnlock(*obj);
+ virObjectUnref(*obj);
+ *obj = NULL;
+}
+
+
+char *
+virNWFilterBindingObjConfigFile(const char *dir,
+ const char *name)
+{
+ char *ret;
+
+ ignore_value(virAsprintf(&ret, "%s/%s.xml", dir, name));
+ return ret;
+}
+
+
+int
+virNWFilterBindingObjSave(const virNWFilterBindingObj *obj,
+ const char *statusDir)
+{
+ char *filename;
+ char *xml = NULL;
+ int ret = -1;
+
+ if (!(filename = virNWFilterBindingObjConfigFile(statusDir,
+ obj->def->portdevname)))
+ return -1;
+
+ if (!(xml = virNWFilterBindingObjFormat(obj)))
+ goto cleanup;
+
+ if (virFileMakePath(statusDir) < 0) {
+ virReportSystemError(errno,
+ _("cannot create config directory '%s'"),
+ statusDir);
+ goto cleanup;
+ }
+
+ ret = virXMLSaveFile(filename,
+ obj->def->portdevname,
"nwfilter-binding-create",
+ xml);
+
+ cleanup:
+ VIR_FREE(xml);
+ VIR_FREE(filename);
+ return ret;
+}
+
+
+int
+virNWFilterBindingObjDelete(const virNWFilterBindingObj *obj,
+ const char *statusDir)
+{
+ char *filename;
+ int ret = -1;
+
+ if (!(filename = virNWFilterBindingObjConfigFile(statusDir,
+ obj->def->portdevname)))
+ return -1;
+
+ if (unlink(filename) < 0 &&
+ errno != ENOENT) {
+ virReportSystemError(errno,
+ _("Unable to remove status '%s' for nwfilter
binding %s'"),
+ filename, obj->def->portdevname);
+ goto cleanup;
+ }
+
+ ret = 0;
+
+ cleanup:
+ VIR_FREE(filename);
+ return ret;
+}
+
+
+static virNWFilterBindingObjPtr
+virNWFilterBindingObjParseXML(xmlDocPtr doc,
+ xmlXPathContextPtr ctxt)
+{
+ virNWFilterBindingObjPtr ret;
+ xmlNodePtr node;
+
+ if (VIR_ALLOC(ret) < 0)
+ return NULL;
+
+ if (!(node = virXPathNode("./filterbinding", ctxt))) {
+ virReportError(VIR_ERR_INTERNAL_ERROR,
+ "%s", _("filter binding status missing
binding"));
+ goto cleanup;
+ }
+
+ if (!(ret->def = virNWFilterBindingDefParseNode(doc, node)))
+ goto cleanup;
+
+ return ret;
+
+ cleanup:
+ virObjectUnref(ret);
+ return NULL;
+}
+
+
+static virNWFilterBindingObjPtr
+virNWFilterBindingObjParseNode(xmlDocPtr doc,
+ xmlNodePtr root)
+{
+ xmlXPathContextPtr ctxt = NULL;
+ virNWFilterBindingObjPtr obj = NULL;
+
+ if (STRNEQ((const char *)root->name, "filterbindingb")) {
+ virReportError(VIR_ERR_XML_ERROR,
+ "%s",
+ _("unknown root element for nw filter"));
+ goto cleanup;
+ }
+
+ ctxt = xmlXPathNewContext(doc);
+ if (ctxt == NULL) {
+ virReportOOMError();
+ goto cleanup;
+ }
+
+ ctxt->node = root;
+ obj = virNWFilterBindingObjParseXML(doc, ctxt);
+
+ cleanup:
+ xmlXPathFreeContext(ctxt);
+ return obj;
+}
+
+
+static virNWFilterBindingObjPtr
+virNWFilterBindingObjParse(const char *xmlStr,
+ const char *filename)
+{
+ virNWFilterBindingObjPtr obj = NULL;
+ xmlDocPtr xml;
+
+ if ((xml = virXMLParse(filename, xmlStr, _("(nwfilterbinding_status)"))))
{
+ obj = virNWFilterBindingObjParseNode(xml, xmlDocGetRootElement(xml));
+ xmlFreeDoc(xml);
+ }
+
+ return obj;
+}
+
+
+
+virNWFilterBindingObjPtr
+virNWFilterBindingObjParseFile(const char *filename)
+{
+ return virNWFilterBindingObjParse(NULL, filename);
+}
+
+
+char *
+virNWFilterBindingObjFormat(const virNWFilterBindingObj *obj)
+{
+ virBuffer buf = VIR_BUFFER_INITIALIZER;
+
+ virBufferAddLit(&buf, "<filterbindingstatus>\n");
+
+ virBufferAdjustIndent(&buf, 2);
+
+ if (virNWFilterBindingDefFormatBuf(&buf, obj->def) < 0) {
+ virBufferFreeAndReset(&buf);
+ return NULL;
+ }
+
+ virBufferAdjustIndent(&buf, -2);
+ virBufferAddLit(&buf, "</filterbindingstatus>\n");
+
+ if (virBufferCheckError(&buf) < 0)
+ return NULL;
+
+ return virBufferContentAndReset(&buf);
+}
diff --git a/src/conf/virnwfilterbindingobj.h b/src/conf/virnwfilterbindingobj.h
new file mode 100644
index 0000000000..e0f1806ca0
--- /dev/null
+++ b/src/conf/virnwfilterbindingobj.h
@@ -0,0 +1,60 @@
+/*
+ * virnwfilterbindingobj.h: network filter binding XML processing
+ *
+ * Copyright (C) 2018 Red Hat, Inc.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library. If not, see
+ * <
http://www.gnu.org/licenses/>.
+ *
+ */
+#ifndef VIR_NWFILTER_BINDING_OBJ_H
+# define VIR_NWFILTER_BINDING_OBJ_H
+
+# include "internal.h"
+# include "virnwfilterbindingdef.h"
+# include "virobject.h"
+
+typedef struct _virNWFilterBindingObj virNWFilterBindingObj;
+typedef virNWFilterBindingObj *virNWFilterBindingObjPtr;
+
+struct _virNWFilterBindingObj {
+ virObjectLockable parent;
+
+ bool removing;
+ virNWFilterBindingDefPtr def;
+};
+
+virNWFilterBindingObjPtr
+virNWFilterBindingObjNew(void);
+
+void virNWFilterBindingObjEndAPI(virNWFilterBindingObjPtr *obj);
+
+char *virNWFilterBindingObjConfigFile(const char *dir,
+ const char *name);
+
+int
+virNWFilterBindingObjSave(const virNWFilterBindingObj *obj,
+ const char *statusDir);
+
+int
+virNWFilterBindingObjDelete(const virNWFilterBindingObj *obj,
+ const char *statusDir);
+
+virNWFilterBindingObjPtr
+virNWFilterBindingObjParseFile(const char *filename);
+
+char *
+virNWFilterBindingObjFormat(const virNWFilterBindingObj *obj);
+
+#endif /* VIR_NWFILTER_BINDING_OBJ_H */
diff --git a/src/libvirt_private.syms b/src/libvirt_private.syms
index 0ce685b6f2..92ad2e983f 100644
--- a/src/libvirt_private.syms
+++ b/src/libvirt_private.syms
@@ -1051,6 +1051,16 @@ virNWFilterBindingDefParseNode;
virNWFilterBindingDefParseString;
+# conf/virnwfilterbindingobj.h
+virNWFilterBindingObjConfigFile;
+virNWFilterBindingObjDelete;
+virNWFilterBindingObjEndAPI;
+virNWFilterBindingObjFormat;
+virNWFilterBindingObjNew;
+virNWFilterBindingObjParseFile;
+virNWFilterBindingObjSave;
+
+
# conf/virnwfilterobj.h
virNWFilterObjGetDef;
virNWFilterObjGetNewDef;
--
2.17.0