]> git.ipfire.org Git - thirdparty/mdadm.git/blob - Incremental.c
Allow --incremental to add a device as a spare if policy allows.
[thirdparty/mdadm.git] / Incremental.c
1 /*
2 * Incremental.c - support --incremental. Part of:
3 * mdadm - manage Linux "md" devices aka RAID arrays.
4 *
5 * Copyright (C) 2006-2009 Neil Brown <neilb@suse.de>
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"
32
33 static int count_active(struct supertype *st, int mdfd, char **availp,
34 struct mdinfo *info);
35 static void find_reject(int mdfd, struct supertype *st, struct mdinfo *sra,
36 int number, __u64 events, int verbose,
37 char *array_name);
38 static int try_spare(char *devname, int *dfdp, struct dev_policy *pol,
39 struct supertype *st, int verbose);
40
41 int Incremental(char *devname, int verbose, int runstop,
42 struct supertype *st, char *homehost, int require_homehost,
43 int autof)
44 {
45 /* Add this device to an array, creating the array if necessary
46 * and starting the array if sensible or - if runstop>0 - if possible.
47 *
48 * This has several steps:
49 *
50 * 1/ Check if device is permitted by mdadm.conf, reject if not.
51 * 2/ Find metadata, reject if none appropriate (check
52 * version/name from args)
53 * 3/ Check if there is a match in mdadm.conf
54 * 3a/ if not, check for homehost match. If no match, assemble as
55 * a 'foreign' array.
56 * 4/ Determine device number.
57 * - If in mdadm.conf with std name, use that
58 * - UUID in /var/run/mdadm.map use that
59 * - If name is suggestive, use that. unless in use with different uuid.
60 * - Choose a free, high number.
61 * - Use a partitioned device unless strong suggestion not to.
62 * e.g. auto=md
63 * Don't choose partitioned for containers.
64 * 5/ Find out if array already exists
65 * 5a/ if it does not
66 * - choose a name, from mdadm.conf or 'name' field in array.
67 * - create the array
68 * - add the device
69 * 5b/ if it does
70 * - check one drive in array to make sure metadata is a reasonably
71 * close match. Reject if not (e.g. different type)
72 * - add the device
73 * 6/ Make sure /var/run/mdadm.map contains this array.
74 * 7/ Is there enough devices to possibly start the array?
75 * For a container, this means running Incremental_container.
76 * 7a/ if not, finish with success.
77 * 7b/ if yes,
78 * - read all metadata and arrange devices like -A does
79 * - if number of OK devices match expected, or -R and there are enough,
80 * start the array (auto-readonly).
81 */
82 struct stat stb;
83 struct mdinfo info, dinfo;
84 struct mddev_ident_s *array_list, *match;
85 char chosen_name[1024];
86 int rv = 1;
87 struct map_ent *mp, *map = NULL;
88 int dfd = -1, mdfd = -1;
89 char *avail;
90 int active_disks;
91 int trustworthy = FOREIGN;
92 char *name_to_use;
93 mdu_array_info_t ainf;
94 struct dev_policy *policy = NULL;
95
96 struct createinfo *ci = conf_get_create_info();
97
98
99 /* 1/ Check if device is permitted by mdadm.conf */
100
101 if (!conf_test_dev(devname)) {
102 if (verbose >= 0)
103 fprintf(stderr, Name
104 ": %s not permitted by mdadm.conf.\n",
105 devname);
106 goto out;
107 }
108
109 /* 2/ Find metadata, reject if none appropriate (check
110 * version/name from args) */
111
112 dfd = dev_open(devname, O_RDONLY|O_EXCL);
113 if (dfd < 0) {
114 if (verbose >= 0)
115 fprintf(stderr, Name ": cannot open %s: %s.\n",
116 devname, strerror(errno));
117 goto out;
118 }
119 if (fstat(dfd, &stb) < 0) {
120 if (verbose >= 0)
121 fprintf(stderr, Name ": fstat failed for %s: %s.\n",
122 devname, strerror(errno));
123 goto out;
124 }
125 if ((stb.st_mode & S_IFMT) != S_IFBLK) {
126 if (verbose >= 0)
127 fprintf(stderr, Name ": %s is not a block device.\n",
128 devname);
129 goto out;
130 }
131
132 dinfo.disk.major = major(stb.st_rdev);
133 dinfo.disk.minor = minor(stb.st_rdev);
134
135 policy = disk_policy(&dinfo);
136
137 if (st == NULL && (st = guess_super(dfd)) == NULL) {
138 if (verbose >= 0)
139 fprintf(stderr, Name
140 ": no recognisable superblock on %s.\n",
141 devname);
142 rv = try_spare(devname, &dfd, policy, st, verbose);
143 goto out;
144 }
145 if (st->ss->load_super(st, dfd, NULL)) {
146 if (verbose >= 0)
147 fprintf(stderr, Name ": no RAID superblock on %s.\n",
148 devname);
149 rv = try_spare(devname, &dfd, policy, st, verbose);
150 goto out;
151 }
152 close (dfd); dfd = -1;
153
154 memset(&info, 0, sizeof(info));
155 st->ss->getinfo_super(st, &info);
156 /* 3/ Check if there is a match in mdadm.conf */
157
158 array_list = conf_get_ident(NULL);
159 match = NULL;
160 for (; array_list; array_list = array_list->next) {
161 if (array_list->uuid_set &&
162 same_uuid(array_list->uuid, info.uuid, st->ss->swapuuid)
163 == 0) {
164 if (verbose >= 2 && array_list->devname)
165 fprintf(stderr, Name
166 ": UUID differs from %s.\n",
167 array_list->devname);
168 continue;
169 }
170 if (array_list->name[0] &&
171 strcasecmp(array_list->name, info.name) != 0) {
172 if (verbose >= 2 && array_list->devname)
173 fprintf(stderr, Name
174 ": Name differs from %s.\n",
175 array_list->devname);
176 continue;
177 }
178 if (array_list->devices &&
179 !match_oneof(array_list->devices, devname)) {
180 if (verbose >= 2 && array_list->devname)
181 fprintf(stderr, Name
182 ": Not a listed device for %s.\n",
183 array_list->devname);
184 continue;
185 }
186 if (array_list->super_minor != UnSet &&
187 array_list->super_minor != info.array.md_minor) {
188 if (verbose >= 2 && array_list->devname)
189 fprintf(stderr, Name
190 ": Different super-minor to %s.\n",
191 array_list->devname);
192 continue;
193 }
194 if (!array_list->uuid_set &&
195 !array_list->name[0] &&
196 !array_list->devices &&
197 array_list->super_minor == UnSet) {
198 if (verbose >= 2 && array_list->devname)
199 fprintf(stderr, Name
200 ": %s doesn't have any identifying information.\n",
201 array_list->devname);
202 continue;
203 }
204 /* FIXME, should I check raid_disks and level too?? */
205
206 if (match) {
207 if (verbose >= 0) {
208 if (match->devname && array_list->devname)
209 fprintf(stderr, Name
210 ": we match both %s and %s - cannot decide which to use.\n",
211 match->devname, array_list->devname);
212 else
213 fprintf(stderr, Name
214 ": multiple lines in mdadm.conf match\n");
215 }
216 rv = 2;
217 goto out;
218 }
219 match = array_list;
220 }
221
222 if (match && match->devname
223 && strcasecmp(match->devname, "<ignore>") == 0) {
224 if (verbose >= 0)
225 fprintf(stderr, Name ": array containing %s is explicitly"
226 " ignored by mdadm.conf\n",
227 devname);
228 goto out;
229 }
230
231 /* 3a/ if not, check for homehost match. If no match, continue
232 * but don't trust the 'name' in the array. Thus a 'random' minor
233 * number will be assigned, and the device name will be based
234 * on that. */
235 if (match)
236 trustworthy = LOCAL;
237 else if (st->ss->match_home(st, homehost) == 1)
238 trustworthy = LOCAL;
239 else if (st->ss->match_home(st, "any") == 1)
240 trustworthy = LOCAL_ANY;
241 else
242 trustworthy = FOREIGN;
243
244
245 if (!match && !conf_test_metadata(st->ss->name,
246 (trustworthy == LOCAL))) {
247 if (verbose >= 1)
248 fprintf(stderr, Name
249 ": %s has metadata type %s for which "
250 "auto-assembly is disabled\n",
251 devname, st->ss->name);
252 goto out;
253 }
254 if (trustworthy == LOCAL_ANY)
255 trustworthy = LOCAL;
256
257 /* There are three possible sources for 'autof': command line,
258 * ARRAY line in mdadm.conf, or CREATE line in mdadm.conf.
259 * ARRAY takes precedence, then command line, then
260 * CREATE.
261 */
262 if (match && match->autof)
263 autof = match->autof;
264 if (autof == 0)
265 autof = ci->autof;
266
267 if (st->ss->container_content && st->loaded_container) {
268 if ((runstop > 0 && info.container_enough >= 0) ||
269 info.container_enough > 0)
270 /* pass */;
271 else {
272 if (verbose)
273 fprintf(stderr, Name ": not enough devices to start the container\n");
274 rv = 0;
275 goto out;
276 }
277
278 /* This is a pre-built container array, so we do something
279 * rather different.
280 */
281 rv = Incremental_container(st, devname, verbose, runstop,
282 autof, trustworthy);
283 goto out;
284 }
285
286 name_to_use = info.name;
287 if (name_to_use[0] == 0 &&
288 info.array.level == LEVEL_CONTAINER &&
289 trustworthy == LOCAL) {
290 name_to_use = info.text_version;
291 trustworthy = METADATA;
292 }
293 if (name_to_use[0] && trustworthy != LOCAL &&
294 ! require_homehost &&
295 conf_name_is_free(name_to_use))
296 trustworthy = LOCAL;
297
298 /* strip "hostname:" prefix from name if we have decided
299 * to treat it as LOCAL
300 */
301 if (trustworthy == LOCAL && strchr(name_to_use, ':') != NULL)
302 name_to_use = strchr(name_to_use, ':')+1;
303
304 /* 4/ Check if array exists.
305 */
306 if (map_lock(&map))
307 fprintf(stderr, Name ": failed to get exclusive lock on "
308 "mapfile\n");
309 mp = map_by_uuid(&map, info.uuid);
310 if (mp)
311 mdfd = open_dev(mp->devnum);
312 else
313 mdfd = -1;
314
315 if (mdfd < 0) {
316 struct mdinfo *sra;
317
318 /* Couldn't find an existing array, maybe make a new one */
319 mdfd = create_mddev(match ? match->devname : NULL,
320 name_to_use, autof, trustworthy, chosen_name);
321
322 if (mdfd < 0)
323 goto out;
324
325 sysfs_init(&info, mdfd, 0);
326
327 if (set_array_info(mdfd, st, &info) != 0) {
328 fprintf(stderr, Name ": failed to set array info for %s: %s\n",
329 chosen_name, strerror(errno));
330 rv = 2;
331 goto out;
332 }
333
334 dinfo = info;
335 dinfo.disk.major = major(stb.st_rdev);
336 dinfo.disk.minor = minor(stb.st_rdev);
337 if (add_disk(mdfd, st, &info, &dinfo) != 0) {
338 fprintf(stderr, Name ": failed to add %s to %s: %s.\n",
339 devname, chosen_name, strerror(errno));
340 ioctl(mdfd, STOP_ARRAY, 0);
341 rv = 2;
342 goto out;
343 }
344 sra = sysfs_read(mdfd, fd2devnum(mdfd), GET_DEVS);
345 if (!sra || !sra->devs || sra->devs->disk.raid_disk >= 0) {
346 /* It really should be 'none' - must be old buggy
347 * kernel, and mdadm -I may not be able to complete.
348 * So reject it.
349 */
350 ioctl(mdfd, STOP_ARRAY, NULL);
351 fprintf(stderr, Name
352 ": You have an old buggy kernel which cannot support\n"
353 " --incremental reliably. Aborting.\n");
354 sysfs_free(sra);
355 rv = 2;
356 goto out;
357 }
358 info.array.working_disks = 1;
359 sysfs_free(sra);
360 /* 6/ Make sure /var/run/mdadm.map contains this array. */
361 map_update(&map, fd2devnum(mdfd),
362 info.text_version,
363 info.uuid, chosen_name);
364 } else {
365 /* 5b/ if it does */
366 /* - check one drive in array to make sure metadata is a reasonably */
367 /* close match. Reject if not (e.g. different type) */
368 /* - add the device */
369 char dn[20];
370 int dfd2;
371 int err;
372 struct mdinfo *sra;
373 struct supertype *st2;
374 struct mdinfo info2, *d;
375
376 if (mp->path)
377 strcpy(chosen_name, mp->path);
378 else
379 strcpy(chosen_name, devnum2devname(mp->devnum));
380
381 /* It is generally not OK to add non-spare drives to a
382 * running array as they are probably missing because
383 * they failed. However if runstop is 1, then the
384 * array was possibly started early and our best bet is
385 * to add this anyway.
386 * Also if action policy is re-add or better we allow
387 * re-add
388 */
389 if ((info.disk.state & (1<<MD_DISK_SYNC)) != 0
390 && ! policy_action_allows(policy, st->ss->name,
391 act_re_add)
392 && runstop < 1) {
393 int active = 0;
394
395 if (st->ss->external) {
396 char *devname = devnum2devname(fd2devnum(mdfd));
397
398 active = devname && is_container_active(devname);
399 free(devname);
400 } else if (ioctl(mdfd, GET_ARRAY_INFO, &ainf) == 0)
401 active = 1;
402 if (active) {
403 fprintf(stderr, Name
404 ": not adding %s to active array (without --run) %s\n",
405 devname, chosen_name);
406 rv = 2;
407 goto out;
408 }
409 }
410 sra = sysfs_read(mdfd, fd2devnum(mdfd), (GET_DEVS | GET_STATE));
411 if (!sra) {
412 rv = 2;
413 goto out;
414 }
415 if (sra->devs) {
416 sprintf(dn, "%d:%d", sra->devs->disk.major,
417 sra->devs->disk.minor);
418 dfd2 = dev_open(dn, O_RDONLY);
419 st2 = dup_super(st);
420 if (st2->ss->load_super(st2, dfd2, NULL) ||
421 st->ss->compare_super(st, st2) != 0) {
422 fprintf(stderr, Name
423 ": metadata mismatch between %s and "
424 "chosen array %s\n",
425 devname, chosen_name);
426 close(dfd2);
427 rv = 2;
428 goto out;
429 }
430 close(dfd2);
431 memset(&info2, 0, sizeof(info2));
432 st2->ss->getinfo_super(st2, &info2);
433 st2->ss->free_super(st2);
434 if (info.array.level != info2.array.level ||
435 memcmp(info.uuid, info2.uuid, 16) != 0 ||
436 info.array.raid_disks != info2.array.raid_disks) {
437 fprintf(stderr, Name
438 ": unexpected difference between %s and %s.\n",
439 chosen_name, devname);
440 rv = 2;
441 goto out;
442 }
443 }
444 info2.disk.major = major(stb.st_rdev);
445 info2.disk.minor = minor(stb.st_rdev);
446 /* add disk needs to know about containers */
447 if (st->ss->external)
448 sra->array.level = LEVEL_CONTAINER;
449 err = add_disk(mdfd, st, sra, &info2);
450 if (err < 0 && errno == EBUSY) {
451 /* could be another device present with the same
452 * disk.number. Find and reject any such
453 */
454 find_reject(mdfd, st, sra, info.disk.number,
455 info.events, verbose, chosen_name);
456 err = add_disk(mdfd, st, sra, &info2);
457 }
458 if (err < 0) {
459 fprintf(stderr, Name ": failed to add %s to %s: %s.\n",
460 devname, chosen_name, strerror(errno));
461 rv = 2;
462 goto out;
463 }
464 info.array.working_disks = 0;
465 for (d = sra->devs; d; d=d->next)
466 info.array.working_disks ++;
467
468 }
469
470 /* 7/ Is there enough devices to possibly start the array? */
471 /* 7a/ if not, finish with success. */
472 if (info.array.level == LEVEL_CONTAINER) {
473 /* Try to assemble within the container */
474 map_unlock(&map);
475 sysfs_uevent(&info, "change");
476 if (verbose >= 0)
477 fprintf(stderr, Name
478 ": container %s now has %d devices\n",
479 chosen_name, info.array.working_disks);
480 wait_for(chosen_name, mdfd);
481 close(mdfd);
482 rv = Incremental(chosen_name, verbose, runstop,
483 NULL, homehost, require_homehost, autof);
484 if (rv == 1)
485 /* Don't fail the whole -I if a subarray didn't
486 * have enough devices to start yet
487 */
488 rv = 0;
489 return rv;
490 }
491 avail = NULL;
492 active_disks = count_active(st, mdfd, &avail, &info);
493 if (enough(info.array.level, info.array.raid_disks,
494 info.array.layout, info.array.state & 1,
495 avail, active_disks) == 0) {
496 free(avail);
497 if (verbose >= 0)
498 fprintf(stderr, Name
499 ": %s attached to %s, not enough to start (%d).\n",
500 devname, chosen_name, active_disks);
501 map_unlock(&map);
502 rv = 0;
503 goto out;
504 }
505 free(avail);
506
507 /* 7b/ if yes, */
508 /* - if number of OK devices match expected, or -R and there */
509 /* are enough, */
510 /* + add any bitmap file */
511 /* + start the array (auto-readonly). */
512
513 if (ioctl(mdfd, GET_ARRAY_INFO, &ainf) == 0) {
514 if (verbose >= 0)
515 fprintf(stderr, Name
516 ": %s attached to %s which is already active.\n",
517 devname, chosen_name);
518 map_unlock(&map);
519 rv = 0;
520 goto out;
521 }
522
523 map_unlock(&map);
524 if (runstop > 0 || active_disks >= info.array.working_disks) {
525 struct mdinfo *sra, *dsk;
526 /* Let's try to start it */
527 if (match && match->bitmap_file) {
528 int bmfd = open(match->bitmap_file, O_RDWR);
529 if (bmfd < 0) {
530 fprintf(stderr, Name
531 ": Could not open bitmap file %s.\n",
532 match->bitmap_file);
533 goto out;
534 }
535 if (ioctl(mdfd, SET_BITMAP_FILE, bmfd) != 0) {
536 close(bmfd);
537 fprintf(stderr, Name
538 ": Failed to set bitmapfile for %s.\n",
539 chosen_name);
540 goto out;
541 }
542 close(bmfd);
543 }
544 /* GET_* needed so add_disk works below */
545 sra = sysfs_read(mdfd, fd2devnum(mdfd),
546 GET_DEVS|GET_OFFSET|GET_SIZE|GET_STATE);
547 if ((sra == NULL || active_disks >= info.array.working_disks)
548 && trustworthy != FOREIGN)
549 rv = ioctl(mdfd, RUN_ARRAY, NULL);
550 else
551 rv = sysfs_set_str(sra, NULL,
552 "array_state", "read-auto");
553 if (rv == 0) {
554 if (verbose >= 0)
555 fprintf(stderr, Name
556 ": %s attached to %s, which has been started.\n",
557 devname, chosen_name);
558 rv = 0;
559 wait_for(chosen_name, mdfd);
560 /* We just started the array, so some devices
561 * might have been evicted from the array
562 * because their event counts were too old.
563 * If the action=re-add policy is in-force for
564 * those devices we should re-add them now.
565 */
566 for (dsk = sra->devs; dsk ; dsk = dsk->next) {
567 if (disk_action_allows(dsk, st->ss->name, act_re_add) &&
568 add_disk(mdfd, st, sra, dsk) == 0)
569 fprintf(stderr, Name
570 ": %s re-added to %s\n",
571 dsk->sys_name, chosen_name);
572 }
573 } else {
574 fprintf(stderr, Name
575 ": %s attached to %s, but failed to start: %s.\n",
576 devname, chosen_name, strerror(errno));
577 rv = 1;
578 }
579 } else {
580 if (verbose >= 0)
581 fprintf(stderr, Name
582 ": %s attached to %s, not enough to start safely.\n",
583 devname, chosen_name);
584 rv = 0;
585 }
586 out:
587 if (dfd >= 0)
588 close(dfd);
589 if (mdfd >= 0)
590 close(mdfd);
591 if (policy)
592 dev_policy_free(policy);
593 return rv;
594 }
595
596 static void find_reject(int mdfd, struct supertype *st, struct mdinfo *sra,
597 int number, __u64 events, int verbose,
598 char *array_name)
599 {
600 /* Find a device attached to this array with a disk.number of number
601 * and events less than the passed events, and remove the device.
602 */
603 struct mdinfo *d;
604 mdu_array_info_t ra;
605
606 if (ioctl(mdfd, GET_ARRAY_INFO, &ra) == 0)
607 return; /* not safe to remove from active arrays
608 * without thinking more */
609
610 for (d = sra->devs; d ; d = d->next) {
611 char dn[10];
612 int dfd;
613 struct mdinfo info;
614 sprintf(dn, "%d:%d", d->disk.major, d->disk.minor);
615 dfd = dev_open(dn, O_RDONLY);
616 if (dfd < 0)
617 continue;
618 if (st->ss->load_super(st, dfd, NULL)) {
619 close(dfd);
620 continue;
621 }
622 st->ss->getinfo_super(st, &info);
623 st->ss->free_super(st);
624 close(dfd);
625
626 if (info.disk.number != number ||
627 info.events >= events)
628 continue;
629
630 if (d->disk.raid_disk > -1)
631 sysfs_set_str(sra, d, "slot", "none");
632 if (sysfs_set_str(sra, d, "state", "remove") == 0)
633 if (verbose >= 0)
634 fprintf(stderr, Name
635 ": removing old device %s from %s\n",
636 d->sys_name+4, array_name);
637 }
638 }
639
640 static int count_active(struct supertype *st, int mdfd, char **availp,
641 struct mdinfo *bestinfo)
642 {
643 /* count how many devices in sra think they are active */
644 struct mdinfo *d;
645 int cnt = 0, cnt1 = 0;
646 __u64 max_events = 0;
647 struct mdinfo *sra = sysfs_read(mdfd, -1, GET_DEVS | GET_STATE);
648 char *avail = NULL;
649
650 if (!sra)
651 return 0;
652
653 for (d = sra->devs ; d ; d = d->next) {
654 char dn[30];
655 int dfd;
656 int ok;
657 struct mdinfo info;
658
659 sprintf(dn, "%d:%d", d->disk.major, d->disk.minor);
660 dfd = dev_open(dn, O_RDONLY);
661 if (dfd < 0)
662 continue;
663 ok = st->ss->load_super(st, dfd, NULL);
664 close(dfd);
665 if (ok != 0)
666 continue;
667 st->ss->getinfo_super(st, &info);
668 if (!avail) {
669 avail = malloc(info.array.raid_disks);
670 if (!avail) {
671 fprintf(stderr, Name ": out of memory.\n");
672 exit(1);
673 }
674 memset(avail, 0, info.array.raid_disks);
675 *availp = avail;
676 }
677
678 if (info.disk.state & (1<<MD_DISK_SYNC))
679 {
680 if (cnt == 0) {
681 cnt++;
682 max_events = info.events;
683 avail[info.disk.raid_disk] = 2;
684 st->ss->getinfo_super(st, bestinfo);
685 } else if (info.events == max_events) {
686 cnt++;
687 avail[info.disk.raid_disk] = 2;
688 } else if (info.events == max_events-1) {
689 cnt1++;
690 avail[info.disk.raid_disk] = 1;
691 } else if (info.events < max_events - 1)
692 ;
693 else if (info.events == max_events+1) {
694 int i;
695 cnt1 = cnt;
696 cnt = 1;
697 max_events = info.events;
698 for (i=0; i<info.array.raid_disks; i++)
699 if (avail[i])
700 avail[i]--;
701 avail[info.disk.raid_disk] = 2;
702 st->ss->getinfo_super(st, bestinfo);
703 } else { /* info.events much bigger */
704 cnt = 1; cnt1 = 0;
705 memset(avail, 0, info.disk.raid_disk);
706 max_events = info.events;
707 st->ss->getinfo_super(st, bestinfo);
708 }
709 }
710 st->ss->free_super(st);
711 }
712 return cnt + cnt1;
713 }
714
715 static int try_spare(char *devname, int *dfdp, struct dev_policy *pol,
716 struct supertype *st, int verbose)
717 {
718 /* This device doesn't have any md metadata
719 * If it is 'bare' and theh device policy allows 'spare' look for
720 * an array or container to attach it to.
721 * If st is set, then only arrays of that type are considered
722 * Return 0 on success, or some exit code on failure, probably 1.
723 */
724 int rv = -1;
725 char bufpad[4096 + 4096];
726 char *buf = (char*)(((long)bufpad + 4096) & ~4095);
727 struct stat stb;
728 struct map_ent *mp, *map = NULL;
729 struct mdinfo *chosen = NULL;
730 int dfd = *dfdp;
731
732 /* First check policy */
733 if (!policy_action_allows(pol, st?st->ss->name:NULL, act_spare))
734 return 1;
735
736 if (fstat(dfd, &stb) != 0)
737 return 1;
738 /* Now check if the device is bare - we don't add non-bare devices
739 * yet even if action=-spare
740 */
741
742 if (lseek(dfd, 0, SEEK_SET) != 0 ||
743 read(dfd, buf, 4096) != 4096) {
744 not_bare:
745 if (verbose > 1)
746 fprintf(stderr, Name ": %s is not bare, so not considering as a spare\n",
747 devname);
748 return 1;
749 }
750 if (buf[0] != '\0' && buf[0] != '\x5a' && buf[0] != '\xff')
751 goto not_bare;
752 if (memcmp(buf, buf+1, 4095) != 0)
753 goto not_bare;
754
755 /* OK, first 4K appear blank, try the end. */
756 if (lseek(dfd, -4096, SEEK_END) < 0 ||
757 read(dfd, buf, 4096) != 4096)
758 goto not_bare;
759
760 if (buf[0] != '\0' && buf[0] != '\x5a' && buf[0] != '\xff')
761 goto not_bare;
762 if (memcmp(buf, buf+1, 4095) != 0)
763 goto not_bare;
764
765 /* This device passes our test for 'is bare'.
766 * Now we need to find a suitable array to add this to.
767 * We only accept arrays that:
768 * - match 'st'
769 * - are in the same domains as the device
770 * - are of an size for which the device will be useful
771 * and we choose the one that is the most degraded
772 */
773
774 if (map_lock(&map)) {
775 fprintf(stderr, Name ": failed to get exclusive lock on "
776 "mapfile\n");
777 return 1;
778 }
779 for (mp = map ; mp ; mp = mp->next) {
780 struct supertype *st2;
781 struct domainlist *dl = NULL;
782 struct mdinfo *sra;
783 unsigned long long devsize;
784
785 if (is_subarray(mp->metadata))
786 continue;
787 if (st) {
788 st2 = st->ss->match_metadata_desc(mp->metadata);
789 if (!st2 ||
790 (st->minor_version >= 0 &&
791 st->minor_version != st2->minor_version)) {
792 if (verbose > 1)
793 fprintf(stderr, Name ": not adding %s to %s as metadata type doesn't match\n",
794 devname, mp->path);
795 free(st2);
796 continue;
797 }
798 free(st2);
799 }
800 sra = sysfs_read(-1, mp->devnum,
801 GET_DEVS|GET_OFFSET|GET_SIZE|GET_STATE|
802 GET_DEGRADED|GET_COMPONENT|GET_VERSION);
803 if (!sra) {
804 /* Probably a container - no degraded info */
805 sra = sysfs_read(-1, mp->devnum,
806 GET_DEVS|GET_OFFSET|GET_SIZE|GET_STATE|
807 GET_COMPONENT|GET_VERSION);
808 if (sra)
809 sra->array.failed_disks = 0;
810 }
811 if (!sra)
812 continue;
813 if (st == NULL) {
814 int i;
815 st2 = NULL;
816 for(i=0; !st2 && superlist[i]; i++)
817 st2 = superlist[i]->match_metadata_desc(
818 sra->text_version);
819 } else
820 st2 = st;
821 get_dev_size(dfd, NULL, &devsize);
822 if (st2->ss->avail_size(st2, devsize) < sra->component_size) {
823 if (verbose > 1)
824 fprintf(stderr, Name ": not adding %s to %s as it is too small\n",
825 devname, mp->path);
826 goto next;
827 }
828 dl = domain_from_array(sra, st2->ss->name);
829 if (!domain_test(dl, pol, st2->ss->name)) {
830 /* domain test fails */
831 if (verbose > 1)
832 fprintf(stderr, Name ": not adding %s to %s as it is not in a compatible domain\n",
833 devname, mp->path);
834
835 goto next;
836 }
837 /* all tests passed, OK to add to this array */
838 if (!chosen) {
839 chosen = sra;
840 sra = NULL;
841 } else if (chosen->array.failed_disks < sra->array.failed_disks) {
842 sysfs_free(chosen);
843 chosen = sra;
844 sra = NULL;
845 }
846 next:
847 if (sra)
848 sysfs_free(sra);
849 if (st != st2)
850 free(st2);
851 if (dl)
852 domain_free(dl);
853 }
854 if (chosen) {
855 /* add current device to chosen array as a spare */
856 int mdfd = open_dev(devname2devnum(chosen->sys_name));
857 if (mdfd >= 0) {
858 struct mddev_dev_s devlist;
859 char devname[20];
860 devlist.next = NULL;
861 devlist.used = 0;
862 devlist.re_add = 0;
863 devlist.writemostly = 0;
864 devlist.devname = devname;
865 sprintf(devname, "%d:%d", major(stb.st_rdev),
866 minor(stb.st_rdev));
867 devlist.disposition = 'a';
868 close(dfd);
869 *dfdp = -1;
870 rv = Manage_subdevs(chosen->sys_name, mdfd, &devlist,
871 -1, 0);
872 close(mdfd);
873 }
874 if (verbose > 0) {
875 if (rv == 0)
876 fprintf(stderr, Name ": added %s as spare for %s\n",
877 devname, chosen->sys_name);
878 else
879 fprintf(stderr, Name ": failed to add %s as spare for %s\n",
880 devname, chosen->sys_name);
881 }
882 sysfs_free(chosen);
883 }
884 return rv ? 0 : 1;
885 }
886
887 int IncrementalScan(int verbose)
888 {
889 /* look at every device listed in the 'map' file.
890 * If one is found that is not running then:
891 * look in mdadm.conf for bitmap file.
892 * if one exists, but array has none, add it.
893 * try to start array in auto-readonly mode
894 */
895 struct map_ent *mapl = NULL;
896 struct map_ent *me;
897 mddev_ident_t devs, mddev;
898 int rv = 0;
899
900 map_read(&mapl);
901 devs = conf_get_ident(NULL);
902
903 for (me = mapl ; me ; me = me->next) {
904 mdu_array_info_t array;
905 mdu_bitmap_file_t bmf;
906 struct mdinfo *sra;
907 int mdfd = open_dev(me->devnum);
908
909 if (mdfd < 0)
910 continue;
911 if (ioctl(mdfd, GET_ARRAY_INFO, &array) == 0 ||
912 errno != ENODEV) {
913 close(mdfd);
914 continue;
915 }
916 /* Ok, we can try this one. Maybe it needs a bitmap */
917 for (mddev = devs ; mddev ; mddev = mddev->next)
918 if (mddev->devname && me->path
919 && devname_matches(mddev->devname, me->path))
920 break;
921 if (mddev && mddev->bitmap_file) {
922 /*
923 * Note: early kernels will wrongly fail this, so it
924 * is a hint only
925 */
926 int added = -1;
927 if (ioctl(mdfd, GET_ARRAY_INFO, &bmf) < 0) {
928 int bmfd = open(mddev->bitmap_file, O_RDWR);
929 if (bmfd >= 0) {
930 added = ioctl(mdfd, SET_BITMAP_FILE,
931 bmfd);
932 close(bmfd);
933 }
934 }
935 if (verbose >= 0) {
936 if (added == 0)
937 fprintf(stderr, Name
938 ": Added bitmap %s to %s\n",
939 mddev->bitmap_file, me->path);
940 else if (errno != EEXIST)
941 fprintf(stderr, Name
942 ": Failed to add bitmap to %s: %s\n",
943 me->path, strerror(errno));
944 }
945 }
946 sra = sysfs_read(mdfd, 0, 0);
947 if (sra) {
948 if (sysfs_set_str(sra, NULL,
949 "array_state", "read-auto") == 0) {
950 if (verbose >= 0)
951 fprintf(stderr, Name
952 ": started array %s\n",
953 me->path ?: devnum2devname(me->devnum));
954 } else {
955 fprintf(stderr, Name
956 ": failed to start array %s: %s\n",
957 me->path ?: devnum2devname(me->devnum),
958 strerror(errno));
959 rv = 1;
960 }
961 }
962 }
963 return rv;
964 }
965
966 static char *container2devname(char *devname)
967 {
968 char *mdname = NULL;
969
970 if (devname[0] == '/') {
971 int fd = open(devname, O_RDONLY);
972 if (fd >= 0) {
973 mdname = devnum2devname(fd2devnum(fd));
974 close(fd);
975 }
976 } else {
977 int uuid[4];
978 struct map_ent *mp, *map = NULL;
979
980 if (!parse_uuid(devname, uuid))
981 return mdname;
982 mp = map_by_uuid(&map, uuid);
983 if (mp)
984 mdname = devnum2devname(mp->devnum);
985 map_free(map);
986 }
987
988 return mdname;
989 }
990
991 int Incremental_container(struct supertype *st, char *devname, int verbose,
992 int runstop, int autof, int trustworthy)
993 {
994 /* Collect the contents of this container and for each
995 * array, choose a device name and assemble the array.
996 */
997
998 struct mdinfo *list = st->ss->container_content(st);
999 struct mdinfo *ra;
1000 struct map_ent *map = NULL;
1001
1002 if (map_lock(&map))
1003 fprintf(stderr, Name ": failed to get exclusive lock on "
1004 "mapfile\n");
1005
1006 for (ra = list ; ra ; ra = ra->next) {
1007 int mdfd;
1008 char chosen_name[1024];
1009 struct map_ent *mp;
1010 struct mddev_ident_s *match = NULL;
1011
1012 mp = map_by_uuid(&map, ra->uuid);
1013
1014 if (mp) {
1015 mdfd = open_dev(mp->devnum);
1016 if (mp->path)
1017 strcpy(chosen_name, mp->path);
1018 else
1019 strcpy(chosen_name, devnum2devname(mp->devnum));
1020 } else {
1021
1022 /* Check in mdadm.conf for container == devname and
1023 * member == ra->text_version after second slash.
1024 */
1025 char *sub = strchr(ra->text_version+1, '/');
1026 struct mddev_ident_s *array_list;
1027 if (sub) {
1028 sub++;
1029 array_list = conf_get_ident(NULL);
1030 } else
1031 array_list = NULL;
1032 for(; array_list ; array_list = array_list->next) {
1033 char *dn;
1034 if (array_list->member == NULL ||
1035 array_list->container == NULL)
1036 continue;
1037 if (strcmp(array_list->member, sub) != 0)
1038 continue;
1039 if (array_list->uuid_set &&
1040 !same_uuid(ra->uuid, array_list->uuid, st->ss->swapuuid))
1041 continue;
1042 dn = container2devname(array_list->container);
1043 if (dn == NULL)
1044 continue;
1045 if (strncmp(dn, ra->text_version+1,
1046 strlen(dn)) != 0 ||
1047 ra->text_version[strlen(dn)+1] != '/') {
1048 free(dn);
1049 continue;
1050 }
1051 free(dn);
1052 /* we have a match */
1053 match = array_list;
1054 if (verbose>0)
1055 fprintf(stderr, Name ": match found for member %s\n",
1056 array_list->member);
1057 break;
1058 }
1059
1060 if (match && match->devname &&
1061 strcasecmp(match->devname, "<ignore>") == 0) {
1062 if (verbose > 0)
1063 fprintf(stderr, Name ": array %s/%s is "
1064 "explicitly ignored by mdadm.conf\n",
1065 match->container, match->member);
1066 return 2;
1067 }
1068 if (match)
1069 trustworthy = LOCAL;
1070
1071 mdfd = create_mddev(match ? match->devname : NULL,
1072 ra->name,
1073 autof,
1074 trustworthy,
1075 chosen_name);
1076 }
1077
1078 if (mdfd < 0) {
1079 fprintf(stderr, Name ": failed to open %s: %s.\n",
1080 chosen_name, strerror(errno));
1081 return 2;
1082 }
1083
1084 assemble_container_content(st, mdfd, ra, runstop,
1085 chosen_name, verbose);
1086 }
1087 map_unlock(&map);
1088 return 0;
1089 }
1090
1091 /*
1092 * IncrementalRemove - Attempt to see if the passed in device belongs to any
1093 * raid arrays, and if so first fail (if needed) and then remove the device.
1094 *
1095 * @devname - The device we want to remove
1096 *
1097 * Note: the device name must be a kernel name like "sda", so
1098 * that we can find it in /proc/mdstat
1099 */
1100 int IncrementalRemove(char *devname, int verbose)
1101 {
1102 int mdfd;
1103 int rv;
1104 struct mdstat_ent *ent;
1105 struct mddev_dev_s devlist;
1106
1107 if (strchr(devname, '/')) {
1108 fprintf(stderr, Name ": incremental removal requires a "
1109 "kernel device name, not a file: %s\n", devname);
1110 return 1;
1111 }
1112 ent = mdstat_by_component(devname);
1113 if (!ent) {
1114 fprintf(stderr, Name ": %s does not appear to be a component "
1115 "of any array\n", devname);
1116 return 1;
1117 }
1118 mdfd = open_dev(ent->devnum);
1119 if (mdfd < 0) {
1120 fprintf(stderr, Name ": Cannot open array %s!!\n", ent->dev);
1121 return 1;
1122 }
1123 memset(&devlist, 0, sizeof(devlist));
1124 devlist.devname = devname;
1125 devlist.disposition = 'f';
1126 Manage_subdevs(ent->dev, mdfd, &devlist, verbose, 0);
1127 devlist.disposition = 'r';
1128 rv = Manage_subdevs(ent->dev, mdfd, &devlist, verbose, 0);
1129 close(mdfd);
1130 return rv;
1131 }