render / rpms / libvirt

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