ia64/xen-unstable

changeset 14089:38fb6c392dec

Implement VBD and VIF handling on Solaris for libxenstat.

Also, fix up a confusion with ERR that was breaking xentop.

Signed-off-by: John Levon <john.levon@sun.com>
author kfraser@localhost.localdomain
date Fri Feb 23 10:47:55 2007 +0000 (2007-02-23)
parents d7fe2318fc5f
children cdc765772f69
files tools/xenstat/libxenstat/Makefile tools/xenstat/libxenstat/src/xenstat.c tools/xenstat/libxenstat/src/xenstat.h tools/xenstat/libxenstat/src/xenstat_linux.c tools/xenstat/libxenstat/src/xenstat_priv.h tools/xenstat/libxenstat/src/xenstat_solaris.c tools/xenstat/xentop/xentop.c
line diff
     1.1 --- a/tools/xenstat/libxenstat/Makefile	Fri Feb 23 10:43:00 2007 +0000
     1.2 +++ b/tools/xenstat/libxenstat/Makefile	Fri Feb 23 10:47:55 2007 +0000
     1.3 @@ -14,7 +14,6 @@
     1.4  
     1.5  XEN_ROOT=../../..
     1.6  include $(XEN_ROOT)/tools/Rules.mk
     1.7 -LINUX_ROOT := $(XEN_ROOT)/linux-2.6-xen-sparse
     1.8  
     1.9  prefix=/usr
    1.10  includedir=$(prefix)/include
    1.11 @@ -29,26 +28,40 @@ MINOR=0
    1.12  LIB=src/libxenstat.a
    1.13  SHLIB=src/libxenstat.so.$(MAJOR).$(MINOR)
    1.14  SHLIB_LINKS=src/libxenstat.so.$(MAJOR) src/libxenstat.so
    1.15 -OBJECTS=src/xenstat.o
    1.16 +OBJECTS-y=src/xenstat.o
    1.17 +OBJECTS-$(CONFIG_Linux) += src/xenstat_linux.o
    1.18 +OBJECTS-$(CONFIG_SunOS) += src/xenstat_solaris.o
    1.19  SONAME_FLAGS=-Wl,$(SONAME_LDFLAG) -Wl,libxenstat.so.$(MAJOR)
    1.20  
    1.21  WARN_FLAGS=-Wall -Werror
    1.22  
    1.23  CFLAGS+=-Isrc -I$(XEN_LIBXC) -I$(XEN_XENSTORE)
    1.24  LDFLAGS+=-Lsrc -L$(XEN_XENSTORE)/ -L$(XEN_LIBXC)/
    1.25 +LDLIBS-y = -lxenstore -lxenctrl
    1.26 +LDLIBS-$(CONFIG_SunOS) += -lkstat
    1.27 +ARLIBS-y = $(XEN_XENSTORE)/libxenstore.so $(XEN_LIBXC)/libxenctrl.so
    1.28 +ARLIBS-x86_64 = /usr/lib/amd64/libkstat.so
    1.29 +ARLIBS-x86_32 = /usr/lib/libkstat.so
    1.30 +ARLIBS-$(CONFIG_SunOS) += $(ARLIBS-$(XEN_TARGET_ARCH))
    1.31  
    1.32  .PHONY: all
    1.33  all: $(LIB)
    1.34  
    1.35 -$(LIB): $(OBJECTS)
    1.36 -	$(AR) rc $@ $^ $(XEN_XENSTORE)/libxenstore.so $(XEN_LIBXC)/libxenctrl.so
    1.37 +$(LIB): $(OBJECTS-y)
    1.38 +	$(AR) rc $@ $^ $(ARLIBS-y)
    1.39  	$(RANLIB) $@
    1.40  
    1.41 -$(SHLIB): $(OBJECTS)
    1.42 -	$(CC) $(CFLAGS) $(LDFLAGS) $(SONAME_FLAGS) $(SHLIB_CFLAGS) -o $@ $(OBJECTS) \
    1.43 -		-lxenstore -lxenctrl
    1.44 +$(SHLIB): $(OBJECTS-y)
    1.45 +	$(CC) $(CFLAGS) $(LDFLAGS) $(SONAME_FLAGS) $(SHLIB_CFLAGS) -o $@ \
    1.46 +	    $(OBJECTS-y) $(LDLIBS-y)
    1.47  
    1.48 -src/xenstat.o: src/xenstat.c src/xenstat.h
    1.49 +src/xenstat.o: src/xenstat.c src/xenstat.h src/xenstat_priv.h
    1.50 +	$(CC) $(CFLAGS) $(WARN_FLAGS) -c -o $@ $<
    1.51 +
    1.52 +src/xenstat_linux.o: src/xenstat_linux.c src/xenstat_priv.h
    1.53 +	$(CC) $(CFLAGS) $(WARN_FLAGS) -c -o $@ $<
    1.54 +
    1.55 +src/xenstat_solaris.o: src/xenstat_solaris.c src/xenstat_priv.h
    1.56  	$(CC) $(CFLAGS) $(WARN_FLAGS) -c -o $@ $<
    1.57  
    1.58  src/libxenstat.so.$(MAJOR): $(LIB)
    1.59 @@ -140,5 +153,5 @@ endif
    1.60  
    1.61  .PHONY: clean
    1.62  clean:
    1.63 -	rm -f $(LIB) $(SHLIB) $(SHLIB_LINKS) $(OBJECTS) \
    1.64 +	rm -f $(LIB) $(SHLIB) $(SHLIB_LINKS) $(OBJECTS-y) \
    1.65  	      $(BINDINGS) $(BINDINGSRC)
     2.1 --- a/tools/xenstat/libxenstat/src/xenstat.c	Fri Feb 23 10:43:00 2007 +0000
     2.2 +++ b/tools/xenstat/libxenstat/src/xenstat.c	Fri Feb 23 10:47:55 2007 +0000
     2.3 @@ -15,89 +15,17 @@
     2.4   * Lesser General Public License for more details.
     2.5   */
     2.6  
     2.7 -#include <limits.h>
     2.8 -#include <stdlib.h>
     2.9 -#include <stdio.h>
    2.10 -#include <string.h>
    2.11 -#include <unistd.h>
    2.12 -#include <fcntl.h>
    2.13 -#include <dirent.h>
    2.14 -#include <sys/types.h>
    2.15 -#include <sys/stat.h>
    2.16 -#include <xs.h>
    2.17 -#include "xenstat.h"
    2.18 -
    2.19 -#include "xenctrl.h"
    2.20 -
    2.21  /*
    2.22 - * Types
    2.23 + * Copyright 2007 Sun Microsystems, Inc.  All rights reserved.
    2.24 + * Use is subject to license terms.
    2.25   */
    2.26 -#define SHORT_ASC_LEN 5                 /* length of 65535 */
    2.27 -#define VERSION_SIZE (2 * SHORT_ASC_LEN + 1 + sizeof(xen_extraversion_t) + 1)
    2.28 -
    2.29 -struct xenstat_handle {
    2.30 -	int xc_handle;
    2.31 -	struct xs_handle *xshandle; /* xenstore handle */
    2.32 -	int page_size;
    2.33 -	FILE *procnetdev;
    2.34 -	DIR *sysfsvbd;
    2.35 -	char xen_version[VERSION_SIZE]; /* xen version running on this node */
    2.36 -};
    2.37 -
    2.38 -struct xenstat_node {
    2.39 -	xenstat_handle *handle;
    2.40 -	unsigned int flags;
    2.41 -	unsigned long long cpu_hz;
    2.42 -	unsigned int num_cpus;
    2.43 -	unsigned long long tot_mem;
    2.44 -	unsigned long long free_mem;
    2.45 -	unsigned int num_domains;
    2.46 -	xenstat_domain *domains;	/* Array of length num_domains */
    2.47 -};
    2.48  
    2.49 -struct xenstat_domain {
    2.50 -	unsigned int id;
    2.51 -	char *name;
    2.52 -	unsigned int state;
    2.53 -	unsigned long long cpu_ns;
    2.54 -	unsigned int num_vcpus;		/* No. vcpus configured for domain */
    2.55 -	xenstat_vcpu *vcpus;		/* Array of length num_vcpus */
    2.56 -	unsigned long long cur_mem;	/* Current memory reservation */
    2.57 -	unsigned long long max_mem;	/* Total memory allowed */
    2.58 -	unsigned int ssid;
    2.59 -	unsigned int num_networks;
    2.60 -	xenstat_network *networks;	/* Array of length num_networks */
    2.61 -	unsigned int num_vbds;
    2.62 -	xenstat_vbd *vbds;
    2.63 -};
    2.64 -
    2.65 -struct xenstat_vcpu {
    2.66 -	unsigned int online;
    2.67 -	unsigned long long ns;
    2.68 -};
    2.69 +#include <stdlib.h>
    2.70 +#include <string.h>
    2.71 +#include <stdio.h>
    2.72 +#include <unistd.h>
    2.73  
    2.74 -struct xenstat_network {
    2.75 -	unsigned int id;
    2.76 -	/* Received */
    2.77 -	unsigned long long rbytes;
    2.78 -	unsigned long long rpackets;
    2.79 -	unsigned long long rerrs;
    2.80 -	unsigned long long rdrop;
    2.81 -	/* Transmitted */
    2.82 -	unsigned long long tbytes;
    2.83 -	unsigned long long tpackets;
    2.84 -	unsigned long long terrs;
    2.85 -	unsigned long long tdrop;
    2.86 -};
    2.87 -
    2.88 -struct xenstat_vbd {
    2.89 -       unsigned int dev;
    2.90 -       unsigned long long oo_reqs;
    2.91 -       unsigned long long rd_reqs;
    2.92 -       unsigned long long wr_reqs;
    2.93 -};
    2.94 -#define SYSFS_VBD_PATH "/sys/devices/xen-backend/"
    2.95 -
    2.96 +#include "xenstat_priv.h"
    2.97  
    2.98  /*
    2.99   * Data-collection types
   2.100 @@ -125,17 +53,13 @@ typedef struct xenstat_collector {
   2.101  } xenstat_collector;
   2.102  
   2.103  static int  xenstat_collect_vcpus(xenstat_node * node);
   2.104 -static int  xenstat_collect_networks(xenstat_node * node);
   2.105  static int  xenstat_collect_xen_version(xenstat_node * node);
   2.106 -static int  xenstat_collect_vbds(xenstat_node * node);
   2.107  static void xenstat_free_vcpus(xenstat_node * node);
   2.108  static void xenstat_free_networks(xenstat_node * node);
   2.109  static void xenstat_free_xen_version(xenstat_node * node);
   2.110  static void xenstat_free_vbds(xenstat_node * node);
   2.111  static void xenstat_uninit_vcpus(xenstat_handle * handle);
   2.112 -static void xenstat_uninit_networks(xenstat_handle * handle);
   2.113  static void xenstat_uninit_xen_version(xenstat_handle * handle);
   2.114 -static void xenstat_uninit_vbds(xenstat_handle * handle);
   2.115  static char *xenstat_get_domain_name(xenstat_handle * handle, unsigned int domain_id);
   2.116  static void xenstat_prune_domain(xenstat_node *node, unsigned int entry);
   2.117  
   2.118 @@ -202,6 +126,7 @@ void xenstat_uninit(xenstat_handle * han
   2.119  			collectors[i].uninit(handle);
   2.120  		xc_interface_close(handle->xc_handle);
   2.121  		xs_daemon_close(handle->xshandle);
   2.122 +		free(handle->priv);
   2.123  		free(handle);
   2.124  	}
   2.125  }
   2.126 @@ -586,97 +511,6 @@ unsigned long long xenstat_vcpu_ns(xenst
   2.127   * Network functions
   2.128   */
   2.129  
   2.130 -/* Expected format of /proc/net/dev */
   2.131 -static const char PROCNETDEV_HEADER[] =
   2.132 -    "Inter-|   Receive                                                |"
   2.133 -    "  Transmit\n"
   2.134 -    " face |bytes    packets errs drop fifo frame compressed multicast|"
   2.135 -    "bytes    packets errs drop fifo colls carrier compressed\n";
   2.136 -
   2.137 -/* Collect information about networks */
   2.138 -static int xenstat_collect_networks(xenstat_node * node)
   2.139 -{
   2.140 -	/* Open and validate /proc/net/dev if we haven't already */
   2.141 -	if (node->handle->procnetdev == NULL) {
   2.142 -		char header[sizeof(PROCNETDEV_HEADER)];
   2.143 -		node->handle->procnetdev = fopen("/proc/net/dev", "r");
   2.144 -		if (node->handle->procnetdev == NULL) {
   2.145 -			perror("Error opening /proc/net/dev");
   2.146 -			return 0;
   2.147 -		}
   2.148 -
   2.149 -		/* Validate the format of /proc/net/dev */
   2.150 -		if (fread(header, sizeof(PROCNETDEV_HEADER) - 1, 1,
   2.151 -			  node->handle->procnetdev) != 1) {
   2.152 -			perror("Error reading /proc/net/dev header");
   2.153 -			return 0;
   2.154 -		}
   2.155 -		header[sizeof(PROCNETDEV_HEADER) - 1] = '\0';
   2.156 -		if (strcmp(header, PROCNETDEV_HEADER) != 0) {
   2.157 -			fprintf(stderr,
   2.158 -				"Unexpected /proc/net/dev format\n");
   2.159 -			return 0;
   2.160 -		}
   2.161 -	}
   2.162 -
   2.163 -	/* Fill in networks */
   2.164 -	/* FIXME: optimize this */
   2.165 -	fseek(node->handle->procnetdev, sizeof(PROCNETDEV_HEADER) - 1,
   2.166 -	      SEEK_SET);
   2.167 -	while (1) {
   2.168 -		xenstat_domain *domain;
   2.169 -		xenstat_network net;
   2.170 -		unsigned int domid;
   2.171 -		int ret = fscanf(node->handle->procnetdev,
   2.172 -				 "vif%u.%u:%llu%llu%llu%llu%*u%*u%*u%*u"
   2.173 -				 "%llu%llu%llu%llu%*u%*u%*u%*u\n",
   2.174 -				 &domid, &net.id,
   2.175 -				 &net.tbytes, &net.tpackets, &net.terrs,
   2.176 -				 &net.tdrop,
   2.177 -				 &net.rbytes, &net.rpackets, &net.rerrs,
   2.178 -				 &net.rdrop);
   2.179 -		if (ret == EOF)
   2.180 -			break;
   2.181 -		if (ret != 10) {
   2.182 -			unsigned int c;
   2.183 -			do {
   2.184 -				c = fgetc(node->handle->procnetdev);
   2.185 -			} while (c != '\n' && c != EOF);
   2.186 -			if (c == EOF)
   2.187 -				break;
   2.188 -			continue;
   2.189 -		}
   2.190 -
   2.191 -		/* FIXME: this does a search for the domid */
   2.192 -		domain = xenstat_node_domain(node, domid);
   2.193 -		if (domain == NULL) {
   2.194 -			fprintf(stderr,
   2.195 -				"Found interface vif%u.%u but domain %u"
   2.196 -				" does not exist.\n", domid, net.id,
   2.197 -				domid);
   2.198 -			continue;
   2.199 -		}
   2.200 -		if (domain->networks == NULL) {
   2.201 -			domain->num_networks = 1;
   2.202 -			domain->networks = malloc(sizeof(xenstat_network));
   2.203 -		} else {
   2.204 -			struct xenstat_network *tmp;
   2.205 -			domain->num_networks++;
   2.206 -			tmp = realloc(domain->networks,
   2.207 -				      domain->num_networks *
   2.208 -				      sizeof(xenstat_network));
   2.209 -			if (tmp == NULL)
   2.210 -				free(domain->networks);
   2.211 -			domain->networks = tmp;
   2.212 -		}
   2.213 -		if (domain->networks == NULL)
   2.214 -			return 0;
   2.215 -		domain->networks[domain->num_networks - 1] = net;
   2.216 -	}
   2.217 -
   2.218 -	return 1;
   2.219 -}
   2.220 -
   2.221  /* Free network information */
   2.222  static void xenstat_free_networks(xenstat_node * node)
   2.223  {
   2.224 @@ -685,13 +519,6 @@ static void xenstat_free_networks(xensta
   2.225  		free(node->domains[i].networks);
   2.226  }
   2.227  
   2.228 -/* Free network information in handle */
   2.229 -static void xenstat_uninit_networks(xenstat_handle * handle)
   2.230 -{
   2.231 -	if(handle->procnetdev)
   2.232 -		fclose(handle->procnetdev);
   2.233 -}
   2.234 -
   2.235  /* Get the network ID */
   2.236  unsigned int xenstat_network_id(xenstat_network * network)
   2.237  {
   2.238 @@ -790,96 +617,6 @@ static void xenstat_uninit_xen_version(x
   2.239   * VBD functions
   2.240   */
   2.241  
   2.242 -static int read_attributes_vbd(const char *vbd_directory, const char *what, char *ret, int cap)
   2.243 -{
   2.244 -	static char file_name[80];
   2.245 -	int fd, num_read;
   2.246 -
   2.247 -	sprintf(file_name, "%s/%s/%s", SYSFS_VBD_PATH, vbd_directory, what);
   2.248 -	fd = open(file_name, O_RDONLY, 0);
   2.249 -	if (fd==-1) return -1;
   2.250 -	num_read = read(fd, ret, cap - 1);
   2.251 -	close(fd);
   2.252 -	if (num_read<=0) return -1;
   2.253 -	ret[num_read] = '\0';
   2.254 -	return num_read;
   2.255 -}
   2.256 -
   2.257 -/* Collect information about VBDs */
   2.258 -static int xenstat_collect_vbds(xenstat_node * node)
   2.259 -{
   2.260 -	struct dirent *dp;
   2.261 -
   2.262 -	if (node->handle->sysfsvbd == NULL) {
   2.263 -		node->handle->sysfsvbd = opendir(SYSFS_VBD_PATH);
   2.264 -		if (node->handle->sysfsvbd == NULL) {
   2.265 -			perror("Error opening " SYSFS_VBD_PATH);
   2.266 -			return 0;
   2.267 -		}
   2.268 -	}
   2.269 -
   2.270 -	rewinddir(node->handle->sysfsvbd);
   2.271 -
   2.272 -	for(dp = readdir(node->handle->sysfsvbd); dp != NULL ;
   2.273 -	    dp = readdir(node->handle->sysfsvbd)) {
   2.274 -		xenstat_domain *domain;
   2.275 -		xenstat_vbd vbd;
   2.276 -		unsigned int domid;
   2.277 -		int ret;
   2.278 -		char buf[256];
   2.279 -
   2.280 -
   2.281 -		ret = sscanf(dp->d_name, "vbd-%u-%u", &domid, &vbd.dev);
   2.282 -		if (ret != 2) {
   2.283 -			continue;
   2.284 -		}
   2.285 -		printf("%s is VBD.\n",dp->d_name);
   2.286 -
   2.287 -		domain = xenstat_node_domain(node, domid);
   2.288 -		if (domain == NULL) {
   2.289 -			fprintf(stderr,
   2.290 -				"Found interface vbd-%u-%u but domain %u"
   2.291 -				" does not exist.\n",
   2.292 -				domid, vbd.dev, domid);
   2.293 -			continue;
   2.294 -		}
   2.295 -
   2.296 -		if((read_attributes_vbd(dp->d_name, "statistics/oo_req", buf, 256)<=0)
   2.297 -		   || ((ret = sscanf(buf, "%llu", &vbd.oo_reqs)) != 1))
   2.298 -		{
   2.299 -			continue;
   2.300 -		}
   2.301 -
   2.302 -		if((read_attributes_vbd(dp->d_name, "statistics/rd_req", buf, 256)<=0)
   2.303 -		   || ((ret = sscanf(buf, "%llu", &vbd.rd_reqs)) != 1))
   2.304 -		{
   2.305 -			continue;
   2.306 -		}
   2.307 -
   2.308 -		if((read_attributes_vbd(dp->d_name, "statistics/wr_req", buf, 256)<=0)
   2.309 -		   || ((ret = sscanf(buf, "%llu", &vbd.wr_reqs)) != 1))
   2.310 -		{
   2.311 -			continue;
   2.312 -		}
   2.313 -
   2.314 -
   2.315 -		if (domain->vbds == NULL) {
   2.316 -			domain->num_vbds = 1;
   2.317 -			domain->vbds = malloc(sizeof(xenstat_vbd));
   2.318 -		} else {
   2.319 -			domain->num_vbds++;
   2.320 -			domain->vbds = realloc(domain->vbds,
   2.321 -					       domain->num_vbds *
   2.322 -					       sizeof(xenstat_vbd));
   2.323 -		}
   2.324 -		if (domain->vbds == NULL)
   2.325 -			return 0;
   2.326 -		domain->vbds[domain->num_vbds - 1] = vbd;
   2.327 -	}
   2.328 -
   2.329 -	return 1;	
   2.330 -}
   2.331 -
   2.332  /* Free VBD information */
   2.333  static void xenstat_free_vbds(xenstat_node * node)
   2.334  {
   2.335 @@ -888,13 +625,6 @@ static void xenstat_free_vbds(xenstat_no
   2.336  		free(node->domains[i].vbds);
   2.337  }
   2.338  
   2.339 -/* Free VBD information in handle */
   2.340 -static void xenstat_uninit_vbds(xenstat_handle * handle)
   2.341 -{
   2.342 -	if (handle->sysfsvbd)
   2.343 -		closedir(handle->sysfsvbd);
   2.344 -}
   2.345 -
   2.346  /* Get the major number of VBD device */
   2.347  unsigned int xenstat_vbd_dev(xenstat_vbd * vbd)
   2.348  {
   2.349 @@ -948,4 +678,3 @@ static void xenstat_prune_domain(xenstat
   2.350  	   strictly necessary but safer! */
   2.351  	memset(&node->domains[node->num_domains], 0, sizeof(xenstat_domain)); 
   2.352  }
   2.353 -
     3.1 --- a/tools/xenstat/libxenstat/src/xenstat.h	Fri Feb 23 10:43:00 2007 +0000
     3.2 +++ b/tools/xenstat/libxenstat/src/xenstat.h	Fri Feb 23 10:47:55 2007 +0000
     3.3 @@ -17,6 +17,9 @@
     3.4  
     3.5  /* libxenstat API */
     3.6  
     3.7 +#ifndef XENSTAT_H
     3.8 +#define XENSTAT_H
     3.9 +
    3.10  /* Opaque handles */
    3.11  typedef struct xenstat_handle xenstat_handle;
    3.12  typedef struct xenstat_domain xenstat_domain;
    3.13 @@ -176,3 +179,5 @@ unsigned int xenstat_vbd_dev(xenstat_vbd
    3.14  unsigned long long xenstat_vbd_oo_reqs(xenstat_vbd * vbd);
    3.15  unsigned long long xenstat_vbd_rd_reqs(xenstat_vbd * vbd);
    3.16  unsigned long long xenstat_vbd_wr_reqs(xenstat_vbd * vbd);
    3.17 +
    3.18 +#endif /* XENSTAT_H */
     4.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     4.2 +++ b/tools/xenstat/libxenstat/src/xenstat_linux.c	Fri Feb 23 10:47:55 2007 +0000
     4.3 @@ -0,0 +1,265 @@
     4.4 +/* libxenstat: statistics-collection library for Xen
     4.5 + * Copyright (C) International Business Machines Corp., 2005
     4.6 + * Authors: Josh Triplett <josht@us.ibm.com>
     4.7 + *          Judy Fischbach <jfisch@us.ibm.com>
     4.8 + *          David Hendricks <dhendrix@us.ibm.com>
     4.9 + *
    4.10 + * This library is free software; you can redistribute it and/or
    4.11 + * modify it under the terms of the GNU Lesser General Public
    4.12 + * License as published by the Free Software Foundation; either
    4.13 + * version 2.1 of the License, or (at your option) any later version.
    4.14 + *
    4.15 + * This library is distributed in the hope that it will be useful,
    4.16 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
    4.17 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
    4.18 + * Lesser General Public License for more details.
    4.19 + */
    4.20 +
    4.21 +/*
    4.22 + * Copyright 2007 Sun Microsystems, Inc.  All rights reserved.
    4.23 + * Use is subject to license terms.
    4.24 + */
    4.25 +
    4.26 +#include <fcntl.h>
    4.27 +#include <dirent.h>
    4.28 +#include <sys/types.h>
    4.29 +#include <sys/stat.h>
    4.30 +#include <stdio.h>
    4.31 +#include <stdlib.h>
    4.32 +#include <string.h>
    4.33 +#include <unistd.h>
    4.34 +
    4.35 +#include "xenstat_priv.h"
    4.36 +
    4.37 +#define SYSFS_VBD_PATH "/sys/devices/xen-backend/"
    4.38 +
    4.39 +struct priv_data {
    4.40 +	FILE *procnetdev;
    4.41 +	DIR *sysfsvbd;
    4.42 +};
    4.43 +
    4.44 +static struct priv_data *
    4.45 +get_priv_data(xenstat_handle *handle)
    4.46 +{
    4.47 +	if (handle->priv != NULL)
    4.48 +		return handle->priv;
    4.49 +
    4.50 +	handle->priv = malloc(sizeof(struct priv_data));
    4.51 +	if (handle->priv == NULL)
    4.52 +		return (NULL);
    4.53 +
    4.54 +	((struct priv_data *)handle->priv)->procnetdev = NULL;
    4.55 +	((struct priv_data *)handle->priv)->sysfsvbd = NULL;
    4.56 +
    4.57 +	return handle->priv;
    4.58 +}
    4.59 +
    4.60 +/* Expected format of /proc/net/dev */
    4.61 +static const char PROCNETDEV_HEADER[] =
    4.62 +    "Inter-|   Receive                                                |"
    4.63 +    "  Transmit\n"
    4.64 +    " face |bytes    packets errs drop fifo frame compressed multicast|"
    4.65 +    "bytes    packets errs drop fifo colls carrier compressed\n";
    4.66 +
    4.67 +/* Collect information about networks */
    4.68 +int xenstat_collect_networks(xenstat_node * node)
    4.69 +{
    4.70 +	struct priv_data *priv = get_priv_data(node->handle);
    4.71 +
    4.72 +	if (priv == NULL) {
    4.73 +		perror("Allocation error");
    4.74 +		return 0;
    4.75 +	}
    4.76 +
    4.77 +	/* Open and validate /proc/net/dev if we haven't already */
    4.78 +	if (priv->procnetdev == NULL) {
    4.79 +		char header[sizeof(PROCNETDEV_HEADER)];
    4.80 +		priv->procnetdev = fopen("/proc/net/dev", "r");
    4.81 +		if (priv->procnetdev == NULL) {
    4.82 +			perror("Error opening /proc/net/dev");
    4.83 +			return 0;
    4.84 +		}
    4.85 +
    4.86 +		/* Validate the format of /proc/net/dev */
    4.87 +		if (fread(header, sizeof(PROCNETDEV_HEADER) - 1, 1,
    4.88 +			  priv->procnetdev) != 1) {
    4.89 +			perror("Error reading /proc/net/dev header");
    4.90 +			return 0;
    4.91 +		}
    4.92 +		header[sizeof(PROCNETDEV_HEADER) - 1] = '\0';
    4.93 +		if (strcmp(header, PROCNETDEV_HEADER) != 0) {
    4.94 +			fprintf(stderr,
    4.95 +				"Unexpected /proc/net/dev format\n");
    4.96 +			return 0;
    4.97 +		}
    4.98 +	}
    4.99 +
   4.100 +	/* Fill in networks */
   4.101 +	/* FIXME: optimize this */
   4.102 +	fseek(priv->procnetdev, sizeof(PROCNETDEV_HEADER) - 1,
   4.103 +	      SEEK_SET);
   4.104 +	while (1) {
   4.105 +		xenstat_domain *domain;
   4.106 +		xenstat_network net;
   4.107 +		unsigned int domid;
   4.108 +		int ret = fscanf(priv->procnetdev,
   4.109 +				 "vif%u.%u:%llu%llu%llu%llu%*u%*u%*u%*u"
   4.110 +				 "%llu%llu%llu%llu%*u%*u%*u%*u\n",
   4.111 +				 &domid, &net.id,
   4.112 +				 &net.tbytes, &net.tpackets, &net.terrs,
   4.113 +				 &net.tdrop,
   4.114 +				 &net.rbytes, &net.rpackets, &net.rerrs,
   4.115 +				 &net.rdrop);
   4.116 +		if (ret == EOF)
   4.117 +			break;
   4.118 +		if (ret != 10) {
   4.119 +			unsigned int c;
   4.120 +			do {
   4.121 +				c = fgetc(priv->procnetdev);
   4.122 +			} while (c != '\n' && c != EOF);
   4.123 +			if (c == EOF)
   4.124 +				break;
   4.125 +			continue;
   4.126 +		}
   4.127 +
   4.128 +		/* FIXME: this does a search for the domid */
   4.129 +		domain = xenstat_node_domain(node, domid);
   4.130 +		if (domain == NULL) {
   4.131 +			fprintf(stderr,
   4.132 +				"Found interface vif%u.%u but domain %u"
   4.133 +				" does not exist.\n", domid, net.id,
   4.134 +				domid);
   4.135 +			continue;
   4.136 +		}
   4.137 +		if (domain->networks == NULL) {
   4.138 +			domain->num_networks = 1;
   4.139 +			domain->networks = malloc(sizeof(xenstat_network));
   4.140 +		} else {
   4.141 +			struct xenstat_network *tmp;
   4.142 +			domain->num_networks++;
   4.143 +			tmp = realloc(domain->networks,
   4.144 +				      domain->num_networks *
   4.145 +				      sizeof(xenstat_network));
   4.146 +			if (tmp == NULL)
   4.147 +				free(domain->networks);
   4.148 +			domain->networks = tmp;
   4.149 +		}
   4.150 +		if (domain->networks == NULL)
   4.151 +			return 0;
   4.152 +		domain->networks[domain->num_networks - 1] = net;
   4.153 +	}
   4.154 +
   4.155 +	return 1;
   4.156 +}
   4.157 +
   4.158 +/* Free network information in handle */
   4.159 +void xenstat_uninit_networks(xenstat_handle * handle)
   4.160 +{
   4.161 +	struct priv_data *priv = get_priv_data(handle);
   4.162 +	if (priv != NULL && priv->procnetdev != NULL)
   4.163 +		fclose(priv->procnetdev);
   4.164 +}
   4.165 +
   4.166 +static int read_attributes_vbd(const char *vbd_directory, const char *what, char *ret, int cap)
   4.167 +{
   4.168 +	static char file_name[80];
   4.169 +	int fd, num_read;
   4.170 +
   4.171 +	sprintf(file_name, "%s/%s/%s", SYSFS_VBD_PATH, vbd_directory, what);
   4.172 +	fd = open(file_name, O_RDONLY, 0);
   4.173 +	if (fd==-1) return -1;
   4.174 +	num_read = read(fd, ret, cap - 1);
   4.175 +	close(fd);
   4.176 +	if (num_read<=0) return -1;
   4.177 +	ret[num_read] = '\0';
   4.178 +	return num_read;
   4.179 +}
   4.180 +
   4.181 +/* Collect information about VBDs */
   4.182 +int xenstat_collect_vbds(xenstat_node * node)
   4.183 +{
   4.184 +	struct dirent *dp;
   4.185 +	struct priv_data *priv = get_priv_data(node->handle);
   4.186 +
   4.187 +	if (priv == NULL) {
   4.188 +		perror("Allocation error");
   4.189 +		return 0;
   4.190 +	}
   4.191 +
   4.192 +	if (priv->sysfsvbd == NULL) {
   4.193 +		priv->sysfsvbd = opendir(SYSFS_VBD_PATH);
   4.194 +		if (priv->sysfsvbd == NULL) {
   4.195 +			perror("Error opening " SYSFS_VBD_PATH);
   4.196 +			return 0;
   4.197 +		}
   4.198 +	}
   4.199 +
   4.200 +	rewinddir(priv->sysfsvbd);
   4.201 +
   4.202 +	for(dp = readdir(priv->sysfsvbd); dp != NULL ;
   4.203 +	    dp = readdir(priv->sysfsvbd)) {
   4.204 +		xenstat_domain *domain;
   4.205 +		xenstat_vbd vbd;
   4.206 +		unsigned int domid;
   4.207 +		int ret;
   4.208 +		char buf[256];
   4.209 +
   4.210 +
   4.211 +		ret = sscanf(dp->d_name, "vbd-%u-%u", &domid, &vbd.dev);
   4.212 +		if (ret != 2) {
   4.213 +			continue;
   4.214 +		}
   4.215 +		printf("%s is VBD.\n",dp->d_name);
   4.216 +
   4.217 +		domain = xenstat_node_domain(node, domid);
   4.218 +		if (domain == NULL) {
   4.219 +			fprintf(stderr,
   4.220 +				"Found interface vbd-%u-%u but domain %u"
   4.221 +				" does not exist.\n",
   4.222 +				domid, vbd.dev, domid);
   4.223 +			continue;
   4.224 +		}
   4.225 +
   4.226 +		if((read_attributes_vbd(dp->d_name, "statistics/oo_req", buf, 256)<=0)
   4.227 +		   || ((ret = sscanf(buf, "%llu", &vbd.oo_reqs)) != 1))
   4.228 +		{
   4.229 +			continue;
   4.230 +		}
   4.231 +
   4.232 +		if((read_attributes_vbd(dp->d_name, "statistics/rd_req", buf, 256)<=0)
   4.233 +		   || ((ret = sscanf(buf, "%llu", &vbd.rd_reqs)) != 1))
   4.234 +		{
   4.235 +			continue;
   4.236 +		}
   4.237 +
   4.238 +		if((read_attributes_vbd(dp->d_name, "statistics/wr_req", buf, 256)<=0)
   4.239 +		   || ((ret = sscanf(buf, "%llu", &vbd.wr_reqs)) != 1))
   4.240 +		{
   4.241 +			continue;
   4.242 +		}
   4.243 +
   4.244 +
   4.245 +		if (domain->vbds == NULL) {
   4.246 +			domain->num_vbds = 1;
   4.247 +			domain->vbds = malloc(sizeof(xenstat_vbd));
   4.248 +		} else {
   4.249 +			domain->num_vbds++;
   4.250 +			domain->vbds = realloc(domain->vbds,
   4.251 +					       domain->num_vbds *
   4.252 +					       sizeof(xenstat_vbd));
   4.253 +		}
   4.254 +		if (domain->vbds == NULL)
   4.255 +			return 0;
   4.256 +		domain->vbds[domain->num_vbds - 1] = vbd;
   4.257 +	}
   4.258 +
   4.259 +	return 1;	
   4.260 +}
   4.261 +
   4.262 +/* Free VBD information in handle */
   4.263 +void xenstat_uninit_vbds(xenstat_handle * handle)
   4.264 +{
   4.265 +	struct priv_data *priv = get_priv_data(handle);
   4.266 +	if (priv != NULL && priv->sysfsvbd != NULL)
   4.267 +		closedir(priv->sysfsvbd);
   4.268 +}
     5.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     5.2 +++ b/tools/xenstat/libxenstat/src/xenstat_priv.h	Fri Feb 23 10:47:55 2007 +0000
     5.3 @@ -0,0 +1,101 @@
     5.4 +/* libxenstat: statistics-collection library for Xen
     5.5 + * Copyright (C) International Business Machines Corp., 2005
     5.6 + * Authors: Josh Triplett <josht@us.ibm.com>
     5.7 + *          Judy Fischbach <jfisch@us.ibm.com>
     5.8 + *          David Hendricks <dhendrix@us.ibm.com>
     5.9 + *
    5.10 + * This library is free software; you can redistribute it and/or
    5.11 + * modify it under the terms of the GNU Lesser General Public
    5.12 + * License as published by the Free Software Foundation; either
    5.13 + * version 2.1 of the License, or (at your option) any later version.
    5.14 + *
    5.15 + * This library is distributed in the hope that it will be useful,
    5.16 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
    5.17 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
    5.18 + * Lesser General Public License for more details.
    5.19 + */
    5.20 +
    5.21 +/*
    5.22 + * Copyright 2007 Sun Microsystems, Inc.  All rights reserved.
    5.23 + * Use is subject to license terms.
    5.24 + */
    5.25 +
    5.26 +#ifndef XENSTAT_PRIV_H
    5.27 +#define XENSTAT_PRIV_H
    5.28 +
    5.29 +#include <sys/types.h>
    5.30 +#include <xs.h>
    5.31 +#include "xenstat.h"
    5.32 +
    5.33 +#include "xenctrl.h"
    5.34 +
    5.35 +#define SHORT_ASC_LEN 5                 /* length of 65535 */
    5.36 +#define VERSION_SIZE (2 * SHORT_ASC_LEN + 1 + sizeof(xen_extraversion_t) + 1)
    5.37 +
    5.38 +struct xenstat_handle {
    5.39 +	int xc_handle;
    5.40 +	struct xs_handle *xshandle; /* xenstore handle */
    5.41 +	int page_size;
    5.42 +	void *priv;
    5.43 +	char xen_version[VERSION_SIZE]; /* xen version running on this node */
    5.44 +};
    5.45 +
    5.46 +struct xenstat_node {
    5.47 +	xenstat_handle *handle;
    5.48 +	unsigned int flags;
    5.49 +	unsigned long long cpu_hz;
    5.50 +	unsigned int num_cpus;
    5.51 +	unsigned long long tot_mem;
    5.52 +	unsigned long long free_mem;
    5.53 +	unsigned int num_domains;
    5.54 +	xenstat_domain *domains;	/* Array of length num_domains */
    5.55 +};
    5.56 +
    5.57 +struct xenstat_domain {
    5.58 +	unsigned int id;
    5.59 +	char *name;
    5.60 +	unsigned int state;
    5.61 +	unsigned long long cpu_ns;
    5.62 +	unsigned int num_vcpus;		/* No. vcpus configured for domain */
    5.63 +	xenstat_vcpu *vcpus;		/* Array of length num_vcpus */
    5.64 +	unsigned long long cur_mem;	/* Current memory reservation */
    5.65 +	unsigned long long max_mem;	/* Total memory allowed */
    5.66 +	unsigned int ssid;
    5.67 +	unsigned int num_networks;
    5.68 +	xenstat_network *networks;	/* Array of length num_networks */
    5.69 +	unsigned int num_vbds;
    5.70 +	xenstat_vbd *vbds;
    5.71 +};
    5.72 +
    5.73 +struct xenstat_vcpu {
    5.74 +	unsigned int online;
    5.75 +	unsigned long long ns;
    5.76 +};
    5.77 +
    5.78 +struct xenstat_network {
    5.79 +	unsigned int id;
    5.80 +	/* Received */
    5.81 +	unsigned long long rbytes;
    5.82 +	unsigned long long rpackets;
    5.83 +	unsigned long long rerrs;
    5.84 +	unsigned long long rdrop;
    5.85 +	/* Transmitted */
    5.86 +	unsigned long long tbytes;
    5.87 +	unsigned long long tpackets;
    5.88 +	unsigned long long terrs;
    5.89 +	unsigned long long tdrop;
    5.90 +};
    5.91 +
    5.92 +struct xenstat_vbd {
    5.93 +       unsigned int dev;
    5.94 +       unsigned long long oo_reqs;
    5.95 +       unsigned long long rd_reqs;
    5.96 +       unsigned long long wr_reqs;
    5.97 +};
    5.98 +
    5.99 +extern int xenstat_collect_networks(xenstat_node * node);
   5.100 +extern void xenstat_uninit_networks(xenstat_handle * handle);
   5.101 +extern int xenstat_collect_vbds(xenstat_node * node);
   5.102 +extern void xenstat_uninit_vbds(xenstat_handle * handle);
   5.103 +
   5.104 +#endif /* XENSTAT_PRIV_H */
     6.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     6.2 +++ b/tools/xenstat/libxenstat/src/xenstat_solaris.c	Fri Feb 23 10:47:55 2007 +0000
     6.3 @@ -0,0 +1,431 @@
     6.4 +/* libxenstat: statistics-collection library for Xen
     6.5 + *
     6.6 + * This library is free software; you can redistribute it and/or
     6.7 + * modify it under the terms of the GNU Lesser General Public
     6.8 + * License as published by the Free Software Foundation; either
     6.9 + * version 2.1 of the License, or (at your option) any later version.
    6.10 + *
    6.11 + * This library is distributed in the hope that it will be useful,
    6.12 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
    6.13 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
    6.14 + * Lesser General Public License for more details.
    6.15 + */
    6.16 +
    6.17 +/*
    6.18 + * Copyright 2007 Sun Microsystems, Inc.  All rights reserved.
    6.19 + * Use is subject to license terms.
    6.20 + */
    6.21 +
    6.22 +#include <strings.h>
    6.23 +#include <string.h>
    6.24 +#include <stdlib.h>
    6.25 +#include <stdio.h>
    6.26 +#include <ctype.h>
    6.27 +#include <kstat.h>
    6.28 +
    6.29 +#include "xenstat_priv.h"
    6.30 +
    6.31 +#define DEVICE_NIC 1
    6.32 +#define DEVICE_XDB 2
    6.33 +
    6.34 +typedef struct stdevice {
    6.35 +	int domid;
    6.36 +	int used;
    6.37 +	int type;
    6.38 +	char name[256];
    6.39 +	int instance;
    6.40 +	uint64_t stats[2][8];
    6.41 +	struct stdevice *next;
    6.42 +} stdevice_t;
    6.43 +
    6.44 +typedef struct priv_data {
    6.45 +	kstat_ctl_t *kc;
    6.46 +	stdevice_t *devs;
    6.47 +} priv_data_t;
    6.48 +
    6.49 +static priv_data_t *get_priv_data(xenstat_handle *handle)
    6.50 +{
    6.51 +	priv_data_t *priv = handle->priv;
    6.52 +
    6.53 +	if (priv == NULL) {
    6.54 +		priv = malloc(sizeof (priv_data_t));
    6.55 +		if (priv == NULL)
    6.56 +			return NULL;
    6.57 +		priv->devs = NULL;
    6.58 +		priv->kc = NULL;
    6.59 +	}
    6.60 +
    6.61 +	if (priv->kc == NULL) {
    6.62 +		if ((priv->kc = kstat_open()) == NULL) {
    6.63 +			free(priv);
    6.64 +			return NULL;
    6.65 +		}
    6.66 +	}
    6.67 +
    6.68 +	handle->priv = priv;
    6.69 +	return handle->priv;
    6.70 +}
    6.71 +
    6.72 +static int kstat_get(kstat_t *ksp, const char *name, uint64_t *val)
    6.73 +{
    6.74 +	kstat_named_t *ksn = kstat_data_lookup(ksp, (char *)name);
    6.75 +	if (ksn == NULL)
    6.76 +		return 0;
    6.77 +	*val = ksn->value.ui64;
    6.78 +	return 1;
    6.79 +}
    6.80 +
    6.81 +static void gc_devs(priv_data_t *priv, int type)
    6.82 +{
    6.83 +	stdevice_t *start = NULL;
    6.84 +	stdevice_t *dev;
    6.85 +	stdevice_t *tmp;
    6.86 +
    6.87 +	for (dev = priv->devs; dev != NULL; dev = tmp) {
    6.88 +		tmp = dev->next;
    6.89 +
    6.90 +		if (dev->used || dev->type != type) {
    6.91 +			dev->next = start;
    6.92 +			start = dev;
    6.93 +		} else {
    6.94 +			free(dev);
    6.95 +		}
    6.96 +	}
    6.97 +
    6.98 +	priv->devs = start;
    6.99 +}
   6.100 +
   6.101 +static void xenstat_uninit_devs(xenstat_handle *handle, int type)
   6.102 +{
   6.103 +	priv_data_t *priv = get_priv_data(handle);
   6.104 +	stdevice_t *dev;
   6.105 +
   6.106 +	if (priv == NULL)
   6.107 +		return;
   6.108 +
   6.109 +	for (dev = priv->devs; dev != NULL; dev = dev->next)
   6.110 +		dev->used = 0;
   6.111 +
   6.112 +	gc_devs(priv, type);
   6.113 +
   6.114 +	if (priv->kc != NULL)
   6.115 +	 	kstat_close(priv->kc);
   6.116 +	priv->kc = NULL;
   6.117 +}
   6.118 +
   6.119 +static int parse_nic(const char *nic, char *module, int *instance)
   6.120 +{
   6.121 +	const char *c;
   6.122 +
   6.123 +	for (c = &nic[strlen(nic) - 1]; c != nic && isdigit(*c); c--)
   6.124 +		;
   6.125 +
   6.126 +	if (c == nic)
   6.127 +		return 0;
   6.128 +
   6.129 +	c++;
   6.130 +
   6.131 +	if (sscanf(c, "%d", instance) != 1)
   6.132 +		return 0;
   6.133 +
   6.134 +	strncpy(module, nic, c - nic);
   6.135 +	module[c - nic] = '\0';
   6.136 +	return 1;
   6.137 +}
   6.138 +
   6.139 +static int update_dev_stats(priv_data_t *priv, stdevice_t *dev)
   6.140 +{
   6.141 +	char mod[256];
   6.142 +	const char *name;
   6.143 +	int inst;
   6.144 +	kstat_t *ksp;
   6.145 +
   6.146 +	if (dev->type == DEVICE_NIC) {
   6.147 +		if (!parse_nic(dev->name, mod, &inst))
   6.148 +			return 0;
   6.149 +		name = "mac";
   6.150 +	} else {
   6.151 +		strcpy(mod, "xdb");
   6.152 +		inst = dev->instance;
   6.153 +		name = "req_statistics";
   6.154 +	}
   6.155 +
   6.156 +	if (kstat_chain_update(priv->kc) == -1)
   6.157 +		return 0;
   6.158 +
   6.159 +	ksp = kstat_lookup(priv->kc, mod, inst, (char *)name);
   6.160 +	if (ksp == NULL)
   6.161 +		return 0;
   6.162 +	if (kstat_read(priv->kc, ksp, NULL) == -1)
   6.163 +		return 0;
   6.164 +
   6.165 +	dev->used = 1;
   6.166 +
   6.167 +	bcopy(&(dev->stats[1][0]), &(dev->stats[0][0]), sizeof(dev->stats[0]));
   6.168 +
   6.169 +	if (dev->type == DEVICE_NIC) {
   6.170 +		if (!kstat_get(ksp, "rbytes64", &dev->stats[1][0]) ||
   6.171 +		    !kstat_get(ksp, "ipackets64", &dev->stats[1][1]) ||
   6.172 +		    !kstat_get(ksp, "ierrors", &dev->stats[1][2]) ||
   6.173 +		    !kstat_get(ksp, "obytes64", &dev->stats[1][3]) ||
   6.174 +		    !kstat_get(ksp, "opackets64", &dev->stats[1][4]) ||
   6.175 +		    !kstat_get(ksp, "oerrors", &dev->stats[1][5]))
   6.176 +			return 0;
   6.177 +
   6.178 +		dev->stats[1][6] = 0;
   6.179 +		dev->stats[1][7] = 0;
   6.180 +	} else {
   6.181 +		if (!kstat_get(ksp, "rd_reqs", &dev->stats[1][0]) ||
   6.182 +		    !kstat_get(ksp, "wr_reqs", &dev->stats[1][1]) ||
   6.183 +		    !kstat_get(ksp, "oo_reqs", &dev->stats[1][2]))
   6.184 +			return 0;
   6.185 +	}
   6.186 +
   6.187 +	return 1;
   6.188 +}
   6.189 +
   6.190 +static int init_dev(priv_data_t *priv, int type, const char *name,
   6.191 +    int instance, int domid)
   6.192 +{
   6.193 +	stdevice_t *dev;
   6.194 +
   6.195 +	if (!(dev = malloc(sizeof(*dev))))
   6.196 +		return 0;
   6.197 +
   6.198 +	bzero(dev, sizeof(*dev));
   6.199 +	dev->type = type;
   6.200 +	if (name != NULL)
   6.201 +		strcpy(dev->name, name);
   6.202 +	dev->instance = instance;
   6.203 +	dev->domid = domid;
   6.204 +	dev->next = priv->devs;
   6.205 +	priv->devs = dev;
   6.206 +
   6.207 +	/*
   6.208 +	 * Update twice to avoid delta-since-boot.
   6.209 +	 */
   6.210 +	if (!update_dev_stats(priv, dev))
   6.211 +		return 0;
   6.212 +	return update_dev_stats(priv, dev);
   6.213 +}
   6.214 +
   6.215 +static int update_nic(priv_data_t *priv, xenstat_domain *dom,
   6.216 +    xenstat_network *net, const char *name)
   6.217 +{
   6.218 +	stdevice_t *dev;
   6.219 +
   6.220 +	for (dev = priv->devs; dev != NULL; dev = dev->next) {
   6.221 +		if (dev->type == DEVICE_NIC && dev->domid == dom->id &&
   6.222 +		    strcmp(name, dev->name) == 0) {
   6.223 +			if (!update_dev_stats(priv, dev))
   6.224 +				return 0;
   6.225 +			net->rbytes = dev->stats[1][0] - dev->stats[0][0];
   6.226 +			net->rpackets = dev->stats[1][1] - dev->stats[0][1];
   6.227 +			net->rerrs = dev->stats[1][2] - dev->stats[0][2];
   6.228 +			net->tbytes = dev->stats[1][3] - dev->stats[0][3];
   6.229 +			net->tpackets = dev->stats[1][4] - dev->stats[0][4];
   6.230 +			net->terrs = dev->stats[1][5] - dev->stats[0][5];
   6.231 +			net->rdrop = dev->stats[1][6] - dev->stats[0][6];
   6.232 +			net->tdrop = dev->stats[1][7] - dev->stats[0][7];
   6.233 +			return 1;
   6.234 +		}
   6.235 +	}
   6.236 +
   6.237 +	return init_dev(priv, DEVICE_NIC, name, 0, dom->id);
   6.238 +}
   6.239 +
   6.240 +static int
   6.241 +collect_dom_networks(xenstat_node *node, priv_data_t *priv, xenstat_domain *dom)
   6.242 +{
   6.243 +	char path[PATH_MAX];
   6.244 +	char **vifs;
   6.245 +	int ret = 1;
   6.246 +	int nr;
   6.247 +	int i;
   6.248 +
   6.249 +	snprintf(path, sizeof(path), "/local/domain/%d/device/vif", dom->id);
   6.250 +	
   6.251 +	dom->num_networks = 0;
   6.252 +	free(dom->networks);
   6.253 +	dom->networks = NULL;
   6.254 +
   6.255 +	vifs = xs_directory(node->handle->xshandle, XBT_NULL, path, &nr);
   6.256 +	if (vifs == NULL)
   6.257 +		goto out;
   6.258 +
   6.259 +	dom->num_networks = nr;
   6.260 +	dom->networks = calloc(nr, sizeof(xenstat_network));
   6.261 +
   6.262 +	for (i = 0; i < dom->num_networks; i++) {
   6.263 +		char *tmp;
   6.264 +
   6.265 +		snprintf(path, sizeof(path),
   6.266 +		    "/local/domain/%d/device/vif/%d/backend", dom->id, i);
   6.267 +
   6.268 +		tmp = xs_read(node->handle->xshandle, XBT_NULL, path, NULL);
   6.269 +
   6.270 +		if (tmp == NULL)
   6.271 +			goto out;
   6.272 +
   6.273 +		snprintf(path, sizeof(path), "%s/nic", tmp);
   6.274 +		free(tmp);
   6.275 +	
   6.276 +		tmp = xs_read(node->handle->xshandle, XBT_NULL, path, NULL);
   6.277 +
   6.278 +		if (tmp == NULL || tmp[0] == '\0') {
   6.279 +			free(tmp);
   6.280 +			goto out;
   6.281 +		}
   6.282 +
   6.283 +		if (!(ret = update_nic(priv, dom, &dom->networks[i], tmp))) {
   6.284 +			free(tmp);
   6.285 +			goto out;
   6.286 +		}
   6.287 +
   6.288 +		free(tmp);
   6.289 +	}
   6.290 +
   6.291 +	ret = 1;
   6.292 +out:
   6.293 +	free(vifs);
   6.294 +	return ret;
   6.295 +}
   6.296 +
   6.297 +int xenstat_collect_networks(xenstat_node * node)
   6.298 +{
   6.299 +	int i;
   6.300 +	priv_data_t *priv = get_priv_data(node->handle);
   6.301 +	stdevice_t *dev;
   6.302 +
   6.303 +	if (priv == NULL)
   6.304 +		return 0;
   6.305 +
   6.306 +	for (dev = priv->devs; dev != NULL; dev = dev->next)
   6.307 +		dev->used = 0;
   6.308 +
   6.309 +	for (i = 0; i < node->num_domains; i++) {
   6.310 +		if (node->domains[i].id == 0)
   6.311 +			continue;
   6.312 +		if (!collect_dom_networks(node, priv, &node->domains[i]))
   6.313 +			return 0;
   6.314 +	}
   6.315 +
   6.316 +	gc_devs(priv, DEVICE_NIC);
   6.317 +
   6.318 +	return 1;
   6.319 +}
   6.320 +
   6.321 +void xenstat_uninit_networks(xenstat_handle *handle)
   6.322 +{
   6.323 +	xenstat_uninit_devs(handle, DEVICE_NIC);
   6.324 +}
   6.325 +
   6.326 +static int update_xdb(priv_data_t *priv, xenstat_domain *dom,
   6.327 +    xenstat_vbd *vbd, int instance)
   6.328 +{
   6.329 +	stdevice_t *dev;
   6.330 +
   6.331 +	for (dev = priv->devs; dev != NULL; dev = dev->next) {
   6.332 +		if (dev->type == DEVICE_XDB && dev->domid == dom->id &&
   6.333 +		    dev->instance == instance) {
   6.334 +			if (!update_dev_stats(priv, dev))
   6.335 +				return 0;
   6.336 +			vbd->dev = dev->instance;
   6.337 +			vbd->rd_reqs = dev->stats[1][0] - dev->stats[0][0];
   6.338 +			vbd->wr_reqs = dev->stats[1][1] - dev->stats[0][1];
   6.339 +			vbd->oo_reqs = dev->stats[1][2] - dev->stats[0][2];
   6.340 +			return 1;
   6.341 +		}
   6.342 +	}
   6.343 +
   6.344 +	return init_dev(priv, DEVICE_XDB, NULL, instance, dom->id);
   6.345 +}
   6.346 +
   6.347 +static int
   6.348 +collect_dom_vbds(xenstat_node *node, priv_data_t *priv, xenstat_domain *dom)
   6.349 +{
   6.350 +	char path[PATH_MAX];
   6.351 +	char **vbds;
   6.352 +	int ret = 1;
   6.353 +	int nr;
   6.354 +	int i;
   6.355 +
   6.356 +	snprintf(path, sizeof(path), "/local/domain/%d/device/vbd", dom->id);
   6.357 +	
   6.358 +	dom->num_vbds = 0;
   6.359 +	free(dom->vbds);
   6.360 +	dom->vbds = NULL;
   6.361 +
   6.362 +	vbds = xs_directory(node->handle->xshandle, XBT_NULL, path, &nr);
   6.363 +	if (vbds == NULL)
   6.364 +		goto out;
   6.365 +
   6.366 +	dom->num_vbds = nr;
   6.367 +	dom->vbds = calloc(nr, sizeof(xenstat_vbd));
   6.368 +
   6.369 +	for (i = 0; i < dom->num_vbds; i++) {
   6.370 +		char *tmp;
   6.371 +		int inst;
   6.372 +
   6.373 +		snprintf(path, sizeof(path),
   6.374 +		    "/local/domain/%d/device/vbd/%s/backend", dom->id, vbds[i]);
   6.375 +
   6.376 +		tmp = xs_read(node->handle->xshandle, XBT_NULL, path, NULL);
   6.377 +
   6.378 +		if (tmp == NULL)
   6.379 +			goto out;
   6.380 +
   6.381 +		snprintf(path, sizeof(path), "%s/instance", tmp);
   6.382 +		free(tmp);
   6.383 +	
   6.384 +		tmp = xs_read(node->handle->xshandle, XBT_NULL, path, NULL);
   6.385 +
   6.386 +		/*
   6.387 +		 * Fails when connection is not completed; mark it clearly with
   6.388 +		 * a -1.
   6.389 +		 */
   6.390 +		if (tmp == NULL || sscanf(tmp, "%d", &inst) != 1) {
   6.391 +			dom->vbds[i].dev = -1;
   6.392 +			free(tmp);
   6.393 +			goto out;
   6.394 +		}
   6.395 +
   6.396 +		free(tmp);
   6.397 +
   6.398 +		if (!(ret = update_xdb(priv, dom, &dom->vbds[i], inst)))
   6.399 +			goto out;
   6.400 +	}
   6.401 +
   6.402 +out:
   6.403 +	free(vbds);
   6.404 +	return ret;
   6.405 +}
   6.406 +
   6.407 +int xenstat_collect_vbds(xenstat_node * node)
   6.408 +{
   6.409 +	int i;
   6.410 +	priv_data_t *priv = get_priv_data(node->handle);
   6.411 +	stdevice_t *dev;
   6.412 +
   6.413 +	if (priv == NULL)
   6.414 +		return 0;
   6.415 +
   6.416 +	for (dev = priv->devs; dev != NULL; dev = dev->next)
   6.417 +		dev->used = 0;
   6.418 +
   6.419 +	for (i = 0; i < node->num_domains; i++) {
   6.420 +		if (node->domains[i].id == 0)
   6.421 +			continue;
   6.422 +		if (!collect_dom_vbds(node, priv, &node->domains[i]))
   6.423 +			return 0;
   6.424 +	}
   6.425 +
   6.426 +	gc_devs(priv, DEVICE_XDB);
   6.427 +
   6.428 +	return 1;
   6.429 +}
   6.430 +
   6.431 +void xenstat_uninit_vbds(xenstat_handle * handle)
   6.432 +{
   6.433 +	xenstat_uninit_devs(handle, DEVICE_XDB);
   6.434 +}
     7.1 --- a/tools/xenstat/xentop/xentop.c	Fri Feb 23 10:43:00 2007 +0000
     7.2 +++ b/tools/xenstat/xentop/xentop.c	Fri Feb 23 10:47:55 2007 +0000
     7.3 @@ -50,7 +50,11 @@
     7.4  #define KEY_ESCAPE '\x1B'
     7.5  
     7.6  #ifdef HOST_SunOS
     7.7 -/* Old curses library on Solaris takes non-const strings. */
     7.8 +/* Old curses library on Solaris takes non-const strings. Also, ERR interferes
     7.9 + * with curse's definition.
    7.10 + */
    7.11 +#undef ERR
    7.12 +#define ERR (-1)
    7.13  #define curses_str_t char *
    7.14  #else
    7.15  #define curses_str_t const char *
    7.16 @@ -914,7 +918,7 @@ void do_vbd(xenstat_domain *domain)
    7.17  	for (i=0 ; i< num_vbds; i++) {
    7.18  		vbd = xenstat_domain_vbd(domain,i);
    7.19  				
    7.20 -		print("VBD %4u [%2x:%2x]  OO: %8llu   RD: %8llu   WR: %8llu\n",
    7.21 +		print("VBD %4d [%2x:%2x]  OO: %8llu   RD: %8llu   WR: %8llu\n",
    7.22  		      xenstat_vbd_dev(vbd),
    7.23  		      MAJOR(xenstat_vbd_dev(vbd)), MINOR(xenstat_vbd_dev(vbd)),
    7.24  		      xenstat_vbd_oo_reqs(vbd),