summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--usr/src/cmd/stat/Makefile2
-rw-r--r--usr/src/cmd/stat/arcstat/Makefile33
-rwxr-xr-xusr/src/cmd/stat/arcstat/arcstat.pl364
-rw-r--r--usr/src/man/man1m/Makefile1
-rw-r--r--usr/src/man/man1m/arcstat.1m467
-rw-r--r--usr/src/pkg/manifests/system-monitoring-arcstat.mf27
6 files changed, 893 insertions, 1 deletions
diff --git a/usr/src/cmd/stat/Makefile b/usr/src/cmd/stat/Makefile
index d5356ae42d..34149b2b37 100644
--- a/usr/src/cmd/stat/Makefile
+++ b/usr/src/cmd/stat/Makefile
@@ -27,7 +27,7 @@
include ../Makefile.cmd
-SUBDIRS= iostat mpstat vmstat fsstat kstat
+SUBDIRS= arcstat iostat mpstat vmstat fsstat kstat
all := TARGET = all
install := TARGET = install
diff --git a/usr/src/cmd/stat/arcstat/Makefile b/usr/src/cmd/stat/arcstat/Makefile
new file mode 100644
index 0000000000..6ae60a8d3d
--- /dev/null
+++ b/usr/src/cmd/stat/arcstat/Makefile
@@ -0,0 +1,33 @@
+#
+# This file and its contents are supplied under the terms of the
+# Common Development and Distribution License ("CDDL"), version 1.0.
+# You may only use this file in accordance with the terms of version
+# 1.0 of the CDDL.
+#
+# A full copy of the text of the CDDL should have accompanied this
+# source. A copy of the CDDL is also available via the Internet at
+# http://www.illumos.org/license/CDDL.
+#
+
+#
+# Copyright 2014 Adam Stevko. All rights reserved.
+#
+
+include $(SRC)/cmd/Makefile.cmd
+
+PROG= arcstat
+
+.KEEP_STATE:
+
+all: $(PROG)
+
+install: all .WAIT $(ROOTPROG)
+
+clean:
+
+$(ROOTBINPROG): $(PROG)
+ $(INS.file)
+
+lint:
+
+include $(SRC)/cmd/Makefile.targ
diff --git a/usr/src/cmd/stat/arcstat/arcstat.pl b/usr/src/cmd/stat/arcstat/arcstat.pl
new file mode 100755
index 0000000000..58491140c4
--- /dev/null
+++ b/usr/src/cmd/stat/arcstat/arcstat.pl
@@ -0,0 +1,364 @@
+#!/usr/perl5/bin/perl -w
+# The above invocation line was changed in 0.5 to allow for
+# interoperability with linux.
+#
+# Print out ZFS ARC Statistics exported via kstat(1)
+# For a definition of fields, or usage, use arctstat.pl -v
+#
+# This script is a fork of the original arcstat.pl (0.1) by
+# Neelakanth Nadgir, originally published on his Sun blog on
+# 09/18/2007
+# http://blogs.sun.com/realneel/entry/zfs_arc_statistics
+#
+# This version aims to improve upon the original by adding features
+# and fixing bugs as needed. This version is maintained by
+# Mike Harsch and is hosted in a public open source repository:
+# http://github.com/mharsch/arcstat
+#
+# Comments, Questions, or Suggestions are always welcome.
+# Contact the maintainer at ( mike at harschsystems dot com )
+#
+# CDDL HEADER START
+#
+# The contents of this file are subject to the terms of the
+# Common Development and Distribution License, Version 1.0 only
+# (the "License"). You may not use this file except in compliance
+# with the License.
+#
+# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+# or http://www.opensolaris.org/os/licensing.
+# See the License for the specific language governing permissions
+# and limitations under the License.
+#
+# When distributing Covered Code, include this CDDL HEADER in each
+# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+# If applicable, add the following below this CDDL HEADER, with the
+# fields enclosed by brackets "[]" replaced with your own identifying
+# information: Portions Copyright [yyyy] [name of copyright owner]
+#
+# CDDL HEADER END
+#
+#
+# Fields have a fixed width. Every interval, we fill the "v"
+# hash with its corresponding value (v[field]=value) using calculate().
+# @hdr is the array of fields that needs to be printed, so we
+# just iterate over this array and print the values using our pretty printer.
+
+use strict;
+use warnings;
+use POSIX qw(strftime);
+use Sun::Solaris::Kstat;
+use Getopt::Long;
+use IO::Handle;
+
+my %cols = (# HDR => [Size, Scale, Description]
+ "time" =>[8, -1, "Time"],
+ "hits" =>[4, 1000, "ARC reads per second"],
+ "miss" =>[4, 1000, "ARC misses per second"],
+ "read" =>[4, 1000, "Total ARC accesses per second"],
+ "hit%" =>[4, 100, "ARC Hit percentage"],
+ "miss%" =>[5, 100, "ARC miss percentage"],
+ "dhit" =>[4, 1000, "Demand Data hits per second"],
+ "dmis" =>[4, 1000, "Demand Data misses per second"],
+ "dh%" =>[3, 100, "Demand Data hit percentage"],
+ "dm%" =>[3, 100, "Demand Data miss percentage"],
+ "phit" =>[4, 1000, "Prefetch hits per second"],
+ "pmis" =>[4, 1000, "Prefetch misses per second"],
+ "ph%" =>[3, 100, "Prefetch hits percentage"],
+ "pm%" =>[3, 100, "Prefetch miss percentage"],
+ "mhit" =>[4, 1000, "Metadata hits per second"],
+ "mmis" =>[4, 1000, "Metadata misses per second"],
+ "mread" =>[4, 1000, "Metadata accesses per second"],
+ "mh%" =>[3, 100, "Metadata hit percentage"],
+ "mm%" =>[3, 100, "Metadata miss percentage"],
+ "arcsz" =>[5, 1024, "ARC Size"],
+ "c" =>[4, 1024, "ARC Target Size"],
+ "mfu" =>[4, 1000, "MFU List hits per second"],
+ "mru" =>[4, 1000, "MRU List hits per second"],
+ "mfug" =>[4, 1000, "MFU Ghost List hits per second"],
+ "mrug" =>[4, 1000, "MRU Ghost List hits per second"],
+ "eskip" =>[5, 1000, "evict_skip per second"],
+ "mtxmis" =>[6, 1000, "mutex_miss per second"],
+ "rmis" =>[4, 1000, "recycle_miss per second"],
+ "dread" =>[5, 1000, "Demand data accesses per second"],
+ "pread" =>[5, 1000, "Prefetch accesses per second"],
+ "l2hits" =>[6, 1000, "L2ARC hits per second"],
+ "l2miss" =>[6, 1000, "L2ARC misses per second"],
+ "l2read" =>[6, 1000, "Total L2ARC accesses per second"],
+ "l2hit%" =>[6, 100, "L2ARC access hit percentage"],
+ "l2miss%" =>[7, 100, "L2ARC access miss percentage"],
+ "l2asize" =>[7, 1024, "Actual (compressed) size of the L2ARC"],
+ "l2size" =>[6, 1024, "Size of the L2ARC"],
+ "l2bytes" =>[7, 1024, "bytes read per second from the L2ARC"],
+);
+my %v=();
+my @hdr = qw(time read miss miss% dmis dm% pmis pm% mmis mm% arcsz c);
+my @xhdr = qw(time mfu mru mfug mrug eskip mtxmis rmis dread pread read);
+my $int = 1; # Default interval is 1 second
+my $count = 1; # Default count is 1
+my $hdr_intr = 20; # Print header every 20 lines of output
+my $opfile = "";
+my $sep = " "; # Default separator is 2 spaces
+my $raw_output;
+my $version = "0.5";
+my $l2exist = 0;
+my $cmd = "Usage: arcstat [-hvxr] [-f fields] [-o file] [-s string] " .
+ "[interval [count]]\n";
+my %cur;
+my %d;
+my $out;
+my $kstat = Sun::Solaris::Kstat->new();
+STDOUT->autoflush;
+
+sub detailed_usage {
+ print STDERR "$cmd\n";
+ print STDERR "Field definitions are as follows:\n";
+ foreach my $hdr (keys %cols) {
+ print STDERR sprintf("%11s : %s\n", $hdr, $cols{$hdr}[2]);
+ }
+ exit(1);
+}
+
+sub usage {
+ print STDERR "$cmd\n";
+ print STDERR "\t -h : Print this help message\n";
+ print STDERR "\t -v : List all possible field headers " .
+ "and definitions\n";
+ print STDERR "\t -x : Print extended stats\n";
+ print STDERR "\t -r : Raw output mode (values not scaled)\n";
+ print STDERR "\t -f : Specify specific fields to print (see -v)\n";
+ print STDERR "\t -o : Redirect output to the specified file\n";
+ print STDERR "\t -s : Override default field separator with custom " .
+ "character or string\n";
+ print STDERR "\nExamples:\n";
+ print STDERR "\tarcstat -o /tmp/a.log 2 10\n";
+ print STDERR "\tarcstat -s \",\" -o /tmp/a.log 2 10\n";
+ print STDERR "\tarcstat -v\n";
+ print STDERR "\tarcstat -f time,hit%,dh%,ph%,mh% 1\n";
+ exit(1);
+}
+
+sub init {
+ my $desired_cols;
+ my $xflag = '';
+ my $hflag = '';
+ my $vflag;
+ my $res = GetOptions('x' => \$xflag,
+ 'o=s' => \$opfile,
+ 'help|h|?' => \$hflag,
+ 'v' => \$vflag,
+ 's=s' => \$sep,
+ 'f=s' => \$desired_cols,
+ 'r' => \$raw_output);
+
+ if (defined $ARGV[0] && defined $ARGV[1]) {
+ $int = $ARGV[0];
+ $count = $ARGV[1];
+ } elsif (defined $ARGV[0]) {
+ $int = $ARGV[0];
+ $count = 0;
+ }
+
+ usage() if !$res or $hflag or ($xflag and $desired_cols);
+ detailed_usage() if $vflag;
+ @hdr = @xhdr if $xflag; #reset headers to xhdr
+
+ # check if L2ARC exists
+ snap_stats();
+ if (defined $cur{"l2_size"}) {
+ $l2exist = 1;
+ }
+
+ if ($desired_cols) {
+ @hdr = split(/[ ,]+/, $desired_cols);
+ # Now check if they are valid fields
+ my @invalid = ();
+ my @incompat = ();
+ foreach my $ele (@hdr) {
+ if (not exists($cols{$ele})) {
+ push(@invalid, $ele);
+ } elsif (($l2exist == 0) && ($ele =~ /^l2/)) {
+ printf("No L2ARC here\n", $ele);
+ push(@incompat, $ele);
+ }
+ }
+ if (scalar @invalid > 0) {
+ print STDERR "Invalid column definition! -- "
+ . "@invalid\n\n";
+ usage();
+ }
+
+ if (scalar @incompat > 0) {
+ print STDERR "Incompatible field specified -- "
+ . "@incompat\n\n";
+ usage();
+ }
+ }
+
+ if ($opfile) {
+ open($out, ">$opfile") ||die "Cannot open $opfile for writing";
+ $out->autoflush;
+ select $out;
+ }
+}
+
+# Capture kstat statistics. We maintain 3 hashes, prev, cur, and
+# d (delta). As their names imply they maintain the previous, current,
+# and delta (cur - prev) statistics.
+sub snap_stats {
+ my %prev = %cur;
+ if ($kstat->update()) {
+ printf("<State Changed>\n");
+ }
+ my $hashref_cur = $kstat->{"zfs"}{0}{"arcstats"};
+ %cur = %$hashref_cur;
+ foreach my $key (keys %cur) {
+ next if $key =~ /class/;
+ if (defined $prev{$key}) {
+ $d{$key} = $cur{$key} - $prev{$key};
+ } else {
+ $d{$key} = $cur{$key};
+ }
+ }
+}
+
+# Pretty print num. Arguments are width, scale, and num
+sub prettynum {
+ my @suffix = (' ', 'K', 'M', 'G', 'T');
+ my $num = $_[2] || 0;
+ my $scale = $_[1];
+ my $sz = $_[0];
+ my $index = 0;
+ my $save = 0;
+
+ if ($scale == -1) { #special case for date field
+ return sprintf("%s", $num);
+ } elsif (($num > 0) && ($num < 1)) { #rounding error. return 0
+ $num = 0;
+ }
+
+ while ($num > $scale and $index < 5) {
+ $save = $num;
+ $num = $num/$scale;
+ $index++;
+ }
+
+ return sprintf("%*d", $sz, $num) if ($index == 0);
+ if (($save / $scale) < 10) {
+ return sprintf("%*.1f%s", $sz - 1, $num,$suffix[$index]);
+ } else {
+ return sprintf("%*d%s", $sz - 1, $num,$suffix[$index]);
+ }
+}
+
+sub print_values {
+ foreach my $col (@hdr) {
+ if (not $raw_output) {
+ printf("%s%s", prettynum($cols{$col}[0], $cols{$col}[1],
+ $v{$col}), $sep);
+ } else {
+ printf("%d%s", $v{$col} || 0, $sep);
+ }
+ }
+ printf("\n");
+}
+
+sub print_header {
+ if (not $raw_output) {
+ foreach my $col (@hdr) {
+ printf("%*s%s", $cols{$col}[0], $col, $sep);
+ }
+ } else {
+ # Don't try to align headers in raw mode
+ foreach my $col (@hdr) {
+ printf("%s%s", $col, $sep);
+ }
+ }
+ printf("\n");
+}
+
+sub calculate {
+ %v = ();
+
+ if ($raw_output) {
+ $v{"time"} = strftime("%s", localtime);
+ } else {
+ $v{"time"} = strftime("%H:%M:%S", localtime);
+ }
+
+ $v{"hits"} = $d{"hits"}/$int;
+ $v{"miss"} = $d{"misses"}/$int;
+ $v{"read"} = $v{"hits"} + $v{"miss"};
+ $v{"hit%"} = 100 * ($v{"hits"} / $v{"read"}) if $v{"read"} > 0;
+ $v{"miss%"} = 100 - $v{"hit%"} if $v{"read"} > 0;
+
+ $v{"dhit"} = ($d{"demand_data_hits"} +
+ $d{"demand_metadata_hits"})/$int;
+ $v{"dmis"} = ($d{"demand_data_misses"} +
+ $d{"demand_metadata_misses"})/$int;
+
+ $v{"dread"} = $v{"dhit"} + $v{"dmis"};
+ $v{"dh%"} = 100 * ($v{"dhit"} / $v{"dread"}) if $v{"dread"} > 0;
+ $v{"dm%"} = 100 - $v{"dh%"} if $v{"dread"} > 0;
+
+ $v{"phit"} = ($d{"prefetch_data_hits"} +
+ $d{"prefetch_metadata_hits"})/$int;
+ $v{"pmis"} = ($d{"prefetch_data_misses"} +
+ $d{"prefetch_metadata_misses"})/$int;
+
+ $v{"pread"} = $v{"phit"} + $v{"pmis"};
+ $v{"ph%"} = 100 * ($v{"phit"} / $v{"pread"}) if $v{"pread"} > 0;
+ $v{"pm%"} = 100 - $v{"ph%"} if $v{"pread"} > 0;
+
+ $v{"mhit"} = ($d{"prefetch_metadata_hits"} +
+ $d{"demand_metadata_hits"})/$int;
+ $v{"mmis"} = ($d{"prefetch_metadata_misses"} +
+ $d{"demand_metadata_misses"})/$int;
+
+ $v{"mread"} = $v{"mhit"} + $v{"mmis"};
+ $v{"mh%"} = 100 * ($v{"mhit"} / $v{"mread"}) if $v{"mread"} > 0;
+ $v{"mm%"} = 100 - $v{"mh%"} if $v{"mread"} > 0;
+
+ $v{"arcsz"} = $cur{"size"};
+ $v{"c"} = $cur{"c"};
+ $v{"mfu"} = $d{"mfu_hits"}/$int;
+ $v{"mru"} = $d{"mru_hits"}/$int;
+ $v{"mrug"} = $d{"mru_ghost_hits"}/$int;
+ $v{"mfug"} = $d{"mfu_ghost_hits"}/$int;
+ $v{"eskip"} = $d{"evict_skip"}/$int;
+ $v{"rmiss"} = $d{"recycle_miss"}/$int;
+ $v{"mtxmis"} = $d{"mutex_miss"}/$int;
+
+ if ($l2exist) {
+ $v{"l2hits"} = $d{"l2_hits"}/$int;
+ $v{"l2miss"} = $d{"l2_misses"}/$int;
+ $v{"l2read"} = $v{"l2hits"} + $v{"l2miss"};
+ $v{"l2hit%"} = 100 * ($v{"l2hits"} / $v{"l2read"})
+ if $v{"l2read"} > 0;
+
+ $v{"l2miss%"} = 100 - $v{"l2hit%"} if $v{"l2read"} > 0;
+ $v{"l2size"} = $cur{"l2_size"};
+ $v{"l2asize"} = $cur{"l2_asize"};
+ $v{"l2bytes"} = $d{"l2_read_bytes"}/$int;
+ }
+}
+
+sub main {
+ my $i = 0;
+ my $count_flag = 0;
+
+ init();
+ if ($count > 0) { $count_flag = 1; }
+ while (1) {
+ print_header() if ($i == 0);
+ snap_stats();
+ calculate();
+ print_values();
+ last if ($count_flag == 1 && $count-- <= 1);
+ $i = (($i == $hdr_intr) && (not $raw_output)) ? 0 : $i+1;
+ sleep($int);
+ }
+ close($out) if defined $out;
+}
+
+&main;
diff --git a/usr/src/man/man1m/Makefile b/usr/src/man/man1m/Makefile
index 9510504781..402fb5d7e1 100644
--- a/usr/src/man/man1m/Makefile
+++ b/usr/src/man/man1m/Makefile
@@ -34,6 +34,7 @@ _MANFILES= 6to4relay.1m \
add_allocatable.1m \
add_drv.1m \
addbadsec.1m \
+ arcstat.1m \
arp.1m \
atohexlabel.1m \
audit.1m \
diff --git a/usr/src/man/man1m/arcstat.1m b/usr/src/man/man1m/arcstat.1m
new file mode 100644
index 0000000000..585f84baf9
--- /dev/null
+++ b/usr/src/man/man1m/arcstat.1m
@@ -0,0 +1,467 @@
+.\"
+.\" This file and its contents are supplied under the terms of the
+.\" Common Development and Distribution License ("CDDL"), version 1.0.
+.\" You may only use this file in accordance with the terms of version
+.\" 1.0 of the CDDL.
+.\"
+.\" A full copy of the text of the CDDL should have accompanied this
+.\" source. A copy of the CDDL is also available via the Internet at
+.\" http://www.illumos.org/license/CDDL.
+.\"
+.\"
+.\" Copyright 2014 Adam Stevko. All rights reserved.
+.\"
+.TH ARCSTAT 1M "Feb 4, 2014"
+.SH NAME
+arcstat \- report ZFS ARC and L2ARC statistics
+.SH SYNOPSIS
+.LP
+.nf
+\fBarcstat\fR [\fB-hvxr\fR] [\fB-f field[,field]...\fR] [\fB-o file\fR] [\fB-s string\fR]
+ [\fBinterval\fR [\fBcount\fR]]
+.fi
+
+.SH DESCRIPTION
+.sp
+.LP
+The \fBarcstat\fR utility print various ZFS ARC and L2ARC statistics in
+vmstat-like fashion.
+.sp
+
+.sp
+.LP
+The \fBarcstat\fR command reports the following information:
+.sp
+.ne 2
+
+.\"
+.sp
+.ne 1
+.na
+\fBc \fR
+.ad
+.RS 14n
+ARC Target Size
+.RE
+
+.sp
+.ne 2
+.na
+\fBdh% \fR
+.ad
+.RS 14n
+Demand Data hit percentage
+.RE
+
+.sp
+.ne 2
+.na
+\fBdm% \fR
+.ad
+.RS 14n
+Demand Data miss percentage
+.RE
+
+.sp
+.ne 2
+.na
+\fBmfu \fR
+.ad
+.RS 14n
+MFU List hits per second
+.RE
+
+.sp
+.ne 2
+.na
+\fBmh% \fR
+.ad
+.RS 14n
+Metadata hit percentage
+.RE
+
+.sp
+.ne 2
+.na
+\fBmm% \fR
+.ad
+.RS 14n
+Metadata miss percentage
+.RE
+
+.sp
+.ne 2
+.na
+\fBmru \fR
+.ad
+.RS 14n
+MRU List hits per second
+.RE
+
+.sp
+.ne 2
+.na
+\fBph% \fR
+.ad
+.RS 14n
+Prefetch hits percentage
+.RE
+
+.sp
+.ne 2
+.na
+\fBpm% \fR
+.ad
+.RS 14n
+Prefetch miss percentage
+.RE
+
+.sp
+.ne 2
+.na
+\fBdhit \fR
+.ad
+.RS 14n
+Demand Data hits per second
+.RE
+
+.sp
+.ne 2
+.na
+\fBdmis \fR
+.ad
+.RS 14n
+Demand Data misses per second
+.RE
+
+.sp
+.ne 2
+.na
+\fBhit% \fR
+.ad
+.RS 14n
+ARC Hit percentage
+.RE
+
+.sp
+.ne 2
+.na
+\fBhits \fR
+.ad
+.RS 14n
+ARC reads per second
+.RE
+
+.sp
+.ne 2
+.na
+\fBmfug \fR
+.ad
+.RS 14n
+MFU Ghost List hits per second
+.RE
+
+.sp
+.ne 2
+.na
+\fBmhit \fR
+.ad
+.RS 14n
+Metadata hits per second
+.RE
+
+.sp
+.ne 2
+.na
+\fBmiss \fR
+.ad
+.RS 14n
+ARC misses per second
+.RE
+
+.sp
+.ne 2
+.na
+\fBmmis \fR
+.ad
+.RS 14n
+Metadata misses per second
+.RE
+
+.sp
+.ne 2
+.na
+\fBmrug \fR
+.ad
+.RS 14n
+MRU Ghost List hits per second
+.RE
+
+.sp
+.ne 2
+.na
+\fBphit \fR
+.ad
+.RS 14n
+Prefetch hits per second
+.RE
+
+.sp
+.ne 2
+.na
+\fBpmis \fR
+.ad
+.RS 14n
+Prefetch misses per second
+.RE
+
+.sp
+.ne 2
+.na
+\fBread \fR
+.ad
+.RS 14n
+Total ARC accesses per second
+.RE
+
+.sp
+.ne 2
+.na
+\fBrmis \fR
+.ad
+.RS 14n
+recycle_miss per second
+.RE
+
+.sp
+.ne 2
+.na
+\fBtime \fR
+.ad
+.RS 14n
+Time
+.RE
+
+.sp
+.ne 2
+.na
+\fBarcsz \fR
+.ad
+.RS 14n
+ARC Size
+.RE
+
+.sp
+.ne 2
+.na
+\fBdread \fR
+.ad
+.RS 14n
+Demand data accesses per second
+.RE
+
+.sp
+.ne 2
+.na
+\fBeskip \fR
+.ad
+.RS 14n
+evict_skip per second
+.RE
+
+.sp
+.ne 2
+.na
+\fBmiss% \fR
+.ad
+.RS 14n
+ARC miss percentage
+.RE
+
+.sp
+.ne 2
+.na
+\fBmread \fR
+.ad
+.RS 14n
+Metadata accesses per second
+.RE
+
+.sp
+.ne 2
+.na
+\fBpread \fR
+.ad
+.RS 14n
+Prefetch accesses per second
+.RE
+
+.sp
+.ne 2
+.na
+\fBl2hit% \fR
+.ad
+.RS 14n
+L2ARC access hit percentage
+.RE
+
+.sp
+.ne 2
+.na
+\fBl2hits \fR
+.ad
+.RS 14n
+L2ARC hits per second
+.RE
+
+.sp
+.ne 2
+.na
+\fBl2miss \fR
+.ad
+.RS 14n
+L2ARC misses per second
+.RE
+
+.sp
+.ne 2
+.na
+\fBl2read \fR
+.ad
+.RS 14n
+Total L2ARC accesses per second
+.RE
+
+.sp
+.ne 2
+.na
+\fBl2size \fR
+.ad
+.RS 14n
+Size of the L2ARC
+.RE
+
+.sp
+.ne 2
+.na
+\fBmtxmis \fR
+.ad
+.RS 14n
+mutex_miss per second
+.RE
+
+.sp
+.ne 2
+.na
+\fBl2bytes \fR
+.ad
+.RS 14n
+bytes read per second from the L2ARC
+.RE
+
+.sp
+.ne 2
+.na
+\fBl2miss% \fR
+.ad
+.RS 14n
+L2ARC access miss percentage
+.RE
+
+.sp
+.ne 2
+.na
+\fBl2asize \fR
+.ad
+.RS 14n
+Actual (compressed) size of the L2ARC
+.RE
+.\"
+
+.SH OPTIONS
+.sp
+.LP
+The following options are supported:
+
+.sp
+.ne 2
+.na
+\fB\fB-f\fR\fR
+.ad
+.RS 12n
+Display only specific fields. See \fBDESCRIPTION\fR for supported statistics.
+.RE
+
+.sp
+.ne 2
+.na
+\fB\fB-h\fR\fR
+.ad
+.RS 12n
+Display help message.
+.RE
+
+.sp
+.ne 2
+.na
+\fB\fB-o\fR\fR
+.ad
+.RS 12n
+Report statistics to a file instead of the standard output.
+.RE
+
+.sp
+.ne 2
+.na
+\fB\fB-s\fR\fR
+.ad
+.RS 12n
+Display data with a specified separator (default: 2 spaces).
+.RE
+
+.sp
+.ne 2
+.na
+\fB\fB-x\fR\fR
+
+.ad
+.RS 12n
+Print extended stats (same as -f time,mfu,mru,mfug,mrug,eskip,mtxmis,rmis,dread,pread,read).
+.RE
+
+.sp
+.ne 2
+.na
+\fB\fB-v\fR\fR
+.ad
+.RS 12n
+Show field headers and definitions
+.RE
+
+.SH OPERANDS
+.sp
+.LP
+The following operands are supported:
+.sp
+.ne 2
+.na
+\fB\fIcount\fR\fR
+.ad
+.RS 12n
+Display only \fIcount\fR reports.
+.RE
+
+.sp
+.ne 2
+.na
+\fB\fIinterval\fR\fR
+.ad
+.RS 12n
+Specify the sampling interval in seconds.
+.RE
+
+.SH AUTHORS
+.sp
+.LP
+arcstat was originally written by Neelakanth Nadgir and supported only ZFS ARC statistics.
+Mike Harsch updated it to support L2ARC statistics.
diff --git a/usr/src/pkg/manifests/system-monitoring-arcstat.mf b/usr/src/pkg/manifests/system-monitoring-arcstat.mf
new file mode 100644
index 0000000000..0c3fd4fb0d
--- /dev/null
+++ b/usr/src/pkg/manifests/system-monitoring-arcstat.mf
@@ -0,0 +1,27 @@
+#
+# This file and its contents are supplied under the terms of the
+# Common Development and Distribution License ("CDDL"), version 1.0.
+# You may only use this file in accordance with the terms of version
+# 1.0 of the CDDL.
+#
+# A full copy of the text of the CDDL should have accompanied this
+# source. A copy is of the CDDL is also available via the Internet
+# at http://www.illumos.org/license/CDDL.
+#
+
+# Copyright 2014 Adam Stevko. All rights reserved.
+
+set name=pkg.fmri value=pkg:/system/monitoring/arcstat@$(PKGVERS)
+set name=pkg.summary \
+ value="arcstat displays various ZFS ARC and L2ARC statistics"
+set name=info.classification \
+ value="org.opensolaris.category.2008:Applications/System Utilities"
+set name=variant.arch value=$(ARCH)
+dir path=usr group=sys
+dir path=usr/bin
+dir path=usr/share
+dir path=usr/share/man
+dir path=usr/share/man/man1m
+file path=usr/bin/arcstat mode=0555
+file path=usr/share/man/man1m/arcstat.1m
+license lic_CDDL license=lic_CDDL