Use uuid as /dev name when assembling array of uncertain origin.
[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 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
39 int Incremental(char *devname, int verbose, int runstop,
40                 struct supertype *st, char *homehost, int autof)
41 {
42         /* Add this device to an array, creating the array if necessary
43          * and starting the array if sensible or - if runstop>0 - if possible.
44          *
45          * This has several steps:
46          *
47          * 1/ Check if device is permitted by mdadm.conf, reject if not.
48          * 2/ Find metadata, reject if none appropriate (check
49          *       version/name from args)
50          * 3/ Check if there is a match in mdadm.conf
51          * 3a/ if not, check for homehost match.  If no match, reject.
52          * 4/ Determine device number.
53          * - If in mdadm.conf with std name, use that
54          * - UUID in /var/run/mdadm.map  use that
55          * - If name is suggestive, use that. unless in use with different uuid.
56          * - Choose a free, high number.
57          * - Use a partitioned device unless strong suggestion not to.
58          *         e.g. auto=md
59          *   Don't choose partitioned for containers.
60          * 5/ Find out if array already exists
61          * 5a/ if it does not
62          * - choose a name, from mdadm.conf or 'name' field in array.
63          * - create the array
64          * - add the device
65          * 5b/ if it does
66          * - check one drive in array to make sure metadata is a reasonably
67          *       close match.  Reject if not (e.g. different type)
68          * - add the device
69          * 6/ Make sure /var/run/mdadm.map contains this array.
70          * 7/ Is there enough devices to possibly start the array?
71          *     For a container, this means running Incremental_container.
72          * 7a/ if not, finish with success.
73          * 7b/ if yes,
74          * - read all metadata and arrange devices like -A does
75          * - if number of OK devices match expected, or -R and there are enough,
76          *   start the array (auto-readonly).
77          */
78         struct stat stb;
79         struct mdinfo info;
80         struct mddev_ident_s *array_list, *match;
81         char chosen_name[1024];
82         int rv;
83         int devnum;
84         struct map_ent *mp, *map = NULL;
85         int dfd, mdfd;
86         char *avail;
87         int active_disks;
88         int uuid_for_name = 0;
89         char *name_to_use;
90         char nbuf[64];
91
92         struct createinfo *ci = conf_get_create_info();
93
94         if (autof == 0)
95                 autof = ci->autof;
96
97         /* 1/ Check if device is permitted by mdadm.conf */
98
99         if (!conf_test_dev(devname)) {
100                 if (verbose >= 0)
101                         fprintf(stderr, Name
102                                 ": %s not permitted by mdadm.conf.\n",
103                                 devname);
104                 return 1;
105         }
106
107         /* 2/ Find metadata, reject if none appropriate (check
108          *            version/name from args) */
109
110         dfd = dev_open(devname, O_RDONLY|O_EXCL);
111         if (dfd < 0) {
112                 if (verbose >= 0)
113                         fprintf(stderr, Name ": cannot open %s: %s.\n",
114                                 devname, strerror(errno));
115                 return 1;
116         }
117         if (fstat(dfd, &stb) < 0) {
118                 if (verbose >= 0)
119                         fprintf(stderr, Name ": fstat failed for %s: %s.\n",
120                                 devname, strerror(errno));
121                 close(dfd);
122                 return 1;
123         }
124         if ((stb.st_mode & S_IFMT) != S_IFBLK) {
125                 if (verbose >= 0)
126                         fprintf(stderr, Name ": %s is not a block device.\n",
127                                 devname);
128                 close(dfd);
129                 return 1;
130         }
131
132         if (st == NULL && (st = guess_super(dfd)) == NULL) {
133                 if (verbose >= 0)
134                         fprintf(stderr, Name
135                                 ": no recognisable superblock on %s.\n",
136                                 devname);
137                 close(dfd);
138                 return 1;
139         }
140         if (st->ss->load_super(st, dfd, NULL)) {
141                 if (verbose >= 0)
142                         fprintf(stderr, Name ": no RAID superblock on %s.\n",
143                                 devname);
144                 close(dfd);
145                 return 1;
146         }
147         close (dfd);
148
149         if (st->ss->container_content && st->loaded_container) {
150                 /* This is a pre-built container array, so we do something
151                  * rather different.
152                  */
153                 return Incremental_container(st, devname, verbose, runstop,
154                                              autof);
155         }
156
157         memset(&info, 0, sizeof(info));
158         st->ss->getinfo_super(st, &info);
159         /* 3/ Check if there is a match in mdadm.conf */
160
161         array_list = conf_get_ident(NULL);
162         match = NULL;
163         for (; array_list; array_list = array_list->next) {
164                 if (array_list->uuid_set &&
165                     same_uuid(array_list->uuid, info.uuid, st->ss->swapuuid)
166                     == 0) {
167                         if (verbose >= 2)
168                                 fprintf(stderr, Name
169                                         ": UUID differs from %s.\n",
170                                         array_list->devname);
171                         continue;
172                 }
173                 if (array_list->name[0] &&
174                     strcasecmp(array_list->name, info.name) != 0) {
175                         if (verbose >= 2)
176                                 fprintf(stderr, Name
177                                         ": Name differs from %s.\n",
178                                         array_list->devname);
179                         continue;
180                 }
181                 if (array_list->devices &&
182                     !match_oneof(array_list->devices, devname)) {
183                         if (verbose >= 2)
184                                 fprintf(stderr, Name
185                                         ": Not a listed device for %s.\n",
186                                         array_list->devname);
187                         continue;
188                 }
189                 if (array_list->super_minor != UnSet &&
190                     array_list->super_minor != info.array.md_minor) {
191                         if (verbose >= 2)
192                                 fprintf(stderr, Name
193                                         ": Different super-minor to %s.\n",
194                                         array_list->devname);
195                         continue;
196                 }
197                 if (!array_list->uuid_set &&
198                     !array_list->name[0] &&
199                     !array_list->devices &&
200                     array_list->super_minor == UnSet) {
201                         if (verbose  >= 2)
202                                 fprintf(stderr, Name
203                              ": %s doesn't have any identifying information.\n",
204                                         array_list->devname);
205                         continue;
206                 }
207                 /* FIXME, should I check raid_disks and level too?? */
208
209                 if (match) {
210                         if (verbose >= 0)
211                                 fprintf(stderr, Name
212                    ": we match both %s and %s - cannot decide which to use.\n",
213                                         match->devname, array_list->devname);
214                         return 2;
215                 }
216                 match = array_list;
217         }
218
219         /* 3a/ if not, check for homehost match.  If no match, reject. */
220         if (!match) {
221                 if (homehost == NULL ||
222                        st->ss->match_home(st, homehost) != 1)
223                         uuid_for_name = 1;
224         }
225         /* 4/ Determine device number. */
226         /* - If in mdadm.conf with std name, use that */
227         /* - UUID in /var/run/mdadm.map  use that */
228         /* - If name is suggestive, use that. unless in use with */
229         /*           different uuid. */
230         /* - Choose a free, high number. */
231         /* - Use a partitioned device unless strong suggestion not to. */
232         /*         e.g. auto=md */
233         mp = map_by_uuid(&map, info.uuid);
234
235         if (uuid_for_name && ! mp) {
236                 name_to_use = fname_from_uuid(st, &info, nbuf);
237                 if (verbose >= 0)
238                         fprintf(stderr, Name
239                 ": not found in mdadm.conf and not identified by homehost"
240                                 " - using uuid based name\n");
241         } else
242                 name_to_use = info.name;
243
244         if (match && is_standard(match->devname, &devnum))
245                 /* We have devnum now */;
246         else if (mp != NULL)
247                 devnum = mp->devnum;
248         else {
249                 /* Have to guess a bit. */
250                 int use_partitions = 1;
251                 char *np, *ep;
252                 char *nm, nbuf[1024];
253                 struct stat stb2;
254
255                 if ((autof&7) == 3 || (autof&7) == 5)
256                         use_partitions = 0;
257                 if (st->ss->external)
258                         use_partitions = 0;
259                 np = strchr(name_to_use, ':');
260                 if (np)
261                         np++;
262                 else
263                         np = name_to_use;
264                 devnum = strtoul(np, &ep, 10);
265                 if (ep > np && *ep == 0) {
266                         /* This is a number.  Let check that it is unused. */
267                         if (mddev_busy(use_partitions ? (-1-devnum) : devnum))
268                                 devnum = -1;
269                 } else
270                         devnum = -1;
271
272                 if (match)
273                         nm = match->devname;
274                 else {
275                         sprintf(nbuf, "/dev/md/%s", np);
276                         nm = nbuf;
277                 }
278                 if (stat(nm, &stb2) == 0 &&
279                     S_ISBLK(stb2.st_mode) &&
280                     major(stb2.st_rdev) == (use_partitions ?
281                                             get_mdp_major() : MD_MAJOR)) {
282                         if (use_partitions)
283                                 devnum = minor(stb2.st_rdev) >> MdpMinorShift;
284                         else
285                                 devnum = minor(stb2.st_rdev);
286                         if (mddev_busy(use_partitions ? (-1-devnum) : devnum))
287                                 devnum = -1;
288                 }
289
290                 if (devnum < 0) {
291                         /* Haven't found anything yet, choose something free */
292                         devnum = find_free_devnum(use_partitions);
293
294                         if (devnum == NoMdDev) {
295                                 fprintf(stderr, Name
296                                         ": No spare md devices!!\n");
297                                 return 2;
298                         }
299                 } else
300                         devnum = use_partitions ? (-1-devnum) : devnum;
301         }
302
303         mdfd = open_mddev_devnum(match ? match->devname : mp ? mp->path : NULL,
304                                  devnum,
305                                  name_to_use,
306                                  chosen_name, autof >> 3);
307         if (mdfd < 0) {
308                 fprintf(stderr, Name ": failed to open %s: %s.\n",
309                         chosen_name, strerror(errno));
310                 return 2;
311         }
312         sysfs_init(&info, mdfd, 0);
313
314         /* 5/ Find out if array already exists */
315         if (! mddev_busy(devnum)) {
316         /* 5a/ if it does not */
317         /* - choose a name, from mdadm.conf or 'name' field in array. */
318         /* - create the array */
319         /* - add the device */
320                 struct mdinfo *sra;
321                 struct mdinfo dinfo;
322
323                 if (set_array_info(mdfd, st, &info) != 0) {
324                         fprintf(stderr, Name ": failed to set array info for %s: %s\n",
325                                 chosen_name, strerror(errno));
326                         close(mdfd);
327                         return 2;
328                 }
329
330                 dinfo = info;
331                 dinfo.disk.major = major(stb.st_rdev);
332                 dinfo.disk.minor = minor(stb.st_rdev);
333                 if (add_disk(mdfd, st, &info, &dinfo) != 0) {
334                         fprintf(stderr, Name ": failed to add %s to %s: %s.\n",
335                                 devname, chosen_name, strerror(errno));
336                         ioctl(mdfd, STOP_ARRAY, 0);
337                         close(mdfd);
338                         return 2;
339                 }
340                 sra = sysfs_read(mdfd, devnum, GET_DEVS);
341                 if (!sra || !sra->devs || sra->devs->disk.raid_disk >= 0) {
342                         /* It really should be 'none' - must be old buggy
343                          * kernel, and mdadm -I may not be able to complete.
344                          * So reject it.
345                          */
346                         ioctl(mdfd, STOP_ARRAY, NULL);
347                         fprintf(stderr, Name
348                       ": You have an old buggy kernel which cannot support\n"
349                                 "      --incremental reliably.  Aborting.\n");
350                         close(mdfd);
351                         sysfs_free(sra);
352                         return 2;
353                 }
354                 info.array.working_disks = 1;
355                 sysfs_free(sra);
356         } else {
357         /* 5b/ if it does */
358         /* - check one drive in array to make sure metadata is a reasonably */
359         /*        close match.  Reject if not (e.g. different type) */
360         /* - add the device */
361                 char dn[20];
362                 int dfd2;
363                 int err;
364                 struct mdinfo *sra;
365                 struct supertype *st2;
366                 struct mdinfo info2, *d;
367                 sra = sysfs_read(mdfd, devnum, (GET_DEVS | GET_STATE));
368
369                 sprintf(dn, "%d:%d", sra->devs->disk.major,
370                         sra->devs->disk.minor);
371                 dfd2 = dev_open(dn, O_RDONLY);
372                 st2 = dup_super(st);
373                 if (st2->ss->load_super(st2, dfd2, NULL) ||
374                     st->ss->compare_super(st, st2) != 0) {
375                         fprintf(stderr, Name
376                                 ": metadata mismatch between %s and "
377                                 "chosen array %s\n",
378                                 devname, chosen_name);
379                         close(mdfd);
380                         close(dfd2);
381                         return 2;
382                 }
383                 close(dfd2);
384                 memset(&info2, 0, sizeof(info2));
385                 st2->ss->getinfo_super(st2, &info2);
386                 st2->ss->free_super(st2);
387                 if (info.array.level != info2.array.level ||
388                     memcmp(info.uuid, info2.uuid, 16) != 0 ||
389                     info.array.raid_disks != info2.array.raid_disks) {
390                         fprintf(stderr, Name
391                                 ": unexpected difference between %s and %s.\n",
392                                 chosen_name, devname);
393                         close(mdfd);
394                         return 2;
395                 }
396                 info2.disk.major = major(stb.st_rdev);
397                 info2.disk.minor = minor(stb.st_rdev);
398                 /* add disk needs to know about containers */
399                 if (st->ss->external)
400                         sra->array.level = LEVEL_CONTAINER;
401                 err = add_disk(mdfd, st2, sra, &info2);
402                 if (err < 0 && errno == EBUSY) {
403                         /* could be another device present with the same
404                          * disk.number. Find and reject any such
405                          */
406                         find_reject(mdfd, st, sra, info.disk.number,
407                                     info.events, verbose, chosen_name);
408                         err = add_disk(mdfd, st2, sra, &info2);
409                 }
410                 if (err < 0) {
411                         fprintf(stderr, Name ": failed to add %s to %s: %s.\n",
412                                 devname, chosen_name, strerror(errno));
413                         close(mdfd);
414                         return 2;
415                 }
416                 info.array.working_disks = 0;
417                 for (d = sra->devs; d; d=d->next)
418                         info.array.working_disks ++;
419                         
420         }
421         /* 6/ Make sure /var/run/mdadm.map contains this array. */
422         map_update(&map, devnum,
423                    info.text_version,
424                    info.uuid, chosen_name);
425
426         /* 7/ Is there enough devices to possibly start the array? */
427         /* 7a/ if not, finish with success. */
428         if (info.array.level == LEVEL_CONTAINER) {
429                 /* Try to assemble within the container */
430                 close(mdfd);
431                 if (verbose >= 0)
432                         fprintf(stderr, Name
433                                 ": container %s now has %d devices\n",
434                                 chosen_name, info.array.working_disks);
435                 return Incremental(chosen_name, verbose, runstop,
436                                    NULL, homehost, autof);
437         }
438         avail = NULL;
439         active_disks = count_active(st, mdfd, &avail, &info);
440         if (enough(info.array.level, info.array.raid_disks,
441                    info.array.layout, info.array.state & 1,
442                    avail, active_disks) == 0) {
443                 free(avail);
444                 if (verbose >= 0)
445                         fprintf(stderr, Name
446                              ": %s attached to %s, not enough to start (%d).\n",
447                                 devname, chosen_name, active_disks);
448                 close(mdfd);
449                 return 0;
450         }
451         free(avail);
452
453         /* 7b/ if yes, */
454         /* - if number of OK devices match expected, or -R and there */
455         /*             are enough, */
456         /*   + add any bitmap file  */
457         /*   + start the array (auto-readonly). */
458 {
459         mdu_array_info_t ainf;
460
461         if (ioctl(mdfd, GET_ARRAY_INFO, &ainf) == 0) {
462                 if (verbose >= 0)
463                         fprintf(stderr, Name
464                            ": %s attached to %s which is already active.\n",
465                                 devname, chosen_name);
466                 close (mdfd);
467                 return 0;
468         }
469 }
470         if (runstop > 0 || active_disks >= info.array.working_disks) {
471                 struct mdinfo *sra;
472                 /* Let's try to start it */
473                 if (match && match->bitmap_file) {
474                         int bmfd = open(match->bitmap_file, O_RDWR);
475                         if (bmfd < 0) {
476                                 fprintf(stderr, Name
477                                         ": Could not open bitmap file %s.\n",
478                                         match->bitmap_file);
479                                 close(mdfd);
480                                 return 1;
481                         }
482                         if (ioctl(mdfd, SET_BITMAP_FILE, bmfd) != 0) {
483                                 close(bmfd);
484                                 fprintf(stderr, Name
485                                         ": Failed to set bitmapfile for %s.\n",
486                                         chosen_name);
487                                 close(mdfd);
488                                 return 1;
489                         }
490                         close(bmfd);
491                 }
492                 sra = sysfs_read(mdfd, devnum, 0);
493                 if (sra == NULL || active_disks >= info.array.working_disks)
494                         rv = ioctl(mdfd, RUN_ARRAY, NULL);
495                 else
496                         rv = sysfs_set_str(sra, NULL,
497                                            "array_state", "read-auto");
498                 if (rv == 0) {
499                         if (verbose >= 0)
500                                 fprintf(stderr, Name
501                            ": %s attached to %s, which has been started.\n",
502                                         devname, chosen_name);
503                         rv = 0;
504                 } else {
505                         fprintf(stderr, Name
506                              ": %s attached to %s, but failed to start: %s.\n",
507                                 devname, chosen_name, strerror(errno));
508                         rv = 1;
509                 }
510         } else {
511                 if (verbose >= 0)
512                         fprintf(stderr, Name
513                           ": %s attached to %s, not enough to start safely.\n",
514                                 devname, chosen_name);
515                 rv = 0;
516         }
517         close(mdfd);
518         return rv;
519 }
520
521 static void find_reject(int mdfd, struct supertype *st, struct mdinfo *sra,
522                         int number, __u64 events, int verbose,
523                         char *array_name)
524 {
525         /* Find a device attached to this array with a disk.number of number
526          * and events less than the passed events, and remove the device.
527          */
528         struct mdinfo *d;
529         mdu_array_info_t ra;
530
531         if (ioctl(mdfd, GET_ARRAY_INFO, &ra) == 0)
532                 return; /* not safe to remove from active arrays
533                          * without thinking more */
534
535         for (d = sra->devs; d ; d = d->next) {
536                 char dn[10];
537                 int dfd;
538                 struct mdinfo info;
539                 sprintf(dn, "%d:%d", d->disk.major, d->disk.minor);
540                 dfd = dev_open(dn, O_RDONLY);
541                 if (dfd < 0)
542                         continue;
543                 if (st->ss->load_super(st, dfd, NULL)) {
544                         close(dfd);
545                         continue;
546                 }
547                 st->ss->getinfo_super(st, &info);
548                 st->ss->free_super(st);
549                 close(dfd);
550
551                 if (info.disk.number != number ||
552                     info.events >= events)
553                         continue;
554
555                 if (d->disk.raid_disk > -1)
556                         sysfs_set_str(sra, d, "slot", "none");
557                 if (sysfs_set_str(sra, d, "state", "remove") == 0)
558                         if (verbose >= 0)
559                                 fprintf(stderr, Name
560                                         ": removing old device %s from %s\n",
561                                         d->sys_name+4, array_name);
562         }
563 }
564
565 static int count_active(struct supertype *st, int mdfd, char **availp,
566                         struct mdinfo *bestinfo)
567 {
568         /* count how many devices in sra think they are active */
569         struct mdinfo *d;
570         int cnt = 0, cnt1 = 0;
571         __u64 max_events = 0;
572         struct mdinfo *sra = sysfs_read(mdfd, -1, GET_DEVS | GET_STATE);
573         char *avail = NULL;
574
575         for (d = sra->devs ; d ; d = d->next) {
576                 char dn[30];
577                 int dfd;
578                 int ok;
579                 struct mdinfo info;
580
581                 sprintf(dn, "%d:%d", d->disk.major, d->disk.minor);
582                 dfd = dev_open(dn, O_RDONLY);
583                 if (dfd < 0)
584                         continue;
585                 ok =  st->ss->load_super(st, dfd, NULL);
586                 close(dfd);
587                 if (ok != 0)
588                         continue;
589                 st->ss->getinfo_super(st, &info);
590                 if (info.disk.state & (1<<MD_DISK_SYNC))
591                 {
592                         if (avail == NULL) {
593                                 avail = malloc(info.array.raid_disks);
594                                 memset(avail, 0, info.array.raid_disks);
595                         }
596                         if (cnt == 0) {
597                                 cnt++;
598                                 max_events = info.events;
599                                 avail[info.disk.raid_disk] = 2;
600                                 st->ss->getinfo_super(st, bestinfo);
601                         } else if (info.events == max_events) {
602                                 cnt++;
603                                 avail[info.disk.raid_disk] = 2;
604                         } else if (info.events == max_events-1) {
605                                 cnt1++;
606                                 avail[info.disk.raid_disk] = 1;
607                         } else if (info.events < max_events - 1)
608                                 ;
609                         else if (info.events == max_events+1) {
610                                 int i;
611                                 cnt1 = cnt;
612                                 cnt = 1;
613                                 max_events = info.events;
614                                 for (i=0; i<info.array.raid_disks; i++)
615                                         if (avail[i])
616                                                 avail[i]--;
617                                 avail[info.disk.raid_disk] = 2;
618                                 st->ss->getinfo_super(st, bestinfo);
619                         } else { /* info.events much bigger */
620                                 cnt = 1; cnt1 = 0;
621                                 memset(avail, 0, info.disk.raid_disk);
622                                 max_events = info.events;
623                                 st->ss->getinfo_super(st, bestinfo);
624                         }
625                 }
626                 st->ss->free_super(st);
627         }
628         return cnt + cnt1;
629 }
630
631 void RebuildMap(void)
632 {
633         struct mdstat_ent *mdstat = mdstat_read(0, 0);
634         struct mdstat_ent *md;
635         struct map_ent *map = NULL;
636         int mdp = get_mdp_major();
637
638         for (md = mdstat ; md ; md = md->next) {
639                 struct mdinfo *sra = sysfs_read(-1, md->devnum, GET_DEVS);
640                 struct mdinfo *sd;
641
642                 for (sd = sra->devs ; sd ; sd = sd->next) {
643                         char dn[30];
644                         int dfd;
645                         int ok;
646                         struct supertype *st;
647                         char *path;
648                         struct mdinfo info;
649
650                         sprintf(dn, "%d:%d", sd->disk.major, sd->disk.minor);
651                         dfd = dev_open(dn, O_RDONLY);
652                         if (dfd < 0)
653                                 continue;
654                         st = guess_super(dfd);
655                         if ( st == NULL)
656                                 ok = -1;
657                         else
658                                 ok = st->ss->load_super(st, dfd, NULL);
659                         close(dfd);
660                         if (ok != 0)
661                                 continue;
662                         st->ss->getinfo_super(st, &info);
663                         if (md->devnum > 0)
664                                 path = map_dev(MD_MAJOR, md->devnum, 0);
665                         else
666                                 path = map_dev(mdp, (-1-md->devnum)<< 6, 0);
667                         map_add(&map, md->devnum,
668                                 info.text_version,
669                                 info.uuid, path ? : "/unknown");
670                         st->ss->free_super(st);
671                         break;
672                 }
673         }
674         map_write(map);
675         map_free(map);
676 }
677
678 int IncrementalScan(int verbose)
679 {
680         /* look at every device listed in the 'map' file.
681          * If one is found that is not running then:
682          *  look in mdadm.conf for bitmap file.
683          *   if one exists, but array has none, add it.
684          *  try to start array in auto-readonly mode
685          */
686         struct map_ent *mapl = NULL;
687         struct map_ent *me;
688         mddev_ident_t devs, mddev;
689         int rv = 0;
690
691         map_read(&mapl);
692         devs = conf_get_ident(NULL);
693
694         for (me = mapl ; me ; me = me->next) {
695                 char path[1024];
696                 mdu_array_info_t array;
697                 mdu_bitmap_file_t bmf;
698                 struct mdinfo *sra;
699                 int mdfd = open_mddev_devnum(me->path, me->devnum,
700                                              NULL, path, 0);
701                 if (mdfd < 0)
702                         continue;
703                 if (ioctl(mdfd, GET_ARRAY_INFO, &array) == 0 ||
704                     errno != ENODEV) {
705                         close(mdfd);
706                         continue;
707                 }
708                 /* Ok, we can try this one.   Maybe it needs a bitmap */
709                 for (mddev = devs ; mddev ; mddev = mddev->next)
710                         if (strcmp(mddev->devname, me->path) == 0)
711                                 break;
712                 if (mddev && mddev->bitmap_file) {
713                         /*
714                          * Note: early kernels will wrongly fail this, so it
715                          * is a hint only
716                          */
717                         int added = -1;
718                         if (ioctl(mdfd, GET_ARRAY_INFO, &bmf) < 0) {
719                                 int bmfd = open(mddev->bitmap_file, O_RDWR);
720                                 if (bmfd >= 0) {
721                                         added = ioctl(mdfd, SET_BITMAP_FILE,
722                                                       bmfd);
723                                         close(bmfd);
724                                 }
725                         }
726                         if (verbose >= 0) {
727                                 if (added == 0)
728                                         fprintf(stderr, Name
729                                                 ": Added bitmap %s to %s\n",
730                                                 mddev->bitmap_file, me->path);
731                                 else if (errno != EEXIST)
732                                         fprintf(stderr, Name
733                                            ": Failed to add bitmap to %s: %s\n",
734                                                 me->path, strerror(errno));
735                         }
736                 }
737                 sra = sysfs_read(mdfd, 0, 0);
738                 if (sra) {
739                         if (sysfs_set_str(sra, NULL,
740                                           "array_state", "read-auto") == 0) {
741                                 if (verbose >= 0)
742                                         fprintf(stderr, Name
743                                                 ": started array %s\n",
744                                                 me->path);
745                         } else {
746                                 fprintf(stderr, Name
747                                         ": failed to start array %s: %s\n",
748                                         me->path, strerror(errno));
749                                 rv = 1;
750                         }
751                 }
752         }
753         return rv;
754 }
755
756 static char *container2devname(char *devname)
757 {
758         int fd = open(devname, O_RDONLY);
759         char *mdname = NULL;
760
761         if (fd >= 0) {
762                 mdname = devnum2devname(fd2devnum(fd));
763                 close(fd);
764         }
765
766         return mdname;
767 }
768
769 int Incremental_container(struct supertype *st, char *devname, int verbose,
770                           int runstop, int autof)
771 {
772         /* Collect the contents of this container and for each
773          * array, choose a device name and assemble the array.
774          */
775
776         struct mdinfo *list = st->ss->container_content(st);
777         struct mdinfo *ra;
778         char *mdname = container2devname(devname);
779
780         if (!mdname) {
781                 fprintf(stderr, Name": failed to determine device name\n");
782                 return 2;
783         }
784
785         for (ra = list ; ra ; ra = ra->next) {
786                 struct mdinfo *dev;
787                 int devnum = -1;
788                 int mdfd;
789                 char chosen_name[1024];
790                 int usepart = 1;
791                 char *n;
792                 int working = 0, preexist = 0;
793                 struct map_ent *mp, *map = NULL;
794                 char nbuf[64];
795                 char *name_to_use;
796
797                 if ((autof&7) == 3 || (autof&7) == 5)
798                         usepart = 0;
799
800                 mp = map_by_uuid(&map, ra->uuid);
801
802                 name_to_use = ra->name;
803                 if (! name_to_use ||
804                     ! *name_to_use ||
805                     (*devname != '/' || strncmp("UUID-", strrchr(devname,'/')+1,5) == 0)
806                         )
807                         name_to_use = fname_from_uuid(st, ra, nbuf);
808                     
809                 if (mp)
810                         devnum = mp->devnum;
811                 else {
812
813                         n = name_to_use;
814                         if (*n == 'd')
815                                 n++;
816                         if (*n && devnum < 0) {
817                                 devnum = strtoul(n, &n, 10);
818                                 if (devnum >= 0 && (*n == 0 || *n == ' ')) {
819                                         /* Use this devnum */
820                                         usepart = (name_to_use[0] == 'd');
821                                         if (mddev_busy(usepart ? (-1-devnum) : devnum))
822                                                 devnum = -1;
823                                 } else
824                                         devnum = -1;
825                         }
826
827                         if (devnum < 0) {
828                                 char *nm = name_to_use;
829                                 char nbuf[1024];
830                                 struct stat stb;
831                                 if (strchr(nm, ':'))
832                                         nm = strchr(nm, ':')+1;
833                                 sprintf(nbuf, "/dev/md/%s", nm);
834
835                                 if (stat(nbuf, &stb) == 0 &&
836                                     S_ISBLK(stb.st_mode) &&
837                                     major(stb.st_rdev) == (usepart ?
838                                                            get_mdp_major() : MD_MAJOR)){
839                                         if (usepart)
840                                                 devnum = minor(stb.st_rdev)
841                                                         >> MdpMinorShift;
842                                         else
843                                                 devnum = minor(stb.st_rdev);
844                                         if (mddev_busy(usepart ? (-1-devnum) : devnum))
845                                                 devnum = -1;
846                                 }
847                         }
848
849                         if (devnum >= 0)
850                                 devnum = usepart ? (-1-devnum) : devnum;
851                         else
852                                 devnum = find_free_devnum(usepart);
853                 }
854                 mdfd = open_mddev_devnum(mp ? mp->path : NULL, devnum, name_to_use,
855                                          chosen_name, autof>>3);
856
857                 if (mdfd < 0) {
858                         fprintf(stderr, Name ": failed to open %s: %s.\n",
859                                 chosen_name, strerror(errno));
860                         return 2;
861                 }
862
863                 sysfs_init(ra, mdfd, 0);
864                 sysfs_set_array(ra, md_get_version(mdfd));
865                 for (dev = ra->devs; dev; dev = dev->next)
866                         if (sysfs_add_disk(ra, dev) == 0)
867                                 working++;
868                         else if (errno == EEXIST)
869                                 preexist++;
870                 if (working == 0)
871                         /* Nothing new, don't try to start */ ;
872                 else if (runstop > 0 ||
873                          (working + preexist) >= ra->array.working_disks) {
874                         switch(ra->array.level) {
875                         case LEVEL_LINEAR:
876                         case LEVEL_MULTIPATH:
877                         case 0:
878                                 sysfs_set_str(ra, NULL, "array_state",
879                                               "active");
880                                 break;
881                         default:
882                                 sysfs_set_str(ra, NULL, "array_state",
883                                               "readonly");
884                                 /* start mdmon if needed. */
885                                 if (!mdmon_running(st->container_dev))
886                                         start_mdmon(st->container_dev);
887                                 ping_monitor(devnum2devname(st->container_dev));
888                                 break;
889                         }
890                         sysfs_set_safemode(ra, ra->safe_mode_delay);
891                         if (verbose >= 0) {
892                                 fprintf(stderr, Name
893                                         ": Started %s with %d devices",
894                                         chosen_name, working + preexist);
895                                 if (preexist)
896                                         fprintf(stderr, " (%d new)", working);
897                                 fprintf(stderr, "\n");
898                         }
899                         /* FIXME should have an O_EXCL and wait for read-auto */
900                 } else
901                         if (verbose >= 0)
902                                 fprintf(stderr, Name
903                                         ": %s assembled with %d devices but "
904                                         "not started\n",
905                                         chosen_name, working);
906                 close(mdfd);
907                 map_update(&map, devnum,
908                            ra->text_version,
909                            ra->uuid, chosen_name);
910         }
911         return 0;
912 }