]> www.infradead.org Git - users/dhowells/kafs-utils.git/commitdiff
Implement "vos examine"
authorDavid Howells <dhowells@redhat.com>
Thu, 10 Apr 2014 13:04:52 +0000 (14:04 +0100)
committerDavid Howells <dhowells@redhat.com>
Fri, 11 Apr 2014 13:41:27 +0000 (14:41 +0100)
Implement the "vos examine" command.  There is a lot of common display code
between this and several of the other commands, so the common bits are drawn
out into a library module for all to share.

Signed-off-by: David Howells <dhowells@redhat.com>
suite/commands/vos/examine.py [new file with mode: 0644]
suite/commands/vos/listvldb.py
suite/commands/vos/listvol.py
suite/lib/voldisplay.py [new file with mode: 0644]

diff --git a/suite/commands/vos/examine.py b/suite/commands/vos/examine.py
new file mode 100644 (file)
index 0000000..750a265
--- /dev/null
@@ -0,0 +1,143 @@
+#
+# AFS Volume management toolkit: Volume location database info
+# -*- coding: utf-8 -*-
+#
+
+__copyright__ = """
+Copyright (C) 2014 Red Hat, Inc. All Rights Reserved.
+Written by David Howells (dhowells@redhat.com)
+
+This program is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public Licence 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 Licence for more details.
+
+You should have received a copy of the GNU General Public Licence
+along with this program; if not, write to the Free Software
+Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+"""
+
+from afs.argparse import *
+from afs.lib.debug import debug
+from afs.lib.partition import id2part
+from afs.lib.volserver import volserver
+from afs.lib.voldisplay import *
+import afs.lib.addrcache as addrcache
+import kafs
+import sys
+import datetime
+
+help = "Show volume header and VLDB entry information for a volume"
+
+command_arguments = [
+    [ "id",             get_volume_name,        "rs",         "<volume name or ID>" ],
+    [ "extended",       get_dummy,              "fn" ],
+    [ "format",         get_dummy,              "fn" ],
+    [ "cell",           get_cell,               "os",         "<cell name>" ],
+    [ "noauth",         get_auth,               "fn" ],
+    [ "localauth",      get_auth,               "fn" ],
+    [ "verbose",        get_dummy,              "fn" ],
+    [ "encrypt",        get_dummy,              "fn" ],
+    [ "noresolve",      get_dummy,              "fn" ],
+]
+
+cant_combine_arguments = [
+    ( "cell",           "localauth" ),
+    ( "noauth",         "localauth" ),
+]
+
+description = r"""
+Show volume header and VLDB entry information for a volume
+"""
+
+def display_vldb(params, vldb):
+    s = ""
+    if vldb.volumeId[kafs.RWVOL] != 0:
+        s += "    RWrite: {:<10d}".format(vldb.volumeId[kafs.RWVOL])
+    if vldb.volumeId[kafs.ROVOL] != 0:
+        s += "    ROnly: {:<10d}".format(vldb.volumeId[kafs.ROVOL])
+    if vldb.volumeId[kafs.BACKVOL] != 0:
+        s += "    Backup: {:<10d}".format(vldb.volumeId[kafs.BACKVOL])
+    print(s)
+
+    display_vldb_site_list(params, vldb, "   ")
+
+def display_normal(params, vldb, vol):
+    display_vol_information(params, vol)
+    if "extended" in params:
+        display_vol_statistics(params, vol)
+    display_vldb(params, vldb)
+
+def display_format(params, vldb, vol):
+    display_vol_mp_information(params, vol)
+    print()
+    display_vldb(params, vldb)
+
+###############################################################################
+#
+#
+#
+###############################################################################
+def main(params):
+    cell = params["cell"]
+    vl_conn = cell.open_vl_server(params)
+
+    volname = params["id"]
+    if volname.isnumeric():
+        volid = int(volname)
+        ret = kafs.VL_GetEntryByIDN(vl_conn, volid, 0xffffffff)
+        vldb = ret.entry
+        if volid == vldb.volumeId[kafs.RWVOL]:
+            servflag = kafs.VLSF_RWVOL
+        elif volid == vldb.volumeId[kafs.ROVOL]:
+            servflag = kafs.VLSF_ROVOL
+        elif volid == vldb.volumeId[kafs.BACKVOL]:
+            servflag = kafs.VLSF_BACKVOL
+        else:
+            raise RuntimeError("Requested volume ID not in record for volume ID")
+    else:
+        ret = kafs.VL_GetEntryByNameN(vl_conn, volname)
+        vldb = ret.entry
+        servflag = 0
+        for i in range(0, vldb.nServers):
+            servflag |= vldb.serverFlags[i]
+        if servflag & kafs.VLSF_RWVOL:
+            servflag = kafs.VLSF_RWVOL
+            volid = vldb.volumeId[kafs.RWVOL]
+        elif servflag & kafs.VLSF_ROVOL:
+            servflag = kafs.VLSF_ROVOL
+            volid = vldb.volumeId[kafs.ROVOL]
+        elif servflag & kafs.VLSF_BACKVOL:
+            servflag = kafs.VLSF_BACKVOL
+            volid = vldb.volumeId[kafs.BACKVOL]
+        else:
+            raise RuntimeError("Requested volume does not exist on any server")
+
+    del vl_conn;
+
+    for i in range(0, vldb.nServers):
+        if vldb.serverFlags[i] & servflag == 0:
+            continue
+
+        vol_server = volserver(vldb.serverNumber[i])
+        vol_conn = cell.open_volume_server(vol_server, params)
+        if "extended" in params:
+            ret = kafs.VOLSER_AFSVolXListOneVolume(vol_conn, vldb.serverPartition[i], volid)
+        else:
+            ret = kafs.VOLSER_AFSVolListOneVolume(vol_conn, vldb.serverPartition[i], volid)
+        params["server"] = vol_server
+        params["_partname"] = id2part(vldb.serverPartition[i])
+        vol = ret.resultEntries[0]
+        del vol_conn
+        break
+    else:
+        raise RuntimeError("Couldn't examine requested volume")
+
+    if "format" in params and "extended" not in params:
+        display_format(params, vldb, vol)
+    else:
+        display_normal(params, vldb, vol)
index b3adfca7bd9860ad4f19d93cdcfd92c0c0784466..354bf43b9a312bc0f896d010f90303b5b1e11848 100644 (file)
@@ -22,6 +22,7 @@ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
 """
 
 from afs.argparse import *
+from afs.lib.voldisplay import *
 import afs.lib.addrcache as addrcache
 import kafs
 from socket import inet_ntoa
@@ -61,49 +62,7 @@ def print_record(params, vldb):
     print(" RWrite: {:<12d} ROnly: {:<12d} Backup: {:<12d}".format(vldb.volumeId[0],
                                                                    vldb.volumeId[1],
                                                                    vldb.volumeId[2]))
-    print(" number of sites ->", vldb.nServers)
-    for i in range(0, vldb.nServers):
-        inaddr = bytearray(4)
-        inaddr[0] = (vldb.serverNumber[i] >> 24) & 0xff
-        inaddr[1] = (vldb.serverNumber[i] >> 16) & 0xff
-        inaddr[2] = (vldb.serverNumber[i] >>  8) & 0xff
-        inaddr[3] = (vldb.serverNumber[i] >>  0) & 0xff
-        addr = inet_ntoa(bytes(inaddr))
-
-        if "noresolve" not in params:
-            name = addrcache.addr2name(addr)
-            if name != None:
-                addr = name
-
-        partnum = vldb.serverPartition[i]
-        if partnum < 26:
-            part = "{:c}".format(97 + partnum)
-        else:
-            partnum -= 26
-            part = "{:c}{:c}".format(97 + partnum / 26, 97 + partnum % 26)
-
-        flags = vldb.serverFlags[i]
-        if flags & kafs.VLSF_ROVOL:
-            ptype = "RO"
-        elif flags & kafs.VLSF_RWVOL:
-            ptype = "RW"
-        else:
-            ptype = "Back"
-
-        print("    server {:s} partition /vicep{:s} {:s} Site".format(addr, part, ptype))
-
-    if vldb.flags & (kafs.VLOP_MOVE | kafs.VLOP_RELEASE | kafs.VLOP_BACKUP | kafs.VLOP_DELETE | kafs.VLOP_DUMP):
-        print(" Volume is currently LOCKED")
-        if vldb.flags & kafs.VLOP_MOVE:
-            print("Volume is locked for a move operation")
-        if vldb.flags & kafs.VLOP_RELEASE:
-            print("Volume is locked for a release operation")
-        if vldb.flags & kafs.VLOP_BACKUP:
-            print("Volume is locked for a backup operation")
-        if vldb.flags & kafs.VLOP_DELETE:
-            print("Volume is locked for a delete/misc operation")
-        if vldb.flags & kafs.VLOP_DUMP:
-            print("Volume is locked for a dump/restore operation")
+    display_vldb_site_list(params, vldb)
 
 def main(params):
     # Get a list of VLDB servers to query
index 489cb888ff0ec5032b43f721d4c36ba40bc7f6b1..736a26ee4b123848c2544086e0d0a9c6ca14a3c3 100644 (file)
@@ -24,6 +24,7 @@ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
 from afs.argparse import *
 from afs.lib.debug import debug
 from afs.lib.partition import id2part
+from afs.lib.voldisplay import *
 import afs.lib.addrcache as addrcache
 import kafs
 import sys
@@ -57,156 +58,15 @@ description = r"""
 Display information from a volume header
 """
 
-def vol_type(vol):
-    if vol.type == 0:
-        return "RW"
-    if vol.type == 1:
-        return "RO"
-    if vol.type == 2:
-        return "BK"
-    return "0x{:02x}".format(vol.type)
-
-def vol_state(vol):
-    if vol.inUse:
-        s = "On-line"
-    else:
-        s = "Off-line"
-    try:
-        # This isn't available in struct xvolintInfo
-        if vol.needsSalvaged:
-            s += "**needs salvage**"
-    except AttributeError:
-        pass
-    return s
-
-def vol_status(vol):
-    if vol.status == kafs.VOK:
-        return "OK"
-    if vol.status == kafs.VBUSY:
-        return "BUSY"
-    return "UNATTACHABLE"
-
-def vol_date(d, never = False):
-    if d == 0 and never:
-        return "Never"
-    t = datetime.datetime.fromtimestamp(d)
-    return t.strftime("%a %b %d %H:%M:%S %Y")
-
-def yes_or_no(n):
-    if (n):
-        return "Y"
-    return "N"
-
-def display_normal(params, vol):
-    print("{:32s} {:10d} {:2s} {:10d} K {:s}".format(vol.name,
-                                                     vol.volid,
-                                                     vol_type(vol),
-                                                     vol.size,
-                                                     vol_state(vol)))
-
 def display_fast(params, vol):
     print(vol.volid)
 
-def display_long(params, vol):
-    display_normal(params, vol)
-    print("   ", params["server"], params["_partname"])
-    print("   ", "RWrite {:10d} ROnly {:10d} Backup {:10d}".format(vol.parentID,
-                                                                   vol.cloneID,
-                                                                   vol.backupID))
-    print("   ", "MaxQuota {:10d} K".format(vol.maxquota))
-    print("   ", "Creation   ", vol_date(vol.creationDate, True))
-    print("   ", "Copy       ", vol_date(vol.copyDate, True))
-    print("   ", "Backup     ", vol_date(vol.backupDate, True))
-    print("   ", "Last Access", vol_date(vol.accessDate, True))
-    print("   ", "Last Update", vol_date(vol.updateDate, True))
-    print("   ", vol.dayUse, "accesses in the past day (i.e., vnode references)")
-    print()
-
 def display_extended(params, vol):
     display_long(params, vol)
-    print("                      Raw Read/Write Stats")
-    print("          |-------------------------------------------|")
-    print("          |    Same Network     |    Diff Network     |")
-    print("          |----------|----------|----------|----------|")
-    print("          |  Total   |   Auth   |   Total  |   Auth   |")
-    print("          |----------|----------|----------|----------|")
-    print("Reads     |{:9d} |{:9d} |{:9d} |{:9d} |".format(vol.stat_reads[0],
-                                                           vol.stat_reads[1],
-                                                           vol.stat_reads[2],
-                                                           vol.stat_reads[3]))
-    print("Writes    |{:9d} |{:9d} |{:9d} |{:9d} |".format(vol.stat_writes[0],
-                                                           vol.stat_writes[1],
-                                                           vol.stat_writes[2],
-                                                           vol.stat_writes[3]))
-    print("          |-------------------------------------------|")
-
-    print()
-    print("                   Writes Affecting Authorship")
-    print("          |-------------------------------------------|")
-    print("          |   File Authorship   | Directory Authorship|")
-    print("          |----------|----------|----------|----------|")
-    print("          |   Same   |   Diff   |    Same  |   Diff   |")
-    print("          |----------|----------|----------|----------|")
-
-    ranges = [
-        "0-60 sec ",
-        "1-10 min ",
-        "10min-1hr",
-        "1hr-1day ",
-        "1day-1wk ",
-        "> 1wk    "
-    ]
-
-    for i in range(0, 5):
-        print("{:s} |{:9d} |{:9d} |{:9d} |{:9d} |".format(ranges[i],
-                                                          vol.stat_fileSameAuthor[i],
-                                                          vol.stat_fileDiffAuthor[i],
-                                                          vol.stat_dirSameAuthor[i],
-                                                          vol.stat_dirDiffAuthor[i]))
-    print("          |-------------------------------------------|")
-    print()
-
-def display_format_basic(params, vol):
-    server = params["server"]
-    print("BEGIN_OF_ENTRY")
-    print("name\t\t{:s}".format(vol.name))
-    print("id\t\t{:d}".format(vol.volid))
-    print("serv\t\t{:<15s}\t{:s}".format(str(server), server.addr()))
-    print("part\t\t{:s}".format(params["_partname"]))
-    print("status\t\t{:s}".format(vol_status(vol)))
-    print("backupID\t{:d}".format(vol.backupID))
-    print("parentID\t{:d}".format(vol.parentID))
-    print("cloneID\t\t{:d}".format(vol.cloneID))
-    print("inUse\t\t{:s}".format(yes_or_no(vol.inUse)))
-    try:
-        print("needsSalvaged\t{:s}".format(yes_or_no(vol.needsSalvaged)))
-        print("destroyMe\t{:s}".format(yes_or_no(vol.destroyMe)))
-    except AttributeError:
-        pass
-    print("type\t\t{:s}".format(vol_type(vol)))
-    print("creationDate\t{:<10d}\t{:s}".format(vol.creationDate, vol_date(vol.creationDate)))
-    print("accessDate\t{:<10d}\t{:s}".format(vol.accessDate, vol_date(vol.accessDate)))
-    print("updateDate\t{:<10d}\t{:s}".format(vol.updateDate, vol_date(vol.updateDate)))
-    print("backupData\t{:<10d}\t{:s}".format(vol.backupDate, vol_date(vol.backupDate)))
-    print("copyDate\t{:<10d}\t{:s}".format(vol.copyDate, vol_date(vol.copyDate)))
-    try:
-        print("flags\t\t{:<7d}\t(Optional)".format(vol.flags))
-    except AttributeError:
-        pass
-    print("diskused\t{:d}".format(vol.size))
-    print("maxquota\t{:d}".format(vol.maxquota))
-    try:
-        print("minquota\t{:<7d}\t(Optional)".format(vol.spare0))
-    except AttributeError:
-        pass
-    print("filecount\t{:d}".format(vol.filecount))
-    print("dayUse\t\t{:d}".format(vol.dayUse))
+    display_vol_statistics(params, vol)
 
 def display_format_normal(params, vol):
-    display_format_basic(params, vol)
-    print("weekUse\t\t{:<7d}\t(Optional)".format(vol.spare1))
-    print("spare2\t\t{:<7d}\t(Optional)".format(vol.spare2))
-    print("spare3\t\t{:<7d}\t(Optional)".format(vol.spare3))
+    display_vol_mp_information(params, vol)
     print("END_OF_ENTRY")
 
 reads_labels = [ "reads_same_net", "reads_same_net_auth",
@@ -223,7 +83,7 @@ def display_format_extended(params, vol):
         print("COULD_NOT_ATTACH_VOLUME\t{:d}\n", vol.volid)
         return
 
-    display_format_basic(params, vol)
+    display_vol_mp_basic_information(params, vol)
 
     for i in range(0, 4):
         print("{:s}\t{:8d}".format(reads_labels[i], vol.stat_reads[i]))
@@ -253,7 +113,7 @@ def display_one_partition(params, vol_conn, partition):
         print("Total number of volumes on server", params["server"], "partition",
               partname + ":", len(ret.resultEntries))
 
-    display_func = display_normal
+    display_func = display_vol_oneline_summary
     if "fast" in params:
         display_func = display_fast
     elif "format" in params and "extended" in params:
@@ -263,7 +123,7 @@ def display_one_partition(params, vol_conn, partition):
     elif "extended" in params:
         display_func = display_extended
     elif "long" in params:
-        display_func = display_long
+        display_func = display_vol_information
 
     n_online = 0
     n_offline = 0
@@ -288,6 +148,11 @@ def display_one_partition(params, vol_conn, partition):
             print("VOLUMES_OFFLINE", n_offline)
             print("VOLUMES_BUSY   ", n_busy)
 
+###############################################################################
+#
+#
+#
+###############################################################################
 def main(params):
     cell = params["cell"]
     vol_conn = cell.open_volume_server(params["server"], params)
diff --git a/suite/lib/voldisplay.py b/suite/lib/voldisplay.py
new file mode 100644 (file)
index 0000000..c5cf0ba
--- /dev/null
@@ -0,0 +1,330 @@
+#
+# AFS Volume management toolkit: Volume / Volume location display common pieces
+# -*- coding: utf-8 -*-
+#
+
+__copyright__ = """
+Copyright (C) 2014 Red Hat, Inc. All Rights Reserved.
+Written by David Howells (dhowells@redhat.com)
+
+This program is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public Licence 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 Licence for more details.
+
+You should have received a copy of the GNU General Public Licence
+along with this program; if not, write to the Free Software
+Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+"""
+
+import afs.lib.addrcache as addrcache
+import afs.lib.partition as partition
+import kafs
+import datetime
+
+statistics_time_ranges = [
+    "0-60 sec ",
+    "1-10 min ",
+    "10min-1hr",
+    "1hr-1day ",
+    "1day-1wk ",
+    "> 1wk    "
+]
+
+def vol_type(vol):
+    if vol.type == 0:
+        return "RW"
+    if vol.type == 1:
+        return "RO"
+    if vol.type == 2:
+        return "BK"
+    return "0x{:02x}".format(vol.type)
+
+def vol_state(vol):
+    if vol.inUse:
+        s = "On-line"
+    else:
+        s = "Off-line"
+    try:
+        # This isn't available in struct xvolintInfo
+        if vol.needsSalvaged:
+            s += "**needs salvage**"
+    except AttributeError:
+        pass
+    return s
+
+def vol_status(vol):
+    if vol.status == kafs.VOK:
+        return "OK"
+    if vol.status == kafs.VBUSY:
+        return "BUSY"
+    return "UNATTACHABLE"
+
+def vol_date(d, never = False):
+    if d == 0 and never:
+        return "Never"
+    t = datetime.datetime.fromtimestamp(d)
+    return t.strftime("%a %b %d %H:%M:%S %Y")
+
+def yes_or_no(n):
+    if (n):
+        return "Y"
+    return "N"
+
+###############################################################################
+#
+# Display the VLDB site list, looking something like:
+#
+#       number of sites -> 2
+#          server fserver.abc.com partition /vicepa RW Site
+#          server fserver.abc.com partition /vicepa RO Site
+#
+###############################################################################
+def display_vldb_site_list(params, vldb, indent=""):
+    print(indent, "number of sites ->", vldb.nServers)
+    for i in range(0, vldb.nServers):
+        addr = addrcache.resolve(params, vldb.serverNumber[i])
+        part = partition.id2part(vldb.serverPartition[i])
+
+        flags = vldb.serverFlags[i]
+        if flags & kafs.VLSF_ROVOL:
+            ptype = "RO"
+        elif flags & kafs.VLSF_RWVOL:
+            ptype = "RW"
+        else:
+            ptype = "Back"
+
+        print(indent, "   server {:s} partition {:s} {:s} Site".format(addr, part, ptype))
+
+    if vldb.flags & (kafs.VLOP_MOVE |
+                     kafs.VLOP_RELEASE |
+                     kafs.VLOP_BACKUP |
+                     kafs.VLOP_DELETE |
+                     kafs.VLOP_DUMP):
+        print(indent, "Volume is currently LOCKED")
+        if vldb.flags & kafs.VLOP_MOVE:
+            print(indent, "Volume is locked for a move operation")
+        if vldb.flags & kafs.VLOP_RELEASE:
+            print(indent, "Volume is locked for a release operation")
+        if vldb.flags & kafs.VLOP_BACKUP:
+            print(indent, "Volume is locked for a backup operation")
+        if vldb.flags & kafs.VLOP_DELETE:
+            print(indent, "Volume is locked for a delete/misc operation")
+        if vldb.flags & kafs.VLOP_DUMP:
+            print(indent, "Volume is locked for a dump/restore operation")
+
+###############################################################################
+#
+# Display a one-line volume summary
+#
+#       proj.foo                          536870957 RW   40475760 K On-line
+#
+###############################################################################
+def display_vol_oneline_summary(params, vol):
+    print("{:32s} {:10d} {:2s} {:10d} K {:s}".format(vol.name,
+                                                     vol.volid,
+                                                     vol_type(vol),
+                                                     vol.size,
+                                                     vol_state(vol)))
+
+###############################################################################
+#
+# Display volume information
+#
+#       proj.foo                          536870957 RW   40475760 K On-line
+#           204.29.154.47 /vicepa
+#           RWrite  536870957 ROnly  536870958 Backup          0
+#           MaxQuota          0 K
+#           Creation    Sat Aug 22 06:22:27 2009
+#           Copy        Tue Oct 26 00:40:32 2010
+#           Backup      Never
+#           Last Access Tue Jan 28 23:20:37 2014
+#           Last Update Mon Aug 05 21:15:32 2013
+#           0 accesses in the past day (i.e., vnode references)
+#       <blank>
+#
+###############################################################################
+def display_vol_information(params, vol):
+    display_vol_oneline_summary(params, vol)
+    print("   ", params["server"], params["_partname"])
+    print("   ", "RWrite {:10d} ROnly {:10d} Backup {:10d}".format(vol.parentID,
+                                                                   vol.cloneID,
+                                                                   vol.backupID))
+    print("   ", "MaxQuota {:10d} K".format(vol.maxquota))
+    print("   ", "Creation   ", vol_date(vol.creationDate, True))
+    print("   ", "Copy       ", vol_date(vol.copyDate, True))
+    print("   ", "Backup     ", vol_date(vol.backupDate, True))
+    print("   ", "Last Access", vol_date(vol.accessDate, True))
+    print("   ", "Last Update", vol_date(vol.updateDate, True))
+    print("   ", vol.dayUse, "accesses in the past day (i.e., vnode references)")
+    print()
+
+###############################################################################
+#
+# Display volume access statistics
+#
+#                             Raw Read/Write Stats
+#                 |-------------------------------------------|
+#                 |    Same Network     |    Diff Network     |
+#                 |----------|----------|----------|----------|
+#                 |  Total   |   Auth   |   Total  |   Auth   |
+#                 |----------|----------|----------|----------|
+#       Reads     |        0 |        0 |        0 |        0 |
+#       Writes    |        0 |        0 |        0 |        0 |
+#                 |-------------------------------------------|
+#       <blank>
+#                          Writes Affecting Authorship
+#                 |-------------------------------------------|
+#                 |   File Authorship   | Directory Authorship|
+#                 |----------|----------|----------|----------|
+#                 |   Same   |   Diff   |    Same  |   Diff   |
+#                 |----------|----------|----------|----------|
+#       0-60 sec  |        0 |        0 |        0 |        0 |
+#       1-10 min  |        0 |        0 |        0 |        0 |
+#       10min-1hr |        0 |        0 |        0 |        0 |
+#       1hr-1day  |        0 |        0 |        0 |        0 |
+#       1day-1wk  |        0 |        0 |        0 |        0 |
+#       > 1wk     |        0 |        0 |        0 |        0 |
+#                 |-------------------------------------------|
+#
+###############################################################################
+def display_vol_statistics(params, vol):
+    print("                      Raw Read/Write Stats")
+    print("          |-------------------------------------------|")
+    print("          |    Same Network     |    Diff Network     |")
+    print("          |----------|----------|----------|----------|")
+    print("          |  Total   |   Auth   |   Total  |   Auth   |")
+    print("          |----------|----------|----------|----------|")
+    print("Reads     |{:9d} |{:9d} |{:9d} |{:9d} |".format(vol.stat_reads[0],
+                                                           vol.stat_reads[1],
+                                                           vol.stat_reads[2],
+                                                           vol.stat_reads[3]))
+    print("Writes    |{:9d} |{:9d} |{:9d} |{:9d} |".format(vol.stat_writes[0],
+                                                           vol.stat_writes[1],
+                                                           vol.stat_writes[2],
+                                                           vol.stat_writes[3]))
+    print("          |-------------------------------------------|")
+
+    print()
+    print("                   Writes Affecting Authorship")
+    print("          |-------------------------------------------|")
+    print("          |   File Authorship   | Directory Authorship|")
+    print("          |----------|----------|----------|----------|")
+    print("          |   Same   |   Diff   |    Same  |   Diff   |")
+    print("          |----------|----------|----------|----------|")
+
+    for i in range(0, 5):
+        print("{:s} |{:9d} |{:9d} |{:9d} |{:9d} |".format(statistics_time_ranges[i],
+                                                          vol.stat_fileSameAuthor[i],
+                                                          vol.stat_fileDiffAuthor[i],
+                                                          vol.stat_dirSameAuthor[i],
+                                                          vol.stat_dirDiffAuthor[i]))
+    print("          |-------------------------------------------|")
+    print()
+
+###############################################################################
+#
+# Display machine parseable form of volume record, but excluding certain info
+#
+#       name            proj.foo
+#       id              536870957
+#       serv            111.22.33.44   foo.abc.com
+#       part            /vicepa
+#       status          OK
+#       backupID        0
+#       parentID        536870957
+#       cloneID         536870958
+#       inUse           Y
+#       needsSalvaged   N
+#       destroyMe       N
+#       type            RW
+#       creationDate    1250918547      Sat Aug 22 06:22:27 2009
+#       accessDate      1390951237      Tue Jan 28 23:20:37 2014
+#       updateDate      1375733732      Mon Aug  5 21:15:32 2013
+#       backupDate      0               Thu Jan  1 01:00:00 1970
+#       copyDate        1288050032      Tue Oct 26 00:40:32 2010
+#       flags           0       (Optional)
+#       diskused        40475760
+#       maxquota        0
+#       minquota        0       (Optional)
+#       filecount       327
+#       dayUse          0
+#
+###############################################################################
+def display_vol_mp_basic_information(params, vol):
+    server = params["server"]
+    print("BEGIN_OF_ENTRY")
+    print("name\t\t{:s}".format(vol.name))
+    print("id\t\t{:d}".format(vol.volid))
+    print("serv\t\t{:<15s}\t{:s}".format(str(server), server.addr()))
+    print("part\t\t{:s}".format(params["_partname"]))
+    print("status\t\t{:s}".format(vol_status(vol)))
+    print("backupID\t{:d}".format(vol.backupID))
+    print("parentID\t{:d}".format(vol.parentID))
+    print("cloneID\t\t{:d}".format(vol.cloneID))
+    print("inUse\t\t{:s}".format(yes_or_no(vol.inUse)))
+    try:
+        print("needsSalvaged\t{:s}".format(yes_or_no(vol.needsSalvaged)))
+        print("destroyMe\t{:s}".format(yes_or_no(vol.destroyMe)))
+    except AttributeError:
+        pass
+    print("type\t\t{:s}".format(vol_type(vol)))
+    print("creationDate\t{:<10d}\t{:s}".format(vol.creationDate, vol_date(vol.creationDate)))
+    print("accessDate\t{:<10d}\t{:s}".format(vol.accessDate, vol_date(vol.accessDate)))
+    print("updateDate\t{:<10d}\t{:s}".format(vol.updateDate, vol_date(vol.updateDate)))
+    print("backupData\t{:<10d}\t{:s}".format(vol.backupDate, vol_date(vol.backupDate)))
+    print("copyDate\t{:<10d}\t{:s}".format(vol.copyDate, vol_date(vol.copyDate)))
+    try:
+        print("flags\t\t{:<7d}\t(Optional)".format(vol.flags))
+    except AttributeError:
+        pass
+    print("diskused\t{:d}".format(vol.size))
+    print("maxquota\t{:d}".format(vol.maxquota))
+    try:
+        print("minquota\t{:<7d}\t(Optional)".format(vol.spare0))
+    except AttributeError:
+        pass
+    print("filecount\t{:d}".format(vol.filecount))
+    print("dayUse\t\t{:d}".format(vol.dayUse))
+
+###############################################################################
+#
+# Display machine parseable form of volume record
+#
+#       name            proj.foo
+#       id              536870957
+#       serv            111.22.33.44   foo.abc.com
+#       part            /vicepa
+#       status          OK
+#       backupID        0
+#       parentID        536870957
+#       cloneID         536870958
+#       inUse           Y
+#       needsSalvaged   N
+#       destroyMe       N
+#       type            RW
+#       creationDate    1250918547      Sat Aug 22 06:22:27 2009
+#       accessDate      1390951237      Tue Jan 28 23:20:37 2014
+#       updateDate      1375733732      Mon Aug  5 21:15:32 2013
+#       backupDate      0               Thu Jan  1 01:00:00 1970
+#       copyDate        1288050032      Tue Oct 26 00:40:32 2010
+#       flags           0       (Optional)
+#       diskused        40475760
+#       maxquota        0
+#       minquota        0       (Optional)
+#       filecount       327
+#       dayUse          0
+#       weekUse         0       (Optional)
+#       spare2          21775   (Optional)
+#       spare3          0       (Optional)
+#
+###############################################################################
+def display_vol_mp_information(params, vol):
+    display_vol_mp_basic_information(params, vol)
+    print("weekUse\t\t{:<7d}\t(Optional)".format(vol.spare1))
+    print("spare2\t\t{:<7d}\t(Optional)".format(vol.spare2))
+    print("spare3\t\t{:<7d}\t(Optional)".format(vol.spare3))