Support failing and removed of detached and faulty devices.
This if you unplug a device and udev removes the entry from /dev, you can still remove the device.
This commit is contained in:
parent
6f9a21a78f
commit
b80da66161
|
@ -1,3 +1,12 @@
|
|||
Changes Prior to this release
|
||||
- --fail detached and --remove faulty can be used to fail and
|
||||
remove devices that are no longer physically present.
|
||||
- --export option for --detail or present information in a format
|
||||
that can be processed by udev.
|
||||
- fix internal bitmap allocation problems with v1.1, v1.2 metadata.
|
||||
- --help now goes to stdout so you can direct it to a pager.
|
||||
- Various manpage updates.
|
||||
|
||||
Changes Prior to 2.6.1 release
|
||||
- --monitor was producing some meaningless warnings due to a bug.
|
||||
- Fix some compiler warnings.
|
||||
|
|
108
Manage.c
108
Manage.c
|
@ -180,13 +180,17 @@ int Manage_subdevs(char *devname, int fd,
|
|||
* try HOT_ADD_DISK
|
||||
* If that fails EINVAL, try ADD_NEW_DISK
|
||||
* 'r' - remove the device HOT_REMOVE_DISK
|
||||
* device can be 'faulty' or 'detached' in which case all
|
||||
* matching devices are removed.
|
||||
* 'f' - set the device faulty SET_DISK_FAULTY
|
||||
* device can be 'detached' in which case any device that
|
||||
* is inaccessible will be marked faulty.
|
||||
*/
|
||||
mdu_array_info_t array;
|
||||
mdu_disk_info_t disc;
|
||||
mddev_dev_t dv;
|
||||
mddev_dev_t dv, next = NULL;
|
||||
struct stat stb;
|
||||
int j;
|
||||
int j, jnext = 0;
|
||||
int tfd;
|
||||
struct supertype *st;
|
||||
void *dsuper = NULL;
|
||||
|
@ -199,18 +203,86 @@ int Manage_subdevs(char *devname, int fd,
|
|||
devname);
|
||||
return 1;
|
||||
}
|
||||
for (dv = devlist ; dv; dv=dv->next) {
|
||||
for (dv = devlist, j=0 ; dv; dv = next, j = jnext) {
|
||||
unsigned long long ldsize;
|
||||
char dvname[20];
|
||||
char *dnprintable = dv->devname;
|
||||
|
||||
if (stat(dv->devname, &stb)) {
|
||||
fprintf(stderr, Name ": cannot find %s: %s\n",
|
||||
dv->devname, strerror(errno));
|
||||
return 1;
|
||||
}
|
||||
if ((stb.st_mode & S_IFMT) != S_IFBLK) {
|
||||
fprintf(stderr, Name ": %s is not a block device.\n",
|
||||
dv->devname);
|
||||
return 1;
|
||||
next = dv->next;
|
||||
jnext = 0;
|
||||
|
||||
if (strcmp(dv->devname, "failed")==0 ||
|
||||
strcmp(dv->devname, "faulty")==0) {
|
||||
if (dv->disposition != 'r') {
|
||||
fprintf(stderr, Name ": %s only meaningful "
|
||||
"with -r, not -%c\n",
|
||||
dv->devname, dv->disposition);
|
||||
return 1;
|
||||
}
|
||||
for (; j < array.raid_disks + array.nr_disks ; j++) {
|
||||
disc.number = j;
|
||||
if (ioctl(fd, GET_DISK_INFO, &disc))
|
||||
continue;
|
||||
if (disc.major == 0 && disc.minor == 0)
|
||||
continue;
|
||||
if ((disc.state & 1) == 0) /* faulty */
|
||||
continue;
|
||||
stb.st_rdev = makedev(disc.major, disc.minor);
|
||||
next = dv;
|
||||
jnext = j+1;
|
||||
sprintf(dvname,"%d:%d", disc.major, disc.minor);
|
||||
dnprintable = dvname;
|
||||
break;
|
||||
}
|
||||
if (jnext == 0)
|
||||
continue;
|
||||
} else if (strcmp(dv->devname, "detached") == 0) {
|
||||
if (dv->disposition != 'r' && dv->disposition != 'f') {
|
||||
fprintf(stderr, Name ": %s only meaningful "
|
||||
"with -r of -f, not -%c\n",
|
||||
dv->devname, dv->disposition);
|
||||
return 1;
|
||||
}
|
||||
for (; j < array.raid_disks + array.nr_disks; j++) {
|
||||
int sfd;
|
||||
disc.number = j;
|
||||
if (ioctl(fd, GET_DISK_INFO, &disc))
|
||||
continue;
|
||||
if (disc.major == 0 && disc.minor == 0)
|
||||
continue;
|
||||
sprintf(dvname,"%d:%d", disc.major, disc.minor);
|
||||
sfd = dev_open(dvname, O_RDONLY);
|
||||
if (sfd >= 0) {
|
||||
close(sfd);
|
||||
continue;
|
||||
}
|
||||
if (dv->disposition == 'f' &&
|
||||
(disc.state & 1) == 1) /* already faulty */
|
||||
continue;
|
||||
if (errno != ENXIO)
|
||||
continue;
|
||||
stb.st_rdev = makedev(disc.major, disc.minor);
|
||||
next = dv;
|
||||
jnext = j+1;
|
||||
dnprintable = dvname;
|
||||
break;
|
||||
}
|
||||
if (jnext == 0)
|
||||
continue;
|
||||
} else {
|
||||
j = 0;
|
||||
|
||||
if (stat(dv->devname, &stb)) {
|
||||
fprintf(stderr, Name ": cannot find %s: %s\n",
|
||||
dv->devname, strerror(errno));
|
||||
return 1;
|
||||
}
|
||||
if ((stb.st_mode & S_IFMT) != S_IFBLK) {
|
||||
fprintf(stderr, Name ": %s is not a "
|
||||
"block device.\n",
|
||||
dv->devname);
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
switch(dv->disposition){
|
||||
default:
|
||||
|
@ -409,24 +481,26 @@ int Manage_subdevs(char *devname, int fd,
|
|||
/* hot remove */
|
||||
/* FIXME check that it is a current member */
|
||||
if (ioctl(fd, HOT_REMOVE_DISK, (unsigned long)stb.st_rdev)) {
|
||||
fprintf(stderr, Name ": hot remove failed for %s: %s\n",
|
||||
dv->devname, strerror(errno));
|
||||
fprintf(stderr, Name ": hot remove failed "
|
||||
"for %s: %s\n", dnprintable,
|
||||
strerror(errno));
|
||||
return 1;
|
||||
}
|
||||
if (verbose >= 0)
|
||||
fprintf(stderr, Name ": hot removed %s\n", dv->devname);
|
||||
fprintf(stderr, Name ": hot removed %s\n",
|
||||
dnprintable);
|
||||
break;
|
||||
|
||||
case 'f': /* set faulty */
|
||||
/* FIXME check current member */
|
||||
if (ioctl(fd, SET_DISK_FAULTY, (unsigned long) stb.st_rdev)) {
|
||||
fprintf(stderr, Name ": set device faulty failed for %s: %s\n",
|
||||
dv->devname, strerror(errno));
|
||||
dnprintable, strerror(errno));
|
||||
return 1;
|
||||
}
|
||||
if (verbose >= 0)
|
||||
fprintf(stderr, Name ": set %s faulty in %s\n",
|
||||
dv->devname, devname);
|
||||
dnprintable, devname);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
|
25
mdadm.8
25
mdadm.8
|
@ -859,11 +859,29 @@ re-add a device that was recently removed from an array.
|
|||
.TP
|
||||
.BR \-r ", " \-\-remove
|
||||
remove listed devices. They must not be active. i.e. they should
|
||||
be failed or spare devices.
|
||||
be failed or spare devices. As well as the name of a device file
|
||||
(e.g.
|
||||
.BR /dev/sda1 )
|
||||
the words
|
||||
.B failed
|
||||
and
|
||||
.B detached
|
||||
can be given to
|
||||
.BR \-\-remove .
|
||||
The first causes all failed device to be removed. The second causes
|
||||
any device which is no longer connected to the system (i.e and open
|
||||
returns
|
||||
.BR ENXIO )
|
||||
to be removed. This will only succeed for devices that are spares or
|
||||
have already been marked as failed.
|
||||
|
||||
.TP
|
||||
.BR \-f ", " \-\-fail
|
||||
mark listed devices as faulty.
|
||||
As well as the name of a device file, the word
|
||||
.B detached
|
||||
can be given. This will cause any device that has been detached from
|
||||
the system to be marked as failed. It can then be removed.
|
||||
|
||||
.TP
|
||||
.BR \-\-set\-faulty
|
||||
|
@ -1977,6 +1995,11 @@ appropriate.
|
|||
Rebuild the array map from any current arrays, and then start any that
|
||||
can be started.
|
||||
|
||||
.B " mdadm /dev/md4 --fail detached --remove detached"
|
||||
.br
|
||||
Any devices which are components of /dev/md4 will be marked as faulty
|
||||
and then remove from the array.
|
||||
|
||||
.B " mdadm \-\-create \-\-help"
|
||||
.br
|
||||
Provide help about the Create mode.
|
||||
|
|
Loading…
Reference in New Issue