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

« back to all changes in this revision

Viewing changes to util.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:
146
146
{
147
147
        struct utsname name;
148
148
        char *cp;
149
 
        int a,b,c;
 
149
        int a = 0, b = 0,c = 0;
150
150
        if (uname(&name) <0)
151
151
                return -1;
152
152
 
153
153
        cp = name.release;
154
154
        a = strtoul(cp, &cp, 10);
155
 
        if (*cp != '.') return -1;
156
 
        b = strtoul(cp+1, &cp, 10);
157
 
        if (*cp != '.') return -1;
158
 
        c = strtoul(cp+1, NULL, 10);
 
155
        if (*cp == '.')
 
156
                b = strtoul(cp+1, &cp, 10);
 
157
        if (*cp == '.')
 
158
                c = strtoul(cp+1, &cp, 10);
159
159
 
160
160
        return (a*1000000)+(b*1000)+c;
161
161
}
363
363
        struct mdu_array_info_s array;
364
364
        struct mdu_disk_info_s disk;
365
365
        int avail_disks = 0;
366
 
        int i;
 
366
        int i, rv;
367
367
        char *avail;
368
368
 
369
369
        if (ioctl(fd, GET_ARRAY_INFO, &array) != 0 ||
386
386
                avail[disk.raid_disk] = 1;
387
387
        }
388
388
        /* This is used on an active array, so assume it is clean */
389
 
        return enough(array.level, array.raid_disks, array.layout,
390
 
                      1,
391
 
                      avail, avail_disks);
 
389
        rv = enough(array.level, array.raid_disks, array.layout,
 
390
                    1, avail, avail_disks);
 
391
        free(avail);
 
392
        return rv;
392
393
}
393
394
 
394
395
 
535
536
        struct supertype *st = guess_super(fd);
536
537
 
537
538
        if (!st) return 0;
 
539
        st->ignore_hw_compat = 1;
538
540
        st->ss->load_super(st, fd, name);
539
541
        /* Looks like a raid array .. */
540
542
        fprintf(stderr, Name ": %s appears to be part of a raid array:\n",
639
641
         * We allow upto 2048Megabytes before converting to
640
642
         * gigabytes, as that shows more precision and isn't
641
643
         * too large a number.
642
 
         * Terrabytes are not yet handled.
 
644
         * Terabytes are not yet handled.
643
645
         */
644
646
 
645
647
        if (bytes < 5000*1024)
702
704
unsigned long long calc_array_size(int level, int raid_disks, int layout,
703
705
                                   int chunksize, unsigned long long devsize)
704
706
{
 
707
        devsize &= ~(unsigned long long)((chunksize>>9)-1);
 
708
        return get_data_disks(level, layout, raid_disks) * devsize;
 
709
}
 
710
 
 
711
int get_data_disks(int level, int layout, int raid_disks)
 
712
{
705
713
        int data_disks = 0;
706
714
        switch (level) {
707
715
        case 0: data_disks = raid_disks; break;
712
720
        case 10: data_disks = raid_disks / (layout & 255) / ((layout>>8)&255);
713
721
                break;
714
722
        }
715
 
        devsize &= ~(unsigned long long)((chunksize>>9)-1);
716
 
        return data_disks * devsize;
 
723
 
 
724
        return data_disks;
717
725
}
718
726
 
719
727
#if !defined(MDASSEMBLE) || defined(MDASSEMBLE) && defined(MDASSEMBLE_AUTO)
1120
1128
{
1121
1129
        struct GPT gpt;
1122
1130
        unsigned char empty_gpt_entry[16]= {0};
1123
 
        struct GPT_part_entry part;
 
1131
        struct GPT_part_entry *part;
 
1132
        char buf[512];
1124
1133
        unsigned long long curr_part_end;
1125
1134
        unsigned all_partitions, entry_size;
1126
1135
        unsigned part_nr;
1144
1153
 
1145
1154
        /* sanity checks */
1146
1155
        if (all_partitions > 1024 ||
1147
 
            entry_size > 512)
 
1156
            entry_size > sizeof(buf))
1148
1157
                return -1;
1149
1158
 
 
1159
        part = (struct GPT_part_entry *)buf;
 
1160
 
1150
1161
        for (part_nr=0; part_nr < all_partitions; part_nr++) {
1151
1162
                /* read partition entry */
1152
 
                if (read(fd, &part, entry_size) != (ssize_t)entry_size)
 
1163
                if (read(fd, buf, entry_size) != (ssize_t)entry_size)
1153
1164
                        return 0;
1154
1165
 
1155
1166
                /* is this valid partition? */
1156
 
                if (memcmp(part.type_guid, empty_gpt_entry, 16) != 0) {
 
1167
                if (memcmp(part->type_guid, empty_gpt_entry, 16) != 0) {
1157
1168
                        /* check the last lba for the current partition */
1158
 
                        curr_part_end = __le64_to_cpu(part.ending_lba);
 
1169
                        curr_part_end = __le64_to_cpu(part->ending_lba);
1159
1170
                        if (curr_part_end > *endofpart)
1160
1171
                                *endofpart = curr_part_end;
1161
1172
                }
1369
1380
                if (!quiet)
1370
1381
                        fprintf(stderr, Name ": Couldn't open %s, aborting\n",
1371
1382
                                dev);
1372
 
                return 2;
 
1383
                return -1;
1373
1384
        }
1374
1385
 
1375
1386
        st->devnum = fd2devnum(fd);
1572
1583
 
1573
1584
int start_mdmon(int devnum)
1574
1585
{
1575
 
        int i;
 
1586
        int i, skipped;
1576
1587
        int len;
1577
1588
        pid_t pid;      
1578
1589
        int status;
1587
1598
        if (check_env("MDADM_NO_MDMON"))
1588
1599
                return 0;
1589
1600
 
1590
 
        len = readlink("/proc/self/exe", pathbuf, sizeof(pathbuf));
 
1601
        len = readlink("/proc/self/exe", pathbuf, sizeof(pathbuf)-1);
1591
1602
        if (len > 0) {
1592
1603
                char *sl;
1593
1604
                pathbuf[len] = 0;
1603
1614
        switch(fork()) {
1604
1615
        case 0:
1605
1616
                /* FIXME yuk. CLOSE_EXEC?? */
1606
 
                for (i=3; i < 100; i++)
1607
 
                        close(i);
 
1617
                skipped = 0;
 
1618
                for (i=3; skipped < 20; i++)
 
1619
                        if (close(i) < 0)
 
1620
                                skipped++;
 
1621
                        else
 
1622
                                skipped = 0;
 
1623
 
1608
1624
                for (i=0; paths[i]; i++)
1609
1625
                        if (paths[i][0])
1610
1626
                                execl(paths[i], "mdmon",
1697
1713
        if (check_env("MDADM_EXPERIMENTAL"))
1698
1714
                return 1;
1699
1715
        else {
1700
 
                fprintf(stderr, Name ": To use this feature MDADM_EXPERIMENTAL enviroment variable has to defined.\n");
 
1716
                fprintf(stderr, Name ": To use this feature MDADM_EXPERIMENTAL"
 
1717
                                " environment variable has to be defined.\n");
1701
1718
                return 0;
1702
1719
        }
1703
1720
}