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);
|
int fd = open(dev, O_RDONLY);
|
||||||
mdu_array_info_t array;
|
mdu_array_info_t array;
|
||||||
mdu_disk_info_t *disks;
|
mdu_disk_info_t *disks = NULL;
|
||||||
int next;
|
int next;
|
||||||
int d;
|
int d;
|
||||||
time_t atime;
|
time_t atime;
|
||||||
|
@ -280,7 +280,7 @@ int Detail(char *dev, struct context *c)
|
||||||
}
|
}
|
||||||
map_free(map);
|
map_free(map);
|
||||||
}
|
}
|
||||||
if (sra) {
|
if (!c->no_devices && sra) {
|
||||||
struct mdinfo *mdi;
|
struct mdinfo *mdi;
|
||||||
for (mdi = sra->devs; mdi; mdi = mdi->next) {
|
for (mdi = sra->devs; mdi; mdi = mdi->next) {
|
||||||
char *path;
|
char *path;
|
||||||
|
@ -655,12 +655,17 @@ This is pretty boring
|
||||||
printf("\n\n");
|
printf("\n\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
if (array.raid_disks)
|
if (!c->no_devices) {
|
||||||
printf(" Number Major Minor RaidDevice State\n");
|
if (array.raid_disks)
|
||||||
else
|
printf(" Number Major Minor RaidDevice State\n");
|
||||||
printf(" Number Major Minor RaidDevice\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++) {
|
for (d = 0; d < max_disks * 2; d++) {
|
||||||
char *dv;
|
char *dv;
|
||||||
|
@ -747,6 +752,8 @@ This is pretty boring
|
||||||
if (!c->brief)
|
if (!c->brief)
|
||||||
printf("\n");
|
printf("\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
skip_devices_state:
|
||||||
if (spares && c->brief && array.raid_disks)
|
if (spares && c->brief && array.raid_disks)
|
||||||
printf(" spares=%d", spares);
|
printf(" spares=%d", spares);
|
||||||
if (c->brief && st && st->sb)
|
if (c->brief && st && st->sb)
|
||||||
|
@ -766,8 +773,9 @@ This is pretty boring
|
||||||
!enough(array.level, array.raid_disks, array.layout, 1, avail))
|
!enough(array.level, array.raid_disks, array.layout, 1, avail))
|
||||||
rv = 2;
|
rv = 2;
|
||||||
|
|
||||||
free(disks);
|
|
||||||
out:
|
out:
|
||||||
|
free(info);
|
||||||
|
free(disks);
|
||||||
close(fd);
|
close(fd);
|
||||||
free(subarray);
|
free(subarray);
|
||||||
free(avail);
|
free(avail);
|
||||||
|
|
1
ReadMe.c
1
ReadMe.c
|
@ -181,6 +181,7 @@ struct option long_options[] = {
|
||||||
|
|
||||||
/* For Detail/Examine */
|
/* For Detail/Examine */
|
||||||
{"brief", 0, 0, Brief},
|
{"brief", 0, 0, Brief},
|
||||||
|
{"no-devices",0, 0, NoDevices},
|
||||||
{"export", 0, 0, 'Y'},
|
{"export", 0, 0, 'Y'},
|
||||||
{"sparc2.2", 0, 0, Sparc22},
|
{"sparc2.2", 0, 0, Sparc22},
|
||||||
{"test", 0, 0, 't'},
|
{"test", 0, 0, 't'},
|
||||||
|
|
4
mdadm.c
4
mdadm.c
|
@ -159,6 +159,10 @@ int main(int argc, char *argv[])
|
||||||
c.brief = 1;
|
c.brief = 1;
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
|
case NoDevices:
|
||||||
|
c.no_devices = 1;
|
||||||
|
continue;
|
||||||
|
|
||||||
case 'Y': c.export++;
|
case 'Y': c.export++;
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
|
|
2
mdadm.h
2
mdadm.h
|
@ -440,6 +440,7 @@ enum special_options {
|
||||||
NoSharing,
|
NoSharing,
|
||||||
HelpOptions,
|
HelpOptions,
|
||||||
Brief,
|
Brief,
|
||||||
|
NoDevices,
|
||||||
ManageOpt,
|
ManageOpt,
|
||||||
Add,
|
Add,
|
||||||
AddSpare,
|
AddSpare,
|
||||||
|
@ -550,6 +551,7 @@ struct context {
|
||||||
int runstop;
|
int runstop;
|
||||||
int verbose;
|
int verbose;
|
||||||
int brief;
|
int brief;
|
||||||
|
int no_devices;
|
||||||
int force;
|
int force;
|
||||||
char *homehost;
|
char *homehost;
|
||||||
int require_homehost;
|
int require_homehost;
|
||||||
|
|
Loading…
Reference in New Issue