import CS git nfs-utils-2.3.3-69.el8_10
This commit is contained in:
parent
5b17e0882e
commit
28c7c6d2b3
@ -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
|
||||
|
||||
@ -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
|
||||
|
||||
@ -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
|
||||
|
||||
@ -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)
|
||||
|
||||
|
||||
Loading…
Reference in New Issue
Block a user