From nobody Sat Nov 23 15:35:05 2024 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; spf=pass (zohomail.com: domain of lists.libvirt.org designates 8.43.85.245 as permitted sender) smtp.mailfrom=devel-bounces@lists.libvirt.org Return-Path: Received: from lists.libvirt.org (lists.libvirt.org [8.43.85.245]) by mx.zohomail.com with SMTPS id 1715545004617566.5184848221792; Sun, 12 May 2024 13:16:44 -0700 (PDT) Received: by lists.libvirt.org (Postfix, from userid 996) id 7AE4B1CA4; Sun, 12 May 2024 16:16:43 -0400 (EDT) Received: from lists.libvirt.org (localhost [IPv6:::1]) by lists.libvirt.org (Postfix) with ESMTP id 3877D1BB1; Sun, 12 May 2024 16:13:01 -0400 (EDT) Received: by lists.libvirt.org (Postfix, from userid 996) id 2F00E1A65; Sun, 12 May 2024 16:12:49 -0400 (EDT) Received: from mail-wm1-f52.google.com (mail-wm1-f52.google.com [209.85.128.52]) (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 687AC1A6D for ; Sun, 12 May 2024 16:12:47 -0400 (EDT) Received: by mail-wm1-f52.google.com with SMTP id 5b1f17b1804b1-41ffad2426eso21609985e9.3 for ; Sun, 12 May 2024 13:12:47 -0700 (PDT) Received: from localhost.localdomain ([162.213.65.233]) by smtp.gmail.com with ESMTPSA id 5b1f17b1804b1-42014f563adsm22354735e9.38.2024.05.12.13.12.45 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Sun, 12 May 2024 13:12:45 -0700 (PDT) X-Spam-Checker-Version: SpamAssassin 3.4.4 (2020-01-24) on lists.libvirt.org X-Spam-Level: X-Spam-Status: No, score=-1.0 required=5.0 tests=HEADER_FROM_DIFFERENT_DOMAINS, MAILING_LIST_MULTI,RCVD_IN_DNSWL_NONE,RCVD_IN_MSPIKE_H2,SPF_HELO_NONE autolearn=unavailable autolearn_force=no version=3.4.4 X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1715544766; x=1716149566; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=jPMvpuC+LLzItXn75SL0dCynD5VqIEF4VHPy79usZNY=; b=wFCGjJ3SgOutjjZesgJ0yAVloIKgcV69SHCpDw5K/Br/zxNc6+7hPnD7uatCgozqcj d8pB6NCgarrQoRtPWGx58PL0F3poYP4zpnV6iIn59sW/FtUlwnHykJ0LD88TmfsIla+f NAJS1JNXaZRJ3nKYAGRJ1RjqEhJzInxPr4V9/Rht85uvgzH9F/3wvzTLPYV30K2tl8jM dH/HdtzIfGfoxuQ3DMF9C8upaBvP/R9VFuGgCU5+ZnC8Vl0E8Ov13JA9d7g+flItxQBo VVfymPWh1O9/ZJarH19+TNwAmjFjMEFOjVdlMghIPeQ5fQtY3mmqWIv5Hq7rb9y+F7E/ 4/MA== X-Gm-Message-State: AOJu0YyXkGIUV/hOJ8t8uNf9ACGhG+8CG38x0O1YajCN7BgJ21TpO7Mr Vpy1tN4AyBEi5JAi3va+CtVkgiHAlRMpThV2apH/042KBD0TjYE1DSYj/BPpGhG9DskK61dVP7C o X-Google-Smtp-Source: AGHT+IH9HP7SDSO79FaWpy/rJoeFDLh7Ly34WGimjJmtiHdklTxf+RYZYAcT4CyMB9VHkSSX2Yvi1Q== X-Received: by 2002:a05:600c:1989:b0:420:78f:3f9b with SMTP id 5b1f17b1804b1-420078f4105mr59168425e9.37.1715544765569; Sun, 12 May 2024 13:12:45 -0700 (PDT) From: Andrew Melnychenko To: devel@lists.libvirt.org Subject: [RFC PATCH v3 2/6] qemu_capabilities: Added logic for retrieving eBPF objects from QEMU. Date: Sun, 12 May 2024 22:45:44 +0300 Message-ID: <20240512194550.5023-3-andrew@daynix.com> X-Mailer: git-send-email 2.44.0 In-Reply-To: <20240512194550.5023-1-andrew@daynix.com> References: <20240512194550.5023-1-andrew@daynix.com> MIME-Version: 1.0 Message-ID-Hash: 7M2QSR453HRZOGD7HVAJS6H5AFLGPMO2 X-Message-ID-Hash: 7M2QSR453HRZOGD7HVAJS6H5AFLGPMO2 X-MailFrom: andrew@daynix.com X-Mailman-Rule-Hits: nonmember-moderation 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 CC: yuri.benditovich@daynix.com, yan@daynix.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: Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable X-ZM-MESSAGEID: 1715545006047100001 eBPF objects stored in the hash table during runtime. eBPF objects cached encoded in base64 in the .xml cache file. Signed-off-by: Andrew Melnychenko --- src/qemu/qemu_capabilities.c | 122 +++++++++++++++++++++++++++++++++++ src/qemu/qemu_capabilities.h | 3 + 2 files changed, 125 insertions(+) diff --git a/src/qemu/qemu_capabilities.c b/src/qemu/qemu_capabilities.c index 45525db803..09bb6ca36e 100644 --- a/src/qemu/qemu_capabilities.c +++ b/src/qemu/qemu_capabilities.c @@ -799,6 +799,9 @@ struct _virQEMUCaps { virQEMUCapsAccel kvm; virQEMUCapsAccel hvf; virQEMUCapsAccel tcg; + + /* Hash of ebpf objects encoded in base64 */ + GHashTable *ebpfObjects; }; =20 struct virQEMUCapsSearchData { @@ -846,6 +849,13 @@ const char *virQEMUCapsArchToString(virArch arch) } =20 =20 +const char * +virQEMUCapsGetEbpf(virQEMUCaps *qemuCaps, const char *id) +{ + return virHashLookup(qemuCaps->ebpfObjects, id); +} + + /* Checks whether a domain with @guest arch can run natively on @host. */ bool @@ -1823,6 +1833,8 @@ virQEMUCapsNew(void) qemuCaps->invalidation =3D true; qemuCaps->flags =3D virBitmapNew(QEMU_CAPS_LAST); =20 + qemuCaps->ebpfObjects =3D virHashNew(g_free); + return qemuCaps; } =20 @@ -1965,6 +1977,9 @@ virQEMUCaps *virQEMUCapsNewCopy(virQEMUCaps *qemuCaps) { g_autoptr(virQEMUCaps) ret =3D virQEMUCapsNewBinary(qemuCaps->binary); size_t i; + GHashTableIter iter; + const char *key; + const char *value; =20 ret->invalidation =3D qemuCaps->invalidation; ret->kvmSupportsNesting =3D qemuCaps->kvmSupportsNesting; @@ -2003,6 +2018,12 @@ virQEMUCaps *virQEMUCapsNewCopy(virQEMUCaps *qemuCap= s) ret->hypervCapabilities =3D g_memdup(qemuCaps->hypervCapabilities, sizeof(virDomainCapsFeatureHyperv)); =20 + ret->ebpfObjects =3D virHashNew(g_free); + g_hash_table_iter_init(&iter, qemuCaps->ebpfObjects); + while (g_hash_table_iter_next(&iter, (gpointer *) &key, (gpointer *) &= value)) { + g_hash_table_insert(ret->ebpfObjects, g_strdup(key), g_strdup(valu= e)); + } + return g_steal_pointer(&ret); } =20 @@ -2045,6 +2066,8 @@ void virQEMUCapsDispose(void *obj) =20 g_free(qemuCaps->hypervCapabilities); =20 + g_hash_table_destroy(qemuCaps->ebpfObjects); + virQEMUCapsAccelClear(&qemuCaps->kvm); virQEMUCapsAccelClear(&qemuCaps->hvf); virQEMUCapsAccelClear(&qemuCaps->tcg); @@ -4560,6 +4583,40 @@ virQEMUCapsValidateArch(virQEMUCaps *qemuCaps, xmlXP= athContextPtr ctxt) } =20 =20 +static int +virQEMUCapsParseEbpfObjects(virQEMUCaps *qemuCaps, xmlXPathContextPtr ctxt) +{ + g_autofree xmlNodePtr *nodes =3D NULL; + size_t i; + int n; + + if ((n =3D virXPathNodeSet("./ebpf/object", ctxt, &nodes)) < 0) { + virReportError(VIR_ERR_INTERNAL_ERROR, "%s", + _("failed to parse qemu cached eBPF object")); + return -1; + } + + for (i =3D 0; i < n; i++) { + g_autofree char *id =3D NULL; + g_autofree char *ebpf =3D NULL; + + if (!(id =3D virXMLPropStringRequired(nodes[i], "id"))) + return -1; + + if (!(ebpf =3D virXMLPropStringRequired(nodes[i], "data"))) + return -1; + + if (virHashAddEntry(qemuCaps->ebpfObjects, id, ebpf) < 0) + return -1; + + /* steal the ebpf if it was added to the hash without issues */ + g_steal_pointer(&ebpf); + } + + return 0; +} + + /* * Parsing a doc that looks like * @@ -4707,6 +4764,9 @@ virQEMUCapsLoadCache(virArch hostArch, if (skipInvalidation) qemuCaps->invalidation =3D false; =20 + if (virQEMUCapsParseEbpfObjects(qemuCaps, ctxt) < 0) + return -1; + return 0; } =20 @@ -4944,6 +5004,16 @@ virQEMUCapsFormatHypervCapabilities(virQEMUCaps *qem= uCaps, } =20 =20 +static int +virQEMUCapsFormatEbpfObjectsIterator(void *payload, const char *name, void= *opaque) +{ + virBuffer *buf =3D opaque; + + virBufferAsprintf(buf, "\n", name, (con= st char *)payload); + + return 0; +} + char * virQEMUCapsFormatCache(virQEMUCaps *qemuCaps) { @@ -5034,6 +5104,14 @@ virQEMUCapsFormatCache(virQEMUCaps *qemuCaps) if (qemuCaps->kvmSupportsSecureGuest) virBufferAddLit(&buf, "\n"); =20 + if (virHashSize(qemuCaps->ebpfObjects) > 0) { + virBufferAddLit(&buf, "\n"); + virBufferAdjustIndent(&buf, 2); + virHashForEachSorted(qemuCaps->ebpfObjects, virQEMUCapsFormatEbpfO= bjectsIterator, &buf); + virBufferAdjustIndent(&buf, -2); + virBufferAddLit(&buf, "\n"); + } + virBufferAdjustIndent(&buf, -2); virBufferAddLit(&buf, "\n"); =20 @@ -5456,6 +5534,47 @@ virQEMUCapsInitProcessCaps(virQEMUCaps *qemuCaps) } =20 =20 +static int +virQEMUCapsProbeQMPEbpfObject(virQEMUCaps *qemuCaps, const char *id, qemuM= onitor *mon) +{ + const char *ebpfObject =3D NULL; + + ebpfObject =3D qemuMonitorGetEbpf(mon, id); + if (ebpfObject =3D=3D NULL) + return -1; + + return virHashAddEntry(qemuCaps->ebpfObjects, id, (void *)ebpfObject); +} + + +static int +virQEMUCapsProbeQMPSchemaEbpf(virQEMUCaps *qemuCaps, GHashTable *schema, q= emuMonitor *mon) +{ + virJSONValue *ebpfIdsArray; + virJSONValue *ebpfIdsSchema; + size_t i; + + if (virQEMUQAPISchemaPathGet("request-ebpf/arg-type/id", schema, &ebpf= IdsSchema) !=3D 1) + return 0; + + if (!(ebpfIdsArray =3D virJSONValueObjectGetArray(ebpfIdsSchema, "valu= es"))) { + virReportError(VIR_ERR_INTERNAL_ERROR, "%s", + _("malformed QMP schema of 'request-ebpf'")); + return -1; + } + + /* Try to request every eBPF */ + for (i =3D 0; i < virJSONValueArraySize(ebpfIdsArray); i++) { + virJSONValue *id =3D virJSONValueArrayGet(ebpfIdsArray, i); + + if (virQEMUCapsProbeQMPEbpfObject(qemuCaps, virJSONValueGetString(= id), mon) < 0) + return -1; + } + + return 0; +} + + static int virQEMUCapsProbeQMPSchemaCapabilities(virQEMUCaps *qemuCaps, qemuMonitor *mon) @@ -5489,6 +5608,9 @@ virQEMUCapsProbeQMPSchemaCapabilities(virQEMUCaps *qe= muCaps, virQEMUQAPISchemaPathExists("block-stream/arg-type/backing-mask-pr= otocol", schema)) virQEMUCapsSet(qemuCaps, QEMU_CAPS_BLOCKJOB_BACKING_MASK_PROTOCOL); =20 + if (virQEMUCapsProbeQMPSchemaEbpf(qemuCaps, schema, mon) < 0) + return -1; + return 0; } =20 diff --git a/src/qemu/qemu_capabilities.h b/src/qemu/qemu_capabilities.h index 00b4066e9a..371ea19bd0 100644 --- a/src/qemu/qemu_capabilities.h +++ b/src/qemu/qemu_capabilities.h @@ -906,3 +906,6 @@ int virQEMUCapsProbeQMPMachineTypes(virQEMUCaps *qemuCaps, virDomainVirtType virtType, qemuMonitor *mon); + +const char * +virQEMUCapsGetEbpf(virQEMUCaps *qemuCaps, const char *id); --=20 2.44.0 _______________________________________________ Devel mailing list -- devel@lists.libvirt.org To unsubscribe send an email to devel-leave@lists.libvirt.org