First steps to supporting auto-spare-add to groups of partitioned devices.
Adding a spare to a group of partitioned devices is quite different from adding one to an array. So detect which option is worth trying based on policy and then try one or the other - or possibly both - as appropriate. Signed-off-by: NeilBrown <neilb@suse.de>
This commit is contained in:
parent
0592faeb5e
commit
56e8be854a
122
Incremental.c
122
Incremental.c
|
@ -714,7 +714,7 @@ static int count_active(struct supertype *st, int mdfd, char **availp,
|
||||||
return cnt + cnt1;
|
return cnt + cnt1;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int try_spare(char *devname, int *dfdp, struct dev_policy *pol,
|
static int array_try_spare(char *devname, int *dfdp, struct dev_policy *pol,
|
||||||
struct supertype *st, int verbose)
|
struct supertype *st, int verbose)
|
||||||
{
|
{
|
||||||
/* This device doesn't have any md metadata
|
/* This device doesn't have any md metadata
|
||||||
|
@ -724,47 +724,15 @@ static int try_spare(char *devname, int *dfdp, struct dev_policy *pol,
|
||||||
* Return 0 on success, or some exit code on failure, probably 1.
|
* Return 0 on success, or some exit code on failure, probably 1.
|
||||||
*/
|
*/
|
||||||
int rv = -1;
|
int rv = -1;
|
||||||
char bufpad[4096 + 4096];
|
|
||||||
char *buf = (char*)(((long)bufpad + 4096) & ~4095);
|
|
||||||
struct stat stb;
|
struct stat stb;
|
||||||
struct map_ent *mp, *map = NULL;
|
struct map_ent *mp, *map = NULL;
|
||||||
struct mdinfo *chosen = NULL;
|
struct mdinfo *chosen = NULL;
|
||||||
int dfd = *dfdp;
|
int dfd = *dfdp;
|
||||||
|
|
||||||
/* First check policy */
|
|
||||||
if (!policy_action_allows(pol, st?st->ss->name:NULL, act_spare))
|
|
||||||
return 1;
|
|
||||||
|
|
||||||
if (fstat(dfd, &stb) != 0)
|
if (fstat(dfd, &stb) != 0)
|
||||||
return 1;
|
return 1;
|
||||||
/* Now check if the device is bare - we don't add non-bare devices
|
|
||||||
* yet even if action=-spare
|
|
||||||
*/
|
|
||||||
|
|
||||||
if (lseek(dfd, 0, SEEK_SET) != 0 ||
|
/*
|
||||||
read(dfd, buf, 4096) != 4096) {
|
|
||||||
not_bare:
|
|
||||||
if (verbose > 1)
|
|
||||||
fprintf(stderr, Name ": %s is not bare, so not considering as a spare\n",
|
|
||||||
devname);
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
if (buf[0] != '\0' && buf[0] != '\x5a' && buf[0] != '\xff')
|
|
||||||
goto not_bare;
|
|
||||||
if (memcmp(buf, buf+1, 4095) != 0)
|
|
||||||
goto not_bare;
|
|
||||||
|
|
||||||
/* OK, first 4K appear blank, try the end. */
|
|
||||||
if (lseek(dfd, -4096, SEEK_END) < 0 ||
|
|
||||||
read(dfd, buf, 4096) != 4096)
|
|
||||||
goto not_bare;
|
|
||||||
|
|
||||||
if (buf[0] != '\0' && buf[0] != '\x5a' && buf[0] != '\xff')
|
|
||||||
goto not_bare;
|
|
||||||
if (memcmp(buf, buf+1, 4095) != 0)
|
|
||||||
goto not_bare;
|
|
||||||
|
|
||||||
/* This device passes our test for 'is bare'.
|
|
||||||
* Now we need to find a suitable array to add this to.
|
* Now we need to find a suitable array to add this to.
|
||||||
* We only accept arrays that:
|
* We only accept arrays that:
|
||||||
* - match 'st'
|
* - match 'st'
|
||||||
|
@ -886,6 +854,92 @@ static int try_spare(char *devname, int *dfdp, struct dev_policy *pol,
|
||||||
return rv ? 0 : 1;
|
return rv ? 0 : 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int partition_try_spare(char *devname, int *dfdp, struct dev_policy *pol,
|
||||||
|
struct supertype *st, int verbose)
|
||||||
|
{
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* adding a spare to a regular array is quite different from adding one to
|
||||||
|
* a set-of-partitions virtual array.
|
||||||
|
* This function determines which is worth trying and tries as appropriate.
|
||||||
|
* Arrays are given priority over partitions.
|
||||||
|
*/
|
||||||
|
static int try_spare(char *devname, int *dfdp, struct dev_policy *pol,
|
||||||
|
struct supertype *st, int verbose)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
int rv;
|
||||||
|
int arrays_ok = 0;
|
||||||
|
int partitions_ok = 0;
|
||||||
|
char bufpad[4096 + 4096];
|
||||||
|
char *buf = (char*)(((long)bufpad + 4096) & ~4095);
|
||||||
|
int dfd = *dfdp;
|
||||||
|
|
||||||
|
/* Can only add a spare if device has at least one domains */
|
||||||
|
if (pol_find(pol, pol_domain) == NULL)
|
||||||
|
return 1;
|
||||||
|
/* And only if some action allows spares */
|
||||||
|
if (!policy_action_allows(pol, st?st->ss->name:NULL, act_spare))
|
||||||
|
return 1;
|
||||||
|
|
||||||
|
/* Now check if the device is bare - we don't add non-bare devices
|
||||||
|
* yet even if action=-spare
|
||||||
|
*/
|
||||||
|
|
||||||
|
if (lseek(dfd, 0, SEEK_SET) != 0 ||
|
||||||
|
read(dfd, buf, 4096) != 4096) {
|
||||||
|
not_bare:
|
||||||
|
if (verbose > 1)
|
||||||
|
fprintf(stderr, Name ": %s is not bare, so not considering as a spare\n",
|
||||||
|
devname);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
if (buf[0] != '\0' && buf[0] != '\x5a' && buf[0] != '\xff')
|
||||||
|
goto not_bare;
|
||||||
|
if (memcmp(buf, buf+1, 4095) != 0)
|
||||||
|
goto not_bare;
|
||||||
|
|
||||||
|
/* OK, first 4K appear blank, try the end. */
|
||||||
|
if (lseek(dfd, -4096, SEEK_END) < 0 ||
|
||||||
|
read(dfd, buf, 4096) != 4096)
|
||||||
|
goto not_bare;
|
||||||
|
|
||||||
|
if (buf[0] != '\0' && buf[0] != '\x5a' && buf[0] != '\xff')
|
||||||
|
goto not_bare;
|
||||||
|
if (memcmp(buf, buf+1, 4095) != 0)
|
||||||
|
goto not_bare;
|
||||||
|
|
||||||
|
/* This device passes our test for 'is bare'.
|
||||||
|
* Let's see what policy allows for such things.
|
||||||
|
*/
|
||||||
|
if (st) {
|
||||||
|
/* just try try 'array' or 'partition' based on this metadata */
|
||||||
|
if (st->ss->add_to_super)
|
||||||
|
return array_try_spare(devname, dfdp, pol,
|
||||||
|
st, verbose);
|
||||||
|
else
|
||||||
|
return partition_try_spare(devname, dfdp, pol,
|
||||||
|
st, verbose);
|
||||||
|
}
|
||||||
|
/* Now see which metadata type support spare */
|
||||||
|
for (i = 0; (!arrays_ok || !partitions_ok) && superlist[i] ; i++) {
|
||||||
|
if (superlist[i]->add_to_super && !arrays_ok &&
|
||||||
|
policy_action_allows(pol, superlist[i]->name, act_spare))
|
||||||
|
arrays_ok = 1;
|
||||||
|
if (superlist[i]->add_to_super == NULL && !partitions_ok &&
|
||||||
|
policy_action_allows(pol, superlist[i]->name, act_spare))
|
||||||
|
partitions_ok = 1;
|
||||||
|
}
|
||||||
|
rv = 0;
|
||||||
|
if (arrays_ok)
|
||||||
|
rv = array_try_spare(devname, dfdp, pol, st, verbose);
|
||||||
|
if (rv == 0 && partitions_ok)
|
||||||
|
rv = partition_try_spare(devname, dfdp, pol, st, verbose);
|
||||||
|
return rv;
|
||||||
|
}
|
||||||
|
|
||||||
int IncrementalScan(int verbose)
|
int IncrementalScan(int verbose)
|
||||||
{
|
{
|
||||||
/* look at every device listed in the 'map' file.
|
/* look at every device listed in the 'map' file.
|
||||||
|
|
Loading…
Reference in New Issue