~xnox/ubuntu/quantal/mdadm/merge

« back to all changes in this revision

Viewing changes to mdadm.c

  • Committer: Dmitrijs Ledkovs
  • Author(s): Clint Byrum
  • Date: 2011-12-16 11:06:12 UTC
  • mfrom: (1.1.26 sid)
  • Revision ID: dmitrijs.ledkovs@canonical.com-20111216110612-f91bfvyfvxc1t0rq
Tags: 3.2.2-1ubuntu1
* Merge from debian unstable.  Remaining changes:
  - Call checks in local-premount to avoid race condition with udev
    and opening a degraded array.
  - d/initramfs/mdadm-functions: Record in /run when boot-degraded 
    question has been asked so that it is only asked once
  - pass --test to mdadm to enable result codes for degraded arrays. 
  - Build udeb with -O2 on ppc64, working around a link error.
  - debian/control: we need udev and util-linux in the right version. We
    also remove the build dependency from quilt and docbook-to-man as both
    are not used in Ubuntus mdadm.
  - debian/initramfs/hook: kept the Ubuntus version for handling the absence
    of active raid arrays in <initramfs>/etc/mdadm/mdadm.conf
  - debian/initramfs/script.local-top.DEBIAN, debian/mdadm-startall,
    debian/mdadm.raid.DEBIAN: removed. udev does its job now instead.
  - debian/mdadm-startall.sgml, debian/mdadm-startall.8: documentation of
    unused startall script
  - debian/mdadm.config, debian/mdadm.postinst - let udev do the handling
    instead. Resolved merge conflict by keeping Ubuntu's version.
  - debian/mdadm.postinst, debian/mdadm.config, initramfs/init-premount:
    boot-degraded enablement; maintain udev starting of RAID devices;
    init-premount hook script for the initramfs, to provide information at
    boot
  - debian/mkconf.in is the older mkconf. Kept the Ubuntu version.
  - debian/rules: Kept Ubuntus version for installing apport hooks, not
    installing un-used startall script and for adding a udev rule
    corresponding to mdadm.
  - debian/install-rc, check.d/_numbers, check.d/root_on_raid: Ubuntu partman
    installer changes
  - debian/presubj: Dropped this unused bug reporting file. Instead use
    source_mdadm.py act as an apport hook for bug handling.
  - rename debian/mdadm.vol_id.udev to debian/mdadm.mdadm-blkid.udev so that
    the rules file ends up with a more reasonable name
  - d/p/debian-changes-3.1.4-1+8efb9d1ubuntu4: mdadm udev rule
    incrementally adds mdadm member when detected. Starting such an
    array in degraded mode is possible by mdadm -IRs. Using mdadm
    -ARs without stopping the array first does nothing when no
    mdarray-unassociated device is available. Using mdadm -IRs to
    start a previously partially assembled array through incremental
    mode. Keeping the mdadm -ARs for assembling arrays which were for
    some reason not assembled through incremental mode (i.e through
    mdadm's udev rule).
* Disabling -fno-strict-aliasing as according to debian bug 375876 it
  has been unnecessary since mdadm 2.5.2
* Dropped changes:
  - applied upstream
  - d/rules: fix FTBFS by adding -Wno-unused-but-set-variable to
    compiler flags until upstream solves the issue. (fixed upstream)
  - d/control: add dependency on initscripts >= 2.88dsf-13.3 to ensure
    /run exists per http://wiki.debian.org/ReleaseGoals/RunDirectory
    (change also done in debian)
* d/rules: add 'man' to build mdadm.8

Show diffs side-by-side

added added

removed removed

Lines of Context:
46
46
        int layout = UnSet;
47
47
        char *layout_str = NULL;
48
48
        int raiddisks = 0;
49
 
        int max_disks = MD_SB_DISKS; /* just a default */
50
49
        int sparedisks = 0;
51
 
        struct mddev_ident_s ident;
 
50
        struct mddev_ident ident;
52
51
        char *configfile = NULL;
53
52
        char *cp;
54
53
        char *update = NULL;
55
54
        int scan = 0;
56
 
        char devmode = 0;
 
55
        int devmode = 0;
57
56
        int runstop = 0;
58
57
        int readonly = 0;
59
58
        int write_behind = 0;
60
59
        int bitmap_fd = -1;
61
60
        char *bitmap_file = NULL;
62
61
        char *backup_file = NULL;
 
62
        int invalid_backup = 0;
63
63
        int bitmap_chunk = UnSet;
64
64
        int SparcAdjust = 0;
65
 
        mddev_dev_t devlist = NULL;
66
 
        mddev_dev_t *devlistend = & devlist;
67
 
        mddev_dev_t dv;
 
65
        struct mddev_dev *devlist = NULL;
 
66
        struct mddev_dev **devlistend = & devlist;
 
67
        struct mddev_dev *dv;
68
68
        int devs_found = 0;
69
69
        int verbose = 0;
70
70
        int quiet = 0;
96
96
        int daemonise = 0;
97
97
        char *pidfile = NULL;
98
98
        int oneshot = 0;
 
99
        int spare_sharing = 1;
99
100
        struct supertype *ss = NULL;
100
101
        int writemostly = 0;
101
102
        int re_add = 0;
102
103
        char *shortopt = short_options;
103
104
        int dosyslog = 0;
104
105
        int rebuild_map = 0;
105
 
        int auto_update_home = 0;
106
106
        char *subarray = NULL;
 
107
        char *remove_path = NULL;
 
108
        char *udev_filename = NULL;
107
109
 
108
110
        int print_help = 0;
109
111
        FILE *outf;
133
135
                int newmode = mode;
134
136
                /* firstly, some mode-independent options */
135
137
                switch(opt) {
 
138
                case HelpOptions:
 
139
                        print_help = 2;
 
140
                        continue;
136
141
                case 'h':
137
 
                        if (option_index > 0 &&
138
 
                            strcmp(long_options[option_index].name, "help-options")==0)
139
 
                                print_help = 2;
140
 
                        else
141
 
                                print_help = 1;
 
142
                        print_help = 1;
142
143
                        continue;
143
144
 
144
145
                case 'V':
152
153
                        continue;
153
154
 
154
155
                case 'b':
155
 
                        if (mode == ASSEMBLE || mode == BUILD || mode == CREATE || mode == GROW ||
156
 
                            mode == INCREMENTAL || mode == MANAGE)
 
156
                        if (mode == ASSEMBLE || mode == BUILD || mode == CREATE
 
157
                            || mode == GROW || mode == INCREMENTAL
 
158
                            || mode == MANAGE)
157
159
                                break; /* b means bitmap */
 
160
                case Brief:
158
161
                        brief = 1;
159
162
                        continue;
160
163
 
179
182
                 */
180
183
 
181
184
                switch(opt) {
182
 
                case '@': /* just incase they say --manage */
 
185
                case ManageOpt:
183
186
                        newmode = MANAGE;
184
187
                        shortopt = short_bitmap_options;
185
188
                        break;
186
189
                case 'a':
 
190
                case Add:
187
191
                case 'r':
 
192
                case Remove:
188
193
                case 'f':
 
194
                case Fail:
189
195
                case ReAdd: /* re-add */
190
196
                        if (!mode) {
191
197
                                newmode = MANAGE;
205
211
                case AutoDetect:
206
212
                        newmode = AUTODETECT; break;
207
213
 
208
 
                case '#':
 
214
                case MiscOpt:
209
215
                case 'D':
210
216
                case 'E':
211
217
                case 'X':
215
221
                case 'o':
216
222
                case 'w':
217
223
                case 'W':
 
224
                case WaitOpt:
218
225
                case Waitclean:
219
226
                case DetailPlatform:
220
227
                case KillSubarray:
221
228
                case UpdateSubarray:
222
229
                        if (opt == KillSubarray || opt == UpdateSubarray) {
223
230
                                if (subarray) {
224
 
                                        fprintf(stderr, Name ": subarray can only be specified once\n");
 
231
                                        fprintf(stderr, Name ": subarray can only"
 
232
                                                " be specified once\n");
225
233
                                        exit(2);
226
234
                                }
227
235
                                subarray = optarg;
228
236
                        }
 
237
                case UdevRules:
229
238
                case 'K': if (!mode) newmode = MISC; break;
 
239
                case NoSharing: newmode = MONITOR; break;
230
240
                }
231
241
                if (mode && newmode == mode) {
232
242
                        /* everybody happy ! */
243
253
                        exit(2);
244
254
                } else if (!mode && newmode) {
245
255
                        mode = newmode;
 
256
                        if (mode == MISC && devs_found) {
 
257
                                fprintf(stderr, Name ": No action given for %s in --misc mode\n",
 
258
                                        devlist->devname);
 
259
                                fprintf(stderr,"       Action options must come before device names\n");
 
260
                                exit(2);
 
261
                        }
246
262
                } else {
247
263
                        /* special case of -c --help */
248
 
                        if (opt == 'c' &&
 
264
                        if ((opt == 'c' || opt == ConfigFile) &&
249
265
                            ( strncmp(optarg, "--h", 3)==0 ||
250
266
                              strncmp(optarg, "-h", 2)==0)) {
251
267
                                fputs(Help_config, stdout);
265
281
                                        dv->writemostly = writemostly;
266
282
                                        dv->re_add = re_add;
267
283
                                        dv->used = 0;
268
 
                                        dv->content = NULL;
269
284
                                        dv->next = NULL;
270
285
                                        *devlistend = dv;
271
286
                                        devlistend = &dv->next;
288
303
 
289
304
                /* if we just set the mode, then done */
290
305
                switch(opt) {
291
 
                case '@':
292
 
                case '#':
 
306
                case ManageOpt:
 
307
                case MiscOpt:
293
308
                case 'A':
294
309
                case 'B':
295
310
                case 'C':
302
317
                if (opt == 1) {
303
318
                        /* an undecorated option - must be a device name.
304
319
                         */
305
 
                        if (devs_found > 0 && mode == '@' && !devmode) {
306
 
                                fprintf(stderr, Name ": Must give one of -a/-r/-f for subsequent devices at %s\n", optarg);
 
320
                        if (devs_found > 0 && mode == MANAGE && !devmode) {
 
321
                                fprintf(stderr, Name ": Must give one of -a/-r/-f"
 
322
                                        " for subsequent devices at %s\n", optarg);
307
323
                                exit(2);
308
324
                        }
309
 
                        if (devs_found > 0 && mode == 'G' && !devmode) {
310
 
                                fprintf(stderr, Name ": Must give one of -a for devices do add: %s\n", optarg);
 
325
                        if (devs_found > 0 && mode == GROW && !devmode) {
 
326
                                fprintf(stderr, Name ": Must give -a/--add for"
 
327
                                        " devices to add: %s\n", optarg);
311
328
                                exit(2);
312
329
                        }
313
330
                        dv = malloc(sizeof(*dv));
320
337
                        dv->writemostly = writemostly;
321
338
                        dv->re_add = re_add;
322
339
                        dv->used = 0;
323
 
                        dv->content = NULL;
324
340
                        dv->next = NULL;
325
341
                        *devlistend = dv;
326
342
                        devlistend = &dv->next;
331
347
 
332
348
                /* We've got a mode, and opt is now something else which
333
349
                 * could depend on the mode */
334
 
#define O(a,b) ((a<<8)|b)
 
350
#define O(a,b) ((a<<16)|b)
335
351
                switch (O(mode,opt)) {
336
352
                case O(GROW,'c'):
 
353
                case O(GROW,ChunkSize):
337
354
                case O(CREATE,'c'):
 
355
                case O(CREATE,ChunkSize):
338
356
                case O(BUILD,'c'): /* chunk or rounding */
 
357
                case O(BUILD,ChunkSize): /* chunk or rounding */
339
358
                        if (chunk) {
340
359
                                fprintf(stderr, Name ": chunk/rounding may only be specified once. "
341
360
                                        "Second value is %s.\n", optarg);
342
361
                                exit(2);
343
362
                        }
344
 
                        chunk = strtol(optarg, &c, 10);
345
 
                        if (!optarg[0] || *c || chunk<4 || ((chunk-1)&chunk)) {
 
363
                        chunk = parse_size(optarg);
 
364
                        if (chunk < 8 || (chunk&1)) {
346
365
                                fprintf(stderr, Name ": invalid chunk/rounding value: %s\n",
347
366
                                        optarg);
348
367
                                exit(2);
349
368
                        }
 
369
                        /* Convert sectors to K */
 
370
                        chunk /= 2;
350
371
                        continue;
351
372
 
352
 
#if 0
353
 
                case O(ASSEMBLE,AutoHomeHost):
354
 
                        auto_update_home = 1;
355
 
                        continue;
356
 
#endif
357
373
                case O(INCREMENTAL, 'e'):
358
374
                case O(CREATE,'e'):
359
375
                case O(ASSEMBLE,'e'):
369
385
                                fprintf(stderr, Name ": unrecognised metadata identifier: %s\n", optarg);
370
386
                                exit(2);
371
387
                        }
372
 
                        max_disks = ss->max_devs;
373
388
                        continue;
374
389
 
375
390
                case O(MANAGE,'W'):
 
391
                case O(MANAGE,WriteMostly):
376
392
                case O(BUILD,'W'):
 
393
                case O(BUILD,WriteMostly):
377
394
                case O(CREATE,'W'):
 
395
                case O(CREATE,WriteMostly):
378
396
                        /* set write-mostly for following devices */
379
397
                        writemostly = 1;
380
398
                        continue;
456
474
                        continue;
457
475
 
458
476
                case O(GROW, 'p'): /* new layout */
 
477
                case O(GROW, Layout):
459
478
                        if (layout_str) {
460
479
                                fprintf(stderr,Name ": layout may only be sent once.  "
461
480
                                        "Second value was %s\n", optarg);
466
485
                        continue;
467
486
 
468
487
                case O(CREATE,'p'): /* raid5 layout */
 
488
                case O(CREATE,Layout):
469
489
                case O(BUILD,'p'): /* faulty layout */
 
490
                case O(BUILD,Layout):
470
491
                        if (layout != UnSet) {
471
492
                                fprintf(stderr,Name ": layout may only be sent once.  "
472
493
                                        "Second value was %s\n", optarg);
521
542
 
522
543
                case O(CREATE,AssumeClean):
523
544
                case O(BUILD,AssumeClean): /* assume clean */
 
545
                case O(GROW,AssumeClean):
524
546
                        assume_clean = 1;
525
547
                        continue;
526
548
 
561
583
                        continue;
562
584
 
563
585
                case O(CREATE,'a'):
 
586
                case O(CREATE,Auto):
564
587
                case O(BUILD,'a'):
 
588
                case O(BUILD,Auto):
565
589
                case O(INCREMENTAL,'a'):
566
 
                case O(ASSEMBLE,'a'): /* auto-creation of device node */
 
590
                case O(INCREMENTAL,Auto):
 
591
                case O(ASSEMBLE,'a'):
 
592
                case O(ASSEMBLE,Auto): /* auto-creation of device node */
567
593
                        autof = parse_auto(optarg, "--auto flag", 0);
568
594
                        continue;
569
595
 
574
600
                        continue;
575
601
 
576
602
                case O(BUILD,'f'): /* force honouring '-n 1' */
 
603
                case O(BUILD,Force): /* force honouring '-n 1' */
577
604
                case O(GROW,'f'): /* ditto */
 
605
                case O(GROW,Force): /* ditto */
578
606
                case O(CREATE,'f'): /* force honouring of device list */
 
607
                case O(CREATE,Force): /* force honouring of device list */
579
608
                case O(ASSEMBLE,'f'): /* force assembly */
 
609
                case O(ASSEMBLE,Force): /* force assembly */
580
610
                case O(MISC,'f'): /* force zero */
 
611
                case O(MISC,Force): /* force zero */
581
612
                        force=1;
582
613
                        continue;
583
614
 
618
649
                        continue;
619
650
 
620
651
                case O(ASSEMBLE,'m'): /* super-minor for array */
 
652
                case O(ASSEMBLE,SuperMinor):
621
653
                        if (ident.super_minor != UnSet) {
622
654
                                fprintf(stderr, Name ": super-minor cannot be set twice.  "
623
655
                                        "Second value: %s.\n", optarg);
637
669
                case O(ASSEMBLE,'U'): /* update the superblock */
638
670
                case O(MISC,'U'):
639
671
                        if (update) {
640
 
                                fprintf(stderr, Name ": Can only update one aspect of superblock, both %s and %s given.\n",
 
672
                                fprintf(stderr, Name ": Can only update one aspect"
 
673
                                        " of superblock, both %s and %s given.\n",
641
674
                                        update, optarg);
642
675
                                exit(2);
643
676
                        }
644
677
                        if (mode == MISC && !subarray) {
645
 
                                fprintf(stderr, Name ": Only subarrays can be updated in misc mode\n");
 
678
                                fprintf(stderr, Name ": Only subarrays can be"
 
679
                                        " updated in misc mode\n");
646
680
                                exit(2);
647
681
                        }
648
682
                        update = optarg;
662
696
                                continue;
663
697
                        if (strcmp(update, "devicesize")==0)
664
698
                                continue;
 
699
                        if (strcmp(update, "no-bitmap")==0)
 
700
                                continue;
665
701
                        if (strcmp(update, "byteorder")==0) {
666
702
                                if (ss) {
667
 
                                        fprintf(stderr, Name ": must not set metadata type with --update=byteorder.\n");
 
703
                                        fprintf(stderr,
 
704
                                                Name ": must not set metadata"
 
705
                                                " type with --update=byteorder.\n");
668
706
                                        exit(2);
669
707
                                }
670
708
                                for(i=0; !ss && superlist[i]; i++)
671
 
                                        ss = superlist[i]->match_metadata_desc("0.swap");
 
709
                                        ss = superlist[i]->match_metadata_desc(
 
710
                                                "0.swap");
672
711
                                if (!ss) {
673
 
                                        fprintf(stderr, Name ": INTERNAL ERROR cannot find 0.swap\n");
 
712
                                        fprintf(stderr, Name ": INTERNAL ERROR"
 
713
                                                " cannot find 0.swap\n");
674
714
                                        exit(2);
675
715
                                }
676
716
 
688
728
                        }
689
729
                        fprintf(outf, "Valid --update options are:\n"
690
730
                "     'sparc2.2', 'super-minor', 'uuid', 'name', 'resync',\n"
691
 
                "     'summaries', 'homehost', 'byteorder', 'devicesize'.\n");
 
731
                "     'summaries', 'homehost', 'byteorder', 'devicesize',\n"
 
732
                "     'no-bitmap'\n");
692
733
                        exit(outf == stdout ? 0 : 2);
693
734
 
 
735
                case O(MANAGE,'U'):
 
736
                        /* update=devicesize is allowed with --re-add */
 
737
                        if (devmode != 'a' || re_add != 1) {
 
738
                                fprintf(stderr, Name "--update in Manage mode only"
 
739
                                        " allowed with --re-add.\n");
 
740
                                exit(1);
 
741
                        }
 
742
                        if (update) {
 
743
                                fprintf(stderr, Name ": Can only update one aspect"
 
744
                                        " of superblock, both %s and %s given.\n",
 
745
                                        update, optarg);
 
746
                                exit(2);
 
747
                        }
 
748
                        update = optarg;
 
749
                        if (strcmp(update, "devicesize") != 0) {
 
750
                                fprintf(stderr, Name ": only 'devicesize' can be"
 
751
                                        " updated with --re-add\n");
 
752
                                exit(2);
 
753
                        }
 
754
                        continue;
 
755
 
694
756
                case O(INCREMENTAL,NoDegraded):
695
757
                        fprintf(stderr, Name ": --no-degraded is deprecated in Incremental mode\n");
696
758
                case O(ASSEMBLE,NoDegraded): /* --no-degraded */
698
760
                                       * so we overload slightly */
699
761
                        continue;
700
762
 
701
 
                case O(ASSEMBLE,'c'): /* config file */
 
763
                case O(ASSEMBLE,'c'):
 
764
                case O(ASSEMBLE,ConfigFile):
702
765
                case O(INCREMENTAL, 'c'):
 
766
                case O(INCREMENTAL, ConfigFile):
703
767
                case O(MISC, 'c'):
 
768
                case O(MISC, ConfigFile):
704
769
                case O(MONITOR,'c'):
 
770
                case O(MONITOR,ConfigFile):
705
771
                        if (configfile) {
706
772
                                fprintf(stderr, Name ": configfile cannot be set twice.  "
707
773
                                        "Second value is %s.\n", optarg);
719
785
                        continue;
720
786
 
721
787
                case O(MONITOR,'m'): /* mail address */
 
788
                case O(MONITOR,EMail):
722
789
                        if (mailaddr)
723
790
                                fprintf(stderr, Name ": only specify one mailaddress. %s ignored.\n",
724
791
                                        optarg);
727
794
                        continue;
728
795
 
729
796
                case O(MONITOR,'p'): /* alert program */
 
797
                case O(MONITOR,ProgramOpt): /* alert program */
730
798
                        if (program)
731
799
                                fprintf(stderr, Name ": only specify one alter program. %s ignored.\n",
732
800
                                        optarg);
735
803
                        continue;
736
804
 
737
805
                case O(MONITOR,'r'): /* rebuild increments */
 
806
                case O(MONITOR,Increment):
738
807
                        increments = atoi(optarg);
739
808
                        if (increments>99 || increments<1) {
740
809
                                fprintf(stderr, Name ": please specify positive integer between 1 and 99 as rebuild increments.\n");
759
828
                        }
760
829
                        continue;
761
830
                case O(MONITOR,'f'): /* daemonise */
 
831
                case O(MONITOR,Fork):
762
832
                        daemonise = 1;
763
833
                        continue;
764
834
                case O(MONITOR,'i'): /* pid */
778
848
                        openlog("mdadm", LOG_PID, SYSLOG_FACILITY);
779
849
                        dosyslog = 1;
780
850
                        continue;
781
 
 
 
851
                case O(MONITOR, NoSharing):
 
852
                        spare_sharing = 0;
 
853
                        continue;
782
854
                        /* now the general management options.  Some are applicable
783
855
                         * to other modes. None have arguments.
784
856
                         */
785
857
                case O(GROW,'a'):
786
 
                case O(MANAGE,'a'): /* add a drive */
 
858
                case O(GROW,Add):
 
859
                case O(MANAGE,'a'):
 
860
                case O(MANAGE,Add): /* add a drive */
787
861
                        devmode = 'a';
788
862
                        re_add = 0;
789
863
                        continue;
792
866
                        re_add = 1;
793
867
                        continue;
794
868
                case O(MANAGE,'r'): /* remove a drive */
 
869
                case O(MANAGE,Remove):
795
870
                        devmode = 'r';
796
871
                        continue;
797
872
                case O(MANAGE,'f'): /* set faulty */
798
 
                case O(INCREMENTAL,'f'): /* r for incremental is taken, use f
 
873
                case O(MANAGE,Fail):
 
874
                case O(INCREMENTAL,'f'):
 
875
                case O(INCREMENTAL,Remove):
 
876
                case O(INCREMENTAL,Fail): /* r for incremental is taken, use f
799
877
                                          * even though we will both fail and
800
878
                                          * remove the device */
801
879
                        devmode = 'f';
832
910
                case O(MISC,'o'):
833
911
                case O(MISC,'w'):
834
912
                case O(MISC,'W'):
 
913
                case O(MISC, WaitOpt):
835
914
                case O(MISC, Waitclean):
836
915
                case O(MISC, DetailPlatform):
837
916
                case O(MISC, KillSubarray):
853
932
                        }
854
933
                        devmode = opt;
855
934
                        continue;
 
935
               case O(MISC, UdevRules):
 
936
                       if (devmode && devmode != opt) {
 
937
                               fprintf(stderr, Name ": --udev-rules must"
 
938
                                       " be the only option.\n");
 
939
                       } else {
 
940
                               if (udev_filename)
 
941
                                       fprintf(stderr, Name ": only specify one udev "
 
942
                                               "rule filename. %s ignored.\n",
 
943
                                               optarg);
 
944
                               else
 
945
                                       udev_filename = optarg;
 
946
                       }
 
947
                       devmode = opt;
 
948
                       continue;
856
949
                case O(MISC,'t'):
857
950
                        test = 1;
858
951
                        continue;
866
959
                        continue;
867
960
 
868
961
                case O(ASSEMBLE,'b'): /* here we simply set the bitmap file */
 
962
                case O(ASSEMBLE,Bitmap):
869
963
                        if (!optarg) {
870
964
                                fprintf(stderr, Name ": bitmap file needed with -b in --assemble mode\n");
871
965
                                exit(2);
894
988
                        backup_file = optarg;
895
989
                        continue;
896
990
 
 
991
                case O(ASSEMBLE, InvalidBackup):
 
992
                        /* Acknowledge that the backupfile is invalid, but ask
 
993
                         * to continue anyway
 
994
                         */
 
995
                        invalid_backup = 1;
 
996
                        continue;
 
997
 
897
998
                case O(BUILD,'b'):
898
 
                case O(CREATE,'b'): /* here we create the bitmap */
 
999
                case O(BUILD,Bitmap):
 
1000
                case O(CREATE,'b'):
 
1001
                case O(CREATE,Bitmap): /* here we create the bitmap */
899
1002
                        if (strcmp(optarg, "none") == 0) {
900
1003
                                fprintf(stderr, Name ": '--bitmap none' only"
901
1004
                                        " support for --grow\n");
903
1006
                        }
904
1007
                        /* FALL THROUGH */
905
1008
                case O(GROW,'b'):
 
1009
                case O(GROW,Bitmap):
906
1010
                        if (strcmp(optarg, "internal")== 0 ||
907
1011
                            strcmp(optarg, "none")== 0 ||
908
1012
                            strchr(optarg, '/') != NULL) {
917
1021
                case O(GROW,BitmapChunk):
918
1022
                case O(BUILD,BitmapChunk):
919
1023
                case O(CREATE,BitmapChunk): /* bitmap chunksize */
920
 
                        bitmap_chunk = strtol(optarg, &c, 10);
921
 
                        if (!optarg[0] || *c || bitmap_chunk < 0 ||
922
 
                                        bitmap_chunk & (bitmap_chunk - 1)) {
923
 
                                fprintf(stderr, Name ": invalid bitmap chunksize: %s\n",
924
 
                                                optarg);
 
1024
                        bitmap_chunk = parse_size(optarg);
 
1025
                        if (bitmap_chunk < 0 ||
 
1026
                            bitmap_chunk & (bitmap_chunk - 1)) {
 
1027
                                fprintf(stderr,
 
1028
                                        Name ": invalid bitmap chunksize: %s\n",
 
1029
                                        optarg);
925
1030
                                exit(2);
926
1031
                        }
927
 
                        /* convert K to B, chunk of 0K means 512B */
928
 
                        bitmap_chunk = bitmap_chunk ? bitmap_chunk * 1024 : 512;
 
1032
                        /* convert sectors to B, chunk of 0 means 512B */
 
1033
                        bitmap_chunk = bitmap_chunk ? bitmap_chunk * 512 : 512;
929
1034
                        continue;
930
1035
 
931
1036
                case O(GROW, WriteBehind):
943
1048
                        continue;
944
1049
 
945
1050
                case O(INCREMENTAL, 'r'):
 
1051
                case O(INCREMENTAL, RebuildMapOpt):
946
1052
                        rebuild_map = 1;
947
1053
                        continue;
 
1054
                case O(INCREMENTAL, IncrementalPath):
 
1055
                        remove_path = optarg;
 
1056
                        continue;
948
1057
                }
949
1058
                /* We have now processed all the valid options. Anything else is
950
1059
                 * an error
1055
1164
        }
1056
1165
 
1057
1166
        if (raiddisks) {
1058
 
                if (raiddisks > max_disks) {
1059
 
                        fprintf(stderr, Name ": invalid number of raid devices: %d\n",
1060
 
                                raiddisks);
1061
 
                        exit(2);
1062
 
                }
1063
1167
                if (raiddisks == 1 &&  !force && level != -5) {
1064
1168
                        fprintf(stderr, Name ": '1' is an unusual number of drives for an array, so it is probably\n"
1065
1169
                                "     a mistake.  If you really mean it you will need to specify --force before\n"
1067
1171
                        exit(2);
1068
1172
                }
1069
1173
        }
1070
 
        if (sparedisks) {
1071
 
                if ( sparedisks > max_disks - raiddisks) {
1072
 
                        fprintf(stderr, Name ": invalid number of spare-devices: %d\n",
1073
 
                                sparedisks);
1074
 
                        exit(2);
1075
 
                }
1076
 
        }
1077
1174
 
1078
1175
        if (homehost == NULL)
1079
1176
                homehost = conf_get_homehost(&require_homehost);
1080
 
        if (homehost == NULL || strcmp(homehost, "<system>")==0) {
 
1177
        if (homehost == NULL || strcasecmp(homehost, "<system>")==0) {
1081
1178
                if (gethostname(sys_hostname, sizeof(sys_hostname)) == 0) {
1082
1179
                        sys_hostname[sizeof(sys_hostname)-1] = 0;
1083
1180
                        homehost = sys_hostname;
1084
1181
                }
1085
1182
        }
 
1183
        if (homehost && (!homehost[0] || strcasecmp(homehost, "<none>") == 0)) {
 
1184
                homehost = NULL;
 
1185
                require_homehost = 0;
 
1186
        }
1086
1187
 
1087
1188
        if ((mode != MISC || devmode != 'E') &&
1088
1189
            geteuid() != 0) {
1100
1201
                        rv = Manage_ro(devlist->devname, mdfd, readonly);
1101
1202
                if (!rv && devs_found>1)
1102
1203
                        rv = Manage_subdevs(devlist->devname, mdfd,
1103
 
                                            devlist->next, verbose-quiet, test);
 
1204
                                            devlist->next, verbose-quiet, test,
 
1205
                                            update);
1104
1206
                if (!rv && readonly < 0)
1105
1207
                        rv = Manage_ro(devlist->devname, mdfd, readonly);
1106
1208
                if (!rv && runstop)
1110
1212
                if (devs_found == 1 && ident.uuid_set == 0 &&
1111
1213
                    ident.super_minor == UnSet && ident.name[0] == 0 && !scan ) {
1112
1214
                        /* Only a device has been given, so get details from config file */
1113
 
                        mddev_ident_t array_ident = conf_get_ident(devlist->devname);
 
1215
                        struct mddev_ident *array_ident = conf_get_ident(devlist->devname);
1114
1216
                        if (array_ident == NULL) {
1115
1217
                                fprintf(stderr, Name ": %s not identified in config file.\n",
1116
1218
                                        devlist->devname);
1121
1223
                                if (array_ident->autof == 0)
1122
1224
                                        array_ident->autof = autof;
1123
1225
                                rv |= Assemble(ss, devlist->devname, array_ident,
1124
 
                                               NULL, backup_file,
 
1226
                                               NULL, backup_file, invalid_backup,
1125
1227
                                               readonly, runstop, update,
1126
1228
                                               homehost, require_homehost,
1127
1229
                                               verbose-quiet, force);
1128
1230
                        }
1129
1231
                } else if (!scan)
1130
1232
                        rv = Assemble(ss, devlist->devname, &ident,
1131
 
                                      devlist->next, backup_file,
 
1233
                                      devlist->next, backup_file, invalid_backup,
1132
1234
                                      readonly, runstop, update,
1133
1235
                                      homehost, require_homehost,
1134
1236
                                      verbose-quiet, force);
1142
1244
                                exit(1);
1143
1245
                        }
1144
1246
                        for (dv = devlist ; dv ; dv=dv->next) {
1145
 
                                mddev_ident_t array_ident = conf_get_ident(dv->devname);
 
1247
                                struct mddev_ident *array_ident = conf_get_ident(dv->devname);
1146
1248
                                if (array_ident == NULL) {
1147
1249
                                        fprintf(stderr, Name ": %s not identified in config file.\n",
1148
1250
                                                dv->devname);
1152
1254
                                if (array_ident->autof == 0)
1153
1255
                                        array_ident->autof = autof;
1154
1256
                                rv |= Assemble(ss, dv->devname, array_ident,
1155
 
                                               NULL, backup_file,
 
1257
                                               NULL, backup_file, invalid_backup,
1156
1258
                                               readonly, runstop, update,
1157
1259
                                               homehost, require_homehost,
1158
1260
                                               verbose-quiet, force);
1159
1261
                        }
1160
1262
                } else {
1161
 
                        mddev_ident_t a, array_list =  conf_get_ident(NULL);
1162
 
                        mddev_dev_t devlist = conf_get_devs();
 
1263
                        struct mddev_ident *a, *array_list =  conf_get_ident(NULL);
 
1264
                        struct mddev_dev *devlist = conf_get_devs();
1163
1265
                        int cnt = 0;
1164
1266
                        int failures, successes;
1165
1267
                        if (devlist == NULL) {
1193
1295
                                
1194
1296
                                        r = Assemble(ss, a->devname,
1195
1297
                                                     a,
1196
 
                                                     NULL, NULL,
 
1298
                                                     NULL, NULL, 0,
1197
1299
                                                     readonly, runstop, NULL,
1198
1300
                                                     homehost, require_homehost,
1199
1301
                                                     verbose-quiet, force);
1215
1317
                                int acnt;
1216
1318
                                ident.autof = autof;
1217
1319
                                do {
1218
 
                                        mddev_dev_t devlist = conf_get_devs();
 
1320
                                        struct mddev_dev *devlist = conf_get_devs();
1219
1321
                                        acnt = 0;
1220
1322
                                        do {
1221
1323
                                                rv2 = Assemble(ss, NULL,
1222
1324
                                                               &ident,
1223
 
                                                               devlist, NULL,
 
1325
                                                               devlist, NULL, 0,
1224
1326
                                                               readonly, runstop, NULL,
1225
1327
                                                               homehost, require_homehost,
1226
1328
                                                               verbose-quiet, force);
1228
1330
                                                        cnt++;
1229
1331
                                                        acnt++;
1230
1332
                                                }
1231
 
                                                if (rv2 == 1)
1232
 
                                                        /* found something so even though assembly failed  we
1233
 
                                                         * want to avoid auto-updates
1234
 
                                                         */
1235
 
                                                        auto_update_home = 0;
1236
1333
                                        } while (rv2!=2);
1237
1334
                                        /* Incase there are stacked devices, we need to go around again */
1238
1335
                                } while (acnt);
1239
 
#if 0
1240
 
                                if (cnt == 0 && auto_update_home && homehost) {
1241
 
                                        /* Nothing found, maybe we need to bootstrap homehost info */
1242
 
                                        do {
1243
 
                                                acnt = 0;
1244
 
                                                do {
1245
 
                                                        rv2 = Assemble(ss, NULL,
1246
 
                                                                       &ident,
1247
 
                                                                       NULL, NULL,
1248
 
                                                                       readonly, runstop, "homehost",
1249
 
                                                                       homehost, require_homehost,
1250
 
                                                                       verbose-quiet, force);
1251
 
                                                        if (rv2==0) {
1252
 
                                                                cnt++;
1253
 
                                                                acnt++;
1254
 
                                                        }
1255
 
                                                } while (rv2!=2);
1256
 
                                                /* Incase there are stacked devices, we need to go around again */
1257
 
                                        } while (acnt);
1258
 
                                }
1259
 
#endif
1260
1336
                                if (cnt == 0 && rv == 0) {
1261
1337
                                        fprintf(stderr, Name ": No arrays found in config file or automatically\n");
1262
1338
                                        rv = 1;
1409
1485
                                                free_mdstat(ms);
1410
1486
                                        } while (!last && err);
1411
1487
                                        if (err) rv |= 1;
 
1488
                                } else if (devmode == UdevRules) {
 
1489
                                        rv = Write_rules(udev_filename);
1412
1490
                                } else {
1413
1491
                                        fprintf(stderr, Name ": No devices given.\n");
1414
1492
                                        exit(2);
1438
1516
                                case 'X':
1439
1517
                                        rv |= ExamineBitmap(dv->devname, brief, ss); continue;
1440
1518
                                case 'W':
 
1519
                                case WaitOpt:
1441
1520
                                        rv |= Wait(dv->devname); continue;
1442
1521
                                case Waitclean:
1443
1522
                                        rv |= WaitClean(dv->devname, -1, verbose-quiet); continue;
1484
1563
                        break;
1485
1564
                }
1486
1565
                if (delay == 0) {
1487
 
                        if (get_linux_version() > 20616)
 
1566
                        if (get_linux_version() > 2006016)
1488
1567
                                /* mdstat responds to poll */
1489
1568
                                delay = 1000;
1490
1569
                        else
1492
1571
                }
1493
1572
                rv= Monitor(devlist, mailaddr, program,
1494
1573
                            delay?delay:60, daemonise, scan, oneshot,
1495
 
                            dosyslog, test, pidfile, increments);
 
1574
                            dosyslog, test, pidfile, increments, spare_sharing);
1496
1575
                break;
1497
1576
 
1498
1577
        case GROW:
1527
1606
                                break;
1528
1607
                        }
1529
1608
                }
1530
 
                if (devs_found > 1) {
1531
 
 
 
1609
                if (devs_found > 1 && raiddisks == 0) {
1532
1610
                        /* must be '-a'. */
1533
 
                        if (size >= 0 || raiddisks || chunk || layout_str != NULL || bitmap_file) {
1534
 
                                fprintf(stderr, Name ": --add cannot be used with other geometry changes in --grow mode\n");
 
1611
                        if (size >= 0 || chunk || layout_str != NULL || bitmap_file) {
 
1612
                                fprintf(stderr, Name ": --add cannot be used with "
 
1613
                                        "other geometry changes in --grow mode\n");
1535
1614
                                rv = 1;
1536
1615
                                break;
1537
1616
                        }
1538
1617
                        for (dv=devlist->next; dv ; dv=dv->next) {
1539
 
                                rv = Grow_Add_device(devlist->devname, mdfd, dv->devname);
 
1618
                                rv = Grow_Add_device(devlist->devname, mdfd,
 
1619
                                                     dv->devname);
1540
1620
                                if (rv)
1541
1621
                                        break;
1542
1622
                        }
1543
1623
                } else if (bitmap_file) {
1544
 
                        if (size >= 0 || raiddisks || chunk || layout_str != NULL) {
1545
 
                                fprintf(stderr, Name ": --bitmap changes cannot be used with other geometry changes in --grow mode\n");
 
1624
                        if (size >= 0 || raiddisks || chunk ||
 
1625
                            layout_str != NULL || devs_found > 1) {
 
1626
                                fprintf(stderr, Name ": --bitmap changes cannot be "
 
1627
                                        "used with other geometry changes "
 
1628
                                        "in --grow mode\n");
1546
1629
                                rv = 1;
1547
1630
                                break;
1548
1631
                        }
1553
1636
                } else if (size >= 0 || raiddisks != 0 || layout_str != NULL
1554
1637
                           || chunk != 0 || level != UnSet) {
1555
1638
                        rv = Grow_reshape(devlist->devname, mdfd, quiet, backup_file,
1556
 
                                          size, level, layout_str, chunk, raiddisks);
 
1639
                                          size, level, layout_str, chunk, raiddisks,
 
1640
                                          devlist->next,
 
1641
                                          assume_clean, force);
1557
1642
                } else if (array_size < 0)
1558
1643
                        fprintf(stderr, Name ": no changes to --grow\n");
1559
1644
                break;
1588
1673
                        rv = 1;
1589
1674
                        break;
1590
1675
                }
1591
 
                if (devmode == 'f') {
1592
 
                        rv = IncrementalRemove(devlist->devname, verbose-quiet);
1593
 
                        break;
1594
 
                }
1595
 
                rv = Incremental(devlist->devname, verbose-quiet, runstop,
1596
 
                                 ss, homehost, require_homehost, autof);
 
1676
                if (devmode == 'f')
 
1677
                        rv = IncrementalRemove(devlist->devname, remove_path,
 
1678
                                               verbose-quiet);
 
1679
                else
 
1680
                        rv = Incremental(devlist->devname, verbose-quiet,
 
1681
                                         runstop, ss, homehost,
 
1682
                                         require_homehost, autof);
1597
1683
                break;
1598
1684
        case AUTODETECT:
1599
1685
                autodetect();