Blame gfs2/scripts/gfs2_lockcapture

Packit Service 360c39
#!/usr/bin/python
Packit Service 360c39
"""
Packit Service 360c39
The script "gfs2_lockcapture" will capture locking information from GFS2 file
Packit Service 360c39
systems and DLM.
Packit Service 360c39
Packit Service 360c39
@author    : Shane Bradley
Packit Service 360c39
@contact   : sbradley@redhat.com
Packit Service 360c39
@version   : 0.95
Packit Service 360c39
@copyright : GPLv2
Packit Service 360c39
"""
Packit Service 360c39
import sys
Packit Service 360c39
import os
Packit Service 360c39
import os.path
Packit Service 360c39
import logging
Packit Service 360c39
import logging.handlers
Packit Service 360c39
from optparse import OptionParser, Option, SUPPRESS_HELP
Packit Service 360c39
import time
Packit Service 360c39
import platform
Packit Service 360c39
import shutil
Packit Service 360c39
import subprocess
Packit Service 360c39
import tarfile
Packit Service 360c39
Packit Service 360c39
# #####################################################################
Packit Service 360c39
# Global vars:
Packit Service 360c39
# #####################################################################
Packit Service 360c39
"""
Packit Service 360c39
@cvar VERSION_NUMBER: The version number of this script.
Packit Service 360c39
@type VERSION_NUMBER: String
Packit Service 360c39
@cvar MAIN_LOGGER_NAME: The name of the logger.
Packit Service 360c39
@type MAIN_LOGGER_NAME: String
Packit Service 360c39
@cvar PATH_TO_DEBUG_DIR: The path to the debug directory for the linux kernel.
Packit Service 360c39
@type PATH_TO_DEBUG_DIR: String
Packit Service 360c39
@cvar PATH_TO_PID_FILENAME: The path to the pid file that will be used to make
Packit Service 360c39
sure only 1 instance of this script is running at any time.
Packit Service 360c39
@type PATH_TO_PID_FILENAME: String
Packit Service 360c39
"""
Packit Service 360c39
VERSION_NUMBER = "0.9-8"
Packit Service 360c39
MAIN_LOGGER_NAME = "%s" %(os.path.basename(sys.argv[0]))
Packit Service 360c39
PATH_TO_DEBUG_DIR="/sys/kernel/debug"
Packit Service 360c39
PATH_TO_PID_FILENAME = "/var/run/%s.pid" %(os.path.basename(sys.argv[0]))
Packit Service 360c39
Packit Service 360c39
# #####################################################################
Packit Service 360c39
# Class to define what a clusternode is.
Packit Service 360c39
# #####################################################################
Packit Service 360c39
class ClusterNode:
Packit Service 360c39
    """
Packit Service 360c39
    This class represents a cluster node that is a current member in a cluster.
Packit Service 360c39
    """
Packit Service 360c39
    def __init__(self, clusternodeName, clusternodeID, clusterName, mapOfMountedFilesystemLabels):
Packit Service 360c39
        """
Packit Service 360c39
        @param clusternodeName: The name of the cluster node.
Packit Service 360c39
        @type clusternodeName: String
Packit Service 360c39
        @param clusterName: The name of the cluster that this cluster node is a
Packit Service 360c39
        member of.
Packit Service 360c39
        @param clusternodeID: The id of the cluster node.
Packit Service 360c39
        @type clusternodeID: Int
Packit Service 360c39
        @param clusterName: The name of the cluster that this cluster node is a
Packit Service 360c39
        @type clusterName: String
Packit Service 360c39
        @param mapOfMountedFilesystemLabels: A map of filesystem labels(key) for
Packit Service 360c39
        a mounted filesystem. The value is the line for the matching mounted
Packit Service 360c39
        filesystem from the mount -l command.
Packit Service 360c39
        @type mapOfMountedFilesystemLabels: Dict
Packit Service 360c39
        """
Packit Service 360c39
        self.__clusternodeName = clusternodeName
Packit Service 360c39
        self.__clusternodeID  = clusternodeID
Packit Service 360c39
        self.__clusterName = clusterName
Packit Service 360c39
        self.__mapOfMountedFilesystemLabels = mapOfMountedFilesystemLabels
Packit Service 360c39
Packit Service 360c39
    def __str__(self):
Packit Service 360c39
        """
Packit Service 360c39
        This function will return a string representation of the object.
Packit Service 360c39
Packit Service 360c39
        @return: Returns a string representation of the object.
Packit Service 360c39
        @rtype: String
Packit Service 360c39
        """
Packit Service 360c39
        rString = ""
Packit Service 360c39
        rString += "%s:%s(id:%d)" %(self.getClusterName(), self.getClusterNodeName(), self.getClusterNodeID())
Packit Service 360c39
        fsLabels = list(self.__mapOfMountedFilesystemLabels.keys())
Packit Service 360c39
        fsLabels.sort()
Packit Service 360c39
        for fsLabel in fsLabels:
Packit Service 360c39
            rString += "\n\t%s --> %s" %(fsLabel, self.__mapOfMountedFilesystemLabels.get(fsLabel))
Packit Service 360c39
        return rString.rstrip()
Packit Service 360c39
Packit Service 360c39
    def getClusterNodeName(self):
Packit Service 360c39
        """
Packit Service 360c39
        Returns the name of the cluster node.
Packit Service 360c39
Packit Service 360c39
        @return: Returns the name of the cluster node.
Packit Service 360c39
        @rtype: String
Packit Service 360c39
        """
Packit Service 360c39
        return self.__clusternodeName
Packit Service 360c39
Packit Service 360c39
    def getClusterNodeID(self):
Packit Service 360c39
        """
Packit Service 360c39
        Returns the id of the cluster node.
Packit Service 360c39
        @return: Returns the id of the cluster node.
Packit Service 360c39
        @rtype: String
Packit Service 360c39
        """
Packit Service 360c39
        return self.__clusternodeID
Packit Service 360c39
Packit Service 360c39
    def getClusterName(self):
Packit Service 360c39
        """
Packit Service 360c39
        Returns the name of cluster that this cluster node is a member of.
Packit Service 360c39
Packit Service 360c39
        @return: Returns the name of cluster that this cluster node is a member
Packit Service 360c39
        of.
Packit Service 360c39
        @rtype: String
Packit Service 360c39
        """
Packit Service 360c39
        return self.__clusterName
Packit Service 360c39
Packit Service 360c39
    def getMountedGFS2FilesystemNames(self, includeClusterName=True):
Packit Service 360c39
        """
Packit Service 360c39
        Returns the names of all the mounted GFS2 filesystems. By default
Packit Service 360c39
        includeClusterName is True which will include the name of the cluster
Packit Service 360c39
        and the GFS2 filesystem name(ex. f18cluster:mygfs2vol1) in the list of
Packit Service 360c39
        mounted GFS2 filesystems. If includeClusterName is False it will only
Packit Service 360c39
        return a list of all the mounted GFS2 filesystem names(ex. mygfs2vol1).
Packit Service 360c39
Packit Service 360c39
        @return: Returns a list of all the mounted GFS2 filesystem names.
Packit Service 360c39
        @rtype: Array
Packit Service 360c39
Packit Service 360c39
        @param includeClusterName: By default this option is True and will
Packit Service 360c39
        include the name of the cluster and the GFS2 filesystem name. If False
Packit Service 360c39
        then only the GFS2 filesystem name will be included.
Packit Service 360c39
        @param includeClusterName: Boolean
Packit Service 360c39
        """
Packit Service 360c39
        # If true will prepend the cluster name to gfs2 fs name
Packit Service 360c39
        if (includeClusterName):
Packit Service 360c39
            return list(self.__mapOfMountedFilesystemLabels.keys())
Packit Service 360c39
        else:
Packit Service 360c39
            listOfGFS2MountedFilesystemLabels = []
Packit Service 360c39
            for fsLabel in list(self.__mapOfMountedFilesystemLabels.keys()):
Packit Service 360c39
                fsLabelSplit = fsLabel.split(":", 1)
Packit Service 360c39
                if (len(fsLabelSplit) == 2):
Packit Service 360c39
                    listOfGFS2MountedFilesystemLabels.append(fsLabelSplit[1])
Packit Service 360c39
            return listOfGFS2MountedFilesystemLabels
Packit Service 360c39
Packit Service 360c39
    def getMountedGFS2FilesystemPaths(self):
Packit Service 360c39
        """
Packit Service 360c39
        Returns a map of all the mounted GFS2 filesystem paths. The key is the
Packit Service 360c39
        GFS2 fs name(clustername:fs name) and value is the mountpoint.
Packit Service 360c39
Packit Service 360c39
        @return: Returns a map of all the mounted GFS2 filesystem paths. The key
Packit Service 360c39
        is the GFS2 fs name(clustername:fs name) and value is the mountpoint.
Packit Service 360c39
        Returns a list of all the mounted GFS2 filesystem paths.
Packit Service 360c39
        @rtype: Map
Packit Service 360c39
        """
Packit Service 360c39
        mapOfGFS2MountedFilesystemPaths = {}
Packit Service 360c39
        for fsLabel in list(self.__mapOfMountedFilesystemLabels.keys()):
Packit Service 360c39
            value = self.__mapOfMountedFilesystemLabels.get(fsLabel)
Packit Service 360c39
            mountPoint = value.split("type", 1)[0].split("on")[1]
Packit Service 360c39
            if (len(mountPoint) > 0):
Packit Service 360c39
                mapOfGFS2MountedFilesystemPaths[fsLabel] = mountPoint
Packit Service 360c39
        return mapOfGFS2MountedFilesystemPaths
Packit Service 360c39
Packit Service 360c39
# #####################################################################
Packit Service 360c39
# Helper functions.
Packit Service 360c39
# #####################################################################
Packit Service 360c39
def runCommand(command, listOfCommandOptions, standardOut=subprocess.PIPE, standardError=subprocess.PIPE):
Packit Service 360c39
    """
Packit Service 360c39
    This function will execute a command. It will return True if the return code
Packit Service 360c39
    was zero, otherwise False is returned.
Packit Service 360c39
Packit Service 360c39
    @return: Returns True if the return code was zero, otherwise False is
Packit Service 360c39
    returned.
Packit Service 360c39
    @rtype: Boolean
Packit Service 360c39
Packit Service 360c39
    @param command: The command that will be executed.
Packit Service 360c39
    @type command: String
Packit Service 360c39
    @param listOfCommandOptions: The list of options for the command that will
Packit Service 360c39
    be executed.
Packit Service 360c39
    @type listOfCommandOptions: Array
Packit Service 360c39
    @param standardOut: The pipe that will be used to write standard output. By
Packit Service 360c39
    default the pipe that is used is subprocess.PIPE.
Packit Service 360c39
    @type standardOut: Pipe
Packit Service 360c39
    @param standardError: The pipe that will be used to write standard error. By
Packit Service 360c39
    default the pipe that is used is subprocess.PIPE.
Packit Service 360c39
    @type standardError: Pipe
Packit Service 360c39
    """
Packit Service 360c39
    stdout = ""
Packit Service 360c39
    stderr = ""
Packit Service 360c39
    try:
Packit Service 360c39
        commandList = [command]
Packit Service 360c39
        commandList += listOfCommandOptions
Packit Service 360c39
        task = subprocess.Popen(commandList, stdout=standardOut, stderr=standardError)
Packit Service 360c39
        task.wait()
Packit Service 360c39
        (stdout, stderr) = task.communicate()
Packit Service 360c39
        return (task.returncode == 0)
Packit Service 360c39
    except OSError:
Packit Service 360c39
        commandOptionString = ""
Packit Service 360c39
        for option in listOfCommandOptions:
Packit Service 360c39
            commandOptionString += "%s " %(option)
Packit Service 360c39
        message = "An error occurred running the command: $ %s %s" %(command, commandOptionString)
Packit Service 360c39
        if (len(stdout.rstrip()) > 0):
Packit Service 360c39
            message += "\n%s" %(stdout.rstrip())
Packit Service 360c39
        if (len(stderr.rstrip()) > 0):
Packit Service 360c39
            message += "\n%s" %(stderr.rstrip())
Packit Service 360c39
        logging.getLogger(MAIN_LOGGER_NAME).error(message)
Packit Service 360c39
    return False
Packit Service 360c39
Packit Service 360c39
def runCommandOutput(command, listOfCommandOptions, standardOut=subprocess.PIPE, standardError=subprocess.PIPE):
Packit Service 360c39
    """
Packit Service 360c39
    This function will execute a command. Returns the output that was written to standard output. None is
Packit Service 360c39
    returned if there was an error.
Packit Service 360c39
Packit Service 360c39
    @return: Returns the output that was written to standard output. None is
Packit Service 360c39
    returned if there was an error.
Packit Service 360c39
    @rtype: String
Packit Service 360c39
Packit Service 360c39
    @param command: The command that will be executed.
Packit Service 360c39
    @type command: String
Packit Service 360c39
    @param listOfCommandOptions: The list of options for the command that will
Packit Service 360c39
    be executed.
Packit Service 360c39
    @type listOfCommandOptions: Array
Packit Service 360c39
    @param standardOut: The pipe that will be used to write standard output. By
Packit Service 360c39
    default the pipe that is used is subprocess.PIPE.
Packit Service 360c39
    @type standardOut: Pipe
Packit Service 360c39
    @param standardError: The pipe that will be used to write standard error. By
Packit Service 360c39
    default the pipe that is used is subprocess.PIPE.
Packit Service 360c39
    @type standardError: Pipe
Packit Service 360c39
    """
Packit Service 360c39
    stdout = ""
Packit Service 360c39
    stderr = ""
Packit Service 360c39
    try:
Packit Service 360c39
        commandList = [command]
Packit Service 360c39
        commandList += listOfCommandOptions
Packit Service 360c39
        task = subprocess.Popen(commandList, stdout=standardOut, stderr=standardError)
Packit Service 360c39
        task.wait()
Packit Service 360c39
        (stdout, stderr) = task.communicate()
Packit Service 360c39
    except OSError:
Packit Service 360c39
        commandOptionString = ""
Packit Service 360c39
        for option in listOfCommandOptions:
Packit Service 360c39
            commandOptionString += "%s " %(option)
Packit Service 360c39
        message = "An error occurred running the command: $ %s %s" %(command, commandOptionString)
Packit Service 360c39
        if (len(stdout.rstrip()) > 0):
Packit Service 360c39
            message += "\n%s" %(stdout.rstrip())
Packit Service 360c39
        if (len(stderr.rstrip()) > 0):
Packit Service 360c39
            message += "\n%s" %(stderr.rstrip())
Packit Service 360c39
        logging.getLogger(MAIN_LOGGER_NAME).error(message)
Packit Service 360c39
        return None
Packit Service 360c39
    return stdout.decode().strip().rstrip()
Packit Service 360c39
Packit Service 360c39
def writeToFile(pathToFilename, data, appendToFile=True, createFile=False):
Packit Service 360c39
    """
Packit Service 360c39
    This function will write a string to a file.
Packit Service 360c39
Packit Service 360c39
    @return: Returns True if the string was successfully written to the file,
Packit Service 360c39
    otherwise False is returned.
Packit Service 360c39
    @rtype: Boolean
Packit Service 360c39
Packit Service 360c39
    @param pathToFilename: The path to the file that will have a string written
Packit Service 360c39
    to it.
Packit Service 360c39
    @type pathToFilename: String
Packit Service 360c39
    @param data: The string that will be written to the file.
Packit Service 360c39
    @type data: String
Packit Service 360c39
    @param appendToFile: If True then the data will be appened to the file, if
Packit Service 360c39
    False then the data will overwrite the contents of the file.
Packit Service 360c39
    @type appendToFile: Boolean
Packit Service 360c39
    @param createFile: If True then the file will be created if it does not
Packit Service 360c39
    exists, if False then file will not be created if it does not exist
Packit Service 360c39
    resulting in no data being written to the file.
Packit Service 360c39
    @type createFile: Boolean
Packit Service 360c39
    """
Packit Service 360c39
    [parentDir, filename] = os.path.split(pathToFilename)
Packit Service 360c39
    if (os.path.isfile(pathToFilename) or (os.path.isdir(parentDir) and createFile)):
Packit Service 360c39
        try:
Packit Service 360c39
            filemode = "w"
Packit Service 360c39
            if (appendToFile):
Packit Service 360c39
                filemode = "a"
Packit Service 360c39
            fout = open(pathToFilename, filemode)
Packit Service 360c39
            fout.write(data + "\n")
Packit Service 360c39
            fout.close()
Packit Service 360c39
            return True
Packit Service 360c39
        except UnicodeEncodeError as e:
Packit Service 360c39
            message = "There was a unicode encode error writing to the file: %s." %(pathToFilename)
Packit Service 360c39
            logging.getLogger(MAIN_LOGGER_NAME).error(message)
Packit Service 360c39
            return False
Packit Service 360c39
        except IOError:
Packit Service 360c39
            message = "There was an error writing to the file: %s." %(pathToFilename)
Packit Service 360c39
            logging.getLogger(MAIN_LOGGER_NAME).error(message)
Packit Service 360c39
            return False
Packit Service 360c39
    return False
Packit Service 360c39
Packit Service 360c39
def mkdirs(pathToDSTDir):
Packit Service 360c39
    """
Packit Service 360c39
    This function will attempt to create a directory with the path of the value of pathToDSTDir.
Packit Service 360c39
Packit Service 360c39
    @return: Returns True if the directory was created or already exists.
Packit Service 360c39
    @rtype: Boolean
Packit Service 360c39
Packit Service 360c39
    @param pathToDSTDir: The path to the directory that will be created.
Packit Service 360c39
    @type pathToDSTDir: String
Packit Service 360c39
    """
Packit Service 360c39
    if (os.path.isdir(pathToDSTDir)):
Packit Service 360c39
        return True
Packit Service 360c39
    elif ((not os.access(pathToDSTDir, os.F_OK)) and (len(pathToDSTDir) > 0)):
Packit Service 360c39
        try:
Packit Service 360c39
            os.makedirs(pathToDSTDir)
Packit Service 360c39
        except (OSError, os.error):
Packit Service 360c39
            message = "Could not create the directory: %s." %(pathToDSTDir)
Packit Service 360c39
            logging.getLogger(MAIN_LOGGER_NAME).error(message)
Packit Service 360c39
            return False
Packit Service 360c39
        except (IOError, os.error):
Packit Service 360c39
            message = "Could not create the directory with the path: %s." %(pathToDSTDir)
Packit Service 360c39
            logging.getLogger(MAIN_LOGGER_NAME).error(message)
Packit Service 360c39
            return False
Packit Service 360c39
    return os.path.isdir(pathToDSTDir)
Packit Service 360c39
Packit Service 360c39
def removePIDFile():
Packit Service 360c39
    """
Packit Service 360c39
    This function will remove the pid file.
Packit Service 360c39
Packit Service 360c39
    @return: Returns True if the file was successfully remove or does not exist,
Packit Service 360c39
    otherwise False is returned.
Packit Service 360c39
    @rtype: Boolean
Packit Service 360c39
    """
Packit Service 360c39
    message = "Removing the pid file: %s" %(PATH_TO_PID_FILENAME)
Packit Service 360c39
    logging.getLogger(MAIN_LOGGER_NAME).debug(message)
Packit Service 360c39
    if (os.path.exists(PATH_TO_PID_FILENAME)):
Packit Service 360c39
        try:
Packit Service 360c39
            os.remove(PATH_TO_PID_FILENAME)
Packit Service 360c39
        except IOError:
Packit Service 360c39
            message = "There was an error removing the file: %s." %(PATH_TO_PID_FILENAME)
Packit Service 360c39
            logging.getLogger(MAIN_LOGGER_NAME).error(message)
Packit Service 360c39
    return os.path.exists(PATH_TO_PID_FILENAME)
Packit Service 360c39
Packit Service 360c39
def archiveData(pathToSrcDir):
Packit Service 360c39
    """
Packit Service 360c39
    This function will return the path to the tar.bz2 file that was created. If
Packit Service 360c39
    the tar.bz2 file failed to be created then an empty string will be returned
Packit Service 360c39
    which would indicate an error occurred.
Packit Service 360c39
Packit Service 360c39
    @return: This function will return the path to the tar.bz2 file that was
Packit Service 360c39
    created. If the tar.bz2 file failed to be created then an empty string will
Packit Service 360c39
    be returned which would indicate an error occurred.
Packit Service 360c39
    @rtype: String
Packit Service 360c39
Packit Service 360c39
    @param pathToSrcDir: The path to the directory that will be archived into a
Packit Service 360c39
    .tar.bz2 file.
Packit Service 360c39
    @type pathToSrcDir: String
Packit Service 360c39
    """
Packit Service 360c39
    if (os.path.exists(pathToSrcDir)):
Packit Service 360c39
        pathToTarFilename = "%s-%s.tar.bz2" %(pathToSrcDir, platform.node())
Packit Service 360c39
        if (os.path.exists(pathToTarFilename)):
Packit Service 360c39
            message = "A compressed archvied file already exists and will be removed: %s" %(pathToTarFilename)
Packit Service 360c39
            logging.getLogger(MAIN_LOGGER_NAME).status(message)
Packit Service 360c39
            try:
Packit Service 360c39
                os.remove(pathToTarFilename)
Packit Service 360c39
            except IOError:
Packit Service 360c39
                message = "There was an error removing the file: %s." %(pathToTarFilename)
Packit Service 360c39
                logging.getLogger(MAIN_LOGGER_NAME).error(message)
Packit Service 360c39
                return ""
Packit Service 360c39
        message = "Creating a compressed archvied file: %s" %(pathToTarFilename)
Packit Service 360c39
        logging.getLogger(MAIN_LOGGER_NAME).status(message)
Packit Service 360c39
        try:
Packit Service 360c39
            tar = tarfile.open(pathToTarFilename, "w:bz2")
Packit Service 360c39
            tar.add(pathToSrcDir, arcname=os.path.basename(pathToSrcDir))
Packit Service 360c39
            tar.close()
Packit Service 360c39
        except tarfile.TarError:
Packit Service 360c39
            message = "There was an error creating the tarfile: %s." %(pathToTarFilename)
Packit Service 360c39
            logging.getLogger(MAIN_LOGGER_NAME).error(message)
Packit Service 360c39
            return ""
Packit Service 360c39
        if (os.path.exists(pathToTarFilename)):
Packit Service 360c39
            return pathToTarFilename
Packit Service 360c39
    return ""
Packit Service 360c39
Packit Service 360c39
def getDataFromFile(pathToSrcFile) :
Packit Service 360c39
    """
Packit Service 360c39
    This function will return the data in an array. Where each newline in file
Packit Service 360c39
    is a seperate item in the array. This should really just be used on
Packit Service 360c39
    relatively small files.
Packit Service 360c39
Packit Service 360c39
    None is returned if no file is found.
Packit Service 360c39
Packit Service 360c39
    @return: Returns an array of Strings, where each newline in file is an item
Packit Service 360c39
    in the array.
Packit Service 360c39
    @rtype: Array
Packit Service 360c39
Packit Service 360c39
    @param pathToSrcFile: The path to the file which will be read.
Packit Service 360c39
    @type pathToSrcFile: String
Packit Service 360c39
    """
Packit Service 360c39
    if (len(pathToSrcFile) > 0) :
Packit Service 360c39
        try:
Packit Service 360c39
            fin = open(pathToSrcFile, "r")
Packit Service 360c39
            data = fin.readlines()
Packit Service 360c39
            fin.close()
Packit Service 360c39
            return data
Packit Service 360c39
        except (IOError, os.error):
Packit Service 360c39
            message = "An error occured reading the file: %s." %(pathToSrcFile)
Packit Service 360c39
            logging.getLogger(MAIN_LOGGER_NAME).error(message)
Packit Service 360c39
    return None
Packit Service 360c39
Packit Service 360c39
def copyFile(pathToSrcFile, pathToDstFile):
Packit Service 360c39
    """
Packit Service 360c39
    This function will copy a src file to dst file.
Packit Service 360c39
Packit Service 360c39
    @return: Returns True if the file was copied successfully.
Packit Service 360c39
    @rtype: Boolean
Packit Service 360c39
Packit Service 360c39
    @param pathToSrcFile: The path to the source file that will be copied.
Packit Service 360c39
    @type pathToSrcFile: String
Packit Service 360c39
    @param pathToDstFile: The path to the destination of the file.
Packit Service 360c39
    @type pathToDstFile: String
Packit Service 360c39
    """
Packit Service 360c39
    if(not os.path.exists(pathToSrcFile)):
Packit Service 360c39
        message = "The file does not exist with the path: %s." %(pathToSrcFile)
Packit Service 360c39
        logging.getLogger(MAIN_LOGGER_NAME).error(message)
Packit Service 360c39
        return False
Packit Service 360c39
    elif (not os.path.isfile(pathToSrcFile)):
Packit Service 360c39
        message = "The path to the source file is not a regular file: %s." %(pathToSrcFile)
Packit Service 360c39
        logging.getLogger(MAIN_LOGGER_NAME).error(message)
Packit Service 360c39
        return False
Packit Service 360c39
    elif (pathToSrcFile == pathToDstFile):
Packit Service 360c39
        message = "The path to the source file and path to destination file cannot be the same: %s." %(pathToDstFile)
Packit Service 360c39
        logging.getLogger(MAIN_LOGGER_NAME).error(message)
Packit Service 360c39
        return False
Packit Service 360c39
    else:
Packit Service 360c39
        # Create the directory structure if it does not exist.
Packit Service 360c39
        (head, tail) = os.path.split(pathToDstFile)
Packit Service 360c39
        if (not mkdirs(head)) :
Packit Service 360c39
            # The path to the directory was not created so file
Packit Service 360c39
            # could not be copied.
Packit Service 360c39
            return False
Packit Service 360c39
        # Copy the file to the dst path.
Packit Service 360c39
        try:
Packit Service 360c39
            shutil.copy(pathToSrcFile, pathToDstFile)
Packit Service 360c39
        except shutil.Error:
Packit Service 360c39
            message = "Cannot copy the file %s to %s." %(pathToSrcFile, pathToDstFile)
Packit Service 360c39
            logging.getLogger(MAIN_LOGGER_NAME).error(message)
Packit Service 360c39
            return False
Packit Service 360c39
        except OSError:
Packit Service 360c39
            message = "Cannot copy the file %s to %s." %(pathToSrcFile, pathToDstFile)
Packit Service 360c39
            logging.getLogger(MAIN_LOGGER_NAME).error(message)
Packit Service 360c39
            return False
Packit Service 360c39
        except IOError:
Packit Service 360c39
            message = "Cannot copy the file %s to %s." %(pathToSrcFile, pathToDstFile)
Packit Service 360c39
            logging.getLogger(MAIN_LOGGER_NAME).error(message)
Packit Service 360c39
            return False
Packit Service 360c39
        return (os.path.exists(pathToDstFile))
Packit Service 360c39
Packit Service 360c39
def copyDirectory(pathToSrcDir, pathToDstDir):
Packit Service 360c39
    """
Packit Service 360c39
    This function will copy a src dir to dst dir.
Packit Service 360c39
Packit Service 360c39
    @return: Returns True if the dir was copied successfully.
Packit Service 360c39
    @rtype: Boolean
Packit Service 360c39
Packit Service 360c39
    @param pathToSrcDir: The path to the source dir that will be copied.
Packit Service 360c39
    @type pathToSrcDir: String
Packit Service 360c39
    @param pathToDstDir: The path to the destination of the dir.
Packit Service 360c39
    @type pathToDstDir: String
Packit Service 360c39
    """
Packit Service 360c39
    if(not os.path.exists(pathToSrcDir)):
Packit Service 360c39
        message = "The directory does not exist with the path: %s." %(pathToSrcDir)
Packit Service 360c39
        logging.getLogger(MAIN_LOGGER_NAME).error(message)
Packit Service 360c39
        return False
Packit Service 360c39
    elif (not os.path.isdir(pathToSrcDir)):
Packit Service 360c39
        message = "The path to the source directory is not a directory: %s." %(pathToSrcDir)
Packit Service 360c39
        logging.getLogger(MAIN_LOGGER_NAME).error(message)
Packit Service 360c39
        return False
Packit Service 360c39
    elif (pathToSrcDir == pathToDstDir):
Packit Service 360c39
        message = "The path to the source directory and path to destination directory cannot be the same: %s." %(pathToDstDir)
Packit Service 360c39
        logging.getLogger(MAIN_LOGGER_NAME).error(message)
Packit Service 360c39
        return False
Packit Service 360c39
    else:
Packit Service 360c39
        if (not mkdirs(pathToDstDir)) :
Packit Service 360c39
            # The path to the directory was not created so file
Packit Service 360c39
            # could not be copied.
Packit Service 360c39
            return False
Packit Service 360c39
        # Copy the file to the dst path.
Packit Service 360c39
        dst = os.path.join(pathToDstDir, os.path.basename(pathToSrcDir))
Packit Service 360c39
        try:
Packit Service 360c39
            shutil.copytree(pathToSrcDir, dst)
Packit Service 360c39
        except shutil.Error:
Packit Service 360c39
            message = "Cannot copy the directory %s to %s." %(pathToSrcDir, dst)
Packit Service 360c39
            logging.getLogger(MAIN_LOGGER_NAME).error(message)
Packit Service 360c39
            return False
Packit Service 360c39
        except OSError:
Packit Service 360c39
            message = "Cannot copy the directory %s to %s." %(pathToSrcDir, dst)
Packit Service 360c39
            logging.getLogger(MAIN_LOGGER_NAME).error(message)
Packit Service 360c39
            return False
Packit Service 360c39
        except IOError:
Packit Service 360c39
            message = "Cannot copy the directory %s to %s." %(pathToSrcDir, dst)
Packit Service 360c39
            logging.getLogger(MAIN_LOGGER_NAME).error(message)
Packit Service 360c39
            return False
Packit Service 360c39
        return (os.path.exists(dst))
Packit Service 360c39
Packit Service 360c39
def backupOutputDirectory(pathToOutputDir):
Packit Service 360c39
    """
Packit Service 360c39
    This function will return True if the pathToOutputDir does not exist or the
Packit Service 360c39
    directory was successfully rename. If pathToOutputDir exists and was not
Packit Service 360c39
    successfully rename then False is returned.
Packit Service 360c39
Packit Service 360c39
    @return: Returns True if the pathToOutputDir does not exist or the directory
Packit Service 360c39
    was successfully rename. If pathToOutputDir exists and was not successfully
Packit Service 360c39
    rename then False is returned.
Packit Service 360c39
    @rtype: Boolean
Packit Service 360c39
Packit Service 360c39
    @param pathToOutputDir: The path to the directory that will be backed up.
Packit Service 360c39
    @type pathToOutputDir: String
Packit Service 360c39
    """
Packit Service 360c39
    if (os.path.exists(pathToOutputDir)):
Packit Service 360c39
        message = "The path already exists and could contain previous lockdump data: %s" %(pathToOutputDir)
Packit Service 360c39
        logging.getLogger(MAIN_LOGGER_NAME).info(message)
Packit Service 360c39
        backupIndex = 1
Packit Service 360c39
        pathToDST = ""
Packit Service 360c39
        keepSearchingForIndex = True
Packit Service 360c39
        while (keepSearchingForIndex):
Packit Service 360c39
            pathToDST = "%s.bk-%d" %(pathToOutputDir, backupIndex)
Packit Service 360c39
            if (os.path.exists(pathToDST)):
Packit Service 360c39
                backupIndex += 1
Packit Service 360c39
            else:
Packit Service 360c39
                keepSearchingForIndex = False
Packit Service 360c39
        try:
Packit Service 360c39
            message = "The existing output directory will be renamed: %s to %s." %(pathToOutputDir, pathToDST)
Packit Service 360c39
            logging.getLogger(MAIN_LOGGER_NAME).status(message)
Packit Service 360c39
            shutil.move(pathToOutputDir, pathToDST)
Packit Service 360c39
        except shutil.Error:
Packit Service 360c39
            message = "There was an error renaming the directory: %s to %s." %(pathToOutputDir, pathToDST)
Packit Service 360c39
            logging.getLogger(MAIN_LOGGER_NAME).error(message)
Packit Service 360c39
        except OSError:
Packit Service 360c39
            message = "There was an error renaming the directory: %s to %s." %(pathToOutputDir, pathToDST)
Packit Service 360c39
            logging.getLogger(MAIN_LOGGER_NAME).error(message)
Packit Service 360c39
    # The path should not exists now, else there was an error backing up an
Packit Service 360c39
    # existing output directory.
Packit Service 360c39
    return (not os.path.exists(pathToOutputDir))
Packit Service 360c39
Packit Service 360c39
def mountFilesystem(filesystemType, pathToDevice, pathToMountPoint):
Packit Service 360c39
    """
Packit Service 360c39
    This function will attempt to mount a filesystem. If the filesystem is
Packit Service 360c39
    already mounted or the filesystem was successfully mounted then True is
Packit Service 360c39
    returned, otherwise False is returned.
Packit Service 360c39
Packit Service 360c39
    @return: If the filesystem is already mounted or the filesystem was
Packit Service 360c39
    successfully mounted then True is returned, otherwise False is returned.
Packit Service 360c39
    @rtype: Boolean
Packit Service 360c39
Packit Service 360c39
    @param filesystemType: The type of filesystem that will be mounted.
Packit Service 360c39
    @type filesystemType: String
Packit Service 360c39
    @param pathToDevice: The path to the device that will be mounted.
Packit Service 360c39
    @type pathToDevice: String
Packit Service 360c39
    @param pathToMountPoint: The path to the directory that will be used as the
Packit Service 360c39
    mount point for the device.
Packit Service 360c39
    @type pathToMountPoint: String
Packit Service 360c39
    """
Packit Service 360c39
    if (os.path.ismount(PATH_TO_DEBUG_DIR)):
Packit Service 360c39
        return True
Packit Service 360c39
    listOfCommandOptions = ["-t", filesystemType, pathToDevice, pathToMountPoint]
Packit Service 360c39
    if (not runCommand("mount", listOfCommandOptions)):
Packit Service 360c39
        message = "There was an error mounting the filesystem type %s for the device %s to the mount point %s." %(filesystemType, pathToDevice, pathToMountPoint)
Packit Service 360c39
        logging.getLogger(MAIN_LOGGER_NAME).error(message)
Packit Service 360c39
    return  os.path.ismount(PATH_TO_DEBUG_DIR)
Packit Service 360c39
Packit Service 360c39
def exitScript(removePidFile=True, errorCode=0):
Packit Service 360c39
    """
Packit Service 360c39
    This function will cause the script to exit or quit. It will return an error
Packit Service 360c39
    code and will remove the pid file that was created.
Packit Service 360c39
Packit Service 360c39
    @param removePidFile: If True(default) then the pid file will be remove
Packit Service 360c39
    before the script exits.
Packit Service 360c39
    @type removePidFile: Boolean
Packit Service 360c39
    @param errorCode: The exit code that will be returned. The default value is 0.
Packit Service 360c39
    @type errorCode: Int
Packit Service 360c39
    """
Packit Service 360c39
    if (removePidFile):
Packit Service 360c39
        removePIDFile()
Packit Service 360c39
    message = "The script will exit."
Packit Service 360c39
    logging.getLogger(MAIN_LOGGER_NAME).info(message)
Packit Service 360c39
    sys.exit(errorCode)
Packit Service 360c39
Packit Service 360c39
# #####################################################################
Packit Service 360c39
# Helper functions for gathering the lockdumps.
Packit Service 360c39
# #####################################################################
Packit Service 360c39
def getClusterNode(listOfGFS2Names):
Packit Service 360c39
    """
Packit Service 360c39
    This function return a ClusterNode object if the machine is a member of a
Packit Service 360c39
    cluster and has GFS2 filesystems mounted for that cluster. The
Packit Service 360c39
    listOfGFS2Names is a list of GFS2 filesystem that need to have their data
Packit Service 360c39
    capture. If the list is empty then that means that all the mounted GFS2
Packit Service 360c39
    filesystems will be captured, if list is not empty then only those GFS2
Packit Service 360c39
    filesystems in the list will have their data captured.
Packit Service 360c39
Packit Service 360c39
    @return: Returns a cluster node object if there was mounted GFS2 filesystems
Packit Service 360c39
    found that will have their data captured.
Packit Service 360c39
    @rtype: ClusterNode
Packit Service 360c39
Packit Service 360c39
    @param listOfGFS2Names: A list of GFS2 filesystem names that will have their
Packit Service 360c39
    data captured.  If the list is empty then that means that all the mounted
Packit Service 360c39
    GFS2 filesystems will be captured, if list is not empty then only those GFS2
Packit Service 360c39
    filesystems in the list will have their data captured.
Packit Service 360c39
    @type listOfGFS2Names: Array
Packit Service 360c39
    """
Packit Service 360c39
    # Return a ClusterNode object if the clusternode and cluster name are found
Packit Service 360c39
    # in the output, else return None.
Packit Service 360c39
    clusterName = ""
Packit Service 360c39
    clusternodeName = ""
Packit Service 360c39
    clusternodeID = ""
Packit Service 360c39
    if (runCommand("which", ["cman_tool"])):
Packit Service 360c39
        stdout = runCommandOutput("cman_tool", ["status"])
Packit Service 360c39
        if (not stdout == None):
Packit Service 360c39
            stdoutSplit = stdout.split("\n")
Packit Service 360c39
            clusterName = ""
Packit Service 360c39
            clusternodeName = ""
Packit Service 360c39
            for line in stdoutSplit:
Packit Service 360c39
                if (line.startswith("Cluster Name:")):
Packit Service 360c39
                    clusterName = line.split("Cluster Name:")[1].strip().rstrip()
Packit Service 360c39
                if (line.startswith("Node name: ")):
Packit Service 360c39
                    clusternodeName = line.split("Node name:")[1].strip().rstrip()
Packit Service 360c39
                if (line.startswith("Node ID: ")):
Packit Service 360c39
                    clusternodeID = line.split("Node ID: ")[1].strip().rstrip()
Packit Service 360c39
    elif (runCommand("which", ["corosync-cmapctl"])):
Packit Service 360c39
        # Another way to get the local cluster node is: $ crm_node -i; crm_node -l
Packit Service 360c39
        # Get the name of the cluster.
Packit Service 360c39
        stdout = runCommandOutput("corosync-cmapctl", ["-g", "totem.cluster_name"])
Packit Service 360c39
        if (not stdout == None):
Packit Service 360c39
            stdoutSplit = stdout.split("=")
Packit Service 360c39
            if (len(stdoutSplit) == 2):
Packit Service 360c39
                clusterName = stdoutSplit[1].strip().rstrip()
Packit Service 360c39
        # Get the id of the local cluster node so we can get the clusternode name
Packit Service 360c39
        clusternodeID = ""
Packit Service 360c39
        stdout = runCommandOutput("corosync-cmapctl", ["-g", "runtime.votequorum.this_node_id"])
Packit Service 360c39
        if (not stdout == None):
Packit Service 360c39
            stdoutSplit = stdout.split("=")
Packit Service 360c39
            if (len(stdoutSplit) == 2):
Packit Service 360c39
               clusternodeID = stdoutSplit[1].strip().rstrip()
Packit Service 360c39
        # Now that we the nodeid then we can get the clusternode name.
Packit Service 360c39
        if (len(clusternodeID) > 0):
Packit Service 360c39
            stdout = runCommandOutput("corosync-quorumtool", ["-l"])
Packit Service 360c39
            if (not stdout == None):
Packit Service 360c39
                for line in stdout.split("\n"):
Packit Service 360c39
                    if (line.find("local") >=0):
Packit Service 360c39
                        splitLine = line.split(" (local)")
Packit Service 360c39
                        clusternodeName = splitLine[0].split()[2]
Packit Service 360c39
                        break;
Packit Service 360c39
    # If a clusternode name and cluster name was found then return a new object
Packit Service 360c39
    # since this means this cluster is part of cluster.
Packit Service 360c39
    if ((len(clusterName) > 0) and (len(clusternodeName) > 0)):
Packit Service 360c39
        mapOfMountedFilesystemLabels = getLabelMapForMountedFilesystems(clusterName, getMountedGFS2Filesystems())
Packit Service 360c39
        # These will be the GFS2 filesystems that will have their lockdump information gathered.
Packit Service 360c39
        if (len(listOfGFS2Names) > 0):
Packit Service 360c39
            for label in list(mapOfMountedFilesystemLabels.keys()):
Packit Service 360c39
                foundMatch = False
Packit Service 360c39
                for gfs2FSName in listOfGFS2Names:
Packit Service 360c39
                    if ((gfs2FSName == label) or ("%s:%s"%(clusterName, gfs2FSName) == label)):
Packit Service 360c39
                        foundMatch = True
Packit Service 360c39
                        break
Packit Service 360c39
                if ((not foundMatch) and (label in mapOfMountedFilesystemLabels)):
Packit Service 360c39
                    del(mapOfMountedFilesystemLabels[label])
Packit Service 360c39
        # Cast the node id to an int, and default is 0 if node is not found or
Packit Service 360c39
        # not castable.
Packit Service 360c39
        clusternodeIDInt = 0
Packit Service 360c39
        if (clusternodeID.isalnum()):
Packit Service 360c39
            try:
Packit Service 360c39
                clusternodeIDInt = int(clusternodeID)
Packit Service 360c39
            except(ValueError):
Packit Service 360c39
                pass
Packit Service 360c39
        return ClusterNode(clusternodeName, clusternodeIDInt, clusterName, mapOfMountedFilesystemLabels)
Packit Service 360c39
    else:
Packit Service 360c39
        return None
Packit Service 360c39
Packit Service 360c39
def parse_dlm_ls(dlm_ls):
Packit Service 360c39
    """
Packit Service 360c39
    This function returns the names of all the dlm lockspace names found with the
Packit Service 360c39
    commands "dlm_tool ls" or "group_tool ls" output.
Packit Service 360c39
Packit Service 360c39
    @return: A list of all the dlm lockspace names.
Packit Service 360c39
    @rtype: Array
Packit Service 360c39
    """
Packit Service 360c39
    dlmLockspaces = []
Packit Service 360c39
    if (not dlm_ls == None):
Packit Service 360c39
        dlm_ls = dlm_ls.replace("dlm lockspaces\n", "")
Packit Service 360c39
        dlmToolLSKeys = ["name", "id", "flags", "change", "members"]
Packit Service 360c39
        # Split on newlines
Packit Service 360c39
        dlm_lsSections = dlm_ls.split("\n\n")
Packit Service 360c39
        for section in dlm_lsSections:
Packit Service 360c39
            # Create tmp map to hold data
Packit Service 360c39
            if (section.startswith("fence domain")):
Packit Service 360c39
                # Not concerned with fence information.
Packit Service 360c39
                continue
Packit Service 360c39
            dlmToolLSMap = dict.fromkeys(dlmToolLSKeys)
Packit Service 360c39
            lines = section.split("\n")
Packit Service 360c39
            for line in lines:
Packit Service 360c39
                for dlmToolLSKey in list(dlmToolLSMap.keys()):
Packit Service 360c39
                    if (line.startswith(dlmToolLSKey)):
Packit Service 360c39
                        value = line.replace(dlmToolLSKey, " ", 1).strip().rstrip()
Packit Service 360c39
                        dlmToolLSMap[dlmToolLSKey] = value
Packit Service 360c39
                if ((not dlmToolLSMap.get("name") == None) and (not dlmToolLSMap.get("id") == None)):
Packit Service 360c39
                    dlmLockspaces.append(dlmToolLSMap.get("name"))
Packit Service 360c39
    return dlmLockspaces
Packit Service 360c39
Packit Service 360c39
def getGroupToolDLMLockspaces():
Packit Service 360c39
    """
Packit Service 360c39
    This function returns the names of all the dlm lockspace names found with the
Packit Service 360c39
    command: "group_tool ls".
Packit Service 360c39
Packit Service 360c39
    @return: A list of all the dlm lockspace names.
Packit Service 360c39
    @rtype: Array
Packit Service 360c39
    """
Packit Service 360c39
    dlmLockspaces = []
Packit Service 360c39
    stdout = runCommandOutput("group_tool", ["ls"])
Packit Service 360c39
    if (not stdout == None):
Packit Service 360c39
        lines = stdout.split("\n")
Packit Service 360c39
        if (len(lines) > 0):
Packit Service 360c39
            if (lines[0].startswith("type")):
Packit Service 360c39
                # Then running cman-2.0
Packit Service 360c39
                for line in lines:
Packit Service 360c39
                    if (line.startswith("dlm")):
Packit Service 360c39
                        dlmLockspaces.append(line.split()[2])
Packit Service 360c39
            else:
Packit Service 360c39
                # Then running cman-3.0 and uses same sorta output as `dlm_tool ls`.
Packit Service 360c39
                dlmLockspaces = parse_dlm_ls(stdout)
Packit Service 360c39
    return dlmLockspaces
Packit Service 360c39
Packit Service 360c39
def getDLMLockspaces():
Packit Service 360c39
    """
Packit Service 360c39
    Returns a list of the dlm lockspace names.
Packit Service 360c39
Packit Service 360c39
    @return: Returns a list of dlm lockspace names.
Packit Service 360c39
    @rtype: Array
Packit Service 360c39
    """
Packit Service 360c39
    message = "Gathering the DLM Lockspace Names."
Packit Service 360c39
    logging.getLogger(MAIN_LOGGER_NAME).debug(message)
Packit Service 360c39
    dlmLockspaces = parse_dlm_ls(runCommandOutput("dlm_tool", ["ls"]))
Packit Service 360c39
    if (not len(dlmLockspaces) > 0):
Packit Service 360c39
        message = "There was no dlm lockspaces found with the \"dlm_tool ls\" command.  Trying with the \"group_tool ls\" command."
Packit Service 360c39
        logging.getLogger(MAIN_LOGGER_NAME).debug(message)
Packit Service 360c39
        dlmLockspaces = getGroupToolDLMLockspaces()
Packit Service 360c39
    return dlmLockspaces
Packit Service 360c39
Packit Service 360c39
def getVerifiedDLMLockspaceNames(lockspaceNames):
Packit Service 360c39
    """
Packit Service 360c39
    Returns a list of DLM lockspaces that have been verified to exists in the
Packit Service 360c39
    command output of $(dlm_tool ls).
Packit Service 360c39
Packit Service 360c39
    @return: Returns a list of DLM lockspaces that have been verified to exists
Packit Service 360c39
    in the command output of $(dlm_tool ls).
Packit Service 360c39
    @rtype: Array
Packit Service 360c39
Packit Service 360c39
    @param lockspaceNames: This is the list of DLM lockspaces that will have
Packit Service 360c39
    their debug directory copied.
Packit Service 360c39
    @type lockspaceNames: Array
Packit Service 360c39
    """
Packit Service 360c39
    # Get a list of all the DLM lockspaces names.
Packit Service 360c39
    dlmLockspaces = getDLMLockspaces()
Packit Service 360c39
    # Verify the lockspaceNames are lockspaces that exist.
Packit Service 360c39
    verifiedLockspaceNames = []
Packit Service 360c39
    for lockspaceName in lockspaceNames:
Packit Service 360c39
        if ((lockspaceName in dlmLockspaces) and
Packit Service 360c39
            (not lockspaceName in verifiedLockspaceNames)):
Packit Service 360c39
            verifiedLockspaceNames.append(lockspaceName)
Packit Service 360c39
    return verifiedLockspaceNames
Packit Service 360c39
Packit Service 360c39
def getMountedGFS2Filesystems():
Packit Service 360c39
    """
Packit Service 360c39
    This function returns a list of all the mounted GFS2 filesystems.
Packit Service 360c39
Packit Service 360c39
    @return: Returns a list of all the mounted GFS2 filesystems.
Packit Service 360c39
    @rtype: Array
Packit Service 360c39
    """
Packit Service 360c39
    fsType = "gfs2"
Packit Service 360c39
    listOfMountedFilesystems = []
Packit Service 360c39
    stdout = runCommandOutput("mount", ["-l"])
Packit Service 360c39
    if (not stdout == None):
Packit Service 360c39
        stdoutSplit = stdout.split("\n")
Packit Service 360c39
        for line in stdoutSplit:
Packit Service 360c39
            splitLine = line.split()
Packit Service 360c39
            if (len(splitLine) >= 5):
Packit Service 360c39
                if (splitLine[4] == fsType):
Packit Service 360c39
                    listOfMountedFilesystems.append(line)
Packit Service 360c39
    return listOfMountedFilesystems
Packit Service 360c39
Packit Service 360c39
def getLabelMapForMountedFilesystems(clusterName, listOfMountedFilesystems):
Packit Service 360c39
    """
Packit Service 360c39
    This function will return a dictionary of the mounted GFS2 filesystem that
Packit Service 360c39
    contain a label that starts with the cluster name. For example:
Packit Service 360c39
    {'f18cluster:mygfs2vol1': '/dev/vdb1 on /mnt/gfs2vol1 type gfs2 (rw,relatime) [f18cluster:mygfs2vol1]'}
Packit Service 360c39
Packit Service 360c39
    @return: Returns a dictionary of the mounted GFS2 filesystems that contain a
Packit Service 360c39
    label that starts with the cluster name.
Packit Service 360c39
    @rtype: Dict
Packit Service 360c39
Packit Service 360c39
    @param clusterName: The name of the cluster.
Packit Service 360c39
    @type clusterName: String
Packit Service 360c39
    @param listOfMountedFilesystems: A list of all the mounted GFS2 filesystems.
Packit Service 360c39
    @type listOfMountedFilesystems: Array
Packit Service 360c39
    """
Packit Service 360c39
    mapOfMountedFilesystemLabels = {}
Packit Service 360c39
    for mountedFilesystem in listOfMountedFilesystems:
Packit Service 360c39
        splitMountedFilesystem = mountedFilesystem.split()
Packit Service 360c39
        fsLabel = splitMountedFilesystem[-1].strip().strip("[").rstrip("]")
Packit Service 360c39
        if (len(fsLabel) > 0):
Packit Service 360c39
            # Verify it starts with name of the cluster.
Packit Service 360c39
            if (fsLabel.startswith("%s:" %(clusterName))):
Packit Service 360c39
                mapOfMountedFilesystemLabels[fsLabel] = mountedFilesystem
Packit Service 360c39
    return mapOfMountedFilesystemLabels
Packit Service 360c39
Packit Service 360c39
# #####################################################################
Packit Service 360c39
# Gather output from command functions
Packit Service 360c39
# #####################################################################
Packit Service 360c39
def gatherHostData(pathToDSTDir):
Packit Service 360c39
    """
Packit Service 360c39
    This function will gather general information about the cluster and write
Packit Service 360c39
    the results to a file. The following data will be captured: hostname, date,
Packit Service 360c39
    uname -a, uptime.
Packit Service 360c39
Packit Service 360c39
    @param pathToDSTDir: This is the path to directory where the files will be
Packit Service 360c39
    written to.
Packit Service 360c39
    @type pathToDSTDir: String
Packit Service 360c39
    """
Packit Service 360c39
    # Gather some general information and write to system.txt.
Packit Service 360c39
    systemString = "HOSTNAME=%s\nTIMESTAMP=%s\n" %(platform.node(), time.strftime("%Y-%m-%d %H:%M:%S"))
Packit Service 360c39
    stdout = runCommandOutput("uname", ["-a"]).strip().rstrip()
Packit Service 360c39
    if (not stdout == None):
Packit Service 360c39
        systemString += "UNAMEA=%s\n" %(stdout)
Packit Service 360c39
    stdout = runCommandOutput("uptime", []).strip().rstrip()
Packit Service 360c39
    if (not stdout == None):
Packit Service 360c39
        systemString += "UPTIME=%s" %(stdout)
Packit Service 360c39
    writeToFile(os.path.join(pathToDSTDir, "hostinformation.txt"), systemString, createFile=True)
Packit Service 360c39
Packit Service 360c39
def gatherDiagnosticData(pathToDSTDir):
Packit Service 360c39
    """
Packit Service 360c39
    This function will gather general information about the cluster and write (or
Packit Service 360c39
    copy) the results to a file.
Packit Service 360c39
Packit Service 360c39
    @param pathToDSTDir: This is the path to directory where the files will be
Packit Service 360c39
    written to.
Packit Service 360c39
    @type pathToDSTDir: String
Packit Service 360c39
Packit Service 360c39
    """
Packit Service 360c39
    # Get "ps -eo user,pid,%cpu,%mem,vsz,rss,tty,stat,start,time,comm,wchan" data.
Packit Service 360c39
    # Get " ps h -AL -o tid,s,cmd
Packit Service 360c39
    command = "ps"
Packit Service 360c39
    pathToCommandOutput = os.path.join(pathToDSTDir, "ps_hALo-tid.s.cmd")
Packit Service 360c39
    try:
Packit Service 360c39
        fout = open(pathToCommandOutput, "w")
Packit Service 360c39
        #runCommand(command, ["-eo", "user,pid,%cpu,%mem,vsz,rss,tty,stat,start,time,comm,wchan"], standardOut=fout)
Packit Service 360c39
        runCommand(command, ["h", "-AL", "-o", "tid,s,cmd"], standardOut=fout)
Packit Service 360c39
        fout.close()
Packit Service 360c39
    except IOError:
Packit Service 360c39
        message = "There was an error writing the command output for %s to the file %s." %(command, pathToCommandOutput)
Packit Service 360c39
        logging.getLogger(MAIN_LOGGER_NAME).error(message)
Packit Service 360c39
Packit Service 360c39
    # Copy misc files
Packit Service 360c39
    pathToSrcFile = "/proc/mounts"
Packit Service 360c39
    copyFile(pathToSrcFile, os.path.join(pathToDSTDir, pathToSrcFile.strip("/")))
Packit Service 360c39
    pathToSrcFile = "/proc/slabinfo"
Packit Service 360c39
    copyFile(pathToSrcFile, os.path.join(pathToDSTDir, pathToSrcFile.strip("/")))
Packit Service 360c39
Packit Service 360c39
    # Copy the DLM hash table sizes:
Packit Service 360c39
    pathToHashTableFiles = ["/sys/kernel/config/dlm/cluster/lkbtbl_size", "/sys/kernel/config/dlm/cluster/dirtbl_size",
Packit Service 360c39
                            "/sys/kernel/config/dlm/cluster/rsbtbl_size"]
Packit Service 360c39
    for pathToSrcFile in pathToHashTableFiles:
Packit Service 360c39
        if (os.path.exists(pathToSrcFile)):
Packit Service 360c39
            copyFile(pathToSrcFile, os.path.join(pathToDSTDir, pathToSrcFile.strip("/")))
Packit Service 360c39
Packit Service 360c39
def gatherOptionalDiagnosticData(pathToDSTDir):
Packit Service 360c39
    """
Packit Service 360c39
    This function will gather optional information about the cluster and write
Packit Service 360c39
    the results to a file.
Packit Service 360c39
Packit Service 360c39
    @param pathToDSTDir: This is the path to directory where the files will be
Packit Service 360c39
    written to.
Packit Service 360c39
    @type pathToDSTDir: String
Packit Service 360c39
    """
Packit Service 360c39
    # Get df -h ouput
Packit Service 360c39
    command = "df"
Packit Service 360c39
    pathToCommandOutput = os.path.join(pathToDSTDir, "df-h.cmd")
Packit Service 360c39
    try:
Packit Service 360c39
        fout = open(pathToCommandOutput, "w")
Packit Service 360c39
        runCommand(command, ["-h"], standardOut=fout)
Packit Service 360c39
        fout.close()
Packit Service 360c39
    except IOError:
Packit Service 360c39
        message = "There was an error writing the command output for %s to the file %s." %(command, pathToCommandOutput)
Packit Service 360c39
        logging.getLogger(MAIN_LOGGER_NAME).error(message)
Packit Service 360c39
Packit Service 360c39
    # Write the status of all the nodes in the cluster out.
Packit Service 360c39
    if (runCommand("which", ["cman_tool"])):
Packit Service 360c39
        command = "cman_tool"
Packit Service 360c39
        pathToCommandOutput = os.path.join(pathToDSTDir, "cman_tool_status")
Packit Service 360c39
        try:
Packit Service 360c39
            fout = open(pathToCommandOutput, "w")
Packit Service 360c39
            runCommand(command, ["status"], standardOut=fout)
Packit Service 360c39
            fout.close()
Packit Service 360c39
        except IOError:
Packit Service 360c39
            message = "There was an error the command output for %s to the file %s." %(command, pathToCommandOutput)
Packit Service 360c39
            logging.getLogger(MAIN_LOGGER_NAME).error(message)
Packit Service 360c39
    elif (runCommand("which", ["corosync-cmapctl"])):
Packit Service 360c39
        command = "corosync-quorumtool"
Packit Service 360c39
        pathToCommandOutput = os.path.join(pathToDSTDir, "corosync-quorumtool_l")
Packit Service 360c39
        try:
Packit Service 360c39
            fout = open(pathToCommandOutput, "w")
Packit Service 360c39
            runCommand(command, ["-l"], standardOut=fout)
Packit Service 360c39
            fout.close()
Packit Service 360c39
        except IOError:
Packit Service 360c39
            message = "There was an error the command output for %s to the file %s." %(command, pathToCommandOutput)
Packit Service 360c39
            logging.getLogger(MAIN_LOGGER_NAME).error(message)
Packit Service 360c39
Packit Service 360c39
# #####################################################################
Packit Service 360c39
# Gather Process Information
Packit Service 360c39
# #####################################################################
Packit Service 360c39
def isProcPidStackEnabled(pathToPidData):
Packit Service 360c39
    """
Packit Service 360c39
    Returns true if the init process has the file "stack" in its pid data
Packit Service 360c39
    directory which contains the task functions for that process.
Packit Service 360c39
Packit Service 360c39
    @return: Returns true if the init process has the file "stack" in its pid
Packit Service 360c39
    data directory which contains the task functions for that process.
Packit Service 360c39
    @rtype: Boolean
Packit Service 360c39
Packit Service 360c39
    @param pathToPidData: The path to the directory where all the pid data
Packit Service 360c39
    directories are located.
Packit Service 360c39
    @type pathToPidData: String
Packit Service 360c39
    """
Packit Service 360c39
    return os.path.exists(os.path.join(pathToPidData, "1/stack"))
Packit Service 360c39
Packit Service 360c39
def gatherPidData(pathToPidData, pathToDSTDir):
Packit Service 360c39
    """
Packit Service 360c39
    This command will gather all the directories which contain data about all the pids.
Packit Service 360c39
Packit Service 360c39
    @return: Returns a list of paths to the directory that contains the
Packit Service 360c39
    information about the pid.
Packit Service 360c39
    @rtype: Array
Packit Service 360c39
Packit Service 360c39
    @param pathToPidData: The path to the directory where all the pid data
Packit Service 360c39
    directories are located.
Packit Service 360c39
    @type pathToPidData: String
Packit Service 360c39
    """
Packit Service 360c39
    # Status has: command name, pid, ppid, state, possibly registers
Packit Service 360c39
    listOfFilesToCopy = ["cmdline", "stack", "status"]
Packit Service 360c39
    listOfPathToPidsData = []
Packit Service 360c39
    if (os.path.exists(pathToPidData)):
Packit Service 360c39
        for srcFilename in os.listdir(pathToPidData):
Packit Service 360c39
            pathToPidDirDST = os.path.join(pathToDSTDir, srcFilename)
Packit Service 360c39
            if (srcFilename.isdigit()):
Packit Service 360c39
                pathToSrcDir = os.path.join(pathToPidData, srcFilename)
Packit Service 360c39
                for filenameToCopy in listOfFilesToCopy:
Packit Service 360c39
                    copyFile(os.path.join(pathToSrcDir, filenameToCopy), os.path.join(pathToPidDirDST, filenameToCopy))
Packit Service 360c39
                if (os.path.exists(pathToPidDirDST)):
Packit Service 360c39
                    listOfPathToPidsData.append(pathToPidDirDST)
Packit Service 360c39
    return listOfPathToPidsData
Packit Service 360c39
Packit Service 360c39
def triggerSysRQEvents():
Packit Service 360c39
    """
Packit Service 360c39
    This command will trigger sysrq events which will write the output to
Packit Service 360c39
    /var/log/messages. The events that will be trigger are "m" and "t". The "m"
Packit Service 360c39
    event will dump information about memory allocation. The "t" event will dump
Packit Service 360c39
    all the threads state information.
Packit Service 360c39
    """
Packit Service 360c39
    command = "echo"
Packit Service 360c39
    pathToSysrqTriggerFile = "/proc/sysrq-trigger"
Packit Service 360c39
    # m - dump information about memory allocation
Packit Service 360c39
    # t - dump thread state information
Packit Service 360c39
    # triggers = ["m", "t"]
Packit Service 360c39
    triggers = ["t"]
Packit Service 360c39
    for trigger in triggers:
Packit Service 360c39
        try:
Packit Service 360c39
            fout = open(pathToSysrqTriggerFile, "w")
Packit Service 360c39
            runCommand(command, [trigger], standardOut=fout)
Packit Service 360c39
            fout.close()
Packit Service 360c39
        except IOError:
Packit Service 360c39
            message = "There was an error writing the command output for %s to the file %s." %(command, pathToSysrqTriggerFile)
Packit Service 360c39
            logging.getLogger(MAIN_LOGGER_NAME).error(message)
Packit Service 360c39
Packit Service 360c39
# #####################################################################
Packit Service 360c39
# Gather lockdumps and logs
Packit Service 360c39
# #####################################################################
Packit Service 360c39
def gatherLogs(pathToDSTDir):
Packit Service 360c39
    """
Packit Service 360c39
    This function will copy all the cluster logs(/var/log/cluster) and the
Packit Service 360c39
    system log(/var/log/messages) to the directory given by pathToDSTDir.
Packit Service 360c39
Packit Service 360c39
    @param pathToDSTDir: This is the path to directory where the files will be
Packit Service 360c39
    copied to.
Packit Service 360c39
    @type pathToDSTDir: String
Packit Service 360c39
    """
Packit Service 360c39
    pathToLogFile = "/var/log/messages"
Packit Service 360c39
    pathToDSTLogFile = os.path.join(pathToDSTDir, os.path.basename(pathToLogFile))
Packit Service 360c39
    copyFile(pathToLogFile, pathToDSTLogFile)
Packit Service 360c39
Packit Service 360c39
    pathToLogDir = "/var/log/cluster"
Packit Service 360c39
    if (os.path.exists(pathToLogDir)):
Packit Service 360c39
        pathToDSTLogDir = os.path.join(pathToDSTDir, os.path.basename(pathToLogDir))
Packit Service 360c39
        copyDirectory(pathToLogDir, pathToDSTDir)
Packit Service 360c39
Packit Service 360c39
def gatherDLMLockDumps(pathToDSTDir, lockspaceNames):
Packit Service 360c39
    """
Packit Service 360c39
    This function copies all the debug files for dlm and sorts them into their
Packit Service 360c39
    own directory based on name of dlm lockspace.
Packit Service 360c39
Packit Service 360c39
    @param pathToDSTDir: This is the path to directory where the files will be
Packit Service 360c39
    copied to.
Packit Service 360c39
    @type pathToDSTDir: String
Packit Service 360c39
    @param lockspaceNames: This is the list of DLM lockspaces that will have
Packit Service 360c39
    their debug directory copied.
Packit Service 360c39
    @type lockspaceNames: Array
Packit Service 360c39
    """
Packit Service 360c39
    # This function assumes that verifiedLockspaceNames has already been called
Packit Service 360c39
    # to verify the lockspace does exist.
Packit Service 360c39
    lockDumpType = "dlm"
Packit Service 360c39
    pathToSrcDir = os.path.join(PATH_TO_DEBUG_DIR, lockDumpType)
Packit Service 360c39
    pathToOutputDir = os.path.join(pathToDSTDir, lockDumpType)
Packit Service 360c39
    message = "Copying the files in the %s lockdump data directory %s." %(lockDumpType.upper(), pathToSrcDir)
Packit Service 360c39
    logging.getLogger(MAIN_LOGGER_NAME).debug(message)
Packit Service 360c39
Packit Service 360c39
    # Get list of all the dlm lockspaces
Packit Service 360c39
    if (os.path.exists(pathToSrcDir)):
Packit Service 360c39
        for filename in os.listdir(pathToSrcDir):
Packit Service 360c39
            for lockspaceName in lockspaceNames:
Packit Service 360c39
                if (filename.startswith(lockspaceName)):
Packit Service 360c39
                    copyFile(os.path.join(pathToSrcDir, filename),
Packit Service 360c39
                             os.path.join(os.path.join(pathToOutputDir, lockspaceName), filename))
Packit Service 360c39
Packit Service 360c39
    # Run dlm_tool lockdebug against the lockspace names and write to file.
Packit Service 360c39
    for lockspaceName in lockspaceNames:
Packit Service 360c39
        dstDir = os.path.join(pathToOutputDir, lockspaceName)
Packit Service 360c39
        if (mkdirs(dstDir)):
Packit Service 360c39
            pathToCommandOutput = os.path.join(dstDir,"%s_lockdebug" %(lockspaceName))
Packit Service 360c39
            try:
Packit Service 360c39
                fout = open(pathToCommandOutput, "w")
Packit Service 360c39
                runCommand("dlm_tool", ["lockdebug", "-v", "-s", "-w", lockspaceName], standardOut=fout)
Packit Service 360c39
                fout.close()
Packit Service 360c39
            except IOError:
Packit Service 360c39
                message = "There was an error writing the command output to the file %s." %(pathToCommandOutput)
Packit Service 360c39
                logging.getLogger(MAIN_LOGGER_NAME).error(message)
Packit Service 360c39
Packit Service 360c39
def gatherGFS2LockDumps(pathToDSTDir, listOfGFS2Filesystems):
Packit Service 360c39
    """
Packit Service 360c39
    This function copies the debug directory for a GFS2 filesystems in the list
Packit Service 360c39
    to a directory. The list of GFS2 filesystems will include the cluster name
Packit Service 360c39
    and filesystem name for each item in the list. For example:
Packit Service 360c39
    "f18cluster:mygfs2vol1"
Packit Service 360c39
Packit Service 360c39
    @return: Returns True if files(not directories) were copied to the
Packit Service 360c39
    destination directory.
Packit Service 360c39
    @rtype: Boolean
Packit Service 360c39
Packit Service 360c39
    @param pathToDSTDir: This is the path to directory where the files will be
Packit Service 360c39
    copied to.
Packit Service 360c39
    @type pathToDSTDir: String
Packit Service 360c39
    @param listOfGFS2Filesystems: This is the list of the GFS2 filesystems that
Packit Service 360c39
    will have their debug directory copied.
Packit Service 360c39
    @type listOfGFS2Filesystems: Array
Packit Service 360c39
    """
Packit Service 360c39
    lockDumpType = "gfs2"
Packit Service 360c39
    pathToSrcDir = os.path.join(PATH_TO_DEBUG_DIR, lockDumpType)
Packit Service 360c39
    pathToOutputDir = os.path.join(pathToDSTDir, lockDumpType)
Packit Service 360c39
    # The number of files that were copied
Packit Service 360c39
    fileCopiedCount = 0
Packit Service 360c39
    if (not os.path.exists(pathToSrcDir)):
Packit Service 360c39
        return False
Packit Service 360c39
    for dirName in os.listdir(pathToSrcDir):
Packit Service 360c39
        pathToCurrentDir = os.path.join(pathToSrcDir, dirName)
Packit Service 360c39
        if ((os.path.isdir(pathToCurrentDir)) and (dirName in listOfGFS2Filesystems)):
Packit Service 360c39
            message = "Copying the lockdump data for the %s filesystem: %s" %(lockDumpType.upper(), dirName)
Packit Service 360c39
            logging.getLogger(MAIN_LOGGER_NAME).debug(message)
Packit Service 360c39
            copySuccessful = copyDirectory(pathToCurrentDir, pathToOutputDir)
Packit Service 360c39
            if (copySuccessful and os.path.exists(os.path.join(pathToOutputDir, dirName))):
Packit Service 360c39
                fileCopiedCount = len(os.listdir(os.path.join(pathToOutputDir, dirName)))
Packit Service 360c39
    # If the number of files(not directories) copied was greater than zero then files were copied
Packit Service 360c39
    # succesfully.
Packit Service 360c39
    return (fileCopiedCount > 0)
Packit Service 360c39
Packit Service 360c39
# ##############################################################################
Packit Service 360c39
# Get user selected options
Packit Service 360c39
# ##############################################################################
Packit Service 360c39
def __getOptions(version) :
Packit Service 360c39
    """
Packit Service 360c39
    This function creates the OptionParser and returns commandline
Packit Service 360c39
    a tuple of the selected commandline options and commandline args.
Packit Service 360c39
Packit Service 360c39
    The cmdlineOpts which is the options user selected and cmdLineArgs
Packit Service 360c39
    is value passed and  not associated with an option.
Packit Service 360c39
Packit Service 360c39
    @return: A tuple of the selected commandline options and commandline args.
Packit Service 360c39
    @rtype: Tuple
Packit Service 360c39
Packit Service 360c39
    @param version: The version of the this script.
Packit Service 360c39
    @type version: String
Packit Service 360c39
    """
Packit Service 360c39
    cmdParser = OptionParserExtended(version)
Packit Service 360c39
    cmdParser.add_option("-d", "--debug",
Packit Service 360c39
                         action="store_true",
Packit Service 360c39
                         dest="enableDebugLogging",
Packit Service 360c39
                         help="enables debug logging",
Packit Service 360c39
                         default=False)
Packit Service 360c39
    cmdParser.add_option("-q", "--quiet",
Packit Service 360c39
                         action="store_true",
Packit Service 360c39
                         dest="disableLoggingToConsole",
Packit Service 360c39
                         help="disables logging to console",
Packit Service 360c39
                         default=False)
Packit Service 360c39
    cmdParser.add_option("-y", "--no_ask",
Packit Service 360c39
                         action="store_true",
Packit Service 360c39
                         dest="disableQuestions",
Packit Service 360c39
                         help="disables all questions and assumes yes",
Packit Service 360c39
                         default=False)
Packit Service 360c39
    cmdParser.add_option("-i", "--info",
Packit Service 360c39
                         action="store_true",
Packit Service 360c39
                         dest="enablePrintInfo",
Packit Service 360c39
                         help="prints information about the mounted GFS2 file-systems",
Packit Service 360c39
                         default=False)
Packit Service 360c39
    cmdParser.add_option("-P", "--disable_process_gather",
Packit Service 360c39
                         action="store_true",
Packit Service 360c39
                         dest="disableProcessGather",
Packit Service 360c39
                         help="the gathering of process information will be disabled",
Packit Service 360c39
                         default=False)
Packit Service 360c39
    cmdParser.add_option("-m", "--diagnostic_data",
Packit Service 360c39
                         action="store_true",
Packit Service 360c39
                         dest="enableDiagnosticData",
Packit Service 360c39
                         help=SUPPRESS_HELP,
Packit Service 360c39
                         default=False)
Packit Service 360c39
    cmdParser.add_option("-o", "--path_to_output_dir",
Packit Service 360c39
                         action="store",
Packit Service 360c39
                         dest="pathToOutputDir",
Packit Service 360c39
                         help="the directory where all the collect data will be stored",
Packit Service 360c39
                         type="string",
Packit Service 360c39
                         metavar="<output directory>",
Packit Service 360c39
                         default="/tmp")
Packit Service 360c39
    cmdParser.add_option("-r", "--num_of_runs",
Packit Service 360c39
                         action="store",
Packit Service 360c39
                         dest="numberOfRuns",
Packit Service 360c39
                         help="number of runs capturing the lockdump data(default: 3 runs)",
Packit Service 360c39
                         type="int",
Packit Service 360c39
                         metavar="<number of runs>",
Packit Service 360c39
                         default=3)
Packit Service 360c39
    cmdParser.add_option("-s", "--seconds_sleep",
Packit Service 360c39
                         action="store",
Packit Service 360c39
                         dest="secondsToSleep",
Packit Service 360c39
                         help="number of seconds to sleep between runs of capturing the lockdump data(default: 120 seconds)",
Packit Service 360c39
                         type="int",
Packit Service 360c39
                         metavar="<seconds to sleep>",
Packit Service 360c39
                         default=120)
Packit Service 360c39
    cmdParser.add_option("-n", "--fs_name",
Packit Service 360c39
                         action="extend",
Packit Service 360c39
                         dest="listOfGFS2Names",
Packit Service 360c39
                         help="name of the GFS2 filesystem(s) that will have their lockdump data captured(default: all GFS2 file-systems will be captured)",
Packit Service 360c39
                         type="string",
Packit Service 360c39
                         metavar="<name of GFS2 filesystem>",
Packit Service 360c39
                         default=[])
Packit Service 360c39
 # Get the options and return the result.
Packit Service 360c39
    (cmdLineOpts, cmdLineArgs) = cmdParser.parse_args()
Packit Service 360c39
    return (cmdLineOpts, cmdLineArgs)
Packit Service 360c39
Packit Service 360c39
# ##############################################################################
Packit Service 360c39
# OptParse classes for commandline options
Packit Service 360c39
# ##############################################################################
Packit Service 360c39
class OptionParserExtended(OptionParser):
Packit Service 360c39
    """
Packit Service 360c39
    This is the class that gets the command line options the end user
Packit Service 360c39
    selects.
Packit Service 360c39
    """
Packit Service 360c39
    def __init__(self, version) :
Packit Service 360c39
        """
Packit Service 360c39
        @param version: The version of the this script.
Packit Service 360c39
        @type version: String
Packit Service 360c39
        """
Packit Service 360c39
        self.__commandName = os.path.basename(sys.argv[0])
Packit Service 360c39
        versionMessage = "%s %s\n" %(self.__commandName, version)
Packit Service 360c39
Packit Service 360c39
        commandDescription  ="%s gfs2_lockcapture will capture locking information from GFS2 file systems and DLM.\n"%(self.__commandName)
Packit Service 360c39
Packit Service 360c39
        OptionParser.__init__(self, option_class=ExtendOption,
Packit Service 360c39
                              version=versionMessage,
Packit Service 360c39
                              description=commandDescription)
Packit Service 360c39
Packit Service 360c39
    def print_help(self):
Packit Service 360c39
        """
Packit Service 360c39
        Print examples at the bottom of the help message.
Packit Service 360c39
        """
Packit Service 360c39
        self.print_version()
Packit Service 360c39
        examplesMessage = "\n"
Packit Service 360c39
        examplesMessage = "\nPrints information about the available GFS2 filesystems that can have lockdump data captured."
Packit Service 360c39
        examplesMessage += "\n# %s -i\n" %(self.__commandName)
Packit Service 360c39
Packit Service 360c39
        examplesMessage += "\nIt will do 3 runs of gathering the lockdump information in 10 second intervals for only the"
Packit Service 360c39
        examplesMessage += "\nGFS2 filesystems with the names myGFS2vol2,myGFS2vol1. Then it will archive and compress"
Packit Service 360c39
        examplesMessage += "\nthe data collected in the output directory /tmp and all the questions will be answered with yes.\n"
Packit Service 360c39
        examplesMessage += "\n# %s -r 3 -s 10 -n myGFS2vol2,myGFS2vol1 -o /tmp -y\n" %(self.__commandName)
Packit Service 360c39
Packit Service 360c39
        examplesMessage += "\nIt will do 2 runs of gathering the lockdump information in 25 second intervals for all the"
Packit Service 360c39
        examplesMessage += "\nmounted GFS2 filesystems. The gathering process data will be disabled. Then it will archive and compress"
Packit Service 360c39
        examplesMessage += "\nthe data collected in the output directory: /tmp and all the questions will be answered with yes.\n"
Packit Service 360c39
        examplesMessage += "\n# %s -r 2 -s 25 -P -o /tmp\n" %(self.__commandName)
Packit Service 360c39
        OptionParser.print_help(self)
Packit Service 360c39
        print(examplesMessage)
Packit Service 360c39
Packit Service 360c39
class ExtendOption (Option):
Packit Service 360c39
    """
Packit Service 360c39
    Allow to specify comma delimited list of entries for arrays
Packit Service 360c39
    and dictionaries.
Packit Service 360c39
    """
Packit Service 360c39
    ACTIONS = Option.ACTIONS + ("extend",)
Packit Service 360c39
    STORE_ACTIONS = Option.STORE_ACTIONS + ("extend",)
Packit Service 360c39
    TYPED_ACTIONS = Option.TYPED_ACTIONS + ("extend",)
Packit Service 360c39
Packit Service 360c39
    def take_action(self, action, dest, opt, value, values, parser):
Packit Service 360c39
        """
Packit Service 360c39
        This function is a wrapper to take certain options passed on command
Packit Service 360c39
        prompt and wrap them into an Array.
Packit Service 360c39
Packit Service 360c39
        @param action: The type of action that will be taken. For example:
Packit Service 360c39
        "store_true", "store_false", "extend".
Packit Service 360c39
        @type action: String
Packit Service 360c39
        @param dest: The name of the variable that will be used to store the
Packit Service 360c39
        option.
Packit Service 360c39
        @type dest: String/Boolean/Array
Packit Service 360c39
        @param opt: The option string that triggered the action.
Packit Service 360c39
        @type opt: String
Packit Service 360c39
        @param value: The value of opt(option) if it takes a
Packit Service 360c39
        value, if not then None.
Packit Service 360c39
        @type value:
Packit Service 360c39
        @param values: All the opt(options) in a dictionary.
Packit Service 360c39
        @type values: Dictionary
Packit Service 360c39
        @param parser: The option parser that was orginally called.
Packit Service 360c39
        @type parser: OptionParser
Packit Service 360c39
        """
Packit Service 360c39
        if (action == "extend") :
Packit Service 360c39
            valueList = []
Packit Service 360c39
            try:
Packit Service 360c39
                for v in value.split(","):
Packit Service 360c39
                    # Need to add code for dealing with paths if there is option for paths.
Packit Service 360c39
                    newValue = value.strip().rstrip()
Packit Service 360c39
                    if (len(newValue) > 0):
Packit Service 360c39
                        valueList.append(newValue)
Packit Service 360c39
            except:
Packit Service 360c39
                pass
Packit Service 360c39
            else:
Packit Service 360c39
                values.ensure_value(dest, []).extend(valueList)
Packit Service 360c39
        else:
Packit Service 360c39
            Option.take_action(self, action, dest, opt, value, values, parser)
Packit Service 360c39
Packit Service 360c39
# ###############################################################################
Packit Service 360c39
# Main Function
Packit Service 360c39
# ###############################################################################
Packit Service 360c39
if __name__ == "__main__":
Packit Service 360c39
    """
Packit Service 360c39
    When the script is executed then this code is ran. If there was files(not
Packit Service 360c39
    directories) created then 0 will be returned, else a 1 is returned.
Packit Service 360c39
    """
Packit Service 360c39
    try:
Packit Service 360c39
        # #######################################################################
Packit Service 360c39
        # Get the options from the commandline.
Packit Service 360c39
        # #######################################################################
Packit Service 360c39
        (cmdLineOpts, cmdLineArgs) = __getOptions(VERSION_NUMBER)
Packit Service 360c39
        # #######################################################################
Packit Service 360c39
        # Setup the logger and create config directory
Packit Service 360c39
        # #######################################################################
Packit Service 360c39
        # Create the logger
Packit Service 360c39
        logLevel = logging.INFO
Packit Service 360c39
        logger = logging.getLogger(MAIN_LOGGER_NAME)
Packit Service 360c39
        logger.setLevel(logLevel)
Packit Service 360c39
        # Create a new status function and level.
Packit Service 360c39
        logging.STATUS = logging.INFO + 2
Packit Service 360c39
        logging.addLevelName(logging.STATUS, "STATUS")
Packit Service 360c39
Packit Service 360c39
        # Log to main system logger that script has started then close the
Packit Service 360c39
        # handler before the other handlers are created.
Packit Service 360c39
        sysLogHandler = logging.handlers.SysLogHandler(address = '/dev/log')
Packit Service 360c39
        logger.addHandler(sysLogHandler)
Packit Service 360c39
        logger.info("Capturing of the data to analyze GFS2 lockdumps.")
Packit Service 360c39
        logger.removeHandler(sysLogHandler)
Packit Service 360c39
Packit Service 360c39
        # Create a function for the STATUS_LEVEL since not defined by python. This
Packit Service 360c39
        # means you can call it like the other predefined message
Packit Service 360c39
        # functions. Example: logging.getLogger("loggerName").status(message)
Packit Service 360c39
        setattr(logger, "status", lambda *args: logger.log(logging.STATUS, *args))
Packit Service 360c39
        streamHandler = logging.StreamHandler()
Packit Service 360c39
        streamHandler.setLevel(logLevel)
Packit Service 360c39
        streamHandler.setFormatter(logging.Formatter("%(levelname)s %(message)s"))
Packit Service 360c39
        logger.addHandler(streamHandler)
Packit Service 360c39
Packit Service 360c39
        # Please note there will not be a global log file created. If a log file
Packit Service 360c39
        # is needed then redirect the output. There will be a log file created
Packit Service 360c39
        # for each run in the corresponding directory.
Packit Service 360c39
Packit Service 360c39
        # #######################################################################
Packit Service 360c39
        # Set the logging levels.
Packit Service 360c39
        # #######################################################################
Packit Service 360c39
        if ((cmdLineOpts.enableDebugLogging) and (not cmdLineOpts.disableLoggingToConsole)):
Packit Service 360c39
            logging.getLogger(MAIN_LOGGER_NAME).setLevel(logging.DEBUG)
Packit Service 360c39
            streamHandler.setLevel(logging.DEBUG)
Packit Service 360c39
            message = "Debugging has been enabled."
Packit Service 360c39
            logging.getLogger(MAIN_LOGGER_NAME).debug(message)
Packit Service 360c39
        if (cmdLineOpts.disableLoggingToConsole):
Packit Service 360c39
            streamHandler.setLevel(logging.CRITICAL)
Packit Service 360c39
        # #######################################################################
Packit Service 360c39
        # Check to see if pid file exists and error if it does.
Packit Service 360c39
        # #######################################################################
Packit Service 360c39
        if (os.path.exists(PATH_TO_PID_FILENAME)):
Packit Service 360c39
            message = "The PID file %s already exists and this script cannot run till it does not exist." %(PATH_TO_PID_FILENAME)
Packit Service 360c39
            logging.getLogger(MAIN_LOGGER_NAME).error(message)
Packit Service 360c39
            message = "Verify that there are no other existing processes running. If there are running processes those need to be stopped first and the file removed."
Packit Service 360c39
            logging.getLogger(MAIN_LOGGER_NAME).info(message)
Packit Service 360c39
            exitScript(removePidFile=False, errorCode=1)
Packit Service 360c39
        else:
Packit Service 360c39
            message = "Creating the pid file: %s" %(PATH_TO_PID_FILENAME)
Packit Service 360c39
            logging.getLogger(MAIN_LOGGER_NAME).debug(message)
Packit Service 360c39
            # Creata the pid file so we dont have more than 1 process of this
Packit Service 360c39
            # script running.
Packit Service 360c39
            writeToFile(PATH_TO_PID_FILENAME, str(os.getpid()), createFile=True)
Packit Service 360c39
        # #######################################################################
Packit Service 360c39
        # Get the clusternode name and verify that mounted GFS2 filesystems were
Packit Service 360c39
        # found.
Packit Service 360c39
        # #######################################################################
Packit Service 360c39
        clusternode = getClusterNode(cmdLineOpts.listOfGFS2Names)
Packit Service 360c39
        if (clusternode == None):
Packit Service 360c39
            message = "The cluster or cluster node name could not be found."
Packit Service 360c39
            logging.getLogger(MAIN_LOGGER_NAME).error(message)
Packit Service 360c39
            exitScript(removePidFile=True, errorCode=1)
Packit Service 360c39
        elif (not len(clusternode.getMountedGFS2FilesystemNames()) > 0):
Packit Service 360c39
            message = "There were no mounted GFS2 filesystems found."
Packit Service 360c39
            if (len(cmdLineOpts.listOfGFS2Names) > 0):
Packit Service 360c39
                message = "There were no mounted GFS2 filesystems found with the name:"
Packit Service 360c39
                for name in cmdLineOpts.listOfGFS2Names:
Packit Service 360c39
                    message += " %s" %(name)
Packit Service 360c39
                message += "."
Packit Service 360c39
            logging.getLogger(MAIN_LOGGER_NAME).error(message)
Packit Service 360c39
        if (cmdLineOpts.enablePrintInfo):
Packit Service 360c39
            logging.disable(logging.CRITICAL)
Packit Service 360c39
            print("List of all the mounted GFS2 filesystems that can have their lockdump data captured:")
Packit Service 360c39
            print(clusternode)
Packit Service 360c39
            exitScript()
Packit Service 360c39
        # #######################################################################
Packit Service 360c39
        # Verify they want to continue because this script will trigger sysrq events.
Packit Service 360c39
        # #######################################################################
Packit Service 360c39
        if (not cmdLineOpts.disableQuestions and not cmdLineOpts.disableProcessGather):
Packit Service 360c39
            valid = {"yes":True, "y":True, "no":False, "n":False}
Packit Service 360c39
            question = "This script will trigger a sysrq -t event or collect the data for each pid directory located in /proc for each run. Are you sure you want to continue?"
Packit Service 360c39
            prompt = " [y/n] "
Packit Service 360c39
            while True:
Packit Service 360c39
                sys.stdout.write(question + prompt)
Packit Service 360c39
                try: # python2 compatible input
Packit Service 360c39
                    input = raw_input
Packit Service 360c39
                except NameError:
Packit Service 360c39
                    pass
Packit Service 360c39
                choice = input().lower()
Packit Service 360c39
                if (choice in valid):
Packit Service 360c39
                    if (valid.get(choice)):
Packit Service 360c39
                        # If yes, or y then exit loop and continue.
Packit Service 360c39
                        break
Packit Service 360c39
                    else:
Packit Service 360c39
                        message = "The script will not continue since you chose not to continue."
Packit Service 360c39
                        logging.getLogger(MAIN_LOGGER_NAME).error(message)
Packit Service 360c39
                        exitScript(removePidFile=True, errorCode=1)
Packit Service 360c39
                else:
Packit Service 360c39
                    sys.stdout.write("Please respond with '(y)es' or '(n)o'.\n")
Packit Service 360c39
        # #######################################################################
Packit Service 360c39
        # Create the output directory to verify it can be created before
Packit Service 360c39
        # proceeding unless it is already created from a previous run data needs
Packit Service 360c39
        # to be analyzed. Probably could add more debugging on if file or dir.
Packit Service 360c39
Packit Service 360c39
        # Backup any existing directory with same name as current output
Packit Service 360c39
        # directory.
Packit Service 360c39
        # #######################################################################
Packit Service 360c39
        pathToOutputDir = "%s" %(os.path.join(cmdLineOpts.pathToOutputDir, "%s-%s" %(os.path.basename(sys.argv[0]), time.strftime("%Y-%m-%d"))))
Packit Service 360c39
        if (backupOutputDirectory(pathToOutputDir)):
Packit Service 360c39
            message = "This directory that will be used to capture all the data: %s" %(pathToOutputDir)
Packit Service 360c39
            logging.getLogger(MAIN_LOGGER_NAME).info(message)
Packit Service 360c39
            if (not mkdirs(pathToOutputDir)):
Packit Service 360c39
                exitScript(errorCode=1)
Packit Service 360c39
        else:
Packit Service 360c39
            # There was an existing directory with same path as current output
Packit Service 360c39
            # directory and it failed to back it up.
Packit Service 360c39
            message = "Please change the output directory path (-o) or manual rename or remove the existing path: %s" %(pathToOutputDir)
Packit Service 360c39
            logging.getLogger(MAIN_LOGGER_NAME).info(message)
Packit Service 360c39
            exitScript(errorCode=1)
Packit Service 360c39
        # #######################################################################
Packit Service 360c39
        # Check to see if the debug directory is mounted. If not then
Packit Service 360c39
        # log an error.
Packit Service 360c39
        # #######################################################################
Packit Service 360c39
        if(mountFilesystem("debugfs", "none", PATH_TO_DEBUG_DIR)):
Packit Service 360c39
            message = "The debug filesystem %s is mounted." %(PATH_TO_DEBUG_DIR)
Packit Service 360c39
            logging.getLogger(MAIN_LOGGER_NAME).info(message)
Packit Service 360c39
        else:
Packit Service 360c39
            message = "There was a problem mounting the debug filesystem: %s" %(PATH_TO_DEBUG_DIR)
Packit Service 360c39
            logging.getLogger(MAIN_LOGGER_NAME).error(message)
Packit Service 360c39
            message = "The debug filesystem is required to be mounted for this script to run."
Packit Service 360c39
            logging.getLogger(MAIN_LOGGER_NAME).info(message)
Packit Service 360c39
            exitScript(errorCode=1)
Packit Service 360c39
        # #######################################################################
Packit Service 360c39
        # Gather data and the lockdumps.
Packit Service 360c39
        # #######################################################################
Packit Service 360c39
        if (cmdLineOpts.numberOfRuns <= 0):
Packit Service 360c39
            message = "The number of runs must be greater than zero."
Packit Service 360c39
            logging.getLogger(MAIN_LOGGER_NAME).warning(message)
Packit Service 360c39
            exitScript(errorCode=1)
Packit Service 360c39
        # If GFS2 lockdump files were successfully copied to output directory
Packit Service 360c39
        # then the exit code will be set to 0, else the exit code will be 1.
Packit Service 360c39
        exitCode = 1
Packit Service 360c39
        for i in range(1,(cmdLineOpts.numberOfRuns + 1)):
Packit Service 360c39
            # The current log count that will start at 1 and not zero to make it
Packit Service 360c39
            # make sense in logs.
Packit Service 360c39
            # Add clusternode name under each run dir to make combining multple
Packit Service 360c39
            # clusternode gfs2_lockgather data together and all data in each run directory.
Packit Service 360c39
            pathToOutputRunDir = os.path.join(pathToOutputDir, "run%d/%s" %(i, clusternode.getClusterNodeName()))
Packit Service 360c39
            # Create the the directory that will be used to capture the data.
Packit Service 360c39
            if (not mkdirs(pathToOutputRunDir)):
Packit Service 360c39
                exitScript(errorCode=1)
Packit Service 360c39
            # Set the handler for writing to log file for this run.
Packit Service 360c39
            currentRunFileHandler = None
Packit Service 360c39
            pathToLogFile = os.path.join(pathToOutputRunDir, "%s.log" %(MAIN_LOGGER_NAME))
Packit Service 360c39
            if (((os.access(pathToLogFile, os.W_OK) and os.access("/tmp", os.R_OK))) or (not os.path.exists(pathToLogFile))):
Packit Service 360c39
                currentRunFileHandler = logging.FileHandler(pathToLogFile)
Packit Service 360c39
                currentRunFileHandler.setFormatter(logging.Formatter("%(asctime)s %(levelname)s %(message)s", "%Y-%m-%d %H:%M:%S"))
Packit Service 360c39
                logging.getLogger(MAIN_LOGGER_NAME).addHandler(currentRunFileHandler)
Packit Service 360c39
            message = "Pass (%d/%d): Gathering all the lockdump data." %(i, cmdLineOpts.numberOfRuns)
Packit Service 360c39
            logging.getLogger(MAIN_LOGGER_NAME).status(message)
Packit Service 360c39
Packit Service 360c39
            # Gather various bits of data from the clusternode.
Packit Service 360c39
            message = "Pass (%d/%d): Gathering simple data about the host." %(i, cmdLineOpts.numberOfRuns)
Packit Service 360c39
            logging.getLogger(MAIN_LOGGER_NAME).debug(message)
Packit Service 360c39
            gatherHostData(pathToOutputRunDir)
Packit Service 360c39
            # Write the clusternode name and id to the general information file.
Packit Service 360c39
            writeToFile(os.path.join(pathToOutputRunDir, "hostinformation.txt"),
Packit Service 360c39
                        "NODE_NAME=%s\nNODE_ID=%d" %(clusternode.getClusterNodeName(), clusternode.getClusterNodeID()),
Packit Service 360c39
                        appendToFile=True, createFile=True)
Packit Service 360c39
            # #######################################################################
Packit Service 360c39
            # Gather the DLM data and lock-dumps
Packit Service 360c39
            # #######################################################################
Packit Service 360c39
            # Gather data for the  DLM lockspaces that are found.
Packit Service 360c39
            lockspaceNames = clusternode.getMountedGFS2FilesystemNames(includeClusterName=False)
Packit Service 360c39
            # In addition always gather these lockspaces(if they exist).
Packit Service 360c39
            lockspaceNames.append("clvmd")
Packit Service 360c39
            lockspaceNames.append("rgmanager")
Packit Service 360c39
            # Verify that these lockspace names exist.
Packit Service 360c39
            lockspaceNames = getVerifiedDLMLockspaceNames(lockspaceNames)
Packit Service 360c39
            # Gather the dlm locks.
Packit Service 360c39
            message = "Pass (%d/%d): Gathering the DLM lock-dumps for the host." %(i, cmdLineOpts.numberOfRuns)
Packit Service 360c39
            logging.getLogger(MAIN_LOGGER_NAME).debug(message)
Packit Service 360c39
            # Add other notable lockspace names that should be captured if they exist.
Packit Service 360c39
            gatherDLMLockDumps(pathToOutputRunDir, lockspaceNames)
Packit Service 360c39
Packit Service 360c39
            # #######################################################################
Packit Service 360c39
            # Gather the GFS2 data and lock-dumps
Packit Service 360c39
            # #######################################################################
Packit Service 360c39
            # Gather the glock locks from gfs2.
Packit Service 360c39
            message = "Pass (%d/%d): Gathering the GFS2 lock-dumps for the host." %(i, cmdLineOpts.numberOfRuns)
Packit Service 360c39
            logging.getLogger(MAIN_LOGGER_NAME).debug(message)
Packit Service 360c39
            if(gatherGFS2LockDumps(pathToOutputRunDir, clusternode.getMountedGFS2FilesystemNames())):
Packit Service 360c39
                exitCode = 0
Packit Service 360c39
            # If enabled then gather the process data. This will be included even if -R option is enabled.
Packit Service 360c39
            if (not cmdLineOpts.disableProcessGather):
Packit Service 360c39
                # Gather the backtraces for all the pids, by grabbing the /proc/
Packit Service 360c39
                # number> or triggering sysrq events to capture task bask traces
Packit Service 360c39
                # from log.
Packit Service 360c39
                # Gather the data in the /proc/<pid> directory if the file
Packit Service 360c39
                # </proc/<pid>/stack exists. If file exists we will not trigger
Packit Service 360c39
                # sysrq events.
Packit Service 360c39
Packit Service 360c39
                # Should I gather anyhow and only capture sysrq if needed.
Packit Service 360c39
                pathToPidData = "/proc"
Packit Service 360c39
                if (isProcPidStackEnabled(pathToPidData)):
Packit Service 360c39
                    message = "Pass (%d/%d): Triggering the capture of all pid directories in %s." %(i, cmdLineOpts.numberOfRuns, pathToPidData)
Packit Service 360c39
                    logging.getLogger(MAIN_LOGGER_NAME).debug(message)
Packit Service 360c39
                    gatherPidData(pathToPidData, os.path.join(pathToOutputRunDir, pathToPidData.strip("/")))
Packit Service 360c39
                else:
Packit Service 360c39
                    message = "Pass (%d/%d): Triggering the sysrq events for the host since stack was not captured in pid directory." %(i, cmdLineOpts.numberOfRuns)
Packit Service 360c39
                    logging.getLogger(MAIN_LOGGER_NAME).debug(message)
Packit Service 360c39
                    triggerSysRQEvents()
Packit Service 360c39
Packit Service 360c39
            # Gather log files
Packit Service 360c39
            message = "Pass (%d/%d): Gathering the log files for the host." %(i, cmdLineOpts.numberOfRuns)
Packit Service 360c39
            logging.getLogger(MAIN_LOGGER_NAME).debug(message)
Packit Service 360c39
            gatherLogs(os.path.join(pathToOutputRunDir, "logs"))
Packit Service 360c39
Packit Service 360c39
            # Gather diagnostic data
Packit Service 360c39
            message = "Pass (%d/%d): Gathering diagnostic data about the host." %(i, cmdLineOpts.numberOfRuns)
Packit Service 360c39
            logging.getLogger(MAIN_LOGGER_NAME).debug(message)
Packit Service 360c39
            gatherDiagnosticData(pathToOutputRunDir)
Packit Service 360c39
            if (cmdLineOpts.enableDiagnosticData):
Packit Service 360c39
                # Gather diagnostic data
Packit Service 360c39
                message = "Pass (%d/%d): Gathering optional diagnostic data about the host." %(i, cmdLineOpts.numberOfRuns)
Packit Service 360c39
                logging.getLogger(MAIN_LOGGER_NAME).debug(message)
Packit Service 360c39
                gatherOptionalDiagnosticData(pathToOutputRunDir)
Packit Service 360c39
Packit Service 360c39
            # #######################################################################
Packit Service 360c39
            # Sleep for X seconds between runs
Packit Service 360c39
            # #######################################################################
Packit Service 360c39
            # Sleep between each run if secondsToSleep is greater than or equal
Packit Service 360c39
            # to 0 and current run is not the last run. Add 2 seconds to each sleep so
Packit Service 360c39
            # that we know that there is a timestamp difference in logs between runs.
Packit Service 360c39
            # The minimal sleep is 2 seconds.
Packit Service 360c39
            secondsToSleep = cmdLineOpts.secondsToSleep + 2
Packit Service 360c39
            if (secondsToSleep < 2):
Packit Service 360c39
                secondsToSleep = 2
Packit Service 360c39
            if (i < cmdLineOpts.numberOfRuns):
Packit Service 360c39
                message = "The script will sleep for %d seconds between each run of capturing the lockdump data." %(secondsToSleep)
Packit Service 360c39
                logging.getLogger(MAIN_LOGGER_NAME).info(message)
Packit Service 360c39
                time.sleep(secondsToSleep)
Packit Service 360c39
            # Remove the handler:
Packit Service 360c39
            logging.getLogger(MAIN_LOGGER_NAME).removeHandler(currentRunFileHandler)
Packit Service 360c39
Packit Service 360c39
        # #######################################################################
Packit Service 360c39
        # Archive the directory that contains all the data and archive it after
Packit Service 360c39
        # all the information has been gathered.
Packit Service 360c39
        # #######################################################################
Packit Service 360c39
        message = "All the files have been gathered and this directory contains all the captured data: %s" %(pathToOutputDir)
Packit Service 360c39
        logging.getLogger(MAIN_LOGGER_NAME).info(message)
Packit Service 360c39
        message = "The lockdump data will now be archive. This could some time depending on the size of the data collected."
Packit Service 360c39
        logging.getLogger(MAIN_LOGGER_NAME).info(message)
Packit Service 360c39
        pathToTarFilename = archiveData(pathToOutputDir)
Packit Service 360c39
        if (os.path.exists(pathToTarFilename)):
Packit Service 360c39
            message = "The compressed archvied file was created: %s" %(pathToTarFilename)
Packit Service 360c39
            logging.getLogger(MAIN_LOGGER_NAME).info(message)
Packit Service 360c39
            # Do some cleanup by removing the directory of the data if file archived file was created.
Packit Service 360c39
            try:
Packit Service 360c39
                shutil.rmtree(pathToOutputDir)
Packit Service 360c39
            except OSError:
Packit Service 360c39
                message = "There was an error removing the directory: %s." %(pathToOutputDir)
Packit Service 360c39
                logging.getLogger(MAIN_LOGGER_NAME).error(message)
Packit Service 360c39
        else:
Packit Service 360c39
            message = "The compressed archvied failed to be created: %s" %(pathToTarFilename)
Packit Service 360c39
            logging.getLogger(MAIN_LOGGER_NAME).error(message)
Packit Service 360c39
        # #######################################################################
Packit Service 360c39
    except KeyboardInterrupt:
Packit Service 360c39
        print("")
Packit Service 360c39
        message =  "This script will exit since control-c was executed by end user."
Packit Service 360c39
        logging.getLogger(MAIN_LOGGER_NAME).error(message)
Packit Service 360c39
        exitScript(errorCode=1)
Packit Service 360c39
    # #######################################################################
Packit Service 360c39
    # Exit the application with zero exit code since we cleanly exited.
Packit Service 360c39
    # #######################################################################
Packit Service 360c39
    exitScript(errorCode=exitCode)