forked from rpms/libvirt
210 lines
7.4 KiB
Diff
210 lines
7.4 KiB
Diff
|
From 14d881a9ddd3820be9518cc38e5504f26bf5fd56 Mon Sep 17 00:00:00 2001
|
||
|
Message-Id: <14d881a9ddd3820be9518cc38e5504f26bf5fd56@dist-git>
|
||
|
From: Peter Krempa <pkrempa@redhat.com>
|
||
|
Date: Tue, 4 Feb 2020 15:07:43 +0100
|
||
|
Subject: [PATCH] util: hash: Improve debugability of "Duplicate key" error
|
||
|
message
|
||
|
MIME-Version: 1.0
|
||
|
Content-Type: text/plain; charset=UTF-8
|
||
|
Content-Transfer-Encoding: 8bit
|
||
|
|
||
|
If we get a user reporting this error message being shown it's pretty
|
||
|
useless in terms of actually debugging it since we don't know which hash
|
||
|
and which key are actually subject to the error.
|
||
|
|
||
|
This patch adds a new hash table callback which formats the
|
||
|
user-readable version of the hash key and reports it in the new message
|
||
|
which will look like:
|
||
|
|
||
|
"Duplicate hash table key 'blah'"
|
||
|
|
||
|
That way we will at least have an anchor point where to start the
|
||
|
search.
|
||
|
|
||
|
There are two special implementations of keys which are numeric so we
|
||
|
add specific printer functions for them.
|
||
|
|
||
|
Signed-off-by: Peter Krempa <pkrempa@redhat.com>
|
||
|
Reviewed-by: Michal Privoznik <mprivozn@redhat.com>
|
||
|
(cherry picked from commit ae60e05817d6ea2d47533051c31e16b430453d62)
|
||
|
|
||
|
https://bugzilla.redhat.com/show_bug.cgi?id=1207659
|
||
|
Message-Id: <214b5e7934db2f3d3b097c9e19f4e89de4912b6d.1580824112.git.pkrempa@redhat.com>
|
||
|
Reviewed-by: Ján Tomko <jtomko@redhat.com>
|
||
|
---
|
||
|
src/conf/domain_addr.c | 9 +++++++++
|
||
|
src/util/vircgroup.c | 8 ++++++++
|
||
|
src/util/virhash.c | 22 ++++++++++++++++++++--
|
||
|
src/util/virhash.h | 13 +++++++++++++
|
||
|
4 files changed, 50 insertions(+), 2 deletions(-)
|
||
|
|
||
|
diff --git a/src/conf/domain_addr.c b/src/conf/domain_addr.c
|
||
|
index ef7ee80e6a..607ba56efd 100644
|
||
|
--- a/src/conf/domain_addr.c
|
||
|
+++ b/src/conf/domain_addr.c
|
||
|
@@ -1007,6 +1007,13 @@ virZPCIAddrKeyCopy(const void *name)
|
||
|
}
|
||
|
|
||
|
|
||
|
+static char *
|
||
|
+virZPCIAddrKeyPrintHuman(const void *name)
|
||
|
+{
|
||
|
+ return g_strdup_printf("%u", *((unsigned int *)name));
|
||
|
+}
|
||
|
+
|
||
|
+
|
||
|
static void
|
||
|
virZPCIAddrKeyFree(void *name)
|
||
|
{
|
||
|
@@ -1041,6 +1048,7 @@ virDomainPCIAddressSetExtensionAlloc(virDomainPCIAddressSetPtr addrs,
|
||
|
virZPCIAddrKeyCode,
|
||
|
virZPCIAddrKeyEqual,
|
||
|
virZPCIAddrKeyCopy,
|
||
|
+ virZPCIAddrKeyPrintHuman,
|
||
|
virZPCIAddrKeyFree)))
|
||
|
goto error;
|
||
|
|
||
|
@@ -1048,6 +1056,7 @@ virDomainPCIAddressSetExtensionAlloc(virDomainPCIAddressSetPtr addrs,
|
||
|
virZPCIAddrKeyCode,
|
||
|
virZPCIAddrKeyEqual,
|
||
|
virZPCIAddrKeyCopy,
|
||
|
+ virZPCIAddrKeyPrintHuman,
|
||
|
virZPCIAddrKeyFree)))
|
||
|
goto error;
|
||
|
}
|
||
|
diff --git a/src/util/vircgroup.c b/src/util/vircgroup.c
|
||
|
index 87ed9f4565..dff2f6fd3a 100644
|
||
|
--- a/src/util/vircgroup.c
|
||
|
+++ b/src/util/vircgroup.c
|
||
|
@@ -2502,6 +2502,13 @@ virCgroupPidCopy(const void *name)
|
||
|
}
|
||
|
|
||
|
|
||
|
+static char *
|
||
|
+virCgroupPidPrintHuman(const void *name)
|
||
|
+{
|
||
|
+ return g_strdup_printf("%ld", (const long)name);
|
||
|
+}
|
||
|
+
|
||
|
+
|
||
|
int
|
||
|
virCgroupKillRecursiveInternal(virCgroupPtr group,
|
||
|
int signum,
|
||
|
@@ -2587,6 +2594,7 @@ virCgroupKillRecursive(virCgroupPtr group, int signum)
|
||
|
virCgroupPidCode,
|
||
|
virCgroupPidEqual,
|
||
|
virCgroupPidCopy,
|
||
|
+ virCgroupPidPrintHuman,
|
||
|
NULL);
|
||
|
|
||
|
VIR_DEBUG("group=%p path=%s signum=%d", group, group->path, signum);
|
||
|
diff --git a/src/util/virhash.c b/src/util/virhash.c
|
||
|
index 313ca57a54..edf11e8b7a 100644
|
||
|
--- a/src/util/virhash.c
|
||
|
+++ b/src/util/virhash.c
|
||
|
@@ -59,6 +59,7 @@ struct _virHashTable {
|
||
|
virHashKeyCode keyCode;
|
||
|
virHashKeyEqual keyEqual;
|
||
|
virHashKeyCopy keyCopy;
|
||
|
+ virHashKeyPrintHuman keyPrint;
|
||
|
virHashKeyFree keyFree;
|
||
|
};
|
||
|
|
||
|
@@ -98,6 +99,14 @@ static void *virHashStrCopy(const void *name)
|
||
|
return ret;
|
||
|
}
|
||
|
|
||
|
+
|
||
|
+static char *
|
||
|
+virHashStrPrintHuman(const void *name)
|
||
|
+{
|
||
|
+ return g_strdup(name);
|
||
|
+}
|
||
|
+
|
||
|
+
|
||
|
static void virHashStrFree(void *name)
|
||
|
{
|
||
|
VIR_FREE(name);
|
||
|
@@ -136,6 +145,7 @@ virHashTablePtr virHashCreateFull(ssize_t size,
|
||
|
virHashKeyCode keyCode,
|
||
|
virHashKeyEqual keyEqual,
|
||
|
virHashKeyCopy keyCopy,
|
||
|
+ virHashKeyPrintHuman keyPrint,
|
||
|
virHashKeyFree keyFree)
|
||
|
{
|
||
|
virHashTablePtr table = NULL;
|
||
|
@@ -153,6 +163,7 @@ virHashTablePtr virHashCreateFull(ssize_t size,
|
||
|
table->keyCode = keyCode;
|
||
|
table->keyEqual = keyEqual;
|
||
|
table->keyCopy = keyCopy;
|
||
|
+ table->keyPrint = keyPrint;
|
||
|
table->keyFree = keyFree;
|
||
|
|
||
|
if (VIR_ALLOC_N(table->table, size) < 0) {
|
||
|
@@ -180,6 +191,7 @@ virHashNew(virHashDataFree dataFree)
|
||
|
virHashStrCode,
|
||
|
virHashStrEqual,
|
||
|
virHashStrCopy,
|
||
|
+ virHashStrPrintHuman,
|
||
|
virHashStrFree);
|
||
|
}
|
||
|
|
||
|
@@ -200,6 +212,7 @@ virHashTablePtr virHashCreate(ssize_t size, virHashDataFree dataFree)
|
||
|
virHashStrCode,
|
||
|
virHashStrEqual,
|
||
|
virHashStrCopy,
|
||
|
+ virHashStrPrintHuman,
|
||
|
virHashStrFree);
|
||
|
}
|
||
|
|
||
|
@@ -353,8 +366,13 @@ virHashAddOrUpdateEntry(virHashTablePtr table, const void *name,
|
||
|
entry->payload = userdata;
|
||
|
return 0;
|
||
|
} else {
|
||
|
- virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
|
||
|
- _("Duplicate key"));
|
||
|
+ g_autofree char *keystr = NULL;
|
||
|
+
|
||
|
+ if (table->keyPrint)
|
||
|
+ keystr = table->keyPrint(name);
|
||
|
+
|
||
|
+ virReportError(VIR_ERR_INTERNAL_ERROR,
|
||
|
+ _("Duplicate hash table key '%s'"), NULLSTR(keystr));
|
||
|
return -1;
|
||
|
}
|
||
|
}
|
||
|
diff --git a/src/util/virhash.h b/src/util/virhash.h
|
||
|
index 6318c0b3cd..08f99d8a3d 100644
|
||
|
--- a/src/util/virhash.h
|
||
|
+++ b/src/util/virhash.h
|
||
|
@@ -86,6 +86,18 @@ typedef bool (*virHashKeyEqual)(const void *namea, const void *nameb);
|
||
|
* Returns a newly allocated copy of @name
|
||
|
*/
|
||
|
typedef void *(*virHashKeyCopy)(const void *name);
|
||
|
+/**
|
||
|
+ * virHashKeyPrintHuman:
|
||
|
+ * @name: the hash key
|
||
|
+ *
|
||
|
+ * Get a human readable version of the key for error messages. Caller
|
||
|
+ * will free the returned string.
|
||
|
+ *
|
||
|
+ * Returns a string representation of the key for use in error messages. Caller
|
||
|
+ * promises to always free the returned string.
|
||
|
+ */
|
||
|
+typedef char *(*virHashKeyPrintHuman) (const void *name);
|
||
|
+
|
||
|
/**
|
||
|
* virHashKeyFree:
|
||
|
* @name: the hash key
|
||
|
@@ -108,6 +120,7 @@ virHashTablePtr virHashCreateFull(ssize_t size,
|
||
|
virHashKeyCode keyCode,
|
||
|
virHashKeyEqual keyEqual,
|
||
|
virHashKeyCopy keyCopy,
|
||
|
+ virHashKeyPrintHuman keyPrint,
|
||
|
virHashKeyFree keyFree);
|
||
|
void virHashFree(virHashTablePtr table);
|
||
|
ssize_t virHashSize(const virHashTable *table);
|
||
|
--
|
||
|
2.25.0
|
||
|
|