From nobody Sun Feb 8 20:24:52 2026 Delivered-To: importer@patchew.org Received-SPF: pass (zohomail.com: domain of lists.libvirt.org designates 8.43.85.245 as permitted sender) client-ip=8.43.85.245; envelope-from=devel-bounces@lists.libvirt.org; helo=lists.libvirt.org; Authentication-Results: mx.zohomail.com; dkim=fail; spf=pass (zohomail.com: domain of lists.libvirt.org designates 8.43.85.245 as permitted sender) smtp.mailfrom=devel-bounces@lists.libvirt.org; dmarc=pass(p=reject dis=none) header.from=lists.libvirt.org ARC-Seal: i=1; a=rsa-sha256; t=1742319473; cv=none; d=zohomail.com; s=zohoarc; b=l0M3TNn2/RwERI2wA/Lx5GUatQc3Jor4PWycZ3CKCQML5/jZCNq2F7R6gASQfz4V2hEKRLZPb4YacqNfjNn+Z2n6M2hlg3qlwclKOXCGQy8gT0kCkmWW3wXO24pnua1DIRgvMpgn+40I9WGyPX2gUMPSNoRERc7kVjf2/pJ24Ek= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1742319473; h=Content-Type:Content-Transfer-Encoding:Cc:Cc:Date:Date:From:From:In-Reply-To:List-Subscribe:List-Post:List-Id:List-Archive:List-Help:List-Unsubscribe:MIME-Version:Message-ID:Reply-To:Reply-To:References:Subject:Subject:To:To:Message-Id; bh=zF1S4N0NYG+XwLWZibac11rBw6y+HuEhlncNE5eNIaY=; b=TiouUulLtzWDEy3ucmPazgC1o5BteZ80H8cgaWLkl6k9MShTpDeoSvhJ0AYoWx4ShHYk+QgP/Y/ECoHVuLyr33yfIuAdjvXZPJe76rPJKR/gBPhO/xNMbXAWeGZ2TJrmVJl6BQa4jxjEkDzU6dpcvomXNhpH1jpiBSSJZC+tPYw= ARC-Authentication-Results: i=1; mx.zohomail.com; dkim=fail; spf=pass (zohomail.com: domain of lists.libvirt.org designates 8.43.85.245 as permitted sender) smtp.mailfrom=devel-bounces@lists.libvirt.org; dmarc=pass header.from= (p=reject dis=none) Return-Path: Received: from lists.libvirt.org (lists.libvirt.org [8.43.85.245]) by mx.zohomail.com with SMTPS id 1742319473814813.9020312133334; Tue, 18 Mar 2025 10:37:53 -0700 (PDT) Received: by lists.libvirt.org (Postfix, from userid 996) id 30A691679; Tue, 18 Mar 2025 13:37:53 -0400 (EDT) Received: from lists.libvirt.org (localhost [IPv6:::1]) by lists.libvirt.org (Postfix) with ESMTP id 5FFB115F4; Tue, 18 Mar 2025 13:35:01 -0400 (EDT) Received: by lists.libvirt.org (Postfix, from userid 996) id 3FDE515D3; Tue, 18 Mar 2025 13:34:57 -0400 (EDT) Received: from us-smtp-delivery-124.mimecast.com (us-smtp-delivery-124.mimecast.com [170.10.133.124]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by lists.libvirt.org (Postfix) with ESMTPS id E0D6F16F0 for ; Tue, 18 Mar 2025 13:34:44 -0400 (EDT) Received: from mx-prod-mc-06.mail-002.prod.us-west-2.aws.redhat.com (ec2-35-165-154-97.us-west-2.compute.amazonaws.com [35.165.154.97]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.3, cipher=TLS_AES_256_GCM_SHA384) id us-mta-100-0QG6OoEZNwOym-7s6-0oTQ-1; Tue, 18 Mar 2025 13:34:42 -0400 Received: from mx-prod-int-01.mail-002.prod.us-west-2.aws.redhat.com (mx-prod-int-01.mail-002.prod.us-west-2.aws.redhat.com [10.30.177.4]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (2048 bits) server-digest SHA256) (No client certificate requested) by mx-prod-mc-06.mail-002.prod.us-west-2.aws.redhat.com (Postfix) with ESMTPS id BCB671800361; Tue, 18 Mar 2025 17:34:41 +0000 (UTC) Received: from speedmetal.redhat.com (unknown [10.45.242.6]) by mx-prod-int-01.mail-002.prod.us-west-2.aws.redhat.com (Postfix) with ESMTP id 6A19F3001D0E; Tue, 18 Mar 2025 17:34:40 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.4.4 (2020-01-24) on lists.libvirt.org X-Spam-Level: X-Spam-Status: No, score=-0.8 required=5.0 tests=DKIM_INVALID,DKIM_SIGNED, MAILING_LIST_MULTI,RCVD_IN_DNSWL_NONE,RCVD_IN_MSPIKE_H2, RCVD_IN_VALIDITY_RPBL_BLOCKED,RCVD_IN_VALIDITY_SAFE_BLOCKED, SPF_HELO_NONE autolearn=unavailable autolearn_force=no version=3.4.4 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1742319284; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=rJKWjpBtx32a6VUQ/7SVS89Zb+eMGorbNH527XEnVL8=; b=Y6sdjbmKYbDNp14SPaR1sqO1xR1RBc33FDVtTCmbeIdp44GlGubyG6b54X1C46jALX6iD1 zwBeuNYEB1sVNoKwAaOKJNgrhveQ2Zv0tiBKaW7/EwvkEs0iD7syWV3T6VecYJpBSQBhjG gmmqveFEMT+MjnsiVdeJtkoclv3rBBQ= X-MC-Unique: 0QG6OoEZNwOym-7s6-0oTQ-1 X-Mimecast-MFC-AGG-ID: 0QG6OoEZNwOym-7s6-0oTQ_1742319281 To: devel@lists.libvirt.org Subject: [PATCH v9 04/17] config: Introduce ThrottleFilter and corresponding XML parsing Date: Tue, 18 Mar 2025 18:34:18 +0100 Message-ID: <4e171833689a6c78abdde88c31472e960cb38092.1742318898.git.pkrempa@redhat.com> In-Reply-To: References: MIME-Version: 1.0 X-Scanned-By: MIMEDefang 3.4.1 on 10.30.177.4 X-Mimecast-Spam-Score: 0 X-Mimecast-MFC-PROC-ID: ugZHwXDXfWLfY-yAUpLg-U5IvinEWNGxMB55qVvZUEs_1742319281 X-Mimecast-Originator: redhat.com Content-Transfer-Encoding: quoted-printable Message-ID-Hash: B7QZGVMGZDXHNE25OWLILAGBFZDBQCI4 X-Message-ID-Hash: B7QZGVMGZDXHNE25OWLILAGBFZDBQCI4 X-MailFrom: pkrempa@redhat.com X-Mailman-Rule-Misses: dmarc-mitigation; no-senders; approved; emergency; loop; banned-address; member-moderation; header-match-config-1; header-match-config-2; header-match-config-3; header-match-devel.lists.libvirt.org-0; nonmember-moderation; administrivia; implicit-dest; max-recipients; max-size; news-moderation; no-subject; suspicious-header CC: Harikumar Rajkumar , harikumar.rajkumar@ibm.com X-Mailman-Version: 3.2.2 Precedence: list List-Id: Development discussions about the libvirt library & tools Archived-At: List-Archive: List-Help: List-Post: List-Subscribe: List-Unsubscribe: From: Peter Krempa via Devel Reply-To: Peter Krempa X-ZohoMail-DKIM: fail (Header signature does not verify) X-ZM-MESSAGEID: 1742319476041019000 Content-Type: text/plain; charset="utf-8" From: Chun Feng Wu Introduce throttle filter along with corresponding operations. * Define new struct 'virDomainThrottleFilterDef' and corresponding destruct= or * Update _virDomainDiskDef to include virDomainThrottleFilterDef * Support throttle filter "Parse" and "Format" for operations between DOM X= ML and structs. Note, this commit just contains parse/format of group name f= or throttle filter in domain_conf.c, there is other commit to handle throttle filter nodename parse/format between throttlefilter and diskPrivateData f= or statusxml in qemu_domain.c when processing qemuDomainDiskPrivate and qemuDomainDiskPrivate Signed-off-by: Chun Feng Wu * Error handling for null throttle group. * Update of code documentation comments. * Apply suggested coding style changes. Signed-off-by: Harikumar Rajkumar * Fixed naming of virDomainThrottleFilterDefClear to ...Free * Fixed memleak of the throttle filter definitions Reviewed-by: Peter Krempa Signed-off-by: Peter Krempa --- 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) virDomainIothreadMa= ppingDefFree); + if (def->throttlefilters) { + size_t i; + + for (i =3D 0; i < def->nthrottlefilters; i++) + virDomainThrottleFilterDefFree(def->throttlefilters[i]); + + g_free(def->throttlefilters); + } + g_free(def); } @@ -3834,6 +3843,17 @@ virDomainThrottleGroupDefArrayFree(virDomainThrottle= GroupDef **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 =3D g_new0(virDomainThrot= tleFilterDef, 1); + + filter->group_name =3D virXMLPropStringRequired(node, "group"); + + return g_steal_pointer(&filter); +} + + +static int +virDomainDiskDefThrottleFiltersParse(virDomainDiskDef *def, + xmlXPathContextPtr ctxt) +{ + size_t i; + int n =3D 0; + g_autofree xmlNodePtr *nodes =3D NULL; + + if ((n =3D virXPathNodeSet("./throttlefilters/throttlefilter", ctxt, &= nodes)) < 0) + return -1; + + if (n) + def->throttlefilters =3D g_new0(virDomainThrottleFilterDef *, n); + + for (i =3D 0; i < n; i++) { + g_autoptr(virDomainThrottleFilterDef) filter =3D NULL; + + if (!(filter =3D 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++] =3D 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 =3D virXPathString("string(./backenddomain/@name)", c= txt); def->serial =3D virXPathString("string(./serial)", ctxt); def->wwn =3D 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 =3D 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 =3D VIR_BUFFER_INIT_CHILD(buf); + for (i =3D 0; i < disk->nthrottlefilters; i++) { + g_auto(virBuffer) throttleAttrBuf =3D VIR_BUFFER_INITIALIZER; + virBufferEscapeString(&throttleAttrBuf, " group=3D'%s'", disk->thr= ottlefilters[i]->group_name); + virXMLFormatElement(&throttleChildBuf, "throttlefilter", &throttle= AttrBuf, 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, "\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(virDomainIothread= MappingDef *def); G_DEFINE_AUTOPTR_CLEANUP_FUNC(virDomainIothreadMappingDef, virDomainIothre= adMappingDefFree); +/* 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, virDomainThrottl= eFilterDefFree); + +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 virDomainBlockIo= TuneInfo; 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; --=20 2.48.1