#!/usr/bin/python
# -*- python-mode -*-
"""Emulate iostat for NFS mount points using /proc/self/mountstats
"""

__copyright__ = """
Copyright (C) 2005, Chuck Lever <cel@netapp.com>

This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License version 2 as
published by the Free Software Foundation.

This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
GNU General Public License for more details.

You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
"""

import sys, os, time
from optparse import OptionParser, OptionGroup

Iostats_version = '0.2'

def difference(x, y):
    """Used for a map() function
    """
    return x - y

NfsEventCounters = [
    'inoderevalidates',
    'dentryrevalidates',
    'datainvalidates',
    'attrinvalidates',
    'vfsopen',
    'vfslookup',
    'vfspermission',
    'vfsupdatepage',
    'vfsreadpage',
    'vfsreadpages',
    'vfswritepage',
    'vfswritepages',
    'vfsreaddir',
    'vfssetattr',
    'vfsflush',
    'vfsfsync',
    'vfslock',
    'vfsrelease',
    'congestionwait',
    'setattrtrunc',
    'extendwrite',
    'sillyrenames',
    'shortreads',
    'shortwrites',
    'delay'
]

NfsByteCounters = [
    'normalreadbytes',
    'normalwritebytes',
    'directreadbytes',
    'directwritebytes',
    'serverreadbytes',
    'serverwritebytes',
    'readpages',
    'writepages'
]

class DeviceData:
    """DeviceData objects provide methods for parsing and displaying
    data for a single mount grabbed from /proc/self/mountstats
    """
    def __init__(self):
        self.__nfs_data = dict()
        self.__rpc_data = dict()
        self.__rpc_data['ops'] = []

    def __parse_nfs_line(self, words):
        if words[0] == 'device':
            self.__nfs_data['export'] = words[1]
            self.__nfs_data['mountpoint'] = words[4]
            self.__nfs_data['fstype'] = words[7]
            if words[7] == 'nfs':
                self.__nfs_data['statvers'] = words[8]
        elif words[0] == 'age:':
            self.__nfs_data['age'] = long(words[1])
        elif words[0] == 'opts:':
            self.__nfs_data['mountoptions'] = ''.join(words[1:]).split(',')
        elif words[0] == 'caps:':
            self.__nfs_data['servercapabilities'] = ''.join(words[1:]).split(',')
        elif words[0] == 'nfsv4:':
            self.__nfs_data['nfsv4flags'] = ''.join(words[1:]).split(',')
        elif words[0] == 'sec:':
            keys = ''.join(words[1:]).split(',')
            self.__nfs_data['flavor'] = int(keys[0].split('=')[1])
            self.__nfs_data['pseudoflavor'] = 0
            if self.__nfs_data['flavor'] == 6:
                self.__nfs_data['pseudoflavor'] = int(keys[1].split('=')[1])
        elif words[0] == 'events:':
            i = 1
            for key in NfsEventCounters:
                self.__nfs_data[key] = int(words[i])
                i += 1
        elif words[0] == 'bytes:':
            i = 1
            for key in NfsByteCounters:
                self.__nfs_data[key] = long(words[i])
                i += 1

    def __parse_rpc_line(self, words):
        if words[0] == 'RPC':
            self.__rpc_data['statsvers'] = float(words[3])
            self.__rpc_data['programversion'] = words[5]
        elif words[0] == 'xprt:':
            self.__rpc_data['protocol'] = words[1]
            if words[1] == 'udp':
                self.__rpc_data['port'] = int(words[2])
                self.__rpc_data['bind_count'] = int(words[3])
                self.__rpc_data['rpcsends'] = int(words[4])
                self.__rpc_data['rpcreceives'] = int(words[5])
                self.__rpc_data['badxids'] = int(words[6])
                self.__rpc_data['inflightsends'] = long(words[7])
                self.__rpc_data['backlogutil'] = long(words[8])
            elif words[1] == 'tcp':
                self.__rpc_data['port'] = words[2]
                self.__rpc_data['bind_count'] = int(words[3])
                self.__rpc_data['connect_count'] = int(words[4])
                self.__rpc_data['connect_time'] = int(words[5])
                self.__rpc_data['idle_time'] = int(words[6])
                self.__rpc_data['rpcsends'] = int(words[7])
                self.__rpc_data['rpcreceives'] = int(words[8])
                self.__rpc_data['badxids'] = int(words[9])
                self.__rpc_data['inflightsends'] = long(words[10])
                self.__rpc_data['backlogutil'] = long(words[11])
            elif words[1] == 'rdma':
                self.__rpc_data['port'] = words[2]
                self.__rpc_data['bind_count'] = int(words[3])
                self.__rpc_data['connect_count'] = int(words[4])
                self.__rpc_data['connect_time'] = int(words[5])
                self.__rpc_data['idle_time'] = int(words[6])
                self.__rpc_data['rpcsends'] = int(words[7])
                self.__rpc_data['rpcreceives'] = int(words[8])
                self.__rpc_data['badxids'] = int(words[9])
                self.__rpc_data['backlogutil'] = int(words[10])
                self.__rpc_data['read_chunks'] = int(words[11])
                self.__rpc_data['write_chunks'] = int(words[12])
                self.__rpc_data['reply_chunks'] = int(words[13])
                self.__rpc_data['total_rdma_req'] = int(words[14])
                self.__rpc_data['total_rdma_rep'] = int(words[15])
                self.__rpc_data['pullup'] = int(words[16])
                self.__rpc_data['fixup'] = int(words[17])
                self.__rpc_data['hardway'] = int(words[18])
                self.__rpc_data['failed_marshal'] = int(words[19])
                self.__rpc_data['bad_reply'] = int(words[20])
        elif words[0] == 'per-op':
            self.__rpc_data['per-op'] = words
        else:
            op = words[0][:-1]
            self.__rpc_data['ops'] += [op]
            self.__rpc_data[op] = [long(word) for word in words[1:]]

    def parse_stats(self, lines):
        """Turn a list of lines from a mount stat file into a 
        dictionary full of stats, keyed by name
        """
        found = False
        for line in lines:
            words = line.split()
            if len(words) == 0:
                continue
            if (not found and words[0] != 'RPC'):
                self.__parse_nfs_line(words)
                continue

            found = True
            self.__parse_rpc_line(words)

    def is_nfs_mountpoint(self):
        """Return True if this is an NFS or NFSv4 mountpoint,
        otherwise return False
        """
        if self.__nfs_data['fstype'] == 'nfs':
            return True
        elif self.__nfs_data['fstype'] == 'nfs4':
            return True
        return False

    def compare_iostats(self, old_stats):
        """Return the difference between two sets of stats
        """
        result = DeviceData()

        # copy self into result
        for key, value in self.__nfs_data.iteritems():
            result.__nfs_data[key] = value
        for key, value in self.__rpc_data.iteritems():
            result.__rpc_data[key] = value

        # compute the difference of each item in the list
        # note the copy loop above does not copy the lists, just
        # the reference to them.  so we build new lists here
        # for the result object.
        for op in result.__rpc_data['ops']:
            result.__rpc_data[op] = map(difference, self.__rpc_data[op], old_stats.__rpc_data[op])

        # update the remaining keys we care about
        result.__rpc_data['rpcsends'] -= old_stats.__rpc_data['rpcsends']
        result.__rpc_data['backlogutil'] -= old_stats.__rpc_data['backlogutil']

        for key in NfsEventCounters:
            result.__nfs_data[key] -= old_stats.__nfs_data[key]
        for key in NfsByteCounters:
            result.__nfs_data[key] -= old_stats.__nfs_data[key]

        return result

    def __print_data_cache_stats(self):
        """Print the data cache hit rate
        """
        nfs_stats = self.__nfs_data
        app_bytes_read = float(nfs_stats['normalreadbytes'])
        if app_bytes_read != 0:
            client_bytes_read = float(nfs_stats['serverreadbytes'] - nfs_stats['directreadbytes'])
            ratio = ((app_bytes_read - client_bytes_read) * 100) / app_bytes_read

            print
            print 'app bytes: %f  client bytes %f' % (app_bytes_read, client_bytes_read)
            print 'Data cache hit ratio: %4.2f%%' % ratio

    def __print_attr_cache_stats(self, sample_time):
        """Print attribute cache efficiency stats
        """
        nfs_stats = self.__nfs_data
        getattr_stats = self.__rpc_data['GETATTR']

        if nfs_stats['inoderevalidates'] != 0:
            getattr_ops = float(getattr_stats[1])
            opens = float(nfs_stats['vfsopen'])
            revalidates = float(nfs_stats['inoderevalidates']) - opens
            if revalidates != 0:
                ratio = ((revalidates - getattr_ops) * 100) / revalidates
            else:
                ratio = 0.0

            data_invalidates = float(nfs_stats['datainvalidates'])
            attr_invalidates = float(nfs_stats['attrinvalidates'])

            print
            print '%d inode revalidations, hitting in cache %4.2f%% of the time' % \
                (revalidates, ratio)
            print '%d open operations (mandatory GETATTR requests)' % opens
            if getattr_ops != 0:
                print '%4.2f%% of GETATTRs resulted in data cache invalidations' % \
                   ((data_invalidates * 100) / getattr_ops)

    def __print_dir_cache_stats(self, sample_time):
        """Print directory stats
        """
        nfs_stats = self.__nfs_data
        lookup_ops = self.__rpc_data['LOOKUP'][0]
        readdir_ops = self.__rpc_data['READDIR'][0]
        if self.__rpc_data.has_key('READDIRPLUS'):
            readdir_ops += self.__rpc_data['READDIRPLUS'][0]

        dentry_revals = nfs_stats['dentryrevalidates']
        opens = nfs_stats['vfsopen']
        lookups = nfs_stats['vfslookup']
        getdents = nfs_stats['vfsreaddir']

        print
        print '%d open operations (pathname lookups)' % opens
        print '%d dentry revalidates and %d vfs lookup requests' % \
            (dentry_revals, lookups),
        print 'resulted in %d LOOKUPs on the wire' % lookup_ops
        print '%d vfs getdents calls resulted in %d READDIRs on the wire' % \
            (getdents, readdir_ops)

    def __print_page_stats(self, sample_time):
        """Print page cache stats
        """
        nfs_stats = self.__nfs_data

        vfsreadpage = nfs_stats['vfsreadpage']
        vfsreadpages = nfs_stats['vfsreadpages']
        pages_read = nfs_stats['readpages']
        vfswritepage = nfs_stats['vfswritepage']
        vfswritepages = nfs_stats['vfswritepages']
        pages_written = nfs_stats['writepages']

        print
        print '%d nfs_readpage() calls read %d pages' % \
            (vfsreadpage, vfsreadpage)
        print '%d nfs_readpages() calls read %d pages' % \
            (vfsreadpages, pages_read - vfsreadpage),
        if vfsreadpages != 0:
            print '(%.1f pages per call)' % \
                (float(pages_read - vfsreadpage) / vfsreadpages)
        else:
            print

        print
        print '%d nfs_updatepage() calls' % nfs_stats['vfsupdatepage']
        print '%d nfs_writepage() calls wrote %d pages' % \
            (vfswritepage, vfswritepage)
        print '%d nfs_writepages() calls wrote %d pages' % \
            (vfswritepages, pages_written - vfswritepage),
        if (vfswritepages) != 0:
            print '(%.1f pages per call)' % \
                (float(pages_written - vfswritepage) / vfswritepages)
        else:
            print

        congestionwaits = nfs_stats['congestionwait']
        if congestionwaits != 0:
            print
            print '%d congestion waits' % congestionwaits

    def __print_rpc_op_stats(self, op, sample_time):
        """Print generic stats for one RPC op
        """
        if not self.__rpc_data.has_key(op):
            return

        rpc_stats = self.__rpc_data[op]
        ops = float(rpc_stats[0])
        retrans = float(rpc_stats[1] - rpc_stats[0])
        kilobytes = float(rpc_stats[3] + rpc_stats[4]) / 1024
        rtt = float(rpc_stats[6])
        exe = float(rpc_stats[7])

        # prevent floating point exceptions
        if ops != 0:
            kb_per_op = kilobytes / ops
            retrans_percent = (retrans * 100) / ops
            rtt_per_op = rtt / ops
            exe_per_op = exe / ops
        else:
            kb_per_op = 0.0
            retrans_percent = 0.0
            rtt_per_op = 0.0
            exe_per_op = 0.0

        op += ':'
        print '%s' % op.lower().ljust(15),
        print '  ops/s\t\t   kB/s\t\t  kB/op\t\tretrans\t\tavg RTT (ms)\tavg exe (ms)'

        print '\t\t%7.3f' % (ops / sample_time),
        print '\t%7.3f' % (kilobytes / sample_time),
        print '\t%7.3f' % kb_per_op,
        print ' %7d (%3.1f%%)' % (retrans, retrans_percent),
        print '\t%7.3f' % rtt_per_op,
        print '\t%7.3f' % exe_per_op

    def ops(self, sample_time):
        sends = float(self.__rpc_data['rpcsends'])
        if sample_time == 0:
            sample_time = float(self.__nfs_data['age'])
        return (sends / sample_time)

    def display_iostats(self, sample_time, which):
        """Display NFS and RPC stats in an iostat-like way
        """
        sends = float(self.__rpc_data['rpcsends'])
        if sample_time == 0:
            sample_time = float(self.__nfs_data['age'])
        if sends != 0:
            backlog = (float(self.__rpc_data['backlogutil']) / sends) / sample_time
        else:
            backlog = 0.0

        print
        print '%s mounted on %s:' % \
            (self.__nfs_data['export'], self.__nfs_data['mountpoint'])
        print

        print '   op/s\t\trpc bklog'
        print '%7.2f' % (sends / sample_time), 
        print '\t%7.2f' % backlog

        if which == 0:
            self.__print_rpc_op_stats('READ', sample_time)
            self.__print_rpc_op_stats('WRITE', sample_time)
        elif which == 1:
            self.__print_rpc_op_stats('GETATTR', sample_time)
            self.__print_rpc_op_stats('ACCESS', sample_time)
            self.__print_attr_cache_stats(sample_time)
        elif which == 2:
            self.__print_rpc_op_stats('LOOKUP', sample_time)
            self.__print_rpc_op_stats('READDIR', sample_time)
            if self.__rpc_data.has_key('READDIRPLUS'):
                self.__print_rpc_op_stats('READDIRPLUS', sample_time)
            self.__print_dir_cache_stats(sample_time)
        elif which == 3:
            self.__print_rpc_op_stats('READ', sample_time)
            self.__print_rpc_op_stats('WRITE', sample_time)
            self.__print_page_stats(sample_time)

#
# Functions
#

def parse_stats_file(filename):
    """pop the contents of a mountstats file into a dictionary,
    keyed by mount point.  each value object is a list of the
    lines in the mountstats file corresponding to the mount
    point named in the key.
    """
    ms_dict = dict()
    key = ''

    f = file(filename)
    for line in f.readlines():
        words = line.split()
        if len(words) == 0:
            continue
        if words[0] == 'device':
            key = words[4]
            new = [ line.strip() ]
        else:
            new += [ line.strip() ]
        ms_dict[key] = new
    f.close

    return ms_dict

def print_iostat_summary(old, new, devices, time, options):
    stats = {}
    diff_stats = {}

    if old:
        # Trim device list to only include intersection of old and new data,
        # this addresses umounts due to autofs mountpoints
        devicelist = filter(lambda x:x in devices,old)
    else:
        devicelist = devices

    for device in devicelist:
        stats[device] = DeviceData()
        stats[device].parse_stats(new[device])
        if old:
            old_stats = DeviceData()
            old_stats.parse_stats(old[device])
            diff_stats[device] = stats[device].compare_iostats(old_stats)

    if options.sort:
        if old:
            # We now have compared data and can print a comparison
            # ordered by mountpoint ops per second
            devicelist.sort(key=lambda x: diff_stats[x].ops(time), reverse=True)
        else:
            # First iteration, just sort by newly parsed ops/s
            devicelist.sort(key=lambda x: stats[x].ops(time), reverse=True)

    count = 1
    for device in devicelist:
        if old:
            diff_stats[device].display_iostats(time, options.which)
        else:
            stats[device].display_iostats(time, options.which)

        count += 1
        if (count > options.list):
            return


def list_nfs_mounts(givenlist, mountstats):
    """return a list of NFS mounts given a list to validate or
       return a full list if the given list is empty -
       may return an empty list if none found
    """
    list = []
    if len(givenlist) > 0:
        for device in givenlist:
            stats = DeviceData()
            stats.parse_stats(mountstats[device])
            if stats.is_nfs_mountpoint():
                list += [device]
    else:
        for device, descr in mountstats.iteritems():
            stats = DeviceData()
            stats.parse_stats(descr)
            if stats.is_nfs_mountpoint():
                list += [device]
    return list

def iostat_command(name):
    """iostat-like command for NFS mount points
    """
    mountstats = parse_stats_file('/proc/self/mountstats')
    devices = []
    origdevices = []
    interval_seen = False
    count_seen = False

    mydescription= """
Sample iostat-like program to display NFS client per-mount'
statistics.  The <interval> parameter specifies the amount of time in seconds
between each report.  The first report contains statistics for the time since
each file system was mounted.  Each subsequent report contains statistics
collected during the interval since the previous report.  If the <count>
parameter is specified, the value of <count> determines the number of reports
generated at <interval> seconds apart.  If the interval parameter is specified
without the <count> parameter, the command generates reports continuously.
If one or more <mount point> names are specified, statistics for only these
mount points will be displayed.  Otherwise, all NFS mount points on the
client are listed.
"""
    parser = OptionParser(
        usage="usage: %prog [ <interval> [ <count> ] ] [ <options> ] [ <mount point> ]",
        description=mydescription,
        version='version %s' % Iostats_version)
    parser.set_defaults(which=0, sort=False, list=sys.maxint)

    statgroup = OptionGroup(parser, "Statistics Options",
                            'File I/O is displayed unless one of the following is specified:')
    statgroup.add_option('-a', '--attr',
                            action="store_const",
                            dest="which",
                            const=1,
                            help='displays statistics related to the attribute cache')
    statgroup.add_option('-d', '--dir',
                            action="store_const",
                            dest="which",
                            const=2,
                            help='displays statistics related to directory operations')
    statgroup.add_option('-p', '--page',
                            action="store_const",
                            dest="which",
                            const=3,
                            help='displays statistics related to the page cache')
    parser.add_option_group(statgroup)
    displaygroup = OptionGroup(parser, "Display Options",
                               'Options affecting display format:')
    displaygroup.add_option('-s', '--sort',
                            action="store_true",
                            dest="sort",
                            help="Sort NFS mount points by ops/second")
    displaygroup.add_option('-l','--list',
                            action="store",
                            type="int",
                            dest="list",
                            help="only print stats for first LIST mount points")
    parser.add_option_group(displaygroup)

    (options, args) = parser.parse_args(sys.argv)

    for arg in args:

        if arg == sys.argv[0]:
            continue

        if arg in mountstats:
            origdevices += [arg]
        elif not interval_seen:
            try:
                interval = int(arg)
            except:
                print 'Illegal <interval> value %s' % arg
                return
            if interval > 0:
                interval_seen = True
            else:
                print 'Illegal <interval> value %s' % arg
                return
        elif not count_seen:
            try:
                count = int(arg)
            except:
                print 'Ilegal <count> value %s' % arg
                return
            if count > 0:
                count_seen = True
            else:
                print 'Illegal <count> value %s' % arg
                return

    # make certain devices contains only NFS mount points
    devices = list_nfs_mounts(origdevices, mountstats)
    if len(devices) == 0:
        print 'No NFS mount points were found'
        return


    old_mountstats = None
    sample_time = 0.0

    if not interval_seen:
        print_iostat_summary(old_mountstats, mountstats, devices, sample_time, options)
        return

    if count_seen:
        while count != 0:
            print_iostat_summary(old_mountstats, mountstats, devices, sample_time, options)
            old_mountstats = mountstats
            time.sleep(interval)
            sample_time = interval
            mountstats = parse_stats_file('/proc/self/mountstats')
            # automount mountpoints add and drop, if automount is involved
            # we need to recheck the devices list when reparsing
            devices = list_nfs_mounts(origdevices,mountstats)
            if len(devices) == 0:
                print 'No NFS mount points were found'
                return
            count -= 1
    else: 
        while True:
            print_iostat_summary(old_mountstats, mountstats, devices, sample_time, options)
            old_mountstats = mountstats
            time.sleep(interval)
            sample_time = interval
            mountstats = parse_stats_file('/proc/self/mountstats')
            # automount mountpoints add and drop, if automount is involved
            # we need to recheck the devices list when reparsing
            devices = list_nfs_mounts(origdevices,mountstats)
            if len(devices) == 0:
                print 'No NFS mount points were found'
                return

#
# Main
#
prog = os.path.basename(sys.argv[0])

try:
    iostat_command(prog)
except KeyboardInterrupt:
    print 'Caught ^C... exiting'
    sys.exit(1)

sys.exit(0)
