/* Plugin name */
#define PLUGIN_NAME "virt"
+/* Secure strcat macro assuring null termination. Parameter (n) is the size of
+ buffer (d), allowing this macro to be safe for static and dynamic buffers */
+#define SSTRNCAT(d, s, n) \
+ do { \
+ size_t _l = strlen(d); \
+ sstrncpy((d) + _l, (s), (n)-_l); \
+ } while (0)
+
#ifdef LIBVIR_CHECK_VERSION
#if LIBVIR_CHECK_VERSION(0, 9, 2)
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
#if LIBVIR_CHECK_VERSION(1, 0, 1)
#define HAVE_DOM_REASON_PAUSED_SNAPSHOT 1
case VIR_DOMAIN_EVENT_SHUTDOWN:
ret = VIR_DOMAIN_SHUTDOWN;
break;
+#ifdef HAVE_DOM_STATE_PMSUSPENDED
case VIR_DOMAIN_EVENT_PMSUSPENDED:
ret = VIR_DOMAIN_PMSUSPENDED;
break;
+#endif
+#ifdef HAVE_DOM_REASON_CRASHED
case VIR_DOMAIN_EVENT_CRASHED:
ret = VIR_DOMAIN_CRASHED;
break;
+#endif
default:
ret = VIR_DOMAIN_NOSTATE;
}
return ret;
}
+#ifdef HAVE_DOM_REASON
static int map_domain_event_detail_to_reason(int event, int detail) {
int ret;
switch (event) {
case VIR_DOMAIN_EVENT_STARTED_FROM_SNAPSHOT: /* Restored from snapshot */
ret = VIR_DOMAIN_RUNNING_FROM_SNAPSHOT;
break;
+#ifdef HAVE_DOM_REASON_RUNNING_WAKEUP
case VIR_DOMAIN_EVENT_STARTED_WAKEUP: /* Started due to wakeup event */
ret = VIR_DOMAIN_RUNNING_WAKEUP;
break;
+#endif
default:
ret = VIR_DOMAIN_RUNNING_UNKNOWN;
}
libvirt API call */
ret = VIR_DOMAIN_PAUSED_UNKNOWN;
break;
+#ifdef HAVE_DOM_REASON_POSTCOPY
case VIR_DOMAIN_EVENT_SUSPENDED_POSTCOPY: /* Suspended for post-copy
migration */
ret = VIR_DOMAIN_PAUSED_POSTCOPY;
post-copy */
ret = VIR_DOMAIN_PAUSED_POSTCOPY_FAILED;
break;
+#endif
default:
ret = VIR_DOMAIN_PAUSED_UNKNOWN;
}
case VIR_DOMAIN_EVENT_RESUMED_FROM_SNAPSHOT: /* Resumed from snapshot */
ret = VIR_DOMAIN_RUNNING_FROM_SNAPSHOT;
break;
+#ifdef HAVE_DOM_REASON_POSTCOPY
case VIR_DOMAIN_EVENT_RESUMED_POSTCOPY: /* Resumed, but migration is still
running in post-copy mode */
ret = VIR_DOMAIN_RUNNING_POSTCOPY;
break;
+#endif
default:
ret = VIR_DOMAIN_RUNNING_UNKNOWN;
}
ret = VIR_DOMAIN_SHUTDOWN_UNKNOWN;
}
break;
+#ifdef HAVE_DOM_STATE_PMSUSPENDED
case VIR_DOMAIN_EVENT_PMSUSPENDED:
switch (detail) {
case VIR_DOMAIN_EVENT_PMSUSPENDED_MEMORY: /* Guest was PM suspended to
ret = VIR_DOMAIN_PMSUSPENDED_UNKNOWN;
}
break;
+#endif
case VIR_DOMAIN_EVENT_CRASHED:
switch (detail) {
case VIR_DOMAIN_EVENT_CRASHED_PANICKED: /* Guest was panicked */
return ret;
}
-#ifdef HAVE_DOM_REASON
#define DOMAIN_STATE_REASON_MAX_SIZE 20
const char *domain_reasons[][DOMAIN_STATE_REASON_MAX_SIZE] = {
[VIR_DOMAIN_NOSTATE][VIR_DOMAIN_NOSTATE_UNKNOWN] =
[VIR_DOMAIN_RUNNING][VIR_DOMAIN_RUNNING_POSTCOPY] =
"running in post-copy migration mode",
#endif
-
[VIR_DOMAIN_BLOCKED][VIR_DOMAIN_BLOCKED_UNKNOWN] =
"the reason is unknown",
[VIR_DOMAIN_PAUSED][VIR_DOMAIN_PAUSED_POSTCOPY_FAILED] =
"paused after failed post-copy",
#endif
-
[VIR_DOMAIN_SHUTDOWN][VIR_DOMAIN_SHUTDOWN_UNKNOWN] =
"the reason is unknown",
[VIR_DOMAIN_SHUTDOWN][VIR_DOMAIN_SHUTDOWN_USER] =
}
static void init_value_list(value_list_t *vl, virDomainPtr dom) {
- int n;
const char *name;
char uuid[VIR_UUID_STRING_BUFLEN];
if (hostname_format[i] == hf_none)
continue;
- n = DATA_MAX_NAME_LEN - strlen(vl->host) - 2;
-
- if (i > 0 && n >= 1) {
- strncat(vl->host, ":", 1);
- n--;
- }
+ if (i > 0)
+ SSTRNCAT(vl->host, ":", sizeof(vl->host));
switch (hostname_format[i]) {
case hf_none:
break;
case hf_hostname:
- strncat(vl->host, hostname_g, n);
+ SSTRNCAT(vl->host, hostname_g, sizeof(vl->host));
break;
case hf_name:
name = virDomainGetName(dom);
if (name)
- strncat(vl->host, name, n);
+ SSTRNCAT(vl->host, name, sizeof(vl->host));
break;
case hf_uuid:
if (virDomainGetUUIDString(dom, uuid) == 0)
- strncat(vl->host, uuid, n);
+ SSTRNCAT(vl->host, uuid, sizeof(vl->host));
break;
}
}
- vl->host[sizeof(vl->host) - 1] = '\0';
-
/* Construct the plugin instance field according to PluginInstanceFormat. */
for (int i = 0; i < PLGINST_MAX_FIELDS; ++i) {
if (plugin_instance_format[i] == plginst_none)
continue;
- n = sizeof(vl->plugin_instance) - strlen(vl->plugin_instance) - 2;
-
- if (i > 0 && n >= 1) {
- strncat(vl->plugin_instance, ":", 1);
- n--;
- }
+ if (i > 0)
+ SSTRNCAT(vl->plugin_instance, ":", sizeof(vl->plugin_instance));
switch (plugin_instance_format[i]) {
case plginst_none:
case plginst_name:
name = virDomainGetName(dom);
if (name)
- strncat(vl->plugin_instance, name, n);
+ SSTRNCAT(vl->plugin_instance, name, sizeof(vl->plugin_instance));
break;
case plginst_uuid:
if (virDomainGetUUIDString(dom, uuid) == 0)
- strncat(vl->plugin_instance, uuid, n);
+ SSTRNCAT(vl->plugin_instance, uuid, sizeof(vl->plugin_instance));
break;
}
}
- vl->plugin_instance[sizeof(vl->plugin_instance) - 1] = '\0';
-
} /* void init_value_list */
static int init_notif(notification_t *notif, const virDomainPtr domain,
virDomainPtr dom, int event, int detail,
__attribute__((unused)) void *opaque) {
int domain_state = map_domain_event_to_state(event);
- int domain_reason = map_domain_event_detail_to_reason(event, detail);
+ int domain_reason = 0; /* 0 means UNKNOWN reason for any state */
+#ifdef HAVE_DOM_REASON
+ domain_reason = map_domain_event_detail_to_reason(event, detail);
+#endif
domain_state_submit_notif(dom, domain_state, domain_reason);
return 0;
int status = 0;
int n;
#ifdef HAVE_LIST_ALL_DOMAINS
- virDomainPtr *domains;
+ virDomainPtr *domains = NULL;
n = virConnectListAllDomains(conn, &domains,
- VIR_CONNECT_GET_ALL_DOMAINS_STATS_PERSISTENT);
+ VIR_CONNECT_LIST_DOMAINS_PERSISTENT);
if (n < 0) {
VIRT_ERROR(conn, "reading list of persistent domains");
status = -1;
ERROR(PLUGIN_NAME " plugin: could not notify state of domain %s",
virDomainGetName(domains[i]));
}
+ virDomainFree(domains[i]);
}
sfree(domains);
/* Get domains' metrics */
for (int i = 0; i < state->nr_domains; ++i) {
domain_t *dom = &state->domains[i];
- int status;
+ int status = 0;
if (dom->active)
status = get_domain_metrics(dom);
+#ifdef HAVE_DOM_REASON
else
status = get_domain_state(dom->ptr);
+#endif
if (status != 0)
ERROR(PLUGIN_NAME " failed to get metrics for domain=%s",
#ifndef HAVE_LIST_ALL_DOMAINS
sfree(domids);
#else
+ for (int i = 0; i < m; ++i)
+ virDomainFree(domains_inactive[i]);
sfree(domains_inactive);
#endif
return -1;
}
#ifdef HAVE_LIST_ALL_DOMAINS
+ for (int i = 0; i < n; ++i)
+ virDomainFree(domains[i]);
sfree(domains);
+ for (int i = 0; i < m; ++i)
+ virDomainFree(domains_inactive[i]);
sfree(domains_inactive);
#else
sfree(domids);