/*
* Types
*/
+#define SHORT_ASC_LEN 5 /* length of 65535 */
+#define VERSION_SIZE (2 * SHORT_ASC_LEN + 1 + sizeof(xen_extraversion_t) + 1)
+
struct xenstat_handle {
xi_handle *xihandle;
int page_size;
FILE *procnetdev;
+ char xen_version[VERSION_SIZE]; /* xen version running on this node */
};
-#define SHORT_ASC_LEN 5 /* length of 65535 */
-#define VERSION_SIZE (2 * SHORT_ASC_LEN + 1 + sizeof(xen_extraversion_t) + 1)
-
struct xenstat_node {
+ xenstat_handle *handle;
unsigned int flags;
unsigned long long cpu_hz;
unsigned int num_cpus;
unsigned long long tot_mem;
unsigned long long free_mem;
unsigned int num_domains;
- char xen_version[VERSION_SIZE]; /* xen version running on this node */
xenstat_domain *domains; /* Array of length num_domains */
};
*/
/* Called to collect the information for the node and all the domains on
* it. When called, the domain information has already been collected. */
-typedef int (*xenstat_collect_func)(xenstat_handle * handle,
- xenstat_node * node);
+typedef int (*xenstat_collect_func)(xenstat_node * node);
/* Called to free the information collected by the collect function. The free
* function will only be called on a xenstat_node if that node includes
* information collected by the corresponding collector. */
xenstat_uninit_func uninit;
} xenstat_collector;
-static int xenstat_collect_vcpus(xenstat_handle * handle,
- xenstat_node * node);
-static int xenstat_collect_networks(xenstat_handle * handle,
- xenstat_node * node);
+static int xenstat_collect_vcpus(xenstat_node * node);
+static int xenstat_collect_networks(xenstat_node * node);
+static int xenstat_collect_xen_version(xenstat_node * node);
static void xenstat_free_vcpus(xenstat_node * node);
static void xenstat_free_networks(xenstat_node * node);
+static void xenstat_free_xen_version(xenstat_node * node);
static void xenstat_uninit_vcpus(xenstat_handle * handle);
static void xenstat_uninit_networks(xenstat_handle * handle);
+static void xenstat_uninit_xen_version(xenstat_handle * handle);
static xenstat_collector collectors[] = {
{ XENSTAT_VCPU, xenstat_collect_vcpus,
xenstat_free_vcpus, xenstat_uninit_vcpus },
{ XENSTAT_NETWORK, xenstat_collect_networks,
- xenstat_free_networks, xenstat_uninit_networks }
+ xenstat_free_networks, xenstat_uninit_networks },
+ { XENSTAT_XEN_VERSION, xenstat_collect_xen_version,
+ xenstat_free_xen_version, xenstat_uninit_xen_version }
};
#define NUM_COLLECTORS (sizeof(collectors)/sizeof(xenstat_collector))
#define DOMAIN_CHUNK_SIZE 256
xenstat_node *node;
dom0_physinfo_t physinfo;
- xen_extraversion_t version;
- long vnum = 0;
dom0_getdomaininfo_t domaininfo[DOMAIN_CHUNK_SIZE];
unsigned int num_domains, new_domains;
unsigned int i;
if (node == NULL)
return NULL;
+ /* Store the handle in the node for later access */
+ node->handle = handle;
+
/* Get information about the physical system */
if (xi_get_physinfo(handle->xihandle, &physinfo) < 0) {
free(node);
return NULL;
}
- /* Get the xen version number and xen version tag */
- if (xi_get_xen_version(handle->xihandle, &vnum, &version) < 0) {
- free(node);
- return NULL;
- }
- snprintf(node->xen_version, VERSION_SIZE, "%ld.%ld%s\n",
- ((vnum >> 16) & 0xFFFF), vnum & 0xFFFF, version);
-
node->cpu_hz = ((unsigned long long)physinfo.cpu_khz) * 1000ULL;
node->num_cpus =
(physinfo.threads_per_core * physinfo.cores_per_socket *
for (i = 0; i < NUM_COLLECTORS; i++) {
if ((flags & collectors[i].flag) == collectors[i].flag) {
node->flags |= collectors[i].flag;
- if(collectors[i].collect(handle, node) == 0) {
+ if(collectors[i].collect(node) == 0) {
xenstat_free_node(node);
return NULL;
}
return NULL;
}
-const char *xenstat_node_xen_ver(xenstat_node * node)
+const char *xenstat_node_xen_version(xenstat_node * node)
{
- return node->xen_version;
+ return node->handle->xen_version;
}
unsigned long long xenstat_node_tot_mem(xenstat_node * node)
* VCPU functions
*/
/* Collect information about VCPUs */
-static int xenstat_collect_vcpus(xenstat_handle * handle, xenstat_node * node)
+static int xenstat_collect_vcpus(xenstat_node * node)
{
unsigned int i, vcpu;
/* Fill in VCPU information */
for (vcpu = 0; vcpu < node->domains[i].num_vcpus; vcpu++) {
/* FIXME: need to be using a more efficient mechanism*/
long long vcpu_time;
- vcpu_time =
- xi_get_vcpu_usage(handle->xihandle,
- node->domains[i].id,
- vcpu);
+ vcpu_time = xi_get_vcpu_usage(node->handle->xihandle,
+ node->domains[i].id,
+ vcpu);
if (vcpu_time < 0)
return 0;
node->domains[i].vcpus[vcpu].ns = vcpu_time;
"bytes packets errs drop fifo colls carrier compressed\n";
/* Collect information about networks */
-static int xenstat_collect_networks(xenstat_handle * handle,
- xenstat_node * node)
+static int xenstat_collect_networks(xenstat_node * node)
{
/* Open and validate /proc/net/dev if we haven't already */
- if (handle->procnetdev == NULL) {
+ if (node->handle->procnetdev == NULL) {
char header[sizeof(PROCNETDEV_HEADER)];
- handle->procnetdev = fopen("/proc/net/dev", "r");
- if (handle->procnetdev == NULL) {
+ node->handle->procnetdev = fopen("/proc/net/dev", "r");
+ if (node->handle->procnetdev == NULL) {
perror("Error opening /proc/net/dev");
return 1;
}
/* Validate the format of /proc/net/dev */
if (fread(header, sizeof(PROCNETDEV_HEADER) - 1, 1,
- handle->procnetdev) != 1) {
+ node->handle->procnetdev) != 1) {
perror("Error reading /proc/net/dev header");
return 1;
}
/* Fill in networks */
/* FIXME: optimize this */
- fseek(handle->procnetdev, sizeof(PROCNETDEV_HEADER) - 1, SEEK_SET);
+ fseek(node->handle->procnetdev, sizeof(PROCNETDEV_HEADER) - 1,
+ SEEK_SET);
while (1) {
xenstat_domain *domain;
xenstat_network net;
unsigned int domid;
- int ret = fscanf(handle->procnetdev,
+ int ret = fscanf(node->handle->procnetdev,
"vif%u.%u:%llu%llu%llu%llu%*u%*u%*u%*u"
"%llu%llu%llu%llu%*u%*u%*u%*u\n",
&domid, &net.id,
if (ret != 10) {
unsigned int c;
do {
- c = fgetc(handle->procnetdev);
+ c = fgetc(node->handle->procnetdev);
} while (c != '\n' && c != EOF);
if (c == EOF)
break;
{
return network->tdrop;
}
+
+/*
+ * Xen version functions
+ */
+
+/* Collect Xen version information */
+static int xenstat_collect_xen_version(xenstat_node * node)
+{
+ long vnum = 0;
+ xen_extraversion_t version;
+
+ /* Collect Xen version information if not already collected */
+ if (node->handle->xen_version[0] == '\0') {
+ /* Get the Xen version number and extraversion string */
+ if (xi_get_xen_version(node->handle->xihandle,
+ &vnum, &version) < 0)
+ return 0;
+ /* Format the version information as a string and store it */
+ snprintf(node->handle->xen_version, VERSION_SIZE, "%ld.%ld%s",
+ ((vnum >> 16) & 0xFFFF), vnum & 0xFFFF, version);
+ }
+
+ return 1;
+}
+
+/* Free Xen version information in node - nothing to do */
+static void xenstat_free_xen_version(xenstat_node * node)
+{
+}
+
+/* Free Xen version information in handle - nothing to do */
+static void xenstat_uninit_xen_version(xenstat_handle * handle)
+{
+}