close(dfd);
*dfdp = -1;
rv = Manage_subdevs(chosen->sys_name, mdfd, &devlist,
- -1, 0);
+ -1, 0, NULL);
close(mdfd);
}
if (verbose > 0) {
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;
}
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
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) {
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
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);
.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.
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
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;
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);
}
" '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 */
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)
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);