Whamcloud - gitweb
EX-4583 lipe: show all lpcc information in 'lpcc status' command
authorLei Feng <flei@whamcloud.com>
Wed, 19 Jan 2022 02:02:20 +0000 (21:02 -0500)
committerAndreas Dilger <adilger@whamcloud.com>
Thu, 10 Mar 2022 04:32:56 +0000 (04:32 +0000)
Collect lpcc config, lpcc_purge stats, and lustre stats related to
lpcc to together and show in 'lpcc status' command. 'lpcc status-all'
is an alias of 'lpcc status'. The output of 'lpcc status' looks like:
{
    "/mnt/lustre": {
        "pcc": [
            {
                "mount": "/mnt/lustre",
                "cache": "/mnt/pcc",
                ...
            },
            {
                "mount": "/mnt/lustre",
                "cache": "/mnt/pcc2",
                ...
            }
        ],
        "fs_stats": {
        }
}

Change-Id: I032763fb3b45646330b13f5cef34ce8658bddfe4
Signed-off-by: Lei Feng <flei@whamcloud.com>
Test-Parameters: trivial testlist=sanity-pcc
Reviewed-on: https://review.whamcloud.com/46191
Tested-by: jenkins <devops@whamcloud.com>
Tested-by: Maloo <maloo@whamcloud.com>
Reviewed-by: Andreas Dilger <adilger@whamcloud.com>
lipe/lpcc
lipe/man/lpcc-status.8

index e3d0584..3fd3c62 100755 (executable)
--- a/lipe/lpcc
+++ b/lipe/lpcc
@@ -381,6 +381,77 @@ class LpccMonitor:
         request['action'] = 'stop-all'
         return self._stop_pcc(request)
 
+    def _get_fs_stats(self, mount):
+        """
+        Get the stats of lustre fs
+        """
+        result = {}
+
+        fsname = subprocess.check_output(['lfs', 'getname', mount]).split()[0]
+        cmdline = ['lctl', 'get_param', '-n', 'llite.%s.stats' % fsname]
+        output = subprocess.check_output(cmdline)
+        for line in output.splitlines():
+            words = line.split()
+            if (words[0] == "open"):
+                result['open_count'] = int(words[1])
+            elif (words[0] == "pcc_attach"):
+                result['pcc_attach'] = int(words[1])
+            elif (words[0] == "pcc_attach_bytes"):
+                result['pcc_attach_bytes'] = int(words[6])
+            elif (words[0] == "pcc_hit_bytes"):
+                result['pcc_hit'] = int(words[1])
+                result['pcc_hit_bytes'] = int(words[6])
+            elif (words[0] == "read_bytes"):
+                result['read_bytes'] = int(words[6])
+
+        # adjust open times and calc hit ratio
+        real_hit = result.get('pcc_hit', 0) - result.get('pcc_attach', 0);
+        result['pcc_real_hit'] = real_hit
+        result.pop('pcc_hit', None)
+        result.pop('pcc_attach', None)
+        result['open_count'] = result.get('open_count', 0)
+
+        if (result['open_count'] == 0):
+            result['pcc_open_hit_pct'] = 0
+        else:
+            result['pcc_open_hit_pct'] = 100.0 * real_hit / result['open_count']
+
+        total_read_bytes = result.get('read_bytes', 0) \
+                           + result.get('pcc_hit_bytes', 0) \
+                           - result.get('pcc_attach_bytes', 0)
+        real_hit_bytes = result.get('pcc_hit_bytes', 0) \
+                         - result.get('pcc_attach_bytes', 0)
+        result['pcc_real_hit_bytes'] = real_hit_bytes;
+        result['total_read_bytes'] = total_read_bytes;
+        result.pop('read_bytes', None)
+        result.pop('pcc_hit_bytes', None)
+        result.pop('pcc_attach_bytes', None)
+        if (real_hit_bytes == 0):
+            result['pcc_read_hit_bytes_pct'] = 0
+        else:
+            result['pcc_read_hit_bytes_pct'] = 100.0 * real_hit_bytes \
+                                                 / total_read_bytes
+        return result
+
+    def _group_status_list(self, status_list):
+        """
+        Group status list by mount point and add fs_stats
+        """
+        groups = {}
+        for lpcc_status in status_list:
+            mount = lpcc_status['mount']
+            if groups.has_key(mount):
+                groups[mount]['pcc'].append(lpcc_status)
+            else:
+                groups[mount] = {}
+                groups[mount]['pcc'] = [lpcc_status,]
+
+        for mount in groups.keys():
+            fs_stats = self._get_fs_stats(mount)
+            groups[mount]['fs_stats'] = fs_stats
+
+        return groups
+
     def _status_pcc(self, request):
         response = {}
         mount = request.get('mount')
@@ -400,7 +471,7 @@ class LpccMonitor:
             status_list.append(lpcc_status)
 
         response['retcode'] = 0
-        response['status_list'] = status_list
+        response['status_list'] = self._group_status_list(status_list)
         return response
 
     def _process_cmd(self, request):
@@ -547,7 +618,7 @@ def main():
     status_parser = subparsers.add_parser('status', help=\
         'get the status of one LPCC of specfied lustre file system and ' +\
         'cache dir, or all LPCCs based on specified lustre file system')
-    status_parser.add_argument('mount', nargs=1, help=\
+    status_parser.add_argument('mount', nargs='?', help=\
         'the mount point of lustre file system')
     status_parser.add_argument('cache', nargs='?', help=\
         'the cache dir of LPCC')
@@ -598,7 +669,7 @@ def main():
     if args.action == 'status':
         request = {}
         request['action'] = args.action
-        request['mount'] = args.mount[0]
+        request['mount'] = args.mount
         request['cache'] = args.cache
 
         response = LpccCli().run_cmd(request)
index ac212dc..1d2e3e4 100644 (file)
@@ -8,17 +8,18 @@
 lpcc-status - lpcc status sub command
 
 .SH SYNOPSIS
-.BI "lpcc status MOUNT_POINT [CACHE_DIR]"
-.PP
-.BI "lpcc status-all"
+.BI "lpcc status [MOUNT_POINT [CACHE_DIR]]"
 .PP
 
 .SH DESCRIPTION
-Get status of a specific LPCC if both \fBMOUNT_POINT\fR and \fBCAHCE_DIR\fR
-are specified.
-Get status all LPCCs based on a specific Lustre file system if only
-\fBMOUNT_POINT\fR are specified.
-\fBstatus_all\fR sub command get the status of all LPCCs in config file.
+Get the status of a specific LPCC
+if both \fBMOUNT_POINT\fR and \fBCAHCE_DIR\fR are specified.
+.PP
+Get the status of all LPCCs based on a specific Lustre file system
+if only \fBMOUNT_POINT\fR are specified.
+.PP
+Get the status of all LPCCs in config file
+if neither \fBMOUNT_POINT\fR nor \fBCACHE_DIR\fR is specified.
 .PP
 .SH "SEE ALSO"
 .BR lpcc(8)