summaryrefslogtreecommitdiffstats
path: root/Detail.c
diff options
context:
space:
mode:
authorColy Li <colyli@suse.de>2019-07-31 07:29:29 +0200
committerJes Sorensen <jsorensen@fb.com>2019-08-12 22:16:36 +0200
commitd11abe4bd5cad39803726ddff1888674e417bda5 (patch)
treee93976438518db6defd35a3533d7ecfb3e3f13bd /Detail.c
parentmdadm.h: include sysmacros.h unconditionally (diff)
downloadmdadm-d11abe4bd5cad39803726ddff1888674e417bda5.tar.xz
mdadm-d11abe4bd5cad39803726ddff1888674e417bda5.zip
mdadm: add --no-devices to avoid component devices detail information
When people assemble a md raid device with a large number of component deivces (e.g. 1500 DASD disks), the raid device detail information generated by 'mdadm --detail --export $devnode' is very large. It is because the detail information contains information of all the component disks (even the missing/failed ones). In such condition, when udev-md-raid-arrays.rules is triggered and internally calls "mdadm --detail --no-devices --export $devnode", user may observe systemd error message ""invalid message length". It is because the following on-stack raw message buffer in systemd code is not big enough, systemd/src/libudev/libudev-monitor.c _public_ struct udev_device *udev_monito ... struct ucred *cred; union { struct udev_monitor_netlink_header nlh; char raw[8192]; } buf; Even change size of raw[] from 8KB to larger size, it may still be not enough for detail message of a md raid device with much larger number of component devices. To fix this problem, an extra option '--no-devices' is added (the original idea is proposed by Neil Brown). When printing detailed information of a md raid device, if '--no-devices' is specified, then all component devices information will not be printed, then the output message size can be restricted to a small number, even with the systemd only has 8KB on-disk raw buffer, the md raid array udev rules can work correctly without failure message. Signed-off-by: Coly Li <colyli@suse.de> Reviewed-by: NeilBrown <neilb@suse.com> Signed-off-by: Jes Sorensen <jsorensen@fb.com>
Diffstat (limited to 'Detail.c')
-rw-r--r--Detail.c24
1 files changed, 16 insertions, 8 deletions
diff --git a/Detail.c b/Detail.c
index 20ea03ad..ad60434f 100644
--- a/Detail.c
+++ b/Detail.c
@@ -56,7 +56,7 @@ int Detail(char *dev, struct context *c)
*/
int fd = open(dev, O_RDONLY);
mdu_array_info_t array;
- mdu_disk_info_t *disks;
+ mdu_disk_info_t *disks = NULL;
int next;
int d;
time_t atime;
@@ -280,7 +280,7 @@ int Detail(char *dev, struct context *c)
}
map_free(map);
}
- if (sra) {
+ if (!c->no_devices && sra) {
struct mdinfo *mdi;
for (mdi = sra->devs; mdi; mdi = mdi->next) {
char *path;
@@ -655,12 +655,17 @@ This is pretty boring
printf("\n\n");
}
- if (array.raid_disks)
- printf(" Number Major Minor RaidDevice State\n");
- else
- printf(" Number Major Minor RaidDevice\n");
+ if (!c->no_devices) {
+ if (array.raid_disks)
+ printf(" Number Major Minor RaidDevice State\n");
+ else
+ printf(" Number Major Minor RaidDevice\n");
+ }
}
- free(info);
+
+ /* if --no_devices specified, not print component devices info */
+ if (c->no_devices)
+ goto skip_devices_state;
for (d = 0; d < max_disks * 2; d++) {
char *dv;
@@ -747,6 +752,8 @@ This is pretty boring
if (!c->brief)
printf("\n");
}
+
+skip_devices_state:
if (spares && c->brief && array.raid_disks)
printf(" spares=%d", spares);
if (c->brief && st && st->sb)
@@ -766,8 +773,9 @@ This is pretty boring
!enough(array.level, array.raid_disks, array.layout, 1, avail))
rv = 2;
- free(disks);
out:
+ free(info);
+ free(disks);
close(fd);
free(subarray);
free(avail);