KGRKJGETMRETU895U-589TY5MIGM5JGB5SDFESFREWTGR54TY
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/21572/root/usr/lib/python2.4/site-packages/sos/plugins/

Upload File :
current_dir [ Writeable ] document_root [ Writeable ]

 

Current File : //proc/21572/root/usr/lib/python2.4/site-packages/sos/plugins/gfs2.py
### 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()
            

Anon7 - 2021