From: Chun Feng Wu <danielwuwy(a)163.com>
Introduce throttle filter along with corresponding operations.
* Define new struct 'virDomainThrottleFilterDef' and corresponding destructor
* Update _virDomainDiskDef to include virDomainThrottleFilterDef
* Support throttle filter "Parse" and "Format" for operations between
DOM XML
and structs. Note, this commit just contains parse/format of group name for
throttle filter in domain_conf.c, there is other commit to handle throttle
filter nodename parse/format between throttlefilter and diskPrivateData for
statusxml in qemu_domain.c when processing qemuDomainDiskPrivate and
qemuDomainDiskPrivate
Signed-off-by: Chun Feng Wu <danielwuwy(a)163.com>
* Error handling for null throttle group.
* Update of code documentation comments.
* Apply suggested coding style changes.
Signed-off-by: Harikumar Rajkumar <harirajkumar230(a)gmail.com>
* Fixed naming of virDomainThrottleFilterDefClear to ...Free
* Fixed memleak of the throttle filter definitions
Reviewed-by: Peter Krempa <pkrempa(a)redhat.com>
Signed-off-by: Peter Krempa <pkrempa(a)redhat.com>
---
src/conf/domain_conf.c | 109 +++++++++++++++++++++++++++++++++++++++
src/conf/domain_conf.h | 20 +++++++
src/conf/virconftypes.h | 2 +
src/libvirt_private.syms | 2 +
4 files changed, 133 insertions(+)
diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c
index 8306db7cad..0f9da3505d 100644
--- a/src/conf/domain_conf.c
+++ b/src/conf/domain_conf.c
@@ -2437,6 +2437,15 @@ virDomainDiskDefFree(virDomainDiskDef *def)
virObjectUnref(def->privateData);
g_slist_free_full(def->iothreads, (GDestroyNotify)
virDomainIothreadMappingDefFree);
+ if (def->throttlefilters) {
+ size_t i;
+
+ for (i = 0; i < def->nthrottlefilters; i++)
+ virDomainThrottleFilterDefFree(def->throttlefilters[i]);
+
+ g_free(def->throttlefilters);
+ }
+
g_free(def);
}
@@ -3834,6 +3843,17 @@ virDomainThrottleGroupDefArrayFree(virDomainThrottleGroupDef
**def,
}
+void
+virDomainThrottleFilterDefFree(virDomainThrottleFilterDef *def)
+{
+ if (!def)
+ return;
+ g_free(def->group_name);
+ g_free(def->nodename);
+ g_free(def);
+}
+
+
void
virDomainResourceDefFree(virDomainResourceDef *resource)
{
@@ -7997,6 +8017,50 @@ virDomainDefThrottleGroupsParse(virDomainDef *def,
}
+static virDomainThrottleFilterDef *
+virDomainDiskThrottleFilterDefParse(xmlNodePtr node)
+{
+ g_autoptr(virDomainThrottleFilterDef) filter = g_new0(virDomainThrottleFilterDef,
1);
+
+ filter->group_name = virXMLPropStringRequired(node, "group");
+
+ return g_steal_pointer(&filter);
+}
+
+
+static int
+virDomainDiskDefThrottleFiltersParse(virDomainDiskDef *def,
+ xmlXPathContextPtr ctxt)
+{
+ size_t i;
+ int n = 0;
+ g_autofree xmlNodePtr *nodes = NULL;
+
+ if ((n = virXPathNodeSet("./throttlefilters/throttlefilter", ctxt,
&nodes)) < 0)
+ return -1;
+
+ if (n)
+ def->throttlefilters = g_new0(virDomainThrottleFilterDef *, n);
+
+ for (i = 0; i < n; i++) {
+ g_autoptr(virDomainThrottleFilterDef) filter = NULL;
+
+ if (!(filter = virDomainDiskThrottleFilterDefParse(nodes[i]))) {
+ return -1;
+ }
+
+ if (virDomainThrottleFilterFind(def, filter->group_name)) {
+ virReportError(VIR_ERR_XML_ERROR,
+ _("duplicate filter name '%1$s' found"),
+ filter->group_name);
+ return -1;
+ }
+ def->throttlefilters[def->nthrottlefilters++] =
g_steal_pointer(&filter);
+ }
+ return 0;
+}
+
+
static int
virDomainDiskDefMirrorParse(virDomainDiskDef *def,
xmlNodePtr cur,
@@ -8499,6 +8563,9 @@ virDomainDiskDefParseXML(virDomainXMLOption *xmlopt,
if (virDomainDiskDefIotuneParse(def, ctxt) < 0)
return NULL;
+ if (virDomainDiskDefThrottleFiltersParse(def, ctxt) < 0)
+ return NULL;
+
def->domain_name = virXPathString("string(./backenddomain/@name)",
ctxt);
def->serial = virXPathString("string(./serial)", ctxt);
def->wwn = virXPathString("string(./wwn)", ctxt);
@@ -22738,6 +22805,31 @@ virDomainThrottleGroupDel(virDomainDef *def,
}
+/**
+ * virDomainThrottleFilterFind:
+ * @def: domain disk definition
+ * @name: throttle group name
+ *
+ * Search domain disk to find throttle filter referencing
+ * throttle group with name @name.
+ *
+ * Return a pointer to throttle filter found
+ */
+virDomainThrottleFilterDef *
+virDomainThrottleFilterFind(const virDomainDiskDef *def,
+ const char *name)
+{
+ size_t i;
+
+ for (i = 0; i < def->nthrottlefilters; i++) {
+ if (STREQ(name, def->throttlefilters[i]->group_name))
+ return def->throttlefilters[i];
+ }
+
+ return NULL;
+}
+
+
static int
virDomainEventActionDefFormat(virBuffer *buf,
int type,
@@ -23419,6 +23511,21 @@ virDomainIothreadMappingDefFormat(virBuffer *buf,
}
+static void
+virDomainDiskDefFormatThrottleFilters(virBuffer *buf,
+ virDomainDiskDef *disk)
+{
+ size_t i;
+ g_auto(virBuffer) throttleChildBuf = VIR_BUFFER_INIT_CHILD(buf);
+ for (i = 0; i < disk->nthrottlefilters; i++) {
+ g_auto(virBuffer) throttleAttrBuf = VIR_BUFFER_INITIALIZER;
+ virBufferEscapeString(&throttleAttrBuf, " group='%s'",
disk->throttlefilters[i]->group_name);
+ virXMLFormatElement(&throttleChildBuf, "throttlefilter",
&throttleAttrBuf, NULL);
+ }
+ virXMLFormatElement(buf, "throttlefilters", NULL, &throttleChildBuf);
+}
+
+
static void
virDomainDiskDefFormatDriver(virBuffer *buf,
virDomainDiskDef *disk)
@@ -23683,6 +23790,8 @@ virDomainDiskDefFormat(virBuffer *buf,
virDomainDiskDefFormatIotune(&childBuf, def);
+ virDomainDiskDefFormatThrottleFilters(&childBuf, def);
+
if (def->src->readonly)
virBufferAddLit(&childBuf, "<readonly/>\n");
if (def->src->shared)
diff --git a/src/conf/domain_conf.h b/src/conf/domain_conf.h
index ef582c6f87..29a6fe10e3 100644
--- a/src/conf/domain_conf.h
+++ b/src/conf/domain_conf.h
@@ -520,6 +520,15 @@ void virDomainIothreadMappingDefFree(virDomainIothreadMappingDef
*def);
G_DEFINE_AUTOPTR_CLEANUP_FUNC(virDomainIothreadMappingDef,
virDomainIothreadMappingDefFree);
+/* Stores information related to a ThrottleFilter resource. */
+struct _virDomainThrottleFilterDef {
+ char *group_name;
+ char *nodename; /* node name of throttle filter object */
+ /* node name is a qemu driver implementation
+ detail and not a configuration field */
+};
+
+
/* Stores the virtual disk configuration */
struct _virDomainDiskDef {
virStorageSource *src; /* non-NULL. XXX Allow NULL for empty cdrom? */
@@ -552,6 +561,9 @@ struct _virDomainDiskDef {
virDomainBlockIoTuneInfo blkdeviotune;
+ size_t nthrottlefilters;
+ virDomainThrottleFilterDef **throttlefilters;
+
char *driverName;
char *serial;
@@ -4660,3 +4672,11 @@ virDomainThrottleGroupByName(const virDomainDef *def,
void
virDomainThrottleGroupDefCopy(const virDomainThrottleGroupDef *src,
virDomainThrottleGroupDef *dst);
+
+void
+virDomainThrottleFilterDefFree(virDomainThrottleFilterDef *def);
+G_DEFINE_AUTOPTR_CLEANUP_FUNC(virDomainThrottleFilterDef,
virDomainThrottleFilterDefFree);
+
+virDomainThrottleFilterDef *
+virDomainThrottleFilterFind(const virDomainDiskDef *def,
+ const char *name);
diff --git a/src/conf/virconftypes.h b/src/conf/virconftypes.h
index 1936ef6ab1..c70437bc05 100644
--- a/src/conf/virconftypes.h
+++ b/src/conf/virconftypes.h
@@ -82,6 +82,8 @@ typedef struct _virDomainBlockIoTuneInfo virDomainBlockIoTuneInfo;
typedef struct _virDomainBlockIoTuneInfo virDomainThrottleGroupDef;
+typedef struct _virDomainThrottleFilterDef virDomainThrottleFilterDef;
+
typedef struct _virDomainCheckpointDef virDomainCheckpointDef;
typedef struct _virDomainCheckpointObj virDomainCheckpointObj;
diff --git a/src/libvirt_private.syms b/src/libvirt_private.syms
index 91a49ecf32..aec0a1c579 100644
--- a/src/libvirt_private.syms
+++ b/src/libvirt_private.syms
@@ -682,6 +682,8 @@ virDomainTaintMessageTypeFromString;
virDomainTaintMessageTypeToString;
virDomainTaintTypeFromString;
virDomainTaintTypeToString;
+virDomainThrottleFilterDefFree;
+virDomainThrottleFilterFind;
virDomainThrottleGroupAdd;
virDomainThrottleGroupByName;
virDomainThrottleGroupDefCopy;
--
2.48.1