]> www.infradead.org Git - users/dhowells/kafs-utils.git/commitdiff
Implement "vos listvol"
authorDavid Howells <dhowells@redhat.com>
Wed, 9 Apr 2014 23:13:39 +0000 (00:13 +0100)
committerDavid Howells <dhowells@redhat.com>
Thu, 10 Apr 2014 10:20:03 +0000 (11:20 +0100)
Signed-off-by: David Howells <dhowells@redhat.com>
suite/commands/vos/listvol.py [new file with mode: 0644]

diff --git a/suite/commands/vos/listvol.py b/suite/commands/vos/listvol.py
new file mode 100644 (file)
index 0000000..489cb88
--- /dev/null
@@ -0,0 +1,306 @@
+#
+# 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
+import afs.lib.addrcache as addrcache
+import kafs
+import sys
+import datetime
+
+help = "Display information from a volume header"
+
+command_arguments = [
+    [ "server",         get_volserver,          "rs",         "<machine name>" ],
+    [ "partition",      get_partition_id,       "os",         "<partition name>" ],
+    [ "fast",           get_dummy,              "fn" ],
+    [ "long",           get_dummy,              "fn" ],
+    [ "quiet",          get_dummy,              "fn" ],
+    [ "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" ),
+    ( "fast",           "extended" ),
+]
+
+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))
+
+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))
+    print("END_OF_ENTRY")
+
+reads_labels = [ "reads_same_net", "reads_same_net_auth",
+                 "reads_diff_net", "reads_diff_net_auth" ]
+
+writes_labels = [ "writes_same_net", "writes_same_net_auth",
+                  "writes_diff_net", "writes_diff_net_auth" ]
+
+def display_format_extended(params, vol):
+    if vol.status == kafs.VBUSY:
+        print("VOLUME_BUSY\t{:d}\n", vol.volid)
+        return
+    elif vol.status != kafs.VOK:
+        print("COULD_NOT_ATTACH_VOLUME\t{:d}\n", vol.volid)
+        return
+
+    display_format_basic(params, vol)
+
+    for i in range(0, 4):
+        print("{:s}\t{:8d}".format(reads_labels[i], vol.stat_reads[i]))
+    for i in range(0, 4):
+        print("{:s}\t{:8d}".format(writes_labels[i], vol.stat_writes[i]))
+    for i in range(0, 6):
+        print("file_same_author_idx_{:d}\t{:8d}".format(i, vol.stat_fileSameAuthor[i]))
+        print("file_diff_author_idx_{:d}\t{:8d}".format(i, vol.stat_fileDiffAuthor[i]))
+        print("dir_same_author_idx_{:d}\t{:8d}".format(i, vol.stat_dirSameAuthor[i]))
+        print("dir_dif_author_idx_{:d}\t{:8d}".format(i, vol.stat_dirDiffAuthor[i]))
+
+    print("END_OF_ENTRY")
+
+###############################################################################
+#
+# Display the records for a single partition in the appropriate format
+#
+###############################################################################
+def display_one_partition(params, vol_conn, partition):
+    if "extended" in params:
+        ret = kafs.VOLSER_AFSVolXListVolumes(vol_conn, partition, 1)
+    else:
+        ret = kafs.VOLSER_AFSVolListVolumes(vol_conn, partition, 1)
+
+    params["_partname"] = partname = id2part(partition)
+    if "quiet" not in params:
+        print("Total number of volumes on server", params["server"], "partition",
+              partname + ":", len(ret.resultEntries))
+
+    display_func = display_normal
+    if "fast" in params:
+        display_func = display_fast
+    elif "format" in params and "extended" in params:
+        display_func = display_format_extended
+    elif "format" in params:
+        display_func = display_format_normal
+    elif "extended" in params:
+        display_func = display_extended
+    elif "long" in params:
+        display_func = display_long
+
+    n_online = 0
+    n_offline = 0
+    n_busy = 0
+    volumes = ret.resultEntries
+    volumes.sort(key=lambda vol: vol.name)
+    for vol in volumes:
+        if vol.inUse:
+            n_online += 1
+        if vol.status == kafs.VBUSY:
+            n_busy += 1
+        display_func(params, vol)
+
+    if "quiet" not in params:
+        print()
+        if "fast" not in params and "format" not in params:
+            print("Total volumes onLine", n_online, "; Total volumes offLine", n_offline,
+                  "; Total busy", n_busy)
+            print()
+        elif "format" in params and "extended" in params:
+            print("VOLUMES_ONLINE ", n_online)
+            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)
+
+    if "partition" in params:
+        try:
+            display_one_partition(params, vol_conn, params["partition"])
+        except kafs.AbortVOLSERILLEGAL_PARTITION:
+            print("vos : partition", params["raw.partition"][0],
+                  "does not exist on the server", file=sys.stderr)
+            sys.exit(2)
+
+    else:
+        ret = kafs.VOLSER_AFSVolXListPartitions(vol_conn)
+        for p in ret.ent:
+            one_partition(params, vol_conn, p)