mdadm/assemble-EXCL-race.fix

75 lines
2.1 KiB
Plaintext
Raw Normal View History

From: NeilBrown <neilb@suse.de>
References: bnc#793954
If we get EBUSY when openning a device during ASSEMBLE,
try again a limited number of times as we could be racing with
"mdadm -I" from udev or similar.
This is fixed upstream by more intrusive locking changed.
Signed-off-by: NeilBrown <neilb@suse.de>
---
Assemble.c | 36 +++++++++++++++++++++++++++++-------
1 file changed, 29 insertions(+), 7 deletions(-)
--- mdadm-3.2.6.orig/Assemble.c
+++ mdadm-3.2.6/Assemble.c
@@ -494,7 +494,7 @@ int Assemble(struct supertype *st, char
tmpdev = NULL;
goto loop;
} else {
-
+ int cnt = 5;
content = &info;
tst->ss->getinfo_super(tst, content, NULL);
@@ -508,6 +508,13 @@ int Assemble(struct supertype *st, char
* be looking at
*/
dfd = dev_open(devname, O_RDONLY | O_EXCL);
+ while (dfd < 0 && errno == EBUSY && cnt > 0) {
+ fprintf(stderr, "EBUSY - retrying dev_open of %s\n",
+ devname);
+ usleep(200000);
+ dfd = dev_open(devname, O_RDONLY | O_EXCL);
+ cnt--;
+ }
if (dfd < 0) {
if (report_missmatch)
fprintf(stderr, Name ": %s is busy - skipping\n", devname);
@@ -1315,13 +1322,28 @@ int Assemble(struct supertype *st, char
j = chosen_drive;
if (j >= 0 /* && devices[j].uptodate */) {
- int dfd = dev_open(devices[j].devname,
- O_RDWR|O_EXCL);
- if (dfd >= 0) {
- remove_partitions(dfd);
- close(dfd);
+ int cnt = 5;
+ while (cnt > 0) {
+ int dfd = dev_open(devices[j].devname,
+ O_RDWR|O_EXCL);
+ cnt--;
+ if (dfd < 0 && errno == EBUSY) {
+ fprintf(stderr, "EBUSY - retrying open of %s\n",
+ devices[j].devname);
+ usleep(200000);
+ continue;
+ }
+ if (dfd >= 0) {
+ remove_partitions(dfd);
+ close(dfd);
+ }
+ rv = add_disk(mdfd, st, content, &devices[j].i);
+ if (rv == 0 || errno != EBUSY)
+ break;
+ fprintf(stderr, "EBUSY - retrying add of %s\n",
+ devices[j].devname);
+ usleep(200000);
}
- rv = add_disk(mdfd, st, content, &devices[j].i);
if (rv) {
fprintf(stderr, Name ": failed to add "