Can now mostly assemble DDF arrays
[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, info2;
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         st->ss->getinfo_super(st, &info);
154         /* 3/ Check if there is a match in mdadm.conf */
155
156         array_list = conf_get_ident(NULL);
157         match = NULL;
158         for (; array_list; array_list = array_list->next) {
159                 if (array_list->uuid_set &&
160                     same_uuid(array_list->uuid, info.uuid, st->ss->swapuuid)
161                     == 0) {
162                         if (verbose >= 2)
163                                 fprintf(stderr, Name
164                                         ": UUID differs from %s.\n",
165                                         array_list->devname);
166                         continue;
167                 }
168                 if (array_list->name[0] &&
169                     strcasecmp(array_list->name, info.name) != 0) {
170                         if (verbose >= 2)
171                                 fprintf(stderr, Name
172                                         ": Name differs from %s.\n",
173                                         array_list->devname);
174                         continue;
175                 }
176                 if (array_list->devices &&
177                     !match_oneof(array_list->devices, devname)) {
178                         if (verbose >= 2)
179                                 fprintf(stderr, Name
180                                         ": Not a listed device for %s.\n",
181                                         array_list->devname);
182                         continue;
183                 }
184                 if (array_list->super_minor != UnSet &&
185                     array_list->super_minor != info.array.md_minor) {
186                         if (verbose >= 2)
187                                 fprintf(stderr, Name
188                                         ": Different super-minor to %s.\n",
189                                         array_list->devname);
190                         continue;
191                 }
192                 if (!array_list->uuid_set &&
193                     !array_list->name[0] &&
194                     !array_list->devices &&
195                     array_list->super_minor == UnSet) {
196                         if (verbose  >= 2)
197                                 fprintf(stderr, Name
198                              ": %s doesn't have any identifying information.\n",
199                                         array_list->devname);
200                         continue;
201                 }
202                 /* FIXME, should I check raid_disks and level too?? */
203
204                 if (match) {
205                         if (verbose >= 0)
206                                 fprintf(stderr, Name
207                    ": we match both %s and %s - cannot decide which to use.\n",
208                                         match->devname, array_list->devname);
209                         return 2;
210                 }
211                 match = array_list;
212         }
213
214         /* 3a/ if not, check for homehost match.  If no match, reject. */
215         if (!match) {
216                 if (homehost == NULL ||
217                     st->ss->match_home(st, homehost) == 0) {
218                         if (verbose >= 0)
219                                 fprintf(stderr, Name
220               ": not found in mdadm.conf and not identified by homehost.\n");
221                         return 2;
222                 }
223         }
224         /* 4/ Determine device number. */
225         /* - If in mdadm.conf with std name, use that */
226         /* - UUID in /var/run/mdadm.map  use that */
227         /* - If name is suggestive, use that. unless in use with */
228         /*           different uuid. */
229         /* - Choose a free, high number. */
230         /* - Use a partitioned device unless strong suggestion not to. */
231         /*         e.g. auto=md */
232         if (match && is_standard(match->devname, &devnum))
233                 /* We have devnum now */;
234         else if ((mp = map_by_uuid(&map, info.uuid)) != NULL)
235                 devnum = mp->devnum;
236         else {
237                 /* Have to guess a bit. */
238                 int use_partitions = 1;
239                 char *np, *ep;
240                 if ((autof&7) == 3 || (autof&7) == 5)
241                         use_partitions = 0;
242                 np = strchr(info.name, ':');
243                 if (np)
244                         np++;
245                 else
246                         np = info.name;
247                 devnum = strtoul(np, &ep, 10);
248                 if (ep > np && *ep == 0) {
249                         /* This is a number.  Let check that it is unused. */
250                         if (mddev_busy(use_partitions ? (-1-devnum) : devnum))
251                                 devnum = -1;
252                 } else
253                         devnum = -1;
254
255                 if (devnum < 0) {
256                         /* Haven't found anything yet, choose something free */
257                         devnum = find_free_devnum(use_partitions);
258
259                         if (devnum == NoMdDev) {
260                                 fprintf(stderr, Name
261                                         ": No spare md devices!!\n");
262                                 return 2;
263                         }
264                 } else
265                         devnum = use_partitions ? (-1-devnum) : devnum;
266         }
267         mdfd = open_mddev_devnum(match ? match->devname : NULL,
268                                  devnum,
269                                  info.name,
270                                  chosen_name, autof >> 3);
271         if (mdfd < 0) {
272                 fprintf(stderr, Name ": failed to open %s: %s.\n",
273                         chosen_name, strerror(errno));
274                 return 2;
275         }
276         /* 5/ Find out if array already exists */
277         if (! mddev_busy(devnum)) {
278         /* 5a/ if it does not */
279         /* - choose a name, from mdadm.conf or 'name' field in array. */
280         /* - create the array */
281         /* - add the device */
282                 mdu_array_info_t ainf;
283                 mdu_disk_info_t disk;
284                 char md[20];
285                 struct mdinfo *sra;
286
287                 memset(&ainf, 0, sizeof(ainf));
288                 ainf.major_version = st->ss->major;
289                 ainf.minor_version = st->minor_version;
290                 if (ioctl(mdfd, SET_ARRAY_INFO, &ainf) != 0) {
291                         fprintf(stderr, Name
292                                 ": SET_ARRAY_INFO failed for %s: %s\b",
293                                 chosen_name, strerror(errno));
294                         close(mdfd);
295                         return 2;
296                 }
297                 sprintf(md, "%d.%d\n", st->ss->major, st->minor_version);
298                 sra = sysfs_read(mdfd, devnum, GET_VERSION);
299                 sysfs_set_str(sra, NULL, "metadata_version", md);
300                 memset(&disk, 0, sizeof(disk));
301                 disk.major = major(stb.st_rdev);
302                 disk.minor = minor(stb.st_rdev);
303                 sysfs_free(sra);
304                 if (ioctl(mdfd, ADD_NEW_DISK, &disk) != 0) {
305                         fprintf(stderr, Name ": failed to add %s to %s: %s.\n",
306                                 devname, chosen_name, strerror(errno));
307                         ioctl(mdfd, STOP_ARRAY, 0);
308                         close(mdfd);
309                         return 2;
310                 }
311                 sra = sysfs_read(mdfd, devnum, GET_DEVS);
312                 if (!sra || !sra->devs || sra->devs->disk.raid_disk >= 0) {
313                         /* It really should be 'none' - must be old buggy
314                          * kernel, and mdadm -I may not be able to complete.
315                          * So reject it.
316                          */
317                         ioctl(mdfd, STOP_ARRAY, NULL);
318                         fprintf(stderr, Name
319                       ": You have an old buggy kernel which cannot support\n"
320                                 "      --incremental reliably.  Aborting.\n");
321                         close(mdfd);
322                         sysfs_free(sra);
323                         return 2;
324                 }
325         } else {
326         /* 5b/ if it does */
327         /* - check one drive in array to make sure metadata is a reasonably */
328         /*        close match.  Reject if not (e.g. different type) */
329         /* - add the device */
330                 char dn[20];
331                 int dfd2;
332                 mdu_disk_info_t disk;
333                 int err;
334                 struct mdinfo *sra;
335                 struct supertype *st2;
336                 sra = sysfs_read(mdfd, devnum, (GET_VERSION | GET_DEVS |
337                                                 GET_STATE));
338
339                 if (sra->array.major_version != st->ss->major ||
340                     sra->array.minor_version != st->minor_version) {
341                         if (verbose >= 0)
342                                 fprintf(stderr, Name
343               ": %s has different metadata to chosen array %s %d.%d %d.%d.\n",
344                                         devname, chosen_name,
345                                         sra->array.major_version,
346                                         sra->array.minor_version,
347                                         st->ss->major, st->minor_version);
348                         close(mdfd);
349                         return 1;
350                 }
351                 sprintf(dn, "%d:%d", sra->devs->disk.major,
352                         sra->devs->disk.minor);
353                 dfd2 = dev_open(dn, O_RDONLY);
354                 st2 = dup_super(st);
355                 if (st2->ss->load_super(st2, dfd2, NULL)) {
356                         fprintf(stderr, Name
357                                 ": Strange error loading metadata for %s.\n",
358                                 chosen_name);
359                         close(mdfd);
360                         close(dfd2);
361                         return 2;
362                 }
363                 close(dfd2);
364                 st2->ss->getinfo_super(st2, &info2);
365                 st2->ss->free_super(st2);
366                 if (info.array.level != info2.array.level ||
367                     memcmp(info.uuid, info2.uuid, 16) != 0 ||
368                     info.array.raid_disks != info2.array.raid_disks) {
369                         fprintf(stderr, Name
370                                 ": unexpected difference between %s and %s.\n",
371                                 chosen_name, devname);
372                         close(mdfd);
373                         return 2;
374                 }
375                 memset(&disk, 0, sizeof(disk));
376                 disk.major = major(stb.st_rdev);
377                 disk.minor = minor(stb.st_rdev);
378                 err = ioctl(mdfd, ADD_NEW_DISK, &disk);
379                 if (err < 0 && errno == EBUSY) {
380                         /* could be another device present with the same
381                          * disk.number. Find and reject any such
382                          */
383                         find_reject(mdfd, st, sra, info.disk.number,
384                                     info.events, verbose, chosen_name);
385                         err = ioctl(mdfd, ADD_NEW_DISK, &disk);
386                 }
387                 if (err < 0) {
388                         fprintf(stderr, Name ": failed to add %s to %s: %s.\n",
389                                 devname, chosen_name, strerror(errno));
390                         close(mdfd);
391                         return 2;
392                 }
393         }
394         /* 6/ Make sure /var/run/mdadm.map contains this array. */
395         map_update(&map, devnum,
396                    info.array.major_version,
397                    info.array.minor_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, st->ss->major,
632                                 st->minor_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 int Incremental_container(struct supertype *st, char *devname, int verbose,
721                           int runstop, int autof)
722 {
723         /* Collect the contents of this container and for each
724          * array, choose a device name and assemble the array.
725          */
726
727         struct mdinfo *list = st->ss->container_content(st);
728         struct mdinfo *ra;
729
730         for (ra = list ; ra ; ra = ra->next) {
731                 struct mdinfo *sra;
732                 struct mdinfo *dev;
733                 int devnum = -1;
734                 int mdfd;
735                 char chosen_name[1024];
736                 int usepart = 1;
737                 char *n;
738                 int working = 0;
739
740                 if ((autof&7) == 3 || (autof&7) == 5)
741                         usepart = 0;
742
743                 n = ra->name;
744                 if (*n == 'd')
745                         n++;
746                 if (*n) {
747                         devnum = strtoul(n, &n, 10);
748                         if (devnum >= 0 && (*n == 0 || *n == ' ')) {
749                                 /* Use this devnum */
750                                 usepart = (ra->name[0] == 'd');
751                                 if (mddev_busy(usepart ? (-1-devnum) : devnum))
752                                         devnum = -1;
753                         } else
754                                 devnum = -1;
755                 }
756
757                 if (devnum >= 0)
758                         devnum = usepart ? (-1-devnum) : devnum;
759                 else
760                         devnum = find_free_devnum(usepart);
761                 mdfd = open_mddev_devnum(NULL, devnum, ra->name,
762                                          chosen_name, autof>>3);
763
764                 if (mdfd < 0) {
765                         fprintf(stderr, Name ": failed to open %s: %s.\n",
766                                 chosen_name, strerror(errno));
767                         return 2;
768                 }
769
770                 sra = sysfs_read(mdfd, 0, 0);
771
772                 sysfs_set_array(sra, ra);
773                 for (dev = ra->devs; dev; dev = dev->next) {
774                         char buf[20];
775                         int dfd;
776                         sprintf(buf, "%d:%d", dev->disk.major, dev->disk.minor);
777                         dfd = dev_open(buf, O_RDONLY);
778                         if (sysfs_add_disk(sra, dfd, dev) == 0)
779                                 working++;
780                 }
781                 if (runstop > 0 || working >= ra->array.working_disks) {
782                         switch(ra->array.level) {
783                         case LEVEL_LINEAR:
784                         case LEVEL_MULTIPATH:
785                         case 0:
786                                 sysfs_set_str(sra, NULL, "array_state",
787                                               "active");
788                                 break;
789                         default:
790                                 sysfs_set_str(sra, NULL, "array_state",
791                                               "readonly");
792                                 break;
793                         }
794                         if (verbose >= 0)
795                                 printf("Started %s with %d devices\n",
796                                        chosen_name, working);
797                 } else
798                         if (verbose >= 0)
799                                 printf("%s assembled with %d devices but "
800                                        "not started\n",
801                                        chosen_name, working);
802                 close(mdfd);
803         }
804         return 0;
805 }