~ubuntu-branches/ubuntu/precise/mdadm/precise-updates

« back to all changes in this revision

Viewing changes to Assemble.c

  • Committer: Package Import Robot
  • Author(s): Clint Byrum
  • Date: 2012-02-09 16:53:02 UTC
  • mfrom: (1.1.27 sid)
  • Revision ID: package-import@ubuntu.com-20120209165302-bs4cfosmhoga2rpt
Tags: 3.2.3-2ubuntu1
* Merge from Debian testing. (LP: #920324)  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).

Show diffs side-by-side

added added

removed removed

Lines of Context:
139
139
             char *backup_file, int invalid_backup,
140
140
             int readonly, int runstop,
141
141
             char *update, char *homehost, int require_homehost,
142
 
             int verbose, int force)
 
142
             int verbose, int force, int freeze_reshape)
143
143
{
144
144
        /*
145
145
         * The task of Assemble is to find a collection of
221
221
        int change = 0;
222
222
        int inargv = 0;
223
223
        int report_missmatch;
 
224
#ifndef MDASSEMBLE
224
225
        int bitmap_done;
 
226
#endif
225
227
        int start_partial_ok = (runstop >= 0) && 
226
228
                (force || devlist==NULL || auto_assem);
227
229
        unsigned int num_devs;
294
296
                char *devname = tmpdev->devname;
295
297
                int dfd;
296
298
                struct stat stb;
297
 
                struct supertype *tst = dup_super(st);
 
299
                struct supertype *tst;
298
300
                struct dev_policy *pol = NULL;
299
301
                int found_container = 0;
300
302
 
307
309
                        continue;
308
310
                }
309
311
 
 
312
                tst = dup_super(st);
 
313
 
310
314
                dfd = dev_open(devname, O_RDONLY|O_EXCL);
311
315
                if (dfd < 0) {
312
316
                        if (report_missmatch)
440
444
                             content;
441
445
                             content = content->next) {
442
446
 
443
 
                                /* do not assemble arrays that might have bad blocks */
444
 
                                if (content->array.state & (1<<MD_SB_BBM_ERRORS)) {
445
 
                                        fprintf(stderr, Name ": BBM log found in metadata. "
446
 
                                                                "Cannot activate array(s).\n");
447
 
                                        tmpdev->used = 2;
448
 
                                        goto loop;
449
 
                                }
450
447
                                if (!ident_matches(ident, content, tst,
451
448
                                                   homehost, update,
452
449
                                                   report_missmatch ? devname : NULL))
456
453
                                                fprintf(stderr, Name ": member %s in %s is already assembled\n",
457
454
                                                        content->text_version,
458
455
                                                        devname);
 
456
                                } else if (content->array.state & (1<<MD_SB_BLOCK_VOLUME)) {
 
457
                                        /* do not assemble arrays with unsupported configurations */
 
458
                                        fprintf(stderr, Name ": Cannot activate member %s in %s.\n",
 
459
                                                content->text_version,
 
460
                                                devname);
459
461
                                } else
460
462
                                        break;
461
463
                        }
698
700
                int err;
699
701
                err = assemble_container_content(st, mdfd, content, runstop,
700
702
                                                 chosen_name, verbose,
701
 
                                                 backup_file);
 
703
                                                 backup_file, freeze_reshape);
702
704
                close(mdfd);
703
705
                return err;
704
706
        }
 
707
        bitmap_done = 0;
705
708
#endif
706
709
        /* Ok, no bad inconsistancy, we can try updating etc */
707
 
        bitmap_done = 0;
708
 
        content->update_private = NULL;
709
710
        devices = malloc(num_devs * sizeof(*devices));
710
711
        devmap = calloc(num_devs * content->array.raid_disks, 1);
711
712
        for (tmpdev = devlist; tmpdev; tmpdev=tmpdev->next) if (tmpdev->used == 1) {
890
891
                }
891
892
                devcnt++;
892
893
        }
893
 
        free(content->update_private);
894
 
        content->update_private = NULL;
895
894
 
896
895
        if (devcnt == 0) {
897
896
                fprintf(stderr, Name ": no devices found for %s\n",
1344
1343
                        int rv;
1345
1344
#ifndef MDASSEMBLE
1346
1345
                        if (content->reshape_active &&
1347
 
                            content->delta_disks <= 0)
1348
 
                                rv = Grow_continue(mdfd, st, content, backup_file);
1349
 
                        else
 
1346
                            content->delta_disks <= 0) {
 
1347
                                rv = sysfs_set_str(content, NULL,
 
1348
                                                   "array_state", "readonly");
 
1349
                                if (rv == 0)
 
1350
                                        rv = Grow_continue(mdfd, st, content,
 
1351
                                                           backup_file,
 
1352
                                                           freeze_reshape);
 
1353
                        } else
1350
1354
#endif
1351
1355
                                rv = ioctl(mdfd, RUN_ARRAY, NULL);
1352
1356
                        if (rv == 0) {
1373
1377
                                                        sysfs_set_num(sra, NULL,
1374
1378
                                                                      "stripe_cache_size",
1375
1379
                                                                      (4 * content->array.chunk_size / 4096) + 1);
 
1380
                                                sysfs_free(sra);
1376
1381
                                        }
1377
1382
                                }
1378
1383
                                if (okcnt < (unsigned)content->array.raid_disks) {
1512
1517
int assemble_container_content(struct supertype *st, int mdfd,
1513
1518
                               struct mdinfo *content, int runstop,
1514
1519
                               char *chosen_name, int verbose,
1515
 
                               char *backup_file)
 
1520
                               char *backup_file, int freeze_reshape)
1516
1521
{
1517
1522
        struct mdinfo *dev, *sra;
1518
1523
        int working = 0, preexist = 0;
1524
1529
 
1525
1530
        sra = sysfs_read(mdfd, 0, GET_VERSION);
1526
1531
        if (sra == NULL || strcmp(sra->text_version, content->text_version) != 0)
1527
 
                if (sysfs_set_array(content, md_get_version(mdfd)) != 0)
 
1532
                if (sysfs_set_array(content, md_get_version(mdfd)) != 0) {
 
1533
                        if (sra)
 
1534
                                sysfs_free(sra);
1528
1535
                        return 1;
 
1536
                }
1529
1537
 
1530
 
        if (content->reshape_active)
 
1538
        if (st->ss->external && content->recovery_blocked)
1531
1539
                block_subarray(content);
1532
1540
 
1533
1541
        if (sra)
1553
1561
                 (working + preexist + expansion) >=
1554
1562
                        content->array.working_disks) {
1555
1563
                int err;
 
1564
                int start_reshape;
1556
1565
 
1557
 
                if (content->reshape_active) {
 
1566
                /* There are two types of reshape: container wide or sub-array specific
 
1567
                 * Check if metadata requests blocking container wide reshapes
 
1568
                 */
 
1569
                start_reshape = (content->reshape_active &&
 
1570
                                 !((content->reshape_active == CONTAINER_RESHAPE) &&
 
1571
                                   (content->array.state & (1<<MD_SB_BLOCK_CONTAINER_RESHAPE))));
 
1572
                if (start_reshape) {
1558
1573
                        int spare = content->array.raid_disks + expansion;
1559
 
                        int i;
1560
 
                        int *fdlist = malloc(sizeof(int) *
1561
 
                                             (working + expansion
1562
 
                                              + content->array.raid_disks));
1563
 
                        for (i=0; i<spare; i++)
1564
 
                                fdlist[i] = -1;
1565
 
                        for (dev = content->devs; dev; dev = dev->next) {
1566
 
                                char buf[20];
1567
 
                                int fd;
1568
 
                                sprintf(buf, "%d:%d",
1569
 
                                        dev->disk.major,
1570
 
                                        dev->disk.minor);
1571
 
                                fd = dev_open(buf, O_RDWR);
1572
 
 
1573
 
                                if (dev->disk.raid_disk >= 0)
1574
 
                                        fdlist[dev->disk.raid_disk] = fd;
1575
 
                                else
1576
 
                                        fdlist[spare++] = fd;
1577
 
                        }
1578
 
                        if (st->ss->external && st->ss->recover_backup)
1579
 
                                err = st->ss->recover_backup(st, content);
1580
 
                        else
1581
 
                                err = Grow_restart(st, content, fdlist, spare,
1582
 
                                                   backup_file, verbose > 0);
1583
 
                        while (spare > 0) {
1584
 
                                spare--;
1585
 
                                if (fdlist[spare] >= 0)
1586
 
                                        close(fdlist[spare]);
1587
 
                        }
1588
 
                        if (err) {
1589
 
                                fprintf(stderr, Name ": Failed to restore critical"
1590
 
                                        " section for reshape - sorry.\n");
1591
 
                                if (!backup_file)
1592
 
                                        fprintf(stderr, Name ":  Possibly you need"
1593
 
                                                " to specify a --backup-file\n");
1594
 
                                return 1;
1595
 
                        }
1596
 
 
1597
 
                        err = Grow_continue(mdfd, st, content, backup_file);
 
1574
                        if (restore_backup(st, content,
 
1575
                                           working,
 
1576
                                           spare, backup_file, verbose) == 1)
 
1577
                                return 1;
 
1578
 
 
1579
                        err = sysfs_set_str(content, NULL,
 
1580
                                            "array_state", "readonly");
 
1581
                        if (err)
 
1582
                                return 1;
 
1583
 
 
1584
                        if (st->ss->external) {
 
1585
                                if (!mdmon_running(st->container_dev))
 
1586
                                        start_mdmon(st->container_dev);
 
1587
                                ping_monitor_by_id(st->container_dev);
 
1588
                                if (mdmon_running(st->container_dev) &&
 
1589
                                                st->update_tail == NULL)
 
1590
                                        st->update_tail = &st->updates;
 
1591
                        }
 
1592
 
 
1593
                        err = Grow_continue(mdfd, st, content, backup_file,
 
1594
                                            freeze_reshape);
1598
1595
                } else switch(content->array.level) {
1599
1596
                case LEVEL_LINEAR:
1600
1597
                case LEVEL_MULTIPATH:
1618
1615
                if (verbose >= 0) {
1619
1616
                        if (err)
1620
1617
                                fprintf(stderr, Name
1621
 
                                        ": array %s now has %d devices",
1622
 
                                        chosen_name, working + preexist);
 
1618
                                        ": array %s now has %d device%s",
 
1619
                                        chosen_name, working + preexist,
 
1620
                                        working + preexist == 1 ? "":"s");
1623
1621
                        else
1624
1622
                                fprintf(stderr, Name
1625
 
                                        ": Started %s with %d devices",
1626
 
                                        chosen_name, working + preexist);
 
1623
                                        ": Started %s with %d device%s",
 
1624
                                        chosen_name, working + preexist,
 
1625
                                        working + preexist == 1 ? "":"s");
1627
1626
                        if (preexist)
1628
1627
                                fprintf(stderr, " (%d new)", working);
1629
1628
                        if (expansion)
1636
1635
                return err;
1637
1636
                /* FIXME should have an O_EXCL and wait for read-auto */
1638
1637
        } else {
1639
 
                if (verbose >= 0)
 
1638
                if (verbose >= 0) {
1640
1639
                        fprintf(stderr, Name
1641
 
                                ": %s assembled with %d devices but "
1642
 
                                "not started\n",
1643
 
                                chosen_name, working);
 
1640
                                ": %s assembled with %d device%s",
 
1641
                                chosen_name, preexist + working,
 
1642
                                preexist + working == 1 ? "":"s");
 
1643
                        if (preexist)
 
1644
                                fprintf(stderr, " (%d new)", working);
 
1645
                        fprintf(stderr, " but not started\n");
 
1646
                }
1644
1647
                return 1;
1645
1648
        }
1646
1649
}