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
|
Changes Prior to 2.6.1 release
|
||||||
- --monitor was producing some meaningless warnings due to a bug.
|
- --monitor was producing some meaningless warnings due to a bug.
|
||||||
- Fix some compiler warnings.
|
- 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
|
* try HOT_ADD_DISK
|
||||||
* If that fails EINVAL, try ADD_NEW_DISK
|
* If that fails EINVAL, try ADD_NEW_DISK
|
||||||
* 'r' - remove the device HOT_REMOVE_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
|
* '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_array_info_t array;
|
||||||
mdu_disk_info_t disc;
|
mdu_disk_info_t disc;
|
||||||
mddev_dev_t dv;
|
mddev_dev_t dv, next = NULL;
|
||||||
struct stat stb;
|
struct stat stb;
|
||||||
int j;
|
int j, jnext = 0;
|
||||||
int tfd;
|
int tfd;
|
||||||
struct supertype *st;
|
struct supertype *st;
|
||||||
void *dsuper = NULL;
|
void *dsuper = NULL;
|
||||||
|
@ -199,18 +203,86 @@ int Manage_subdevs(char *devname, int fd,
|
||||||
devname);
|
devname);
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
for (dv = devlist ; dv; dv=dv->next) {
|
for (dv = devlist, j=0 ; dv; dv = next, j = jnext) {
|
||||||
unsigned long long ldsize;
|
unsigned long long ldsize;
|
||||||
|
char dvname[20];
|
||||||
|
char *dnprintable = dv->devname;
|
||||||
|
|
||||||
if (stat(dv->devname, &stb)) {
|
next = dv->next;
|
||||||
fprintf(stderr, Name ": cannot find %s: %s\n",
|
jnext = 0;
|
||||||
dv->devname, strerror(errno));
|
|
||||||
return 1;
|
if (strcmp(dv->devname, "failed")==0 ||
|
||||||
}
|
strcmp(dv->devname, "faulty")==0) {
|
||||||
if ((stb.st_mode & S_IFMT) != S_IFBLK) {
|
if (dv->disposition != 'r') {
|
||||||
fprintf(stderr, Name ": %s is not a block device.\n",
|
fprintf(stderr, Name ": %s only meaningful "
|
||||||
dv->devname);
|
"with -r, not -%c\n",
|
||||||
return 1;
|
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){
|
switch(dv->disposition){
|
||||||
default:
|
default:
|
||||||
|
@ -409,24 +481,26 @@ int Manage_subdevs(char *devname, int fd,
|
||||||
/* hot remove */
|
/* hot remove */
|
||||||
/* FIXME check that it is a current member */
|
/* FIXME check that it is a current member */
|
||||||
if (ioctl(fd, HOT_REMOVE_DISK, (unsigned long)stb.st_rdev)) {
|
if (ioctl(fd, HOT_REMOVE_DISK, (unsigned long)stb.st_rdev)) {
|
||||||
fprintf(stderr, Name ": hot remove failed for %s: %s\n",
|
fprintf(stderr, Name ": hot remove failed "
|
||||||
dv->devname, strerror(errno));
|
"for %s: %s\n", dnprintable,
|
||||||
|
strerror(errno));
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
if (verbose >= 0)
|
if (verbose >= 0)
|
||||||
fprintf(stderr, Name ": hot removed %s\n", dv->devname);
|
fprintf(stderr, Name ": hot removed %s\n",
|
||||||
|
dnprintable);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 'f': /* set faulty */
|
case 'f': /* set faulty */
|
||||||
/* FIXME check current member */
|
/* FIXME check current member */
|
||||||
if (ioctl(fd, SET_DISK_FAULTY, (unsigned long) stb.st_rdev)) {
|
if (ioctl(fd, SET_DISK_FAULTY, (unsigned long) stb.st_rdev)) {
|
||||||
fprintf(stderr, Name ": set device faulty failed for %s: %s\n",
|
fprintf(stderr, Name ": set device faulty failed for %s: %s\n",
|
||||||
dv->devname, strerror(errno));
|
dnprintable, strerror(errno));
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
if (verbose >= 0)
|
if (verbose >= 0)
|
||||||
fprintf(stderr, Name ": set %s faulty in %s\n",
|
fprintf(stderr, Name ": set %s faulty in %s\n",
|
||||||
dv->devname, devname);
|
dnprintable, devname);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
25
mdadm.8
25
mdadm.8
|
@ -859,11 +859,29 @@ re-add a device that was recently removed from an array.
|
||||||
.TP
|
.TP
|
||||||
.BR \-r ", " \-\-remove
|
.BR \-r ", " \-\-remove
|
||||||
remove listed devices. They must not be active. i.e. they should
|
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
|
.TP
|
||||||
.BR \-f ", " \-\-fail
|
.BR \-f ", " \-\-fail
|
||||||
mark listed devices as faulty.
|
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
|
.TP
|
||||||
.BR \-\-set\-faulty
|
.BR \-\-set\-faulty
|
||||||
|
@ -1977,6 +1995,11 @@ appropriate.
|
||||||
Rebuild the array map from any current arrays, and then start any that
|
Rebuild the array map from any current arrays, and then start any that
|
||||||
can be started.
|
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"
|
.B " mdadm \-\-create \-\-help"
|
||||||
.br
|
.br
|
||||||
Provide help about the Create mode.
|
Provide help about the Create mode.
|
||||||
|
|
Loading…
Reference in New Issue