#!/usr/bin/ksh
 #
 # diskhits - disk access by file offset.
 #            Written using DTrace (Solaris 10 3/05).
 #
 # $Id: diskhits 3 2007-08-01 10:50:08Z brendan $
 #
 # This prints how a file was accessed, the locations on a distribution plot.
 # This is for the cache misses only - the file activity that resulted in
 # disk events.
 #
 # USAGE:	diskhits pathname
 #	eg,
 #		diskhits /var/adm/messages
 #
 # FIELDS:
 #		Location (KB)	The file offset of the disk activity, Kbytes.
 #		Size (KB)	Size of the disk activity, Kbytes.
 #		Total RW	Total disk activity, reads + writes.
 #
 # BASED ON: /usr/demo/dtrace/applicat.d
 #
 # SEE ALSO: DTrace Guide "io Provider" chapter (docs.sun.com)
 #           iosnoop (DTraceToolkit)
 #
 # PORTIONS: Copyright (c) 2005, 2006 Brendan Gregg.
 #
 # 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 Docs/cddl1.txt
 #  or http://www.opensolaris.org/os/licensing.
 #  See the License for the specific language governing permissions
 #  and limitations under the License.
 #
 # CDDL HEADER END
 #
 # 08-Jun-2005   Brendan Gregg   Created this.
 # 20-Apr-2006	   "      "	Last update.
 #
 
 ### Usage
 function usage
 {
 	cat <<-END >&2
 	USAGE: diskhits pathname
 	   eg,
 	       diskhits /var/adm/wtmpx
 	END
 	exit 1
 }
 
 ### Process arguments
 if (( $# != 1 )); then
 	usage
 fi
 if [[ $1 == "-h" ]]; then
 	usage
 fi
 pathname=$1
 if [[ ! -e $pathname ]]; then
 	print "ERROR2: file $pathname not found" >&2
 	exit 2
 fi
 
 ### Calculate output scale
 report_lines=20
 set -- `ls -l $pathname`
 filesize=$5
 (( file_kb_max = filesize / 1024 ))
 (( scale_kb = filesize / (1024 * report_lines) ))
 if (( file_kb_max < 20 )); then file_kb_max=20; fi
 if (( scale_kb < 1 )); then scale_kb=1; fi
 
 #
 #  Run DTrace
 #
 /usr/sbin/dtrace -n '
  #pragma D option quiet
 
  inline string PATHNAME = "'$pathname'";
  inline int FILE_KB_MAX = '$file_kb_max';
  inline int SCALE_KB = '$scale_kb';
 
  dtrace:::BEGIN
  {
 	printf("Tracing... Hit Ctrl-C to end.\n");
  }
 
  io:::start
  /args[2]->fi_pathname == PATHNAME/
  {
 	this->kb = args[2]->fi_offset == -1 ? -1 : args[2]->fi_offset / 1024;
 	@Location = lquantize(this->kb, 0, FILE_KB_MAX, SCALE_KB);
 	@Size = quantize(args[0]->b_bcount/1024);
 	@Total = sum(args[0]->b_bcount/1024);
  }
 
  dtrace:::END
  {
 	printf("Location (KB),");
 	printa(@Location);
 
 	printf("Size (KB),");
 	printa(@Size);
 
 	printa("Total RW: %@d KB\n", @Total);
  }
 '