X-Git-Url: https://git.octo.it/?p=collectd.git;a=blobdiff_plain;f=src%2Fvirt.c;h=01c7c7771d2e1a95384f24ae8c30f6c089cefa38;hp=81bf18f8e0c2728aba6e3aa065d239b64f486aec;hb=a811574a6acbf87f23948411876a231fecaeb491;hpb=a1bba58ed83a67ba47e7c88dca6a939ce3181a9d diff --git a/src/virt.c b/src/virt.c index 81bf18f8..01c7c777 100644 --- a/src/virt.c +++ b/src/virt.c @@ -131,16 +131,16 @@ static bool report_network_interfaces = true; static virt_notif_thread_t notif_thread; const char *domain_states[] = { - [VIR_DOMAIN_NOSTATE] = "no state", - [VIR_DOMAIN_RUNNING] = "the domain is running", - [VIR_DOMAIN_BLOCKED] = "the domain is blocked on resource", - [VIR_DOMAIN_PAUSED] = "the domain is paused by user", - [VIR_DOMAIN_SHUTDOWN] = "the domain is being shut down", - [VIR_DOMAIN_SHUTOFF] = "the domain is shut off", - [VIR_DOMAIN_CRASHED] = "the domain is crashed", + [VIR_DOMAIN_NOSTATE] = "no state", + [VIR_DOMAIN_RUNNING] = "the domain is running", + [VIR_DOMAIN_BLOCKED] = "the domain is blocked on resource", + [VIR_DOMAIN_PAUSED] = "the domain is paused by user", + [VIR_DOMAIN_SHUTDOWN] = "the domain is being shut down", + [VIR_DOMAIN_SHUTOFF] = "the domain is shut off", + [VIR_DOMAIN_CRASHED] = "the domain is crashed", #ifdef HAVE_DOM_STATE_PMSUSPENDED - [VIR_DOMAIN_PMSUSPENDED] = - "the domain is suspended by guest power management", + [VIR_DOMAIN_PMSUSPENDED] = + "the domain is suspended by guest power management", #endif }; @@ -352,107 +352,99 @@ static int map_domain_event_detail_to_reason(int event, int detail) { #define DOMAIN_STATE_REASON_MAX_SIZE 20 const char *domain_reasons[][DOMAIN_STATE_REASON_MAX_SIZE] = { - [VIR_DOMAIN_NOSTATE][VIR_DOMAIN_NOSTATE_UNKNOWN] = - "the reason is unknown", - - [VIR_DOMAIN_RUNNING][VIR_DOMAIN_RUNNING_UNKNOWN] = - "the reason is unknown", - [VIR_DOMAIN_RUNNING][VIR_DOMAIN_RUNNING_BOOTED] = - "normal startup from boot", - [VIR_DOMAIN_RUNNING][VIR_DOMAIN_RUNNING_MIGRATED] = - "migrated from another host", - [VIR_DOMAIN_RUNNING][VIR_DOMAIN_RUNNING_RESTORED] = - "restored from a state file", - [VIR_DOMAIN_RUNNING][VIR_DOMAIN_RUNNING_FROM_SNAPSHOT] = - "restored from snapshot", - [VIR_DOMAIN_RUNNING][VIR_DOMAIN_RUNNING_UNPAUSED] = - "returned from paused state", - [VIR_DOMAIN_RUNNING][VIR_DOMAIN_RUNNING_MIGRATION_CANCELED] = - "returned from migration", - [VIR_DOMAIN_RUNNING][VIR_DOMAIN_RUNNING_SAVE_CANCELED] = - "returned from failed save process", + [VIR_DOMAIN_NOSTATE][VIR_DOMAIN_NOSTATE_UNKNOWN] = "the reason is unknown", + + [VIR_DOMAIN_RUNNING][VIR_DOMAIN_RUNNING_UNKNOWN] = "the reason is unknown", + [VIR_DOMAIN_RUNNING][VIR_DOMAIN_RUNNING_BOOTED] = + "normal startup from boot", + [VIR_DOMAIN_RUNNING][VIR_DOMAIN_RUNNING_MIGRATED] = + "migrated from another host", + [VIR_DOMAIN_RUNNING][VIR_DOMAIN_RUNNING_RESTORED] = + "restored from a state file", + [VIR_DOMAIN_RUNNING][VIR_DOMAIN_RUNNING_FROM_SNAPSHOT] = + "restored from snapshot", + [VIR_DOMAIN_RUNNING][VIR_DOMAIN_RUNNING_UNPAUSED] = + "returned from paused state", + [VIR_DOMAIN_RUNNING][VIR_DOMAIN_RUNNING_MIGRATION_CANCELED] = + "returned from migration", + [VIR_DOMAIN_RUNNING][VIR_DOMAIN_RUNNING_SAVE_CANCELED] = + "returned from failed save process", #ifdef HAVE_DOM_REASON_RUNNING_WAKEUP - [VIR_DOMAIN_RUNNING][VIR_DOMAIN_RUNNING_WAKEUP] = - "returned from pmsuspended due to wakeup event", + [VIR_DOMAIN_RUNNING][VIR_DOMAIN_RUNNING_WAKEUP] = + "returned from pmsuspended due to wakeup event", #endif #ifdef HAVE_DOM_REASON_CRASHED - [VIR_DOMAIN_RUNNING][VIR_DOMAIN_RUNNING_CRASHED] = - "resumed from crashed", + [VIR_DOMAIN_RUNNING][VIR_DOMAIN_RUNNING_CRASHED] = "resumed from crashed", #endif #ifdef HAVE_DOM_REASON_POSTCOPY - [VIR_DOMAIN_RUNNING][VIR_DOMAIN_RUNNING_POSTCOPY] = - "running in post-copy migration mode", -#endif - [VIR_DOMAIN_BLOCKED][VIR_DOMAIN_BLOCKED_UNKNOWN] = - "the reason is unknown", - - [VIR_DOMAIN_PAUSED][VIR_DOMAIN_PAUSED_UNKNOWN] = - "the reason is unknown", - [VIR_DOMAIN_PAUSED][VIR_DOMAIN_PAUSED_USER] = "paused on user request", - [VIR_DOMAIN_PAUSED][VIR_DOMAIN_PAUSED_MIGRATION] = - "paused for offline migration", - [VIR_DOMAIN_PAUSED][VIR_DOMAIN_PAUSED_SAVE] = "paused for save", - [VIR_DOMAIN_PAUSED][VIR_DOMAIN_PAUSED_DUMP] = - "paused for offline core dump", - [VIR_DOMAIN_PAUSED][VIR_DOMAIN_PAUSED_IOERROR] = - "paused due to a disk I/O error", - [VIR_DOMAIN_PAUSED][VIR_DOMAIN_PAUSED_WATCHDOG] = - "paused due to a watchdog event", - [VIR_DOMAIN_PAUSED][VIR_DOMAIN_PAUSED_FROM_SNAPSHOT] = - "paused after restoring from snapshot", + [VIR_DOMAIN_RUNNING][VIR_DOMAIN_RUNNING_POSTCOPY] = + "running in post-copy migration mode", +#endif + [VIR_DOMAIN_BLOCKED][VIR_DOMAIN_BLOCKED_UNKNOWN] = "the reason is unknown", + + [VIR_DOMAIN_PAUSED][VIR_DOMAIN_PAUSED_UNKNOWN] = "the reason is unknown", + [VIR_DOMAIN_PAUSED][VIR_DOMAIN_PAUSED_USER] = "paused on user request", + [VIR_DOMAIN_PAUSED][VIR_DOMAIN_PAUSED_MIGRATION] = + "paused for offline migration", + [VIR_DOMAIN_PAUSED][VIR_DOMAIN_PAUSED_SAVE] = "paused for save", + [VIR_DOMAIN_PAUSED][VIR_DOMAIN_PAUSED_DUMP] = + "paused for offline core dump", + [VIR_DOMAIN_PAUSED][VIR_DOMAIN_PAUSED_IOERROR] = + "paused due to a disk I/O error", + [VIR_DOMAIN_PAUSED][VIR_DOMAIN_PAUSED_WATCHDOG] = + "paused due to a watchdog event", + [VIR_DOMAIN_PAUSED][VIR_DOMAIN_PAUSED_FROM_SNAPSHOT] = + "paused after restoring from snapshot", #ifdef HAVE_DOM_REASON_PAUSED_SHUTTING_DOWN - [VIR_DOMAIN_PAUSED][VIR_DOMAIN_PAUSED_SHUTTING_DOWN] = - "paused during shutdown process", + [VIR_DOMAIN_PAUSED][VIR_DOMAIN_PAUSED_SHUTTING_DOWN] = + "paused during shutdown process", #endif #ifdef HAVE_DOM_REASON_PAUSED_SNAPSHOT - [VIR_DOMAIN_PAUSED][VIR_DOMAIN_PAUSED_SNAPSHOT] = - "paused while creating a snapshot", + [VIR_DOMAIN_PAUSED][VIR_DOMAIN_PAUSED_SNAPSHOT] = + "paused while creating a snapshot", #endif #ifdef HAVE_DOM_REASON_PAUSED_CRASHED - [VIR_DOMAIN_PAUSED][VIR_DOMAIN_PAUSED_CRASHED] = - "paused due to a guest crash", + [VIR_DOMAIN_PAUSED][VIR_DOMAIN_PAUSED_CRASHED] = + "paused due to a guest crash", #endif #ifdef HAVE_DOM_REASON_PAUSED_STARTING_UP - [VIR_DOMAIN_PAUSED][VIR_DOMAIN_PAUSED_STARTING_UP] = - "the domain is being started", + [VIR_DOMAIN_PAUSED][VIR_DOMAIN_PAUSED_STARTING_UP] = + "the domain is being started", #endif #ifdef HAVE_DOM_REASON_POSTCOPY - [VIR_DOMAIN_PAUSED][VIR_DOMAIN_PAUSED_POSTCOPY] = - "paused for post-copy migration", - [VIR_DOMAIN_PAUSED][VIR_DOMAIN_PAUSED_POSTCOPY_FAILED] = - "paused after failed post-copy", -#endif - [VIR_DOMAIN_SHUTDOWN][VIR_DOMAIN_SHUTDOWN_UNKNOWN] = - "the reason is unknown", - [VIR_DOMAIN_SHUTDOWN][VIR_DOMAIN_SHUTDOWN_USER] = - "shutting down on user request", - - [VIR_DOMAIN_SHUTOFF][VIR_DOMAIN_SHUTOFF_UNKNOWN] = - "the reason is unknown", - [VIR_DOMAIN_SHUTOFF][VIR_DOMAIN_SHUTOFF_SHUTDOWN] = "normal shutdown", - [VIR_DOMAIN_SHUTOFF][VIR_DOMAIN_SHUTOFF_DESTROYED] = "forced poweroff", - [VIR_DOMAIN_SHUTOFF][VIR_DOMAIN_SHUTOFF_CRASHED] = "domain crashed", - [VIR_DOMAIN_SHUTOFF][VIR_DOMAIN_SHUTOFF_MIGRATED] = - "migrated to another host", - [VIR_DOMAIN_SHUTOFF][VIR_DOMAIN_SHUTOFF_SAVED] = "saved to a file", - [VIR_DOMAIN_SHUTOFF][VIR_DOMAIN_SHUTOFF_FAILED] = - "domain failed to start", - [VIR_DOMAIN_SHUTOFF][VIR_DOMAIN_SHUTOFF_FROM_SNAPSHOT] = - "restored from a snapshot which was taken while domain was shutoff", + [VIR_DOMAIN_PAUSED][VIR_DOMAIN_PAUSED_POSTCOPY] = + "paused for post-copy migration", + [VIR_DOMAIN_PAUSED][VIR_DOMAIN_PAUSED_POSTCOPY_FAILED] = + "paused after failed post-copy", +#endif + [VIR_DOMAIN_SHUTDOWN][VIR_DOMAIN_SHUTDOWN_UNKNOWN] = + "the reason is unknown", + [VIR_DOMAIN_SHUTDOWN][VIR_DOMAIN_SHUTDOWN_USER] = + "shutting down on user request", + + [VIR_DOMAIN_SHUTOFF][VIR_DOMAIN_SHUTOFF_UNKNOWN] = "the reason is unknown", + [VIR_DOMAIN_SHUTOFF][VIR_DOMAIN_SHUTOFF_SHUTDOWN] = "normal shutdown", + [VIR_DOMAIN_SHUTOFF][VIR_DOMAIN_SHUTOFF_DESTROYED] = "forced poweroff", + [VIR_DOMAIN_SHUTOFF][VIR_DOMAIN_SHUTOFF_CRASHED] = "domain crashed", + [VIR_DOMAIN_SHUTOFF][VIR_DOMAIN_SHUTOFF_MIGRATED] = + "migrated to another host", + [VIR_DOMAIN_SHUTOFF][VIR_DOMAIN_SHUTOFF_SAVED] = "saved to a file", + [VIR_DOMAIN_SHUTOFF][VIR_DOMAIN_SHUTOFF_FAILED] = "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", + [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", + [VIR_DOMAIN_CRASHED][VIR_DOMAIN_CRASHED_UNKNOWN] = "the reason is unknown", #ifdef VIR_DOMAIN_CRASHED_PANICKED - [VIR_DOMAIN_CRASHED][VIR_DOMAIN_CRASHED_PANICKED] = "domain panicked", + [VIR_DOMAIN_CRASHED][VIR_DOMAIN_CRASHED_PANICKED] = "domain panicked", #endif #ifdef HAVE_DOM_STATE_PMSUSPENDED - [VIR_DOMAIN_PMSUSPENDED][VIR_DOMAIN_PMSUSPENDED_UNKNOWN] = - "the reason is unknown", + [VIR_DOMAIN_PMSUSPENDED][VIR_DOMAIN_PMSUSPENDED_UNKNOWN] = + "the reason is unknown", #endif }; #endif /* HAVE_DOM_REASON */ @@ -610,7 +602,9 @@ enum ex_stats { #endif ex_stats_disk_allocation = 1 << 10, ex_stats_disk_capacity = 1 << 11, - ex_stats_disk_physical = 1 << 12 + ex_stats_disk_physical = 1 << 12, + ex_stats_memory = 1 << 13, + ex_stats_vcpu = 1 << 14 }; static unsigned int extra_stats = ex_stats_none; @@ -641,6 +635,8 @@ static const struct ex_stats_item ex_stats_table[] = { {"disk_allocation", ex_stats_disk_allocation}, {"disk_capacity", ex_stats_disk_capacity}, {"disk_physical", ex_stats_disk_physical}, + {"memory", ex_stats_memory}, + {"vcpu", ex_stats_vcpu}, {NULL, ex_stats_none}, }; @@ -728,7 +724,10 @@ static int get_block_stats(struct lv_block_stats *bstats, ERROR(PLUGIN_NAME " plugin: %s failed: %s", (s), err->message); \ } while (0) -static char *metadata_get_hostname(virDomainPtr dom) { +enum metadata_set_type_e { META_APPEND_HOST, META_APPEND_PLUGIN_INSTANCE }; + +static void set_field_from_metadata(value_list_t *vl, virDomainPtr dom, + enum metadata_set_type_e field) { const char *xpath_str = NULL; if (hm_xpath == NULL) xpath_str = "/instance/name/text()"; @@ -738,17 +737,18 @@ static char *metadata_get_hostname(virDomainPtr dom) { const char *namespace = NULL; if (hm_ns == NULL) { namespace = "http://openstack.org/xmlns/libvirt/nova/1.0"; - } else { + } // namespace =hm_ns; + else { namespace = hm_ns; } char *metadata_str = virDomainGetMetadata( dom, VIR_DOMAIN_METADATA_ELEMENT, namespace, VIR_DOMAIN_AFFECT_CURRENT); if (metadata_str == NULL) { - return NULL; + return; } - char *hostname = NULL; + const char *value = NULL; xmlXPathContextPtr xpath_ctx = NULL; xmlXPathObjectPtr xpath_obj = NULL; xmlNodePtr xml_node = NULL; @@ -792,18 +792,25 @@ static char *metadata_get_hostname(virDomainPtr dom) { xml_node = xpath_obj->nodesetval->nodeTab[0]; if (xml_node->type == XML_TEXT_NODE) { - hostname = strdup((const char *)xml_node->content); + value = (const char *)xml_node->content; } else if (xml_node->type == XML_ATTRIBUTE_NODE) { - hostname = strdup((const char *)xml_node->children->content); + value = (const char *)xml_node->children->content; } else { ERROR(PLUGIN_NAME " plugin: xmlXPathEval(%s) unsupported node type %d", xpath_str, xml_node->type); goto metadata_end; } - if (hostname == NULL) { - ERROR(PLUGIN_NAME " plugin: strdup(%s) hostname failed", xpath_str); + if (value == NULL) goto metadata_end; + + switch (field) { + case META_APPEND_HOST: + SSTRNCAT(vl->host, value, sizeof(vl->host)); + break; + case META_APPEND_PLUGIN_INSTANCE: + SSTRNCAT(vl->plugin_instance, value, sizeof(vl->plugin_instance)); + break; } metadata_end: @@ -814,7 +821,6 @@ metadata_end: if (xml_doc) xmlFreeDoc(xml_doc); sfree(metadata_str); - return hostname; } static void init_value_list(value_list_t *vl, virDomainPtr dom) { @@ -849,9 +855,7 @@ static void init_value_list(value_list_t *vl, virDomainPtr dom) { SSTRNCAT(vl->host, uuid, sizeof(vl->host)); break; case hf_metadata: - name = metadata_get_hostname(dom); - if (name) - SSTRNCAT(vl->host, name, sizeof(vl->host)); + set_field_from_metadata(vl, dom, META_APPEND_HOST); break; } } @@ -877,13 +881,10 @@ static void init_value_list(value_list_t *vl, virDomainPtr dom) { SSTRNCAT(vl->plugin_instance, uuid, sizeof(vl->plugin_instance)); break; case plginst_metadata: - name = metadata_get_hostname(dom); - if (name) - SSTRNCAT(vl->plugin_instance, name, sizeof(vl->plugin_instance)); + set_field_from_metadata(vl, dom, META_APPEND_PLUGIN_INSTANCE); break; } } - } /* void init_value_list */ static int init_notif(notification_t *notif, const virDomainPtr domain, @@ -942,7 +943,8 @@ static void memory_stats_submit(gauge_t value, virDomainPtr dom, "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); + ERROR(PLUGIN_NAME " plugin: Array index out of bounds: tag_index = %d", + tag_index); return; } @@ -952,7 +954,8 @@ static void memory_stats_submit(gauge_t value, virDomainPtr dom, static void submit_derive2(const char *type, derive_t v0, derive_t v1, virDomainPtr dom, const char *devname) { value_t values[] = { - {.derive = v0}, {.derive = v1}, + {.derive = v0}, + {.derive = v1}, }; submit(dom, type, devname, values, STATIC_ARRAY_SIZE(values)); @@ -972,7 +975,7 @@ static double cpu_ns_to_percent(unsigned int node_cpus, } DEBUG(PLUGIN_NAME " plugin: node_cpus=%u cpu_time_old=%" PRIu64 - " cpu_time_new=%" PRIu64 "cpu_time_diff=%" PRIu64 + " cpu_time_new=%" PRIu64 " cpu_time_diff=%" PRIu64 " time_diff_sec=%f percent=%f", node_cpus, (uint64_t)cpu_time_old, (uint64_t)cpu_time_new, (uint64_t)cpu_time_diff, time_diff_sec, percent); @@ -1519,8 +1522,8 @@ static int lv_domain_block_stats(virDomainPtr dom, const char *path, virTypedParameterPtr params = calloc(nparams, sizeof(*params)); if (params == NULL) { - ERROR("virt plugin: alloc(%i) for block=%s parameters failed.", nparams, - path); + ERROR(PLUGIN_NAME " plugin: alloc(%i) for block=%s parameters failed.", + nparams, path); return -1; } @@ -1560,8 +1563,17 @@ static int get_perf_events(virDomainPtr domain) { int status = virDomainListGetStats(domain_array, VIR_DOMAIN_STATS_PERF, &stats, 0); if (status == -1) { - ERROR("virt plugin: virDomainListGetStats failed with status %i.", status); - return status; + ERROR(PLUGIN_NAME " plugin: virDomainListGetStats failed with status %i.", + status); + + virErrorPtr err = virGetLastError(); + if (err->code == VIR_ERR_NO_SUPPORT) { + ERROR(PLUGIN_NAME + " plugin: Disabled unsupported ExtraStats selector: perf"); + extra_stats &= ~(ex_stats_perf); + } + + return -1; } for (int i = 0; i < status; ++i) @@ -1586,7 +1598,6 @@ static void vcpu_pin_submit(virDomainPtr dom, int max_cpus, int vcpu, static int get_vcpu_stats(virDomainPtr domain, unsigned short nr_virt_cpu) { int max_cpus = VIR_NODEINFO_MAXCPUS(nodeinfo); - int cpu_map_len = VIR_CPU_MAPLEN(max_cpus); virVcpuInfoPtr vinfo = calloc(nr_virt_cpu, sizeof(*vinfo)); if (vinfo == NULL) { @@ -1594,11 +1605,17 @@ static int get_vcpu_stats(virDomainPtr domain, unsigned short nr_virt_cpu) { return -1; } - unsigned char *cpumaps = calloc(nr_virt_cpu, cpu_map_len); - if (cpumaps == NULL) { - ERROR(PLUGIN_NAME " plugin: calloc failed."); - sfree(vinfo); - return -1; + int cpu_map_len = 0; + unsigned char *cpumaps = NULL; + if (extra_stats & ex_stats_vcpupin) { + cpu_map_len = VIR_CPU_MAPLEN(max_cpus); + cpumaps = calloc(nr_virt_cpu, cpu_map_len); + + if (cpumaps == NULL) { + ERROR(PLUGIN_NAME " plugin: calloc failed."); + sfree(vinfo); + return -1; + } } int status = @@ -1606,13 +1623,26 @@ static int get_vcpu_stats(virDomainPtr domain, unsigned short nr_virt_cpu) { if (status < 0) { ERROR(PLUGIN_NAME " plugin: virDomainGetVcpus failed with status %i.", status); + + virErrorPtr err = virGetLastError(); + if (err->code == VIR_ERR_NO_SUPPORT) { + if (extra_stats & ex_stats_vcpu) + ERROR(PLUGIN_NAME + " plugin: Disabled unsupported ExtraStats selector: vcpu"); + if (extra_stats & ex_stats_vcpupin) + ERROR(PLUGIN_NAME + " plugin: Disabled unsupported ExtraStats selector: vcpupin"); + extra_stats &= ~(ex_stats_vcpu | ex_stats_vcpupin); + } + sfree(cpumaps); sfree(vinfo); - return status; + return -1; } for (int i = 0; i < nr_virt_cpu; ++i) { - vcpu_submit(vinfo[i].cpuTime, domain, vinfo[i].number, "virt_vcpu"); + if (extra_stats & ex_stats_vcpu) + vcpu_submit(vinfo[i].cpuTime, domain, vinfo[i].number, "virt_vcpu"); if (extra_stats & ex_stats_vcpupin) vcpu_pin_submit(domain, max_cpus, i, cpumaps, cpu_map_len); } @@ -1627,6 +1657,14 @@ static int get_pcpu_stats(virDomainPtr dom) { int nparams = virDomainGetCPUStats(dom, NULL, 0, -1, 1, 0); if (nparams < 0) { VIRT_ERROR(conn, "getting the CPU params count"); + + virErrorPtr err = virGetLastError(); + if (err->code == VIR_ERR_NO_SUPPORT) { + ERROR(PLUGIN_NAME + " plugin: Disabled unsupported ExtraStats selector: pcpu"); + extra_stats &= ~(ex_stats_pcpu); + } + return -1; } @@ -1678,7 +1716,8 @@ static int submit_domain_state(virDomainPtr domain) { } value_t values[] = { - {.gauge = (gauge_t)domain_state}, {.gauge = (gauge_t)domain_reason}, + {.gauge = (gauge_t)domain_state}, + {.gauge = (gauge_t)domain_reason}, }; submit(domain, "domain_state", NULL, values, STATIC_ARRAY_SIZE(values)); @@ -1709,17 +1748,25 @@ static int get_memory_stats(virDomainPtr domain) { virDomainMemoryStatPtr minfo = calloc(VIR_DOMAIN_MEMORY_STAT_NR, sizeof(*minfo)); if (minfo == NULL) { - ERROR("virt plugin: calloc failed."); + ERROR(PLUGIN_NAME " plugin: calloc failed."); return -1; } int mem_stats = virDomainMemoryStats(domain, minfo, VIR_DOMAIN_MEMORY_STAT_NR, 0); if (mem_stats < 0) { - ERROR("virt plugin: virDomainMemoryStats failed with mem_stats %i.", + ERROR(PLUGIN_NAME " plugin: virDomainMemoryStats failed with mem_stats %i.", mem_stats); sfree(minfo); - return mem_stats; + + virErrorPtr err = virGetLastError(); + if (err->code == VIR_ERR_NO_SUPPORT) { + ERROR(PLUGIN_NAME + " plugin: Disabled unsupported ExtraStats selector: memory"); + extra_stats &= ~(ex_stats_memory); + } + + return -1; } derive_t swap_in = -1; @@ -1754,7 +1801,8 @@ static int get_memory_stats(virDomainPtr domain) { if (min_flt > 0 || maj_flt > 0) { value_t values[] = { - {.gauge = (gauge_t)min_flt}, {.gauge = (gauge_t)maj_flt}, + {.gauge = (gauge_t)min_flt}, + {.gauge = (gauge_t)maj_flt}, }; submit(domain, "ps_pagefaults", NULL, values, STATIC_ARRAY_SIZE(values)); } @@ -1776,6 +1824,15 @@ static int get_disk_err(virDomainPtr domain) { if (disk_err_count == -1) { ERROR(PLUGIN_NAME " plugin: failed to get preferred size of disk errors array"); + + virErrorPtr err = virGetLastError(); + + if (err->code == VIR_ERR_NO_SUPPORT) { + ERROR(PLUGIN_NAME + " plugin: Disabled unsupported ExtraStats selector: disk_err"); + extra_stats &= ~(ex_stats_disk_err); + } + return -1; } @@ -1822,6 +1879,24 @@ static int get_block_device_stats(struct block_device *block_dev) { 0) { ERROR(PLUGIN_NAME " plugin: virDomainGetBlockInfo failed for path: %s", block_dev->path); + + virErrorPtr err = virGetLastError(); + if (err->code == VIR_ERR_NO_SUPPORT) { + + if (extra_stats & ex_stats_disk_allocation) + ERROR(PLUGIN_NAME " plugin: Disabled unsupported ExtraStats " + "selector: disk_allocation"); + if (extra_stats & ex_stats_disk_capacity) + ERROR(PLUGIN_NAME " plugin: Disabled unsupported ExtraStats " + "selector: disk_capacity"); + if (extra_stats & ex_stats_disk_physical) + ERROR(PLUGIN_NAME " plugin: Disabled unsupported ExtraStats " + "selector: disk_physical"); + + extra_stats &= ~(ex_stats_disk_allocation | ex_stats_disk_capacity | + ex_stats_disk_physical); + } + return -1; } } @@ -1908,7 +1983,15 @@ static int get_fs_info(virDomainPtr domain) { if (mount_points_cnt == -1) { ERROR(PLUGIN_NAME " plugin: virDomainGetFSInfo failed: %d", mount_points_cnt); - return mount_points_cnt; + + virErrorPtr err = virGetLastError(); + if (err->code == VIR_ERR_NO_SUPPORT) { + ERROR(PLUGIN_NAME + " plugin: Disabled unsupported ExtraStats selector: fs_info"); + extra_stats &= ~(ex_stats_fs_info); + } + + return -1; } for (int i = 0; i < mount_points_cnt; ++i) { @@ -1955,7 +2038,6 @@ static void job_stats_submit(virDomainPtr domain, virTypedParameterPtr param) { } static int get_job_stats(virDomainPtr domain) { - int ret = 0; int job_type = 0; int nparams = 0; virTypedParameterPtr params = NULL; @@ -1963,10 +2045,24 @@ static int get_job_stats(virDomainPtr domain) { ? VIR_DOMAIN_JOB_STATS_COMPLETED : 0; - ret = virDomainGetJobStats(domain, &job_type, ¶ms, &nparams, flags); + int ret = virDomainGetJobStats(domain, &job_type, ¶ms, &nparams, flags); if (ret != 0) { ERROR(PLUGIN_NAME " plugin: virDomainGetJobStats failed: %d", ret); - return ret; + + virErrorPtr err = virGetLastError(); + // VIR_ERR_INVALID_ARG returned when VIR_DOMAIN_JOB_STATS_COMPLETED flag is + // not supported by driver + if (err->code == VIR_ERR_NO_SUPPORT || err->code == VIR_ERR_INVALID_ARG) { + if (extra_stats & ex_stats_job_stats_completed) + ERROR(PLUGIN_NAME " plugin: Disabled unsupported ExtraStats selector: " + "job_stats_completed"); + if (extra_stats & ex_stats_job_stats_background) + ERROR(PLUGIN_NAME " plugin: Disabled unsupported ExtraStats selector: " + "job_stats_background"); + extra_stats &= + ~(ex_stats_job_stats_completed | ex_stats_job_stats_background); + } + return -1; } DEBUG(PLUGIN_NAME " plugin: job_type=%d nparams=%d", job_type, nparams); @@ -1978,7 +2074,7 @@ static int get_job_stats(virDomainPtr domain) { } virTypedParamsFree(params, nparams); - return ret; + return 0; } #endif /* HAVE_JOB_STATS */ @@ -2019,8 +2115,10 @@ static int get_domain_metrics(domain_t *domain) { memory_submit(domain->ptr, (gauge_t)info.memory * 1024); - GET_STATS(get_vcpu_stats, "vcpu stats", domain->ptr, info.nrVirtCpu); - GET_STATS(get_memory_stats, "memory stats", domain->ptr); + if (extra_stats & (ex_stats_vcpu | ex_stats_vcpupin)) + GET_STATS(get_vcpu_stats, "vcpu stats", domain->ptr, info.nrVirtCpu); + if (extra_stats & ex_stats_memory) + GET_STATS(get_memory_stats, "memory stats", domain->ptr); #ifdef HAVE_PERF_STATS if (extra_stats & ex_stats_perf) @@ -2107,6 +2205,9 @@ static int domain_lifecycle_event_cb(__attribute__((unused)) virConnectPtr con_, return 0; } +static void virt_eventloop_timeout_cb(int timer ATTRIBUTE_UNUSED, + void *timer_info) {} + static int register_event_impl(void) { if (virEventRegisterDefaultImpl() < 0) { virErrorPtr err = virGetLastError(); @@ -2116,6 +2217,14 @@ static int register_event_impl(void) { return -1; } + if (virEventAddTimeout(CDTIME_T_TO_MS(plugin_get_interval()), + virt_eventloop_timeout_cb, NULL, NULL) < 0) { + virErrorPtr err = virGetLastError(); + ERROR(PLUGIN_NAME " plugin: virEventAddTimeout failed: %s", + err && err->message ? err->message : "Unknown error"); + return -1; + } + return 0; } @@ -2311,6 +2420,21 @@ static int lv_read(user_data_t *ud) { return 0; } + int ret = virConnectIsAlive(conn); + if (ret == 0) { /* Connection lost */ + if (inst->id == 0) { + c_complain(LOG_ERR, &conn_complain, + PLUGIN_NAME " plugin: Lost connection."); + + if (!persistent_notification) + stop_event_loop(¬if_thread); + + lv_disconnect(); + last_refresh = 0; + } + return -1; + } + time_t t; time(&t);