Deleted Added
full compact
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 ---