[libvirt PATCH 03/11] src: set the OS level thread name

Daniel P. Berrangé berrange at redhat.com
Fri Feb 14 12:52:01 UTC 2020


Setting the thread name makes it easier to debug libvirtd
when many threads are running.

Signed-off-by: Daniel P. Berrangé <berrange at redhat.com>
---
 src/libvirt_private.syms |  1 +
 src/util/virthread.c     | 44 +++++++++++++++++++++++++++++++++++-----
 src/util/virthread.h     |  4 +++-
 3 files changed, 43 insertions(+), 6 deletions(-)

diff --git a/src/libvirt_private.syms b/src/libvirt_private.syms
index dc0449d1d8..375e6ea000 100644
--- a/src/libvirt_private.syms
+++ b/src/libvirt_private.syms
@@ -3258,6 +3258,7 @@ virThreadCreateFull;
 virThreadID;
 virThreadIsSelf;
 virThreadJoin;
+virThreadMaxName;
 virThreadSelf;
 virThreadSelfID;
 
diff --git a/src/util/virthread.c b/src/util/virthread.c
index cdc5cab604..750e8d5655 100644
--- a/src/util/virthread.c
+++ b/src/util/virthread.c
@@ -175,23 +175,57 @@ void virCondBroadcast(virCondPtr c)
 
 struct virThreadArgs {
     virThreadFunc func;
-    const char *funcName;
+    char *name;
     bool worker;
     void *opaque;
 };
 
+size_t virThreadMaxName(void)
+{
+#if defined(__FreeBSD__) || defined(__APPLE__)
+    return 63;
+#else
+# ifdef __linux__
+    return 15;
+# else
+    return 0; /* unlimited */
+# endif
+#endif
+}
+
 static void *virThreadHelper(void *data)
 {
     struct virThreadArgs *args = data;
     struct virThreadArgs local = *args;
+    g_autofree char *thname = NULL;
+    size_t maxname = virThreadMaxName();
 
     /* Free args early, rather than tying it up during the entire thread.  */
     VIR_FREE(args);
 
     if (local.worker)
-        virThreadJobSetWorker(local.funcName);
+        virThreadJobSetWorker(local.name);
     else
-        virThreadJobSet(local.funcName);
+        virThreadJobSet(local.name);
+
+    if (maxname) {
+        thname = g_strndup(local.name, maxname);
+    } else {
+        thname = g_strdup(local.name);
+    }
+    g_free(local.name);
+
+#if defined(__linux__) || defined(WIN32)
+    pthread_setname_np(pthread_self(), thname);
+#else
+# ifdef __FreeBSD__
+    pthread_set_name_np(pthread_self(), thname);
+# else
+#  ifdef __APPLE__
+    pthread_setname_np(thname);
+#  endif
+# endif
+#endif
 
     local.func(local.opaque);
 
@@ -204,7 +238,7 @@ static void *virThreadHelper(void *data)
 int virThreadCreateFull(virThreadPtr thread,
                         bool joinable,
                         virThreadFunc func,
-                        const char *funcName,
+                        const char *name,
                         bool worker,
                         void *opaque)
 {
@@ -221,7 +255,7 @@ int virThreadCreateFull(virThreadPtr thread,
     }
 
     args->func = func;
-    args->funcName = funcName;
+    args->name = g_strdup(name);
     args->worker = worker;
     args->opaque = opaque;
 
diff --git a/src/util/virthread.h b/src/util/virthread.h
index a7960e444a..c227951ddd 100644
--- a/src/util/virthread.h
+++ b/src/util/virthread.h
@@ -90,13 +90,15 @@ typedef void (*virThreadFunc)(void *opaque);
 int virThreadCreateFull(virThreadPtr thread,
                         bool joinable,
                         virThreadFunc func,
-                        const char *funcName,
+                        const char *name,
                         bool worker,
                         void *opaque) G_GNUC_WARN_UNUSED_RESULT;
 void virThreadSelf(virThreadPtr thread);
 bool virThreadIsSelf(virThreadPtr thread);
 void virThreadJoin(virThreadPtr thread);
 
+size_t virThreadMaxName(void);
+
 /* This API is *NOT* for general use. It exists solely as a stub
  * for integration with libselinux AVC callbacks */
 void virThreadCancel(virThreadPtr thread);
-- 
2.24.1




More information about the libvir-list mailing list