devstat.c (83551) | devstat.c (83868) |
---|---|
1/* 2 * Copyright (c) 1997, 1998 Kenneth D. Merry. 3 * All rights reserved. 4 * 5 * Redistribution and use in source and binary forms, with or without 6 * modification, are permitted provided that the following conditions 7 * are met: 8 * 1. Redistributions of source code must retain the above copyright --- 13 unchanged lines hidden (view full) --- 22 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 23 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 24 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 25 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 26 * SUCH DAMAGE. 27 */ 28 29#include <sys/cdefs.h> | 1/* 2 * Copyright (c) 1997, 1998 Kenneth D. Merry. 3 * All rights reserved. 4 * 5 * Redistribution and use in source and binary forms, with or without 6 * modification, are permitted provided that the following conditions 7 * are met: 8 * 1. Redistributions of source code must retain the above copyright --- 13 unchanged lines hidden (view full) --- 22 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 23 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 24 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 25 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 26 * SUCH DAMAGE. 27 */ 28 29#include <sys/cdefs.h> |
30__FBSDID("$FreeBSD: head/lib/libdevstat/devstat.c 83551 2001-09-16 21:35:07Z dillon $"); | 30__FBSDID("$FreeBSD: head/lib/libdevstat/devstat.c 83868 2001-09-23 23:03:23Z ken $"); |
31 32#include <sys/types.h> 33#include <sys/sysctl.h> 34#include <sys/errno.h> 35#include <sys/dkstat.h> 36#include <sys/queue.h> 37 38#include <ctype.h> --- 71 unchanged lines hidden (view full) --- 110 { DSM_BLOCKS_PER_SECOND_READ, DEVSTAT_ARG_LD }, 111 { DSM_BLOCKS_PER_SECOND_WRITE, DEVSTAT_ARG_LD }, 112 { DSM_MS_PER_TRANSACTION, DEVSTAT_ARG_LD }, 113 { DSM_MS_PER_TRANSACTION_READ, DEVSTAT_ARG_LD }, 114 { DSM_MS_PER_TRANSACTION_WRITE, DEVSTAT_ARG_LD }, 115 { DSM_SKIP, DEVSTAT_ARG_SKIP } 116}; 117 | 31 32#include <sys/types.h> 33#include <sys/sysctl.h> 34#include <sys/errno.h> 35#include <sys/dkstat.h> 36#include <sys/queue.h> 37 38#include <ctype.h> --- 71 unchanged lines hidden (view full) --- 110 { DSM_BLOCKS_PER_SECOND_READ, DEVSTAT_ARG_LD }, 111 { DSM_BLOCKS_PER_SECOND_WRITE, DEVSTAT_ARG_LD }, 112 { DSM_MS_PER_TRANSACTION, DEVSTAT_ARG_LD }, 113 { DSM_MS_PER_TRANSACTION_READ, DEVSTAT_ARG_LD }, 114 { DSM_MS_PER_TRANSACTION_WRITE, DEVSTAT_ARG_LD }, 115 { DSM_SKIP, DEVSTAT_ARG_SKIP } 116}; 117 |
118static char *namelist[] = { | 118static const char *namelist[] = { |
119#define X_NUMDEVS 0 120 "_devstat_num_devs", 121#define X_GENERATION 1 122 "_devstat_generation", 123#define X_VERSION 2 124 "_devstat_version", 125#define X_DEVICE_STATQ 3 126 "_device_statq", 127#define X_END 4 128}; 129 130/* 131 * Local function declarations. 132 */ 133static int compare_select(const void *arg1, const void *arg2); 134static int readkmem(kvm_t *kd, unsigned long addr, void *buf, size_t nbytes); | 119#define X_NUMDEVS 0 120 "_devstat_num_devs", 121#define X_GENERATION 1 122 "_devstat_generation", 123#define X_VERSION 2 124 "_devstat_version", 125#define X_DEVICE_STATQ 3 126 "_device_statq", 127#define X_END 4 128}; 129 130/* 131 * Local function declarations. 132 */ 133static int compare_select(const void *arg1, const void *arg2); 134static int readkmem(kvm_t *kd, unsigned long addr, void *buf, size_t nbytes); |
135static int readkmem_nl(kvm_t *kd, char *name, void *buf, size_t nbytes); | 135static int readkmem_nl(kvm_t *kd, const char *name, void *buf, size_t nbytes); |
136static char *get_devstat_kvm(kvm_t *kd); 137 138#define KREADNL(kd, var, val) \ 139 readkmem_nl(kd, namelist[var], &val, sizeof(val)) 140 141int 142devstat_getnumdevs(kvm_t *kd) 143{ 144 size_t numdevsize; 145 int numdevs; | 136static char *get_devstat_kvm(kvm_t *kd); 137 138#define KREADNL(kd, var, val) \ 139 readkmem_nl(kd, namelist[var], &val, sizeof(val)) 140 141int 142devstat_getnumdevs(kvm_t *kd) 143{ 144 size_t numdevsize; 145 int numdevs; |
146 char *func_name = "devstat_getnumdevs"; | 146 const char *func_name = "devstat_getnumdevs"; |
147 148 numdevsize = sizeof(int); 149 150 /* 151 * Find out how many devices we have in the system. 152 */ 153 if (kd == NULL) { 154 if (sysctlbyname("kern.devstat.numdevs", &numdevs, 155 &numdevsize, NULL, 0) == -1) { 156 snprintf(devstat_errbuf, sizeof(devstat_errbuf), 157 "%s: error getting number of devices\n" 158 "%s: %s", func_name, func_name, 159 strerror(errno)); 160 return(-1); 161 } else 162 return(numdevs); 163 } else { | 147 148 numdevsize = sizeof(int); 149 150 /* 151 * Find out how many devices we have in the system. 152 */ 153 if (kd == NULL) { 154 if (sysctlbyname("kern.devstat.numdevs", &numdevs, 155 &numdevsize, NULL, 0) == -1) { 156 snprintf(devstat_errbuf, sizeof(devstat_errbuf), 157 "%s: error getting number of devices\n" 158 "%s: %s", func_name, func_name, 159 strerror(errno)); 160 return(-1); 161 } else 162 return(numdevs); 163 } else { |
164 |
|
164 if (KREADNL(kd, X_NUMDEVS, numdevs) == -1) 165 return(-1); 166 else 167 return(numdevs); 168 } 169} 170 171/* 172 * This is an easy way to get the generation number, but the generation is 173 * supplied in a more atmoic manner by the kern.devstat.all sysctl. 174 * Because this generation sysctl is separate from the statistics sysctl, 175 * the device list and the generation could change between the time that 176 * this function is called and the device list is retreived. 177 */ 178long 179devstat_getgeneration(kvm_t *kd) 180{ 181 size_t gensize; 182 long generation; | 165 if (KREADNL(kd, X_NUMDEVS, numdevs) == -1) 166 return(-1); 167 else 168 return(numdevs); 169 } 170} 171 172/* 173 * This is an easy way to get the generation number, but the generation is 174 * supplied in a more atmoic manner by the kern.devstat.all sysctl. 175 * Because this generation sysctl is separate from the statistics sysctl, 176 * the device list and the generation could change between the time that 177 * this function is called and the device list is retreived. 178 */ 179long 180devstat_getgeneration(kvm_t *kd) 181{ 182 size_t gensize; 183 long generation; |
183 char *func_name = "devstat_getgeneration"; | 184 const char *func_name = "devstat_getgeneration"; |
184 185 gensize = sizeof(long); 186 187 /* 188 * Get the current generation number. 189 */ 190 if (kd == NULL) { 191 if (sysctlbyname("kern.devstat.generation", &generation, --- 18 unchanged lines hidden (view full) --- 210 * sys/devicestat.h. This will enable userland programs to determine 211 * whether they are out of sync with the kernel. 212 */ 213int 214devstat_getversion(kvm_t *kd) 215{ 216 size_t versize; 217 int version; | 185 186 gensize = sizeof(long); 187 188 /* 189 * Get the current generation number. 190 */ 191 if (kd == NULL) { 192 if (sysctlbyname("kern.devstat.generation", &generation, --- 18 unchanged lines hidden (view full) --- 211 * sys/devicestat.h. This will enable userland programs to determine 212 * whether they are out of sync with the kernel. 213 */ 214int 215devstat_getversion(kvm_t *kd) 216{ 217 size_t versize; 218 int version; |
218 char *func_name = "devstat_getversion"; | 219 const char *func_name = "devstat_getversion"; |
219 220 versize = sizeof(int); 221 222 /* 223 * Get the current devstat version. 224 */ 225 if (kd == NULL) { 226 if (sysctlbyname("kern.devstat.version", &version, &versize, --- 15 unchanged lines hidden (view full) --- 242/* 243 * Check the devstat version we know about against the devstat version the 244 * kernel knows about. If they don't match, print an error into the 245 * devstat error buffer, and return -1. If they match, return 0. 246 */ 247int 248devstat_checkversion(kvm_t *kd) 249{ | 220 221 versize = sizeof(int); 222 223 /* 224 * Get the current devstat version. 225 */ 226 if (kd == NULL) { 227 if (sysctlbyname("kern.devstat.version", &version, &versize, --- 15 unchanged lines hidden (view full) --- 243/* 244 * Check the devstat version we know about against the devstat version the 245 * kernel knows about. If they don't match, print an error into the 246 * devstat error buffer, and return -1. If they match, return 0. 247 */ 248int 249devstat_checkversion(kvm_t *kd) 250{ |
250 char *func_name = "devstat_checkversion"; | 251 const char *func_name = "devstat_checkversion"; |
251 int buflen, res, retval = 0, version; 252 253 version = devstat_getversion(kd); 254 255 if (version != DEVSTAT_VERSION) { 256 /* 257 * If getversion() returns an error (i.e. -1), then it 258 * has printed an error message in the buffer. Therefore, --- 49 unchanged lines hidden (view full) --- 308devstat_getdevs(kvm_t *kd, struct statinfo *stats) 309{ 310 int error; 311 size_t dssize; 312 int oldnumdevs; 313 long oldgeneration; 314 int retval = 0; 315 struct devinfo *dinfo; | 252 int buflen, res, retval = 0, version; 253 254 version = devstat_getversion(kd); 255 256 if (version != DEVSTAT_VERSION) { 257 /* 258 * If getversion() returns an error (i.e. -1), then it 259 * has printed an error message in the buffer. Therefore, --- 49 unchanged lines hidden (view full) --- 309devstat_getdevs(kvm_t *kd, struct statinfo *stats) 310{ 311 int error; 312 size_t dssize; 313 int oldnumdevs; 314 long oldgeneration; 315 int retval = 0; 316 struct devinfo *dinfo; |
316 char *func_name = "devstat_getdevs"; | 317 const char *func_name = "devstat_getdevs"; |
317 318 dinfo = stats->dinfo; 319 320 if (dinfo == NULL) { 321 snprintf(devstat_errbuf, sizeof(devstat_errbuf), 322 "%s: stats->dinfo was NULL", func_name); 323 return(-1); 324 } --- 570 unchanged lines hidden (view full) --- 895 break; 896 } 897 /* 898 * If we get here, then the device at index i in 899 * the current array isn't the same device as the 900 * device at index i in the old array. 901 */ 902 else { | 318 319 dinfo = stats->dinfo; 320 321 if (dinfo == NULL) { 322 snprintf(devstat_errbuf, sizeof(devstat_errbuf), 323 "%s: stats->dinfo was NULL", func_name); 324 return(-1); 325 } --- 570 unchanged lines hidden (view full) --- 896 break; 897 } 898 /* 899 * If we get here, then the device at index i in 900 * the current array isn't the same device as the 901 * device at index i in the old array. 902 */ 903 else { |
903 int found = 0; | 904 found = 0; |
904 905 /* 906 * Search through the old selection array 907 * looking for a device with the same 908 * device number as the device at index i 909 * in the current array. If the selection 910 * status is the same, then we mark it as 911 * found. If the selection status isn't --- 34 unchanged lines hidden (view full) --- 946 * has been selected. If one of them has, and the other one has not, the 947 * selected device is automatically more important than the unselected 948 * device. If neither device is selected, we judge the devices based upon 949 * performance. 950 */ 951static int 952compare_select(const void *arg1, const void *arg2) 953{ | 905 906 /* 907 * Search through the old selection array 908 * looking for a device with the same 909 * device number as the device at index i 910 * in the current array. If the selection 911 * status is the same, then we mark it as 912 * found. If the selection status isn't --- 34 unchanged lines hidden (view full) --- 947 * has been selected. If one of them has, and the other one has not, the 948 * selected device is automatically more important than the unselected 949 * device. If neither device is selected, we judge the devices based upon 950 * performance. 951 */ 952static int 953compare_select(const void *arg1, const void *arg2) 954{ |
954 if ((((struct device_selection *)arg1)->selected) 955 && (((struct device_selection *)arg2)->selected == 0)) | 955 if ((((const struct device_selection *)arg1)->selected) 956 && (((const struct device_selection *)arg2)->selected == 0)) |
956 return(-1); | 957 return(-1); |
957 else if ((((struct device_selection *)arg1)->selected == 0) 958 && (((struct device_selection *)arg2)->selected)) | 958 else if ((((const struct device_selection *)arg1)->selected == 0) 959 && (((const struct device_selection *)arg2)->selected)) |
959 return(1); | 960 return(1); |
960 else if (((struct device_selection *)arg2)->bytes < 961 ((struct device_selection *)arg1)->bytes) | 961 else if (((const struct device_selection *)arg2)->bytes < 962 ((const struct device_selection *)arg1)->bytes) |
962 return(-1); | 963 return(-1); |
963 else if (((struct device_selection *)arg2)->bytes > 964 ((struct device_selection *)arg1)->bytes) | 964 else if (((const struct device_selection *)arg2)->bytes > 965 ((const struct device_selection *)arg1)->bytes) |
965 return(1); 966 else 967 return(0); 968} 969 970/* 971 * Take a string with the general format "arg1,arg2,arg3", and build a 972 * device matching expression from it. 973 */ 974int 975devstat_buildmatch(char *match_str, struct devstat_match **matches, 976 int *num_matches) 977{ 978 char *tstr[5]; 979 char **tempstr; 980 int num_args; 981 register int i, j; | 966 return(1); 967 else 968 return(0); 969} 970 971/* 972 * Take a string with the general format "arg1,arg2,arg3", and build a 973 * device matching expression from it. 974 */ 975int 976devstat_buildmatch(char *match_str, struct devstat_match **matches, 977 int *num_matches) 978{ 979 char *tstr[5]; 980 char **tempstr; 981 int num_args; 982 register int i, j; |
982 char *func_name = "devstat_buildmatch"; | 983 const char *func_name = "devstat_buildmatch"; |
983 984 /* We can't do much without a string to parse */ 985 if (match_str == NULL) { 986 snprintf(devstat_errbuf, sizeof(devstat_errbuf), 987 "%s: no match expression", func_name); 988 return(-1); 989 } 990 --- 167 unchanged lines hidden (view full) --- 1158 1159 return(etime); 1160} 1161 1162int 1163devstat_compute_statistics(struct devstat *current, struct devstat *previous, 1164 long double etime, ...) 1165{ | 984 985 /* We can't do much without a string to parse */ 986 if (match_str == NULL) { 987 snprintf(devstat_errbuf, sizeof(devstat_errbuf), 988 "%s: no match expression", func_name); 989 return(-1); 990 } 991 --- 167 unchanged lines hidden (view full) --- 1159 1160 return(etime); 1161} 1162 1163int 1164devstat_compute_statistics(struct devstat *current, struct devstat *previous, 1165 long double etime, ...) 1166{ |
1166 char *func_name = "devstat_compute_statistics"; | 1167 const char *func_name = "devstat_compute_statistics"; |
1167 u_int64_t totalbytes, totalbytesread, totalbyteswrite; 1168 u_int64_t totaltransfers, totaltransfersread, totaltransferswrite; 1169 u_int64_t totaltransfersother, totalblocks, totalblocksread; 1170 u_int64_t totalblockswrite; 1171 va_list ap; 1172 devstat_metric metric; 1173 u_int64_t *destu64; 1174 long double *destld; --- 270 unchanged lines hidden (view full) --- 1445 1446 va_end(ap); 1447 return(retval); 1448} 1449 1450static int 1451readkmem(kvm_t *kd, unsigned long addr, void *buf, size_t nbytes) 1452{ | 1168 u_int64_t totalbytes, totalbytesread, totalbyteswrite; 1169 u_int64_t totaltransfers, totaltransfersread, totaltransferswrite; 1170 u_int64_t totaltransfersother, totalblocks, totalblocksread; 1171 u_int64_t totalblockswrite; 1172 va_list ap; 1173 devstat_metric metric; 1174 u_int64_t *destu64; 1175 long double *destld; --- 270 unchanged lines hidden (view full) --- 1446 1447 va_end(ap); 1448 return(retval); 1449} 1450 1451static int 1452readkmem(kvm_t *kd, unsigned long addr, void *buf, size_t nbytes) 1453{ |
1453 char *func_name = "readkmem"; | 1454 const char *func_name = "readkmem"; |
1454 1455 if (kvm_read(kd, addr, buf, nbytes) == -1) { 1456 snprintf(devstat_errbuf, sizeof(devstat_errbuf), 1457 "%s: error reading value (kvm_read): %s", func_name, 1458 kvm_geterr(kd)); 1459 return(-1); 1460 } 1461 return(0); 1462} 1463 1464static int | 1455 1456 if (kvm_read(kd, addr, buf, nbytes) == -1) { 1457 snprintf(devstat_errbuf, sizeof(devstat_errbuf), 1458 "%s: error reading value (kvm_read): %s", func_name, 1459 kvm_geterr(kd)); 1460 return(-1); 1461 } 1462 return(0); 1463} 1464 1465static int |
1465readkmem_nl(kvm_t *kd, char *name, void *buf, size_t nbytes) | 1466readkmem_nl(kvm_t *kd, const char *name, void *buf, size_t nbytes) |
1466{ | 1467{ |
1467 char *func_name = "readkmem_nl"; 1468 struct nlist nl[2] = { { name }, { NULL } }; | 1468 const char *func_name = "readkmem_nl"; 1469 struct nlist nl[2]; |
1469 | 1470 |
1471 (const char *)nl[0].n_name = name; 1472 nl[1].n_name = NULL; 1473 |
|
1470 if (kvm_nlist(kd, nl) == -1) { 1471 snprintf(devstat_errbuf, sizeof(devstat_errbuf), 1472 "%s: error getting name list (kvm_nlist): %s", 1473 func_name, kvm_geterr(kd)); 1474 return(-1); 1475 } 1476 return(readkmem(kd, nl[0].n_value, buf, nbytes)); 1477} --- 7 unchanged lines hidden (view full) --- 1485{ 1486 int error, i, wp; 1487 long gen; 1488 struct devstat *nds; 1489 struct devstat ds; 1490 struct devstatlist dhead; 1491 int num_devs; 1492 char *rv = NULL; | 1474 if (kvm_nlist(kd, nl) == -1) { 1475 snprintf(devstat_errbuf, sizeof(devstat_errbuf), 1476 "%s: error getting name list (kvm_nlist): %s", 1477 func_name, kvm_geterr(kd)); 1478 return(-1); 1479 } 1480 return(readkmem(kd, nl[0].n_value, buf, nbytes)); 1481} --- 7 unchanged lines hidden (view full) --- 1489{ 1490 int error, i, wp; 1491 long gen; 1492 struct devstat *nds; 1493 struct devstat ds; 1494 struct devstatlist dhead; 1495 int num_devs; 1496 char *rv = NULL; |
1493 char *func_name = "get_devstat_kvm"; | 1497 const char *func_name = "get_devstat_kvm"; |
1494 1495 if ((num_devs = getnumdevs()) <= 0) 1496 return(NULL); 1497 error = 0; 1498 if (KREADNL(kd, X_DEVICE_STATQ, dhead) == -1) 1499 return(NULL); 1500 1501 nds = STAILQ_FIRST(&dhead); --- 96 unchanged lines hidden --- | 1498 1499 if ((num_devs = getnumdevs()) <= 0) 1500 return(NULL); 1501 error = 0; 1502 if (KREADNL(kd, X_DEVICE_STATQ, dhead) == -1) 1503 return(NULL); 1504 1505 nds = STAILQ_FIRST(&dhead); --- 96 unchanged lines hidden --- |