Changeset View
Changeset View
Standalone View
Standalone View
head/usr.bin/systat/devs.c
/*- | /*- | ||||
* SPDX-License-Identifier: BSD-3-Clause | * SPDX-License-Identifier: BSD-3-Clause | ||||
* | * | ||||
* Copyright (c) 1998 Kenneth D. Merry. | * Copyright (c) 1998 Kenneth D. Merry. | ||||
* 2015 Yoshihiro Ota | |||||
* All rights reserved. | * All rights reserved. | ||||
* | * | ||||
* Redistribution and use in source and binary forms, with or without | * Redistribution and use in source and binary forms, with or without | ||||
* modification, are permitted provided that the following conditions | * modification, are permitted provided that the following conditions | ||||
* are met: | * are met: | ||||
* 1. Redistributions of source code must retain the above copyright | * 1. Redistributions of source code must retain the above copyright | ||||
* notice, this list of conditions and the following disclaimer. | * notice, this list of conditions and the following disclaimer. | ||||
* 2. Redistributions in binary form must reproduce the above copyright | * 2. Redistributions in binary form must reproduce the above copyright | ||||
▲ Show 20 Lines • Show All 51 Lines • ▼ Show 20 Lines | |||||
static const char sccsid[] = "@(#)disks.c 8.1 (Berkeley) 6/6/93"; | static const char sccsid[] = "@(#)disks.c 8.1 (Berkeley) 6/6/93"; | ||||
#endif | #endif | ||||
#include <sys/types.h> | #include <sys/types.h> | ||||
#include <sys/devicestat.h> | #include <sys/devicestat.h> | ||||
#include <sys/resource.h> | #include <sys/resource.h> | ||||
#include <ctype.h> | #include <ctype.h> | ||||
#include <devstat.h> | |||||
#include <err.h> | #include <err.h> | ||||
#include <stdlib.h> | #include <stdlib.h> | ||||
#include <string.h> | #include <string.h> | ||||
#include "systat.h" | #include "systat.h" | ||||
#include "extern.h" | #include "extern.h" | ||||
#include "devs.h" | #include "devs.h" | ||||
typedef enum { | typedef enum { | ||||
DS_MATCHTYPE_NONE, | DS_MATCHTYPE_NONE, | ||||
DS_MATCHTYPE_SPEC, | DS_MATCHTYPE_SPEC, | ||||
DS_MATCHTYPE_PATTERN | DS_MATCHTYPE_PATTERN | ||||
} last_match_type; | } last_match_type; | ||||
struct statinfo cur_dev, last_dev, run_dev; | |||||
last_match_type last_type; | last_match_type last_type; | ||||
struct device_selection *dev_select; | struct device_selection *dev_select; | ||||
long generation; | long generation; | ||||
int num_devices, num_selected; | int num_devices, num_selected; | ||||
int num_selections; | int num_selections; | ||||
long select_generation; | long select_generation; | ||||
struct devstat_match *matches = NULL; | struct devstat_match *matches = NULL; | ||||
int num_matches = 0; | int num_matches = 0; | ||||
char **specified_devices; | char **specified_devices; | ||||
int num_devices_specified = 0; | int num_devices_specified = 0; | ||||
static int dsmatchselect(const char *args, devstat_select_mode select_mode, | static int dsmatchselect(const char *args, devstat_select_mode select_mode, | ||||
int maxshowdevs, struct statinfo *s1); | int maxshowdevs, struct statinfo *s1); | ||||
static int dsselect(const char *args, devstat_select_mode select_mode, | static int dsselect(const char *args, devstat_select_mode select_mode, | ||||
int maxshowdevs, struct statinfo *s1); | int maxshowdevs, struct statinfo *s1); | ||||
int | int | ||||
dsinit(int maxshowdevs, struct statinfo *s1, struct statinfo *s2 __unused, | dsinit(int maxshowdevs) | ||||
struct statinfo *s3 __unused) | |||||
{ | { | ||||
/* | /* | ||||
* Make sure that the userland devstat version matches the kernel | * Make sure that the userland devstat version matches the kernel | ||||
* devstat version. If not, exit and print a message informing | * devstat version. If not, exit and print a message informing | ||||
* the user of his mistake. | * the user of his mistake. | ||||
*/ | */ | ||||
if (devstat_checkversion(NULL) < 0) | if (devstat_checkversion(NULL) < 0) | ||||
errx(1, "%s", devstat_errbuf); | errx(1, "%s", devstat_errbuf); | ||||
if( cur_dev.dinfo ) // init was alreay ran | |||||
return(1); | |||||
if ((num_devices = devstat_getnumdevs(NULL)) < 0) { | |||||
warnx("%s", devstat_errbuf); | |||||
return(0); | |||||
} | |||||
cur_dev.dinfo = calloc(1, sizeof(struct devinfo)); | |||||
last_dev.dinfo = calloc(1, sizeof(struct devinfo)); | |||||
run_dev.dinfo = calloc(1, sizeof(struct devinfo)); | |||||
generation = 0; | generation = 0; | ||||
num_devices = 0; | num_devices = 0; | ||||
num_selected = 0; | num_selected = 0; | ||||
num_selections = 0; | num_selections = 0; | ||||
select_generation = 0; | select_generation = 0; | ||||
last_type = DS_MATCHTYPE_NONE; | last_type = DS_MATCHTYPE_NONE; | ||||
if (devstat_getdevs(NULL, s1) == -1) | if (devstat_getdevs(NULL, &cur_dev) == -1) | ||||
errx(1, "%s", devstat_errbuf); | errx(1, "%s", devstat_errbuf); | ||||
num_devices = s1->dinfo->numdevs; | num_devices = cur_dev.dinfo->numdevs; | ||||
generation = s1->dinfo->generation; | generation = cur_dev.dinfo->generation; | ||||
dev_select = NULL; | dev_select = NULL; | ||||
/* | /* | ||||
* At this point, selectdevs will almost surely indicate that the | * At this point, selectdevs will almost surely indicate that the | ||||
* device list has changed, so we don't look for return values of 0 | * device list has changed, so we don't look for return values of 0 | ||||
* or 1. If we get back -1, though, there is an error. | * or 1. If we get back -1, though, there is an error. | ||||
*/ | */ | ||||
if (devstat_selectdevs(&dev_select, &num_selected, &num_selections, | if (devstat_selectdevs(&dev_select, &num_selected, &num_selections, | ||||
&select_generation, generation, s1->dinfo->devices, num_devices, | &select_generation, generation, cur_dev.dinfo->devices, num_devices, | ||||
NULL, 0, NULL, 0, DS_SELECT_ADD, maxshowdevs, 0) == -1) | NULL, 0, NULL, 0, DS_SELECT_ADD, maxshowdevs, 0) == -1) | ||||
errx(1, "%d %s", __LINE__, devstat_errbuf); | errx(1, "%d %s", __LINE__, devstat_errbuf); | ||||
return(1); | return(1); | ||||
} | } | ||||
void | |||||
dsgetinfo(struct statinfo* dev) | |||||
{ | |||||
switch (devstat_getdevs(NULL, dev)) { | |||||
case -1: | |||||
errx(1, "%s", devstat_errbuf); | |||||
break; | |||||
case 1: | |||||
num_devices = dev->dinfo->numdevs; | |||||
generation = dev->dinfo->generation; | |||||
cmdkre("refresh", NULL); | |||||
break; | |||||
default: | |||||
break; | |||||
} | |||||
} | |||||
int | int | ||||
dscmd(const char *cmd, const char *args, int maxshowdevs, struct statinfo *s1) | dscmd(const char *cmd, const char *args, int maxshowdevs, struct statinfo *s1) | ||||
{ | { | ||||
int retval; | int retval; | ||||
if (prefix(cmd, "display") || prefix(cmd, "add")) | if (prefix(cmd, "display") || prefix(cmd, "add")) | ||||
return(dsselect(args, DS_SELECT_ADDONLY, maxshowdevs, s1)); | return(dsselect(args, DS_SELECT_ADDONLY, maxshowdevs, s1)); | ||||
if (prefix(cmd, "ignore") || prefix(cmd, "delete")) | if (prefix(cmd, "ignore") || prefix(cmd, "delete")) | ||||
▲ Show 20 Lines • Show All 173 Lines • ▼ Show 20 Lines | retval = devstat_selectdevs(&dev_select, &num_selected, | ||||
specified_devices, num_devices_specified, | specified_devices, num_devices_specified, | ||||
select_mode, maxshowdevs, 0); | select_mode, maxshowdevs, 0); | ||||
if (retval == -1) | if (retval == -1) | ||||
err(1, "%s", devstat_errbuf); | err(1, "%s", devstat_errbuf); | ||||
else if (retval == 1) | else if (retval == 1) | ||||
return(2); | return(2); | ||||
} | } | ||||
return(1); | return(1); | ||||
} | |||||
void | |||||
dslabel(int maxdrives, int diskcol, int diskrow) | |||||
{ | |||||
int i, j; | |||||
mvprintw(diskrow, diskcol, "Disks"); | |||||
mvprintw(diskrow + 1, diskcol, "KB/t"); | |||||
mvprintw(diskrow + 2, diskcol, "tps"); | |||||
mvprintw(diskrow + 3, diskcol, "MB/s"); | |||||
mvprintw(diskrow + 4, diskcol, "%%busy"); | |||||
/* | |||||
* For now, we don't support a fourth disk statistic. So there's | |||||
* no point in providing a label for it. If someone can think of a | |||||
* fourth useful disk statistic, there is room to add it. | |||||
*/ | |||||
/* mvprintw(diskrow + 4, diskcol, " msps"); */ | |||||
j = 0; | |||||
for (i = 0; i < num_devices && j < maxdrives; i++) | |||||
if (dev_select[i].selected) { | |||||
char tmpstr[80]; | |||||
sprintf(tmpstr, "%s%d", dev_select[i].device_name, | |||||
dev_select[i].unit_number); | |||||
mvprintw(diskrow, diskcol + 5 + 6 * j, | |||||
" %5.5s", tmpstr); | |||||
j++; | |||||
} | |||||
} | |||||
static void | |||||
dsshow2(int diskcol, int diskrow, int dn, int lc, struct statinfo *now, struct statinfo *then) | |||||
{ | |||||
long double transfers_per_second; | |||||
long double kb_per_transfer, mb_per_second; | |||||
long double elapsed_time, device_busy; | |||||
int di; | |||||
di = dev_select[dn].position; | |||||
if (then != NULL) { | |||||
/* Calculate relative to previous sample */ | |||||
elapsed_time = now->snap_time - then->snap_time; | |||||
} else { | |||||
/* Calculate relative to device creation */ | |||||
elapsed_time = now->snap_time - devstat_compute_etime( | |||||
&now->dinfo->devices[di].creation_time, NULL); | |||||
} | |||||
if (devstat_compute_statistics(&now->dinfo->devices[di], then ? | |||||
&then->dinfo->devices[di] : NULL, elapsed_time, | |||||
DSM_KB_PER_TRANSFER, &kb_per_transfer, | |||||
DSM_TRANSFERS_PER_SECOND, &transfers_per_second, | |||||
DSM_MB_PER_SECOND, &mb_per_second, | |||||
DSM_BUSY_PCT, &device_busy, | |||||
DSM_NONE) != 0) | |||||
errx(1, "%s", devstat_errbuf); | |||||
lc = diskcol + lc * 6; | |||||
putlongdouble(kb_per_transfer, diskrow + 1, lc, 5, 2, 0); | |||||
putlongdouble(transfers_per_second, diskrow + 2, lc, 5, 0, 0); | |||||
putlongdouble(mb_per_second, diskrow + 3, lc, 5, 2, 0); | |||||
putlongdouble(device_busy, diskrow + 4, lc, 5, 0, 0); | |||||
} | |||||
static void | |||||
dsshow3(int diskcol, int diskrow, int dn, int lc, struct statinfo *now, struct statinfo *then) | |||||
{ | |||||
dsshow2(diskcol, diskrow, dn, lc, now, then); | |||||
} | |||||
void | |||||
dsshow(int maxdrives, int diskcol, int diskrow, struct statinfo *now, struct statinfo *then) | |||||
{ | |||||
int i, lc; | |||||
for (i = 0, lc = 0; i < num_devices && lc < maxdrives; i++) | |||||
if (dev_select[i].selected) | |||||
dsshow3(diskcol, diskrow, i, ++lc, now, then); | |||||
} | } |