summaryrefslogtreecommitdiffstats
path: root/Incremental.c
diff options
context:
space:
mode:
Diffstat (limited to 'Incremental.c')
-rw-r--r--Incremental.c122
1 files changed, 114 insertions, 8 deletions
diff --git a/Incremental.c b/Incremental.c
index 9c6524f..806d192 100644
--- a/Incremental.c
+++ b/Incremental.c
@@ -87,9 +87,6 @@ int Incremental(char *devname, int verbose, int runstop,
struct createinfo *ci = conf_get_create_info();
- if (autof == 0)
- autof = ci->autof;
-
/* 1/ Check if devices is permitted by mdadm.conf */
if (!conf_test_dev(devname)) {
@@ -204,6 +201,10 @@ int Incremental(char *devname, int verbose, int runstop,
}
/* 3a/ if not, check for homehost match. If no match, reject. */
+ /* We want to support hot plugged arrays that aren't listed in
+ * /etc/mdadm.conf, so we need to skip the homehost test and allow
+ * unmatched devices through so we can simply pick a random entry
+ * to start them under
if (!match) {
if (homehost == NULL ||
st->ss->match_home(st, homehost) == 0) {
@@ -212,23 +213,128 @@ int Incremental(char *devname, int verbose, int runstop,
": not found in mdadm.conf and not identified by homehost.\n");
return 2;
}
- }
+ } */
/* 4/ Determine device number. */
- /* - If in mdadm.conf with std name, use that */
+ /* - If in mdadm.conf with any name, use that */
/* - UUID in /var/run/mdadm.map use that */
/* - If name is suggestive, use that. unless in use with */
/* different uuid. */
/* - Choose a free, high number. */
/* - Use a partitioned device unless strong suggestion not to. */
/* e.g. auto=md */
- if (match && is_standard(match->devname, &devnum))
- /* We have devnum now */;
- else if ((mp = map_by_uuid(&map, info.uuid)) != NULL)
+ if (match) {
+ int use_partitions;
+ if (autof != 0)
+ /* command line overrides config file */
+ match->autof = autof;
+ else if (match->autof == 0)
+ /* no specific autof setting in config for this */
+ /* array, so use the ci->autof instead */
+ match->autof = ci->autof;
+ switch(is_standard(match->devname, &devnum)) {
+ case 0: /* non-standard name */
+ /* Need to find a free devnum to use */
+ /* Need to know if we are supposed to be partitioned */
+ /* or not to find a free devnum in the right major */
+ switch(match->autof & 0x7) {
+ case 3:
+ case 5:
+ autof = match->autof;
+ case 0: /* this is what you get when you */
+ /* don't specify anything, leave it */
+ /* defaulting to non-partitioned for */
+ /* back compatibility */
+ use_partitions = 0;
+ break;
+ default:
+ autof = match->autof;
+ use_partitions = 1;
+ }
+ /* If we already have an assigned devnum find it */
+ if ((mp = map_by_uuid(&map, info.uuid)) != NULL)
+ devnum = mp->devnum;
+ else
+ devnum = find_free_devnum(use_partitions);
+
+ if (devnum == NoMdDev) {
+ fprintf(stderr, Name
+ ": No spare md devices!!\n");
+ return 2;
+ }
+ break;
+ case -1: /* standard, non-partitioned name */
+ switch(match->autof & 0x7) {
+ case 3:
+ case 5:
+ case 0:
+ /* all good */
+ use_partitions = 0;
+ break;
+ default:
+ /* oops, attempting to set things to */
+ /* an invalid state */
+ fprintf(stderr, Name
+ ": can't be a partitioned device by naming standards!!\n");
+ return 2;
+ }
+ break;
+ case 1: /* standard, partitioned name */
+ switch(match->autof & 0x7) {
+ case 3:
+ case 5:
+ /* oops, attempting to set things to */
+ /* an invalid state */
+ fprintf(stderr, Name
+ ": must be a partitioned device by naming standards!!\n");
+ return 2;
+ case 0:
+ /* we haven't been told how many */
+ /* partitions to make on either the */
+ /* command line or the config file, */
+ /* set to the default and enable */
+ /* partitioned mode due to our name */
+ autof = match->autof = (4 << 3) | 2;
+ default:
+ /* all good */
+ use_partitions = 1;
+ break;
+ }
+ break;
+ case 2: /* may be either partitioned or not, devnum is set */
+ switch(match->autof & 0x7) {
+ case 0:
+ /* not specified in any way, default to */
+ /* unpartitioned for back compatibility */
+ case 1:
+ case 3:
+ case 5:
+ use_partitions = 0;
+ break;
+ case 2:
+ /* partitioned, but we didn't get a number */
+ /* of parititions, so use the default */
+ match->autof = autof |= 4 << 3;
+ case 4:
+ case 6:
+ /* the number of partitions is already in */
+ /* autof */
+ use_partitions = 1;
+ break;
+ }
+ break;
+ }
+ /* We have devnum now */
+ if (use_partitions && devnum > 0)
+ devnum = (-1-devnum);
+ } else if ((mp = map_by_uuid(&map, info.uuid)) != NULL)
devnum = mp->devnum;
else {
/* Have to guess a bit. */
int use_partitions = 1;
char *np, *ep;
+
+ if (autof == 0 && ci->autof)
+ autof = ci->autof;
if ((autof&7) == 3 || (autof&7) == 5)
use_partitions = 0;
np = strchr(info.name, ':');