render / rpms / libvirt

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