Add support to systat to display zfs arc cache status/info

PR:		195460
Submitted by:	ota
This commit is contained in:
Michael Reifenberger 2015-09-27 09:15:54 +00:00
parent abd7105060
commit 27aa47691e
Notes: svn2git 2020-12-20 02:59:44 +00:00
svn path=/head/; revision=288306
7 changed files with 272 additions and 3 deletions

View File

@ -6,7 +6,7 @@
PROG= systat PROG= systat
SRCS= cmds.c cmdtab.c devs.c fetch.c iostat.c keyboard.c main.c \ SRCS= cmds.c cmdtab.c devs.c fetch.c iostat.c keyboard.c main.c \
netcmds.c netstat.c pigs.c swap.c icmp.c \ netcmds.c netstat.c pigs.c swap.c icmp.c \
mode.c ip.c tcp.c \ mode.c ip.c tcp.c zarc.c \
vmstat.c convtbl.c ifcmds.c ifstat.c vmstat.c convtbl.c ifcmds.c ifstat.c
.if ${MK_INET6_SUPPORT} != "no" .if ${MK_INET6_SUPPORT} != "no"

View File

@ -75,6 +75,9 @@ struct cmdtab cmdtab[] = {
{ "ifstat", showifstat, fetchifstat, labelifstat, { "ifstat", showifstat, fetchifstat, labelifstat,
initifstat, openifstat, closeifstat, cmdifstat, initifstat, openifstat, closeifstat, cmdifstat,
0, CF_LOADAV }, 0, CF_LOADAV },
{ "zarc", showzarc, fetchzarc, labelzarc,
initzarc, openzarc, closezarc, 0,
resetzarc, CF_ZFSARC },
{ NULL, NULL, NULL, NULL, NULL, NULL, NULL, 0, 0, 0 } { NULL, NULL, NULL, NULL, NULL, NULL, NULL, 0, 0, 0 }
}; };
struct cmdtab *curcmd = &cmdtab[0]; struct cmdtab *curcmd = &cmdtab[0];

View File

@ -163,3 +163,14 @@ void showtcp(void);
void status(void); void status(void);
void suspend(int); void suspend(int);
char *sysctl_dynread(const char *, size_t *); char *sysctl_dynread(const char *, size_t *);
#define SYSTAT_CMD(name) \
void close ## name(WINDOW *); \
void fetch ## name(void); \
int init ## name(void); \
void label ## name(void); \
WINDOW *open ## name(void); \
void reset ## name(void); \
void show ## name(void)
SYSTAT_CMD( zarc );

View File

@ -243,6 +243,11 @@ labels(void)
"/0 /1 /2 /3 /4 /5 /6 /7 /8 /9 /10"); "/0 /1 /2 /3 /4 /5 /6 /7 /8 /9 /10");
mvaddstr(1, 5, "Load Average"); mvaddstr(1, 5, "Load Average");
} }
if (curcmd->c_flags & CF_ZFSARC) {
mvaddstr(0, 20,
" Total MFU MRU Anon Hdr L2Hdr Other");
mvaddstr(1, 5, "ZFS ARC ");
}
(*curcmd->c_label)(); (*curcmd->c_label)();
#ifdef notdef #ifdef notdef
mvprintw(21, 25, "CPU usage on %s", hostname); mvprintw(21, 25, "CPU usage on %s", hostname);
@ -276,8 +281,33 @@ display(void)
if (j > 50) if (j > 50)
wprintw(wload, " %4.1f", avenrun[0]); wprintw(wload, " %4.1f", avenrun[0]);
} }
if (curcmd->c_flags & CF_ZFSARC) {
uint64_t arc[7] = {};
size_t size = sizeof(arc[0]);
if (sysctlbyname("kstat.zfs.misc.arcstats.size",
&arc[0], &size, NULL, 0) == 0 ) {
GETSYSCTL("vfs.zfs.mfu_size", arc[1]);
GETSYSCTL("vfs.zfs.mru_size", arc[2]);
GETSYSCTL("vfs.zfs.anon_size", arc[3]);
GETSYSCTL("kstat.zfs.misc.arcstats.hdr_size", arc[4]);
GETSYSCTL("kstat.zfs.misc.arcstats.l2_hdr_size", arc[5]);
GETSYSCTL("kstat.zfs.misc.arcstats.other_size", arc[6]);
wmove(wload, 0, 0); wclrtoeol(wload);
for (i = 0 ; i < sizeof(arc) / sizeof(arc[0]) ; i++) {
if (arc[i] > 10llu * 1024 * 1024 * 1024 ) {
wprintw(wload, "%7lluG", arc[i] >> 30);
}
else if (arc[i] > 10 * 1024 * 1024 ) {
wprintw(wload, "%7lluM", arc[i] >> 20);
}
else {
wprintw(wload, "%7lluK", arc[i] >> 10);
}
}
}
}
(*curcmd->c_refresh)(); (*curcmd->c_refresh)();
if (curcmd->c_flags & CF_LOADAV) if (curcmd->c_flags & (CF_LOADAV |CF_ZFSARC))
wrefresh(wload); wrefresh(wload);
wrefresh(wnd); wrefresh(wnd);
move(CMDLINE, col); move(CMDLINE, col);

View File

@ -98,8 +98,9 @@ to be one of:
.Ic pigs , .Ic pigs ,
.Ic swap , .Ic swap ,
.Ic tcp , .Ic tcp ,
.Ic vmstat ,
or or
.Ic vmstat . .Ic zarc ,
These displays can also be requested interactively (without the These displays can also be requested interactively (without the
.Dq Fl ) .Dq Fl )
and are described in and are described in
@ -441,6 +442,8 @@ Display statistics averaged over the refresh interval (the default).
.It Cm zero .It Cm zero
Reset running statistics to zero. Reset running statistics to zero.
.El .El
.It Ic zarc
display arc cache usage and hit/miss statistics.
.It Ic netstat .It Ic netstat
Display, in the lower window, network connections. Display, in the lower window, network connections.
By default, By default,

View File

@ -54,6 +54,7 @@ extern int use_kvm;
#define CF_INIT 0x1 /* been initialized */ #define CF_INIT 0x1 /* been initialized */
#define CF_LOADAV 0x2 /* display w/ load average */ #define CF_LOADAV 0x2 /* display w/ load average */
#define CF_ZFSARC 0x4 /* display w/ ZFS cache usage */
#define TCP 0x1 #define TCP 0x1
#define UDP 0x2 #define UDP 0x2

221
usr.bin/systat/zarc.c Normal file
View File

@ -0,0 +1,221 @@
/*-
* Copyright (c) 2014
* The Regents of the University of California. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 4. Neither the name of the University nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/
#include <sys/cdefs.h>
__FBSDID("$FreeBSD$");
#include <sys/types.h>
#include <sys/sysctl.h>
#include <string.h>
#include "systat.h"
#include "extern.h"
struct zfield{
uint64_t arcstats;
uint64_t arcstats_demand_data;
uint64_t arcstats_demand_metadata;
uint64_t arcstats_prefetch_data;
uint64_t arcstats_prefetch_metadata;
uint64_t zfetchstats;
uint64_t arcstats_l2;
uint64_t vdev_cache_stats;
};
static struct zarcstats {
struct zfield hits;
struct zfield misses;
} curstat, initstat, oldstat;
static void
getinfo(struct zarcstats *ls);
WINDOW *
openzarc(void)
{
return (subwin(stdscr, LINES-3-1, 0, MAINWIN_ROW, 0));
}
void
closezarc(WINDOW *w)
{
if (w == NULL)
return;
wclear(w);
wrefresh(w);
delwin(w);
}
void
labelzarc(void)
{
wmove(wnd, 0, 0); wclrtoeol(wnd);
mvwprintw(wnd, 0, 31+1, "%4.4s %7.7s %7.7s %12.12s %12.12s",
"rate", "hits", "misses", "total hits", "total misses");
#define L(row, str) mvwprintw(wnd, row, 5, str); \
mvwprintw(wnd, row, 31, ":"); \
mvwprintw(wnd, row, 31+4, "%%")
L(1, "arcstats");
L(2, "arcstats.demand_data");
L(3, "arcstats.demand_metadata");
L(4, "arcstats.prefetch_data");
L(5, "arcstats.prefetch_metadata");
L(6, "zfetchstats");
L(7, "arcstats.l2");
L(8, "vdev_cache_stats");
#undef L
}
static int calc(uint64_t hits, uint64_t misses)
{
if( hits )
return 100 * hits / ( hits + misses );
else
return 0;
}
static void
domode(struct zarcstats *delta, struct zarcstats *rate)
{
#define DO(stat) \
delta->hits.stat = (curstat.hits.stat - oldstat.hits.stat); \
delta->misses.stat = (curstat.misses.stat - oldstat.misses.stat); \
rate->hits.stat = calc(delta->hits.stat, delta->misses.stat)
DO(arcstats);
DO(arcstats_demand_data);
DO(arcstats_demand_metadata);
DO(arcstats_prefetch_data);
DO(arcstats_prefetch_metadata);
DO(zfetchstats);
DO(arcstats_l2);
DO(vdev_cache_stats);
DO(arcstats);
DO(arcstats_demand_data);
DO(arcstats_demand_metadata);
DO(arcstats_prefetch_data);
DO(arcstats_prefetch_metadata);
DO(zfetchstats);
DO(arcstats_l2);
DO(vdev_cache_stats);
#undef DO
}
void
showzarc(void)
{
struct zarcstats delta, rate;
memset(&delta, 0, sizeof delta);
memset(&rate, 0, sizeof rate);
domode(&delta, &rate);
#define DO(stat, row, col, fmt) \
mvwprintw(wnd, row, col, fmt, stat)
#define R(row, stat) DO(rate.hits.stat, row, 31+1, "%3lu")
#define H(row, stat) DO(delta.hits.stat, row, 31+1+5, "%7lu"); \
DO(curstat.hits.stat, row, 31+1+5+8+8, "%12lu")
#define M(row, stat) DO(delta.misses.stat, row, 31+1+5+8, "%7lu"); \
DO(curstat.misses.stat, row, 31+1+5+8+8+13, "%12lu")
#define E(row, stat) R(row, stat); H(row, stat); M(row, stat);
E(1, arcstats);
E(2, arcstats_demand_data);
E(3, arcstats_demand_metadata);
E(4, arcstats_prefetch_data);
E(5, arcstats_prefetch_metadata);
E(6, zfetchstats);
E(7, arcstats_l2);
E(8, vdev_cache_stats);
#undef DO
#undef E
#undef M
#undef H
#undef R
}
int
initzarc(void)
{
getinfo(&initstat);
curstat = oldstat = initstat;
return 1;
}
void
resetzarc(void)
{
initzarc();
}
static void
getinfo(struct zarcstats *ls)
{
size_t size = sizeof( ls->hits.arcstats );
if ( sysctlbyname("kstat.zfs.misc.arcstats.hits",
&ls->hits.arcstats, &size, NULL, 0 ) != 0 )
return;
GETSYSCTL("kstat.zfs.misc.arcstats.misses",
ls->misses.arcstats);
GETSYSCTL("kstat.zfs.misc.arcstats.demand_data_hits",
ls->hits.arcstats_demand_data);
GETSYSCTL("kstat.zfs.misc.arcstats.demand_data_misses",
ls->misses.arcstats_demand_data);
GETSYSCTL("kstat.zfs.misc.arcstats.demand_metadata_hits",
ls->hits.arcstats_demand_metadata);
GETSYSCTL("kstat.zfs.misc.arcstats.demand_metadata_misses",
ls->misses.arcstats_demand_metadata);
GETSYSCTL("kstat.zfs.misc.arcstats.prefetch_data_hits",
ls->hits.arcstats_prefetch_data);
GETSYSCTL("kstat.zfs.misc.arcstats.prefetch_data_misses",
ls->misses.arcstats_prefetch_data);
GETSYSCTL("kstat.zfs.misc.arcstats.prefetch_metadata_hits",
ls->hits.arcstats_prefetch_metadata);
GETSYSCTL("kstat.zfs.misc.arcstats.prefetch_metadata_misses",
ls->misses.arcstats_prefetch_metadata);
GETSYSCTL("kstat.zfs.misc.zfetchstats.hits",
ls->hits.zfetchstats);
GETSYSCTL("kstat.zfs.misc.zfetchstats.misses",
ls->misses.zfetchstats);
GETSYSCTL("kstat.zfs.misc.arcstats.l2_hits",
ls->hits.arcstats_l2);
GETSYSCTL("kstat.zfs.misc.arcstats.l2_misses",
ls->misses.arcstats_l2);
GETSYSCTL("kstat.zfs.misc.vdev_cache_stats.hits",
ls->hits.vdev_cache_stats);
GETSYSCTL("kstat.zfs.misc.vdev_cache_stats.misses",
ls->misses.vdev_cache_stats);
}
void
fetchzarc(void)
{
oldstat = curstat;
getinfo(&curstat);
}