gfs2-utils: master - gfs2_lockcapture: Capture the status of the cluster nodes and find the clusternode name and id.

shane bradley sbradley at fedoraproject.org
Wed Feb 6 14:17:15 UTC 2013


Gitweb:        http://git.fedorahosted.org/git/?p=gfs2-utils.git;a=commitdiff;h=e6100419b58041b85463a76283451ebce6041707
Commit:        e6100419b58041b85463a76283451ebce6041707
Parent:        4bbf3baa94249ce80449c451460938ca33a1dff4
Author:        Shane Bradley <sbradley at redhat.com>
AuthorDate:    Thu Jan 31 09:34:24 2013 -0500
Committer:     Shane Bradley <sbradley at redhat.com>
CommitterDate: Wed Feb 6 09:13:54 2013 -0500

gfs2_lockcapture: Capture the status of the cluster nodes and find the clusternode name and id.

The status of the cluster will be captured and written to the file with respect
to version: cman_tool nodes, corosync-quorumtool -l. Added two new configuration
variables to the hostinformation.txt for the clusternode name and id. Updated man page.

Signed-off-by: Shane Bradley <sbradley at redhat.com>
---
 gfs2/man/gfs2_lockcapture.8   |    5 +-
 gfs2/scripts/gfs2_lockcapture |  102 ++++++++++++++++++++++++++++++----------
 2 files changed, 79 insertions(+), 28 deletions(-)

diff --git a/gfs2/man/gfs2_lockcapture.8 b/gfs2/man/gfs2_lockcapture.8
index 854cd71..acd9113 100644
--- a/gfs2/man/gfs2_lockcapture.8
+++ b/gfs2/man/gfs2_lockcapture.8
@@ -5,7 +5,7 @@ gfs2_lockcapture \- will capture locking information from GFS2 file systems and
 
 .SH SYNOPSIS
 .B gfs2_lockcapture \fR[-dqyt]  [-o \fIoutput directory]\fR [-r \fInumber of runs]\fR [-s \fIseconds to sleep]\fR [-n \fIname of GFS2 filesystem]\fP
-.PP 
+.PP
 .B gfs2_lockcapture \fR[-dqyi]
 
 .SH DESCRIPTION
@@ -15,7 +15,7 @@ multiple times and how much time to sleep between each iteration of capturing
 the data. By default all of the mounted GFS2 filesystems will have their data
 collected unless GFS2 filesystems are specified.
 .PP
-Please note that sysrq -t and -m events are trigger or the pid directories in /proc are 
+Please note that sysrq -t and -m events are trigger or the pid directories in /proc are
 collected on each iteration of capturing the data.
 
 .SH OPTIONS
@@ -51,3 +51,4 @@ number of seconds to sleep between runs of capturing the lockdump data.
 name of the GFS2 filesystem(s) that will have their lockdump data captured.
 .
 .SH SEE ALSO
+gfs2_lockanalyze(8)
diff --git a/gfs2/scripts/gfs2_lockcapture b/gfs2/scripts/gfs2_lockcapture
index 2b3421c..6a63fc8 100644
--- a/gfs2/scripts/gfs2_lockcapture
+++ b/gfs2/scripts/gfs2_lockcapture
@@ -45,12 +45,15 @@ class ClusterNode:
     """
     This class represents a cluster node that is a current memeber in a cluster.
     """
-    def __init__(self, clusternodeName, clusterName, mapOfMountedFilesystemLabels):
+    def __init__(self, clusternodeName, clusternodeID, clusterName, mapOfMountedFilesystemLabels):
         """
         @param clusternodeName: The name of the cluster node.
         @type clusternodeName: String
         @param clusterName: The name of the cluster that this cluster node is a
         member of.
+        @param clusternodeID: The id of the cluster node.
+        @type clusternodeID: Int
+        @param clusterName: The name of the cluster that this cluster node is a
         @type clusterName: String
         @param mapOfMountedFilesystemLabels: A map of filesystem labels(key) for
         a mounted filesystem. The value is the line for the matching mounted
@@ -58,6 +61,7 @@ class ClusterNode:
         @type mapOfMountedFilesystemLabels: Dict
         """
         self.__clusternodeName = clusternodeName
+        self.__clusternodeID  = clusternodeID
         self.__clusterName = clusterName
         self.__mapOfMountedFilesystemLabels = mapOfMountedFilesystemLabels
 
@@ -69,7 +73,7 @@ class ClusterNode:
         @rtype: String
         """
         rString = ""
-        rString += "%s:%s" %(self.getClusterName(), self.getClusterNodeName())
+        rString += "%s:%s(id:%d)" %(self.getClusterName(), self.getClusterNodeName(), self.getClusterNodeID())
         fsLabels = self.__mapOfMountedFilesystemLabels.keys()
         fsLabels.sort()
         for fsLabel in fsLabels:
@@ -85,6 +89,14 @@ class ClusterNode:
         """
         return self.__clusternodeName
 
+    def getClusterNodeID(self):
+        """
+        Returns the id of the cluster node.
+        @return: Returns the id of the cluster node.
+        @rtype: String
+        """
+        return self.__clusternodeID
+
     def getClusterName(self):
         """
         Returns the name of cluster that this cluster node is a member of.
@@ -539,6 +551,7 @@ def getClusterNode(listOfGFS2Names):
     # in the output, else return None.
     clusterName = ""
     clusternodeName = ""
+    clusternodeID = ""
     if (runCommand("which", ["cman_tool"])):
         stdout = runCommandOutput("cman_tool", ["status"])
         if (not stdout == None):
@@ -550,6 +563,8 @@ def getClusterNode(listOfGFS2Names):
                     clusterName = line.split("Cluster Name:")[1].strip().rstrip()
                 if (line.startswith("Node name: ")):
                     clusternodeName = line.split("Node name:")[1].strip().rstrip()
+                if (line.startswith("Node ID: ")):
+                    clusternodeID = line.split("Node ID: ")[1].strip().rstrip()
     elif (runCommand("which", ["corosync-cmapctl"])):
         # Another way to get the local cluster node is: $ crm_node -i; crm_node -l
         # Get the name of the cluster.
@@ -559,14 +574,14 @@ def getClusterNode(listOfGFS2Names):
             if (len(stdoutSplit) == 2):
                 clusterName = stdoutSplit[1].strip().rstrip()
         # Get the id of the local cluster node so we can get the clusternode name
-        thisNodeID = ""
+        clusternodeID = ""
         stdout = runCommandOutput("corosync-cmapctl", ["-g", "runtime.votequorum.this_node_id"])
         if (not stdout == None):
             stdoutSplit = stdout.split("=")
             if (len(stdoutSplit) == 2):
-               thisNodeID = stdoutSplit[1].strip().rstrip()
+               clusternodeID = stdoutSplit[1].strip().rstrip()
         # Now that we the nodeid then we can get the clusternode name.
-        if (len(thisNodeID) > 0):
+        if (len(clusternodeID) > 0):
             stdout = runCommandOutput("corosync-quorumtool", ["-l"])
             if (not stdout == None):
                 for line in stdout.split("\n"):
@@ -588,7 +603,15 @@ def getClusterNode(listOfGFS2Names):
                         break
                 if ((not foundMatch) and (mapOfMountedFilesystemLabels.has_key(label))):
                     del(mapOfMountedFilesystemLabels[label])
-        return ClusterNode(clusternodeName, clusterName, mapOfMountedFilesystemLabels)
+        # Cast the node id to an int, and default is 0 if node is not found or
+        # not castable.
+        clusternodeIDInt = 0
+        if (clusternodeID.isalnum()):
+            try:
+                clusternodeIDInt = int(clusternodeID)
+            except(ValueError):
+                pass
+        return ClusterNode(clusternodeName, clusternodeIDInt, clusterName, mapOfMountedFilesystemLabels)
     else:
         return None
 
@@ -701,6 +724,28 @@ def gatherGeneralInformation(pathToDSTDir):
         message = "There was an error the command output for %s to the file %s." %(command, pathToCommandOutput)
         logging.getLogger(MAIN_LOGGER_NAME).error(message)
 
+    # Write the status of all the nodes in the cluster out.
+    if (runCommand("which", ["cman_tool"])):
+        command = "cman_tool"
+        pathToCommandOutput = os.path.join(pathToDSTDir, "cman_tool_status")
+        try:
+            fout = open(pathToCommandOutput, "w")
+            runCommand(command, ["status"], standardOut=fout)
+            fout.close()
+        except IOError:
+            message = "There was an error the command output for %s to the file %s." %(command, pathToCommandOutput)
+            logging.getLogger(MAIN_LOGGER_NAME).error(message)
+    elif (runCommand("which", ["corosync-cmapctl"])):
+        command = "corosync-quorumtool"
+        pathToCommandOutput = os.path.join(pathToDSTDir, "corosync-quorumtool_l")
+        try:
+            fout = open(pathToCommandOutput, "w")
+            runCommand(command, ["-l"], standardOut=fout)
+            fout.close()
+        except IOError:
+            message = "There was an error the command output for %s to the file %s." %(command, pathToCommandOutput)
+            logging.getLogger(MAIN_LOGGER_NAME).error(message)
+
 
 def isProcPidStackEnabled(pathToPidData):
     """
@@ -1067,26 +1112,6 @@ if __name__ == "__main__":
             # script running.
             writeToFile(PATH_TO_PID_FILENAME, str(os.getpid()), createFile=True)
         # #######################################################################
-        # Verify they want to continue because this script will trigger sysrq events.
-        # #######################################################################
-        if (not cmdLineOpts.disableQuestions):
-            valid = {"yes":True, "y":True, "no":False, "n":False}
-            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?"
-            prompt = " [y/n] "
-            while True:
-                sys.stdout.write(question + prompt)
-                choice = raw_input().lower()
-                if (choice in valid):
-                    if (valid.get(choice)):
-                        # If yes, or y then exit loop and continue.
-                        break
-                    else:
-                        message = "The script will not continue since you chose not to continue."
-                        logging.getLogger(MAIN_LOGGER_NAME).error(message)
-                        exitScript(removePidFile=True, errorCode=1)
-                else:
-                    sys.stdout.write("Please respond with '(y)es' or '(n)o'.\n")
-        # #######################################################################
         # Get the clusternode name and verify that mounted GFS2 filesystems were
         # found.
         # #######################################################################
@@ -1110,6 +1135,26 @@ if __name__ == "__main__":
             print clusternode
             exitScript()
         # #######################################################################
+        # Verify they want to continue because this script will trigger sysrq events.
+        # #######################################################################
+        if (not cmdLineOpts.disableQuestions):
+            valid = {"yes":True, "y":True, "no":False, "n":False}
+            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?"
+            prompt = " [y/n] "
+            while True:
+                sys.stdout.write(question + prompt)
+                choice = raw_input().lower()
+                if (choice in valid):
+                    if (valid.get(choice)):
+                        # If yes, or y then exit loop and continue.
+                        break
+                    else:
+                        message = "The script will not continue since you chose not to continue."
+                        logging.getLogger(MAIN_LOGGER_NAME).error(message)
+                        exitScript(removePidFile=True, errorCode=1)
+                else:
+                    sys.stdout.write("Please respond with '(y)es' or '(n)o'.\n")
+        # #######################################################################
         # Create the output directory to verify it can be created before
         # proceeding unless it is already created from a previous run data needs
         # to be analyzed. Probably could add more debugging on if file or dir.
@@ -1178,6 +1223,11 @@ if __name__ == "__main__":
             message = "Pass (%d/%d): Gathering general information about the host." %(i, cmdLineOpts.numberOfRuns)
             logging.getLogger(MAIN_LOGGER_NAME).debug(message)
             gatherGeneralInformation(pathToOutputRunDir)
+            # Write the clusternode name and id to the general information file.
+            writeToFile(os.path.join(pathToOutputRunDir, "hostinformation.txt"),
+                        "NODE_NAME=%s\nNODE_ID=%d" %(clusternode.getClusterNodeName(), clusternode.getClusterNodeID()),
+                        appendToFile=True, createFile=True)
+
             # Going to sleep for 2 seconds, so that TIMESTAMP should be in the
             # past in the logs so that capturing sysrq data will be guaranteed.
             time.sleep(2)


More information about the cluster-commits mailing list