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