]> git.ipfire.org Git - thirdparty/mdadm.git/blame - Manage.c
Manage: implement manage_add_external()
[thirdparty/mdadm.git] / Manage.c
CommitLineData
64c4757e 1/*
9a9dab36 2 * mdadm - manage Linux "md" devices aka RAID arrays.
64c4757e 3 *
6f02172d 4 * Copyright (C) 2001-2013 Neil Brown <neilb@suse.de>
64c4757e
NB
5 *
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; either version 2 of the License, or
10 * (at your option) any later version.
11 *
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License
18 * along with this program; if not, write to the Free Software
19 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
20 *
21 * Author: Neil Brown
e736b623 22 * Email: <neilb@suse.de>
64c4757e
NB
23 */
24
9a9dab36 25#include "mdadm.h"
682c7051
NB
26#include "md_u.h"
27#include "md_p.h"
9935cf0f 28#include "udev.h"
4ccad7b1 29#include <ctype.h>
64c4757e
NB
30
31int Manage_ro(char *devname, int fd, int readonly)
32{
682c7051
NB
33 /* switch to readonly or rw
34 *
35 * requires >= 0.90.0
36 * first check that array is runing
37 * use RESTART_ARRAY_RW or STOP_ARRAY_RO
38 *
39 */
e9dd1598 40 struct mdinfo *mdi;
b73e45ae 41 int rv = 0;
aba69144 42
7bd04da9 43 /* If this is an externally-managed array, we need to modify the
e9dd1598
N
44 * metadata_version so that mdmon doesn't undo our change.
45 */
4dd2df09 46 mdi = sysfs_read(fd, NULL, GET_LEVEL|GET_VERSION);
e9dd1598
N
47 if (mdi &&
48 mdi->array.major_version == -1 &&
e9dd1598
N
49 is_subarray(mdi->text_version)) {
50 char vers[64];
51 strcpy(vers, "external:");
52 strcat(vers, mdi->text_version);
53 if (readonly > 0) {
54 int rv;
55 /* We set readonly ourselves. */
56 vers[9] = '-';
57 sysfs_set_str(mdi, NULL, "metadata_version", vers);
58
59 close(fd);
60 rv = sysfs_set_str(mdi, NULL, "array_state", "readonly");
61
62 if (rv < 0) {
e7b84f9d 63 pr_err("failed to set readonly for %s: %s\n",
e9dd1598
N
64 devname, strerror(errno));
65
66 vers[9] = mdi->text_version[0];
67 sysfs_set_str(mdi, NULL, "metadata_version", vers);
b73e45ae
JS
68 rv = 1;
69 goto out;
e9dd1598
N
70 }
71 } else {
72 char *cp;
73 /* We cannot set read/write - must signal mdmon */
74 vers[9] = '/';
75 sysfs_set_str(mdi, NULL, "metadata_version", vers);
76
77 cp = strchr(vers+10, '/');
1471b8b1 78 if (cp)
e9dd1598
N
79 *cp = 0;
80 ping_monitor(vers+10);
9ea5a252
DW
81 if (mdi->array.level <= 0)
82 sysfs_set_str(mdi, NULL, "array_state", "active");
e9dd1598 83 }
b73e45ae 84 goto out;
e9dd1598 85 }
32141c17 86
80223cb4
JS
87 if (!md_array_active(fd)) {
88 pr_err("%s does not appear to be active.\n", devname);
b73e45ae
JS
89 rv = 1;
90 goto out;
682c7051 91 }
aba69144 92
7bd04da9 93 if (readonly > 0) {
682c7051 94 if (ioctl(fd, STOP_ARRAY_RO, NULL)) {
e7b84f9d 95 pr_err("failed to set readonly for %s: %s\n",
682c7051 96 devname, strerror(errno));
b73e45ae
JS
97 rv = 1;
98 goto out;
682c7051
NB
99 }
100 } else if (readonly < 0) {
101 if (ioctl(fd, RESTART_ARRAY_RW, NULL)) {
e7b84f9d 102 pr_err("failed to set writable for %s: %s\n",
682c7051 103 devname, strerror(errno));
b73e45ae
JS
104 rv = 1;
105 goto out;
682c7051
NB
106 }
107 }
b73e45ae 108out:
6e8d27e7 109 sysfs_free(mdi);
b73e45ae 110 return rv;
64c4757e
NB
111}
112
4dd2df09 113static void remove_devices(char *devnm, char *path)
4ccad7b1 114{
7bd04da9 115 /*
b1702f48
N
116 * Remove names at 'path' - possibly with
117 * partition suffixes - which link to the 'standard'
4dd2df09 118 * name for devnm. These were probably created
b1702f48 119 * by mdadm when the array was assembled.
4ccad7b1
N
120 */
121 char base[40];
122 char *path2;
123 char link[1024];
124 int n;
125 int part;
126 char *be;
127 char *pe;
128
b1702f48
N
129 if (!path)
130 return;
131
4dd2df09 132 sprintf(base, "/dev/%s", devnm);
4ccad7b1 133 be = base + strlen(base);
b1702f48 134
503975b9 135 path2 = xmalloc(strlen(path)+20);
b1702f48
N
136 strcpy(path2, path);
137 pe = path2 + strlen(path2);
7bd04da9 138
4ccad7b1
N
139 for (part = 0; part < 16; part++) {
140 if (part) {
141 sprintf(be, "p%d", part);
b1702f48
N
142
143 if (isdigit(pe[-1]))
144 sprintf(pe, "p%d", part);
145 else
146 sprintf(pe, "%d", part);
4ccad7b1 147 }
b1702f48 148 n = readlink(path2, link, sizeof(link));
d9ca03e9 149 if (n > 0 && (int)strlen(base) == n &&
b1702f48
N
150 strncmp(link, base, n) == 0)
151 unlink(path2);
4ccad7b1 152 }
0eb26465 153 free(path2);
4ccad7b1 154}
4ccad7b1 155
d5a40416 156int Manage_run(char *devname, int fd, struct context *c)
64c4757e 157{
fe7e0e64
N
158 /* Run the array. Array must already be configured
159 * Requires >= 0.90.0
682c7051 160 */
d3786cdc 161 char nm[32], *nmp;
82b27616 162
d3786cdc
N
163 nmp = fd2devnm(fd);
164 if (!nmp) {
165 pr_err("Cannot find %s in sysfs!!\n", devname);
fe7e0e64
N
166 return 1;
167 }
d3786cdc 168 strcpy(nm, nmp);
d5a40416 169 return IncrementalScan(c, nm);
fe7e0e64
N
170}
171
172int Manage_stop(char *devname, int fd, int verbose, int will_retry)
173{
174 /* Stop the array. Array must already be configured
175 * 'will_retry' means that error messages are not wanted.
176 */
177 int rv = 0;
178 struct map_ent *map = NULL;
179 struct mdinfo *mdi;
180 char devnm[32];
181 char container[32];
182 int err;
183 int count;
90fd7001 184 char buf[SYSFS_MAX_BUF_SIZE];
2eba8496 185 unsigned long long rd1, rd2;
fe7e0e64 186
ba728be7
N
187 if (will_retry && verbose == 0)
188 verbose = -1;
189
fe7e0e64
N
190 strcpy(devnm, fd2devnm(fd));
191 /* Get EXCL access first. If this fails, then attempting
192 * to stop is probably a bad idea.
193 */
2eba8496 194 mdi = sysfs_read(fd, NULL, GET_LEVEL|GET_COMPONENT|GET_VERSION);
fe7e0e64
N
195 if (mdi && is_subarray(mdi->text_version)) {
196 char *sl;
197 strncpy(container, mdi->text_version+1, sizeof(container));
198 container[sizeof(container)-1] = 0;
199 sl = strchr(container, '/');
200 if (sl)
201 *sl = 0;
202 } else
203 container[0] = 0;
204 close(fd);
205 count = 5;
52b6ccad 206 while (((fd = ((devname[0] == '/')
fe7e0e64 207 ?open(devname, O_RDONLY|O_EXCL)
fc54fe7a
JS
208 :open_dev_flags(devnm, O_RDONLY|O_EXCL))) < 0 ||
209 strcmp(fd2devnm(fd), devnm) != 0) && container[0] &&
210 mdmon_running(container) && count) {
932be627
N
211 /* Can't open, so something might be wrong. However it
212 * is a container, so we might be racing with mdmon, so
213 * retry for a bit.
214 */
fe7e0e64
N
215 if (fd >= 0)
216 close(fd);
217 flush_mdmon(container);
218 count--;
682c7051 219 }
fe7e0e64
N
220 if (fd < 0 || strcmp(fd2devnm(fd), devnm) != 0) {
221 if (fd >= 0)
222 close(fd);
ba728be7 223 if (verbose >= 0)
7a862a02 224 pr_err("Cannot get exclusive access to %s:Perhaps a running process, mounted filesystem or active volume group?\n",
fe7e0e64 225 devname);
f6feb3fb 226 sysfs_free(mdi);
fe7e0e64
N
227 return 1;
228 }
932be627
N
229 /* If this is an mdmon managed array, just write 'inactive'
230 * to the array state and let mdmon clear up.
231 */
fe7e0e64
N
232 if (mdi &&
233 mdi->array.level > 0 &&
234 is_subarray(mdi->text_version)) {
eb0af526 235 int err;
fe7e0e64 236 /* This is mdmon managed. */
eb0af526 237 close(fd);
daf7a3ce 238
932be627 239 /* As we had an O_EXCL open, any use of the device
eb0af526
N
240 * which blocks STOP_ARRAY is probably a transient use,
241 * so it is reasonable to retry for a while - 5 seconds.
242 */
fe7e0e64
N
243 count = 25;
244 while (count &&
245 (err = sysfs_set_str(mdi, NULL,
246 "array_state",
fc54fe7a
JS
247 "inactive")) < 0 &&
248 errno == EBUSY) {
239b3cc0 249 sleep_for(0, MSEC_TO_NSEC(200), true);
fe7e0e64 250 count--;
eb0af526 251 }
fe7e0e64
N
252 if (err) {
253 if (verbose >= 0)
e7b84f9d
N
254 pr_err("failed to stop array %s: %s\n",
255 devname, strerror(errno));
bccd8153
JS
256 rv = 1;
257 goto out;
682c7051 258 }
fe7e0e64
N
259
260 /* Give monitor a chance to act */
261 ping_monitor(mdi->text_version);
262
263 fd = open_dev_excl(devnm);
264 if (fd < 0) {
265 if (verbose >= 0)
7a862a02 266 pr_err("failed to completely stop %s: Device is busy\n",
fe7e0e64
N
267 devname);
268 rv = 1;
269 goto out;
270 }
271 } else if (mdi &&
272 mdi->array.major_version == -1 &&
273 mdi->array.minor_version == -2 &&
274 !is_subarray(mdi->text_version)) {
275 struct mdstat_ent *mds, *m;
276 /* container, possibly mdmon-managed.
277 * Make sure mdmon isn't opening it, which
278 * would interfere with the 'stop'
97590376 279 */
fe7e0e64 280 ping_monitor(mdi->sys_name);
daf7a3ce 281
fe7e0e64
N
282 /* now check that there are no existing arrays
283 * which are members of this array
284 */
285 mds = mdstat_read(0, 0);
286 for (m = mds; m; m = m->next)
287 if (m->metadata_version &&
288 strncmp(m->metadata_version, "external:", 9)==0 &&
289 metadata_container_matches(m->metadata_version+9,
290 devnm)) {
291 if (verbose >= 0)
7a862a02 292 pr_err("Cannot stop container %s: member %s still active\n",
9581efb1 293 devname, m->devnm);
fe7e0e64
N
294 free_mdstat(mds);
295 rv = 1;
296 goto out;
297 }
298 }
299
2eba8496
N
300 /* If the array is undergoing a reshape which changes the number
301 * of devices, then it would be nice to stop it at a point where
302 * it has completed a full number of stripes in both old and
303 * new layouts as this will allow the reshape to be reverted.
304 * So if 'sync_action' is "reshape" and 'raid_disks' shows two
305 * different numbers, then
306 * - freeze reshape
307 * - set sync_max to next multiple of both data_disks and
308 * chunk sizes (or next but one)
309 * - unfreeze reshape
310 * - wait on 'sync_completed' for that point to be reached.
311 */
70f1ff42 312 if (mdi && is_level456(mdi->array.level) &&
2eba8496
N
313 sysfs_attribute_available(mdi, NULL, "sync_action") &&
314 sysfs_attribute_available(mdi, NULL, "reshape_direction") &&
90fd7001 315 sysfs_get_str(mdi, NULL, "sync_action", buf, sizeof(buf)) > 0 &&
2eba8496 316 strcmp(buf, "reshape\n") == 0 &&
e3e0d0a8 317 sysfs_get_two(mdi, NULL, "raid_disks", &rd1, &rd2) == 2) {
2eba8496
N
318 unsigned long long position, curr;
319 unsigned long long chunk1, chunk2;
320 unsigned long long rddiv, chunkdiv;
321 unsigned long long sectors;
5509dc44
N
322 unsigned long long sync_max, old_sync_max;
323 unsigned long long completed;
2eba8496
N
324 int backwards = 0;
325 int delay;
326 int scfd;
327
e3e0d0a8
N
328 delay = 40;
329 while (rd1 > rd2 && delay > 0 &&
330 sysfs_get_ll(mdi, NULL, "sync_max", &old_sync_max) == 0) {
331 /* must be in the critical section - wait a bit */
332 delay -= 1;
239b3cc0 333 sleep_for(0, MSEC_TO_NSEC(100), true);
e3e0d0a8
N
334 }
335
336 if (sysfs_set_str(mdi, NULL, "sync_action", "frozen") != 0)
337 goto done;
338 /* Array is frozen */
339
2eba8496
N
340 rd1 -= mdi->array.level == 6 ? 2 : 1;
341 rd2 -= mdi->array.level == 6 ? 2 : 1;
342 sysfs_get_str(mdi, NULL, "reshape_direction", buf, sizeof(buf));
343 if (strncmp(buf, "back", 4) == 0)
344 backwards = 1;
e3e0d0a8
N
345 if (sysfs_get_ll(mdi, NULL, "reshape_position", &position) != 0) {
346 /* reshape must have finished now */
347 sysfs_set_str(mdi, NULL, "sync_action", "idle");
348 goto done;
349 }
2eba8496
N
350 sysfs_get_two(mdi, NULL, "chunk_size", &chunk1, &chunk2);
351 chunk1 /= 512;
352 chunk2 /= 512;
353 rddiv = GCD(rd1, rd2);
354 chunkdiv = GCD(chunk1, chunk2);
355 sectors = (chunk1/chunkdiv) * chunk2 * (rd1/rddiv) * rd2;
356
357 if (backwards) {
358 /* Need to subtract 'reshape_position' from
359 * array size to get equivalent of sync_max.
360 * Size calculation based on raid5_size in kernel.
361 */
362 unsigned long long size = mdi->component_size;
363 size &= ~(chunk1-1);
364 size &= ~(chunk2-1);
365 /* rd1 must be smaller */
932be627
N
366 /* Reshape may have progressed further backwards than
367 * recorded, so target even further back (hence "-1")
368 */
5509dc44 369 position = (position / sectors - 1) * sectors;
932be627
N
370 /* rd1 is always the conversion factor between 'sync'
371 * position and 'reshape' position.
372 * We read 1 "new" stripe worth of data from where-ever,
373 * and when write out that full stripe.
374 */
5509dc44 375 sync_max = size - position/rd1;
2eba8496 376 } else {
932be627
N
377 /* Reshape will very likely be beyond position, and it may
378 * be too late to stop at '+1', so aim for '+2'
379 */
5509dc44
N
380 position = (position / sectors + 2) * sectors;
381 sync_max = position/rd1;
2eba8496 382 }
5509dc44
N
383 if (sysfs_get_ll(mdi, NULL, "sync_max", &old_sync_max) < 0)
384 old_sync_max = mdi->component_size;
385 /* Must not advance sync_max as that could confuse
386 * the reshape monitor */
387 if (sync_max < old_sync_max)
388 sysfs_set_num(mdi, NULL, "sync_max", sync_max);
2eba8496
N
389 sysfs_set_str(mdi, NULL, "sync_action", "idle");
390
391 /* That should have set things going again. Now we
3afaff93 392 * wait a little while (3 second max) for sync_completed
2eba8496 393 * to reach the target.
3afaff93
N
394 * The reshape process can block for 500msec if
395 * the sync speed limit is hit, so we need to wait
396 * a lot longer than that. 1 second is usually
397 * enough. 3 is safe.
2eba8496 398 */
3afaff93 399 delay = 3000;
2eba8496 400 scfd = sysfs_open(mdi->sys_name, NULL, "sync_completed");
3afaff93 401 while (scfd >= 0 && delay > 0 && old_sync_max > 0) {
30ddba7d 402 unsigned long long max_completed;
5509dc44 403 sysfs_get_ll(mdi, NULL, "reshape_position", &curr);
2eba8496 404 sysfs_fd_get_str(scfd, buf, sizeof(buf));
b823c8f9 405 if (str_is_none(buf) == true) {
3afaff93
N
406 /* Either reshape has aborted, or hasn't
407 * quite started yet. Wait a bit and
408 * check 'sync_action' to see.
409 */
239b3cc0 410 sleep_for(0, MSEC_TO_NSEC(10), true);
3afaff93
N
411 sysfs_get_str(mdi, NULL, "sync_action", buf, sizeof(buf));
412 if (strncmp(buf, "reshape", 7) != 0)
413 break;
414 }
5509dc44 415
30ddba7d
N
416 if (sysfs_fd_get_two(scfd, &completed,
417 &max_completed) == 2 &&
418 /* 'completed' sometimes reads as max-uulong */
419 completed < max_completed &&
5509dc44
N
420 (completed > sync_max ||
421 (completed == sync_max && curr != position))) {
422 while (completed > sync_max) {
423 sync_max += sectors / rd1;
424 if (backwards)
425 position -= sectors;
426 else
427 position += sectors;
428 }
429 if (sync_max < old_sync_max)
430 sysfs_set_num(mdi, NULL, "sync_max", sync_max);
431 }
432
2eba8496
N
433 if (!backwards && curr >= position)
434 break;
435 if (backwards && curr <= position)
436 break;
437 sysfs_wait(scfd, &delay);
438 }
439 if (scfd >= 0)
440 close(scfd);
441
442 }
e3e0d0a8 443done:
2eba8496 444
fe7e0e64
N
445 /* As we have an O_EXCL open, any use of the device
446 * which blocks STOP_ARRAY is probably a transient use,
447 * so it is reasonable to retry for a while - 5 seconds.
448 */
449 count = 25; err = 0;
fc54fe7a
JS
450 while (count && fd >= 0 &&
451 (err = ioctl(fd, STOP_ARRAY, NULL)) < 0 && errno == EBUSY) {
239b3cc0 452 sleep_for(0, MSEC_TO_NSEC(200), true);
fe7e0e64
N
453 count --;
454 }
455 if (fd >= 0 && err) {
456 if (verbose >= 0) {
457 pr_err("failed to stop array %s: %s\n",
458 devname, strerror(errno));
459 if (errno == EBUSY)
7a862a02 460 cont_err("Perhaps a running process, mounted filesystem or active volume group?\n");
4ccad7b1 461 }
fe7e0e64
N
462 rv = 1;
463 goto out;
464 }
229e66cb 465
9935cf0f 466 if (devnm[0] && udev_is_available()) {
fe7e0e64
N
467 struct map_ent *mp = map_by_devnm(&map, devnm);
468 remove_devices(devnm, mp ? mp->path : NULL);
682c7051 469 }
fe7e0e64
N
470
471 if (verbose >= 0)
472 pr_err("stopped %s\n", devname);
473 map_lock(&map);
474 map_remove(&map, devnm);
475 map_unlock(&map);
476out:
6e8d27e7 477 sysfs_free(mdi);
fe7e0e64 478
bccd8153 479 return rv;
64c4757e
NB
480}
481
5e73b024
N
482static struct mddev_dev *add_one(struct mddev_dev *dv, char *name, char disp)
483{
484 struct mddev_dev *new;
485 new = xmalloc(sizeof(*new));
486 memset(new, 0, sizeof(*new));
487 new->devname = xstrdup(name);
488 new->disposition = disp;
489 new->next = dv->next;
490 dv->next = new;
491 return new;
492}
493
1d997643
N
494static void add_faulty(struct mddev_dev *dv, int fd, char disp)
495{
496 mdu_array_info_t array;
497 mdu_disk_info_t disk;
498 int remaining_disks;
499 int i;
500
9cd39f01 501 if (md_get_array_info(fd, &array) != 0)
1d997643
N
502 return;
503
504 remaining_disks = array.nr_disks;
505 for (i = 0; i < MAX_DISKS && remaining_disks > 0; i++) {
1d997643
N
506 char buf[40];
507 disk.number = i;
d97572f5 508 if (md_get_disk_info(fd, &disk) != 0)
1d997643
N
509 continue;
510 if (disk.major == 0 && disk.minor == 0)
511 continue;
512 remaining_disks--;
513 if ((disk.state & 1) == 0) /* not faulty */
514 continue;
515 sprintf(buf, "%d:%d", disk.major, disk.minor);
5e73b024 516 dv = add_one(dv, buf, disp);
1d997643
N
517 }
518}
519
520static void add_detached(struct mddev_dev *dv, int fd, char disp)
521{
522 mdu_array_info_t array;
523 mdu_disk_info_t disk;
524 int remaining_disks;
525 int i;
526
9cd39f01 527 if (md_get_array_info(fd, &array) != 0)
1d997643
N
528 return;
529
530 remaining_disks = array.nr_disks;
531 for (i = 0; i < MAX_DISKS && remaining_disks > 0; i++) {
1d997643
N
532 char buf[40];
533 int sfd;
534 disk.number = i;
d97572f5 535 if (md_get_disk_info(fd, &disk) != 0)
1d997643
N
536 continue;
537 if (disk.major == 0 && disk.minor == 0)
538 continue;
539 remaining_disks--;
540 if (disp == 'f' && (disk.state & 1) != 0) /* already faulty */
541 continue;
542 sprintf(buf, "%d:%d", disk.major, disk.minor);
543 sfd = dev_open(buf, O_RDONLY);
544 if (sfd >= 0) {
545 /* Not detached */
546 close(sfd);
547 continue;
548 }
549 if (errno != ENXIO)
550 /* Probably not detached */
551 continue;
5e73b024 552 dv = add_one(dv, buf, disp);
1d997643
N
553 }
554}
555
64a78416
N
556static void add_set(struct mddev_dev *dv, int fd, char set_char)
557{
558 mdu_array_info_t array;
559 mdu_disk_info_t disk;
560 int remaining_disks;
561 int copies, set;
562 int i;
563
9cd39f01 564 if (md_get_array_info(fd, &array) != 0)
64a78416
N
565 return;
566 if (array.level != 10)
567 return;
568 copies = ((array.layout & 0xff) *
569 ((array.layout >> 8) & 0xff));
570 if (array.raid_disks % copies)
571 return;
572
573 remaining_disks = array.nr_disks;
574 for (i = 0; i < MAX_DISKS && remaining_disks > 0; i++) {
575 char buf[40];
576 disk.number = i;
d97572f5 577 if (md_get_disk_info(fd, &disk) != 0)
64a78416
N
578 continue;
579 if (disk.major == 0 && disk.minor == 0)
580 continue;
581 remaining_disks--;
582 set = disk.raid_disk % copies;
583 if (set_char != set + 'A')
584 continue;
585 sprintf(buf, "%d:%d", disk.major, disk.minor);
586 dv = add_one(dv, buf, dv->disposition);
587 }
588}
589
abe94694
N
590int attempt_re_add(int fd, int tfd, struct mddev_dev *dv,
591 struct supertype *dev_st, struct supertype *tst,
f2e8393b
MK
592 unsigned long rdev, enum update_opt update,
593 char *devname, int verbose, mdu_array_info_t *array)
abe94694
N
594{
595 struct mdinfo mdi;
596 int duuid[4];
597 int ouuid[4];
598
599 dev_st->ss->getinfo_super(dev_st, &mdi, NULL);
600 dev_st->ss->uuid_from_super(dev_st, ouuid);
601 if (tst->sb)
602 tst->ss->uuid_from_super(tst, duuid);
603 else
604 /* Assume uuid matches: kernel will check */
605 memcpy(duuid, ouuid, sizeof(ouuid));
606 if ((mdi.disk.state & (1<<MD_DISK_ACTIVE)) &&
607 !(mdi.disk.state & (1<<MD_DISK_FAULTY)) &&
608 memcmp(duuid, ouuid, sizeof(ouuid))==0) {
609 /* Looks like it is worth a
610 * try. Need to make sure
611 * kernel will accept it
612 * though.
613 */
614 mdu_disk_info_t disc;
abe94694 615 disc.number = mdi.disk.number;
d97572f5
JS
616 if (md_get_disk_info(fd, &disc) != 0 ||
617 disc.major != 0 || disc.minor != 0)
abe94694
N
618 goto skip_re_add;
619 disc.major = major(rdev);
620 disc.minor = minor(rdev);
621 disc.number = mdi.disk.number;
622 disc.raid_disk = mdi.disk.raid_disk;
623 disc.state = mdi.disk.state;
bff96f73
GJ
624 if (array->state & (1 << MD_SB_CLUSTERED)) {
625 /* extra flags are needed when adding to a cluster as
626 * there are two cases to distinguish
627 */
628 if (dv->disposition == 'c')
629 disc.state |= (1 << MD_DISK_CANDIDATE);
630 else
631 disc.state |= (1 << MD_DISK_CLUSTER_ADD);
632 }
e22fe3ae 633 if (dv->writemostly == FlagSet)
abe94694 634 disc.state |= 1 << MD_DISK_WRITEMOSTLY;
e22fe3ae 635 if (dv->writemostly == FlagClear)
abe94694 636 disc.state &= ~(1 << MD_DISK_WRITEMOSTLY);
e22fe3ae 637 if (dv->failfast == FlagSet)
71574efb 638 disc.state |= 1 << MD_DISK_FAILFAST;
e22fe3ae 639 if (dv->failfast == FlagClear)
71574efb 640 disc.state &= ~(1 << MD_DISK_FAILFAST);
abe94694 641 remove_partitions(tfd);
d7be7d87
JS
642 if (update || dv->writemostly != FlagDefault ||
643 dv->failfast != FlagDefault) {
abe94694
N
644 int rv = -1;
645 tfd = dev_open(dv->devname, O_RDWR);
646 if (tfd < 0) {
7a862a02 647 pr_err("failed to open %s for superblock update during re-add\n", dv->devname);
abe94694
N
648 return -1;
649 }
650
e22fe3ae 651 if (dv->writemostly == FlagSet)
abe94694 652 rv = dev_st->ss->update_super(
03312b52 653 dev_st, NULL, UOPT_SPEC_WRITEMOSTLY,
abe94694 654 devname, verbose, 0, NULL);
e22fe3ae 655 if (dv->writemostly == FlagClear)
abe94694 656 rv = dev_st->ss->update_super(
03312b52 657 dev_st, NULL, UOPT_SPEC_READWRITE,
abe94694 658 devname, verbose, 0, NULL);
e22fe3ae 659 if (dv->failfast == FlagSet)
71574efb 660 rv = dev_st->ss->update_super(
03312b52 661 dev_st, NULL, UOPT_SPEC_FAILFAST,
71574efb 662 devname, verbose, 0, NULL);
e22fe3ae 663 if (dv->failfast == FlagClear)
71574efb 664 rv = dev_st->ss->update_super(
03312b52 665 dev_st, NULL, UOPT_SPEC_NOFAILFAST,
71574efb 666 devname, verbose, 0, NULL);
abe94694
N
667 if (update)
668 rv = dev_st->ss->update_super(
f2e8393b 669 dev_st, NULL, update,
abe94694
N
670 devname, verbose, 0, NULL);
671 if (rv == 0)
672 rv = dev_st->ss->store_super(dev_st, tfd);
673 close(tfd);
674 if (rv != 0) {
7a862a02 675 pr_err("failed to update superblock during re-add\n");
abe94694
N
676 return -1;
677 }
678 }
679 /* don't even try if disk is marked as faulty */
680 errno = 0;
681 if (ioctl(fd, ADD_NEW_DISK, &disc) == 0) {
682 if (verbose >= 0)
683 pr_err("re-added %s\n", dv->devname);
684 return 1;
685 }
686 if (errno == ENOMEM || errno == EROFS) {
687 pr_err("add new device failed for %s: %s\n",
688 dv->devname, strerror(errno));
689 if (dv->disposition == 'M')
690 return 0;
691 return -1;
692 }
693 }
694skip_re_add:
695 return 0;
696}
697
29273f60
MT
698/**
699 * manage_add_external() - Add disk to external container.
700 * @st: external supertype pointer, must not be NULL, superblock is released here.
701 * @fd: container file descriptor, must not have O_EXCL mode.
702 * @disk_fd: device to add file descriptor.
703 * @disk_name: name of the device to add.
704 * @disc: disk info.
705 *
706 * Superblock is released here because any open fd with O_EXCL will block sysfs_add_disk().
707 */
708mdadm_status_t manage_add_external(struct supertype *st, int fd, char *disk_name,
709 mdu_disk_info_t *disc)
710{
711 mdadm_status_t rv = MDADM_STATUS_ERROR;
712 char container_devpath[MD_NAME_MAX];
713 struct mdinfo new_mdi;
714 struct mdinfo *sra = NULL;
715 int container_fd;
716 int disk_fd = -1;
717
718 snprintf(container_devpath, MD_NAME_MAX, "%s", fd2devnm(fd));
719
720 container_fd = open_dev_excl(container_devpath);
721 if (!is_fd_valid(container_fd)) {
722 pr_err("Failed to get exclusive access to container %s\n", container_devpath);
723 return MDADM_STATUS_ERROR;
724 }
725
726 /* Check if metadata handler is able to accept the drive */
727 if (!st->ss->validate_geometry(st, LEVEL_CONTAINER, 0, 1, NULL, 0, 0, disk_name, NULL,
728 0, 1))
729 goto out;
730
731 Kill(disk_name, NULL, 0, -1, 0);
732
733 disk_fd = dev_open(disk_name, O_RDWR | O_EXCL | O_DIRECT);
734 if (!is_fd_valid(disk_fd)) {
735 pr_err("Failed to exclusively open %s\n", disk_name);
736 goto out;
737 }
738
739 if (st->ss->add_to_super(st, disc, disk_fd, disk_name, INVALID_SECTORS))
740 goto out;
741
742 if (!mdmon_running(st->container_devnm))
743 st->ss->sync_metadata(st);
744
745 sra = sysfs_read(container_fd, NULL, 0);
746 if (!sra) {
747 pr_err("Failed to read sysfs for %s\n", disk_name);
748 goto out;
749 }
750
751 sra->array.level = LEVEL_CONTAINER;
752 /* Need to set data_offset and component_size */
753 st->ss->getinfo_super(st, &new_mdi, NULL);
754 new_mdi.disk.major = disc->major;
755 new_mdi.disk.minor = disc->minor;
756 new_mdi.recovery_start = 0;
757
758 st->ss->free_super(st);
759
760 if (sysfs_add_disk(sra, &new_mdi, 0) != 0) {
761 pr_err("Failed to add %s to container %s\n", disk_name, container_devpath);
762 goto out;
763 }
764 ping_monitor(container_devpath);
765 rv = MDADM_STATUS_SUCCESS;
766
767out:
768 close(container_fd);
769
770 if (sra)
771 sysfs_free(sra);
772
773 if (rv != MDADM_STATUS_SUCCESS && is_fd_valid(disk_fd))
774 /* Metadata handler records this descriptor, so release it only on failure. */
775 close(disk_fd);
776
777 if (st->sb)
778 st->ss->free_super(st);
779
780 return rv;
781}
782
38aeaf3a
N
783int Manage_add(int fd, int tfd, struct mddev_dev *dv,
784 struct supertype *tst, mdu_array_info_t *array,
785 int force, int verbose, char *devname,
f2e8393b
MK
786 enum update_opt update, unsigned long rdev,
787 unsigned long long array_size, int raid_slot)
38aeaf3a
N
788{
789 unsigned long long ldsize;
fbd3e15c 790 struct supertype *dev_st;
38aeaf3a
N
791 int j;
792 mdu_disk_info_t disc;
ed2c2cb3 793 struct map_ent *map = NULL;
38aeaf3a
N
794
795 if (!get_dev_size(tfd, dv->devname, &ldsize)) {
796 if (dv->disposition == 'M')
797 return 0;
798 else
799 return -1;
800 }
801
632dc30c 802 if (tst->ss == &super0 && ldsize > 4ULL*1024*1024*1024*1024) {
7ccc4cc4 803 /* More than 4TB is wasted on v0.90 */
38aeaf3a 804 if (!force) {
7a862a02
N
805 pr_err("%s is larger than %s can effectively use.\n"
806 " Add --force is you really want to add this device.\n",
38aeaf3a
N
807 dv->devname, devname);
808 return -1;
809 }
7a862a02
N
810 pr_err("%s is larger than %s can effectively use.\n"
811 " Adding anyway as --force was given.\n",
38aeaf3a
N
812 dv->devname, devname);
813 }
38aeaf3a
N
814
815 if (array->not_persistent == 0 || tst->ss->external) {
816
817 /* need to find a sample superblock to copy, and
818 * a spare slot to use.
819 * For 'external' array (well, container based),
820 * We can just load the metadata for the array->
821 */
822 int array_failed;
823 if (tst->sb)
824 /* already loaded */;
825 else if (tst->ss->external) {
826 tst->ss->load_container(tst, fd, NULL);
827 } else for (j = 0; j < tst->max_devs; j++) {
828 char *dev;
829 int dfd;
830 disc.number = j;
d97572f5 831 if (md_get_disk_info(fd, &disc))
38aeaf3a
N
832 continue;
833 if (disc.major==0 && disc.minor==0)
834 continue;
835 if ((disc.state & 4)==0) /* sync */
836 continue;
837 /* Looks like a good device to try */
838 dev = map_dev(disc.major, disc.minor, 1);
839 if (!dev)
840 continue;
841 dfd = dev_open(dev, O_RDONLY);
842 if (dfd < 0)
843 continue;
844 if (tst->ss->load_super(tst, dfd,
845 NULL)) {
846 close(dfd);
847 continue;
848 }
849 close(dfd);
850 break;
851 }
852 /* FIXME this is a bad test to be using */
fc54fe7a
JS
853 if (!tst->sb && (dv->disposition != 'a' &&
854 dv->disposition != 'S')) {
38aeaf3a
N
855 /* we are re-adding a device to a
856 * completely dead array - have to depend
857 * on kernel to check
858 */
859 } else if (!tst->sb) {
860 pr_err("cannot load array metadata from %s\n", devname);
861 return -1;
862 }
863
864 /* Make sure device is large enough */
01290056
SL
865 if (dv->disposition != 'j' && /* skip size check for Journal */
866 tst->sb &&
2609f339 867 tst->ss->avail_size(tst, ldsize/512, INVALID_SECTORS) <
38aeaf3a
N
868 array_size) {
869 if (dv->disposition == 'M')
870 return 0;
871 pr_err("%s not large enough to join array\n",
872 dv->devname);
873 return -1;
874 }
875
876 /* Possibly this device was recently part of
877 * the array and was temporarily removed, and
878 * is now being re-added. If so, we can
879 * simply re-add it.
880 */
881
e97ca358
MT
882 if (array->not_persistent == 0 && dv->disposition != 'S') {
883 int rv = 0;
884
38aeaf3a
N
885 dev_st = dup_super(tst);
886 dev_st->ss->load_super(dev_st, tfd, NULL);
fbd3e15c 887
e97ca358
MT
888 if (dev_st->sb) {
889 rv = attempt_re_add(fd, tfd, dv, dev_st, tst, rdev, update,
890 devname, verbose, array);
891
f6feb3fb 892 dev_st->ss->free_super(dev_st);
fbd3e15c 893 }
e97ca358
MT
894
895 free(dev_st);
896
897 if (rv)
898 return rv;
38aeaf3a
N
899 }
900 if (dv->disposition == 'M') {
901 if (verbose > 0)
902 pr_err("--re-add for %s to %s is not possible\n",
903 dv->devname, devname);
904 return 0;
905 }
906 if (dv->disposition == 'A') {
907 pr_err("--re-add for %s to %s is not possible\n",
908 dv->devname, devname);
909 return -1;
910 }
911 if (array->active_disks < array->raid_disks) {
912 char *avail = xcalloc(array->raid_disks, 1);
913 int d;
914 int found = 0;
915
d180d2aa 916 for (d = 0; d < MAX_DISKS && found < array->nr_disks; d++) {
38aeaf3a 917 disc.number = d;
d97572f5 918 if (md_get_disk_info(fd, &disc))
38aeaf3a
N
919 continue;
920 if (disc.major == 0 && disc.minor == 0)
921 continue;
922 if (!(disc.state & (1<<MD_DISK_SYNC)))
923 continue;
924 avail[disc.raid_disk] = 1;
d31d0f52 925 found++;
38aeaf3a
N
926 }
927 array_failed = !enough(array->level, array->raid_disks,
928 array->layout, 1, avail);
6157951f 929 free(avail);
38aeaf3a
N
930 } else
931 array_failed = 0;
932 if (array_failed) {
933 pr_err("%s has failed so using --add cannot work and might destroy\n",
934 devname);
935 pr_err("data on %s. You should stop the array and re-assemble it.\n",
936 dv->devname);
937 return -1;
938 }
939 } else {
940 /* non-persistent. Must ensure that new drive
941 * is at least array->size big.
942 */
943 if (ldsize/512 < array_size) {
944 pr_err("%s not large enough to join array\n",
945 dv->devname);
946 return -1;
947 }
948 }
949 /* committed to really trying this device now*/
950 remove_partitions(tfd);
951
952 /* in 2.6.17 and earlier, version-1 superblocks won't
953 * use the number we write, but will choose a free number.
954 * we must choose the same free number, which requires
955 * starting at 'raid_disks' and counting up
956 */
957 for (j = array->raid_disks; j < tst->max_devs; j++) {
958 disc.number = j;
d97572f5 959 if (md_get_disk_info(fd, &disc))
38aeaf3a
N
960 break;
961 if (disc.major==0 && disc.minor==0)
962 break;
963 if (disc.state & 8) /* removed */
964 break;
965 }
966 disc.major = major(rdev);
967 disc.minor = minor(rdev);
4de90913
GJ
968 if (raid_slot < 0)
969 disc.number = j;
970 else
971 disc.number = raid_slot;
38aeaf3a 972 disc.state = 0;
01290056
SL
973
974 /* only add journal to array that supports journaling */
975 if (dv->disposition == 'j') {
01290056
SL
976 struct mdinfo *mdp;
977
978 mdp = sysfs_read(fd, NULL, GET_ARRAY_STATE);
2a1990c0
JS
979 if (!mdp) {
980 pr_err("%s unable to read array state.\n", devname);
981 return -1;
982 }
01290056 983
5e4ca8bb 984 if (mdp->array_state != ARRAY_READONLY) {
d209181d 985 sysfs_free(mdp);
01290056
SL
986 pr_err("%s is not readonly, cannot add journal.\n", devname);
987 return -1;
988 }
989
d209181d
JS
990 sysfs_free(mdp);
991
38c2e05b 992 disc.raid_disk = 0;
01290056
SL
993 }
994
ed2c2cb3
LXK
995 if (map_lock(&map))
996 pr_err("failed to get exclusive lock on mapfile when add disk\n");
997
38aeaf3a
N
998 if (array->not_persistent==0) {
999 int dfd;
01290056
SL
1000 if (dv->disposition == 'j')
1001 disc.state |= (1 << MD_DISK_JOURNAL) | (1 << MD_DISK_SYNC);
e22fe3ae 1002 if (dv->writemostly == FlagSet)
38aeaf3a 1003 disc.state |= 1 << MD_DISK_WRITEMOSTLY;
e22fe3ae 1004 if (dv->failfast == FlagSet)
71574efb 1005 disc.state |= 1 << MD_DISK_FAILFAST;
38aeaf3a
N
1006 dfd = dev_open(dv->devname, O_RDWR | O_EXCL|O_DIRECT);
1007 if (tst->ss->add_to_super(tst, &disc, dfd,
72ca9bcf 1008 dv->devname, INVALID_SECTORS))
ed2c2cb3 1009 goto unlock;
38aeaf3a 1010 if (tst->ss->write_init_super(tst))
ed2c2cb3 1011 goto unlock;
38aeaf3a
N
1012 } else if (dv->disposition == 'A') {
1013 /* this had better be raid1.
1014 * As we are "--re-add"ing we must find a spare slot
1015 * to fill.
1016 */
1017 char *used = xcalloc(array->raid_disks, 1);
1018 for (j = 0; j < tst->max_devs; j++) {
1019 mdu_disk_info_t disc2;
1020 disc2.number = j;
d97572f5 1021 if (md_get_disk_info(fd, &disc2))
38aeaf3a
N
1022 continue;
1023 if (disc2.major==0 && disc2.minor==0)
1024 continue;
1025 if (disc2.state & 8) /* removed */
1026 continue;
1027 if (disc2.raid_disk < 0)
1028 continue;
1029 if (disc2.raid_disk > array->raid_disks)
1030 continue;
1031 used[disc2.raid_disk] = 1;
1032 }
1033 for (j = 0 ; j < array->raid_disks; j++)
1034 if (!used[j]) {
1035 disc.raid_disk = j;
1036 disc.state |= (1<<MD_DISK_SYNC);
1037 break;
1038 }
1039 free(used);
1040 }
4de90913
GJ
1041
1042 if (array->state & (1 << MD_SB_CLUSTERED)) {
1043 if (dv->disposition == 'c')
1044 disc.state |= (1 << MD_DISK_CANDIDATE);
1045 else
1046 disc.state |= (1 << MD_DISK_CLUSTER_ADD);
1047 }
1048
e22fe3ae 1049 if (dv->writemostly == FlagSet)
38aeaf3a 1050 disc.state |= (1 << MD_DISK_WRITEMOSTLY);
e22fe3ae 1051 if (dv->failfast == FlagSet)
71574efb 1052 disc.state |= (1 << MD_DISK_FAILFAST);
38aeaf3a 1053 if (tst->ss->external) {
29273f60 1054 if (manage_add_external(tst, fd, dv->devname, &disc) != MDADM_STATUS_SUCCESS)
ed2c2cb3 1055 goto unlock;
38aeaf3a
N
1056 } else {
1057 tst->ss->free_super(tst);
1058 if (ioctl(fd, ADD_NEW_DISK, &disc)) {
01290056
SL
1059 if (dv->disposition == 'j')
1060 pr_err("Failed to hot add %s as journal, "
1061 "please try restart %s.\n", dv->devname, devname);
1062 else
1063 pr_err("add new device failed for %s as %d: %s\n",
1064 dv->devname, j, strerror(errno));
ed2c2cb3 1065 goto unlock;
38aeaf3a 1066 }
01290056
SL
1067 if (dv->disposition == 'j') {
1068 pr_err("Journal added successfully, making %s read-write\n", devname);
1069 if (Manage_ro(devname, fd, -1))
1070 pr_err("Failed to make %s read-write\n", devname);
1071 }
1072
38aeaf3a
N
1073 }
1074 if (verbose >= 0)
1075 pr_err("added %s\n", dv->devname);
ed2c2cb3 1076 map_unlock(&map);
38aeaf3a 1077 return 1;
ed2c2cb3
LXK
1078unlock:
1079 map_unlock(&map);
1080 return -1;
38aeaf3a
N
1081}
1082
d070235d 1083int Manage_remove(struct supertype *tst, int fd, struct mddev_dev *dv,
1ab9ed2a 1084 int sysfd, unsigned long rdev, int force, int verbose, char *devname)
d070235d
N
1085{
1086 int lfd = -1;
1087 int err;
1088
1089 if (tst->ss->external) {
1090 /* To remove a device from a container, we must
1091 * check that it isn't in use in an array.
1092 * This involves looking in the 'holders'
1093 * directory - there must be just one entry,
1094 * the container.
1095 * To ensure that it doesn't get used as a
1096 * hot spare while we are checking, we
1097 * get an O_EXCL open on the container
1098 */
aab15415 1099 int ret;
4dd2df09
N
1100 char devnm[32];
1101 strcpy(devnm, fd2devnm(fd));
1102 lfd = open_dev_excl(devnm);
d070235d 1103 if (lfd < 0) {
7a862a02 1104 pr_err("Cannot get exclusive access to container - odd\n");
d070235d
N
1105 return -1;
1106 }
aab15415
N
1107 /* We may not be able to check on holders in
1108 * sysfs, either because we don't have the dev num
1109 * (rdev == 0) or because the device has been detached
1110 * and the 'holders' directory no longer exists
1111 * (ret == -1). In that case, assume it is OK to
1112 * remove.
d070235d 1113 */
aab15415
N
1114 if (rdev == 0)
1115 ret = -1;
c922221e
TM
1116 else {
1117 /*
1118 * The drive has already been set to 'faulty', however
1119 * monitor might not have had time to process it and the
1120 * drive might still have an entry in the 'holders'
1121 * directory. Try a few times to avoid a false error
1122 */
1123 int count = 20;
1124
1125 do {
1126 ret = sysfs_unique_holder(devnm, rdev);
1127 if (ret < 2)
1128 break;
239b3cc0 1129 sleep_for(0, MSEC_TO_NSEC(100), true);
c922221e
TM
1130 } while (--count > 0);
1131
1132 if (ret == 0) {
1133 pr_err("%s is not a member, cannot remove.\n",
1134 dv->devname);
1135 close(lfd);
1136 return -1;
1137 }
1138 if (ret >= 2) {
1139 pr_err("%s is still in use, cannot remove.\n",
1140 dv->devname);
1141 close(lfd);
1142 return -1;
1143 }
d070235d
N
1144 }
1145 }
1146 /* FIXME check that it is a current member */
1147 if (sysfd >= 0) {
1148 /* device has been removed and we don't know
1149 * the major:minor number
1150 */
1ab9ed2a 1151 err = sys_hot_remove_disk(sysfd, force);
d070235d 1152 } else {
1ab9ed2a 1153 err = hot_remove_disk(fd, rdev, force);
d070235d
N
1154 if (err && errno == ENODEV) {
1155 /* Old kernels rejected this if no personality
1156 * is registered */
4dd2df09 1157 struct mdinfo *sra = sysfs_read(fd, NULL, GET_DEVS);
d070235d
N
1158 struct mdinfo *dv = NULL;
1159 if (sra)
1160 dv = sra->devs;
1161 for ( ; dv ; dv=dv->next)
1162 if (dv->disk.major == (int)major(rdev) &&
1163 dv->disk.minor == (int)minor(rdev))
1164 break;
1165 if (dv)
1166 err = sysfs_set_str(sra, dv,
1167 "state", "remove");
1168 else
1169 err = -1;
6e8d27e7 1170 sysfs_free(sra);
d070235d
N
1171 }
1172 }
1173 if (err) {
7a862a02 1174 pr_err("hot remove failed for %s: %s\n", dv->devname,
d070235d
N
1175 strerror(errno));
1176 if (lfd >= 0)
1177 close(lfd);
1178 return -1;
1179 }
1180 if (tst->ss->external) {
1181 /*
1182 * Before dropping our exclusive open we make an
1183 * attempt at preventing mdmon from seeing an
1184 * 'add' event before reconciling this 'remove'
1185 * event.
1186 */
4dd2df09 1187 char *devnm = fd2devnm(fd);
d070235d 1188
4dd2df09 1189 if (!devnm) {
d070235d
N
1190 pr_err("unable to get container name\n");
1191 return -1;
1192 }
1193
4dd2df09 1194 ping_manager(devnm);
d070235d
N
1195 }
1196 if (lfd >= 0)
1197 close(lfd);
1198 if (verbose >= 0)
1199 pr_err("hot removed %s from %s\n",
1200 dv->devname, devname);
1201 return 1;
1202}
1203
70c55e36
N
1204int Manage_replace(struct supertype *tst, int fd, struct mddev_dev *dv,
1205 unsigned long rdev, int verbose, char *devname)
1206{
1207 struct mdinfo *mdi, *di;
1208 if (tst->ss->external) {
1209 pr_err("--replace only supported for native metadata (0.90 or 1.x)\n");
1210 return -1;
1211 }
1212 /* Need to find the device in sysfs and add 'want_replacement' to the
1213 * status.
1214 */
4dd2df09 1215 mdi = sysfs_read(fd, NULL, GET_DEVS);
70c55e36
N
1216 if (!mdi || !mdi->devs) {
1217 pr_err("Cannot find status of %s to enable replacement - strange\n",
1218 devname);
1219 return -1;
1220 }
1221 for (di = mdi->devs; di; di = di->next)
1222 if (di->disk.major == (int)major(rdev) &&
1223 di->disk.minor == (int)minor(rdev))
1224 break;
1225 if (di) {
1226 int rv;
1227 if (di->disk.raid_disk < 0) {
1228 pr_err("%s is not active and so cannot be replaced.\n",
1229 dv->devname);
1230 sysfs_free(mdi);
1231 return -1;
1232 }
1233 rv = sysfs_set_str(mdi, di,
1234 "state", "want_replacement");
1235 if (rv) {
1236 sysfs_free(mdi);
1237 pr_err("Failed to request replacement for %s\n",
1238 dv->devname);
1239 return -1;
1240 }
1241 if (verbose >= 0)
1242 pr_err("Marked %s (device %d in %s) for replacement\n",
1243 dv->devname, di->disk.raid_disk, devname);
1244 /* If there is a matching 'with', we need to tell it which
1245 * raid disk
1246 */
1247 while (dv && dv->disposition != 'W')
1248 dv = dv->next;
1249 if (dv) {
1250 dv->disposition = 'w';
1251 dv->used = di->disk.raid_disk;
1252 }
1253 return 1;
1254 }
1255 sysfs_free(mdi);
1256 pr_err("%s not found in %s so cannot --replace it\n",
1257 dv->devname, devname);
1258 return -1;
1259}
1260
1261int Manage_with(struct supertype *tst, int fd, struct mddev_dev *dv,
1262 unsigned long rdev, int verbose, char *devname)
1263{
1264 struct mdinfo *mdi, *di;
1265 /* try to set 'slot' for 'rdev' in 'fd' to 'dv->used' */
4dd2df09 1266 mdi = sysfs_read(fd, NULL, GET_DEVS|GET_STATE);
70c55e36
N
1267 if (!mdi || !mdi->devs) {
1268 pr_err("Cannot find status of %s to enable replacement - strange\n",
1269 devname);
1270 return -1;
1271 }
1272 for (di = mdi->devs; di; di = di->next)
1273 if (di->disk.major == (int)major(rdev) &&
1274 di->disk.minor == (int)minor(rdev))
1275 break;
1276 if (di) {
1277 int rv;
1278 if (di->disk.state & (1<<MD_DISK_FAULTY)) {
1279 pr_err("%s is faulty and cannot be a replacement\n",
1280 dv->devname);
1281 sysfs_free(mdi);
1282 return -1;
1283 }
1284 if (di->disk.raid_disk >= 0) {
1285 pr_err("%s is active and cannot be a replacement\n",
1286 dv->devname);
1287 sysfs_free(mdi);
1288 return -1;
1289 }
1290 rv = sysfs_set_num(mdi, di,
1291 "slot", dv->used);
1292 if (rv) {
1293 sysfs_free(mdi);
51425978 1294 pr_err("Failed to set %s as preferred replacement.\n",
70c55e36
N
1295 dv->devname);
1296 return -1;
1297 }
1298 if (verbose >= 0)
1299 pr_err("Marked %s in %s as replacement for device %d\n",
1300 dv->devname, devname, dv->used);
1301 return 1;
1302 }
1303 sysfs_free(mdi);
1304 pr_err("%s not found in %s so cannot make it preferred replacement\n",
1305 dv->devname, devname);
1306 return -1;
1307}
1308
fc6fd406
MK
1309/**
1310 * is_remove_safe() - Check if remove is safe.
1311 * @array: Array info.
1312 * @fd: Array file descriptor.
1313 * @devname: Name of device to remove.
1314 * @verbose: Verbose.
1315 *
1316 * The function determines if array will be operational
1317 * after removing &devname.
1318 *
1319 * Return: True if array will be operational, false otherwise.
1320 */
1321bool is_remove_safe(mdu_array_info_t *array, const int fd, char *devname, const int verbose)
1322{
1323 dev_t devid = devnm2devid(devname + 5);
1324 struct mdinfo *mdi = sysfs_read(fd, NULL, GET_DEVS | GET_DISKS | GET_STATE);
1325
1326 if (!mdi) {
1327 if (verbose)
1328 pr_err("Failed to read sysfs attributes for %s\n", devname);
1329 return false;
1330 }
1331
1332 char *avail = xcalloc(array->raid_disks, sizeof(char));
1333
1334 for (mdi = mdi->devs; mdi; mdi = mdi->next) {
1335 if (mdi->disk.raid_disk < 0)
1336 continue;
1337 if (!(mdi->disk.state & (1 << MD_DISK_SYNC)))
1338 continue;
1339 if (makedev(mdi->disk.major, mdi->disk.minor) == devid)
1340 continue;
1341 avail[mdi->disk.raid_disk] = 1;
1342 }
1343 sysfs_free(mdi);
1344
1345 bool is_enough = enough(array->level, array->raid_disks,
b3e7b7eb 1346 array->layout, 1, avail);
fc6fd406
MK
1347
1348 free(avail);
1349 return is_enough;
1350}
1351
36a70782
KT
1352/**
1353 * Manage_subdevs() - Execute operation depending on devmode.
1354 *
1355 * @devname: name of the device.
1356 * @fd: file descriptor.
1357 * @devlist: list of sub-devices to manage.
1358 * @verbose: verbose level.
1359 * @test: test flag.
1360 * @update: type of update.
1361 * @force: force flag.
1362 *
1363 * This function executes operation defined by devmode
1364 * for each dev from devlist.
1365 * Devmode can be:
1366 * 'a' - add the device
1367 * 'S' - add the device as a spare - don't try re-add
1368 * 'j' - add the device as a journal device
1369 * 'A' - re-add the device
1370 * 'r' - remove the device: HOT_REMOVE_DISK
1371 * device can be 'faulty' or 'detached' in which case all
1372 * matching devices are removed.
1373 * 'f' - set the device faulty SET_DISK_FAULTY
1374 * device can be 'detached' in which case any device that
1375 * is inaccessible will be marked faulty.
1376 * 'I' - remove device by using incremental fail
1377 * which is executed when device is removed surprisingly.
1378 * 'R' - mark this device as wanting replacement.
1379 * 'W' - this device is added if necessary and activated as
1380 * a replacement for a previous 'R' device.
1381 * -----
1382 * 'w' - 'W' will be changed to 'w' when it is paired with
1383 * a 'R' device. If a 'W' is found while walking the list
1384 * it must be unpaired, and is an error.
1385 * 'M' - this is created by a 'missing' target. It is a slight
1386 * variant on 'A'
1387 * 'F' - Another variant of 'A', where the device was faulty
1388 * so must be removed from the array first.
1389 * 'c' - confirm the device as found (for clustered environments)
1390 *
1391 * For 'f' and 'r', the device can also be a kernel-internal
1392 * name such as 'sdb'.
1393 *
1394 * Return: 0 on success, otherwise 1 or 2.
1395 */
64c4757e 1396int Manage_subdevs(char *devname, int fd,
833bb0f8 1397 struct mddev_dev *devlist, int verbose, int test,
f2e8393b 1398 enum update_opt update, int force)
cd29a5c8 1399{
682c7051 1400 mdu_array_info_t array;
7a3be72f 1401 unsigned long long array_size;
1d997643 1402 struct mddev_dev *dv;
cfad27a9 1403 int tfd = -1;
f6feb3fb 1404 struct supertype *tst = NULL;
4725bc31 1405 char *subarray = NULL;
98d27e39 1406 int sysfd = -1;
7d2e6486 1407 int count = 0; /* number of actions taken */
9f584691 1408 struct mdinfo info;
9465f170 1409 struct mdinfo devinfo;
9f584691 1410 int frozen = 0;
8af530b0 1411 int busy = 0;
4de90913 1412 int raid_slot = -1;
682c7051 1413
dae13137
JS
1414 if (sysfs_init(&info, fd, NULL)) {
1415 pr_err("sysfs not availabile for %s\n", devname);
1416 goto abort;
1417 }
1418
9cd39f01
JS
1419 if (md_get_array_info(fd, &array)) {
1420 pr_err("Cannot get array info for %s\n", devname);
bcbb3112 1421 goto abort;
682c7051 1422 }
7bd04da9 1423 /* array.size is only 32 bits and may be truncated.
7a3be72f
NB
1424 * So read from sysfs if possible, and record number of sectors
1425 */
1426
1427 array_size = get_component_size(fd);
1428 if (array_size <= 0)
1429 array_size = array.size * 2;
1430
4725bc31 1431 tst = super_by_fd(fd, &subarray);
3da92f27 1432 if (!tst) {
e7b84f9d 1433 pr_err("unsupport array - version %d.%d\n",
3da92f27 1434 array.major_version, array.minor_version);
bcbb3112 1435 goto abort;
3da92f27
NB
1436 }
1437
38aeaf3a 1438 for (dv = devlist; dv; dv = dv->next) {
ffaf1a7e 1439 dev_t rdev = 0; /* device to add/remove etc */
38aeaf3a 1440 int rv;
b47024f1 1441 int mj,mn;
4a39c6f2 1442
4de90913
GJ
1443 raid_slot = -1;
1444 if (dv->disposition == 'c') {
1445 rv = parse_cluster_confirm_arg(dv->devname,
1446 &dv->devname,
1447 &raid_slot);
d7a49369 1448 if (rv) {
4de90913
GJ
1449 pr_err("Could not get the devname of cluster\n");
1450 goto abort;
1451 }
1452 }
1453
1d997643
N
1454 if (strcmp(dv->devname, "failed") == 0 ||
1455 strcmp(dv->devname, "faulty") == 0) {
fc54fe7a 1456 if (dv->disposition != 'A' && dv->disposition != 'r') {
7a862a02 1457 pr_err("%s only meaningful with -r or --re-add, not -%c\n",
b80da661 1458 dv->devname, dv->disposition);
bcbb3112 1459 goto abort;
b80da661 1460 }
262e3b7f
N
1461 add_faulty(dv, fd, (dv->disposition == 'A'
1462 ? 'F' : 'r'));
1d997643
N
1463 continue;
1464 }
1465 if (strcmp(dv->devname, "detached") == 0) {
b80da661 1466 if (dv->disposition != 'r' && dv->disposition != 'f') {
7a862a02 1467 pr_err("%s only meaningful with -r of -f, not -%c\n",
b80da661 1468 dv->devname, dv->disposition);
bcbb3112 1469 goto abort;
b80da661 1470 }
1d997643
N
1471 add_detached(dv, fd, dv->disposition);
1472 continue;
1473 }
1474
1475 if (strcmp(dv->devname, "missing") == 0) {
e9ddbb2b 1476 struct mddev_dev *add_devlist;
1d997643 1477 struct mddev_dev **dp;
4de90913
GJ
1478 if (dv->disposition == 'c') {
1479 rv = ioctl(fd, CLUSTERED_DISK_NACK, NULL);
1480 break;
1481 }
1482
c8e1a230 1483 if (dv->disposition != 'A') {
7a862a02 1484 pr_err("'missing' only meaningful with --re-add\n");
bcbb3112 1485 goto abort;
a4e13010 1486 }
1d997643 1487 add_devlist = conf_get_devs();
a4e13010 1488 if (add_devlist == NULL) {
8e5b52cd 1489 pr_err("no devices to scan for missing members.\n");
a4e13010
N
1490 continue;
1491 }
1d997643 1492 for (dp = &add_devlist; *dp; dp = & (*dp)->next)
7bd04da9 1493 /* 'M' (for 'missing') is like 'A' without errors */
1d997643
N
1494 (*dp)->disposition = 'M';
1495 *dp = dv->next;
1496 dv->next = add_devlist;
1497 continue;
1498 }
1499
64a78416
N
1500 if (strncmp(dv->devname, "set-", 4) == 0 &&
1501 strlen(dv->devname) == 5) {
1502 int copies;
1503
1504 if (dv->disposition != 'r' &&
1505 dv->disposition != 'f') {
1506 pr_err("'%s' only meaningful with -r or -f\n",
1507 dv->devname);
1508 goto abort;
1509 }
1510 if (array.level != 10) {
1511 pr_err("'%s' only meaningful with RAID10 arrays\n",
1512 dv->devname);
1513 goto abort;
1514 }
1515 copies = ((array.layout & 0xff) *
1516 ((array.layout >> 8) & 0xff));
1517 if (array.raid_disks % copies != 0 ||
1518 dv->devname[4] < 'A' ||
1519 dv->devname[4] >= 'A' + copies ||
1520 copies > 26) {
1521 pr_err("'%s' not meaningful with this array\n",
1522 dv->devname);
1523 goto abort;
1524 }
1525 add_set(dv, fd, dv->devname[4]);
1526 continue;
1527 }
1528
1d997643 1529 if (strchr(dv->devname, '/') == NULL &&
aab15415
N
1530 strchr(dv->devname, ':') == NULL &&
1531 strlen(dv->devname) < 50) {
98d27e39
N
1532 /* Assume this is a kernel-internal name like 'sda1' */
1533 int found = 0;
1534 char dname[55];
461fae7e
KT
1535 if (dv->disposition != 'r' && dv->disposition != 'f' &&
1536 dv->disposition != 'I') {
1537 pr_err("%s only meaningful with -r, -f or -I, not -%c\n",
98d27e39 1538 dv->devname, dv->disposition);
bcbb3112 1539 goto abort;
98d27e39
N
1540 }
1541
1542 sprintf(dname, "dev-%s", dv->devname);
4dd2df09 1543 sysfd = sysfs_open(fd2devnm(fd), dname, "block/dev");
98d27e39 1544 if (sysfd >= 0) {
90fd7001
MK
1545 char dn[SYSFS_MAX_BUF_SIZE];
1546 if (sysfs_fd_get_str(sysfd, dn, sizeof(dn)) > 0 &&
98d27e39 1547 sscanf(dn, "%d:%d", &mj,&mn) == 2) {
5dffd09d 1548 rdev = makedev(mj,mn);
98d27e39
N
1549 found = 1;
1550 }
1551 close(sysfd);
1552 sysfd = -1;
1553 }
1554 if (!found) {
4dd2df09 1555 sysfd = sysfs_open(fd2devnm(fd), dname, "state");
98d27e39 1556 if (sysfd < 0) {
7a862a02 1557 pr_err("%s does not appear to be a component of %s\n",
98d27e39 1558 dv->devname, devname);
bcbb3112 1559 goto abort;
98d27e39
N
1560 }
1561 }
fc54fe7a
JS
1562 } else if ((dv->disposition == 'r' ||
1563 dv->disposition == 'f') &&
1564 get_maj_min(dv->devname, &mj, &mn)) {
b47024f1
N
1565 /* for 'fail' and 'remove', the device might
1566 * not exist.
1567 */
1568 rdev = makedev(mj, mn);
b80da661 1569 } else {
c7b47447 1570 tfd = dev_open(dv->devname, O_RDONLY);
cc5083d1 1571 if (tfd >= 0) {
0a6bff09 1572 fstat_is_blkdev(tfd, dv->devname, &rdev);
cc5083d1
JS
1573 close(tfd);
1574 } else {
5fe7f5f7 1575 int open_err = errno;
9e04ac1c 1576 if (!stat_is_blkdev(dv->devname, &rdev)) {
5fe7f5f7
N
1577 if (dv->disposition == 'M')
1578 /* non-fatal. Also improbable */
1579 continue;
5fe7f5f7
N
1580 goto abort;
1581 }
1582 if (dv->disposition == 'r')
1583 /* Be happy, the stat worked, that is
1584 * enough for --remove
1585 */
1586 ;
1587 else {
1d997643
N
1588 if (dv->disposition == 'M')
1589 /* non-fatal */
1590 continue;
839f27a3 1591 pr_err("Cannot open %s: %s\n",
5fe7f5f7 1592 dv->devname, strerror(open_err));
bcbb3112 1593 goto abort;
5a9de8db 1594 }
b80da661 1595 }
682c7051 1596 }
cd29a5c8 1597 switch(dv->disposition){
682c7051 1598 default:
e7b84f9d 1599 pr_err("internal error - devmode[%s]=%d\n",
c913b90e 1600 dv->devname, dv->disposition);
bcbb3112 1601 goto abort;
682c7051 1602 case 'a':
f33a71f1 1603 case 'S': /* --add-spare */
01290056 1604 case 'j': /* --add-journal */
c8e1a230 1605 case 'A':
262e3b7f
N
1606 case 'M': /* --re-add missing */
1607 case 'F': /* --re-add faulty */
4de90913 1608 case 'c': /* --cluster-confirm */
4a39c6f2 1609 /* add the device */
4725bc31 1610 if (subarray) {
7a862a02 1611 pr_err("Cannot add disks to a \'member\' array, perform this operation on the parent container\n");
bcbb3112 1612 goto abort;
f94d52f4 1613 }
9465f170
GJ
1614
1615 /* Let's first try to write re-add to sysfs */
1616 if (rdev != 0 &&
1617 (dv->disposition == 'A' || dv->disposition == 'F')) {
1618 sysfs_init_dev(&devinfo, rdev);
1619 if (sysfs_set_str(&info, &devinfo, "state", "re-add") == 0) {
1620 pr_err("re-add %s to %s succeed\n",
1621 dv->devname, info.sys_name);
1622 break;
1623 }
1624 }
1625
262e3b7f
N
1626 if (dv->disposition == 'F')
1627 /* Need to remove first */
1ab9ed2a 1628 hot_remove_disk(fd, rdev, force);
f277ce36 1629 /* Make sure it isn't in use (in 2.6 or later) */
1d997643 1630 tfd = dev_open(dv->devname, O_RDONLY|O_EXCL);
38aeaf3a
N
1631 if (tfd >= 0) {
1632 /* We know no-one else is using it. We'll
1633 * need non-exclusive access to add it, so
1634 * do that now.
1635 */
1636 close(tfd);
1637 tfd = dev_open(dv->devname, O_RDONLY);
1011e834 1638 }
0fbf459d 1639 if (tfd < 0) {
1d997643
N
1640 if (dv->disposition == 'M')
1641 continue;
e7b84f9d 1642 pr_err("Cannot open %s: %s\n",
d7eaf49f 1643 dv->devname, strerror(errno));
bcbb3112 1644 goto abort;
d7eaf49f 1645 }
9f584691
N
1646 if (!frozen) {
1647 if (sysfs_freeze_array(&info) == 1)
1648 frozen = 1;
1649 else
1650 frozen = -1;
1651 }
38aeaf3a
N
1652 rv = Manage_add(fd, tfd, dv, tst, &array,
1653 force, verbose, devname, update,
4de90913 1654 rdev, array_size, raid_slot);
38aeaf3a
N
1655 close(tfd);
1656 tfd = -1;
1657 if (rv < 0)
bcbb3112 1658 goto abort;
38aeaf3a
N
1659 if (rv > 0)
1660 count++;
682c7051
NB
1661 break;
1662
1663 case 'r':
1664 /* hot remove */
4725bc31 1665 if (subarray) {
7a862a02 1666 pr_err("Cannot remove disks from a \'member\' array, perform this operation on the parent container\n");
d070235d
N
1667 rv = -1;
1668 } else
1669 rv = Manage_remove(tst, fd, dv, sysfd,
1ab9ed2a 1670 rdev, verbose, force,
d070235d
N
1671 devname);
1672 if (sysfd >= 0)
98d27e39 1673 close(sysfd);
d070235d
N
1674 sysfd = -1;
1675 if (rv < 0)
bcbb3112 1676 goto abort;
d070235d
N
1677 if (rv > 0)
1678 count++;
682c7051
NB
1679 break;
1680
1681 case 'f': /* set faulty */
fc6fd406
MK
1682 if (!is_remove_safe(&array, fd, dv->devname, verbose)) {
1683 pr_err("Cannot remove %s from %s, array will be failed.\n",
1684 dv->devname, devname);
1685 if (sysfd >= 0)
1686 close(sysfd);
1687 goto abort;
1688 }
461fae7e 1689 case 'I': /* incremental fail */
98d27e39
N
1690 if ((sysfd >= 0 && write(sysfd, "faulty", 6) != 6) ||
1691 (sysfd < 0 && ioctl(fd, SET_DISK_FAULTY,
5dffd09d 1692 rdev))) {
8af530b0
N
1693 if (errno == EBUSY)
1694 busy = 1;
e7b84f9d 1695 pr_err("set device faulty failed for %s: %s\n",
1d997643 1696 dv->devname, strerror(errno));
98d27e39
N
1697 if (sysfd >= 0)
1698 close(sysfd);
bcbb3112 1699 goto abort;
682c7051 1700 }
98d27e39
N
1701 if (sysfd >= 0)
1702 close(sysfd);
1703 sysfd = -1;
7d2e6486 1704 count++;
dab6685f 1705 if (verbose >= 0)
e7b84f9d 1706 pr_err("set %s faulty in %s\n",
1d997643 1707 dv->devname, devname);
682c7051 1708 break;
70c55e36
N
1709 case 'R': /* Mark as replaceable */
1710 if (subarray) {
7a862a02 1711 pr_err("Cannot replace disks in a \'member\' array, perform this operation on the parent container\n");
70c55e36
N
1712 rv = -1;
1713 } else {
1714 if (!frozen) {
1715 if (sysfs_freeze_array(&info) == 1)
1716 frozen = 1;
1717 else
1718 frozen = -1;
1719 }
1720 rv = Manage_replace(tst, fd, dv,
5dffd09d 1721 rdev, verbose,
70c55e36
N
1722 devname);
1723 }
1724 if (rv < 0)
1725 goto abort;
1726 if (rv > 0)
1727 count++;
1728 break;
1729 case 'W': /* --with device that doesn't match */
1730 pr_err("No matching --replace device for --with %s\n",
1731 dv->devname);
1732 goto abort;
1733 case 'w': /* --with device which was matched */
1734 rv = Manage_with(tst, fd, dv,
5dffd09d 1735 rdev, verbose, devname);
70c55e36
N
1736 if (rv < 0)
1737 goto abort;
1738 break;
682c7051
NB
1739 }
1740 }
f6feb3fb 1741 free(tst);
9f584691
N
1742 if (frozen > 0)
1743 sysfs_set_str(&info, NULL, "sync_action","idle");
7d2e6486
N
1744 if (test && count == 0)
1745 return 2;
682c7051 1746 return 0;
bcbb3112
N
1747
1748abort:
f6feb3fb 1749 free(tst);
9f584691
N
1750 if (frozen > 0)
1751 sysfs_set_str(&info, NULL, "sync_action","idle");
8af530b0 1752 return !test && busy ? 2 : 1;
64c4757e 1753}
1f48664b
NB
1754
1755int autodetect(void)
1756{
1757 /* Open any md device, and issue the RAID_AUTORUN ioctl */
1758 int rv = 1;
1759 int fd = dev_open("9:0", O_RDONLY);
1760 if (fd >= 0) {
1761 if (ioctl(fd, RAID_AUTORUN, 0) == 0)
1762 rv = 0;
1763 close(fd);
1764 }
1765 return rv;
1766}
aa534678 1767
f2e8393b
MK
1768int Update_subarray(char *dev, char *subarray, enum update_opt update,
1769 struct mddev_ident *ident, int verbose)
aa534678
DW
1770{
1771 struct supertype supertype, *st = &supertype;
1772 int fd, rv = 2;
70f1ff42 1773 struct mdinfo *info = NULL;
f2e8393b 1774 char *update_verb = map_num(update_options, update);
582945c2 1775 bool allow_active = update == UOPT_PPL || update == UOPT_NO_PPL;
aa534678
DW
1776
1777 memset(st, 0, sizeof(*st));
aa534678 1778
ba728be7 1779 fd = open_subarray(dev, subarray, st, verbose < 0);
aa534678
DW
1780 if (fd < 0)
1781 return 2;
1782
1783 if (!st->ss->update_subarray) {
ba728be7 1784 if (verbose >= 0)
e7b84f9d
N
1785 pr_err("Operation not supported for %s metadata\n",
1786 st->ss->name);
aa534678
DW
1787 goto free_super;
1788 }
1789
582945c2 1790 if (!allow_active && is_subarray_active(subarray, st->devnm)) {
db10eab6
MK
1791 if (verbose >= 0)
1792 pr_err("Subarray %s in %s is active, cannot update %s\n",
f2e8393b 1793 subarray, dev, update_verb);
db10eab6
MK
1794 goto free_super;
1795 }
1796
4dd2df09 1797 if (mdmon_running(st->devnm))
aa534678
DW
1798 st->update_tail = &st->updates;
1799
70f1ff42
LF
1800 info = st->ss->container_content(st, subarray);
1801
f2e8393b 1802 if (update == UOPT_PPL && !is_level456(info->array.level)) {
70f1ff42
LF
1803 pr_err("RWH policy ppl is supported only for raid4, raid5 and raid6.\n");
1804 goto free_super;
1805 }
1806
f2e8393b 1807 rv = st->ss->update_subarray(st, subarray, update, ident);
aa534678
DW
1808
1809 if (rv) {
ba728be7 1810 if (verbose >= 0)
e7b84f9d 1811 pr_err("Failed to update %s of subarray-%s in %s\n",
f2e8393b 1812 update_verb, subarray, dev);
aa534678
DW
1813 } else if (st->update_tail)
1814 flush_metadata_updates(st);
1815 else
1816 st->ss->sync_metadata(st);
1817
f2e8393b 1818 if (rv == 0 && update == UOPT_NAME && verbose >= 0)
e7b84f9d
N
1819 pr_err("Updated subarray-%s name from %s, UUIDs may have changed\n",
1820 subarray, dev);
aa534678 1821
70f1ff42
LF
1822free_super:
1823 if (info)
1824 free(info);
aa534678
DW
1825 st->ss->free_super(st);
1826 close(fd);
1827
1828 return rv;
1829}
d52bb542 1830
7bd04da9
N
1831/* Move spare from one array to another If adding to destination array fails
1832 * add back to original array.
d52bb542
AC
1833 * Returns 1 on success, 0 on failure */
1834int move_spare(char *from_devname, char *to_devname, dev_t devid)
1835{
1836 struct mddev_dev devlist;
1837 char devname[20];
1838
1839 /* try to remove and add */
1840 int fd1 = open(to_devname, O_RDONLY);
1841 int fd2 = open(from_devname, O_RDONLY);
1842
1843 if (fd1 < 0 || fd2 < 0) {
9cf361f8
JS
1844 if (fd1 >= 0)
1845 close(fd1);
1846 if (fd2 >= 0)
1847 close(fd2);
d52bb542
AC
1848 return 0;
1849 }
1850
1851 devlist.next = NULL;
1852 devlist.used = 0;
e22fe3ae
N
1853 devlist.writemostly = FlagDefault;
1854 devlist.failfast = FlagDefault;
d52bb542
AC
1855 devlist.devname = devname;
1856 sprintf(devname, "%d:%d", major(devid), minor(devid));
1857
1858 devlist.disposition = 'r';
f2e8393b 1859 if (Manage_subdevs(from_devname, fd2, &devlist, -1, 0, UOPT_UNDEFINED, 0) == 0) {
d52bb542 1860 devlist.disposition = 'a';
9cf361f8 1861 if (Manage_subdevs(to_devname, fd1, &devlist, -1, 0,
f2e8393b 1862 UOPT_UNDEFINED, 0) == 0) {
d52bb542
AC
1863 /* make sure manager is aware of changes */
1864 ping_manager(to_devname);
1865 ping_manager(from_devname);
1866 close(fd1);
1867 close(fd2);
1868 return 1;
1869 }
9cf361f8
JS
1870 else
1871 Manage_subdevs(from_devname, fd2, &devlist,
f2e8393b 1872 -1, 0, UOPT_UNDEFINED, 0);
d52bb542
AC
1873 }
1874 close(fd1);
1875 close(fd2);
1876 return 0;
1877}