X-Git-Url: https://git.octo.it/?a=blobdiff_plain;f=src%2Fvirt.c;h=fd20c77ebd0a4b4e1ca02183c28e6f855adc32e5;hb=6378ec288f34ff250b2971a1452338a2b34c240a;hp=020cfd7b04b381170be8fe03f62404d4e3c3074e;hpb=f76b809d08ef4081aec7a319c1f94cbd0426e4f5;p=collectd.git diff --git a/src/virt.c b/src/virt.c index 020cfd7b..fd20c77e 100644 --- a/src/virt.c +++ b/src/virt.c @@ -22,10 +22,10 @@ #include "collectd.h" -#include "common.h" #include "plugin.h" +#include "utils/common/common.h" +#include "utils/ignorelist/ignorelist.h" #include "utils_complain.h" -#include "utils_ignorelist.h" #include /* for basename(3) */ #include @@ -138,11 +138,17 @@ static const char *config_keys[] = {"Connection", "Instances", "ExtraStats", "PersistentNotification", + + "ReportBlockDevices", + "ReportNetworkInterfaces", NULL}; /* PersistentNotification is false by default */ static bool persistent_notification = false; +static bool report_block_devices = true; +static bool report_network_interfaces = true; + /* Thread used for handling libvirt notifications events */ static virt_notif_thread_t notif_thread; @@ -1368,6 +1374,16 @@ static int lv_config(const char *key, const char *value) { return 0; } + if (strcasecmp(key, "ReportBlockDevices") == 0) { + report_block_devices = IS_TRUE(value); + return 0; + } + + if (strcasecmp(key, "ReportNetworkInterfaces") == 0) { + report_network_interfaces = IS_TRUE(value); + return 0; + } + /* Unrecognised option. */ return -1; } @@ -1416,7 +1432,7 @@ static int lv_domain_block_info(virDomainPtr dom, const char *path, return -1; } - virTypedParameterPtr params = calloc((size_t)nparams, sizeof(*params)); + virTypedParameterPtr params = calloc(nparams, sizeof(*params)); if (params == NULL) { ERROR("virt plugin: alloc(%i) for block=%s parameters failed.", nparams, path); @@ -1486,7 +1502,7 @@ 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[0])); + virVcpuInfoPtr vinfo = calloc(nr_virt_cpu, sizeof(*vinfo)); if (vinfo == NULL) { ERROR(PLUGIN_NAME " plugin: calloc failed."); return -1; @@ -1528,7 +1544,7 @@ static int get_pcpu_stats(virDomainPtr dom) { return -1; } - virTypedParameterPtr param = calloc(nparams, sizeof(virTypedParameter)); + virTypedParameterPtr param = calloc(nparams, sizeof(*param)); if (param == NULL) { ERROR(PLUGIN_NAME " plugin: alloc(%i) for cpu parameters failed.", nparams); return -1; @@ -1611,9 +1627,9 @@ static int get_domain_state_notify(virDomainPtr domain) { static int get_memory_stats(virDomainPtr domain) { virDomainMemoryStatPtr minfo = - calloc(VIR_DOMAIN_MEMORY_STAT_NR, sizeof(virDomainMemoryStatStruct)); + calloc(VIR_DOMAIN_MEMORY_STAT_NR, sizeof(*minfo)); if (minfo == NULL) { - ERROR("virt plugin: malloc failed."); + ERROR("virt plugin: calloc failed."); return -1; } @@ -2400,6 +2416,94 @@ static int lv_instance_include_domain(struct lv_read_instance *inst, return 0; } +static void lv_add_block_devices(struct lv_read_state *state, virDomainPtr dom, + const char *domname, + xmlXPathContextPtr xpath_ctx) { + const char *bd_xmlpath = "/domain/devices/disk/target[@dev]"; + if (blockdevice_format == source) + bd_xmlpath = "/domain/devices/disk/source[@dev]"; + + xmlXPathObjectPtr xpath_obj = + xmlXPathEval((const xmlChar *)bd_xmlpath, xpath_ctx); + + if (xpath_obj == NULL) + return; + + if (xpath_obj->type != XPATH_NODESET || xpath_obj->nodesetval == NULL) { + xmlXPathFreeObject(xpath_obj); + return; + } + + for (int j = 0; j < xpath_obj->nodesetval->nodeNr; ++j) { + xmlNodePtr node = xpath_obj->nodesetval->nodeTab[j]; + if (!node) + continue; + + char *path = (char *)xmlGetProp(node, (xmlChar *)"dev"); + if (!path) + continue; + + if (ignore_device_match(il_block_devices, domname, path) == 0) + add_block_device(state, dom, path); + + xmlFree(path); + } + xmlXPathFreeObject(xpath_obj); +} + +static void lv_add_network_interfaces(struct lv_read_state *state, + virDomainPtr dom, const char *domname, + xmlXPathContextPtr xpath_ctx) { + xmlXPathObjectPtr xpath_obj = xmlXPathEval( + (xmlChar *)"/domain/devices/interface[target[@dev]]", xpath_ctx); + + if (xpath_obj == NULL) + return; + + if (xpath_obj->type != XPATH_NODESET || xpath_obj->nodesetval == NULL) { + xmlXPathFreeObject(xpath_obj); + return; + } + + xmlNodeSetPtr xml_interfaces = xpath_obj->nodesetval; + + for (int j = 0; j < xml_interfaces->nodeNr; ++j) { + char *path = NULL; + char *address = NULL; + + xmlNodePtr xml_interface = xml_interfaces->nodeTab[j]; + if (!xml_interface) + continue; + + for (xmlNodePtr child = xml_interface->children; child; + child = child->next) { + if (child->type != XML_ELEMENT_NODE) + continue; + + if (xmlStrEqual(child->name, (const xmlChar *)"target")) { + path = (char *)xmlGetProp(child, (const xmlChar *)"dev"); + if (!path) + continue; + } else if (xmlStrEqual(child->name, (const xmlChar *)"mac")) { + address = (char *)xmlGetProp(child, (const xmlChar *)"address"); + if (!address) + continue; + } + } + + if ((ignore_device_match(il_interface_devices, domname, path) == 0 && + ignore_device_match(il_interface_devices, domname, address) == 0)) { + add_interface_device(state, dom, path, address, j + 1); + } + + if (path) + xmlFree(path); + if (address) + xmlFree(address); + } + xmlXPathFreeObject(xpath_obj); +} + static int refresh_lists(struct lv_read_instance *inst) { struct lv_read_state *state = &inst->read_state; int n; @@ -2510,7 +2614,6 @@ static int refresh_lists(struct lv_read_instance *inst) { /* Get a list of devices for this domain. */ xmlDocPtr xml_doc = NULL; xmlXPathContextPtr xpath_ctx = NULL; - xmlXPathObjectPtr xpath_obj = NULL; char *xml = virDomainGetXMLDesc(dom, 0); if (!xml) { @@ -2537,78 +2640,14 @@ static int refresh_lists(struct lv_read_instance *inst) { goto cont; /* Block devices. */ - const char *bd_xmlpath = "/domain/devices/disk/target[@dev]"; - if (blockdevice_format == source) - bd_xmlpath = "/domain/devices/disk/source[@dev]"; - xpath_obj = xmlXPathEval((const xmlChar *)bd_xmlpath, xpath_ctx); - - if (xpath_obj == NULL || xpath_obj->type != XPATH_NODESET || - xpath_obj->nodesetval == NULL) - goto cont; - - for (int j = 0; j < xpath_obj->nodesetval->nodeNr; ++j) { - xmlNodePtr node = xpath_obj->nodesetval->nodeTab[j]; - if (!node) - continue; - - char *path = (char *)xmlGetProp(node, (xmlChar *)"dev"); - if (!path) - continue; - - if (ignore_device_match(il_block_devices, domname, path) == 0) - add_block_device(state, dom, path); - - xmlFree(path); - } - xmlXPathFreeObject(xpath_obj); + if (report_block_devices) + lv_add_block_devices(state, dom, domname, xpath_ctx); /* Network interfaces. */ - xpath_obj = xmlXPathEval( - (xmlChar *)"/domain/devices/interface[target[@dev]]", xpath_ctx); - if (xpath_obj == NULL || xpath_obj->type != XPATH_NODESET || - xpath_obj->nodesetval == NULL) - goto cont; - - xmlNodeSetPtr xml_interfaces = xpath_obj->nodesetval; - - for (int j = 0; j < xml_interfaces->nodeNr; ++j) { - char *path = NULL; - char *address = NULL; - - xmlNodePtr xml_interface = xml_interfaces->nodeTab[j]; - if (!xml_interface) - continue; - - for (xmlNodePtr child = xml_interface->children; child; - child = child->next) { - if (child->type != XML_ELEMENT_NODE) - continue; - - if (xmlStrEqual(child->name, (const xmlChar *)"target")) { - path = (char *)xmlGetProp(child, (const xmlChar *)"dev"); - if (!path) - continue; - } else if (xmlStrEqual(child->name, (const xmlChar *)"mac")) { - address = (char *)xmlGetProp(child, (const xmlChar *)"address"); - if (!address) - continue; - } - } - - if ((ignore_device_match(il_interface_devices, domname, path) == 0 && - ignore_device_match(il_interface_devices, domname, address) == 0)) { - add_interface_device(state, dom, path, address, j + 1); - } - - if (path) - xmlFree(path); - if (address) - xmlFree(address); - } + if (report_network_interfaces) + lv_add_network_interfaces(state, dom, domname, xpath_ctx); cont: - if (xpath_obj) - xmlXPathFreeObject(xpath_obj); if (xpath_ctx) xmlXPathFreeContext(xpath_ctx); if (xml_doc)