From e4274f2f5d0b90d57df3affef8ac7bc2a8aedd30 Mon Sep 17 00:00:00 2001 From: Lei Feng Date: Tue, 18 Jan 2022 21:02:20 -0500 Subject: [PATCH] EX-4583 lipe: show all lpcc information in 'lpcc status' command 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 Test-Parameters: trivial testlist=sanity-pcc Reviewed-on: https://review.whamcloud.com/46191 Tested-by: jenkins Tested-by: Maloo Reviewed-by: Andreas Dilger --- lipe/lpcc | 77 ++++++++++++++++++++++++++++++++++++++++++++++++-- lipe/man/lpcc-status.8 | 17 +++++------ 2 files changed, 83 insertions(+), 11 deletions(-) diff --git a/lipe/lpcc b/lipe/lpcc index e3d0584..3fd3c62 100755 --- 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) diff --git a/lipe/man/lpcc-status.8 b/lipe/man/lpcc-status.8 index ac212dc..1d2e3e4 100644 --- a/lipe/man/lpcc-status.8 +++ b/lipe/man/lpcc-status.8 @@ -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) -- 1.8.3.1