X-Git-Url: https://git.verplant.org/?a=blobdiff_plain;f=src%2Fvirt.c;h=f2acde07348dee0beb15dca40623bdf5fbe94338;hb=0441d713c248a778f090e5f105606c6bfff79ff9;hp=bdb6445caf89b5f52b2c58b7dbd7b70641bd2541;hpb=d0b5df47bb6fc6ae8a5ff9ed5a43349ec84721e2;p=collectd.git diff --git a/src/virt.c b/src/virt.c index bdb6445c..f2acde07 100644 --- a/src/virt.c +++ b/src/virt.c @@ -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; } @@ -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; @@ -2425,10 +2529,8 @@ static int refresh_lists(struct lv_read_instance *inst) { VIR_CONNECT_LIST_DOMAINS_INACTIVE); n = virConnectListAllDomains(conn, &domains, VIR_CONNECT_LIST_DOMAINS_ACTIVE); #else - int *domids; - /* Get list of domains. */ - domids = calloc(n, sizeof(*domids)); + int *domids = calloc(n, sizeof(*domids)); if (domids == NULL) { ERROR(PLUGIN_NAME " plugin: calloc failed."); return -1; @@ -2465,8 +2567,7 @@ static int refresh_lists(struct lv_read_instance *inst) { #ifdef HAVE_LIST_ALL_DOMAINS virDomainPtr dom = domains[i]; #else - virDomainPtr dom = NULL; - dom = virDomainLookupByID(conn, domids[i]); + virDomainPtr dom = virDomainLookupByID(conn, domids[i]); if (dom == NULL) { VIRT_ERROR(conn, "virDomainLookupByID"); /* Could be that the domain went away -- ignore it anyway. */ @@ -2503,7 +2604,7 @@ static int refresh_lists(struct lv_read_instance *inst) { } if (info.state != VIR_DOMAIN_RUNNING) { - DEBUG(PLUGIN_NAME " plugin: skipping inactive domain %s", name); + DEBUG(PLUGIN_NAME " plugin: skipping inactive domain %s", domname); continue; } @@ -2513,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) { @@ -2540,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)