summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNeilBrown <neilb@suse.de>2013-10-31 10:41:50 +1100
committerNeilBrown <neilb@suse.de>2013-10-31 10:41:50 +1100
commitf33a71f107a5ad35345215ee8ebf9920a00099b0 (patch)
treed2625c5e474630c8c283db18263384a89cc22570
parent422da715d933f61c55ca50defc8b7c969af2237f (diff)
Add support for --add-spare
--add-spare is like --add, but a --re-add is never attempted. So it is equivalent to two separate commands: --zero-metadata --add Signed-off-by: NeilBrown <neilb@suse.de>
-rw-r--r--Manage.c7
-rw-r--r--ReadMe.c1
-rw-r--r--mdadm.8.in12
-rw-r--r--mdadm.c4
-rw-r--r--mdadm.h1
5 files changed, 23 insertions, 2 deletions
diff --git a/Manage.c b/Manage.c
index c8276ca1..059cf5b8 100644
--- a/Manage.c
+++ b/Manage.c
@@ -783,7 +783,8 @@ int Manage_add(int fd, int tfd, struct mddev_dev *dv,
break;
}
/* FIXME this is a bad test to be using */
- if (!tst->sb && dv->disposition != 'a') {
+ if (!tst->sb && (dv->disposition != 'a'
+ && dv->disposition != 'S')) {
/* we are re-adding a device to a
* completely dead array - have to depend
* on kernel to check
@@ -813,7 +814,7 @@ int Manage_add(int fd, int tfd, struct mddev_dev *dv,
dev_st = dup_super(tst);
dev_st->ss->load_super(dev_st, tfd, NULL);
}
- if (dev_st && dev_st->sb) {
+ if (dev_st && dev_st->sb && dv->disposition != 'S') {
int rv = attempt_re_add(fd, tfd, dv,
dev_st, tst,
rdev,
@@ -1237,6 +1238,7 @@ int Manage_subdevs(char *devname, int fd,
* 'a' - add the device
* try HOT_ADD_DISK
* If that fails EINVAL, try ADD_NEW_DISK
+ * 'S' - add the device as a spare - don't try re-add
* 'A' - re-add the device
* 'r' - remove the device: HOT_REMOVE_DISK
* device can be 'faulty' or 'detached' in which case all
@@ -1447,6 +1449,7 @@ int Manage_subdevs(char *devname, int fd,
dv->devname, dv->disposition);
goto abort;
case 'a':
+ case 'S': /* --add-spare */
case 'A':
case 'M': /* --re-add missing */
case 'F': /* --re-add faulty */
diff --git a/ReadMe.c b/ReadMe.c
index d742cc70..45046ef7 100644
--- a/ReadMe.c
+++ b/ReadMe.c
@@ -153,6 +153,7 @@ struct option long_options[] = {
/* Management */
{"add", 0, 0, Add},
+ {"add-spare", 0, 0, AddSpare},
{"remove", 0, 0, Remove},
{"fail", 0, 0, Fail},
{"set-faulty",0, 0, Fail},
diff --git a/mdadm.8.in b/mdadm.8.in
index 006ae59f..61cb4f71 100644
--- a/mdadm.8.in
+++ b/mdadm.8.in
@@ -214,7 +214,10 @@ to detect and assemble arrays \(em possibly in an
.P
If a device is given before any options, or if the first option is
+and of
.BR \-\-add ,
+.BR \-\-re\-add ,
+.BR \-\-add\-spare ,
.BR \-\-fail ,
.BR \-\-remove ,
or
@@ -1298,6 +1301,15 @@ useful if you are certain that the reason for failure has been
resolved.
.TP
+.B \-\-add\-spare
+Add a device as a spare. This is similar to
+.B \-\-add
+except that it does not attempt
+.B \-\-re\-add
+first. The device will be added as a spare even if it looks like it
+could be an recent member of the array.
+
+.TP
.BR \-r ", " \-\-remove
remove listed devices. They must not be active. i.e. they should
be failed or spare devices.
diff --git a/mdadm.c b/mdadm.c
index d3cf0fad..359e9f91 100644
--- a/mdadm.c
+++ b/mdadm.c
@@ -187,6 +187,7 @@ int main(int argc, char *argv[])
break;
case 'a':
case Add:
+ case AddSpare:
case 'r':
case Remove:
case Replace:
@@ -915,6 +916,9 @@ int main(int argc, char *argv[])
case O(MANAGE,Add): /* add a drive */
devmode = 'a';
continue;
+ case O(MANAGE,AddSpare): /* add drive - never re-add */
+ devmode = 'S';
+ continue;
case O(MANAGE,ReAdd):
devmode = 'A';
continue;
diff --git a/mdadm.h b/mdadm.h
index cb207c9b..7cfdd8fd 100644
--- a/mdadm.h
+++ b/mdadm.h
@@ -311,6 +311,7 @@ enum special_options {
Brief,
ManageOpt,
Add,
+ AddSpare,
Remove,
Fail,
Replace,