]> git.ipfire.org Git - thirdparty/libvirt.git/commitdiff
src: set the OS level thread name
authorDaniel P. Berrangé <berrange@redhat.com>
Fri, 14 Feb 2020 10:44:01 +0000 (10:44 +0000)
committerDaniel P. Berrangé <berrange@redhat.com>
Thu, 5 Mar 2020 12:23:02 +0000 (12:23 +0000)
Setting the thread name makes it easier to debug libvirtd
when many threads are running.

Reviewed-by: Michal Privoznik <mprivozn@redhat.com>
Signed-off-by: Daniel P. Berrangé <berrange@redhat.com>
src/libvirt_private.syms
src/util/virthread.c
src/util/virthread.h

index 8563695c3220083a2c989c47b45f7b1c619f8e7a..07dee6d841d9ddd8edfd704947324b8ec4dda19e 100644 (file)
@@ -3279,6 +3279,7 @@ virThreadCreateFull;
 virThreadID;
 virThreadIsSelf;
 virThreadJoin;
+virThreadMaxName;
 virThreadSelf;
 virThreadSelfID;
 
index cdc5cab60489be40f74d9fe4927daf460473f274..40792afdc069081ae12b700d76479916d7b38427 100644 (file)
@@ -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);
+    g_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;
 
@@ -230,7 +264,8 @@ int virThreadCreateFull(virThreadPtr thread,
 
     err = pthread_create(&thread->thread, &attr, virThreadHelper, args);
     if (err != 0) {
-        VIR_FREE(args);
+        g_free(args->name);
+        g_free(args);
         goto cleanup;
     }
     /* New thread owns 'args' in success case, so don't free */
index a7960e444a19dce298cb4e30ae861a07cc9562f3..c227951ddd69e4d2b858635c66bb1de5593099e0 100644 (file)
@@ -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);