Rather than passing the next-to-use file descriptor set Id and the hash table for rembering the mappings of aliases to file descriptor sets around, encapsulate the two in a class. Signed-off-by: Stefan Berger --- src/Makefile.am | 1 src/libvirt_private.syms | 10 ++ src/util/virfdset.c | 167 +++++++++++++++++++++++++++++++++++++++++++++++ src/util/virfdset.h | 114 ++++++++++++++++++++++++++++++++ 4 files changed, 292 insertions(+) Index: libvirt/src/util/virfdset.c =================================================================== --- /dev/null +++ libvirt/src/util/virfdset.c @@ -0,0 +1,167 @@ +/* + * virfdset.c: File descriptor set support + * + * Copyright (C) 2013 IBM Corporation + * + * 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 + * . + * + * Author: Stefan Berger + */ + +#include + +#include "virfdset.h" +#include "viralloc.h" +#include "virutil.h" +#include "virerror.h" +#include "virbuffer.h" + +#define VIR_FROM_THIS VIR_FROM_NONE + +static void virFdsetFreeIntPtr(void *payload, + const void *name ATTRIBUTE_UNUSED) +{ + VIR_FREE(payload); +} + +int virFdsetInit(virFdsetPtr fdset) +{ + if (!(fdset->aliasToFdset = virHashCreate(10, virFdsetFreeIntPtr))) { + virReportOOMError(); + return -1; + } + fdset->nextfdset = 1; + + return 0; +} + +void virFdsetReset(virFdsetPtr fdset) +{ + virHashRemoveAll(fdset->aliasToFdset); + fdset->nextfdset = 1; +} + +void virFdsetClear(virFdsetPtr fdset) +{ + virHashFree(fdset->aliasToFdset); +} + +void virFdsetRemoveAlias(virFdsetPtr fdset, const char *alias) +{ + virHashRemoveEntry(fdset->aliasToFdset, alias); +} + +int virFdsetNextSet(virFdsetPtr fdset, const char *alias, + unsigned int *fdsetnum) +{ + int *num; + + if (VIR_ALLOC(num) < 0) { + virReportOOMError(); + return -1; + } + + *num = fdset->nextfdset; + + if (virHashAddEntry(fdset->aliasToFdset, alias, num) < 0) { + virReportOOMError(); + VIR_FREE(num); + return -1; + } + + *fdsetnum = fdset->nextfdset++; + + return 0; +} + +static void virFdsetPrintAliasToFdset(void *payload, + const void *name, + void *data) +{ + virBufferPtr buf = data; + + virBufferAsprintf(buf, " \n", + (char *)name, + *(unsigned int *)payload); +} + +void virFdsetFormatXML(virFdsetPtr fdset, virBufferPtr buf) +{ + virBufferAsprintf(buf, "\n"); + virHashForEach(fdset->aliasToFdset, virFdsetPrintAliasToFdset, buf); + virBufferAsprintf(buf, "\n"); +} + +int virFdsetParseXML(virFdsetPtr fdset, const char *xPath, + xmlXPathContextPtr ctxt) +{ + xmlNodePtr *nodes = NULL; + int n, i; + char *key = NULL; + char *val = NULL; + unsigned int *fdsetnum = NULL; + int ret = 0; + + virFdsetReset(fdset); + + if ((n = virXPathNodeSet(xPath, ctxt, &nodes)) < 0) { + virReportError(VIR_ERR_INTERNAL_ERROR, + "%s", _("failed to parse qemu file descriptor sets")); + goto error; + } + if (n > 0) { + for (i = 0 ; i < n ; i++) { + key = virXMLPropString(nodes[i], "alias"); + val = virXMLPropString(nodes[i], "fdset"); + if (key && val) { + if (VIR_ALLOC(fdsetnum) < 0) { + virReportOOMError(); + ret = -1; + goto error; + } + if (virStrToLong_ui(val, NULL, 10, fdsetnum) < 0) { + virReportError(VIR_ERR_INTERNAL_ERROR, + _("incorrect fdset '%s', expected positive" + "integer"), val); + VIR_FREE(fdsetnum); + ret = -1; + goto error; + } + + if (fdset->nextfdset <= *fdsetnum) + fdset->nextfdset = *fdsetnum + 1; + + if (virHashAddEntry(fdset->aliasToFdset, key, fdsetnum) < 0) { + virReportOOMError(); + VIR_FREE(fdset); + ret = -1; + goto error; + } + } + VIR_FREE(key); + VIR_FREE(val); + } + } + +error: + if (ret < 0) + virFdsetReset(fdset); + + VIR_FREE(nodes); + VIR_FREE(key); + VIR_FREE(val); + + return ret; +} Index: libvirt/src/util/virfdset.h =================================================================== --- /dev/null +++ libvirt/src/util/virfdset.h @@ -0,0 +1,114 @@ +/* + * virfdset.h: File descriptor set support + * + * Copyright (C) 2013 IBM Corporation + * + * 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 + * . + * + * Author: Stefan Berger + */ +#ifndef __FDSET_H__ +# define __FDSET_H__ + +# include "internal.h" +# include "virbuffer.h" +# include "virxml.h" +# include "virhash.h" + +typedef struct _virFdset virFdset; +typedef virFdset *virFdsetPtr; + +struct _virFdset { + virHashTablePtr aliasToFdset; + unsigned int nextfdset; +}; + + +/** + * virFdsetInit + * @fdset: fdset + * + * Initialize the @fdset. + * Returns 0 on success, -1 on failure. + */ +int virFdsetInit(virFdsetPtr fdset); + +/** + * virFdsetReset + * @fdset: fdset + * + * Reset the @fdset and forget about all mappings + * of aliases to file descriptor set data + */ +void virFdsetReset(virFdsetPtr fdset); + +/** + * virFdsetClear + * @fdset: the fdset + * + * Free all memory associated with the @fdset but do not free + * the fdset structure itself. This is the counter part to + * virFdsetInit. + */ +void virFdsetClear(virFdsetPtr fdset); + + +/** + * virFdsetRemoveAlias + * @fdset: the fdset + * @alias: the alias to remove + * + * Remove the given alias' mapping from @fdset + */ +void virFdsetRemoveAlias(virFdsetPtr fdset, const char *alias); + + +/** + * virFdsetNextSet + * @fdset: fdset + * @alias: device alias + * @fdset: pointer to unsigned int for storing the file descriptor set id + * + * Get the next file descriptor set number and store it with the given + * @alias. If successful, return the file descriptor set id in @fdsetnum. + * + * Returns 0 on success, -1 on failure. + */ +int virFdsetNextSet(virFdsetPtr fdset, const char *alias, + unsigned int *fdsetnum); + +/** + * virFdsetFormatXML + * @fdset: fdset + * @buf: virBufferPtr for writing into + * + * Write XML representation of the @fdset into the buffer @buf. + */ +void virFdsetFormatXML(virFdsetPtr fdset, virBufferPtr buf); + +/** + * virFdsetParseXML + * @fdset: fdset + * @xPath: xpath expression to find the @fdset's XML nodes + * @ctxt: xpath context + * + * Parse the fdset XML representation and collect the data into @fdset. + * + * Returns 0 on success, -1 on failure. + */ +int virFdsetParseXML(virFdsetPtr fdset, const char *xPath, + xmlXPathContextPtr ctxt); + +#endif Index: libvirt/src/Makefile.am =================================================================== --- libvirt.orig/src/Makefile.am +++ libvirt/src/Makefile.am @@ -70,6 +70,7 @@ UTIL_SOURCES = \ util/virerror.c util/virerror.h \ util/virevent.c util/virevent.h \ util/vireventpoll.c util/vireventpoll.h \ + util/virfdset.c util/virfdset.h \ util/virfile.c util/virfile.h \ util/virhash.c util/virhash.h \ util/virhashcode.c util/virhashcode.h \ Index: libvirt/src/libvirt_private.syms =================================================================== --- libvirt.orig/src/libvirt_private.syms +++ libvirt/src/libvirt_private.syms @@ -646,6 +646,16 @@ virFDStreamOpen; virFDStreamOpenFile; +# virfdset.h +virFdsetClear; +virFdsetFormatXML; +virFdsetInit; +virFdsetNextSet; +virFdsetParseXML; +virFdsetRemoveAlias; +virFdsetReset; + + # hash.h virHashAddEntry; virHashCreate;