Merge branch 'collectd-5.8'
[collectd.git] / src / virt.c
index 1113113..e97fd84 100644 (file)
@@ -241,8 +241,8 @@ const char *domain_reasons[][DOMAIN_STATE_REASON_MAX_SIZE] = {
   } while (0)
 
 /* Connection. */
-static virConnectPtr conn = 0;
-static char *conn_string = NULL;
+static virConnectPtr conn;
+static char *conn_string;
 static c_complain_t conn_complain = C_COMPLAIN_INIT_STATIC;
 
 /* Node information required for %CPU */
@@ -252,11 +252,11 @@ static virNodeInfo nodeinfo;
 static int interval = 60;
 
 /* List of domains, if specified. */
-static ignorelist_t *il_domains = NULL;
+static ignorelist_t *il_domains;
 /* List of block devices, if specified. */
-static ignorelist_t *il_block_devices = NULL;
+static ignorelist_t *il_block_devices;
 /* List of network interface devices, if specified. */
-static ignorelist_t *il_interface_devices = NULL;
+static ignorelist_t *il_interface_devices;
 
 static int ignore_device_match(ignorelist_t *, const char *domname,
                                const char *devpath);
@@ -401,7 +401,7 @@ static const struct ex_stats_item ex_stats_table[] = {
 };
 
 /* BlockDeviceFormatBasename */
-_Bool blockdevice_format_basename = 0;
+static bool blockdevice_format_basename;
 static enum bd_field blockdevice_format = target;
 static enum if_field interface_format = if_name;
 
@@ -444,12 +444,10 @@ static void init_block_info(struct lv_block_info *binfo) {
 #ifdef HAVE_BLOCK_STATS_FLAGS
 
 #define GET_BLOCK_INFO_VALUE(NAME, FIELD)                                      \
-  do {                                                                         \
-    if (!strcmp(param[i].field, NAME)) {                                       \
-      binfo->FIELD = param[i].value.l;                                         \
-      continue;                                                                \
-    }                                                                          \
-  } while (0)
+  if (!strcmp(param[i].field, NAME)) {                                         \
+    binfo->FIELD = param[i].value.l;                                           \
+    continue;                                                                  \
+  }
 
 static int get_block_info(struct lv_block_info *binfo,
                           virTypedParameterPtr param, int nparams) {
@@ -514,7 +512,8 @@ static int lv_domain_info(virDomainPtr dom, struct lv_info *info) {
 
   ret = virDomainGetCPUStats(dom, param, nparams, -1, 1, 0); // total stats.
   if (ret < 0) {
-    virTypedParamsFree(param, nparams);
+    virTypedParamsClear(param, nparams);
+    sfree(param);
     VIRT_ERROR(conn, "getting the disk params values");
     return -1;
   }
@@ -526,7 +525,8 @@ static int lv_domain_info(virDomainPtr dom, struct lv_info *info) {
       info->total_syst_cpu_time = param[i].value.ul;
   }
 
-  virTypedParamsFree(param, nparams);
+  virTypedParamsClear(param, nparams);
+  sfree(param);
 #endif /* HAVE_CPU_STATS */
 
   return 0;
@@ -697,10 +697,11 @@ static double cpu_ns_to_percent(unsigned int node_cpus,
               (time_diff_sec * node_cpus * NANOSEC_IN_SEC);
   }
 
-  DEBUG(PLUGIN_NAME ": node_cpus=%u cpu_time_old=%llu cpu_time_new=%llu"
-                    "cpu_time_diff=%llu time_diff_sec=%f percent=%f",
-        node_cpus, cpu_time_old, cpu_time_new, cpu_time_diff, time_diff_sec,
-        percent);
+  DEBUG(PLUGIN_NAME ": node_cpus=%u cpu_time_old=%" 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);
 
   return percent;
 }
@@ -729,7 +730,7 @@ static void vcpu_submit(derive_t value, virDomainPtr dom, int vcpu_nr,
                         const char *type) {
   char type_instance[DATA_MAX_NAME_LEN];
 
-  ssnprintf(type_instance, sizeof(type_instance), "%d", vcpu_nr);
+  snprintf(type_instance, sizeof(type_instance), "%d", vcpu_nr);
   submit(dom, type, type_instance, &(value_t){.derive = value}, 1);
 }
 
@@ -750,8 +751,8 @@ static void disk_submit(struct lv_block_info *binfo, virDomainPtr dom,
   }
 
   char flush_type_instance[DATA_MAX_NAME_LEN];
-  ssnprintf(flush_type_instance, sizeof(flush_type_instance), "flush-%s",
-            type_instance);
+  snprintf(flush_type_instance, sizeof(flush_type_instance), "flush-%s",
+           type_instance);
 
   if ((binfo->bi.rd_req != -1) && (binfo->bi.wr_req != -1))
     submit_derive2("disk_ops", (derive_t)binfo->bi.rd_req,
@@ -826,8 +827,8 @@ static void domain_state_submit(virDomainPtr dom, int state, int reason) {
   const char *reason_str = "N/A";
 #endif
 
-  ssnprintf(msg, sizeof(msg), "Domain state: %s. Reason: %s", state_str,
-            reason_str);
+  snprintf(msg, sizeof(msg), "Domain state: %s. Reason: %s", state_str,
+           reason_str);
 
   int severity;
   switch (state) {
@@ -1110,31 +1111,29 @@ static void lv_disconnect(void) {
 static int lv_domain_block_info(virDomainPtr dom, const char *path,
                                 struct lv_block_info *binfo) {
 #ifdef HAVE_BLOCK_STATS_FLAGS
-  virTypedParameterPtr params = NULL;
   int nparams = 0;
-  int rc = -1;
-  int ret = virDomainBlockStatsFlags(dom, path, NULL, &nparams, 0);
-  if (ret < 0 || nparams == 0) {
+  if (virDomainBlockStatsFlags(dom, path, NULL, &nparams, 0) < 0 ||
+      nparams <= 0) {
     VIRT_ERROR(conn, "getting the disk params count");
     return -1;
   }
 
-  params = calloc(nparams, sizeof(virTypedParameter));
+  virTypedParameterPtr params = calloc((size_t)nparams, sizeof(*params));
   if (params == NULL) {
     ERROR("virt plugin: alloc(%i) for block=%s parameters failed.", nparams,
           path);
     return -1;
   }
-  ret = virDomainBlockStatsFlags(dom, path, params, &nparams, 0);
-  if (ret < 0) {
+
+  int rc = -1;
+  if (virDomainBlockStatsFlags(dom, path, params, &nparams, 0) < 0) {
     VIRT_ERROR(conn, "getting the disk params values");
-    goto done;
+  } else {
+    rc = get_block_info(binfo, params, nparams);
   }
 
-  rc = get_block_info(binfo, params, nparams);
-
-done:
-  virTypedParamsFree(params, nparams);
+  virTypedParamsClear(params, nparams);
+  sfree(params);
   return rc;
 #else
   return virDomainBlockStats(dom, path, &(binfo->bi), sizeof(binfo->bi));
@@ -1178,10 +1177,9 @@ static void vcpu_pin_submit(virDomainPtr dom, int max_cpus, int vcpu,
                             unsigned char *cpu_maps, int cpu_map_len) {
   for (int cpu = 0; cpu < max_cpus; ++cpu) {
     char type_instance[DATA_MAX_NAME_LEN];
-    _Bool is_set = VIR_CPU_USABLE(cpu_maps, cpu_map_len, vcpu, cpu) ? 1 : 0;
+    bool is_set = VIR_CPU_USABLE(cpu_maps, cpu_map_len, vcpu, cpu);
 
-    ssnprintf(type_instance, sizeof(type_instance), "vcpu_%d-cpu_%d", vcpu,
-              cpu);
+    snprintf(type_instance, sizeof(type_instance), "vcpu_%d-cpu_%d", vcpu, cpu);
     submit(dom, "cpu_affinity", type_instance, &(value_t){.gauge = is_set}, 1);
   }
 }
@@ -1661,7 +1659,7 @@ static int lv_init_instance(size_t i, plugin_read_cb callback) {
 
   memset(lv_ud, 0, sizeof(*lv_ud));
 
-  ssnprintf(inst->tag, sizeof(inst->tag), "%s-%zu", PLUGIN_NAME, i);
+  snprintf(inst->tag, sizeof(inst->tag), "%s-%" PRIsz, PLUGIN_NAME, i);
   inst->id = i;
 
   user_data_t *ud = &(lv_ud->ud);
@@ -1721,8 +1719,8 @@ static int lv_domain_get_tag(xmlXPathContextPtr xpath_ctx, const char *dom_name,
     goto done;
   }
 
-  ssnprintf(xpath_str, sizeof(xpath_str), "/domain/metadata/%s:%s/text()",
-            METADATA_VM_PARTITION_PREFIX, METADATA_VM_PARTITION_ELEMENT);
+  snprintf(xpath_str, sizeof(xpath_str), "/domain/metadata/%s:%s/text()",
+           METADATA_VM_PARTITION_PREFIX, METADATA_VM_PARTITION_ELEMENT);
   xpath_obj = xmlXPathEvalExpression((xmlChar *)xpath_str, xpath_ctx);
   if (xpath_obj == NULL) {
     ERROR(PLUGIN_NAME " plugin: xmlXPathEval(%s) failed on domain %s",
@@ -1795,6 +1793,18 @@ static int lv_instance_include_domain(struct lv_read_instance *inst,
   return 0;
 }
 
+/*
+  virConnectListAllDomains() appeared in 0.10.2
+  Note that LIBVIR_CHECK_VERSION appeared a year later, so
+  in some systems which actually have virConnectListAllDomains()
+  we can't detect this.
+ */
+#ifdef LIBVIR_CHECK_VERSION
+#if LIBVIR_CHECK_VERSION(0, 10, 2)
+#define HAVE_LIST_ALL_DOMAINS 1
+#endif
+#endif
+
 static int refresh_lists(struct lv_read_instance *inst) {
   struct lv_read_state *state = &inst->read_state;
   int n;
@@ -1808,6 +1818,11 @@ static int refresh_lists(struct lv_read_instance *inst) {
   lv_clean_read_state(state);
 
   if (n > 0) {
+#ifdef HAVE_LIST_ALL_DOMAINS
+    virDomainPtr *domains;
+    n = virConnectListAllDomains(conn, &domains,
+                                 VIR_CONNECT_LIST_DOMAINS_ACTIVE);
+#else
     int *domids;
 
     /* Get list of domains. */
@@ -1818,15 +1833,18 @@ static int refresh_lists(struct lv_read_instance *inst) {
     }
 
     n = virConnectListDomains(conn, domids, n);
+#endif
+
     if (n < 0) {
       VIRT_ERROR(conn, "reading list of domains");
+#ifndef HAVE_LIST_ALL_DOMAINS
       sfree(domids);
+#endif
       return -1;
     }
 
     /* Fetch each domain and add it to the list, unless ignore. */
     for (int i = 0; i < n; ++i) {
-      virDomainPtr dom = NULL;
       const char *name;
       char *xml = NULL;
       xmlDocPtr xml_doc = NULL;
@@ -1836,12 +1854,17 @@ static int refresh_lists(struct lv_read_instance *inst) {
       virDomainInfo info;
       int status;
 
+#ifdef HAVE_LIST_ALL_DOMAINS
+      virDomainPtr dom = domains[i];
+#else
+      virDomainPtr dom = NULL;
       dom = virDomainLookupByID(conn, domids[i]);
       if (dom == NULL) {
         VIRT_ERROR(conn, "virDomainLookupByID");
         /* Could be that the domain went away -- ignore it anyway. */
         continue;
       }
+#endif
 
       name = virDomainGetName(dom);
       if (name == NULL) {
@@ -1982,7 +2005,11 @@ static int refresh_lists(struct lv_read_instance *inst) {
       sfree(xml);
     }
 
+#ifdef HAVE_LIST_ALL_DOMAINS
+    sfree(domains);
+#else
     sfree(domids);
+#endif
   }
 
   DEBUG(PLUGIN_NAME " plugin#%s: refreshing"
@@ -2078,7 +2105,7 @@ static int add_interface_device(struct lv_read_state *state, virDomainPtr dom,
   struct interface_device *new_ptr;
   int new_size =
       sizeof(state->interface_devices[0]) * (state->nr_interface_devices + 1);
-  char *path_copy, *address_copy, number_string[15];
+  char *path_copy, *address_copy, number_string[21];
 
   if ((path == NULL) || (address == NULL))
     return EINVAL;
@@ -2122,13 +2149,13 @@ static int ignore_device_match(ignorelist_t *il, const char *domname,
   if ((domname == NULL) || (devpath == NULL))
     return 0;
 
-  n = sizeof(char) * (strlen(domname) + strlen(devpath) + 2);
+  n = strlen(domname) + strlen(devpath) + 2;
   name = malloc(n);
   if (name == NULL) {
     ERROR(PLUGIN_NAME " plugin: malloc failed.");
     return 0;
   }
-  ssnprintf(name, n, "%s:%s", domname, devpath);
+  snprintf(name, n, "%s:%s", domname, devpath);
   r = ignorelist_match(il, name);
   sfree(name);
   return r;