]> git.ipfire.org Git - thirdparty/mdadm.git/commitdiff
Release 1.8.1 after some man page updates and other fixes. mdadm-1.11.1
authorNeil Brown <neilb@suse.de>
Tue, 7 Jun 2005 23:16:36 +0000 (23:16 +0000)
committerNeil Brown <neilb@suse.de>
Tue, 7 Jun 2005 23:16:36 +0000 (23:16 +0000)
Signed-off-by: Neil Brown <neilb@cse.unsw.edu.au>
Create.c
Makefile
md.4
mdadm.8
mdadm.spec
mdassemble.c
super0.c
super1.c
util.c

index 331835dbcb635b1c606261d2a1ee3828ee3af067..1717240bcf3deeeec377b79cc76b3ff47e4882a5 100644 (file)
--- a/Create.c
+++ b/Create.c
@@ -205,9 +205,9 @@ int Create(struct supertype *st, char *mddev, int mdfd,
                }
                else {
                        ldsize = dsize;
                }
                else {
                        ldsize = dsize;
-                       dsize <<= 9;
+                       ldsize <<= 9;
                }
                }
-               freesize = st->ss->avail_size(ldsize);
+               freesize = st->ss->avail_size(ldsize >> 9);
                if (freesize == 0) {
                        fprintf(stderr, Name ": %s is too small: %luK\n",
                                dname, (unsigned long)(ldsize>>10));
                if (freesize == 0) {
                        fprintf(stderr, Name ": %s is too small: %luK\n",
                                dname, (unsigned long)(ldsize>>10));
index cec6ed64050775a096d16af01a0b5c0a3b2f455f..dcb9b0fb9350dafaecef7befa1a45fb90f9b95c1 100644 (file)
--- a/Makefile
+++ b/Makefile
@@ -62,7 +62,7 @@ OBJS =  mdadm.o config.o mdstat.o  ReadMe.o util.o Manage.o Assemble.o Build.o \
 SRCS =  mdadm.c config.c mdstat.c  ReadMe.c util.c Manage.c Assemble.c Build.c \
        Create.c Detail.c Examine.c Grow.c Monitor.c dlink.c Kill.c Query.c mdopen.c super0.c super1.c
 
 SRCS =  mdadm.c config.c mdstat.c  ReadMe.c util.c Manage.c Assemble.c Build.c \
        Create.c Detail.c Examine.c Grow.c Monitor.c dlink.c Kill.c Query.c mdopen.c super0.c super1.c
 
-ASSEMBLE_SRCS := mdassemble.c Assemble.c config.c dlink.c util.c
+ASSEMBLE_SRCS := mdassemble.c Assemble.c config.c dlink.c util.c super0.c super1.c
 ifdef MDASSEMBLE_AUTO
 ASSEMBLE_SRCS += mdopen.c mdstat.c
 ASSEMBLE_FLAGS = -DMDASSEMBLE_AUTO
 ifdef MDASSEMBLE_AUTO
 ASSEMBLE_SRCS += mdopen.c mdstat.c
 ASSEMBLE_FLAGS = -DMDASSEMBLE_AUTO
diff --git a/md.4 b/md.4
index 4643dd2598f1cae9843c24cac1c578f7a9b2646f..d1fff0b20f9a864d4f229ec9650278f91df96581 100644 (file)
--- a/md.4
+++ b/md.4
@@ -16,7 +16,7 @@ Array of Independent Devices.
 .B md
 supports RAID levels 1 (mirroring) 4 (striped array with parity
 device), 5 (striped array with distributed parity information) and 6
 .B md
 supports RAID levels 1 (mirroring) 4 (striped array with parity
 device), 5 (striped array with distributed parity information) and 6
-(striped array with distributed dual redundancy information.)  If a
+(striped array with distributed dual redundancy information.)  If
 some number of underlying devices fails while using one of these
 levels, the array will continue to function; this number is one for
 RAID levels 4 and 5, two for RAID level 6, and all but one (N-1) for
 some number of underlying devices fails while using one of these
 levels, the array will continue to function; this number is one for
 RAID levels 4 and 5, two for RAID level 6, and all but one (N-1) for
@@ -24,24 +24,42 @@ RAID level 1.
 .PP
 .B md
 also supports a number of pseudo RAID (non-redundant) configurations
 .PP
 .B md
 also supports a number of pseudo RAID (non-redundant) configurations
-including RAID0 (striped array), LINEAR (catenated array) and
-MULTIPATH (a set of different interfaces to the same device).
+including RAID0 (striped array), LINEAR (catenated array),
+MULTIPATH (a set of different interfaces to the same device),
+and FAULTY (a layer over a single device into which errors can be injected).
 
 .SS MD SUPER BLOCK
 
 .SS MD SUPER BLOCK
-With the exception of Legacy Arrays described below, each device that
-is incorporated into an MD array has a
-.I super block
-written towards the end of the device.  This superblock records
-information about the structure and state of the array so that the
-array can be reliably re-assembled after a shutdown.
-
-The superblock is 4K long and is written into a 64K aligned block that
+Each device in an array may have a
+.I superblock
+which records information about the structure and state of the array.
+This allows the array to be reliably re-assembled after a shutdown.
+
+From Linux kernel version 2.6.10,
+.B md
+provides support for two different formats of this superblock, and
+other formats can be added.  Prior to this release, only one format is
+supported.
+
+The common format - known as version 0.90 - has
+a superblock that is 4K long and is written into a 64K aligned block that
 starts at least 64K and less than 128K from the end of the device
 (i.e. to get the address of the superblock round the size of the
 device down to a multiple of 64K and then subtract 64K).
 The available size of each device is the amount of space before the
 super block, so between 64K and 128K is lost when a device in
 incorporated into an MD array.
 starts at least 64K and less than 128K from the end of the device
 (i.e. to get the address of the superblock round the size of the
 device down to a multiple of 64K and then subtract 64K).
 The available size of each device is the amount of space before the
 super block, so between 64K and 128K is lost when a device in
 incorporated into an MD array.
+This superblock stores multi-byte fields in a processor-dependant
+manner, so arrays cannot easily be moved between computers with
+different processors.
+
+The new format - known as version 1 - has a superblock that is
+normally 1K long, but can be longer.  It is normally stored between 8K
+and 12K from the end of the device, on a 4K boundary, though
+variations can be stored at the start of the device (version 1.1) or 4K from
+the start of the device (version 1.2).
+This superblock format stores multibyte data in a
+processor-independant format and has supports upto hundreds of
+component devices (version 0.90 only supports 28).
 
 The superblock contains, among other things:
 .TP
 
 The superblock contains, among other things:
 .TP
@@ -53,17 +71,34 @@ UUID
 a 128 bit Universally Unique Identifier that identifies the array that
 this device is part of.
 
 a 128 bit Universally Unique Identifier that identifies the array that
 this device is part of.
 
-.SS LEGACY ARRAYS
+.SS ARRAYS WITHOUT SUPERBLOCKS
+While it is usually best to create arrays with superblocks so that
+they can be assembled reliably, there are some circumstances where an
+array without superblocks in preferred.  This include:
+.TP
+LEGACY ARRAYS
 Early versions of the
 .B md
 Early versions of the
 .B md
-driver only supported Linear and Raid0 configurations and so
-did not use an MD superblock (as there is no state that needs to be
-recorded).  While it is strongly recommended that all newly created
-arrays utilise a superblock to help ensure that they are assembled
-properly, the
+driver only supported Linear and Raid0 configurations and did not use
+a superblock (which is less critical with these configurations).
+While such arrays should be rebuilt with superblocks if possible,
 .B md
 .B md
-driver still supports legacy linear and raid0 md arrays that
-do not have a superblock.
+continues to support them.
+.TP
+FAULTY
+Being a largely transparent layer over a different device, the FAULTY
+personality doesn't gain anything from having a superblock.
+.TP
+MULTIPATH
+It is often possible to detect devices which are different paths to
+the same storage directly rather than having a distinctive superblock
+written to the device and searched for on all paths.  In this case,
+a MULTIPATH array with no superblock makes sense.
+.TP
+RAID1
+In some configurations it might be desired to create a raid1
+configuration that does use a superblock, and to maintain the state of
+the array elsewhere.  While not encouraged, this is supported.
 
 .SS LINEAR
 
 
 .SS LINEAR
 
diff --git a/mdadm.8 b/mdadm.8
index 3e1c64add498f80f5329837893fb1a58074eba10..45e0ff9ce884c53e8eb35001d9f735bacfa33f4d 100644 (file)
--- a/mdadm.8
+++ b/mdadm.8
@@ -1,5 +1,5 @@
 .\" -*- nroff -*-
 .\" -*- nroff -*-
-.TH MDADM 8 "" v1.11.0
+.TH MDADM 8 "" v1.11.1
 .SH NAME
 mdadm \- manage MD devices
 .I aka
 .SH NAME
 mdadm \- manage MD devices
 .I aka
@@ -92,7 +92,7 @@ information so as to assemble a faulty array.
 
 .TP
 .B Build
 
 .TP
 .B Build
-Build a legacy array without per-device superblocks.
+Build an array without per-device superblocks.
 
 .TP
 .B Create
 
 .TP
 .B Create
@@ -234,6 +234,24 @@ in which case
 says to get a list of array devices from
 .BR /proc/mdstat .
 
 says to get a list of array devices from
 .BR /proc/mdstat .
 
+.TP
+.B -e ", " --metadata=
+Declare the style of superblock (raid metadata) to be used.  The
+default is 0.90 for --create, and to guess for other operations.
+
+Options are:
+.RS
+.IP "0, 0.90, default"
+Use the original 0.90 format superblock.  This format limits arrays to
+28 componenet devices and limits component devices of levels 1 and
+greater to 2 terabytes.
+.IP "1, 1.0, 1.1, 1.2"
+Use the new version-1 format superblock.  This has few restrictions.
+The different subversion store the superblock at different locations
+on the device, either at the end (for 1.0), at the start (for 1.1) or
+4K from the start (for 1.2).
+.RE
+
 .SH For create or build:
 
 .TP
 .SH For create or build:
 
 .TP
index ffad476858c13b921fd1fc5ba45640c5b4dc81a4..cb42ed6413c2b90328268e6370b2444f0aa973ee 100644 (file)
@@ -1,6 +1,6 @@
 Summary:     mdadm is used for controlling Linux md devices (aka RAID arrays)
 Name:        mdadm
 Summary:     mdadm is used for controlling Linux md devices (aka RAID arrays)
 Name:        mdadm
-Version:     1.11.0
+Version:     1.11.1
 Release:     1
 Source:      http://www.cse.unsw.edu.au/~neilb/source/mdadm/mdadm-%{version}.tgz
 URL:         http://www.cse.unsw.edu.au/~neilb/source/mdadm/
 Release:     1
 Source:      http://www.cse.unsw.edu.au/~neilb/source/mdadm/mdadm-%{version}.tgz
 URL:         http://www.cse.unsw.edu.au/~neilb/source/mdadm/
index 43aed3c8377e1a2695d7be483f28157b93447601..597cdb8f1473458e835185ff6d22162ac8bd518e 100644 (file)
@@ -95,7 +95,7 @@ int main() {
                        if (ioctl(mdfd, GET_ARRAY_INFO, &array)>=0)
                                /* already assembled, skip */
                                continue;
                        if (ioctl(mdfd, GET_ARRAY_INFO, &array)>=0)
                                /* already assembled, skip */
                                continue;
-                       rv |= Assemble(array_list->devname, mdfd,
+                       rv |= Assemble(array_list->st, array_list->devname, mdfd,
                                           array_list, configfile,
                                           NULL,
                                           readonly, runstop, NULL, verbose, force);
                                           array_list, configfile,
                                           NULL,
                                           readonly, runstop, NULL, verbose, force);
index 4cf9277cfc78e23ab0b5f60ea59334dba02fcb6f..9346eb870a9b59d6cfbfc2fb6d6eb5cebc75a13b 100644 (file)
--- a/super0.c
+++ b/super0.c
@@ -415,6 +415,7 @@ static int store_super0(int fd, void *sbv)
        if (write(fd, super, sizeof(*super)) != sizeof(*super))
                return 4;
 
        if (write(fd, super, sizeof(*super)) != sizeof(*super))
                return 4;
 
+       fsync(fd);
        return 0;
 }
 
        return 0;
 }
 
index 736ed7ddeedfba4399ce5f35a1367fa5671d05db..628284ff983532165e6d84817f59d5ec92a85105 100644 (file)
--- a/super1.c
+++ b/super1.c
@@ -83,7 +83,9 @@ struct mdp_superblock_1 {
        __u16   dev_roles[0];   /* role in array, or 0xffff for a spare, or 0xfffe for faulty */
 };
 
        __u16   dev_roles[0];   /* role in array, or 0xffff for a spare, or 0xfffe for faulty */
 };
 
+#ifndef offsetof
 #define offsetof(t,f) ((int)&(((t*)0)->f))
 #define offsetof(t,f) ((int)&(((t*)0)->f))
+#endif
 static unsigned int calc_sb_1_csum(struct mdp_superblock_1 * sb)
 {
        unsigned int disk_csum, csum;
 static unsigned int calc_sb_1_csum(struct mdp_superblock_1 * sb)
 {
        unsigned int disk_csum, csum;
@@ -139,11 +141,11 @@ static void examine_super1(void *sbv)
        printf("     Raid Level : %s\n", c?c:"-unknown-");
        printf("   Raid Devices : %d\n", __le32_to_cpu(sb->raid_disks));
        printf("\n");
        printf("     Raid Level : %s\n", c?c:"-unknown-");
        printf("   Raid Devices : %d\n", __le32_to_cpu(sb->raid_disks));
        printf("\n");
-       printf("    Device Size : %llu%s\n", sb->data_size, human_size(sb->data_size<<9));
+       printf("    Device Size : %llu%s\n", (unsigned long long)sb->data_size, human_size(sb->data_size<<9));
        if (sb->data_offset)
        if (sb->data_offset)
-               printf("    Data Offset : %llu sectors\n", __le64_to_cpu(sb->data_offset));
+               printf("    Data Offset : %llu sectors\n", (unsigned long long)__le64_to_cpu(sb->data_offset));
        if (sb->super_offset)
        if (sb->super_offset)
-               printf("   Super Offset : %llu sectors\n", __le64_to_cpu(sb->super_offset));
+               printf("   Super Offset : %llu sectors\n", (unsigned long long)__le64_to_cpu(sb->super_offset));
        printf("    Device UUID : ");
        for (i=0; i<16; i++) {
                printf("%02x", sb->set_uuid[i]);
        printf("    Device UUID : ");
        for (i=0; i<16; i++) {
                printf("%02x", sb->set_uuid[i]);
@@ -159,7 +161,7 @@ static void examine_super1(void *sbv)
        else
                printf("       Checksum : %x - expected %x\n", __le32_to_cpu(sb->sb_csum),
                       __le32_to_cpu(calc_sb_1_csum(sb)));
        else
                printf("       Checksum : %x - expected %x\n", __le32_to_cpu(sb->sb_csum),
                       __le32_to_cpu(calc_sb_1_csum(sb)));
-       printf("         Events : %llu\n", __le64_to_cpu(sb->events));
+       printf("         Events : %llu\n", (unsigned long long)__le64_to_cpu(sb->events));
        printf("\n");
        if (__le32_to_cpu(sb->level) == 5) {
                c = map_num(r5layout, __le32_to_cpu(sb->layout));
        printf("\n");
        if (__le32_to_cpu(sb->level) == 5) {
                c = map_num(r5layout, __le32_to_cpu(sb->layout));
@@ -235,7 +237,7 @@ static void detail_super1(void *sbv)
                printf("%02x", sb->set_uuid[i]);
                if ((i&3)==0 && i != 0) printf(":");
        }
                printf("%02x", sb->set_uuid[i]);
                if ((i&3)==0 && i != 0) printf(":");
        }
-       printf("\n         Events : %llu\n\n", __le64_to_cpu(sb->events));
+       printf("\n         Events : %llu\n\n", (unsigned long long)__le64_to_cpu(sb->events));
 }
 
 static void brief_detail_super1(void *sbv)
 }
 
 static void brief_detail_super1(void *sbv)
@@ -452,6 +454,7 @@ static int store_super1(int fd, void *sbv)
        if (write(fd, sb, sbsize) != sbsize)
                return 4;
 
        if (write(fd, sb, sbsize) != sbsize)
                return 4;
 
+       fsync(fd);
        return 0;
 }
 
        return 0;
 }
 
@@ -575,15 +578,33 @@ static int load_super1(struct supertype *st, int fd, void **sbp, char *devname)
 
 
        if (st->ss == NULL) {
 
 
        if (st->ss == NULL) {
-               /* guess... */
+               int bestvers = -1;
+               __u64 bestctime = 0;
+               /* guess... choose latest ctime */
                st->ss = &super1;
                for (st->minor_version = 0; st->minor_version <= 2 ; st->minor_version++) {
                        switch(load_super1(st, fd, sbp, devname)) {
                st->ss = &super1;
                for (st->minor_version = 0; st->minor_version <= 2 ; st->minor_version++) {
                        switch(load_super1(st, fd, sbp, devname)) {
-                       case 0: return 0; /* good */
+                       case 0: super = *sbp;
+                               if (bestvers == -1 ||
+                                   bestctime < __le64_to_cpu(super->ctime)) {
+                                       bestvers = st->minor_version;
+                                       bestctime = __le64_to_cpu(super->ctime);
+                               }
+                               free(super);
+                               *sbp = NULL;
+                               break;
                        case 1: st->ss = NULL; return 1; /*bad device */
                        case 2: break; /* bad, try next */
                        }
                }
                        case 1: st->ss = NULL; return 1; /*bad device */
                        case 2: break; /* bad, try next */
                        }
                }
+               if (bestvers != -1) {
+                       int rv;
+                       st->minor_version = bestvers;
+                       st->ss = &super1;
+                       rv = load_super1(st, fd, sbp, devname);
+                       if (rv) st->ss = NULL;
+                       return rv;
+               }
                st->ss = NULL;
                return 2;
        }
                st->ss = NULL;
                return 2;
        }
diff --git a/util.c b/util.c
index bb4a4794b823ac96d74226386bd4f01911b257fc..010764ea0661b5a8c0a7fbaa326e29fa9e9621da 100644 (file)
--- a/util.c
+++ b/util.c
@@ -386,6 +386,15 @@ unsigned long calc_csum(void *super, int bytes)
        for(i=0; i<bytes/4; i++)
                newcsum+= superc[i];
        csum = (newcsum& 0xffffffff) + (newcsum>>32);
        for(i=0; i<bytes/4; i++)
                newcsum+= superc[i];
        csum = (newcsum& 0xffffffff) + (newcsum>>32);
+#ifdef __alpha__
+/* The in-kernel checksum calculation is always 16bit on 
+ * the alpha, though it is 32 bit on i386...
+ * I wonder what it is elsewhere... (it uses and API in
+ * a way that it shouldn't).
+ */
+       csum = (csum & 0xffff) + (csum >> 16);
+       csum = (csum & 0xffff) + (csum >> 16);
+#endif
        return csum;
 }
 
        return csum;
 }
 
@@ -544,6 +553,8 @@ struct supertype *guess_super(int fd)
         */
        struct superswitch  *ss;
        struct supertype *st;
         */
        struct superswitch  *ss;
        struct supertype *st;
+       unsigned long besttime = 0;
+       int bestsuper = -1;
        
        void *sbp = NULL;
        int i;
        
        void *sbp = NULL;
        int i;
@@ -554,10 +565,26 @@ struct supertype *guess_super(int fd)
                int rv;
                ss = superlist[i];
                rv = ss->load_super(st, fd, &sbp, NULL);
                int rv;
                ss = superlist[i];
                rv = ss->load_super(st, fd, &sbp, NULL);
+               if (rv == 0) {
+                       struct mdinfo info;
+                       ss->getinfo_super(&info, sbp);
+                       if (bestsuper == -1 ||
+                           besttime < info.array.ctime) {
+                               bestsuper = i;
+                               besttime = info.array.ctime;
+                               st->ss = NULL;
+                       }
+                       free(sbp);
+               }
+       }
+       if (bestsuper != -1) {
+               int rv;
+               rv = superlist[bestsuper]->load_super(st, fd, &sbp, NULL);
                if (rv == 0) {
                        free(sbp);
                        return st;
                }
        }
                if (rv == 0) {
                        free(sbp);
                        return st;
                }
        }
+       free(st);
        return NULL;
 }
        return NULL;
 }