From: David Howells Date: Wed, 9 Apr 2014 23:13:39 +0000 (+0100) Subject: Implement "vos listvol" X-Git-Url: https://www.infradead.org/git/?a=commitdiff_plain;h=d89c23aefbf0a3a7a52a7e92a09c5befd96384eb;p=users%2Fdhowells%2Fkafs-utils.git Implement "vos listvol" Signed-off-by: David Howells --- diff --git a/suite/commands/vos/listvol.py b/suite/commands/vos/listvol.py new file mode 100644 index 0000000..489cb88 --- /dev/null +++ b/suite/commands/vos/listvol.py @@ -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", "" ], + [ "partition", get_partition_id, "os", "" ], + [ "fast", get_dummy, "fn" ], + [ "long", get_dummy, "fn" ], + [ "quiet", get_dummy, "fn" ], + [ "extended", get_dummy, "fn" ], + [ "format", get_dummy, "fn" ], + [ "cell", get_cell, "os", "" ], + [ "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)