?? xenstat.c
字號:
/* libxenstat: statistics-collection library for Xen * Copyright (C) International Business Machines Corp., 2005 * Authors: Josh Triplett <josh@kernel.org> * Judy Fischbach <jfisch@cs.pdx.edu> * David Hendricks <cro_marmot@comcast.net> * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. *//* * Copyright 2007 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. */#include <stdlib.h>#include <string.h>#include <stdio.h>#include <unistd.h>#include "xenstat_priv.h"/* * Data-collection types *//* Called to collect the information for the node and all the domains on * it. When called, the domain information has already been collected. * Return status is 0 if fatal error occurs, 1 for success. Collectors * may prune a domain from the list if it has been deleted between the * time the list was setup and the time the colector is called */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. */typedef void (*xenstat_free_func)(xenstat_node * node);/* Called to free any information stored in the handle. Note the lack of a * matching init function; the collect functions should initialize on first * use. Also, the uninit function must handle the case that the collector has * never been initialized. */typedef void (*xenstat_uninit_func)(xenstat_handle * handle);typedef struct xenstat_collector { unsigned int flag; xenstat_collect_func collect; xenstat_free_func free; xenstat_uninit_func uninit;} xenstat_collector;static int xenstat_collect_vcpus(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_free_vbds(xenstat_node * node);static void xenstat_uninit_vcpus(xenstat_handle * handle);static void xenstat_uninit_xen_version(xenstat_handle * handle);static char *xenstat_get_domain_name(xenstat_handle * handle, unsigned int domain_id);static void xenstat_prune_domain(xenstat_node *node, unsigned int entry);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_XEN_VERSION, xenstat_collect_xen_version, xenstat_free_xen_version, xenstat_uninit_xen_version }, { XENSTAT_VBD, xenstat_collect_vbds, xenstat_free_vbds, xenstat_uninit_vbds }};#define NUM_COLLECTORS (sizeof(collectors)/sizeof(xenstat_collector))/* * libxenstat API */xenstat_handle *xenstat_init(void){ xenstat_handle *handle; handle = (xenstat_handle *) calloc(1, sizeof(xenstat_handle)); if (handle == NULL) return NULL;#if defined(PAGESIZE) handle->page_size = PAGESIZE;#elif defined(PAGE_SIZE) handle->page_size = PAGE_SIZE;#else handle->page_size = sysconf(_SC_PAGE_SIZE); if (handle->page_size < 0) { perror("Failed to retrieve page size."); free(handle); return NULL; }#endif handle->xc_handle = xc_interface_open(); if (handle->xc_handle == -1) { perror("xc_interface_open"); free(handle); return NULL; } handle->xshandle = xs_daemon_open_readonly(); /* open handle to xenstore*/ if (handle->xshandle == NULL) { perror("unable to open xenstore\n"); xc_interface_close(handle->xc_handle); free(handle); return NULL; } return handle;}void xenstat_uninit(xenstat_handle * handle){ unsigned int i; if (handle) { for (i = 0; i < NUM_COLLECTORS; i++) collectors[i].uninit(handle); xc_interface_close(handle->xc_handle); xs_daemon_close(handle->xshandle); free(handle->priv); free(handle); }}xenstat_node *xenstat_get_node(xenstat_handle * handle, unsigned int flags){#define DOMAIN_CHUNK_SIZE 256 xenstat_node *node; xc_physinfo_t physinfo = { 0 }; xc_domaininfo_t domaininfo[DOMAIN_CHUNK_SIZE]; unsigned int new_domains; unsigned int i; /* Create the node */ node = (xenstat_node *) calloc(1, sizeof(xenstat_node)); if (node == NULL) return NULL; /* Store the handle in the node for later access */ node->handle = handle; /* Get information about the physical system */ if (xc_physinfo(handle->xc_handle, &physinfo) < 0) { free(node); return NULL; } node->cpu_hz = ((unsigned long long)physinfo.cpu_khz) * 1000ULL; node->num_cpus = physinfo.nr_cpus; node->tot_mem = ((unsigned long long)physinfo.total_pages) * handle->page_size; node->free_mem = ((unsigned long long)physinfo.free_pages) * handle->page_size; /* malloc(0) is not portable, so allocate a single domain. This will * be resized below. */ node->domains = malloc(sizeof(xenstat_domain)); if (node->domains == NULL) { free(node); return NULL; } node->num_domains = 0; do { xenstat_domain *domain, *tmp; new_domains = xc_domain_getinfolist(handle->xc_handle, node->num_domains, DOMAIN_CHUNK_SIZE, domaininfo); tmp = realloc(node->domains, (node->num_domains + new_domains) * sizeof(xenstat_domain)); if (tmp == NULL) { free(node->domains); free(node); return NULL; } node->domains = tmp; domain = node->domains + node->num_domains; /* zero out newly allocated memory in case error occurs below */ memset(domain, 0, new_domains * sizeof(xenstat_domain)); for (i = 0; i < new_domains; i++) { /* Fill in domain using domaininfo[i] */ domain->id = domaininfo[i].domain; domain->name = xenstat_get_domain_name(handle, domain->id); if (domain->name == NULL) { if (errno == ENOMEM) { /* fatal error */ xenstat_free_node(node); return NULL; } else { /* failed to get name -- this means the domain is being destroyed so simply ignore this entry */ continue; } } domain->state = domaininfo[i].flags; domain->cpu_ns = domaininfo[i].cpu_time; domain->num_vcpus = (domaininfo[i].max_vcpu_id+1); domain->vcpus = NULL; domain->cur_mem = ((unsigned long long)domaininfo[i].tot_pages) * handle->page_size; domain->max_mem = domaininfo[i].max_pages == UINT_MAX ? (unsigned long long)-1 : (unsigned long long)(domaininfo[i].max_pages * handle->page_size); domain->ssid = domaininfo[i].ssidref; domain->num_networks = 0; domain->networks = NULL; domain->num_vbds = 0; domain->vbds = NULL; domain++; node->num_domains++; } } while (new_domains == DOMAIN_CHUNK_SIZE); /* Run all the extra data collectors requested */ node->flags = 0; for (i = 0; i < NUM_COLLECTORS; i++) { if ((flags & collectors[i].flag) == collectors[i].flag) { node->flags |= collectors[i].flag; if(collectors[i].collect(node) == 0) { xenstat_free_node(node); return NULL; } } } return node;}void xenstat_free_node(xenstat_node * node){ int i; if (node) { if (node->domains) { for (i = 0; i < node->num_domains; i++) free(node->domains[i].name); for (i = 0; i < NUM_COLLECTORS; i++) if((node->flags & collectors[i].flag) == collectors[i].flag) collectors[i].free(node); free(node->domains); } free(node); }}xenstat_domain *xenstat_node_domain(xenstat_node * node, unsigned int domid){ unsigned int i; /* FIXME: binary search */ /* Find the appropriate domain entry in the node struct. */ for (i = 0; i < node->num_domains; i++) { if (node->domains[i].id == domid) return &(node->domains[i]); } return NULL;}xenstat_domain *xenstat_node_domain_by_index(xenstat_node * node, unsigned int index){ if (0 <= index && index < node->num_domains) return &(node->domains[index]); return NULL;}const char *xenstat_node_xen_version(xenstat_node * node){ return node->handle->xen_version;}unsigned long long xenstat_node_tot_mem(xenstat_node * node){ return node->tot_mem;}unsigned long long xenstat_node_free_mem(xenstat_node * node){ return node->free_mem;}unsigned int xenstat_node_num_domains(xenstat_node * node){ return node->num_domains;}unsigned int xenstat_node_num_cpus(xenstat_node * node){ return node->num_cpus;}/* Get information about the CPU speed */unsigned long long xenstat_node_cpu_hz(xenstat_node * node){ return node->cpu_hz;}/* Get the domain ID for this domain */unsigned xenstat_domain_id(xenstat_domain * domain){ return domain->id;}/* Get the domain name for the domain */char *xenstat_domain_name(xenstat_domain * domain){ return domain->name;}/* Get information about how much CPU time has been used */unsigned long long xenstat_domain_cpu_ns(xenstat_domain * domain){ return domain->cpu_ns;}/* Find the number of VCPUs for a domain */unsigned int xenstat_domain_num_vcpus(xenstat_domain * domain){
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -