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>
This commit is contained in:
parent
452dc4d13a
commit
d11abe4bd5
24
Detail.c
24
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);
|
||||
|
|
1
ReadMe.c
1
ReadMe.c
|
@ -181,6 +181,7 @@ struct option long_options[] = {
|
|||
|
||||
/* For Detail/Examine */
|
||||
{"brief", 0, 0, Brief},
|
||||
{"no-devices",0, 0, NoDevices},
|
||||
{"export", 0, 0, 'Y'},
|
||||
{"sparc2.2", 0, 0, Sparc22},
|
||||
{"test", 0, 0, 't'},
|
||||
|
|
4
mdadm.c
4
mdadm.c
|
@ -159,6 +159,10 @@ int main(int argc, char *argv[])
|
|||
c.brief = 1;
|
||||
continue;
|
||||
|
||||
case NoDevices:
|
||||
c.no_devices = 1;
|
||||
continue;
|
||||
|
||||
case 'Y': c.export++;
|
||||
continue;
|
||||
|
||||
|
|
Loading…
Reference in New Issue