ia64/xen-unstable

changeset 10607:3edac4400459

[XENSTAT]Add VBD information structure.

Import VBD information from sysfs.

Signed-off-by: Satoshi UCHIDA <s-uchida@ap.jp.nec.com>
author kaf24@firebug.cl.cam.ac.uk
date Fri Jun 30 09:20:22 2006 +0100 (2006-06-30)
parents 5d622ded9efe
children 85b092b4567d
files tools/xenstat/libxenstat/src/xenstat.c tools/xenstat/libxenstat/src/xenstat.h
line diff
     1.1 --- a/tools/xenstat/libxenstat/src/xenstat.c	Thu Jun 29 20:28:21 2006 +0100
     1.2 +++ b/tools/xenstat/libxenstat/src/xenstat.c	Fri Jun 30 09:20:22 2006 +0100
     1.3 @@ -20,6 +20,11 @@
     1.4  #include <stdio.h>
     1.5  #include <string.h>
     1.6  #include <unistd.h>
     1.7 +#include <linux/compiler.h>
     1.8 +#include <fcntl.h>
     1.9 +#include <dirent.h>
    1.10 +#include <sys/types.h>
    1.11 +#include <sys/stat.h>
    1.12  #include <xs.h>
    1.13  #include "xenstat.h"
    1.14  
    1.15 @@ -36,6 +41,7 @@ struct xenstat_handle {
    1.16  	struct xs_handle *xshandle; /* xenstore handle */
    1.17  	int page_size;
    1.18  	FILE *procnetdev;
    1.19 +	DIR *sysfsvbd;
    1.20  	char xen_version[VERSION_SIZE]; /* xen version running on this node */
    1.21  };
    1.22  
    1.23 @@ -62,6 +68,8 @@ struct xenstat_domain {
    1.24  	unsigned int ssid;
    1.25  	unsigned int num_networks;
    1.26  	xenstat_network *networks;	/* Array of length num_networks */
    1.27 +	unsigned int num_vbds;
    1.28 +	xenstat_vbd *vbds;
    1.29  };
    1.30  
    1.31  struct xenstat_vcpu {
    1.32 @@ -83,6 +91,15 @@ struct xenstat_network {
    1.33  	unsigned long long tdrop;
    1.34  };
    1.35  
    1.36 +struct xenstat_vbd {
    1.37 +       unsigned int dev;
    1.38 +       unsigned long long oo_reqs;
    1.39 +       unsigned long long rd_reqs;
    1.40 +       unsigned long long wr_reqs;
    1.41 +};
    1.42 +#define SYSFS_VBD_PATH "/sys/devices/xen-backend/"
    1.43 +
    1.44 +
    1.45  /*
    1.46   * Data-collection types
    1.47   */
    1.48 @@ -108,12 +125,15 @@ typedef struct xenstat_collector {
    1.49  static int  xenstat_collect_vcpus(xenstat_node * node);
    1.50  static int  xenstat_collect_networks(xenstat_node * node);
    1.51  static int  xenstat_collect_xen_version(xenstat_node * node);
    1.52 +static int  xenstat_collect_vbds(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_free_vbds(xenstat_node * node);
    1.57  static void xenstat_uninit_vcpus(xenstat_handle * handle);
    1.58  static void xenstat_uninit_networks(xenstat_handle * handle);
    1.59  static void xenstat_uninit_xen_version(xenstat_handle * handle);
    1.60 +static void xenstat_uninit_vbds(xenstat_handle * handle);
    1.61  static char *xenstat_get_domain_name(xenstat_handle * handle, unsigned int domain_id);
    1.62  
    1.63  static xenstat_collector collectors[] = {
    1.64 @@ -122,7 +142,9 @@ static xenstat_collector collectors[] = 
    1.65  	{ XENSTAT_NETWORK, xenstat_collect_networks,
    1.66  	  xenstat_free_networks, xenstat_uninit_networks },
    1.67  	{ XENSTAT_XEN_VERSION, xenstat_collect_xen_version,
    1.68 -	  xenstat_free_xen_version, xenstat_uninit_xen_version }
    1.69 +	  xenstat_free_xen_version, xenstat_uninit_xen_version },
    1.70 +	{ XENSTAT_VBD, xenstat_collect_vbds,
    1.71 +	  xenstat_free_vbds, xenstat_uninit_vbds }
    1.72  };
    1.73  
    1.74  #define NUM_COLLECTORS (sizeof(collectors)/sizeof(xenstat_collector))
    1.75 @@ -259,6 +281,8 @@ xenstat_node *xenstat_get_node(xenstat_h
    1.76  			domain->ssid = domaininfo[i].ssidref;
    1.77  			domain->num_networks = 0;
    1.78  			domain->networks = NULL;
    1.79 +			domain->num_vbds = 0;
    1.80 +			domain->vbds = NULL;
    1.81  
    1.82  			domain++;
    1.83  		}
    1.84 @@ -451,6 +475,21 @@ xenstat_network *xenstat_domain_network(
    1.85  	return NULL;
    1.86  }
    1.87  
    1.88 +/* Get the number of VBDs for a given domain */
    1.89 +unsigned int xenstat_domain_num_vbds(xenstat_domain * domain)
    1.90 +{
    1.91 +	return domain->num_vbds;
    1.92 +}
    1.93 +
    1.94 +/* Get the VBD handle to obtain VBD stats */
    1.95 +xenstat_vbd *xenstat_domain_vbd(xenstat_domain * domain,
    1.96 +				unsigned int vbd)
    1.97 +{
    1.98 +	if (domain->vbds && 0 <= vbd && vbd < domain->num_vbds)
    1.99 +		return &(domain->vbds[vbd]);
   1.100 +	return NULL;
   1.101 +}
   1.102 +
   1.103  /*
   1.104   * VCPU functions
   1.105   */
   1.106 @@ -710,6 +749,139 @@ static void xenstat_uninit_xen_version(x
   1.107  {
   1.108  }
   1.109  
   1.110 +/*
   1.111 + * VBD functions
   1.112 + */
   1.113 +
   1.114 +static int read_attributes_vbd(const char *vbd_directory, const char *what, char *ret, int cap)
   1.115 +{
   1.116 +	static char file_name[80];
   1.117 +	int fd, num_read;
   1.118 +
   1.119 +	sprintf(file_name, "%s/%s/%s", SYSFS_VBD_PATH, vbd_directory, what);
   1.120 +	fd = open(file_name, O_RDONLY, 0);
   1.121 +	if (unlikely(fd==-1)) return -1;
   1.122 +	num_read = read(fd, ret, cap - 1);
   1.123 +	close(fd);
   1.124 +	if (unlikely(num_read<=0)) return -1;
   1.125 +	ret[num_read] = '\0';
   1.126 +	return num_read;
   1.127 +}
   1.128 +
   1.129 +/* Collect information about VBDs */
   1.130 +static int xenstat_collect_vbds(xenstat_node * node)
   1.131 +{
   1.132 +	struct dirent *dp;
   1.133 +
   1.134 +	if (node->handle->sysfsvbd == NULL) {
   1.135 +		node->handle->sysfsvbd = opendir(SYSFS_VBD_PATH);
   1.136 +		if (node->handle->sysfsvbd == NULL) {
   1.137 +			perror("Error opening " SYSFS_VBD_PATH);
   1.138 +			return 0;
   1.139 +		}
   1.140 +	}
   1.141 +
   1.142 +	rewinddir(node->handle->sysfsvbd);
   1.143 +
   1.144 +	for(dp = readdir(node->handle->sysfsvbd); dp != NULL ;
   1.145 +	    dp = readdir(node->handle->sysfsvbd)) {
   1.146 +		xenstat_domain *domain;
   1.147 +		xenstat_vbd vbd;
   1.148 +		unsigned int domid;
   1.149 +		int ret;
   1.150 +		char buf[256];
   1.151 +
   1.152 +
   1.153 +		ret = sscanf(dp->d_name, "vbd-%u-%u", &domid, &vbd.dev);
   1.154 +		if (ret != 2) {
   1.155 +			continue;
   1.156 +		}
   1.157 +		printf("%s is VBD.\n",dp->d_name);
   1.158 +
   1.159 +		domain = xenstat_node_domain(node, domid);
   1.160 +		if (domain == NULL) {
   1.161 +			fprintf(stderr,
   1.162 +				"Found interface vbd-%u-%u but domain %u"
   1.163 +				" does not exist.\n",
   1.164 +				domid, vbd.dev, domid);
   1.165 +			continue;
   1.166 +		}
   1.167 +
   1.168 +		if((read_attributes_vbd(dp->d_name, "statistics/oo_req", buf, 256)<=0)
   1.169 +		   || ((ret = sscanf(buf, "%llu", &vbd.oo_reqs)) != 1))
   1.170 +		{
   1.171 +			continue;
   1.172 +		}
   1.173 +
   1.174 +		if((read_attributes_vbd(dp->d_name, "statistics/rd_req", buf, 256)<=0)
   1.175 +		   || ((ret = sscanf(buf, "%llu", &vbd.rd_reqs)) != 1))
   1.176 +		{
   1.177 +			continue;
   1.178 +		}
   1.179 +
   1.180 +		if((read_attributes_vbd(dp->d_name, "statistics/wr_req", buf, 256)<=0)
   1.181 +		   || ((ret = sscanf(buf, "%llu", &vbd.wr_reqs)) != 1))
   1.182 +		{
   1.183 +			continue;
   1.184 +		}
   1.185 +
   1.186 +
   1.187 +		if (domain->vbds == NULL) {
   1.188 +			domain->num_vbds = 1;
   1.189 +			domain->vbds = malloc(sizeof(xenstat_vbd));
   1.190 +		} else {
   1.191 +			domain->num_vbds++;
   1.192 +			domain->vbds = realloc(domain->vbds,
   1.193 +					       domain->num_vbds *
   1.194 +					       sizeof(xenstat_vbd));
   1.195 +		}
   1.196 +		if (domain->vbds == NULL)
   1.197 +			return 0;
   1.198 +		domain->vbds[domain->num_vbds - 1] = vbd;
   1.199 +	}
   1.200 +
   1.201 +	return 1;	
   1.202 +}
   1.203 +
   1.204 +/* Free VBD information */
   1.205 +static void xenstat_free_vbds(xenstat_node * node)
   1.206 +{
   1.207 +	unsigned int i;
   1.208 +	for (i = 0; i < node->num_domains; i++)
   1.209 +		free(node->domains[i].vbds);
   1.210 +}
   1.211 +
   1.212 +/* Free VBD information in handle */
   1.213 +static void xenstat_uninit_vbds(xenstat_handle * handle)
   1.214 +{
   1.215 +	if (handle->sysfsvbd)
   1.216 +		closedir(handle->sysfsvbd);
   1.217 +}
   1.218 +
   1.219 +/* Get the major number of VBD device */
   1.220 +unsigned int xenstat_vbd_dev(xenstat_vbd * vbd)
   1.221 +{
   1.222 +	return vbd->dev;
   1.223 +}
   1.224 +
   1.225 +/* Get the number of OO(Out of) requests */
   1.226 +unsigned long long xenstat_vbd_oo_reqs(xenstat_vbd * vbd)
   1.227 +{
   1.228 +	return vbd->oo_reqs;
   1.229 +}
   1.230 +
   1.231 +/* Get the number of READ requests */
   1.232 +unsigned long long xenstat_vbd_rd_reqs(xenstat_vbd * vbd)
   1.233 +{
   1.234 +	return vbd->rd_reqs;
   1.235 +}
   1.236 +
   1.237 +/* Get the number of WRITE requests */
   1.238 +unsigned long long xenstat_vbd_wr_reqs(xenstat_vbd * vbd)
   1.239 +{
   1.240 +	return vbd->wr_reqs;
   1.241 +}
   1.242 +
   1.243  static char *xenstat_get_domain_name(xenstat_handle *handle, unsigned int domain_id)
   1.244  {
   1.245  	char path[80];
     2.1 --- a/tools/xenstat/libxenstat/src/xenstat.h	Thu Jun 29 20:28:21 2006 +0100
     2.2 +++ b/tools/xenstat/libxenstat/src/xenstat.h	Fri Jun 30 09:20:22 2006 +0100
     2.3 @@ -23,6 +23,7 @@ typedef struct xenstat_domain xenstat_do
     2.4  typedef struct xenstat_node xenstat_node;
     2.5  typedef struct xenstat_vcpu xenstat_vcpu;
     2.6  typedef struct xenstat_network xenstat_network;
     2.7 +typedef struct xenstat_vbd xenstat_vbd;
     2.8  
     2.9  /* Initialize the xenstat library.  Returns a handle to be used with
    2.10   * subsequent calls to the xenstat library, or NULL if an error occurs. */
    2.11 @@ -35,7 +36,8 @@ void xenstat_uninit(xenstat_handle * han
    2.12  #define XENSTAT_VCPU 0x1
    2.13  #define XENSTAT_NETWORK 0x2
    2.14  #define XENSTAT_XEN_VERSION 0x4
    2.15 -#define XENSTAT_ALL (XENSTAT_VCPU|XENSTAT_NETWORK|XENSTAT_XEN_VERSION)
    2.16 +#define XENSTAT_VBD 0x8
    2.17 +#define XENSTAT_ALL (XENSTAT_VCPU|XENSTAT_NETWORK|XENSTAT_XEN_VERSION|XENSTAT_VBD)
    2.18  
    2.19  /* Get all available information about a node */
    2.20  xenstat_node *xenstat_get_node(xenstat_handle * handle, unsigned int flags);
    2.21 @@ -117,6 +119,13 @@ unsigned int xenstat_domain_num_networks
    2.22  xenstat_network *xenstat_domain_network(xenstat_domain * domain,
    2.23  					unsigned int network);
    2.24  
    2.25 +/* Get the number of VBDs for a given domain */
    2.26 +unsigned int xenstat_domain_num_vbds(xenstat_domain *);
    2.27 +
    2.28 +/* Get the VBD handle to obtain VBD stats */
    2.29 +xenstat_vbd *xenstat_domain_vbd(xenstat_domain * domain,
    2.30 +				    unsigned int vbd);
    2.31 +
    2.32  /*
    2.33   * VCPU functions - extract information from a xenstat_vcpu
    2.34   */
    2.35 @@ -156,3 +165,14 @@ unsigned long long xenstat_network_terrs
    2.36  
    2.37  /* Get the number of transmit drops for this network */
    2.38  unsigned long long xenstat_network_tdrop(xenstat_network * network);
    2.39 +
    2.40 +/*
    2.41 + * VBD functions - extract information from a xen_vbd
    2.42 + */
    2.43 +/* Get the device number for Virtual Block Device */
    2.44 +unsigned int xenstat_vbd_dev(xenstat_vbd * vbd);
    2.45 +
    2.46 +/* Get the number of OO/RD/WR requests for vbd */
    2.47 +unsigned long long xenstat_vbd_oo_reqs(xenstat_vbd * vbd);
    2.48 +unsigned long long xenstat_vbd_rd_reqs(xenstat_vbd * vbd);
    2.49 +unsigned long long xenstat_vbd_wr_reqs(xenstat_vbd * vbd);