nfs-utils/nfs-utils-2.5.4-nfsiostat-fixes.patch
Steve Dickson 46db879976 mountstats/nfsiostat: bugfixes for iostat (RHEL-72243)
Signed-off-by: Steve Dickson <steved@redhat.com>
Resolves: RHEL-72243
2025-02-16 16:20:00 -05:00

311 lines
11 KiB
Diff

diff --git a/tools/mountstats/mountstats.py b/tools/mountstats/mountstats.py
index 8e129c83..d488f9e1 100755
--- a/tools/mountstats/mountstats.py
+++ b/tools/mountstats/mountstats.py
@@ -333,6 +333,11 @@ class DeviceData:
found = True
self.__parse_rpc_line(words)
+ def fstype(self):
+ """Return the fstype for the mountpoint
+ """
+ return self.__nfs_data['fstype']
+
def is_nfs_mountpoint(self):
"""Return True if this is an NFS or NFSv4 mountpoint,
otherwise return False
@@ -953,73 +958,78 @@ def nfsstat_command(args):
return 0
def print_iostat_summary(old, new, devices, time):
+ if len(devices) == 0:
+ print('No NFS mount points were found')
+ return
+
for device in devices:
stats = DeviceData()
stats.parse_stats(new[device])
- if not old or device not in old:
+ if old and device in old:
+ old_stats = DeviceData()
+ old_stats.parse_stats(old[device])
+ if stats.fstype() == old_stats.fstype():
+ stats.compare_iostats(old_stats).display_iostats(time)
+ else: # device is in old, but fstypes are different
+ stats.display_iostats(time)
+ else: # device is only in new
stats.display_iostats(time)
- else:
- if ("fstype autofs" not in str(old[device])) and ("fstype autofs" not in str(new[device])):
- old_stats = DeviceData()
- old_stats.parse_stats(old[device])
- diff_stats = stats.compare_iostats(old_stats)
- diff_stats.display_iostats(time)
+
+def list_nfs_mounts(givenlist, mountstats):
+ """return a list of NFS mounts given a list to validate or
+ return a full list if the given list is empty -
+ may return an empty list if none found
+ """
+ devicelist = []
+ if len(givenlist) > 0:
+ for device in givenlist:
+ if device in mountstats:
+ stats = DeviceData()
+ stats.parse_stats(mountstats[device])
+ if stats.is_nfs_mountpoint():
+ devicelist += [device]
+ else:
+ for device, descr in mountstats.items():
+ stats = DeviceData()
+ stats.parse_stats(descr)
+ if stats.is_nfs_mountpoint():
+ devicelist += [device]
+ return devicelist
def iostat_command(args):
"""iostat-like command for NFS mount points
"""
mountstats = parse_stats_file(args.infile)
- devices = [os.path.normpath(mp) for mp in args.mountpoints]
+ origdevices = [os.path.normpath(mp) for mp in args.mountpoints]
if args.since:
old_mountstats = parse_stats_file(args.since)
else:
old_mountstats = None
- # make certain devices contains only NFS mount points
- if len(devices) > 0:
- check = []
- for device in devices:
- stats = DeviceData()
- try:
- stats.parse_stats(mountstats[device])
- if stats.is_nfs_mountpoint():
- check += [device]
- except KeyError:
- continue
- devices = check
- else:
- for device, descr in mountstats.items():
- stats = DeviceData()
- stats.parse_stats(descr)
- if stats.is_nfs_mountpoint():
- devices += [device]
- if len(devices) == 0:
- print('No NFS mount points were found')
- return 1
-
sample_time = 0
+ # make certain devices contains only NFS mount points
+ devices = list_nfs_mounts(origdevices, mountstats)
+ print_iostat_summary(old_mountstats, mountstats, devices, sample_time)
+
if args.interval is None:
- print_iostat_summary(old_mountstats, mountstats, devices, sample_time)
return
- if args.count is not None:
- count = args.count
- while count != 0:
- print_iostat_summary(old_mountstats, mountstats, devices, sample_time)
- old_mountstats = mountstats
- time.sleep(args.interval)
- sample_time = args.interval
- mountstats = parse_stats_file(args.infile)
+ count = args.count
+ while True:
+ if count is not None:
count -= 1
- else:
- while True:
- print_iostat_summary(old_mountstats, mountstats, devices, sample_time)
- old_mountstats = mountstats
- time.sleep(args.interval)
- sample_time = args.interval
- mountstats = parse_stats_file(args.infile)
+ if count == 0:
+ break
+ time.sleep(args.interval)
+ old_mountstats = mountstats
+ sample_time = args.interval
+ mountstats = parse_stats_file(args.infile)
+ # nfs mountpoints may appear or disappear, so we need to
+ # recheck the devices list each time we parse mountstats
+ devices = list_nfs_mounts(origdevices, mountstats)
+ print_iostat_summary(old_mountstats, mountstats, devices, sample_time)
args.infile.close()
if args.since:
diff --git a/tools/nfs-iostat/nfs-iostat.py b/tools/nfs-iostat/nfs-iostat.py
index 85294fb9..e46b1a83 100755
--- a/tools/nfs-iostat/nfs-iostat.py
+++ b/tools/nfs-iostat/nfs-iostat.py
@@ -187,6 +187,11 @@ class DeviceData:
found = True
self.__parse_rpc_line(words)
+ def fstype(self):
+ """Return the fstype for the mountpoint
+ """
+ return self.__nfs_data['fstype']
+
def is_nfs_mountpoint(self):
"""Return True if this is an NFS or NFSv4 mountpoint,
otherwise return False
@@ -471,41 +476,31 @@ def parse_stats_file(filename):
return ms_dict
def print_iostat_summary(old, new, devices, time, options):
- stats = {}
- diff_stats = {}
- devicelist = []
- if old:
- # Trim device list to only include intersection of old and new data,
- # this addresses umounts due to autofs mountpoints
- for device in devices:
- if "fstype autofs" not in str(old[device]):
- devicelist.append(device)
- else:
- devicelist = devices
+ display_stats = {}
+
+ if len(devices) == 0:
+ print('No NFS mount points were found')
+ return
- for device in devicelist:
- stats[device] = DeviceData()
- stats[device].parse_stats(new[device])
- if old:
+ for device in devices:
+ stats = DeviceData()
+ stats.parse_stats(new[device])
+ if old and device in old:
old_stats = DeviceData()
old_stats.parse_stats(old[device])
- diff_stats[device] = stats[device].compare_iostats(old_stats)
+ if stats.fstype() == old_stats.fstype():
+ display_stats[device] = stats.compare_iostats(old_stats)
+ else: # device is in old, but fstypes are different
+ display_stats[device] = stats
+ else: # device is only in new
+ display_stats[device] = stats
if options.sort:
- if old:
- # We now have compared data and can print a comparison
- # ordered by mountpoint ops per second
- devicelist.sort(key=lambda x: diff_stats[x].ops(time), reverse=True)
- else:
- # First iteration, just sort by newly parsed ops/s
- devicelist.sort(key=lambda x: stats[x].ops(time), reverse=True)
+ devices.sort(key=lambda x: display_stats[x].ops(time), reverse=True)
count = 1
- for device in devicelist:
- if old:
- diff_stats[device].display_iostats(time, options.which)
- else:
- stats[device].display_iostats(time, options.which)
+ for device in devices:
+ display_stats[device].display_iostats(time, options.which)
count += 1
if (count > options.list):
@@ -520,10 +515,11 @@ def list_nfs_mounts(givenlist, mountstats):
devicelist = []
if len(givenlist) > 0:
for device in givenlist:
- stats = DeviceData()
- stats.parse_stats(mountstats[device])
- if stats.is_nfs_mountpoint():
- devicelist += [device]
+ if device in mountstats:
+ stats = DeviceData()
+ stats.parse_stats(mountstats[device])
+ if stats.is_nfs_mountpoint():
+ devicelist += [device]
else:
for device, descr in mountstats.items():
stats = DeviceData()
@@ -592,11 +588,7 @@ client are listed.
parser.add_option_group(displaygroup)
(options, args) = parser.parse_args(sys.argv)
- for arg in args:
-
- if arg == sys.argv[0]:
- continue
-
+ for arg in args[1:]:
if arg in mountstats:
origdevices += [arg]
elif not interval_seen:
@@ -622,47 +614,29 @@ client are listed.
print('Illegal <count> value %s' % arg)
return
- # make certain devices contains only NFS mount points
- devices = list_nfs_mounts(origdevices, mountstats)
- if len(devices) == 0:
- print('No NFS mount points were found')
- return
-
-
old_mountstats = None
sample_time = 0.0
+ # make certain devices contains only NFS mount points
+ devices = list_nfs_mounts(origdevices, mountstats)
+ print_iostat_summary(old_mountstats, mountstats, devices, sample_time, options)
+
if not interval_seen:
- print_iostat_summary(old_mountstats, mountstats, devices, sample_time, options)
return
- if count_seen:
- while count != 0:
- print_iostat_summary(old_mountstats, mountstats, devices, sample_time, options)
- old_mountstats = mountstats
- time.sleep(interval)
- sample_time = interval
- mountstats = parse_stats_file('/proc/self/mountstats')
- # automount mountpoints add and drop, if automount is involved
- # we need to recheck the devices list when reparsing
- devices = list_nfs_mounts(origdevices,mountstats)
- if len(devices) == 0:
- print('No NFS mount points were found')
- return
+ while True:
+ if count_seen:
count -= 1
- else:
- while True:
- print_iostat_summary(old_mountstats, mountstats, devices, sample_time, options)
- old_mountstats = mountstats
- time.sleep(interval)
- sample_time = interval
- mountstats = parse_stats_file('/proc/self/mountstats')
- # automount mountpoints add and drop, if automount is involved
- # we need to recheck the devices list when reparsing
- devices = list_nfs_mounts(origdevices,mountstats)
- if len(devices) == 0:
- print('No NFS mount points were found')
- return
+ if count == 0:
+ break
+ time.sleep(interval)
+ old_mountstats = mountstats
+ sample_time = interval
+ mountstats = parse_stats_file('/proc/self/mountstats')
+ # nfs mountpoints may appear or disappear, so we need to
+ # recheck the devices list each time we parse mountstats
+ devices = list_nfs_mounts(origdevices, mountstats)
+ print_iostat_summary(old_mountstats, mountstats, devices, sample_time, options)
#
# Main