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