Kanjut SHELL
Server IP : 172.16.15.8  /  Your IP : 18.117.78.215
Web Server : Apache
System : Linux zeus.vwu.edu 4.18.0-553.27.1.el8_10.x86_64 #1 SMP Wed Nov 6 14:29:02 UTC 2024 x86_64
User : apache ( 48)
PHP Version : 7.2.24
Disable Function : NONE
MySQL : OFF  |  cURL : ON  |  WGET : ON  |  Perl : ON  |  Python : ON
Directory (0555) :  /../bin/

[  Home  ][  C0mmand  ][  Upload File  ]

Current File : //../bin/vdostats
#! /usr/libexec/platform-python

#
# Copyright Red Hat
#
# This program is free software; you can redistribute it and/or
# modify it under the terms of the GNU General Public License
# as published by the Free Software Foundation; either version 2
# of the License, or (at your option) any later version.
# 
# 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., 51 Franklin Street, Fifth Floor, Boston, MA
# 02110-1301, USA. 
#

"""
  vdoStats - Report statistics from an Albireo VDO.

  $Id: //eng/vdo-releases/aluminum/src/python/vdo/vdoStats#6 $
"""
from __future__ import absolute_import
from __future__ import division
from __future__ import print_function
from __future__ import unicode_literals

import argparse
import errno
import gettext
import locale
import os
import sys

from vdo.statistics import *
from vdo.utils import Command, CommandError, runCommand

gettext.install('vdo')

parser = argparse.ArgumentParser(
  description="Get configuration and statistics from a running VDO volume")

parser.add_argument("--all", "-a", action="store_true", dest="all",
                    help=_("Equivalent to --verbose"))
parser.add_argument("--human-readable", action="store_true",
                    dest="humanReadable",
                    help=_("Display stats in human-readable form"))
parser.add_argument("--si", action="store_true", dest="si",
                    help=_("Use SI units, implies --human-readable"))
parser.add_argument("--verbose", "-v", action="store_true", dest="verbose",
                    help=_("Include verbose statistics"))
parser.add_argument("--version", "-V", action="store_true", dest="version",
                    help=_("Print the vdostats version number and exit"))
parser.add_argument("devices", metavar="DEVICE", help="a VDO device", nargs="*")
                    

UNITS = [ 'B', 'K', 'M', 'G', 'T' ]

########################################################################
def makeDedupeFormatter(options):
  """
  Make the formatter for dedupe stats if needed.

  :param options:  The command line options

  :return: A formatter if needed or None
  """
  if not options.verbose:
    return None

  return StatFormatter([{ 'namer' : '+'  },
                        { 'indent': '  ', 'namer' : True }],
                       hierarchical=False)

########################################################################
def enumerateDevices():
  """
  Enumerate the list of VDO devices on this host.

  :return: A list of VDO device names
  """
  names = []
  try:
    names = [name.split(":")[0] for name in
             runCommand(["dmsetup", "status", "--target", "vdo"]).splitlines()
             if len(name) > 0]
    paths = [os.path.sep.join(["", "dev", "mapper", name]) for name in names]
    names = list(filter(os.path.exists, paths))
  except CommandError as e:
    print(_("Error enumerating VDO devices: {0}".format(e)), file = sys.stderr)
  return names

########################################################################
def transformDevices(devices):
  """
  Iterates over the list of provided devices transforming any standalone device
  name or absolute path that represents a resolved vdo device to the name/path
  of the vdo device using the vdo name specified at its creation.

  Returns a list of sampling dictionaries.

  :param devices: A list of devices to sample.

  :return:  The dictionary list of devices to sample.
  """
  paths = enumerateDevices()
  names = [os.path.basename(x) for x in paths]
  resolvedPaths = [os.path.realpath(x) for x in paths]
  resolvedNames = [os.path.basename(x) for x in resolvedPaths]
  resolvedToVdoName = dict(list(zip(resolvedNames, names)))
  resolvedToVdoPath = dict(list(zip(resolvedPaths, paths)))

  transformedDevices = []
  for (original, (head, tail)) in [(x, os.path.split(x)) for x in devices]:
    if tail in names:
      transformedDevices.append(Samples.samplingDevice(original, original))
      continue
    if tail in resolvedNames:
      if head == '':
        transformedDevices.append(
          Samples.samplingDevice(original, resolvedToVdoName[tail]))
        continue
      if os.path.isabs(original) and (original in resolvedPaths):
        transformedDevices.append(
          Samples.samplingDevice(original, resolvedToVdoPath[original]))
        continue
    transformedDevices.append(Samples.samplingDevice(original, original))

  return transformedDevices

########################################################################
def getDeviceStats(devices, assays):
  """
  Get the statistics for a given device.

  :param devices:  A list of devices to sample. If empty, all VDOs will
                   be sampled.
  :param assays:   The types of samples to take for each device

  :return:  A tuple whose first entry is the Samples and whose second entry
            is the exit status to use if no subsequent error occurs.
  """
  exitStatus = 0
  if not devices:
    mustBeVDO = False
    devices = [Samples.samplingDevice(x, x) for x in enumerateDevices()]
  else:
    mustBeVDO = True

    # Get the device dictionary containing transformations of references to a
    # vdo device's resolved name/path to references to its symbolic name/path.
    devices = transformDevices(devices)

    # Filter out any specified devices that do not exist.
    #
    # Any specified device that passes os.path.exists is passed through.
    # If it fails os.path.exists and is not a full path it is checked
    # against being an entry in either /dev/mapper or /proc/vdo.
    # If either of those exists the original device is passed through
    # unchanged.
    existingDevices = []
    for device in devices:
      user = device["user"]
      sample = device["sample"]
      if os.path.exists(sample):
        existingDevices.append(device)
      else:
        exists = False
        if (not os.path.isabs(sample)):
          exists = os.path.exists(os.path.sep.join(["", "dev", "mapper",
                                                    sample]))
          if (not exists):
            sample = os.path.sep.join(["", "proc", "vdo", sample])

        if ((not exists) and (not os.path.exists(sample))):
          print("'{0}': {1}".format(user, os.strerror(errno.ENOENT)),
                file = sys.stderr)
          exitStatus = 1
        else:
          existingDevices.append(device)
    devices = existingDevices

  if len(devices) > 0:
    return (Samples.assayDevices(assays, devices, mustBeVDO), exitStatus)
  return (None, exitStatus)

########################################################################
def formatSize(size, options):
  """
  Format a size (in KB) for printing.

  :param size:    The size in bytes.
  :param options: The command line options

  :return: The size formatted for printing based on the options
  """
  if isinstance(size, NotAvailable):
    return size

  if not options.humanReadable:
    return size

  size    *= 1024
  divisor  = 1000.0 if options.si else 1024.0
  unit     = 0
  while ((size >= divisor) and (unit < (len(UNITS) - 1))):
    size /= divisor
    unit += 1

  return "{0:>.1f}{1}".format(size, UNITS[unit])

########################################################################
def formatPercent(value):
  """
  Format a percentage for printing.

  :param value: The value to format

  :return: The formatted value
  """
  return value if isinstance(value, NotAvailable) else "{0}%".format(value)

########################################################################
def dfStats(sample, options):
  """
  Extract the values needed for df-style output from a sample.

  :param sample:  The sample from which to extract df values
  :param options: The command line options
  """
  return ([formatSize(sample.getStat(statName), options)
           for statName in
           ["oneKBlocks", "oneKBlocksUsed", "oneKBlocksAvailable"]]
          + [formatPercent(sample.getStat(statName))
             for statName in ["usedPercent", "savingPercent"]])

########################################################################
def printDF(stats, options):
  """
  Print stats in df-style.

  :param stats:   A list of samples, one for each device sampled
  :param options: The command line options
  """
  dfFormat = "{0:<20} {1:>9} {2:>9} {3:>9} {4:>4} {5:>13}"
  print(dfFormat.format("Device",
                        "Size" if options.humanReadable else "1K-blocks",
                        "Used", "Available", "Use%", "Space saving%"))
  for stat in stats:
    lst = [stat.getDevice()] + dfStats(stat.getSamples()[0], options)
    print(dfFormat.format(*lst))

########################################################################
def printYAML(stats, dedupeFormatter):
  """
  Print stats as (pseudo) YAML.

  :param stats:           A list of Samples, one for each device sampled
  :param dedupeFormatter: The formatter for dedupe stats (may be None)
  """
  for stat in stats:
    samples = stat.getSamples()
    if dedupeFormatter:
      dedupeFormatter.output(LabeledValue.make(stat.getDevice(),
                                               [s.labeled() for s in samples]))

########################################################################
def main():
  try:
    locale.setlocale(locale.LC_ALL, '')
  except locale.Error:
    pass

  options = parser.parse_args()
  if options.version:
    print("{0}.{1}".format(CURRENT_RELEASE_VERSION_NUMBER,
                           VDOStatistics.statisticsVersion))
    sys.exit(0)

  if options.all:
    options.verbose = True
  if options.si:
    options.humanReadable = True

  dedupeFormatter = makeDedupeFormatter(options)

  if options.verbose:
    statsTypes = [VDOStatistics(), KernelStatistics()]
  else:
    statsTypes = [VDOStatistics()]

  exitStatus = 0
  try:
    (stats, exitStatus) = getDeviceStats(options.devices, statsTypes)
    if not stats:
      return exitStatus
  except Exception as e:
    print(e, file = sys.stderr)
    return 1

  if options.verbose:
    printYAML(stats, dedupeFormatter)
  else:
    printDF(stats, options)

  return exitStatus

########################################################################
if __name__ == "__main__":
  sys.exit(main())

Stv3n404 - 2023