|
Server : Apache/2.2.17 (Unix) mod_ssl/2.2.17 OpenSSL/0.9.8e-fips-rhel5 DAV/2 PHP/5.2.17 System : Linux localhost 2.6.18-419.el5 #1 SMP Fri Feb 24 22:47:42 UTC 2017 x86_64 User : nobody ( 99) PHP Version : 5.2.17 Disable Function : NONE Directory : /proc/21573/task/21573/root/proc/21573/root/usr/lib/python2.4/site-packages/sos/plugins/ |
Upload File : |
### 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., 675 Mass Ave, Cambridge, MA 02139, USA.
## GFS2 sosreport plugin v2
import sys
import sos.plugintools
import os
import commands
import time
import libxml2
from time import time
import tempfile
# libxml2 error handler
def noerr(ctx, str):
pass
class gfs2(sos.plugintools.PluginBase):
"""Information on GFS2 Filesystems
"""
def checkenabled(self):
if self.cInfo["policy"].pkgByName("gfs2-utils"):
return True
return False
def getJournalData(self, gfs2FileSystems):
journals = []
formattedOutput = []
#Iterate through the filesystems
for fileSystem in gfs2FileSystems:
#Get the journals. Count them and get their size in blocks
journalCount = 0
jSizeMin = sys.maxint
jSizeMax = 0
return_code, command_out, run_time = self.callExtProgWithOutput("gfs2_tool journals %s" % fileSystem[0])
for journal in command_out.split('\n'):
if journal.startswith("journal"):
journalFields = journal.split()
journalCount += 1
jSize = int(journalFields[2].rstrip('MB'))
if jSize > jSizeMax:
jSizeMax = jSize
if jSize < jSizeMin:
jSizeMin = jSize
jString = " journal"
if (journalCount > 1):
jString = jString + "s"
#add the data for the filesystem in question to an array of formatted data
formattedOutput.append(str("Filesystem " + fileSystem[6]) +" on device" + fileSystem[0])
formattedOutput.append(" mounted at " + str(fileSystem[2]) + " has " + str(journalCount))
if jSizeMin == jSizeMax:
formattedOutput.append(jString + " of " + str(jSizeMin) + "MB\n")
else:
formattedOutput.append(jString + " of " + str(jSizeMin) + "MB - " + str(jSizeMax) + "MB each\n")
formattedOutput.append(str("Warning: " + fileSystem[6] + " journals are not uniformly sized\n"))
journals = []
jSizeMin = 0
jSizeMax = sys.maxint
#Return our array of journal data
return formattedOutput
def setup(self):
# Get mounted GFS2 filesystems in a 2 dimensional list
gfs2FileSystems = []
return_code, command_out, runtime = self.callExtProgWithOutput("mount -l -t gfs2")
for fileSystem in command_out.split('\n'):
if fileSystem:
gfs2FileSystems.append(fileSystem.split())
#Get command output that doesn't require specifying a filesystem
self.collectExtOutput("mount -l -t gfs2")
#Iterate through fileystsems and gather specific command output for each
for fileSystem in gfs2FileSystems:
# Grab some filesystem layout info
self.collectExtOutput("gfs2_edit -p master " + fileSystem[0])
self.collectExtOutput("gfs2_edit -p rgs " + fileSystem[0])
self.collectExtOutput("gfs2_edit -p sb " + fileSystem[0])
#Get lock data
#Mount debug fs
debugfsPath = tempfile.mkdtemp()
self.callExtProg("mkdir " + debugfsPath)
self.callExtProg("mount -t debugfs none " + debugfsPath)
#Iterate through filesystems
for fileSystem in gfs2FileSystems:
# need to ask gfs2_tool since mount output does not unambiguously identify lock_nolock file systems
status, output, runtime = self.callExtProgWithOutput("gfs2_tool sb %s proto" % fileSystem[0])
protoFields = output.split('=')
isNoLock = "lock_nolock" in protoFields[1]
#Get glock files for each GFS2 file system (collectOutputNow)
glockFilePath = debugfsPath + "/gfs2/"+fileSystem[6].strip("[").strip("]") + "/glocks"
self.collectOutputNow("cat " + glockFilePath, "gfs2" + fileSystem[0] + ".glocks")
if not isNoLock:
dlmFilePath = debugfsPath + "/dlm/" + fileSystem[6].strip("[").strip("]").split(":")[1]
dlmLockFilePath = debugfsPath + "/dlm/" + fileSystem[6].strip("[").strip("]").split(":")[1] + "_locks"
dlmWaiterFilePath = debugfsPath + "/dlm/" + fileSystem[6].strip("[").strip("]").split(":")[1] + "_waiters"
self.collectOutputNow("cat "+dlmFilePath, "dlm" + fileSystem[0])
self.collectOutputNow("cat "+dlmLockFilePath, "dlm" + fileSystem[0] + "_locks")
self.collectOutputNow("cat "+dlmWaiterFilePath, "dlm" + fileSystem[0] + "_waiters")
#Unmount the filesystem
self.callExtProg("umount " + debugfsPath)
self.callExtProg("rm -rf " + debugfsPath)
#Get journal data
journalData = self.getJournalData(gfs2FileSystems)
try:
journalFile = tempfile.NamedTemporaryFile(mode="w")
for line in journalData:
journalFile.write(line)
journalFile.flush()
self.collectOutputNow("cat %s" % journalFile.name, "journal_data")
journalFile.close()
except:
pass
def diagnose(self):
#GFS2 is only supported on RHEL 5.3 or above
return_code, command_out, runtime = self.callExtProgWithOutput("cat /etc/redhat-release")
redhatRelease = command_out
if (int(redhatRelease.split()[6].split(".")[0]) < 5):
self.addDiagnose("GFS2 is not supported on RHEL 4")
if (int(redhatRelease.split()[6].split(".")[1]) < 3 and int(redhatRelease.split()[6].split(".")[0]) == 5):
self.addDiagnose("GFS2 requires RHEL 5.3 or higher")
#The package kmod-gfs2 provides an unsupported tech-preview GFS2 module
if self.cInfo["policy"].pkgByName("kmod-gfs2"):
self.addDiagnose("The tech preview kmod-gfs2 is installed. GFS2 is not supported with the tech preview module.")
#Checks that require iteration
return_code, command_out, runtime = self.callExtProgWithOutput("mount -l -t gfs2")
for fileSystem in command_out:
#GFS2 is not supported with lock_nolock
if (fileSystem.find("lock_nolock") != -1):
fileSystemInQuestion = fileSystem.split()
self.addDiagnose("GFS2 filesystems " + fileSystemInQuestion[6] + " is mounted lock_nolock. Local locking is not supported for production use.")
#GFS2 is only supported on CLVM
if (fileSystem.find("mpath") != -1):
fileSystemInQuestion = fileSystem.split()
self.addDiagnose("It appears that + " + fileSystemInQuestion[6] + " may not be on a clustered logical volume. GFS2 is only supported on CLVM.")
if not os.path.exists("/etc/cluster/cluster.conf"):
self.addDiagnose("/etc/cluster/cluster.conf missing")
return
#Check for valid fencing
try:
# suppress libxml2 console output
libxml2.registerErrorHandler(noerr, None)
xml = libxml2.parseFile("/etc/cluster/cluster.conf")
except libxml2.parserError:
self.addDiagnose("/etc/cluster/cluster.conf contains malformed XML")
return
xpathContext = xml.xpathNewContext()
if len(xpathContext.xpathEval("/cluster/clusternodes/clusternode[not(fence/method/device)]")):
self.addDiagnose("One or more nodes have no fence agent configured. Fencing is required for GFS2.")
if len(xpathContext.xpathEval("/cluster/clusternodes/clusternode[/cluster/fencedevices/fencedevice[@agent='fence_manual']/@name=fence/method/device/@name]")):
self.addDiagnose("One or more nodes have manual fencing configured. GFS2 requires a supported power or IO fencing agent.")
# libxml2 python binding objects are not reference counted
xpathContext.xpathFreeContext()
xml.freeDoc()