direct-io.hg

changeset 6424:9404574350ce

Cache the Xen version in the xenstat_handle, since it should never change.
Use a collector and new flag for Xen version information, to avoid the
extra hypercall if the caller does not want the information.
Reference the xenstat_handle in the xenstat_node for ease of access
later, and update collectors accordingly.
Signed-off-by: Josh Triplett <josht@us.ibm.com>
Signed-off-by: Christian Limpach <Christian.Limpach@cl.cam.ac.uk>
author cl349@firebug.cl.cam.ac.uk
date Fri Aug 26 08:48:59 2005 +0000 (2005-08-26)
parents af7251014caf
children 28ffa7296a44
files tools/xenstat/libxenstat/src/xenstat.c tools/xenstat/libxenstat/src/xenstat.h
line diff
     1.1 --- a/tools/xenstat/libxenstat/src/xenstat.c	Fri Aug 26 08:47:49 2005 +0000
     1.2 +++ b/tools/xenstat/libxenstat/src/xenstat.c	Fri Aug 26 08:48:59 2005 +0000
     1.3 @@ -27,23 +27,24 @@
     1.4  /*
     1.5   * Types
     1.6   */
     1.7 +#define SHORT_ASC_LEN 5                 /* length of 65535 */
     1.8 +#define VERSION_SIZE (2 * SHORT_ASC_LEN + 1 + sizeof(xen_extraversion_t) + 1)
     1.9 +
    1.10  struct xenstat_handle {
    1.11  	xi_handle *xihandle;
    1.12  	int page_size;
    1.13  	FILE *procnetdev;
    1.14 +	char xen_version[VERSION_SIZE]; /* xen version running on this node */
    1.15  };
    1.16  
    1.17 -#define SHORT_ASC_LEN 5                 /* length of 65535 */
    1.18 -#define VERSION_SIZE (2 * SHORT_ASC_LEN + 1 + sizeof(xen_extraversion_t) + 1)
    1.19 -
    1.20  struct xenstat_node {
    1.21 +	xenstat_handle *handle;
    1.22  	unsigned int flags;
    1.23  	unsigned long long cpu_hz;
    1.24  	unsigned int num_cpus;
    1.25  	unsigned long long tot_mem;
    1.26  	unsigned long long free_mem;
    1.27  	unsigned int num_domains;
    1.28 -	char xen_version[VERSION_SIZE]; /* xen version running on this node */
    1.29  	xenstat_domain *domains;	/* Array of length num_domains */
    1.30  };
    1.31  
    1.32 @@ -83,8 +84,7 @@ struct xenstat_network {
    1.33   */
    1.34  /* Called to collect the information for the node and all the domains on
    1.35   * it. When called, the domain information has already been collected. */
    1.36 -typedef int (*xenstat_collect_func)(xenstat_handle * handle,
    1.37 -				    xenstat_node * node);
    1.38 +typedef int (*xenstat_collect_func)(xenstat_node * node);
    1.39  /* Called to free the information collected by the collect function.  The free
    1.40   * function will only be called on a xenstat_node if that node includes
    1.41   * information collected by the corresponding collector. */
    1.42 @@ -101,20 +101,23 @@ typedef struct xenstat_collector {
    1.43  	xenstat_uninit_func uninit;
    1.44  } xenstat_collector;
    1.45  
    1.46 -static int  xenstat_collect_vcpus(xenstat_handle * handle,
    1.47 -				  xenstat_node * node);
    1.48 -static int  xenstat_collect_networks(xenstat_handle * handle,
    1.49 -				    xenstat_node * node);
    1.50 +static int  xenstat_collect_vcpus(xenstat_node * node);
    1.51 +static int  xenstat_collect_networks(xenstat_node * node);
    1.52 +static int  xenstat_collect_xen_version(xenstat_node * node);
    1.53  static void xenstat_free_vcpus(xenstat_node * node);
    1.54  static void xenstat_free_networks(xenstat_node * node);
    1.55 +static void xenstat_free_xen_version(xenstat_node * node);
    1.56  static void xenstat_uninit_vcpus(xenstat_handle * handle);
    1.57  static void xenstat_uninit_networks(xenstat_handle * handle);
    1.58 +static void xenstat_uninit_xen_version(xenstat_handle * handle);
    1.59  
    1.60  static xenstat_collector collectors[] = {
    1.61  	{ XENSTAT_VCPU, xenstat_collect_vcpus,
    1.62  	  xenstat_free_vcpus, xenstat_uninit_vcpus },
    1.63  	{ XENSTAT_NETWORK, xenstat_collect_networks,
    1.64 -	  xenstat_free_networks, xenstat_uninit_networks }
    1.65 +	  xenstat_free_networks, xenstat_uninit_networks },
    1.66 +	{ XENSTAT_XEN_VERSION, xenstat_collect_xen_version,
    1.67 +	  xenstat_free_xen_version, xenstat_uninit_xen_version }
    1.68  };
    1.69  
    1.70  #define NUM_COLLECTORS (sizeof(collectors)/sizeof(xenstat_collector))
    1.71 @@ -169,8 +172,6 @@ xenstat_node *xenstat_get_node(xenstat_h
    1.72  #define DOMAIN_CHUNK_SIZE 256
    1.73  	xenstat_node *node;
    1.74  	dom0_physinfo_t physinfo;
    1.75 -	xen_extraversion_t version;
    1.76 -	long vnum = 0;
    1.77  	dom0_getdomaininfo_t domaininfo[DOMAIN_CHUNK_SIZE];
    1.78  	unsigned int num_domains, new_domains;
    1.79  	unsigned int i;
    1.80 @@ -180,20 +181,15 @@ xenstat_node *xenstat_get_node(xenstat_h
    1.81  	if (node == NULL)
    1.82  		return NULL;
    1.83  
    1.84 +	/* Store the handle in the node for later access */
    1.85 +	node->handle = handle;
    1.86 +
    1.87  	/* Get information about the physical system */
    1.88  	if (xi_get_physinfo(handle->xihandle, &physinfo) < 0) {
    1.89  		free(node);
    1.90  		return NULL;
    1.91  	}
    1.92  
    1.93 -	/* Get the xen version number and xen version tag */
    1.94 -	if (xi_get_xen_version(handle->xihandle, &vnum, &version) < 0) {
    1.95 -		free(node);
    1.96 -		return NULL;
    1.97 -	}
    1.98 -	snprintf(node->xen_version, VERSION_SIZE, "%ld.%ld%s\n",
    1.99 -		 ((vnum >> 16) & 0xFFFF), vnum & 0xFFFF, version);
   1.100 -
   1.101  	node->cpu_hz = ((unsigned long long)physinfo.cpu_khz) * 1000ULL;
   1.102  	node->num_cpus =
   1.103  	    (physinfo.threads_per_core * physinfo.cores_per_socket *
   1.104 @@ -259,7 +255,7 @@ xenstat_node *xenstat_get_node(xenstat_h
   1.105  	for (i = 0; i < NUM_COLLECTORS; i++) {
   1.106  		if ((flags & collectors[i].flag) == collectors[i].flag) {
   1.107  			node->flags |= collectors[i].flag;
   1.108 -			if(collectors[i].collect(handle, node) == 0) {
   1.109 +			if(collectors[i].collect(node) == 0) {
   1.110  				xenstat_free_node(node);
   1.111  				return NULL;
   1.112  			}
   1.113 @@ -306,9 +302,9 @@ xenstat_domain *xenstat_node_domain_by_i
   1.114  	return NULL;
   1.115  }
   1.116  
   1.117 -const char *xenstat_node_xen_ver(xenstat_node * node)
   1.118 +const char *xenstat_node_xen_version(xenstat_node * node)
   1.119  {
   1.120 -	return node->xen_version;
   1.121 +	return node->handle->xen_version;
   1.122  }
   1.123  
   1.124  unsigned long long xenstat_node_tot_mem(xenstat_node * node)
   1.125 @@ -434,7 +430,7 @@ xenstat_network *xenstat_domain_network(
   1.126   * VCPU functions
   1.127   */
   1.128  /* Collect information about VCPUs */
   1.129 -static int xenstat_collect_vcpus(xenstat_handle * handle, xenstat_node * node)
   1.130 +static int xenstat_collect_vcpus(xenstat_node * node)
   1.131  {
   1.132  	unsigned int i, vcpu;
   1.133  	/* Fill in VCPU information */
   1.134 @@ -447,10 +443,9 @@ static int xenstat_collect_vcpus(xenstat
   1.135  		for (vcpu = 0; vcpu < node->domains[i].num_vcpus; vcpu++) {
   1.136  			/* FIXME: need to be using a more efficient mechanism*/
   1.137  			long long vcpu_time;
   1.138 -			vcpu_time =
   1.139 -			    xi_get_vcpu_usage(handle->xihandle,
   1.140 -					      node->domains[i].id,
   1.141 -					      vcpu);
   1.142 +			vcpu_time = xi_get_vcpu_usage(node->handle->xihandle,
   1.143 +						      node->domains[i].id,
   1.144 +						      vcpu);
   1.145  			if (vcpu_time < 0)
   1.146  				return 0;
   1.147  			node->domains[i].vcpus[vcpu].ns = vcpu_time;
   1.148 @@ -490,21 +485,20 @@ static const char PROCNETDEV_HEADER[] =
   1.149      "bytes    packets errs drop fifo colls carrier compressed\n";
   1.150  
   1.151  /* Collect information about networks */
   1.152 -static int xenstat_collect_networks(xenstat_handle * handle,
   1.153 -				    xenstat_node * node)
   1.154 +static int xenstat_collect_networks(xenstat_node * node)
   1.155  {
   1.156  	/* Open and validate /proc/net/dev if we haven't already */
   1.157 -	if (handle->procnetdev == NULL) {
   1.158 +	if (node->handle->procnetdev == NULL) {
   1.159  		char header[sizeof(PROCNETDEV_HEADER)];
   1.160 -		handle->procnetdev = fopen("/proc/net/dev", "r");
   1.161 -		if (handle->procnetdev == NULL) {
   1.162 +		node->handle->procnetdev = fopen("/proc/net/dev", "r");
   1.163 +		if (node->handle->procnetdev == NULL) {
   1.164  			perror("Error opening /proc/net/dev");
   1.165  			return 1;
   1.166  		}
   1.167  
   1.168  		/* Validate the format of /proc/net/dev */
   1.169  		if (fread(header, sizeof(PROCNETDEV_HEADER) - 1, 1,
   1.170 -			  handle->procnetdev) != 1) {
   1.171 +			  node->handle->procnetdev) != 1) {
   1.172  			perror("Error reading /proc/net/dev header");
   1.173  			return 1;
   1.174  		}
   1.175 @@ -518,12 +512,13 @@ static int xenstat_collect_networks(xens
   1.176  
   1.177  	/* Fill in networks */
   1.178  	/* FIXME: optimize this */
   1.179 -	fseek(handle->procnetdev, sizeof(PROCNETDEV_HEADER) - 1, SEEK_SET);
   1.180 +	fseek(node->handle->procnetdev, sizeof(PROCNETDEV_HEADER) - 1,
   1.181 +	      SEEK_SET);
   1.182  	while (1) {
   1.183  		xenstat_domain *domain;
   1.184  		xenstat_network net;
   1.185  		unsigned int domid;
   1.186 -		int ret = fscanf(handle->procnetdev,
   1.187 +		int ret = fscanf(node->handle->procnetdev,
   1.188  				 "vif%u.%u:%llu%llu%llu%llu%*u%*u%*u%*u"
   1.189  				 "%llu%llu%llu%llu%*u%*u%*u%*u\n",
   1.190  				 &domid, &net.id,
   1.191 @@ -536,7 +531,7 @@ static int xenstat_collect_networks(xens
   1.192  		if (ret != 10) {
   1.193  			unsigned int c;
   1.194  			do {
   1.195 -				c = fgetc(handle->procnetdev);
   1.196 +				c = fgetc(node->handle->procnetdev);
   1.197  			} while (c != '\n' && c != EOF);
   1.198  			if (c == EOF)
   1.199  				break;
   1.200 @@ -638,3 +633,37 @@ unsigned long long xenstat_network_tdrop
   1.201  {
   1.202  	return network->tdrop;
   1.203  }
   1.204 +
   1.205 +/*
   1.206 + * Xen version functions
   1.207 + */
   1.208 +
   1.209 +/* Collect Xen version information */
   1.210 +static int xenstat_collect_xen_version(xenstat_node * node)
   1.211 +{
   1.212 +	long vnum = 0;
   1.213 +	xen_extraversion_t version;
   1.214 +
   1.215 +	/* Collect Xen version information if not already collected */
   1.216 +	if (node->handle->xen_version[0] == '\0') {
   1.217 +		/* Get the Xen version number and extraversion string */
   1.218 +		if (xi_get_xen_version(node->handle->xihandle,
   1.219 +				       &vnum, &version) < 0)
   1.220 +			return 0;
   1.221 +		/* Format the version information as a string and store it */
   1.222 +		snprintf(node->handle->xen_version, VERSION_SIZE, "%ld.%ld%s",
   1.223 +			 ((vnum >> 16) & 0xFFFF), vnum & 0xFFFF, version);
   1.224 +	}
   1.225 +
   1.226 +	return 1;
   1.227 +}
   1.228 +
   1.229 +/* Free Xen version information in node - nothing to do */
   1.230 +static void xenstat_free_xen_version(xenstat_node * node)
   1.231 +{
   1.232 +}
   1.233 +
   1.234 +/* Free Xen version information in handle - nothing to do */
   1.235 +static void xenstat_uninit_xen_version(xenstat_handle * handle)
   1.236 +{
   1.237 +}
     2.1 --- a/tools/xenstat/libxenstat/src/xenstat.h	Fri Aug 26 08:47:49 2005 +0000
     2.2 +++ b/tools/xenstat/libxenstat/src/xenstat.h	Fri Aug 26 08:48:59 2005 +0000
     2.3 @@ -31,10 +31,13 @@ xenstat_handle *xenstat_init();
     2.4  /* Release the handle to libxc, free resources, etc. */
     2.5  void xenstat_uninit(xenstat_handle * handle);
     2.6  
     2.7 -/* Get all available information about a node */
     2.8 +/* Flags for types of information to collect in xenstat_get_node */
     2.9  #define XENSTAT_VCPU 0x1
    2.10  #define XENSTAT_NETWORK 0x2
    2.11 -#define XENSTAT_ALL (XENSTAT_VCPU|XENSTAT_NETWORK)
    2.12 +#define XENSTAT_XEN_VERSION 0x4
    2.13 +#define XENSTAT_ALL (XENSTAT_VCPU|XENSTAT_NETWORK|XENSTAT_XEN_VERSION)
    2.14 +
    2.15 +/* Get all available information about a node */
    2.16  xenstat_node *xenstat_get_node(xenstat_handle * handle, unsigned int flags);
    2.17  
    2.18  /* Free the information */
    2.19 @@ -53,7 +56,7 @@ xenstat_domain *xenstat_node_domain_by_i
    2.20  					     unsigned index);
    2.21  
    2.22  /* Get xen version of the node */
    2.23 -const char *xenstat_node_xen_ver(xenstat_node * node);
    2.24 +const char *xenstat_node_xen_version(xenstat_node * node);
    2.25  
    2.26  /* Get amount of total memory on a node */
    2.27  unsigned long long xenstat_node_tot_mem(xenstat_node * node);