X-Git-Url: https://git.octo.it/?a=blobdiff_plain;f=src%2Fvirt.c;h=01c7c7771d2e1a95384f24ae8c30f6c089cefa38;hb=c4a5c834e35aa00dbb5c2233df875a6bc7baf6d2;hp=d24407abc1061364f4e0be35071ffca7a5c657a7;hpb=eada465ff40eb2ecaef17490e5462dab3b8874fe;p=collectd.git diff --git a/src/virt.c b/src/virt.c index d24407ab..01c7c777 100644 --- a/src/virt.c +++ b/src/virt.c @@ -602,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; @@ -633,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}, }; @@ -720,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()"; @@ -730,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; @@ -784,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: @@ -806,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) { @@ -841,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; } } @@ -869,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, @@ -934,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; } @@ -965,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); @@ -1512,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; } @@ -1553,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) @@ -1579,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) { @@ -1587,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 = @@ -1599,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); } @@ -1620,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; } @@ -1703,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; @@ -1771,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; } @@ -1817,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; } } @@ -1903,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) { @@ -1950,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; @@ -1958,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); @@ -1973,7 +2074,7 @@ static int get_job_stats(virDomainPtr domain) { } virTypedParamsFree(params, nparams); - return ret; + return 0; } #endif /* HAVE_JOB_STATS */ @@ -2014,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) @@ -2102,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(); @@ -2111,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; } @@ -2306,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);