import CS git nfs-utils-2.3.3-69.el8_10

This commit is contained in:
AlmaLinux RelEng Bot 2026-07-08 10:41:54 -04:00
parent 5b17e0882e
commit 28c7c6d2b3
4 changed files with 238 additions and 1 deletions

View File

@ -0,0 +1,133 @@
From 0f5fe65d83f7455112aea82bf96f99523cb03ca7 Mon Sep 17 00:00:00 2001
From: Aaron Tomlin <atomlin@atomlin.com>
Date: Fri, 6 Mar 2026 17:01:44 -0500
Subject: [PATCH] nfsrahead: enable event-driven mountinfo monitoring and skip
non-NFS devices
The nfsrahead utility relies on parsing "/proc/self/mountinfo" to
correlate a device number with a specific NFS mount point. However, due
to the asynchronous nature of system initialisation, the relevant entry
in mountinfo may not be immediately available when the tool is executed.
Currently, the utility employs a naive polling mechanism, retrying the
search five times with a fixed 50ms delay (totalling 250ms). This
approach proves brittle on systems under heavy load or during
distinctively slow boot sequences.
To mitigate this race condition and improve robustness, update
get_device_info() to utilise the libmount monitoring API.
The new implementation introduces the following logic:
1. Initialises a monitor on /proc/self/mountinfo using
mnt_new_monitor().
2. Replaces the fixed polling loop with mnt_monitor_wait().
3. Increases the maximum wait time to 10 seconds (MNT_NM_TIMEOUT).
4. Introduces a fast-path rejection mechanism. NFS backing devices are
allocated from the kernel's unnamed block device pool (major number
0). While some local multi-device filesystems (such as Btrfs) also
utilise anonymous device numbers, physical hardware block devices
(e.g., sda, nvme) always possess specific, non-zero major numbers.
By instantly exiting with -ENODEV for any device string not
beginning with "0:", we safely bypass the monitor for physical
drives, preventing the exhaustion of udev worker threads.
See set_anon_super() and get_anon_bdev().
5. Implements strict monotonic deadline tracking within the monitor
loop to prevent indefinite blocking.
Fixes: 2b62ac4c ("nfsrahead: enable event-driven mountinfo monitoring")
Reported-by: Yi Zhang <yi.zhang@redhat.com>
Link: https://lore.kernel.org/linux-block/CAHj4cs8URj2fJ7KyP9ViAm6npVOaMiAErnw2uFyPYEU2wb7G_w@mail.gmail.com/T/#t
Signed-off-by: Aaron Tomlin <atomlin@atomlin.com>
Signed-off-by: Steve Dickson <steved@redhat.com>
---
tools/nfsrahead/main.c | 55 +++++++++++++++++++++++++++++++++++++++++-
1 file changed, 54 insertions(+), 1 deletion(-)
diff --git a/tools/nfsrahead/main.c b/tools/nfsrahead/main.c
index b7b889ff..78cd2581 100644
--- a/tools/nfsrahead/main.c
+++ b/tools/nfsrahead/main.c
@@ -3,6 +3,7 @@
#include <stdlib.h>
#include <errno.h>
#include <unistd.h>
+#include <time.h>
#include <libmount/libmount.h>
#include <sys/sysmacros.h>
@@ -17,6 +18,8 @@
#define CONF_NAME "nfsrahead"
#define NFS_DEFAULT_READAHEAD 128
+#define MNT_NM_TIMEOUT 10000
+
/* Device information from the system */
struct device_info {
char *device_number;
@@ -117,7 +120,57 @@ out_free_device_info:
static int get_device_info(const char *device_number, struct device_info *device_info)
{
- int ret = get_mountinfo(device_number, device_info, MOUNTINFO_PATH);
+ int ret;
+ struct libmnt_monitor *mn = NULL;
+ struct timespec start, now;
+ int remaining_ms = MNT_NM_TIMEOUT;
+
+ /*
+ * Fast-path rejection:
+ * NFS backing devices always use the anonymous block device major number (0).
+ * If the device number does not start with "0:", it is a physical block device
+ * and will never be an NFS mount. Exit immediately to prevent blocking udev.
+ */
+ if (strncmp(device_number, "0:", 2) != 0)
+ return -ENODEV;
+
+ ret = get_mountinfo(device_number, device_info, MOUNTINFO_PATH);
+ if (ret == 0)
+ return 0;
+
+ mn = mnt_new_monitor();
+ if (!mn)
+ goto fallback;
+
+ if (mnt_monitor_enable_kernel(mn, 1) < 0) {
+ mnt_unref_monitor(mn);
+ goto fallback;
+ }
+
+ clock_gettime(CLOCK_MONOTONIC, &start);
+
+ while (remaining_ms > 0) {
+ int rc = mnt_monitor_wait(mn, remaining_ms);
+ if (rc > 0) {
+ ret = get_mountinfo(device_number, device_info, MOUNTINFO_PATH);
+ if (ret == 0) {
+ mnt_unref_monitor(mn);
+ return 0;
+ }
+ } else {
+ break;
+ }
+
+ clock_gettime(CLOCK_MONOTONIC, &now);
+ long elapsed_ms = (now.tv_sec - start.tv_sec) * 1000 +
+ (now.tv_nsec - start.tv_nsec) / 1000000;
+ remaining_ms = MNT_NM_TIMEOUT - elapsed_ms;
+ }
+
+ mnt_unref_monitor(mn);
+ return ret;
+
+fallback:
for (int retry_count = 0; retry_count < 5 && ret != 0; retry_count++) {
usleep(50000);
ret = get_mountinfo(device_number, device_info, MOUNTINFO_PATH);
--
2.43.7

View File

@ -0,0 +1,48 @@
From 3395a0aa79286ce9c3df283fd9fb6db14dbbc333 Mon Sep 17 00:00:00 2001
From: Aaron Tomlin <atomlin@atomlin.com>
Date: Wed, 11 Mar 2026 15:14:16 -0400
Subject: [PATCH 2/2] nfsrahead: quieten misleading error for non-NFS block
devices
When get_device_info() evaluates a physical block device via the
fast-path rejection logic, it deliberately returns -ENODEV.
Previously, main() handled this by logging a D_GENERAL error ("unable to
find device"). Because udev invokes nfsrahead for all block devices
across the system, this results in misleading journal spam for devices
that were intentionally skipped, rather than genuinely missing.
Update the error handling logic in main() to explicitly catch the
-ENODEV return code. When encountered, log a more accurate "skipping
non-NFS device" message at the D_ALL debugging level. This prevents
unnecessary journal noise whilst maintaining the existing behaviour of
returning the errno exit status.
Reported-by: Yi Zhang <yi.zhang@redhat.com>
Tested-by: Yi Zhang <yi.zhang@redhat.com>
Signed-off-by: Aaron Tomlin <atomlin@atomlin.com>
Signed-off-by: Steve Dickson <steved@redhat.com>
---
tools/nfsrahead/main.c | 6 +++++-
1 file changed, 5 insertions(+), 1 deletion(-)
diff --git a/tools/nfsrahead/main.c b/tools/nfsrahead/main.c
index 33487f37..86c7fcc6 100644
--- a/tools/nfsrahead/main.c
+++ b/tools/nfsrahead/main.c
@@ -218,7 +218,11 @@ int main(int argc, char **argv)
if ((argc - optind) != 1)
xlog_err("expected the device number of a BDI; is udev ok?");
- if ((ret = get_device_info(argv[optind], &device)) != 0 || device.fstype == NULL) {
+ ret = get_device_info(argv[optind], &device);
+ if (ret == -ENODEV) {
+ xlog(D_ALL, "skipping non-NFS device %s\n", argv[optind]);
+ goto out;
+ } else if (ret != 0 || device.fstype == NULL) {
xlog(D_GENERAL, "unable to find device %s\n", argv[optind]);
goto out;
}
--
2.43.7

View File

@ -0,0 +1,48 @@
From 20fa4785ce5235c41fd27044d7fdef377dd0e088 Mon Sep 17 00:00:00 2001
From: Aaron Tomlin <atomlin@atomlin.com>
Date: Wed, 11 Mar 2026 12:41:28 -0400
Subject: [PATCH 1/2] nfsrahead: zero-initialise device_info struct
A recent commit introduced a fast-path rejection mechanism to prevent
udev worker thread exhaustion. However, this optimisation exposed a bug
in the initialisation of the device_info struct in main().
When the fast-path is triggered (e.g., for a physical block device like
8:16), get_device_info() instantly returns -ENODEV. Because this early
exit occurs before get_mountinfo() is invoked, init_device_info() is
never called.
Consequently, the device_info struct remains populated with
uninitialised stack memory. When main() catches the error and jumps to
the cleanup path, free_device_info() attempts to call free() on garbage
pointers, resulting in a glibc abort(3).
Fix this by explicitly zero-initialising the device_info struct at
declaration, preventing the cleanup path from freeing uninitialised
memory during an early exit.
Fixes: 0f5fe65d ("nfsrahead: fix udev worker exhaustion by skipping non-NFS devices")
Reported-by: Yi Zhang <yi.zhang@redhat.com>
Tested-by: Yi Zhang <yi.zhang@redhat.com>
Signed-off-by: Aaron Tomlin <atomlin@atomlin.com>
Signed-off-by: Steve Dickson <steved@redhat.com>
---
tools/nfsrahead/main.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/tools/nfsrahead/main.c b/tools/nfsrahead/main.c
index 78cd2581..33487f37 100644
--- a/tools/nfsrahead/main.c
+++ b/tools/nfsrahead/main.c
@@ -191,7 +191,7 @@ static int conf_get_readahead(const char *kind) {
int main(int argc, char **argv)
{
int ret = 0, opt;
- struct device_info device;
+ struct device_info device = { 0 };
unsigned int readahead = 128, log_level, log_stderr = 0;
--
2.43.7

View File

@ -2,7 +2,7 @@ Summary: NFS utilities and supporting clients and daemons for the kernel NFS ser
Name: nfs-utils
URL: http://linux-nfs.org/
Version: 2.3.3
Release: 68%{?dist}
Release: 69%{?dist}
Epoch: 1
# group all 32bit related archs
@ -124,6 +124,9 @@ Patch066: nfs-utils-2.3.3-mountd-Minor-refactor-of-get_rootfh.patch
Patch067: nfs-utils-2.3.3-mountd-Separate-lookup-of-the-exported-directory-and.patch
Patch068: nfs-utils-2.3.3-support-Add-a-mini-library-to-extract-and-apply-RPC-.patch
Patch069: nfs-utils-2.3.3-Fix-access-checks-when-mounting-subdirectories-in-NF.patch
Patch070: nfs-utils-2.3.3-nfsrahead-enable-event-driven-mountinfo-monitoring-a.patch
Patch071: nfs-utils-2.3.3-nfsrahead-zero-initialise-device_info-struct.patch
Patch072: nfs-utils-2.3.3-nfsrahead-quieten-misleading-error-for-non-NFS-block.patch
Patch100: nfs-utils-1.2.1-statdpath-man.patch
Patch101: nfs-utils-1.2.1-exp-subtree-warn-off.patch
@ -403,6 +406,11 @@ fi
%{_libdir}/libnfsidmap.so
%changelog
* Thu Mar 19 2026 Scott Mayhew <smayhew@redhat.com> 2.3.3-69
- nfsrahead: enable event-driven mountinfo monitoring and skip non-NFS devices (RHEL-150760)
- nfsrahead: zero-initialise device_info struct (RHEL-150760)
- nfsrahead: quieten misleading error for non-NFS block devices (RHEL-150760)
* Fri Feb 27 2026 Scott Mayhew <smayhew@redhat.com> 2.3.3-68
- Add requires for selinux-policy (RHEL-127095)