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:
parent
691a36b76f
commit
833bb0f8f6
|
@ -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;
|
||||
|
|
21
Manage.c
21
Manage.c
|
@ -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) {
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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
40
mdadm.c
|
@ -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)
|
||||
|
|
3
mdadm.h
3
mdadm.h
|
@ -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);
|
||||
|
|
Loading…
Reference in New Issue