Blame SOURCES/libvirt-util-hash-Improve-debugability-of-Duplicate-key-error-message.patch

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