From: Pavel Rochnyack Date: Tue, 26 Feb 2019 19:59:17 +0000 (+0700) Subject: virt plugin: Fix segfaults on shutdown X-Git-Url: https://git.octo.it/?p=collectd.git;a=commitdiff_plain;h=534d17bc347478ed775c7b6c62eaeac7d85a1fea virt plugin: Fix segfaults on shutdown If connection has failed then `lv_init' returns early without initializing `notif_thread'. This causes segfault due to incorrect `pthread_join()` call on Collectd shutdown. Closes: #3082 --- diff --git a/src/virt.c b/src/virt.c index d44aeb76..00227dd8 100644 --- a/src/virt.c +++ b/src/virt.c @@ -2059,7 +2059,9 @@ static int start_event_loop(virt_notif_thread_t *thread_data) { if (pthread_create(&thread_data->event_loop_tid, NULL, event_loop_worker, thread_data)) { ERROR(PLUGIN_NAME " plugin: failed event loop thread creation"); + virt_notif_thread_set_active(thread_data, 0); virConnectDomainEventDeregisterAny(conn, thread_data->domain_event_cb_id); + thread_data->domain_event_cb_id = -1; return -1; } @@ -2068,13 +2070,18 @@ static int start_event_loop(virt_notif_thread_t *thread_data) { /* stop event loop thread and deregister callback */ static void stop_event_loop(virt_notif_thread_t *thread_data) { - /* stopping loop and de-registering event handler*/ - virt_notif_thread_set_active(thread_data, 0); - if (conn != NULL && thread_data->domain_event_cb_id != -1) - virConnectDomainEventDeregisterAny(conn, thread_data->domain_event_cb_id); + /* Stopping loop */ + if (virt_notif_thread_is_active(thread_data)) { + virt_notif_thread_set_active(thread_data, 0); + if (pthread_join(notif_thread.event_loop_tid, NULL) != 0) + ERROR(PLUGIN_NAME " plugin: stopping notification thread failed"); + } - if (pthread_join(notif_thread.event_loop_tid, NULL) != 0) - ERROR(PLUGIN_NAME " plugin: stopping notification thread failed"); + /* ... and de-registering event handler */ + if (conn != NULL && thread_data->domain_event_cb_id != -1) { + virConnectDomainEventDeregisterAny(conn, thread_data->domain_event_cb_id); + thread_data->domain_event_cb_id = -1; + } } static int persistent_domains_state_notification(void) {