From 3e3fab69033c4259ddd1846c0bf450609b4ca6f3 Mon Sep 17 00:00:00 2001 From: Deyan Chepishev Date: Wed, 26 Oct 2016 18:10:47 +0300 Subject: [PATCH] Modified plugin virt.c Added options: BlockDeviceFormat BlockDeviceFormatBasename --- src/collectd.conf.in | 2 ++ src/collectd.conf.pod | 51 +++++++++++++++++++++++++++++++++++++++++++ src/virt.c | 60 +++++++++++++++++++++++++++++++++++++++++++++++---- 3 files changed, 109 insertions(+), 4 deletions(-) diff --git a/src/collectd.conf.in b/src/collectd.conf.in index ae299511..821d0fff 100644 --- a/src/collectd.conf.in +++ b/src/collectd.conf.in @@ -1412,6 +1412,8 @@ # RefreshInterval 60 # Domain "name" # BlockDevice "name:device" +# BlockDeviceFormat dev +# BlockDeviceFormatBasename false # InterfaceDevice "name:device" # IgnoreSelected false # HostnameFormat name diff --git a/src/collectd.conf.pod b/src/collectd.conf.pod index 1310c50d..90881638 100644 --- a/src/collectd.conf.pod +++ b/src/collectd.conf.pod @@ -7773,6 +7773,10 @@ option is set to 0, refreshing is disabled completely. =item B I +=item B B|B + +=item B B|B + =item B I =item B B|B @@ -7798,6 +7802,53 @@ Example: Ignore all I devices on any domain, but other block devices (eg. I) will be collected. +If I is set to B, then the device names will be the ones +in the I node for the device in the XML definition of the domain. The +default is B. This is the behavior before adding the option. + +If I is set to B, then the device names will be the ones +in the I node for the device in the XML definition of the domain. + +Example: + +If the domain XML have the following device defined: + + + + + + +
+ + +setting + + BlockDeviceFormat dev + +will name the device in the graph as sda + +setting + + BlockDeviceFormat source + +will name the device in the graph as var_lib_libvirt_images_image1.qcow2 + +These names will also be part of the RRD filename. + +I - this option is honored if and only if +option I is set to B. If set to B then +only the last part of the path will be used for device name and naming the +RRD file. + +Example: + +if the device path (source tag) is: /var/lib/libvirt/images/image1.qcow2 + +setting: + BlockDeviceFormatBasename true + +will set the device name to: image1.qcow2 + =item B B When the virt plugin logs data, it sets the hostname of the collected data diff --git a/src/virt.c b/src/virt.c index 99fe42db..e32150af 100644 --- a/src/virt.c +++ b/src/virt.c @@ -31,6 +31,7 @@ #include #include #include +#include /* Plugin name */ #define PLUGIN_NAME "virt" @@ -42,6 +43,8 @@ static const char *config_keys[] = { "Domain", "BlockDevice", + "BlockDeviceFormat", + "BlockDeviceFormatBasename", "InterfaceDevice", "IgnoreSelected", @@ -130,6 +133,12 @@ enum plginst_field { static enum plginst_field plugin_instance_format[PLGINST_MAX_FIELDS] = { plginst_none }; +/* BlockDeviceFormat */ +enum bd_field { + dev, + source +}; + /* InterfaceFormat. */ enum if_field { if_address, @@ -137,6 +146,9 @@ enum if_field { if_number }; +/* BlockDeviceFormatBasename */ +char *blockdevice_format_basename="false"; +static enum bd_field blockdevice_format = dev; static enum if_field interface_format = if_name; /* Time that we last refreshed. */ @@ -338,6 +350,29 @@ lv_config (const char *key, const char *value) if (ignorelist_add (il_block_devices, value)) return 1; return 0; } + + if (strcasecmp (key, "BlockDeviceFormat") == 0) { + if (strcasecmp (value, "dev") == 0) + blockdevice_format = dev; + else if (strcasecmp (value, "source") == 0) + blockdevice_format = source; + else { + ERROR (PLUGIN_NAME " plugin: unknown BlockDeviceFormat: %s", value); + return -1; + } + return 0; + } + if (strcasecmp (key, "BlockDeviceFormatBasename") == 0) { + if (strcasecmp (value, "true") == 0) + blockdevice_format_basename = "true"; + else if (strcasecmp (value, "false") == 0) + blockdevice_format_basename = "false"; + else { + ERROR (PLUGIN_NAME " plugin: unknown BlockDeviceFormatBasename: %s", value); + return -1; + } + return 0; + } if (strcasecmp (key, "InterfaceDevice") == 0) { if (ignorelist_add (il_interface_devices, value)) return 1; return 0; @@ -578,15 +613,23 @@ lv_read (void) &stats, sizeof stats) != 0) continue; + char *new_path=NULL; + if( 0==strcasecmp("true", blockdevice_format_basename) && source==blockdevice_format){ //valid only if we use source (full path to the device) + new_path=strdup(basename(block_devices[i].path)); + }else{ + new_path=strdup(block_devices[i].path); + } if ((stats.rd_req != -1) && (stats.wr_req != -1)) submit_derive2 ("disk_ops", (derive_t) stats.rd_req, (derive_t) stats.wr_req, - block_devices[i].dom, block_devices[i].path); + block_devices[i].dom, new_path); if ((stats.rd_bytes != -1) && (stats.wr_bytes != -1)) submit_derive2 ("disk_octets", (derive_t) stats.rd_bytes, (derive_t) stats.wr_bytes, - block_devices[i].dom, block_devices[i].path); + block_devices[i].dom, new_path); + + free(new_path); } /* for (nr_block_devices) */ /* Get interface stats for each domain. */ @@ -715,9 +758,18 @@ refresh_lists (void) xpath_ctx = xmlXPathNewContext (xml_doc); /* Block devices. */ + char * bd_xmlpath=NULL; + if( source == blockdevice_format ){ + bd_xmlpath="/domain/devices/disk/source[@dev]"; + }else{ + if( dev == blockdevice_format ){ + bd_xmlpath="/domain/devices/disk/target[@dev]"; + } + } xpath_obj = xmlXPathEval - ((xmlChar *) "/domain/devices/disk/target[@dev]", - xpath_ctx); + ((xmlChar *) bd_xmlpath, + xpath_ctx); + if (xpath_obj == NULL || xpath_obj->type != XPATH_NODESET || xpath_obj->nodesetval == NULL) goto cont; -- 2.11.0