]> git.ipfire.org Git - thirdparty/mdadm.git/blame - Incremental.c
Make Incremental_container static
[thirdparty/mdadm.git] / Incremental.c
CommitLineData
8382f19b
NB
1/*
2 * Incremental.c - support --incremental. Part of:
3 * mdadm - manage Linux "md" devices aka RAID arrays.
4 *
e736b623 5 * Copyright (C) 2006-2009 Neil Brown <neilb@suse.de>
8382f19b
NB
6 *
7 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation; either version 2 of the License, or
11 * (at your option) any later version.
12 *
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
17 *
18 * You should have received a copy of the GNU General Public License
19 * along with this program; if not, write to the Free Software
20 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
21 *
22 * Author: Neil Brown
23 * Email: <neilb@suse.de>
24 * Paper: Neil Brown
25 * Novell Inc
26 * GPO Box Q1283
27 * QVB Post Office, NSW 1230
28 * Australia
29 */
30
31#include "mdadm.h"
61018da0
N
32#include <dirent.h>
33#include <ctype.h>
8382f19b
NB
34
35static int count_active(struct supertype *st, int mdfd, char **availp,
36 struct mdinfo *info);
7e0f6979 37static void find_reject(int mdfd, struct supertype *st, struct mdinfo *sra,
8382f19b
NB
38 int number, __u64 events, int verbose,
39 char *array_name);
f08605b3
N
40static int try_spare(char *devname, int *dfdp, struct dev_policy *pol,
41 struct supertype *st, int verbose);
8382f19b 42
7d91c3f5
N
43static int Incremental_container(struct supertype *st, char *devname,
44 int verbose, int runstop, int autof,
45 int trustworthy);
46
8382f19b 47int Incremental(char *devname, int verbose, int runstop,
0ac91628
N
48 struct supertype *st, char *homehost, int require_homehost,
49 int autof)
8382f19b
NB
50{
51 /* Add this device to an array, creating the array if necessary
598f0d58 52 * and starting the array if sensible or - if runstop>0 - if possible.
8382f19b
NB
53 *
54 * This has several steps:
55 *
56 * 1/ Check if device is permitted by mdadm.conf, reject if not.
57 * 2/ Find metadata, reject if none appropriate (check
58 * version/name from args)
59 * 3/ Check if there is a match in mdadm.conf
215bb3f7
N
60 * 3a/ if not, check for homehost match. If no match, assemble as
61 * a 'foreign' array.
8382f19b
NB
62 * 4/ Determine device number.
63 * - If in mdadm.conf with std name, use that
64 * - UUID in /var/run/mdadm.map use that
65 * - If name is suggestive, use that. unless in use with different uuid.
66 * - Choose a free, high number.
67 * - Use a partitioned device unless strong suggestion not to.
68 * e.g. auto=md
352452c3 69 * Don't choose partitioned for containers.
8382f19b
NB
70 * 5/ Find out if array already exists
71 * 5a/ if it does not
72 * - choose a name, from mdadm.conf or 'name' field in array.
73 * - create the array
74 * - add the device
75 * 5b/ if it does
76 * - check one drive in array to make sure metadata is a reasonably
77 * close match. Reject if not (e.g. different type)
78 * - add the device
79 * 6/ Make sure /var/run/mdadm.map contains this array.
80 * 7/ Is there enough devices to possibly start the array?
352452c3 81 * For a container, this means running Incremental_container.
8382f19b
NB
82 * 7a/ if not, finish with success.
83 * 7b/ if yes,
84 * - read all metadata and arrange devices like -A does
85 * - if number of OK devices match expected, or -R and there are enough,
86 * start the array (auto-readonly).
87 */
88 struct stat stb;
7e83544b 89 struct mdinfo info, dinfo;
8382f19b
NB
90 struct mddev_ident_s *array_list, *match;
91 char chosen_name[1024];
15d4a7e4 92 int rv = 1;
8382f19b 93 struct map_ent *mp, *map = NULL;
15d4a7e4 94 int dfd = -1, mdfd = -1;
8382f19b
NB
95 char *avail;
96 int active_disks;
215bb3f7 97 int trustworthy = FOREIGN;
d7288ddc 98 char *name_to_use;
ad5bc697 99 mdu_array_info_t ainf;
7e83544b 100 struct dev_policy *policy = NULL;
8382f19b
NB
101
102 struct createinfo *ci = conf_get_create_info();
103
8382f19b 104
352452c3 105 /* 1/ Check if device is permitted by mdadm.conf */
8382f19b
NB
106
107 if (!conf_test_dev(devname)) {
108 if (verbose >= 0)
109 fprintf(stderr, Name
110 ": %s not permitted by mdadm.conf.\n",
111 devname);
15d4a7e4 112 goto out;
8382f19b
NB
113 }
114
115 /* 2/ Find metadata, reject if none appropriate (check
116 * version/name from args) */
117
118 dfd = dev_open(devname, O_RDONLY|O_EXCL);
119 if (dfd < 0) {
120 if (verbose >= 0)
121 fprintf(stderr, Name ": cannot open %s: %s.\n",
122 devname, strerror(errno));
15d4a7e4 123 goto out;
8382f19b
NB
124 }
125 if (fstat(dfd, &stb) < 0) {
126 if (verbose >= 0)
127 fprintf(stderr, Name ": fstat failed for %s: %s.\n",
128 devname, strerror(errno));
15d4a7e4 129 goto out;
8382f19b
NB
130 }
131 if ((stb.st_mode & S_IFMT) != S_IFBLK) {
132 if (verbose >= 0)
133 fprintf(stderr, Name ": %s is not a block device.\n",
134 devname);
15d4a7e4 135 goto out;
8382f19b
NB
136 }
137
7e83544b
N
138 dinfo.disk.major = major(stb.st_rdev);
139 dinfo.disk.minor = minor(stb.st_rdev);
140
141 policy = disk_policy(&dinfo);
142
8382f19b
NB
143 if (st == NULL && (st = guess_super(dfd)) == NULL) {
144 if (verbose >= 0)
145 fprintf(stderr, Name
146 ": no recognisable superblock on %s.\n",
147 devname);
f08605b3 148 rv = try_spare(devname, &dfd, policy, st, verbose);
15d4a7e4 149 goto out;
8382f19b 150 }
0f22b998
N
151 if (st->ss->compare_super == NULL ||
152 st->ss->load_super(st, dfd, NULL)) {
8382f19b
NB
153 if (verbose >= 0)
154 fprintf(stderr, Name ": no RAID superblock on %s.\n",
155 devname);
f08605b3 156 rv = try_spare(devname, &dfd, policy, st, verbose);
0f22b998 157 free(st);
15d4a7e4 158 goto out;
8382f19b 159 }
15d4a7e4 160 close (dfd); dfd = -1;
8382f19b 161
f35f2525 162 memset(&info, 0, sizeof(info));
a5d85af7 163 st->ss->getinfo_super(st, &info, NULL);
8382f19b
NB
164 /* 3/ Check if there is a match in mdadm.conf */
165
166 array_list = conf_get_ident(NULL);
167 match = NULL;
168 for (; array_list; array_list = array_list->next) {
169 if (array_list->uuid_set &&
170 same_uuid(array_list->uuid, info.uuid, st->ss->swapuuid)
171 == 0) {
fe056d1f 172 if (verbose >= 2 && array_list->devname)
8382f19b
NB
173 fprintf(stderr, Name
174 ": UUID differs from %s.\n",
175 array_list->devname);
176 continue;
177 }
178 if (array_list->name[0] &&
179 strcasecmp(array_list->name, info.name) != 0) {
fe056d1f 180 if (verbose >= 2 && array_list->devname)
8382f19b
NB
181 fprintf(stderr, Name
182 ": Name differs from %s.\n",
183 array_list->devname);
184 continue;
185 }
186 if (array_list->devices &&
187 !match_oneof(array_list->devices, devname)) {
fe056d1f 188 if (verbose >= 2 && array_list->devname)
8382f19b
NB
189 fprintf(stderr, Name
190 ": Not a listed device for %s.\n",
191 array_list->devname);
192 continue;
193 }
194 if (array_list->super_minor != UnSet &&
195 array_list->super_minor != info.array.md_minor) {
fe056d1f 196 if (verbose >= 2 && array_list->devname)
8382f19b
NB
197 fprintf(stderr, Name
198 ": Different super-minor to %s.\n",
199 array_list->devname);
200 continue;
201 }
202 if (!array_list->uuid_set &&
203 !array_list->name[0] &&
204 !array_list->devices &&
205 array_list->super_minor == UnSet) {
fe056d1f 206 if (verbose >= 2 && array_list->devname)
8382f19b
NB
207 fprintf(stderr, Name
208 ": %s doesn't have any identifying information.\n",
209 array_list->devname);
210 continue;
211 }
212 /* FIXME, should I check raid_disks and level too?? */
213
214 if (match) {
fe056d1f
N
215 if (verbose >= 0) {
216 if (match->devname && array_list->devname)
217 fprintf(stderr, Name
8382f19b 218 ": we match both %s and %s - cannot decide which to use.\n",
fe056d1f
N
219 match->devname, array_list->devname);
220 else
221 fprintf(stderr, Name
222 ": multiple lines in mdadm.conf match\n");
223 }
15d4a7e4
N
224 rv = 2;
225 goto out;
8382f19b
NB
226 }
227 match = array_list;
228 }
229
112cace6
N
230 if (match && match->devname
231 && strcasecmp(match->devname, "<ignore>") == 0) {
232 if (verbose >= 0)
233 fprintf(stderr, Name ": array containing %s is explicitly"
234 " ignored by mdadm.conf\n",
235 devname);
15d4a7e4 236 goto out;
112cace6
N
237 }
238
7b403fef
N
239 /* 3a/ if not, check for homehost match. If no match, continue
240 * but don't trust the 'name' in the array. Thus a 'random' minor
241 * number will be assigned, and the device name will be based
242 * on that. */
215bb3f7
N
243 if (match)
244 trustworthy = LOCAL;
d1d3482b
N
245 else if (st->ss->match_home(st, homehost) == 1)
246 trustworthy = LOCAL;
247 else if (st->ss->match_home(st, "any") == 1)
248 trustworthy = LOCAL_ANY;
215bb3f7 249 else
d1d3482b
N
250 trustworthy = FOREIGN;
251
252
4e8d9f0a 253 if (!match && !conf_test_metadata(st->ss->name, policy,
d1d3482b
N
254 (trustworthy == LOCAL))) {
255 if (verbose >= 1)
256 fprintf(stderr, Name
257 ": %s has metadata type %s for which "
258 "auto-assembly is disabled\n",
259 devname, st->ss->name);
15d4a7e4 260 goto out;
d1d3482b
N
261 }
262 if (trustworthy == LOCAL_ANY)
ecb02e31 263 trustworthy = LOCAL;
e12e1d1d 264
4ef2f11e
N
265 /* There are three possible sources for 'autof': command line,
266 * ARRAY line in mdadm.conf, or CREATE line in mdadm.conf.
350ac35d
N
267 * ARRAY takes precedence, then command line, then
268 * CREATE.
4ef2f11e 269 */
350ac35d 270 if (match && match->autof)
4ef2f11e
N
271 autof = match->autof;
272 if (autof == 0)
273 autof = ci->autof;
274
215bb3f7 275 if (st->ss->container_content && st->loaded_container) {
97b4d0e9
DW
276 if ((runstop > 0 && info.container_enough >= 0) ||
277 info.container_enough > 0)
278 /* pass */;
279 else {
280 if (verbose)
281 fprintf(stderr, Name ": not enough devices to start the container\n");
15d4a7e4
N
282 rv = 0;
283 goto out;
97b4d0e9
DW
284 }
285
215bb3f7
N
286 /* This is a pre-built container array, so we do something
287 * rather different.
288 */
15d4a7e4 289 rv = Incremental_container(st, devname, verbose, runstop,
215bb3f7 290 autof, trustworthy);
15d4a7e4 291 goto out;
8382f19b 292 }
ecb02e31 293
7cdc0872 294 name_to_use = info.name;
0ac91628 295 if (name_to_use[0] == 0 &&
ecb02e31
N
296 info.array.level == LEVEL_CONTAINER &&
297 trustworthy == LOCAL) {
298 name_to_use = info.text_version;
299 trustworthy = METADATA;
300 }
0ac91628
N
301 if (name_to_use[0] && trustworthy != LOCAL &&
302 ! require_homehost &&
303 conf_name_is_free(name_to_use))
304 trustworthy = LOCAL;
ecb02e31 305
7cdc0872
N
306 /* strip "hostname:" prefix from name if we have decided
307 * to treat it as LOCAL
308 */
309 if (trustworthy == LOCAL && strchr(name_to_use, ':') != NULL)
310 name_to_use = strchr(name_to_use, ':')+1;
311
ad5bc697 312 /* 4/ Check if array exists.
215bb3f7 313 */
93c861ee
DL
314 if (map_lock(&map))
315 fprintf(stderr, Name ": failed to get exclusive lock on "
316 "mapfile\n");
215bb3f7 317 mp = map_by_uuid(&map, info.uuid);
339c2d6c
N
318 if (mp)
319 mdfd = open_dev(mp->devnum);
320 else
215bb3f7 321 mdfd = -1;
d7288ddc 322
8382f19b 323 if (mdfd < 0) {
7e0f6979 324 struct mdinfo *sra;
8382f19b 325
215bb3f7 326 /* Couldn't find an existing array, maybe make a new one */
ffb3e494 327 mdfd = create_mddev(match ? match->devname : NULL,
e12e1d1d 328 name_to_use, autof, trustworthy, chosen_name);
215bb3f7
N
329
330 if (mdfd < 0)
15d4a7e4 331 goto out;
215bb3f7
N
332
333 sysfs_init(&info, mdfd, 0);
334
f35f2525
N
335 if (set_array_info(mdfd, st, &info) != 0) {
336 fprintf(stderr, Name ": failed to set array info for %s: %s\n",
8382f19b 337 chosen_name, strerror(errno));
15d4a7e4
N
338 rv = 2;
339 goto out;
8382f19b 340 }
7801ac20 341
c5afc314
N
342 dinfo = info;
343 dinfo.disk.major = major(stb.st_rdev);
344 dinfo.disk.minor = minor(stb.st_rdev);
345 if (add_disk(mdfd, st, &info, &dinfo) != 0) {
8382f19b
NB
346 fprintf(stderr, Name ": failed to add %s to %s: %s.\n",
347 devname, chosen_name, strerror(errno));
348 ioctl(mdfd, STOP_ARRAY, 0);
15d4a7e4
N
349 rv = 2;
350 goto out;
8382f19b 351 }
197e3eb6 352 sra = sysfs_read(mdfd, fd2devnum(mdfd), GET_DEVS);
06c7f68e 353 if (!sra || !sra->devs || sra->devs->disk.raid_disk >= 0) {
8382f19b
NB
354 /* It really should be 'none' - must be old buggy
355 * kernel, and mdadm -I may not be able to complete.
356 * So reject it.
357 */
358 ioctl(mdfd, STOP_ARRAY, NULL);
359 fprintf(stderr, Name
360 ": You have an old buggy kernel which cannot support\n"
361 " --incremental reliably. Aborting.\n");
8382f19b 362 sysfs_free(sra);
15d4a7e4
N
363 rv = 2;
364 goto out;
8382f19b 365 }
c5afc314 366 info.array.working_disks = 1;
f35f2525 367 sysfs_free(sra);
ad5bc697
N
368 /* 6/ Make sure /var/run/mdadm.map contains this array. */
369 map_update(&map, fd2devnum(mdfd),
370 info.text_version,
371 info.uuid, chosen_name);
8382f19b
NB
372 } else {
373 /* 5b/ if it does */
374 /* - check one drive in array to make sure metadata is a reasonably */
375 /* close match. Reject if not (e.g. different type) */
376 /* - add the device */
377 char dn[20];
378 int dfd2;
8382f19b 379 int err;
7e0f6979 380 struct mdinfo *sra;
3da92f27 381 struct supertype *st2;
c5afc314 382 struct mdinfo info2, *d;
215bb3f7 383
339c2d6c
N
384 if (mp->path)
385 strcpy(chosen_name, mp->path);
386 else
387 strcpy(chosen_name, devnum2devname(mp->devnum));
215bb3f7 388
ef83fe7c
N
389 /* It is generally not OK to add non-spare drives to a
390 * running array as they are probably missing because
391 * they failed. However if runstop is 1, then the
7e83544b
N
392 * array was possibly started early and our best bet is
393 * to add this anyway.
394 * Also if action policy is re-add or better we allow
395 * re-add
3a6ec29a 396 */
ef83fe7c 397 if ((info.disk.state & (1<<MD_DISK_SYNC)) != 0
7e83544b
N
398 && ! policy_action_allows(policy, st->ss->name,
399 act_re_add)
ef83fe7c 400 && runstop < 1) {
1dccfff9
DW
401 int active = 0;
402
403 if (st->ss->external) {
404 char *devname = devnum2devname(fd2devnum(mdfd));
405
406 active = devname && is_container_active(devname);
407 free(devname);
408 } else if (ioctl(mdfd, GET_ARRAY_INFO, &ainf) == 0)
409 active = 1;
410 if (active) {
3a6ec29a
N
411 fprintf(stderr, Name
412 ": not adding %s to active array (without --run) %s\n",
413 devname, chosen_name);
15d4a7e4
N
414 rv = 2;
415 goto out;
3a6ec29a
N
416 }
417 }
197e3eb6 418 sra = sysfs_read(mdfd, fd2devnum(mdfd), (GET_DEVS | GET_STATE));
15d4a7e4
N
419 if (!sra) {
420 rv = 2;
421 goto out;
422 }
7c548327
N
423 if (sra->devs) {
424 sprintf(dn, "%d:%d", sra->devs->disk.major,
425 sra->devs->disk.minor);
426 dfd2 = dev_open(dn, O_RDONLY);
427 st2 = dup_super(st);
428 if (st2->ss->load_super(st2, dfd2, NULL) ||
429 st->ss->compare_super(st, st2) != 0) {
430 fprintf(stderr, Name
431 ": metadata mismatch between %s and "
432 "chosen array %s\n",
433 devname, chosen_name);
7c548327 434 close(dfd2);
15d4a7e4
N
435 rv = 2;
436 goto out;
7c548327 437 }
8382f19b 438 close(dfd2);
7c548327 439 memset(&info2, 0, sizeof(info2));
a5d85af7 440 st2->ss->getinfo_super(st2, &info2, NULL);
7c548327
N
441 st2->ss->free_super(st2);
442 if (info.array.level != info2.array.level ||
443 memcmp(info.uuid, info2.uuid, 16) != 0 ||
444 info.array.raid_disks != info2.array.raid_disks) {
445 fprintf(stderr, Name
446 ": unexpected difference between %s and %s.\n",
447 chosen_name, devname);
15d4a7e4
N
448 rv = 2;
449 goto out;
7c548327 450 }
8382f19b 451 }
7801ac20
N
452 info2.disk.major = major(stb.st_rdev);
453 info2.disk.minor = minor(stb.st_rdev);
c5afc314
N
454 /* add disk needs to know about containers */
455 if (st->ss->external)
456 sra->array.level = LEVEL_CONTAINER;
ac7de9d9 457 err = add_disk(mdfd, st, sra, &info2);
8382f19b
NB
458 if (err < 0 && errno == EBUSY) {
459 /* could be another device present with the same
460 * disk.number. Find and reject any such
461 */
462 find_reject(mdfd, st, sra, info.disk.number,
463 info.events, verbose, chosen_name);
ac7de9d9 464 err = add_disk(mdfd, st, sra, &info2);
8382f19b
NB
465 }
466 if (err < 0) {
467 fprintf(stderr, Name ": failed to add %s to %s: %s.\n",
468 devname, chosen_name, strerror(errno));
15d4a7e4
N
469 rv = 2;
470 goto out;
8382f19b 471 }
c5afc314
N
472 info.array.working_disks = 0;
473 for (d = sra->devs; d; d=d->next)
474 info.array.working_disks ++;
475
8382f19b 476 }
8382f19b
NB
477
478 /* 7/ Is there enough devices to possibly start the array? */
479 /* 7a/ if not, finish with success. */
352452c3
N
480 if (info.array.level == LEVEL_CONTAINER) {
481 /* Try to assemble within the container */
ad5bc697 482 map_unlock(&map);
97590376 483 sysfs_uevent(&info, "change");
c5afc314
N
484 if (verbose >= 0)
485 fprintf(stderr, Name
486 ": container %s now has %d devices\n",
487 chosen_name, info.array.working_disks);
a7c6e3fb
N
488 wait_for(chosen_name, mdfd);
489 close(mdfd);
03b7f6c6 490 rv = Incremental(chosen_name, verbose, runstop,
0ac91628 491 NULL, homehost, require_homehost, autof);
03b7f6c6
N
492 if (rv == 1)
493 /* Don't fail the whole -I if a subarray didn't
494 * have enough devices to start yet
495 */
496 rv = 0;
497 return rv;
352452c3 498 }
f8409e54 499 avail = NULL;
8382f19b
NB
500 active_disks = count_active(st, mdfd, &avail, &info);
501 if (enough(info.array.level, info.array.raid_disks,
502 info.array.layout, info.array.state & 1,
3288b419 503 avail, active_disks) == 0) {
8382f19b
NB
504 free(avail);
505 if (verbose >= 0)
506 fprintf(stderr, Name
507 ": %s attached to %s, not enough to start (%d).\n",
508 devname, chosen_name, active_disks);
ad5bc697 509 map_unlock(&map);
15d4a7e4
N
510 rv = 0;
511 goto out;
8382f19b
NB
512 }
513 free(avail);
514
515 /* 7b/ if yes, */
516 /* - if number of OK devices match expected, or -R and there */
517 /* are enough, */
518 /* + add any bitmap file */
519 /* + start the array (auto-readonly). */
8382f19b
NB
520
521 if (ioctl(mdfd, GET_ARRAY_INFO, &ainf) == 0) {
522 if (verbose >= 0)
523 fprintf(stderr, Name
524 ": %s attached to %s which is already active.\n",
525 devname, chosen_name);
ad5bc697 526 map_unlock(&map);
15d4a7e4
N
527 rv = 0;
528 goto out;
8382f19b 529 }
ad5bc697
N
530
531 map_unlock(&map);
8382f19b 532 if (runstop > 0 || active_disks >= info.array.working_disks) {
7e83544b 533 struct mdinfo *sra, *dsk;
8382f19b
NB
534 /* Let's try to start it */
535 if (match && match->bitmap_file) {
536 int bmfd = open(match->bitmap_file, O_RDWR);
537 if (bmfd < 0) {
538 fprintf(stderr, Name
539 ": Could not open bitmap file %s.\n",
540 match->bitmap_file);
15d4a7e4 541 goto out;
8382f19b
NB
542 }
543 if (ioctl(mdfd, SET_BITMAP_FILE, bmfd) != 0) {
544 close(bmfd);
545 fprintf(stderr, Name
546 ": Failed to set bitmapfile for %s.\n",
547 chosen_name);
15d4a7e4 548 goto out;
8382f19b
NB
549 }
550 close(bmfd);
551 }
7e83544b
N
552 /* GET_* needed so add_disk works below */
553 sra = sysfs_read(mdfd, fd2devnum(mdfd),
554 GET_DEVS|GET_OFFSET|GET_SIZE|GET_STATE);
7b403fef 555 if ((sra == NULL || active_disks >= info.array.working_disks)
215bb3f7 556 && trustworthy != FOREIGN)
8382f19b
NB
557 rv = ioctl(mdfd, RUN_ARRAY, NULL);
558 else
559 rv = sysfs_set_str(sra, NULL,
560 "array_state", "read-auto");
561 if (rv == 0) {
562 if (verbose >= 0)
563 fprintf(stderr, Name
7e83544b 564 ": %s attached to %s, which has been started.\n",
8382f19b
NB
565 devname, chosen_name);
566 rv = 0;
a7c6e3fb 567 wait_for(chosen_name, mdfd);
7e83544b
N
568 /* We just started the array, so some devices
569 * might have been evicted from the array
570 * because their event counts were too old.
571 * If the action=re-add policy is in-force for
572 * those devices we should re-add them now.
573 */
574 for (dsk = sra->devs; dsk ; dsk = dsk->next) {
575 if (disk_action_allows(dsk, st->ss->name, act_re_add) &&
576 add_disk(mdfd, st, sra, dsk) == 0)
577 fprintf(stderr, Name
578 ": %s re-added to %s\n",
579 dsk->sys_name, chosen_name);
580 }
8382f19b
NB
581 } else {
582 fprintf(stderr, Name
583 ": %s attached to %s, but failed to start: %s.\n",
584 devname, chosen_name, strerror(errno));
585 rv = 1;
586 }
587 } else {
588 if (verbose >= 0)
589 fprintf(stderr, Name
590 ": %s attached to %s, not enough to start safely.\n",
591 devname, chosen_name);
592 rv = 0;
593 }
15d4a7e4
N
594out:
595 if (dfd >= 0)
596 close(dfd);
597 if (mdfd >= 0)
598 close(mdfd);
7e83544b
N
599 if (policy)
600 dev_policy_free(policy);
8382f19b
NB
601 return rv;
602}
603
7e0f6979 604static void find_reject(int mdfd, struct supertype *st, struct mdinfo *sra,
8382f19b
NB
605 int number, __u64 events, int verbose,
606 char *array_name)
607{
3da92f27 608 /* Find a device attached to this array with a disk.number of number
8382f19b
NB
609 * and events less than the passed events, and remove the device.
610 */
06c7f68e 611 struct mdinfo *d;
8382f19b
NB
612 mdu_array_info_t ra;
613
614 if (ioctl(mdfd, GET_ARRAY_INFO, &ra) == 0)
615 return; /* not safe to remove from active arrays
616 * without thinking more */
617
618 for (d = sra->devs; d ; d = d->next) {
619 char dn[10];
620 int dfd;
8382f19b 621 struct mdinfo info;
06c7f68e 622 sprintf(dn, "%d:%d", d->disk.major, d->disk.minor);
8382f19b
NB
623 dfd = dev_open(dn, O_RDONLY);
624 if (dfd < 0)
625 continue;
3da92f27 626 if (st->ss->load_super(st, dfd, NULL)) {
8382f19b
NB
627 close(dfd);
628 continue;
629 }
a5d85af7 630 st->ss->getinfo_super(st, &info, NULL);
3da92f27 631 st->ss->free_super(st);
8382f19b
NB
632 close(dfd);
633
634 if (info.disk.number != number ||
635 info.events >= events)
636 continue;
637
06c7f68e 638 if (d->disk.raid_disk > -1)
8382f19b
NB
639 sysfs_set_str(sra, d, "slot", "none");
640 if (sysfs_set_str(sra, d, "state", "remove") == 0)
641 if (verbose >= 0)
642 fprintf(stderr, Name
643 ": removing old device %s from %s\n",
06c7f68e 644 d->sys_name+4, array_name);
8382f19b
NB
645 }
646}
647
648static int count_active(struct supertype *st, int mdfd, char **availp,
649 struct mdinfo *bestinfo)
650{
651 /* count how many devices in sra think they are active */
06c7f68e 652 struct mdinfo *d;
8382f19b
NB
653 int cnt = 0, cnt1 = 0;
654 __u64 max_events = 0;
7e0f6979 655 struct mdinfo *sra = sysfs_read(mdfd, -1, GET_DEVS | GET_STATE);
8382f19b
NB
656 char *avail = NULL;
657
b526e52d
DW
658 if (!sra)
659 return 0;
660
8382f19b
NB
661 for (d = sra->devs ; d ; d = d->next) {
662 char dn[30];
663 int dfd;
8382f19b
NB
664 int ok;
665 struct mdinfo info;
666
06c7f68e 667 sprintf(dn, "%d:%d", d->disk.major, d->disk.minor);
8382f19b
NB
668 dfd = dev_open(dn, O_RDONLY);
669 if (dfd < 0)
670 continue;
3da92f27 671 ok = st->ss->load_super(st, dfd, NULL);
8382f19b
NB
672 close(dfd);
673 if (ok != 0)
674 continue;
a5d85af7 675 st->ss->getinfo_super(st, &info, NULL);
43aaf431
DL
676 if (!avail) {
677 avail = malloc(info.array.raid_disks);
678 if (!avail) {
679 fprintf(stderr, Name ": out of memory.\n");
680 exit(1);
681 }
682 memset(avail, 0, info.array.raid_disks);
683 *availp = avail;
684 }
685
8382f19b
NB
686 if (info.disk.state & (1<<MD_DISK_SYNC))
687 {
8382f19b
NB
688 if (cnt == 0) {
689 cnt++;
690 max_events = info.events;
691 avail[info.disk.raid_disk] = 2;
a5d85af7 692 st->ss->getinfo_super(st, bestinfo, NULL);
8382f19b
NB
693 } else if (info.events == max_events) {
694 cnt++;
695 avail[info.disk.raid_disk] = 2;
696 } else if (info.events == max_events-1) {
697 cnt1++;
698 avail[info.disk.raid_disk] = 1;
699 } else if (info.events < max_events - 1)
700 ;
701 else if (info.events == max_events+1) {
702 int i;
703 cnt1 = cnt;
704 cnt = 1;
705 max_events = info.events;
706 for (i=0; i<info.array.raid_disks; i++)
707 if (avail[i])
708 avail[i]--;
709 avail[info.disk.raid_disk] = 2;
a5d85af7 710 st->ss->getinfo_super(st, bestinfo, NULL);
8382f19b
NB
711 } else { /* info.events much bigger */
712 cnt = 1; cnt1 = 0;
713 memset(avail, 0, info.disk.raid_disk);
714 max_events = info.events;
1d1a9f87 715 avail[info.disk.raid_disk] = 2;
a5d85af7 716 st->ss->getinfo_super(st, bestinfo, NULL);
8382f19b
NB
717 }
718 }
3da92f27 719 st->ss->free_super(st);
8382f19b
NB
720 }
721 return cnt + cnt1;
722}
723
56e8be85
N
724static int array_try_spare(char *devname, int *dfdp, struct dev_policy *pol,
725 struct supertype *st, int verbose)
f08605b3
N
726{
727 /* This device doesn't have any md metadata
728 * If it is 'bare' and theh device policy allows 'spare' look for
729 * an array or container to attach it to.
730 * If st is set, then only arrays of that type are considered
731 * Return 0 on success, or some exit code on failure, probably 1.
732 */
733 int rv = -1;
f08605b3
N
734 struct stat stb;
735 struct map_ent *mp, *map = NULL;
736 struct mdinfo *chosen = NULL;
737 int dfd = *dfdp;
738
f08605b3
N
739 if (fstat(dfd, &stb) != 0)
740 return 1;
f08605b3 741
56e8be85 742 /*
f08605b3
N
743 * Now we need to find a suitable array to add this to.
744 * We only accept arrays that:
745 * - match 'st'
746 * - are in the same domains as the device
747 * - are of an size for which the device will be useful
748 * and we choose the one that is the most degraded
749 */
750
751 if (map_lock(&map)) {
752 fprintf(stderr, Name ": failed to get exclusive lock on "
753 "mapfile\n");
754 return 1;
755 }
756 for (mp = map ; mp ; mp = mp->next) {
757 struct supertype *st2;
758 struct domainlist *dl = NULL;
759 struct mdinfo *sra;
760 unsigned long long devsize;
761
762 if (is_subarray(mp->metadata))
763 continue;
764 if (st) {
765 st2 = st->ss->match_metadata_desc(mp->metadata);
766 if (!st2 ||
767 (st->minor_version >= 0 &&
768 st->minor_version != st2->minor_version)) {
769 if (verbose > 1)
770 fprintf(stderr, Name ": not adding %s to %s as metadata type doesn't match\n",
771 devname, mp->path);
772 free(st2);
773 continue;
774 }
775 free(st2);
776 }
777 sra = sysfs_read(-1, mp->devnum,
778 GET_DEVS|GET_OFFSET|GET_SIZE|GET_STATE|
779 GET_DEGRADED|GET_COMPONENT|GET_VERSION);
780 if (!sra) {
781 /* Probably a container - no degraded info */
782 sra = sysfs_read(-1, mp->devnum,
783 GET_DEVS|GET_OFFSET|GET_SIZE|GET_STATE|
784 GET_COMPONENT|GET_VERSION);
785 if (sra)
786 sra->array.failed_disks = 0;
787 }
788 if (!sra)
789 continue;
790 if (st == NULL) {
791 int i;
792 st2 = NULL;
793 for(i=0; !st2 && superlist[i]; i++)
794 st2 = superlist[i]->match_metadata_desc(
795 sra->text_version);
796 } else
797 st2 = st;
798 get_dev_size(dfd, NULL, &devsize);
799 if (st2->ss->avail_size(st2, devsize) < sra->component_size) {
800 if (verbose > 1)
801 fprintf(stderr, Name ": not adding %s to %s as it is too small\n",
802 devname, mp->path);
803 goto next;
804 }
805 dl = domain_from_array(sra, st2->ss->name);
806 if (!domain_test(dl, pol, st2->ss->name)) {
807 /* domain test fails */
808 if (verbose > 1)
809 fprintf(stderr, Name ": not adding %s to %s as it is not in a compatible domain\n",
810 devname, mp->path);
811
812 goto next;
813 }
814 /* all tests passed, OK to add to this array */
815 if (!chosen) {
816 chosen = sra;
817 sra = NULL;
818 } else if (chosen->array.failed_disks < sra->array.failed_disks) {
819 sysfs_free(chosen);
820 chosen = sra;
821 sra = NULL;
822 }
823 next:
824 if (sra)
825 sysfs_free(sra);
826 if (st != st2)
827 free(st2);
828 if (dl)
829 domain_free(dl);
830 }
831 if (chosen) {
832 /* add current device to chosen array as a spare */
833 int mdfd = open_dev(devname2devnum(chosen->sys_name));
834 if (mdfd >= 0) {
835 struct mddev_dev_s devlist;
836 char devname[20];
837 devlist.next = NULL;
838 devlist.used = 0;
839 devlist.re_add = 0;
840 devlist.writemostly = 0;
841 devlist.devname = devname;
842 sprintf(devname, "%d:%d", major(stb.st_rdev),
843 minor(stb.st_rdev));
844 devlist.disposition = 'a';
845 close(dfd);
846 *dfdp = -1;
847 rv = Manage_subdevs(chosen->sys_name, mdfd, &devlist,
848 -1, 0);
849 close(mdfd);
850 }
851 if (verbose > 0) {
852 if (rv == 0)
853 fprintf(stderr, Name ": added %s as spare for %s\n",
854 devname, chosen->sys_name);
855 else
856 fprintf(stderr, Name ": failed to add %s as spare for %s\n",
857 devname, chosen->sys_name);
858 }
859 sysfs_free(chosen);
860 }
861 return rv ? 0 : 1;
862}
863
56e8be85
N
864static int partition_try_spare(char *devname, int *dfdp, struct dev_policy *pol,
865 struct supertype *st, int verbose)
866{
61018da0
N
867 /* we know that at least one partition virtual-metadata is
868 * allowed to incorporate spares like this device. We need to
869 * find a suitable device to copy partition information from.
870 *
871 * Getting a list of all disk (not partition) devices is
872 * slightly non-trivial. We could look at /sys/block, but
873 * that is theoretically due to be removed. Maybe best to use
874 * /dev/disk/by-path/?* and ignore names ending '-partNN' as
875 * we depend on this directory of 'path' info. But that fails
876 * to find loop devices and probably others. Maybe don't
877 * worry about that, they aren't the real target.
878 *
879 * So: check things in /dev/disk/by-path to see if they are in
880 * a compatible domain, then load the partition table and see
881 * if it is OK for the new device, and choose the largest
882 * partition table that fits.
883 */
884 DIR *dir;
885 struct dirent *de;
886 char *chosen = NULL;
887 unsigned long long chosen_size;
888 struct supertype *chosen_st = NULL;
889 int fd;
890
891 dir = opendir("/dev/disk/by-path");
892 if (!dir)
893 return 1;
894 while ((de = readdir(dir)) != NULL) {
895 char *ep;
896 struct dev_policy *pol2 = NULL;
897 struct domainlist *domlist = NULL;
898 int fd = -1;
899 struct mdinfo info;
900 struct supertype *st2 = NULL;
901 char *devname = NULL;
902 unsigned long long devsectors;
903
904 if (de->d_ino == 0 ||
905 de->d_name[0] == '.' ||
906 (de->d_type != DT_LNK && de->d_type != DT_UNKNOWN))
907 goto next;
908
909 ep = de->d_name + strlen(de->d_name);
910 while (ep > de->d_name &&
911 isdigit(ep[-1]))
912 ep--;
913 if (ep > de->d_name + 5 &&
914 strncmp(ep-5, "-part", 5) == 0)
915 /* This is a partition - skip it */
916 goto next;
917
918 pol2 = path_policy(de->d_name, type_disk);
919
920 domain_merge(&domlist, pol2, st ? st->ss->name : NULL);
921 if (domain_test(domlist, pol, st ? st->ss->name : NULL) == 0)
922 /* new device is incompatible with this device. */
923 goto next;
924
925 domain_free(domlist);
926 domlist = NULL;
927
928 asprintf(&devname, "/dev/disk/by-path/%s", de->d_name);
929 fd = open(devname, O_RDONLY);
930 if (fd < 0)
931 goto next;
932 if (get_dev_size(fd, devname, &devsectors) == 0)
933 goto next;
934 devsectors >>= 9;
935
936 if (st)
937 st2 = dup_super(st);
938 else
939 st2 = guess_super_type(fd, guess_partitions);
940 if (st2 == NULL ||
941 st2->ss->load_super(st2, fd, NULL) < 0)
942 goto next;
943
944 if (!st) {
945 /* Check domain policy again, this time referring to metadata */
946 domain_merge(&domlist, pol2, st2->ss->name);
947 if (domain_test(domlist, pol, st2->ss->name) == 0)
948 /* Incompatible devices for this metadata type */
949 goto next;
950 }
951
a5d85af7 952 st2->ss->getinfo_super(st2, &info, NULL);
61018da0
N
953 if (info.component_size > devsectors)
954 /* This partitioning doesn't fit in the device */
955 goto next;
956
957 /* This is an acceptable device to copy partition
958 * metadata from. We could just stop here, but I
959 * think I want to keep looking incase a larger
960 * metadata which makes better use of the device can
961 * be found.
962 */
963 if (chosen == NULL ||
964 chosen_size < info.component_size) {
965 chosen_size = info.component_size;
966 free(chosen);
967 chosen = devname;
968 devname = NULL;
969 if (chosen_st) {
970 chosen_st->ss->free_super(chosen_st);
971 free(chosen_st);
972 }
973 chosen_st = st2;
974 st2 = NULL;
975 }
976
977 next:
978 free(devname);
979 domain_free(domlist);
980 dev_policy_free(pol2);
981 if (st2)
982 st2->ss->free_super(st2);
983 free(st2);
984
985 if (fd >= 0)
986 close(fd);
987 }
988
989 if (!chosen)
990 return 1;
991
992 /* 'chosen' is the best device we can find. Let's write its
993 * metadata to devname dfd is read-only so don't use that
994 */
995 fd = open(devname, O_RDWR);
996 if (fd >= 0) {
997 chosen_st->ss->store_super(chosen_st, fd);
998 close(fd);
999 }
1000 free(chosen);
1001 chosen_st->ss->free_super(chosen_st);
1002 free(chosen_st);
1003 return 0;
56e8be85
N
1004}
1005
1006
1007/* adding a spare to a regular array is quite different from adding one to
1008 * a set-of-partitions virtual array.
1009 * This function determines which is worth trying and tries as appropriate.
1010 * Arrays are given priority over partitions.
1011 */
1012static int try_spare(char *devname, int *dfdp, struct dev_policy *pol,
1013 struct supertype *st, int verbose)
1014{
1015 int i;
1016 int rv;
1017 int arrays_ok = 0;
1018 int partitions_ok = 0;
1019 char bufpad[4096 + 4096];
1020 char *buf = (char*)(((long)bufpad + 4096) & ~4095);
1021 int dfd = *dfdp;
1022
1023 /* Can only add a spare if device has at least one domains */
1024 if (pol_find(pol, pol_domain) == NULL)
1025 return 1;
1026 /* And only if some action allows spares */
1027 if (!policy_action_allows(pol, st?st->ss->name:NULL, act_spare))
1028 return 1;
1029
1030 /* Now check if the device is bare - we don't add non-bare devices
1031 * yet even if action=-spare
1032 */
1033
1034 if (lseek(dfd, 0, SEEK_SET) != 0 ||
1035 read(dfd, buf, 4096) != 4096) {
1036 not_bare:
1037 if (verbose > 1)
1038 fprintf(stderr, Name ": %s is not bare, so not considering as a spare\n",
1039 devname);
1040 return 1;
1041 }
1042 if (buf[0] != '\0' && buf[0] != '\x5a' && buf[0] != '\xff')
1043 goto not_bare;
1044 if (memcmp(buf, buf+1, 4095) != 0)
1045 goto not_bare;
1046
1047 /* OK, first 4K appear blank, try the end. */
1048 if (lseek(dfd, -4096, SEEK_END) < 0 ||
1049 read(dfd, buf, 4096) != 4096)
1050 goto not_bare;
1051
1052 if (buf[0] != '\0' && buf[0] != '\x5a' && buf[0] != '\xff')
1053 goto not_bare;
1054 if (memcmp(buf, buf+1, 4095) != 0)
1055 goto not_bare;
1056
1057 /* This device passes our test for 'is bare'.
1058 * Let's see what policy allows for such things.
1059 */
1060 if (st) {
1061 /* just try try 'array' or 'partition' based on this metadata */
1062 if (st->ss->add_to_super)
1063 return array_try_spare(devname, dfdp, pol,
1064 st, verbose);
1065 else
1066 return partition_try_spare(devname, dfdp, pol,
1067 st, verbose);
1068 }
1069 /* Now see which metadata type support spare */
1070 for (i = 0; (!arrays_ok || !partitions_ok) && superlist[i] ; i++) {
1071 if (superlist[i]->add_to_super && !arrays_ok &&
1072 policy_action_allows(pol, superlist[i]->name, act_spare))
1073 arrays_ok = 1;
1074 if (superlist[i]->add_to_super == NULL && !partitions_ok &&
1075 policy_action_allows(pol, superlist[i]->name, act_spare))
1076 partitions_ok = 1;
1077 }
1078 rv = 0;
1079 if (arrays_ok)
1080 rv = array_try_spare(devname, dfdp, pol, st, verbose);
1081 if (rv == 0 && partitions_ok)
1082 rv = partition_try_spare(devname, dfdp, pol, st, verbose);
1083 return rv;
1084}
1085
8382f19b
NB
1086int IncrementalScan(int verbose)
1087{
1088 /* look at every device listed in the 'map' file.
1089 * If one is found that is not running then:
1090 * look in mdadm.conf for bitmap file.
1091 * if one exists, but array has none, add it.
1092 * try to start array in auto-readonly mode
1093 */
1094 struct map_ent *mapl = NULL;
1095 struct map_ent *me;
1096 mddev_ident_t devs, mddev;
1097 int rv = 0;
1098
1099 map_read(&mapl);
1100 devs = conf_get_ident(NULL);
1101
1102 for (me = mapl ; me ; me = me->next) {
8382f19b
NB
1103 mdu_array_info_t array;
1104 mdu_bitmap_file_t bmf;
7e0f6979 1105 struct mdinfo *sra;
339c2d6c 1106 int mdfd = open_dev(me->devnum);
215bb3f7 1107
8382f19b
NB
1108 if (mdfd < 0)
1109 continue;
1110 if (ioctl(mdfd, GET_ARRAY_INFO, &array) == 0 ||
1111 errno != ENODEV) {
1112 close(mdfd);
1113 continue;
1114 }
1115 /* Ok, we can try this one. Maybe it needs a bitmap */
1116 for (mddev = devs ; mddev ; mddev = mddev->next)
339c2d6c 1117 if (mddev->devname && me->path
2400e6eb 1118 && devname_matches(mddev->devname, me->path))
8382f19b
NB
1119 break;
1120 if (mddev && mddev->bitmap_file) {
1121 /*
1122 * Note: early kernels will wrongly fail this, so it
1123 * is a hint only
1124 */
1125 int added = -1;
1126 if (ioctl(mdfd, GET_ARRAY_INFO, &bmf) < 0) {
1127 int bmfd = open(mddev->bitmap_file, O_RDWR);
1128 if (bmfd >= 0) {
1129 added = ioctl(mdfd, SET_BITMAP_FILE,
1130 bmfd);
1131 close(bmfd);
1132 }
1133 }
1134 if (verbose >= 0) {
1135 if (added == 0)
1136 fprintf(stderr, Name
1137 ": Added bitmap %s to %s\n",
1138 mddev->bitmap_file, me->path);
1139 else if (errno != EEXIST)
1140 fprintf(stderr, Name
1141 ": Failed to add bitmap to %s: %s\n",
1142 me->path, strerror(errno));
1143 }
1144 }
1145 sra = sysfs_read(mdfd, 0, 0);
1146 if (sra) {
1147 if (sysfs_set_str(sra, NULL,
1148 "array_state", "read-auto") == 0) {
1149 if (verbose >= 0)
1150 fprintf(stderr, Name
1151 ": started array %s\n",
339c2d6c 1152 me->path ?: devnum2devname(me->devnum));
8382f19b
NB
1153 } else {
1154 fprintf(stderr, Name
1155 ": failed to start array %s: %s\n",
339c2d6c
N
1156 me->path ?: devnum2devname(me->devnum),
1157 strerror(errno));
8382f19b
NB
1158 rv = 1;
1159 }
1160 }
1161 }
1162 return rv;
1163}
598f0d58 1164
1771a6e2
N
1165static char *container2devname(char *devname)
1166{
1167 char *mdname = NULL;
1168
1169 if (devname[0] == '/') {
1170 int fd = open(devname, O_RDONLY);
1171 if (fd >= 0) {
1172 mdname = devnum2devname(fd2devnum(fd));
1173 close(fd);
1174 }
1175 } else {
1176 int uuid[4];
1177 struct map_ent *mp, *map = NULL;
1178
1179 if (!parse_uuid(devname, uuid))
1180 return mdname;
1181 mp = map_by_uuid(&map, uuid);
1182 if (mp)
1183 mdname = devnum2devname(mp->devnum);
1184 map_free(map);
1185 }
1186
1187 return mdname;
1188}
1189
7d91c3f5
N
1190static int Incremental_container(struct supertype *st, char *devname, int verbose,
1191 int runstop, int autof, int trustworthy)
598f0d58
NB
1192{
1193 /* Collect the contents of this container and for each
1194 * array, choose a device name and assemble the array.
1195 */
1196
00bbdbda 1197 struct mdinfo *list = st->ss->container_content(st, NULL);
598f0d58 1198 struct mdinfo *ra;
ad5bc697
N
1199 struct map_ent *map = NULL;
1200
93c861ee
DL
1201 if (map_lock(&map))
1202 fprintf(stderr, Name ": failed to get exclusive lock on "
1203 "mapfile\n");
598f0d58
NB
1204
1205 for (ra = list ; ra ; ra = ra->next) {
598f0d58
NB
1206 int mdfd;
1207 char chosen_name[1024];
ad5bc697 1208 struct map_ent *mp;
dbb44303 1209 struct mddev_ident_s *match = NULL;
598f0d58 1210
c5afc314 1211 mp = map_by_uuid(&map, ra->uuid);
d7288ddc 1212
30926600
N
1213 if (mp) {
1214 mdfd = open_dev(mp->devnum);
339c2d6c
N
1215 if (mp->path)
1216 strcpy(chosen_name, mp->path);
1217 else
1218 strcpy(chosen_name, devnum2devname(mp->devnum));
30926600 1219 } else {
dbb44303 1220
112cace6 1221 /* Check in mdadm.conf for container == devname and
dbb44303
N
1222 * member == ra->text_version after second slash.
1223 */
1224 char *sub = strchr(ra->text_version+1, '/');
1225 struct mddev_ident_s *array_list;
1226 if (sub) {
1227 sub++;
1228 array_list = conf_get_ident(NULL);
1229 } else
1230 array_list = NULL;
1231 for(; array_list ; array_list = array_list->next) {
dbb44303
N
1232 char *dn;
1233 if (array_list->member == NULL ||
1234 array_list->container == NULL)
1235 continue;
1236 if (strcmp(array_list->member, sub) != 0)
1237 continue;
71d60c48
DW
1238 if (array_list->uuid_set &&
1239 !same_uuid(ra->uuid, array_list->uuid, st->ss->swapuuid))
1240 continue;
1771a6e2
N
1241 dn = container2devname(array_list->container);
1242 if (dn == NULL)
dbb44303 1243 continue;
dbb44303
N
1244 if (strncmp(dn, ra->text_version+1,
1245 strlen(dn)) != 0 ||
1246 ra->text_version[strlen(dn)+1] != '/') {
1247 free(dn);
1248 continue;
1249 }
1250 free(dn);
1251 /* we have a match */
1252 match = array_list;
71d60c48
DW
1253 if (verbose>0)
1254 fprintf(stderr, Name ": match found for member %s\n",
1255 array_list->member);
dbb44303
N
1256 break;
1257 }
dbb44303 1258
112cace6
N
1259 if (match && match->devname &&
1260 strcasecmp(match->devname, "<ignore>") == 0) {
1261 if (verbose > 0)
1262 fprintf(stderr, Name ": array %s/%s is "
1263 "explicitly ignored by mdadm.conf\n",
1264 match->container, match->member);
1265 return 2;
1266 }
05833051
N
1267 if (match)
1268 trustworthy = LOCAL;
112cace6 1269
30926600
N
1270 mdfd = create_mddev(match ? match->devname : NULL,
1271 ra->name,
1272 autof,
1273 trustworthy,
1274 chosen_name);
1275 }
598f0d58
NB
1276
1277 if (mdfd < 0) {
1278 fprintf(stderr, Name ": failed to open %s: %s.\n",
1279 chosen_name, strerror(errno));
1280 return 2;
1281 }
1282
03b7f6c6
N
1283 assemble_container_content(st, mdfd, ra, runstop,
1284 chosen_name, verbose);
598f0d58 1285 }
ad5bc697 1286 map_unlock(&map);
598f0d58
NB
1287 return 0;
1288}
29ba4804
N
1289
1290/*
1291 * IncrementalRemove - Attempt to see if the passed in device belongs to any
1292 * raid arrays, and if so first fail (if needed) and then remove the device.
1293 *
1294 * @devname - The device we want to remove
1295 *
1296 * Note: the device name must be a kernel name like "sda", so
1297 * that we can find it in /proc/mdstat
1298 */
1299int IncrementalRemove(char *devname, int verbose)
1300{
1301 int mdfd;
aae3cdc3 1302 int rv;
29ba4804
N
1303 struct mdstat_ent *ent;
1304 struct mddev_dev_s devlist;
1305
1306 if (strchr(devname, '/')) {
1307 fprintf(stderr, Name ": incremental removal requires a "
1308 "kernel device name, not a file: %s\n", devname);
1309 return 1;
1310 }
1311 ent = mdstat_by_component(devname);
1312 if (!ent) {
1313 fprintf(stderr, Name ": %s does not appear to be a component "
1314 "of any array\n", devname);
1315 return 1;
1316 }
1317 mdfd = open_dev(ent->devnum);
1318 if (mdfd < 0) {
1319 fprintf(stderr, Name ": Cannot open array %s!!\n", ent->dev);
1320 return 1;
1321 }
1322 memset(&devlist, 0, sizeof(devlist));
1323 devlist.devname = devname;
1324 devlist.disposition = 'f';
7d2e6486 1325 Manage_subdevs(ent->dev, mdfd, &devlist, verbose, 0);
29ba4804 1326 devlist.disposition = 'r';
aae3cdc3
PC
1327 rv = Manage_subdevs(ent->dev, mdfd, &devlist, verbose, 0);
1328 close(mdfd);
1329 return rv;
29ba4804 1330}