blob: 4663cbfe56487f941ee18bb0817ec3faa6dbe768 [file] [log] [blame]
#!/usr/bin/env python
# Licensed to the Apache Software Foundation (ASF) under one
# or more contributor license agreements. See the NOTICE file
# distributed with this work for additional information
# regarding copyright ownership. The ASF licenses this file
# to you under the Apache License, Version 2.0 (the
# "License"); you may not use this file except in compliance
# with the License. You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing,
# software distributed under the License is distributed on an
# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
# KIND, either express or implied. See the License for the
# specific language governing permissions and limitations
# under the License.
'''
USAGE: gp_df [-m]
platform independent df command
where -m will display output in megabytes
'''
import os, re, sys, time, subprocess
try:
from optparse import Option, OptionParser
from gppylib.gpparseopts import OptParser, OptChecker
from gppylib.commands.unix import SYSTEM
except ImportError, e:
sys.exit('Cannot import modules. Please check that you have sourced greenplum_path.sh. Detail: ' + str(e))
class BytesFormatter:
BYTES = 1
KILOBYTES = 2
MEGABYTES = 3
class FileSystem:
def __init__(self, device, dir, type):
self.device = device
self.dir = dir
self.type = type
self.total_bytes = 0
self.used_bytes = 0
self.available_bytes = 0
@staticmethod
def PrintHeader(formatter):
if formatter == BytesFormatter.BYTES:
used = "USED_BYTES"
available = "AVAILABLE_BYTES"
elif formatter == BytesFormatter.KILOBYTES:
used = "USED_KB"
available = "AVAILABLE_KB"
elif formatter == BytesFormatter.MEGABYTES:
used = "USED_MB"
available = "AVAILABLE_MB"
else:
raise Exception("unknown bytes formatter")
print "%s %s %s %s %s" % ("DEVICE", "DIR", "TYPE", used, available)
def Print(self, formatter):
try:
if formatter == BytesFormatter.BYTES:
used = self.used_bytes
available = self.available_bytes
elif formatter == BytesFormatter.KILOBYTES:
used = int(self.used_bytes/1024)
available = int(self.available_bytes/1024)
elif formatter == BytesFormatter.MEGABYTES:
used = int(self.used_bytes/1024/1024)
available = int(self.available_bytes/1024/1024)
else:
raise Exception("unknown bytes formatter")
except Exception, e:
print >> sys.stderr, e.__str__()
print >> sys.stderr, "Error converting disk usage to numerical form"
sys.exit(1)
except:
print >> sys.stderr, "Error converting disk usage to numerical form"
sys.exit(1)
print "%s %s %s %d %d" % (self.device, self.dir, self.type, used, available)
def getLinuxDirectoryList():
interestedFSTypes = set(['xfs', 'ext3', 'ext4'])
fsList = []
try:
fd = open('/proc/mounts')
buffer = fd.read()
fd.close()
for line in buffer.splitlines():
fields = line.split()
if len(fields) != 6:
raise Exception("Wrong number of fields in /proc/mounts entry: %s" % line.strip())
if fields[2] not in interestedFSTypes:
continue
fsList.append(FileSystem(device=fields[0], dir=fields[1], type=fields[2]))
except Exception, e:
print >> sys.stderr, e.__str__()
print >> sys.stderr, "Error reading list of mounts"
sys.exit(1)
except:
print >> sys.stderr, "Error reading list of mounts"
sys.exit(1)
return fsList
def getSolarisDirectoryList():
cmd = "zfs list -H -t filesystem -o name,mountpoint"
p = subprocess.Popen(cmd, shell = True, stdout = subprocess.PIPE, stderr = subprocess.PIPE)
result = p.communicate()
errormsg = result[1].strip()
output = result[0]
if p.returncode:
print >> sys.stderr, errormsg
print >> sys.stderr, "error getting zpool information from host"
sys.exit(1)
fsList = []
for line in output.splitlines():
fields = line.split()
if len(fields) != 2:
print >> sys.stderr, "bad output line from zfs list: %s" % line
continue
# we want only zfs pools not filesystems that are a subset of a zfs pool
fsname = fields[0].strip()
mount = fields[1].strip()
if re.search("/", fsname):
continue
fsList.append(FileSystem(device=fsname, dir=mount, type='zfs'))
return fsList
def getDirectoryList():
if SYSTEM.getName() == "linux":
return getLinuxDirectoryList()
elif SYSTEM.getName() == "sunos":
return getSolarisDirectoryList()
else:
print >> sys.stderr, "Unsupported platform"
sys.exit(1)
###### main()
if __name__ == '__main__':
gphome = os.environ.get('GPHOME')
if not gphome:
print "GPHOME not set"
sys.exit(1)
parser = OptParser(option_class=OptChecker)
parser.remove_option('-h')
parser.add_option('-h', '-?', '--help', action='store_true')
parser.add_option('-m', '--megabytes', action='store_true')
(options, args) = parser.parse_args()
if options.help:
print __doc__
sys.exit(1)
fsList = getDirectoryList()
for fs in fsList:
stats = os.statvfs(fs.dir)
fs.total_bytes = stats.f_frsize * stats.f_blocks
fs.available_bytes = stats.f_frsize * stats.f_bfree
fs.used_bytes = fs.total_bytes - fs.available_bytes
if fs.used_bytes < 0:
print >> sys.stderr, "statvfs output for device=%s dir=%s has more free bytes than total bytes" % (fs.device, fs.dir)
print >> sys.stderr, stats
sys.exit(1)
if options.megabytes:
formatter = BytesFormatter.MEGABYTES
else:
formatter = BytesFormatter.BYTES
FileSystem.PrintHeader(formatter)
for fs in fsList:
fs.Print(formatter)