Allow --update=devicesize with --re-add

This is useful with 1.1 and 1.2 metadata to update the metadata if
the device size has changed.
The same functionality can be achieved by writing to the device size
in sysfs after re-adding normally, but in some cases this might be
easier.

Signed-off-by: NeilBrown <neilb@suse.de>
This commit is contained in:
NeilBrown 2010-12-09 13:06:29 +11:00
parent 691a36b76f
commit 833bb0f8f6
6 changed files with 72 additions and 16 deletions

View File

@ -980,7 +980,7 @@ static int array_try_spare(char *devname, int *dfdp, struct dev_policy *pol,
close(dfd);
*dfdp = -1;
rv = Manage_subdevs(chosen->sys_name, mdfd, &devlist,
-1, 0);
-1, 0, NULL);
close(mdfd);
}
if (verbose > 0) {
@ -1549,15 +1549,16 @@ int IncrementalRemove(char *devname, char *id_path, int verbose)
int subfd = open_dev(memb->devnum);
if (subfd >= 0) {
Manage_subdevs(memb->dev, subfd,
&devlist, verbose, 0);
&devlist, verbose, 0,
NULL);
close(subfd);
}
}
free_mdstat(mdstat);
} else
Manage_subdevs(ent->dev, mdfd, &devlist, verbose, 0);
Manage_subdevs(ent->dev, mdfd, &devlist, verbose, 0, NULL);
devlist.disposition = 'r';
rv = Manage_subdevs(ent->dev, mdfd, &devlist, verbose, 0);
rv = Manage_subdevs(ent->dev, mdfd, &devlist, verbose, 0, NULL);
close(mdfd);
free_mdstat(ent);
return rv;

View File

@ -325,7 +325,8 @@ int Manage_resize(char *devname, int fd, long long size, int raid_disks)
}
int Manage_subdevs(char *devname, int fd,
struct mddev_dev *devlist, int verbose, int test)
struct mddev_dev *devlist, int verbose, int test,
char *update)
{
/* do something to each dev.
* devmode can be
@ -691,6 +692,24 @@ int Manage_subdevs(char *devname, int fd,
remove_partitions(tfd);
close(tfd);
tfd = -1;
if (update) {
int rv = -1;
tfd = dev_open(dv->devname, O_RDWR);
if (tfd >= 0)
rv = st->ss->update_super(
st, NULL, update,
devname, verbose, 0, NULL);
if (rv == 0)
rv = tst->ss->store_super(st, tfd);
close(tfd);
tfd = -1;
if (rv != 0) {
fprintf(stderr, Name ": failed to update"
" superblock during re-add\n");
return 1;
}
}
/* don't even try if disk is marked as faulty */
errno = 0;
if (ioctl(fd, ADD_NEW_DISK, &disc) == 0) {

View File

@ -739,9 +739,9 @@ static int move_spare(struct state *from, struct state *to,
sprintf(devname, "%d:%d", major(devid), minor(devid));
devlist.disposition = 'r';
if (Manage_subdevs(from->devname, fd2, &devlist, -1, 0) == 0) {
if (Manage_subdevs(from->devname, fd2, &devlist, -1, 0, NULL) == 0) {
devlist.disposition = 'a';
if (Manage_subdevs(to->devname, fd1, &devlist, -1, 0) == 0) {
if (Manage_subdevs(to->devname, fd1, &devlist, -1, 0, NULL) == 0) {
alert("MoveSpare", to->devname, from->devname, info);
/* make sure we will see newly added spare before next
* time through loop
@ -752,7 +752,7 @@ static int move_spare(struct state *from, struct state *to,
close(fd2);
return 1;
}
else Manage_subdevs(from->devname, fd2, &devlist, -1, 0);
else Manage_subdevs(from->devname, fd2, &devlist, -1, 0, NULL);
}
close(fd1);
close(fd2);

View File

@ -1053,7 +1053,7 @@ will report failure if these specifiers didn't find any match.
.BR \-a ", " \-\-add
hot-add listed devices.
If a device appears to have recently been part of the array
(possibly it failed or was removed) the device is re-added as describe
(possibly it failed or was removed) the device is re\-added as describe
in the next point.
If that fails or the device was never part of the array, the device is
added as a hot-spare.
@ -1079,6 +1079,13 @@ When used on an array that has no metadata (i.e. it was built with
it will be assumed that bitmap-based recovery is enough to make the
device fully consistent with the array.
When
.B \-\-re\-add
can be accompanied by
.BR \-\-update=devicesize .
See the description of this option when used in Assemble mode for an
explanation of its use.
If the device name given is
.B missing
then mdadm will try to find any device that looks like it should be

40
mdadm.c
View File

@ -666,12 +666,14 @@ int main(int argc, char *argv[])
case O(ASSEMBLE,'U'): /* update the superblock */
case O(MISC,'U'):
if (update) {
fprintf(stderr, Name ": Can only update one aspect of superblock, both %s and %s given.\n",
fprintf(stderr, Name ": Can only update one aspect"
" of superblock, both %s and %s given.\n",
update, optarg);
exit(2);
}
if (mode == MISC && !subarray) {
fprintf(stderr, Name ": Only subarrays can be updated in misc mode\n");
fprintf(stderr, Name ": Only subarrays can be"
" updated in misc mode\n");
exit(2);
}
update = optarg;
@ -695,13 +697,17 @@ int main(int argc, char *argv[])
continue;
if (strcmp(update, "byteorder")==0) {
if (ss) {
fprintf(stderr, Name ": must not set metadata type with --update=byteorder.\n");
fprintf(stderr,
Name ": must not set metadata"
" type with --update=byteorder.\n");
exit(2);
}
for(i=0; !ss && superlist[i]; i++)
ss = superlist[i]->match_metadata_desc("0.swap");
ss = superlist[i]->match_metadata_desc(
"0.swap");
if (!ss) {
fprintf(stderr, Name ": INTERNAL ERROR cannot find 0.swap\n");
fprintf(stderr, Name ": INTERNAL ERROR"
" cannot find 0.swap\n");
exit(2);
}
@ -723,6 +729,27 @@ int main(int argc, char *argv[])
" 'no-bitmap'\n");
exit(outf == stdout ? 0 : 2);
case O(MANAGE,'U'):
/* update=devicesize is allowed with --re-add */
if (devmode != 'a' || re_add != 1) {
fprintf(stderr, Name "--update in Manage mode only"
" allowed with --re-add.\n");
exit(1);
}
if (update) {
fprintf(stderr, Name ": Can only update one aspect"
" of superblock, both %s and %s given.\n",
update, optarg);
exit(2);
}
update = optarg;
if (strcmp(update, "devicesize") != 0) {
fprintf(stderr, Name ": only 'devicesize' can be"
" updated with --re-add\n");
exit(2);
}
continue;
case O(INCREMENTAL,NoDegraded):
fprintf(stderr, Name ": --no-degraded is deprecated in Incremental mode\n");
case O(ASSEMBLE,NoDegraded): /* --no-degraded */
@ -1153,7 +1180,8 @@ int main(int argc, char *argv[])
rv = Manage_ro(devlist->devname, mdfd, readonly);
if (!rv && devs_found>1)
rv = Manage_subdevs(devlist->devname, mdfd,
devlist->next, verbose-quiet, test);
devlist->next, verbose-quiet, test,
update);
if (!rv && readonly < 0)
rv = Manage_ro(devlist->devname, mdfd, readonly);
if (!rv && runstop)

View File

@ -959,7 +959,8 @@ extern int Manage_ro(char *devname, int fd, int readonly);
extern int Manage_runstop(char *devname, int fd, int runstop, int quiet);
extern int Manage_resize(char *devname, int fd, long long size, int raid_disks);
extern int Manage_subdevs(char *devname, int fd,
struct mddev_dev *devlist, int verbose, int test);
struct mddev_dev *devlist, int verbose, int test,
char *update);
extern int autodetect(void);
extern int Grow_Add_device(char *devname, int fd, char *newdev);
extern int Grow_addbitmap(char *devname, int fd, char *file, int chunk, int delay, int write_behind, int force);