X-Git-Url: https://git.octo.it/?p=collectd.git;a=blobdiff_plain;f=src%2Fvirt.c;h=9cfdb0522f72f1946bb6dc155e561d159147d44c;hp=509e1494b1f6c0372e3253a30c57f59723c049de;hb=6358e0720149251d1720c4a1a7582bb58f8a65ff;hpb=c07e76d81a7790c265676045e96c88a88a7cc85a diff --git a/src/virt.c b/src/virt.c index 509e1494..9cfdb052 100644 --- a/src/virt.c +++ b/src/virt.c @@ -108,6 +108,9 @@ #define HAVE_DOM_REASON_POSTCOPY 1 #endif +#if LIBVIR_CHECK_VERSION(4, 10, 0) +#define HAVE_DOM_REASON_SHUTOFF_DAEMON 1 +#endif #endif /* LIBVIR_CHECK_VERSION */ /* structure used for aggregating notification-thread data*/ @@ -301,6 +304,16 @@ static int map_domain_event_detail_to_reason(int event, int detail) { switch (detail) { case VIR_DOMAIN_EVENT_SHUTDOWN_FINISHED: /* Guest finished shutdown sequence */ +#ifdef LIBVIR_CHECK_VERSION +#if LIBVIR_CHECK_VERSION(3, 4, 0) + case VIR_DOMAIN_EVENT_SHUTDOWN_GUEST: /* Domain finished shutting down after + request from the guest itself (e.g. + hardware-specific action) */ + case VIR_DOMAIN_EVENT_SHUTDOWN_HOST: /* Domain finished shutting down after + request from the host (e.g. killed + by a signal) */ +#endif +#endif ret = VIR_DOMAIN_SHUTDOWN_USER; break; default: @@ -426,6 +439,10 @@ const char *domain_reasons[][DOMAIN_STATE_REASON_MAX_SIZE] = { "domain failed to start", [VIR_DOMAIN_SHUTOFF][VIR_DOMAIN_SHUTOFF_FROM_SNAPSHOT] = "restored from a snapshot which was taken while domain was shutoff", +#ifdef HAVE_DOM_REASON_SHUTOFF_DAEMON + [VIR_DOMAIN_SHUTOFF][VIR_DOMAIN_SHUTOFF_DAEMON] = + "daemon decides to kill domain during reconnection processing", +#endif [VIR_DOMAIN_CRASHED][VIR_DOMAIN_CRASHED_UNKNOWN] = "the reason is unknown", @@ -636,6 +653,8 @@ static enum if_field interface_format = if_name; static time_t last_refresh = (time_t)0; static int refresh_lists(struct lv_read_instance *inst); +static int register_event_impl(void); +static int start_event_loop(virt_notif_thread_t *thread_data); struct lv_block_stats { virDomainBlockStatsStruct bi; @@ -917,10 +936,10 @@ static void memory_submit(virDomainPtr dom, gauge_t value) { static void memory_stats_submit(gauge_t value, virDomainPtr dom, int tag_index) { - static const char *tags[] = {"swap_in", "swap_out", "major_fault", - "minor_fault", "unused", "available", - "actual_balloon", "rss", "usable", - "last_update"}; + static const char *tags[] = {"swap_in", "swap_out", "major_fault", + "minor_fault", "unused", "available", + "actual_balloon", "rss", "usable", + "last_update", "disk_caches"}; if ((tag_index < 0) || (tag_index >= (int)STATIC_ARRAY_SIZE(tags))) { ERROR("virt plugin: Array index out of bounds: tag_index = %d", tag_index); @@ -1442,6 +1461,11 @@ static int lv_config(oconfig_item_t *ci) { static int lv_connect(void) { if (conn == NULL) { + /* event implementation must be registered before connection is opened */ + if (!persistent_notification) + if (register_event_impl() != 0) + return -1; + /* `conn_string == NULL' is acceptable */ #ifdef HAVE_FS_INFO /* virDomainGetFSInfo requires full read-write access connection */ @@ -1459,8 +1483,17 @@ static int lv_connect(void) { int status = virNodeGetInfo(conn, &nodeinfo); if (status != 0) { ERROR(PLUGIN_NAME " plugin: virNodeGetInfo failed"); + virConnectClose(conn); + conn = NULL; return -1; } + + if (!persistent_notification) + if (start_event_loop(¬if_thread) != 0) { + virConnectClose(conn); + conn = NULL; + return -1; + } } c_release(LOG_NOTICE, &conn_complain, PLUGIN_NAME " plugin: Connection established."); @@ -1632,16 +1665,7 @@ static int get_pcpu_stats(virDomainPtr dom) { #endif /* HAVE_CPU_STATS */ #ifdef HAVE_DOM_REASON - -static void domain_state_submit(virDomainPtr dom, int state, int reason) { - value_t values[] = { - {.gauge = (gauge_t)state}, {.gauge = (gauge_t)reason}, - }; - - submit(dom, "domain_state", NULL, values, STATIC_ARRAY_SIZE(values)); -} - -static int get_domain_state(virDomainPtr domain) { +static int submit_domain_state(virDomainPtr domain) { int domain_state = 0; int domain_reason = 0; @@ -1652,9 +1676,13 @@ static int get_domain_state(virDomainPtr domain) { return status; } - domain_state_submit(domain, domain_state, domain_reason); + value_t values[] = { + {.gauge = (gauge_t)domain_state}, {.gauge = (gauge_t)domain_reason}, + }; - return status; + submit(domain, "domain_state", NULL, values, STATIC_ARRAY_SIZE(values)); + + return 0; } #ifdef HAVE_LIST_ALL_DOMAINS @@ -1669,8 +1697,7 @@ static int get_domain_state_notify(virDomainPtr domain) { return status; } - if (persistent_notification) - domain_state_submit_notif(domain, domain_state, domain_reason); + domain_state_submit_notif(domain, domain_state, domain_reason); return status; } @@ -1974,7 +2001,7 @@ static int get_domain_metrics(domain_t *domain) { * however it doesn't provide a reason for entering particular state. * We need to get it from virDomainGetState. */ - GET_STATS(get_domain_state, "domain reason", domain->ptr); + GET_STATS(submit_domain_state, "domain reason", domain->ptr); #endif } @@ -2126,10 +2153,9 @@ static void *event_loop_worker(void *arg) { } static int virt_notif_thread_init(virt_notif_thread_t *thread_data) { - int ret; - assert(thread_data != NULL); - ret = pthread_mutex_init(&thread_data->active_mutex, NULL); + + int ret = pthread_mutex_init(&thread_data->active_mutex, NULL); if (ret != 0) { ERROR(PLUGIN_NAME " plugin: Failed to initialize mutex, err %u", ret); return ret; @@ -2265,33 +2291,26 @@ static int persistent_domains_state_notification(void) { } static int lv_read(user_data_t *ud) { - time_t t; - struct lv_read_instance *inst = NULL; - struct lv_read_state *state = NULL; - if (ud->data == NULL) { ERROR(PLUGIN_NAME " plugin: NULL userdata"); return -1; } - inst = ud->data; - state = &inst->read_state; - - bool reconnect = conn == NULL ? true : false; - /* event implementation must be registered before connection is opened */ - if (inst->id == 0) { - if (!persistent_notification && reconnect) - if (register_event_impl() != 0) - return -1; + struct lv_read_instance *inst = ud->data; + struct lv_read_state *state = &inst->read_state; + if (inst->id == 0) if (lv_connect() < 0) return -1; - if (!persistent_notification && reconnect && conn != NULL) - if (start_event_loop(¬if_thread) != 0) - return -1; + /* Wait until inst#0 establish connection */ + if (conn == NULL) { + DEBUG(PLUGIN_NAME " plugin#%s: Wait until inst#0 establish connection", + inst->tag); + return 0; } + time_t t; time(&t); /* Need to refresh domain or device lists? */ @@ -2338,8 +2357,8 @@ static int lv_read(user_data_t *ud) { if (dom->active) status = get_domain_metrics(dom); #ifdef HAVE_DOM_REASON - else - status = get_domain_state(dom->ptr); + else if (extra_stats & ex_stats_domain_state) + status = submit_domain_state(dom->ptr); #endif if (status != 0) @@ -2412,19 +2431,11 @@ static int lv_init(void) { if (lv_init_ignorelists() != 0) return -1; - /* event implementation must be registered before connection is opened */ if (!persistent_notification) - if (register_event_impl() != 0) + if (virt_notif_thread_init(¬if_thread) != 0) return -1; - if (lv_connect() != 0) - return -1; - - if (!persistent_notification) { - virt_notif_thread_init(¬if_thread); - if (start_event_loop(¬if_thread) != 0) - return -1; - } + lv_connect(); DEBUG(PLUGIN_NAME " plugin: starting %i instances", nr_instances);