Simplistig locking for --incremental.
From: Bill Nottingham <notting@redhat.com> mdadm --incremental doesn't really do any locking. If you get multiple events in parallel for the same device (that has not yet started), they will all go down the path to create the array. One will succeed, the rest will have SET_ARRAY_INFO die with -EBUSY (md: array mdX already has disks!) and will exit without adding the disk. Original bug report is: https://bugzilla.redhat.com/show_bug.cgi?id=433932 This is solved by adding very very rudimentary locking. Incremental() now opens the device with O_EXCL to ensure only one invocation is frobbing the array at once. A simple loop just tries to open 5 times a second for 5 seconds. If the array stays locked that long, you probably have bigger issues.
This commit is contained in:
parent
62552fdfcc
commit
767bd45298
15
mdopen.c
15
mdopen.c
|
@ -302,6 +302,7 @@ int open_mddev_devnum(char *devname, int devnum, char *name, char *chosen_name)
|
|||
*/
|
||||
int major_num, minor_num;
|
||||
struct stat stb;
|
||||
int i;
|
||||
|
||||
if (devname)
|
||||
strcpy(chosen_name, devname);
|
||||
|
@ -353,5 +354,17 @@ int open_mddev_devnum(char *devname, int devnum, char *name, char *chosen_name)
|
|||
}
|
||||
/* FIXME chown/chmod ?? */
|
||||
}
|
||||
return open(chosen_name, O_RDWR);
|
||||
|
||||
/* Simple locking to avoid --incr being called for the same
|
||||
* array multiple times in parallel.
|
||||
*/
|
||||
for (i = 0; i < 25 ; i++) {
|
||||
int fd;
|
||||
|
||||
fd = open(chosen_name, O_RDWR|O_EXCL);
|
||||
if (fd >= 0 || errno != EBUSY)
|
||||
return fd;
|
||||
usleep(200000);
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue