Blame SOURCES/0032-mdadm-add-no-devices-to-avoid-component-devices-deta.patch

f9a9f5
From d11abe4bd5cad39803726ddff1888674e417bda5 Mon Sep 17 00:00:00 2001
f9a9f5
From: Coly Li <colyli@suse.de>
f9a9f5
Date: Wed, 31 Jul 2019 13:29:29 +0800
f9a9f5
Subject: [RHEL7.8 PATCH V2 32/47] mdadm: add --no-devices to avoid component
f9a9f5
 devices detail information
f9a9f5
f9a9f5
When people assemble a md raid device with a large number of
f9a9f5
component deivces (e.g. 1500 DASD disks), the raid device detail
f9a9f5
information generated by 'mdadm --detail --export $devnode' is very
f9a9f5
large. It is because the detail information contains information of
f9a9f5
all the component disks (even the missing/failed ones).
f9a9f5
f9a9f5
In such condition, when udev-md-raid-arrays.rules is triggered and
f9a9f5
internally calls "mdadm --detail --no-devices --export $devnode",
f9a9f5
user may observe systemd error message ""invalid message length". It
f9a9f5
is because the following on-stack raw message buffer in systemd code
f9a9f5
is not big enough,
f9a9f5
        systemd/src/libudev/libudev-monitor.c
f9a9f5
        _public_ struct udev_device *udev_monito ...
f9a9f5
                struct ucred *cred;
f9a9f5
                union {
f9a9f5
                        struct udev_monitor_netlink_header nlh;
f9a9f5
                        char raw[8192];
f9a9f5
                } buf;
f9a9f5
Even change size of raw[] from 8KB to larger size, it may still be not
f9a9f5
enough for detail message of a md raid device with much larger number of
f9a9f5
component devices.
f9a9f5
f9a9f5
To fix this problem, an extra option '--no-devices' is added (the
f9a9f5
original idea is proposed by Neil Brown). When printing detailed
f9a9f5
information of a md raid device, if '--no-devices' is specified, then
f9a9f5
all component devices information will not be printed, then the output
f9a9f5
message size can be restricted to a small number, even with the systemd
f9a9f5
only has 8KB on-disk raw buffer, the md raid array udev rules can work
f9a9f5
correctly without failure message.
f9a9f5
f9a9f5
Signed-off-by: Coly Li <colyli@suse.de>
f9a9f5
Reviewed-by: NeilBrown <neilb@suse.com>
f9a9f5
Signed-off-by: Jes Sorensen <jsorensen@fb.com>
f9a9f5
---
f9a9f5
 Detail.c | 24 ++++++++++++++++--------
f9a9f5
 ReadMe.c |  1 +
f9a9f5
 mdadm.c  |  4 ++++
f9a9f5
 mdadm.h  |  2 ++
f9a9f5
 4 files changed, 23 insertions(+), 8 deletions(-)
f9a9f5
f9a9f5
diff --git a/Detail.c b/Detail.c
f9a9f5
index 20ea03a..ad60434 100644
f9a9f5
--- a/Detail.c
f9a9f5
+++ b/Detail.c
f9a9f5
@@ -56,7 +56,7 @@ int Detail(char *dev, struct context *c)
f9a9f5
 	 */
f9a9f5
 	int fd = open(dev, O_RDONLY);
f9a9f5
 	mdu_array_info_t array;
f9a9f5
-	mdu_disk_info_t *disks;
f9a9f5
+	mdu_disk_info_t *disks = NULL;
f9a9f5
 	int next;
f9a9f5
 	int d;
f9a9f5
 	time_t atime;
f9a9f5
@@ -280,7 +280,7 @@ int Detail(char *dev, struct context *c)
f9a9f5
 			}
f9a9f5
 			map_free(map);
f9a9f5
 		}
f9a9f5
-		if (sra) {
f9a9f5
+		if (!c->no_devices && sra) {
f9a9f5
 			struct mdinfo *mdi;
f9a9f5
 			for (mdi  = sra->devs; mdi; mdi = mdi->next) {
f9a9f5
 				char *path;
f9a9f5
@@ -655,12 +655,17 @@ This is pretty boring
f9a9f5
 			printf("\n\n");
f9a9f5
 		}
f9a9f5
 
f9a9f5
-		if (array.raid_disks)
f9a9f5
-			printf("    Number   Major   Minor   RaidDevice State\n");
f9a9f5
-		else
f9a9f5
-			printf("    Number   Major   Minor   RaidDevice\n");
f9a9f5
+		if (!c->no_devices) {
f9a9f5
+			if (array.raid_disks)
f9a9f5
+				printf("    Number   Major   Minor   RaidDevice State\n");
f9a9f5
+			else
f9a9f5
+				printf("    Number   Major   Minor   RaidDevice\n");
f9a9f5
+		}
f9a9f5
 	}
f9a9f5
-	free(info);
f9a9f5
+
f9a9f5
+	/* if --no_devices specified, not print component devices info */
f9a9f5
+	if (c->no_devices)
f9a9f5
+		goto skip_devices_state;
f9a9f5
 
f9a9f5
 	for (d = 0; d < max_disks * 2; d++) {
f9a9f5
 		char *dv;
f9a9f5
@@ -747,6 +752,8 @@ This is pretty boring
f9a9f5
 		if (!c->brief)
f9a9f5
 			printf("\n");
f9a9f5
 	}
f9a9f5
+
f9a9f5
+skip_devices_state:
f9a9f5
 	if (spares && c->brief && array.raid_disks)
f9a9f5
 		printf(" spares=%d", spares);
f9a9f5
 	if (c->brief && st && st->sb)
f9a9f5
@@ -766,8 +773,9 @@ This is pretty boring
f9a9f5
 	    !enough(array.level, array.raid_disks, array.layout, 1, avail))
f9a9f5
 		rv = 2;
f9a9f5
 
f9a9f5
-	free(disks);
f9a9f5
 out:
f9a9f5
+	free(info);
f9a9f5
+	free(disks);
f9a9f5
 	close(fd);
f9a9f5
 	free(subarray);
f9a9f5
 	free(avail);
f9a9f5
diff --git a/ReadMe.c b/ReadMe.c
f9a9f5
index 12ccf83..eaf1042 100644
f9a9f5
--- a/ReadMe.c
f9a9f5
+++ b/ReadMe.c
f9a9f5
@@ -181,6 +181,7 @@ struct option long_options[] = {
f9a9f5
 
f9a9f5
     /* For Detail/Examine */
f9a9f5
     {"brief",	  0, 0, Brief},
f9a9f5
+    {"no-devices",0, 0, NoDevices},
f9a9f5
     {"export",	  0, 0, 'Y'},
f9a9f5
     {"sparc2.2",  0, 0, Sparc22},
f9a9f5
     {"test",      0, 0, 't'},
f9a9f5
diff --git a/mdadm.c b/mdadm.c
f9a9f5
index 25a1abd..1fb8086 100644
f9a9f5
--- a/mdadm.c
f9a9f5
+++ b/mdadm.c
f9a9f5
@@ -159,6 +159,10 @@ int main(int argc, char *argv[])
f9a9f5
 			c.brief = 1;
f9a9f5
 			continue;
f9a9f5
 
f9a9f5
+		case NoDevices:
f9a9f5
+			c.no_devices = 1;
f9a9f5
+			continue;
f9a9f5
+
f9a9f5
 		case 'Y': c.export++;
f9a9f5
 			continue;
f9a9f5
 
f9a9f5
diff --git a/mdadm.h b/mdadm.h
f9a9f5
index d61a9ca..43b07d5 100644
f9a9f5
--- a/mdadm.h
f9a9f5
+++ b/mdadm.h
f9a9f5
@@ -440,6 +440,7 @@ enum special_options {
f9a9f5
 	NoSharing,
f9a9f5
 	HelpOptions,
f9a9f5
 	Brief,
f9a9f5
+	NoDevices,
f9a9f5
 	ManageOpt,
f9a9f5
 	Add,
f9a9f5
 	AddSpare,
f9a9f5
@@ -550,6 +551,7 @@ struct context {
f9a9f5
 	int	runstop;
f9a9f5
 	int	verbose;
f9a9f5
 	int	brief;
f9a9f5
+	int	no_devices;
f9a9f5
 	int	force;
f9a9f5
 	char	*homehost;
f9a9f5
 	int	require_homehost;
f9a9f5
-- 
f9a9f5
2.7.5
f9a9f5