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