summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--Assemble.c34
-rw-r--r--ReadMe.c1
-rw-r--r--mdadm.c27
-rw-r--r--mdadm.h1
4 files changed, 60 insertions, 3 deletions
diff --git a/Assemble.c b/Assemble.c
index cde0fa70..c01a66f0 100644
--- a/Assemble.c
+++ b/Assemble.c
@@ -134,7 +134,7 @@ int Assemble(struct supertype *st, char *mddev, int mdfd,
int chosen_drive;
int change = 0;
int inargv = 0;
- int start_partial_ok = (runstop >= 0) && (force || devlist==NULL);
+ int start_partial_ok = (runstop >= 0) && (force || devlist==NULL || mdfd < 0);
unsigned int num_devs;
mddev_dev_t tmpdev;
struct mdinfo info;
@@ -293,11 +293,14 @@ int Assemble(struct supertype *st, char *mddev, int mdfd,
if (mdfd < 0) {
if (tst == NULL || super == NULL)
continue;
- if (tst->ss->match_home(super, homehost)==0) {
+ if (update == NULL &&
+ tst->ss->match_home(super, homehost)==0) {
if ((inargv && verbose >= 0) || verbose > 0)
fprintf(stderr, Name ": %s is not built for host %s.\n",
devname, homehost);
/* Auto-assemble, and this is not a usable host */
+ /* if update != NULL, we are updating the host
+ * name... */
continue;
}
}
@@ -846,7 +849,32 @@ int Assemble(struct supertype *st, char *mddev, int mdfd,
fprintf(stderr, " and %d spare%s", sparecnt, sparecnt==1?"":"s");
fprintf(stderr, ".\n");
}
- if (must_close) close(mdfd);
+ if (must_close) {
+ int usecs = 1;
+ close(mdfd);
+ /* There is a nasty race with 'mdadm --monitor'.
+ * If it opens this device before we close it,
+ * it gets an incomplete open on which IO
+ * doesn't work and the capacity if wrong.
+ * If we reopen (to check for layered devices)
+ * before --monitor closes, we loose.
+ *
+ * So: wait upto 1 second for there to be
+ * a non-zero capacity.
+ */
+ while (usecs < 1000) {
+ mdfd = open(mddev, O_RDONLY);
+ if (mdfd >= 0) {
+ unsigned long size;
+ if (ioctl(mdfd, BLKGETSIZE, &size) == 0 &&
+ size > 0)
+ break;
+ close(mdfd);
+ }
+ usleep(usecs);
+ usecs <<= 1;
+ }
+ }
return 0;
}
fprintf(stderr, Name ": failed to RUN_ARRAY %s: %s\n",
diff --git a/ReadMe.c b/ReadMe.c
index ca2bc77d..b6284ab2 100644
--- a/ReadMe.c
+++ b/ReadMe.c
@@ -138,6 +138,7 @@ struct option long_options[] = {
{"write-mostly",0, 0, 'W'},
{"re-add", 0, 0, ReAdd},
{"homehost", 1, 0, HomeHost},
+ {"auto-update-homehost", 0, 0, AutoHomeHost},
/* For assemble */
{"uuid", 1, 0, 'u'},
diff --git a/mdadm.c b/mdadm.c
index ff656e41..fc50d762 100644
--- a/mdadm.c
+++ b/mdadm.c
@@ -100,6 +100,7 @@ int main(int argc, char *argv[])
int re_add = 0;
char *shortopt = short_options;
int dosyslog = 0;
+ int auto_update_home = 0;
int copies;
int print_help = 0;
@@ -315,6 +316,9 @@ int main(int argc, char *argv[])
}
continue;
+ case O(ASSEMBLE,AutoHomeHost):
+ auto_update_home = 1;
+ continue;
case O(CREATE,'e'):
case O(ASSEMBLE,'e'):
case O(MISC,'e'): /* set metadata (superblock) information */
@@ -1037,10 +1041,33 @@ int main(int argc, char *argv[])
cnt++;
acnt++;
}
+ if (rv2 == 1)
+ /* found something so even though assembly failed we
+ * want to avoid auto-updates
+ */
+ auto_update_home = 0;
} while (rv2!=2);
/* Incase there are stacked devices, we need to go around again */
devlist = conf_get_devs(configfile);
} while (acnt);
+ if (cnt == 0 && auto_update_home && homehost) {
+ /* Nothing found, maybe we need to bootstrap homehost info */
+ do {
+ acnt = 0;
+ do {
+ rv2 = Assemble(ss, NULL, -1,
+ &ident, configfile,
+ devlist, NULL,
+ readonly, runstop, "homehost", homehost, verbose-quiet, force);
+ if (rv2==0) {
+ cnt++;
+ acnt++;
+ }
+ } while (rv2!=2);
+ /* Incase there are stacked devices, we need to go around again */
+ devlist = conf_get_devs(configfile);
+ } while (acnt);
+ }
if (cnt == 0 && rv == 0) {
fprintf(stderr, Name ": No arrays found in config file or automatically\n");
rv = 1;
diff --git a/mdadm.h b/mdadm.h
index 7fc3bedd..ba00a9b4 100644
--- a/mdadm.h
+++ b/mdadm.h
@@ -137,6 +137,7 @@ enum special_options {
Sparc22,
BackupFile,
HomeHost,
+ AutoHomeHost,
};
/* structures read from config file */