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 <stefanb(a)linux.vnet.ibm.com>
---
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
+ * <
http://www.gnu.org/licenses/>.
+ *
+ * Author: Stefan Berger <stefanb(a)linux.vnet.ibm.com>
+ */
+
+#include <config.h>
+
+#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, " <entry alias='%s'
fdset='%u'/>\n",
+ (char *)name,
+ *(unsigned int *)payload);
+}
+
+void virFdsetFormatXML(virFdsetPtr fdset, virBufferPtr buf)
+{
+ virBufferAsprintf(buf, "<fdsets>\n");
+ virHashForEach(fdset->aliasToFdset, virFdsetPrintAliasToFdset, buf);
+ virBufferAsprintf(buf, "</fdsets>\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
+ * <
http://www.gnu.org/licenses/>.
+ *
+ * Author: Stefan Berger <stefanb(a)linux.vnet.ibm.com>
+ */
+#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;