From 191b4396d3b894ab099dec52e75d1175d244eb03 Mon Sep 17 00:00:00 2001 From: Daniel P. Berrangé Date: Jun 26 2018 10:22:07 +0000 Subject: conf: introduce a virNWFilterBindingObjPtr struct Introduce a new struct to act as the stateful owner of the virNWFilterBindingDefPtr objects. Reviewed-by: John Ferlan Signed-off-by: Daniel P. Berrangé --- diff --git a/src/conf/Makefile.inc.am b/src/conf/Makefile.inc.am index f5fb323..3d55ba6 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 0000000..a145fb4 --- /dev/null +++ b/src/conf/virnwfilterbindingobj.c @@ -0,0 +1,299 @@ +/* + * virnwfilterbindingobj.c: network filter binding object 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 + * . + */ + +#include + +#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 + +struct _virNWFilterBindingObj { + virObjectLockable parent; + + bool removing; + virNWFilterBindingDefPtr def; +}; + + +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); +} + + +static void +virNWFilterBindingObjDispose(void *obj) +{ + virNWFilterBindingObjPtr bobj = obj; + + virNWFilterBindingDefFree(bobj->def); +} + + +virNWFilterBindingDefPtr +virNWFilterBindingObjGetDef(virNWFilterBindingObjPtr obj) +{ + return obj->def; +} + + +void +virNWFilterBindingObjSetDef(virNWFilterBindingObjPtr obj, + virNWFilterBindingDefPtr def) +{ + virNWFilterBindingDefFree(obj->def); + obj->def = def; +} + + +bool +virNWFilterBindingObjGetRemoving(virNWFilterBindingObjPtr obj) +{ + return obj->removing; +} + + +void +virNWFilterBindingObjSetRemoving(virNWFilterBindingObjPtr obj, + bool removing) +{ + obj->removing = removing; +} + + +/** + * virNWFilterBindingObjEndAPI: + * @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 (!(ret = virNWFilterBindingObjNew())) + return NULL; + + if (!(node = virXPathNode("./filterbindingstatus", ctxt))) { + virReportError(VIR_ERR_INTERNAL_ERROR, "%s", + _("filter binding status missing content")); + 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, "filterbinding")) { + virReportError(VIR_ERR_XML_ERROR, "%s", + _("unknown root element for filter binding")); + 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, "\n"); + + virBufferAdjustIndent(&buf, 2); + + if (virNWFilterBindingDefFormatBuf(&buf, obj->def) < 0) { + virBufferFreeAndReset(&buf); + return NULL; + } + + virBufferAdjustIndent(&buf, -2); + virBufferAddLit(&buf, "\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 0000000..21ae85b --- /dev/null +++ b/src/conf/virnwfilterbindingobj.h @@ -0,0 +1,69 @@ +/* + * virnwfilterbindingobj.h: network filter binding object 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 + * . + * + */ +#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; + +virNWFilterBindingObjPtr +virNWFilterBindingObjNew(void); + +virNWFilterBindingDefPtr +virNWFilterBindingObjGetDef(virNWFilterBindingObjPtr obj); + +void +virNWFilterBindingObjSetDef(virNWFilterBindingObjPtr obj, + virNWFilterBindingDefPtr def); + +bool +virNWFilterBindingObjGetRemoving(virNWFilterBindingObjPtr obj); + +void +virNWFilterBindingObjSetRemoving(virNWFilterBindingObjPtr obj, + bool removing); + +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 b5b8266..ad0c385 100644 --- a/src/libvirt_private.syms +++ b/src/libvirt_private.syms @@ -1057,6 +1057,20 @@ virNWFilterBindingDefParseNode; virNWFilterBindingDefParseString; +# conf/virnwfilterbindingobj.h +virNWFilterBindingObjConfigFile; +virNWFilterBindingObjDelete; +virNWFilterBindingObjEndAPI; +virNWFilterBindingObjFormat; +virNWFilterBindingObjGetDef; +virNWFilterBindingObjGetRemoving; +virNWFilterBindingObjNew; +virNWFilterBindingObjParseFile; +virNWFilterBindingObjSave; +virNWFilterBindingObjSetDef; +virNWFilterBindingObjSetRemoving; + + # conf/virnwfilterobj.h virNWFilterObjGetDef; virNWFilterObjGetNewDef;