From nobody Mon Feb 9 16:02:53 2026 Delivered-To: importer@patchew.org Received-SPF: pass (zohomail.com: domain of redhat.com designates 216.205.24.124 as permitted sender) client-ip=216.205.24.124; envelope-from=libvir-list-bounces@redhat.com; helo=us-smtp-delivery-124.mimecast.com; Authentication-Results: mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of redhat.com designates 216.205.24.124 as permitted sender) smtp.mailfrom=libvir-list-bounces@redhat.com; dmarc=pass(p=none dis=none) header.from=redhat.com ARC-Seal: i=1; a=rsa-sha256; t=1612600532; cv=none; d=zohomail.com; s=zohoarc; b=jmJMZyZlQRWd9auQuDT7D8NqbLKwv5VPMLqcX569nOqyHbFJxudSBYcIkANKOtGicZ4LXqp/VFOKATRo/sQzF35f6xlb+8mGobp4rfPqBBmnBM1AU+Gt0fSGvsjqam7S2J14r/2Sd10nOSzvVwsfmusHDvxUEx+zkFrY40jCIZw= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1612600532; h=Content-Type:Content-Transfer-Encoding:Date:From:In-Reply-To:List-Subscribe:List-Post:List-Id:List-Archive:List-Help:List-Unsubscribe:MIME-Version:Message-ID:References:Sender:Subject:To; bh=tBXhK3PEVVo7U6uhalGIt7DkhJBz1gA0PiG2IWCO3vA=; b=WceWQlBH8UGdSfA2vppJylDEBu12oCSajVgZR4HmUx3lzgqeWDNqq97rB0Gy6oGrrF6OkdYV/t3Tyhq+CEaxRgLaz+XyDCeIY+P1HGZcdZhmLVnQ+NiK7i83ma0+mswgZmV0ItD3+NcakAM3nCYd5qd2njnaerBduJkpejNLR6U= ARC-Authentication-Results: i=1; mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of redhat.com designates 216.205.24.124 as permitted sender) smtp.mailfrom=libvir-list-bounces@redhat.com; dmarc=pass header.from= (p=none dis=none) header.from= Return-Path: Received: from us-smtp-delivery-124.mimecast.com (us-smtp-delivery-124.mimecast.com [216.205.24.124]) by mx.zohomail.com with SMTPS id 1612600532230695.7945725173926; Sat, 6 Feb 2021 00:35:32 -0800 (PST) Received: from mimecast-mx01.redhat.com (mimecast-mx01.redhat.com [209.132.183.4]) (Using TLS) by relay.mimecast.com with ESMTP id us-mta-465-bkzpZlCmNdekz5J36-pdOw-1; Sat, 06 Feb 2021 03:33:53 -0500 Received: from smtp.corp.redhat.com (int-mx01.intmail.prod.int.phx2.redhat.com [10.5.11.11]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mimecast-mx01.redhat.com (Postfix) with ESMTPS id DC86C1DDEB; Sat, 6 Feb 2021 08:33:47 +0000 (UTC) Received: from colo-mx.corp.redhat.com (colo-mx02.intmail.prod.int.phx2.redhat.com [10.5.11.21]) by smtp.corp.redhat.com (Postfix) with ESMTPS id B88C972FAE; Sat, 6 Feb 2021 08:33:47 +0000 (UTC) Received: from lists01.pubmisc.prod.ext.phx2.redhat.com (lists01.pubmisc.prod.ext.phx2.redhat.com [10.5.19.33]) by colo-mx.corp.redhat.com (Postfix) with ESMTP id 8298B58085; Sat, 6 Feb 2021 08:33:47 +0000 (UTC) Received: from smtp.corp.redhat.com (int-mx02.intmail.prod.int.phx2.redhat.com [10.5.11.12]) by lists01.pubmisc.prod.ext.phx2.redhat.com (8.13.8/8.13.8) with ESMTP id 1168Xevm004917 for ; Sat, 6 Feb 2021 03:33:40 -0500 Received: by smtp.corp.redhat.com (Postfix) id 9F01E60C77; Sat, 6 Feb 2021 08:33:40 +0000 (UTC) Received: from speedmetal.lan (unknown [10.40.208.53]) by smtp.corp.redhat.com (Postfix) with ESMTP id F00DC60C76 for ; Sat, 6 Feb 2021 08:33:37 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1612600531; h=from:from:sender:sender:reply-to:subject:subject:date:date: message-id:message-id:to:to:cc:mime-version:mime-version: content-type:content-type: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references:list-id:list-help: list-unsubscribe:list-subscribe:list-post; bh=tBXhK3PEVVo7U6uhalGIt7DkhJBz1gA0PiG2IWCO3vA=; b=fBZHd/YdHDW8ZUW/9dnIvgZ3H/5sU8MOFHyMPUpieOBcKvUET5sfnpWeMSZ8dqEo0Q8op9 MiRqs4R6GPqVunH07TDzIk1pIPfFHpf72ERKt4vbJ37bou561JG/g+04Y32eoTrIxNS8bT 6GqDTlfAAr9S7atIjdlLsh6Q8Vyo+DU= X-MC-Unique: bkzpZlCmNdekz5J36-pdOw-1 From: Peter Krempa To: libvir-list@redhat.com Subject: [PATCH 16/40] util: macmap: Convert to use GSList for storing macs instead of string lists Date: Sat, 6 Feb 2021 09:32:38 +0100 Message-Id: In-Reply-To: References: MIME-Version: 1.0 X-Scanned-By: MIMEDefang 2.79 on 10.5.11.12 X-loop: libvir-list@redhat.com X-BeenThere: libvir-list@redhat.com X-Mailman-Version: 2.1.12 Precedence: junk List-Id: Development discussions about the libvirt library & tools List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Sender: libvir-list-bounces@redhat.com Errors-To: libvir-list-bounces@redhat.com X-Scanned-By: MIMEDefang 2.79 on 10.5.11.11 Authentication-Results: relay.mimecast.com; auth=pass smtp.auth=CUSA124A263 smtp.mailfrom=libvir-list-bounces@redhat.com X-Mimecast-Spam-Score: 0 X-Mimecast-Originator: redhat.com Content-Transfer-Encoding: quoted-printable X-ZohoMail-DKIM: pass (identity @redhat.com) Content-Type: text/plain; charset="utf-8" Since adding and removing is the main use case for the macmap module, convert the code to a more efficient data structure. The refactor also optimizes the loading from file where previously we'd do a hash lookup + list lenght calculation for every entry. Signed-off-by: Peter Krempa --- src/util/virmacmap.c | 118 +++++++++++++++++++++++------------------- src/util/virmacmap.h | 6 ++- tests/virmacmaptest.c | 21 ++++---- 3 files changed, 81 insertions(+), 64 deletions(-) diff --git a/src/util/virmacmap.c b/src/util/virmacmap.c index ec0a67b433..0d458d7b7b 100644 --- a/src/util/virmacmap.c +++ b/src/util/virmacmap.c @@ -50,21 +50,18 @@ struct virMacMap { static virClassPtr virMacMapClass; -static int -virMacMapHashFree(void *payload, - const char *name G_GNUC_UNUSED, - void *opaque G_GNUC_UNUSED) -{ - g_strfreev(payload); - return 0; -} - - static void virMacMapDispose(void *obj) { virMacMapPtr mgr =3D obj; - virHashForEach(mgr->macs, virMacMapHashFree, NULL); + GHashTableIter htitr; + void *value; + + g_hash_table_iter_init(&htitr, mgr->macs); + + while (g_hash_table_iter_next(&htitr, NULL, &value)) + g_slist_free_full(value, g_free); + virHashFree(mgr->macs); } @@ -80,48 +77,57 @@ static int virMacMapOnceInit(void) VIR_ONCE_GLOBAL_INIT(virMacMap); -static int +static void virMacMapAddLocked(virMacMapPtr mgr, const char *domain, const char *mac) { - char **macsList =3D NULL; + GSList *orig_list; + GSList *list; + GSList *next; - if ((macsList =3D virHashLookup(mgr->macs, domain)) && - virStringListHasString((const char**) macsList, mac)) { - return 0; + list =3D orig_list =3D g_hash_table_lookup(mgr->macs, domain); + + for (next =3D list; next; next =3D next->next) { + if (STREQ((const char *) next->data, mac)) + return; } - if (virStringListAdd(&macsList, mac) < 0 || - virHashUpdateEntry(mgr->macs, domain, macsList) < 0) - return -1; + list =3D g_slist_append(list, g_strdup(mac)); - return 0; + if (list !=3D orig_list) + g_hash_table_insert(mgr->macs, g_strdup(domain), list); } -static int +static void virMacMapRemoveLocked(virMacMapPtr mgr, const char *domain, const char *mac) { - char **macsList =3D NULL; - char **newMacsList =3D NULL; + GSList *orig_list; + GSList *list; + GSList *next; - if (!(macsList =3D virHashLookup(mgr->macs, domain))) - return 0; + list =3D orig_list =3D g_hash_table_lookup(mgr->macs, domain); - newMacsList =3D macsList; - virStringListRemove(&newMacsList, mac); - if (!newMacsList) { - virHashSteal(mgr->macs, domain); - } else { - if (macsList !=3D newMacsList && - virHashUpdateEntry(mgr->macs, domain, newMacsList) < 0) - return -1; + if (!orig_list) + return; + + for (next =3D list; next; next =3D next->next) { + if (STREQ((const char *) next->data, mac)) { + list =3D g_slist_remove_link(list, next); + g_slist_free_full(next, g_free); + break; + } } - return 0; + if (list !=3D orig_list) { + if (list) + g_hash_table_insert(mgr->macs, g_strdup(domain), list); + else + g_hash_table_remove(mgr->macs, domain); + } } @@ -162,6 +168,7 @@ virMacMapLoadFile(virMacMapPtr mgr, virJSONValuePtr macs; const char *domain; size_t j; + GSList *vals =3D NULL; if (!(domain =3D virJSONValueObjectGetString(tmp, "domain"))) { virReportError(VIR_ERR_INTERNAL_ERROR, "%s", @@ -175,13 +182,21 @@ virMacMapLoadFile(virMacMapPtr mgr, return -1; } + if (g_hash_table_contains(mgr->macs, domain)) { + virReportError(VIR_ERR_INTERNAL_ERROR, + _("duplicate domain '%s'"), domain); + return -1; + + } + for (j =3D 0; j < virJSONValueArraySize(macs); j++) { virJSONValuePtr macJSON =3D virJSONValueArrayGet(macs, j); - const char *mac =3D virJSONValueGetString(macJSON); - if (virMacMapAddLocked(mgr, domain, mac) < 0) - return -1; + vals =3D g_slist_prepend(vals, g_strdup(virJSONValueGetString(= macJSON))); } + + vals =3D g_slist_reverse(vals); + g_hash_table_insert(mgr->macs, g_strdup(domain), vals); } return 0; @@ -195,11 +210,11 @@ virMACMapHashDumper(void *payload, { g_autoptr(virJSONValue) obj =3D virJSONValueNewObject(); g_autoptr(virJSONValue) arr =3D virJSONValueNewArray(); - const char **macs =3D payload; - size_t i; + GSList *macs =3D payload; + GSList *next; - for (i =3D 0; macs[i]; i++) { - virJSONValuePtr m =3D virJSONValueNewString(macs[i]); + for (next =3D macs; next; next =3D next->next) { + virJSONValuePtr m =3D virJSONValueNewString((const char *) next->d= ata); if (!m || virJSONValueArrayAppend(arr, m) < 0) { @@ -279,8 +294,8 @@ virMacMapNew(const char *file) return NULL; virObjectLock(mgr); - if (!(mgr->macs =3D virHashNew(NULL))) - goto error; + + mgr->macs =3D virHashNew(NULL); if (file && virMacMapLoadFile(mgr, file) < 0) @@ -301,12 +316,10 @@ virMacMapAdd(virMacMapPtr mgr, const char *domain, const char *mac) { - int ret; - virObjectLock(mgr); - ret =3D virMacMapAddLocked(mgr, domain, mac); + virMacMapAddLocked(mgr, domain, mac); virObjectUnlock(mgr); - return ret; + return 0; } @@ -315,20 +328,19 @@ virMacMapRemove(virMacMapPtr mgr, const char *domain, const char *mac) { - int ret; - virObjectLock(mgr); - ret =3D virMacMapRemoveLocked(mgr, domain, mac); + virMacMapRemoveLocked(mgr, domain, mac); virObjectUnlock(mgr); - return ret; + return 0; } -const char *const * +/* note that the returned pointer may be invalidated by other APIs in this= module */ +GSList * virMacMapLookup(virMacMapPtr mgr, const char *domain) { - const char *const *ret; + GSList *ret; virObjectLock(mgr); ret =3D virHashLookup(mgr->macs, domain); diff --git a/src/util/virmacmap.h b/src/util/virmacmap.h index 4652295033..96e32256e3 100644 --- a/src/util/virmacmap.h +++ b/src/util/virmacmap.h @@ -20,6 +20,8 @@ #pragma once +#include "internal.h" + typedef struct virMacMap virMacMap; typedef virMacMap *virMacMapPtr; @@ -37,8 +39,8 @@ int virMacMapRemove(virMacMapPtr mgr, const char *domain, const char *mac); -const char *const *virMacMapLookup(virMacMapPtr mgr, - const char *domain); +GSList *virMacMapLookup(virMacMapPtr mgr, + const char *domain); int virMacMapWriteFile(virMacMapPtr mgr, const char *filename); diff --git a/tests/virmacmaptest.c b/tests/virmacmaptest.c index 8fd9916b95..77fa2b3e98 100644 --- a/tests/virmacmaptest.c +++ b/tests/virmacmaptest.c @@ -36,7 +36,8 @@ testMACLookup(const void *opaque) { const struct testData *data =3D opaque; virMacMapPtr mgr =3D NULL; - const char * const * macs; + GSList *macs; + GSList *next; size_t i, j; char *file =3D NULL; int ret =3D -1; @@ -48,26 +49,27 @@ testMACLookup(const void *opaque) macs =3D virMacMapLookup(mgr, data->domain); - for (i =3D 0; macs && macs[i]; i++) { + for (next =3D macs; next; next =3D next->next) { for (j =3D 0; data->macs && data->macs[j]; j++) { - if (STREQ(macs[i], data->macs[j])) + if (STREQ((const char *) next->data, data->macs[j])) break; } if (!data->macs || !data->macs[j]) { fprintf(stderr, - "Unexpected %s in the returned list of MACs\n", macs[i= ]); + "Unexpected %s in the returned list of MACs\n", + (const char *) next->data); goto cleanup; } } for (i =3D 0; data->macs && data->macs[i]; i++) { - for (j =3D 0; macs && macs[j]; j++) { - if (STREQ(data->macs[i], macs[j])) + for (next =3D macs; next; next =3D next->next) { + if (STREQ(data->macs[i], (const char *) next->data)) break; } - if (!macs || !macs[j]) { + if (!next) { fprintf(stderr, "Expected %s in the returned list of MACs\n", data->ma= cs[i]); goto cleanup; @@ -87,7 +89,7 @@ testMACRemove(const void *opaque) { const struct testData *data =3D opaque; virMacMapPtr mgr =3D NULL; - const char * const * macs; + GSList *macs; size_t i; char *file =3D NULL; int ret =3D -1; @@ -107,7 +109,8 @@ testMACRemove(const void *opaque) if ((macs =3D virMacMapLookup(mgr, data->domain))) { fprintf(stderr, - "Not removed all MACs for domain %s: %s\n", data->domain, = macs[0]); + "Not removed all MACs for domain %s: %s\n", + data->domain, (const char *) macs->data); goto cleanup; } --=20 2.29.2