mdadm-1.0.9 mdadm-1.0.9
authorNeil Brown <neilb@suse.de>
Wed, 12 Feb 2003 00:17:26 +0000 (00:17 +0000)
committerNeil Brown <neilb@suse.de>
Wed, 12 Feb 2003 00:17:26 +0000 (00:17 +0000)
21 files changed:
Assemble.c
ChangeLog
Detail.c
Examine.c
Makefile
Monitor.c
ReadMe.c
TODO
config.c
makedist
md.4
md_p.h
mdadm.8
mdadm.c
mdadm.conf-example
mdadm.conf.5
mdadm.h
mdadm.spec
mdadm.static [new file with mode: 0755]
test [new file with mode: 0644]
util.c

index 7868802..a2ff502 100644 (file)
@@ -35,6 +35,7 @@ int Assemble(char *mddev, int mdfd,
             mddev_ident_t ident, char *conffile,
             mddev_dev_t devlist,
             int readonly, int runstop,
+            char *update,
             int verbose, int force)
 {
        /*
@@ -72,7 +73,7 @@ int Assemble(char *mddev, int mdfd,
         * For each device:
         *   Check superblock - discard if bad
         *   Check uuid (set if we don't have one) - discard if no match
-        *   Check superblock similarity if we have a superbloc - discard if different
+        *   Check superblock similarity if we have a superblock - discard if different
         *   Record events, devicenum, utime
         * This should give us a list of devices for the array
         * We should collect the most recent event and utime numbers
@@ -103,8 +104,8 @@ int Assemble(char *mddev, int mdfd,
                time_t utime;
                int uptodate;
                int raid_disk;
-       } devices[MD_SB_DISKS];
-       int best[MD_SB_DISKS]; /* indexed by raid_disk */
+       } *devices;
+       int *best; /* indexed by raid_disk */
        int devcnt = 0, okcnt, sparecnt;
        int i;
        int most_recent = 0;
@@ -112,6 +113,8 @@ int Assemble(char *mddev, int mdfd,
        int change = 0;
        int inargv = 0;
        int start_partial_ok = force || devlist==NULL;
+       int num_devs;
+       mddev_dev_t tmpdev;
        
        vers = md_get_version(mdfd);
        if (vers <= 0) {
@@ -153,8 +156,16 @@ int Assemble(char *mddev, int mdfd,
                devlist = conf_get_devs(conffile);
        else inargv = 1;
 
+       tmpdev = devlist; num_devs = 0;
+       while (tmpdev) {
+               num_devs++;
+               tmpdev = tmpdev->next;
+       }
+       best = malloc(num_devs * sizeof(*best));
+       devices = malloc(num_devs * sizeof(*devices));
+
        first_super.md_magic = 0;
-       for (i=0; i<MD_SB_DISKS; i++)
+       for (i=0; i<num_devs; i++)
                best[i] = -1;
 
        if (verbose)
@@ -245,11 +256,48 @@ int Assemble(char *mddev, int mdfd,
                        return 1;
                }
 
+
+               /* this is needed until we get a more relaxed super block format */
                if (devcnt >= MD_SB_DISKS) {
                    fprintf(stderr, Name ": ouch - too many devices appear to be in this array. Ignoring %s\n",
                            devname);
                    continue;
                }
+               
+               /* looks like a good enough match to update the super block if needed */
+               if (update) {
+                       if (strcmp(update, "sparc2.2")==0 ) {
+                               /* 2.2 sparc put the events in the wrong place
+                                * So we copy the tail of the superblock
+                                * up 4 bytes before continuing
+                                */
+                               __u32 *sb32 = (__u32*)&super;
+                               memcpy(sb32+MD_SB_GENERIC_CONSTANT_WORDS+7,
+                                      sb32+MD_SB_GENERIC_CONSTANT_WORDS+7+1,
+                                      (MD_SB_WORDS - (MD_SB_GENERIC_CONSTANT_WORDS+7+1))*4);
+                               fprintf (stderr, Name ": adjusting superblock of %s for 2.2/sparc compatability.\n",
+                                        devname);
+                       }
+                       if (strcmp(update, "super-minor") ==0) {
+                               struct stat stb2;
+                               fstat(mdfd, &stb2);
+                               super.md_minor = MINOR(stb2.st_rdev);
+                               if (verbose)
+                                       fprintf(stderr, Name ": updating superblock of %s with minor number %d\n",
+                                               devname, super.md_minor);
+                       }
+                       super.sb_csum = calc_sb_csum(&super);
+                       dfd = open(devname, O_RDWR, 0);
+                       if (dfd < 0) 
+                               fprintf(stderr, Name ": Cannot open %s for superblock update\n",
+                                       devname);
+                       else if (store_super(dfd, &super))
+                               fprintf(stderr, Name ": Could not re-write superblock on %s.\n",
+                                       devname);
+                       if (dfd >= 0)
+                               close(dfd);
+               }
+
                if (verbose)
                        fprintf(stderr, Name ": %s is identified as a member of %s, slot %d.\n",
                                devname, mddev, super.this_disk.raid_disk);
@@ -267,8 +315,12 @@ int Assemble(char *mddev, int mdfd,
                            > devices[most_recent].events)
                                most_recent = devcnt;
                }
-               i = devices[devcnt].raid_disk;
-               if (i>=0 && i < MD_SB_DISKS)
+               if (super.level == -4) 
+                       /* with multipath, the raid_disk from the superblock is meaningless */
+                       i = devcnt;
+               else
+                       i = devices[devcnt].raid_disk;
+               if (i>=0 && i < num_devs)
                        if (best[i] == -1
                            || devices[best[i]].events < devices[devcnt].events)
                                best[i] = devcnt;
@@ -286,7 +338,7 @@ int Assemble(char *mddev, int mdfd,
         */
        okcnt = 0;
        sparecnt=0;
-       for (i=0; i< MD_SB_DISKS;i++) {
+       for (i=0; i< num_devs ;i++) {
                int j = best[i];
                int event_margin = !force;
                if (j < 0) continue;
@@ -337,6 +389,10 @@ int Assemble(char *mddev, int mdfd,
                }
                super.events_hi = (devices[most_recent].events>>32)&0xFFFFFFFF;
                super.events_lo = (devices[most_recent].events)&0xFFFFFFFF;
+               if (super.level == 5 || super.level == 4) {
+                       /* need to force clean */
+                       super.state = 0;
+               }
                super.sb_csum = calc_sb_csum(&super);
 /*DRYRUN*/     if (store_super(fd, &super)) {
                        close(fd);
@@ -358,7 +414,7 @@ int Assemble(char *mddev, int mdfd,
         * superblock.
         */
        chosen_drive = -1;
-       for (i=0; chosen_drive < 0 && i<MD_SB_DISKS; i++) {
+       for (i=0; chosen_drive < 0 && i<num_devs; i++) {
                int j = best[i];
                int fd;
                if (j<0)
@@ -380,7 +436,7 @@ int Assemble(char *mddev, int mdfd,
                close(fd);
        }
 
-       for (i=0; i<MD_SB_DISKS; i++) {
+       for (i=0; i<num_devs; i++) {
                int j = best[i];
                int desired_state;
 
@@ -457,9 +513,9 @@ This doesnt work yet
                        return 1;
                }
                /* First, add the raid disks, but add the chosen one last */
-               for (i=0; i<=MD_SB_DISKS; i++) {
+               for (i=0; i<= num_devs; i++) {
                        int j;
-                       if (i < MD_SB_DISKS) {
+                       if (i < num_devs) {
                                j = best[i];
                                if (j == chosen_drive)
                                        continue;
index 43adfa2..bc0653f 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,7 +1,37 @@
 Changes Prior to this release
+Changes Prior to 1.0.9 release
+    -   Documentation updates including kernel parameters documented
+       in md.4
+    -   --assemble --force for raid4/5 will mark clean, needed for 2.5
+    -   --detail prints out the events counter as well
+    -   flush device before reading superblock to be sure to get
+       current data
+    -   added mdadm.static target to makefile for static linking
+    -  --monitor was ignoring  /dev/md0 due to off-by-one error
+    -  Fix assorted typos
+    -   Fix printing of Gibibytes - calc was wrong.
+    -   Fix printing of Array Size in --detail when very big.
+    -   --monitor no longer tries to work for raid0 or linear as these
+       have nothing to be monitors.
+    -   The word 'partitions' on a DEVICE line will cause all partitions
+       listed in /proc/partitions to be considered
+    -   If the config file is called 'partitions' then it will be treated
+        as though it contained exactly 'device partitions' so e.g.
+         mdadm -Ebsc partitions
+       will fill all raid partitions easily.   
+    -  successfully assemble multipath devices by ignoring raid_disk
+       value from superblock (it is always the same).
+    -   --assemble not tied to MD_SB_DISKS limit quite so much
+    -   Support compiling with tcc
+    -   Support compiling with uclibc - just skip scan of /dev
+    -   Add --update= option for Assemble mode.  Either sparc2.2
+       or super-minor updates are possible.  See mdadm.8
+       
+Changes Prior to 1.0.1 release
     -   Round off MB/GiB etc values instead of round down.
     -   Add --sparc2.2 option to examine to shift superblock around
        and --sparc2.2update to rewrite the superblock
+    -   Fix assorted typos in online help
        
 Changes Prior to 1.0.0 release
     -   Allow --config with Misc mode (for --examine --scan)
index 55e6eb0..e675eda 100644 (file)
--- a/Detail.c
+++ b/Detail.c
@@ -102,7 +102,7 @@ int Detail(char *dev, int brief)
                printf("  Creation Time : %.24s\n", ctime(&atime));
                printf("     Raid Level : %s\n", c?c:"-unknown-");
                if (larray_size)
-               printf("     Array Size : %ld%s\n", (long)(larray_size>>10), human_size(larray_size));
+               printf("     Array Size : %llu%s\n", (larray_size>>10), human_size(larray_size));
                if (array.level >= 1)
                        printf("    Device Size : %d%s\n", array.size, human_size((long long)array.size<<10));
                printf("   Raid Devices : %d\n", array.raid_disks);
@@ -164,7 +164,7 @@ int Detail(char *dev, int brief)
                }
                if ((dv=map_dev(disk.major, disk.minor))) {
                        if (!brief) printf("   %s", dv);
-                       if (!have_super) {
+                       if (!have_super && (disk.state & (1<<MD_DISK_ACTIVE))) {
                                /* try to read the superblock from this device
                                 * to get more info
                                 */
@@ -186,7 +186,8 @@ int Detail(char *dev, int brief)
                               super.set_uuid2, super.set_uuid3);
                else
                        printf("%08x", super.set_uuid0);
-               if (!brief) printf("\n");
+               if (!brief) 
+                       printf("\n         Events : %d.%d\n", super.events_hi, super.events_lo);
        }
        if (brief) printf("\n");
        return 0;
index b886afc..0270108 100644 (file)
--- a/Examine.c
+++ b/Examine.c
@@ -170,7 +170,7 @@ int Examine(mddev_dev_t devlist, int brief, int scan, int SparcAdjust)
                                __u32 *sb32 = (__u32*)&super;
                                memcpy(sb32+MD_SB_GENERIC_CONSTANT_WORDS+7,
                                       sb32+MD_SB_GENERIC_CONSTANT_WORDS+7+1,
-                                      MD_SB_WORDS - (MD_SB_GENERIC_CONSTANT_WORDS+7+1));
+                                      (MD_SB_WORDS - (MD_SB_GENERIC_CONSTANT_WORDS+7+1))*4);
                                printf (" --- adjusting superblock for 2.2/sparc compatability ---\n");
                        }
                        printf("         Events : %d.%d\n", super.events_hi, super.events_lo);
index e355e96..82efc4c 100644 (file)
--- a/Makefile
+++ b/Makefile
@@ -29,6 +29,9 @@
 
 # define "CXFLAGS" to give extra flags to CC.
 # e.g.  make CXFLAGS=-O to optimise
+TCC = tcc
+UCLIBC_GCC = i386-uclibc-gcc
+
 CC = gcc
 CXFLAGS = -ggdb
 SYSCONFDIR = /etc
@@ -48,12 +51,24 @@ MAN5DIR = $(MANDIR)/man5
 MAN8DIR = $(MANDIR)/man8
 
 OBJS =  mdadm.o config.o mdstat.o  ReadMe.o util.o Manage.o Assemble.o Build.o Create.o Detail.o Examine.o Monitor.o dlink.o Kill.o Query.o
+SRCS =  mdadm.c config.c mdstat.c  ReadMe.c util.c Manage.c Assemble.c Build.c Create.c Detail.c Examine.c Monitor.c dlink.c Kill.c Query.c
 
 all : mdadm mdadm.man md.man mdadm.conf.man
 
+everything: all mdadm.static mdadm.tcc mdadm.uclibc
+
 mdadm : $(OBJS)
        $(CC) $(LDFLAGS) -o mdadm $^
 
+mdadm.static : $(OBJS)
+       $(CC) $(LDFLAGS) --static -o mdadm.static $^
+
+mdadm.tcc : $(SRCS) mdadm.h
+       $(TCC) -o mdadm.tcc $(SRCS)
+
+mdadm.uclibc : $(SRCS) mdadm.h
+       $(UCLIBC_GCC) -DUCLIBC -o mdadm.uclibc $(SRCS)
+
 mdadm.man : mdadm.8
        nroff -man mdadm.8 > mdadm.man
 
@@ -72,7 +87,7 @@ install : mdadm mdadm.8 md.4 mdadm.conf.5
        $(INSTALL) -D -m 644 mdadm.conf.5 $(DESTDIR)$(MAN5DIR)/mdadm.conf.5
 
 clean : 
-       rm -f mdadm $(OBJS) core *.man
+       rm -f mdadm $(OBJS) core *.man mdadm.tcc mdadm.uclibc
 
 dist : clean
        ./makedist
index fa0d708..d994dbe 100644 (file)
--- a/Monitor.c
+++ b/Monitor.c
@@ -182,6 +182,14 @@ int Monitor(mddev_dev_t devlist,
                                close(fd);
                                continue;
                        }
+                       if (array.level != 1 && array.level != 5 && array.level != -4) {
+                               if (!st->err)
+                                       alert("DeviceDisappeared", dev, "Wrong-Level",
+                                             mailaddr, alert_cmd);
+                               st->err = 1;
+                               close(fd);
+                               continue;
+                       }
                        if (st->devnum < 0) {
                                struct stat stb;
                                if (fstat(fd, &stb) == 0 &&
@@ -229,7 +237,7 @@ int Monitor(mddev_dev_t devlist,
                                if (ioctl(fd, GET_DISK_INFO, &disc)>= 0) {
                                        newstate = disc.state;
                                        dv = map_dev(disc.major, disc.minor);
-                               } else if (mse && i < strlen(mse->pattern))
+                               } else if (mse &&  mse->pattern && i < strlen(mse->pattern))
                                        switch(mse->pattern[i]) {
                                        case 'U': newstate = 6 /* ACTIVE/SYNC */; break;
                                        case '_': newstate = 0; break;
@@ -271,7 +279,11 @@ int Monitor(mddev_dev_t devlist,
                if (scan) {
                        struct mdstat_ent *mse;
                        for (mse=mdstat; mse; mse=mse->next) 
-                               if (mse->devnum > 0) {
+                               if (mse->devnum >= 0 &&
+                                   (strcmp(mse->level, "raid1")==0 ||
+                                    strcmp(mse->level, "raid5")==0 ||
+                                    strcmp(mse->level, "multipath")==0)
+                                       ) {
                                        struct state *st = malloc(sizeof *st);
                                        if (st == NULL)
                                                continue;
index 5c67eeb..390fee4 100644 (file)
--- a/ReadMe.c
+++ b/ReadMe.c
@@ -29,7 +29,7 @@
 
 #include "mdadm.h"
 
-char Version[] = Name " - v1.0.1 - 20 May 2002\n";
+char Version[] = Name " - v1.0.9 - 12 Feb 2003\n";
 /*
  * File: ReadMe.c
  *
@@ -60,14 +60,14 @@ char Version[] = Name " - v1.0.1 - 20 May 2002\n";
 /*
  * mdadm has 6 major modes of operation:
  * 1/ Create
- *     This mode is used to create a new array with a superbock
+ *     This mode is used to create a new array with a superblock
  *     It can progress in several step create-add-add-run
  *     or it can all happen with one command
  * 2/ Assemble
  *     This mode is used to assemble the parts of a previously created
  *     array into an active array.  Components can be explicitly given
  *     or can be searched for.  mdadm (optionally) check that the components
- *     do form a bonafide array, and can, on request, fiddle superblock
+ *     do form a bona-fide array, and can, on request, fiddle superblock
  *     version numbers so as to assemble a faulty array.
  * 3/ Build
  *     This is for building legacy arrays without superblocks
@@ -86,7 +86,7 @@ char Version[] = Name " - v1.0.1 - 20 May 2002\n";
  *     This mode never exits but just monitors arrays and reports changes.
  */
 
-char short_options[]="-ABCDEFGQhVvbc:l:p:m:n:x:u:c:d:z:sarfRSow";
+char short_options[]="-ABCDEFGQhVvbc:l:p:m:n:x:u:c:d:z:U:sarfRSow";
 struct option long_options[] = {
     {"manage",    0, 0, '@'},
     {"misc",      0, 0, '#'},
@@ -112,7 +112,7 @@ struct option long_options[] = {
     {"chunk",    1, 0, 'c'},
     {"rounding",  1, 0, 'c'}, /* for linear, chunk is really a rounding number */
     {"level",     1, 0, 'l'}, /* 0,1,4,5,linear */
-    {"parity",    1, 0, 'p'}, /* {left,right}-{a,}symetric */
+    {"parity",    1, 0, 'p'}, /* {left,right}-{a,}symmetric */
     {"layout",    1, 0, 'p'},
     {"raid-disks",1, 0, 'n'},
     {"raid-devices",1, 0, 'n'},
@@ -126,6 +126,7 @@ struct option long_options[] = {
     {"config",    1, 0, 'c'},
     {"scan",      0, 0, 's'},
     {"force",    0, 0, 'f'},
+    {"update",   1, 0, 'U'},
     /* Management */
     {"add",       0, 0, 'a'},
     {"remove",    0, 0, 'r'},
@@ -139,7 +140,6 @@ struct option long_options[] = {
     /* For Detail/Examine */
     {"brief",    0, 0, 'b'},
     {"sparc2.2",  0, 0, 22},
-    {"sparc2.2update", 0, 0, 23},
 
     /* For Follow/monitor */
     {"mail",      1, 0, 'm'},
@@ -164,7 +164,7 @@ char Help[] =
 "       mdadm --misc options... devices\n"
 "       mdadm --monitor options...\n"
 "       mdadm device options...\n"
-" mdadm is used for building, manageing, and monitoring\n"
+" mdadm is used for building, managing, and monitoring\n"
 "      Linux md devices (aka RAID arrays)\n"
 " For detail help on the above major modes use --help after the mode\n"
 " e.g.\n"
@@ -186,7 +186,7 @@ char Help[] =
 "  --build       -B   : Build a legacy array\n"
 "  --create      -C   : Create a new array\n"
 "  --detail      -D   : Display details of an array\n"
-"  --examine     -E   : Examine superblock on an array componenet\n"
+"  --examine     -E   : Examine superblock on an array component\n"
 "  --monitor     -F   : monitor (follow) some arrays\n"
 "  --query       -Q   : Display general information about how a\n"
 "                       device relates to the md driver\n"
@@ -195,9 +195,9 @@ char Help[] =
 "\n"
 " For create or build:\n"
 "  --chunk=      -c   : chunk size of kibibytes\n"
-"  --rounding=        : rounding factor for linear array (==chunck size)\n"
+"  --rounding=        : rounding factor for linear array (==chunk size)\n"
 "  --level=      -l   : raid level: 0,1,4,5,linear,mp.  0 or linear for build\n"
-"  --paritiy=    -p   : raid5 parity algorith: {left,right}-{,a}symmetric\n"
+"  --parity=     -p   : raid5 parity algorithm: {left,right}-{,a}symmetric\n"
 "  --layout=          : same as --parity\n"
 "  --raid-devices= -n : number of active devices in array\n"
 "  --spare-devices= -x: number of spares (eXtras) devices in initial array\n"
@@ -213,6 +213,7 @@ char Help[] =
 "  --config=     -c   : config file\n"
 "  --scan        -s   : scan config file for missing information\n"
 "  --force       -f   : Assemble the array even if some superblocks appear out-of-date\n"
+"  --update=     -U   : Update superblock: either sparc2.2 or super-minor\n"
 "\n"
 " For detail or examine:\n"
 "  --brief       -b   : Just print device name and UUID\n"
@@ -229,7 +230,7 @@ char Help[] =
 "  --fail        -f   : mark subsequent devices a faulty\n"
 "  --set-faulty       : same as --fail\n"
 "  --run         -R   : start a partially built array\n"
-"  --stop        -S   : deactive array, releasing all resources\n"
+"  --stop        -S   : deactivate array, releasing all resources\n"
 "  --readonly    -o   : mark array as readonly\n"
 "  --readwrite   -w   : mark array as readwrite\n"
 "  --zero-superblock  : erase the MD superblock from a device.\n"
@@ -259,9 +260,9 @@ char Help_create[] =
 "\n"
 " Options that are valid with --create (-C) are:\n"
 "  --chunk=      -c   : chunk size of kibibytes\n"
-"  --rounding=        : rounding factor for linear array (==chunck size)\n"
+"  --rounding=        : rounding factor for linear array (==chunk size)\n"
 "  --level=      -l   : raid level: 0,1,4,5,linear,multipath and synonyms\n"
-"  --paritiy=    -p   : raid5 parity algorith: {left,right}-{,a}symmetric\n"
+"  --parity=    -p   : raid5 parity algorithm: {left,right}-{,a}symmetric\n"
 "  --layout=          : same as --parity\n"
 "  --raid-devices= -n : number of active devices in array\n"
 "  --spare-devices= -x: number of spares (eXtras) devices in initial array\n"
@@ -287,7 +288,7 @@ char Help_build[] =
 " All devices must be listed and the array will be started once complete.\n"
 " Options that are valid with --build (-B) are:\n"
 "  --chunk=      -c   : chunk size of kibibytes\n"
-"  --rounding=        : rounding factor for linear array (==chunck size)\n"
+"  --rounding=        : rounding factor for linear array (==chunk size)\n"
 "  --level=      -l   : 0, raid0, or linear\n"
 "  --raid-devices= -n   : number of active devices in array\n"
 ;
@@ -335,6 +336,7 @@ char Help_assemble[] =
 "                       for a full array are present\n"
 "  --force       -f   : Assemble the array even if some superblocks appear\n"
 "                     : out-of-date.  This involves modifying the superblocks.\n"
+"  --update=     -U   : Update superblock: either sparc2.2 or super-minor\n"
 ;
 
 char Help_manage[] =
@@ -352,7 +354,7 @@ char Help_manage[] =
 "  --fail        -f   : mark subsequent devices a faulty\n"
 "  --set-faulty       : same as --fail\n"
 "  --run         -R   : start a partially built array\n"
-"  --stop        -S   : deactive array, releasing all resources\n"
+"  --stop        -S   : deactivate array, releasing all resources\n"
 "  --readonly    -o   : mark array as readonly\n"
 "  --readwrite   -w   : mark array as readwrite\n"
 ;
@@ -369,10 +371,10 @@ char Help_misc[] =
 "  --query       -Q   : Display general information about how a\n"
 "                       device relates to the md driver\n"
 "  --detail      -D   : Display details of an array\n"
-"  --examine     -E   : Examine superblock on an array componenet\n"
+"  --examine     -E   : Examine superblock on an array component\n"
 "  --zero-superblock  : erase the MD superblock from a device.\n"
 "  --run         -R   : start a partially built array\n"
-"  --stop        -S   : deactive array, releasing all resources\n"
+"  --stop        -S   : deactivate array, releasing all resources\n"
 "  --readonly    -o   : mark array as readonly\n"
 "  --readwrite   -w   : mark array as readwrite\n"
 ;
@@ -422,7 +424,7 @@ char Help_config[] =
 " array.  The identity can be given as a UUID with a word starting 'uuid=', or\n"
 " as a minor-number stored in the superblock using 'super-minor=', or as a list\n"
 " of devices.  This is given as a comma separated list of names, possibly\n"
-" containing wildcards, preceeded by 'devices='. If multiple critea are given,\n"
+" containing wildcards, preceded by 'devices='. If multiple critea are given,\n"
 " than a device must match all of them to be considered.\n"
 "\n"
 " A mailaddr line starts with the word 'mailaddr' and should contain exactly\n"
diff --git a/TODO b/TODO
index 8c484ab..3cafb8c 100644 (file)
--- a/TODO
+++ b/TODO
@@ -1,3 +1,22 @@
+* --assemble could have a --update option.
+  following word can be:
+       sparc2.2
+       super-minor
+
+* mdadm /dev/md11, where md11 is raid0 can segfault, particularly when looking in the 
+   [UU_UUU] string ... which doesn't exist !
+It should be more sensible.  DONE
+
+Example:
+
+from  Raimund Sacherer <raimund.sacherer@ngit.at>
+
+mke2fs -m0 -q /dev/ram1 300
+mount -n -t ext2 /dev/ram1 /tmp
+echo DEVICE /dev/[sh]* >> /tmp/mdadm.conf
+mdadm -Esb /dev/[sh]* 2>/dev/null >> /tmp/mdadm.conf
+mdadm -ARsc /tmp/mdadm.conf
+umount /tmp
 
 
 ?? Allow -S /dev/md? - current complains subsequent not a/d/r - DONE
index eef3248..1f25244 100644 (file)
--- a/config.c
+++ b/config.c
@@ -201,6 +201,33 @@ struct conf_dev {
     char *name;
 } *cdevlist = NULL;
 
+void load_partitions(void)
+{
+       FILE *f = fopen("/proc/partitions", "r");
+       char buf[1024];
+       if (f == NULL) {
+               fprintf(stderr, Name ": cannot open /proc/partitions\n");
+               return;
+       }
+       while (fgets(buf, 1024, f)) {
+               int major, minor;
+               char *name;
+               buf[1023] = '\0';
+               if (buf[0] != ' ')
+                       continue;
+               if (sscanf(buf, " %d %d ", &major, &minor) != 2)
+                       continue;
+               name = map_dev(major, minor);
+               if (name) {
+                       struct conf_dev *cd;
+
+                       cd = malloc(sizeof(*cd));
+                       cd->name = strdup(name);
+                       cd->next = cdevlist;
+                       cdevlist = cd;
+               }
+       }
+}
 
 
 void devline(char *line) 
@@ -214,6 +241,9 @@ void devline(char *line)
                        cd->name = strdup(w);
                        cd->next = cdevlist;
                        cdevlist = cd;
+               } else if (strcasecmp(w, "partitions") == 0) {
+                       /* read /proc/partitions, and look major/minor up in /dev */
+                       load_partitions();
                } else {
                        fprintf(stderr, Name ": unreconised word on DEVICE line: %s\n",
                                w);
@@ -349,6 +379,10 @@ void load_conffile(char *conffile)
        if (conffile == NULL)
                conffile = DefaultConfFile;
 
+       if (strcmp(conffile, "partitions")==0) {
+               load_partitions();
+               return;
+       }
        f = fopen(conffile, "r");
        if (f ==NULL)
                return;
index 89567da..7ead17a 100755 (executable)
--- a/makedist
+++ b/makedist
@@ -21,7 +21,7 @@ then
   exit 1
 fi
 trap "rm $target/$base; exit" 1 2 3
-( cd .. ; ln -s mdadm mdadm-$version ; tar czhvf - --exclude='*,v' --exclude='*.o' --exclude mdadm --exclude=RCS mdadm-$version ; rm mdadm-$version )  > $target/$base
+( cd .. ; ln -s mdadm mdadm-$version ; tar chvf - --exclude='*,v' --exclude='*.o' --exclude mdadm --exclude=mdadm'.[^ch0-9]' --exclude=RCS mdadm-$version ; rm mdadm-$version ) | gzip --best > $target/$base
 chmod a+r $target/$base
 ls -l $target/$base
 
diff --git a/md.4 b/md.4
index d3010c2..1ac98a3 100644 (file)
--- a/md.4
+++ b/md.4
@@ -99,7 +99,7 @@ still have remaining space.
 .SS RAID1
 
 A RAID1 array is also known as a mirrored set (though mirrors tend to
-provide reflect images, which RAID1 does not) or a plex.
+provide reflected images, which RAID1 does not) or a plex.
 
 Once initialised, each device in a RAID1 array contains exactly the
 same data.  Changes are written to all devices in parallel.  Data is
@@ -171,13 +171,16 @@ correct any possibly inconsistency.  For RAID1, this involves copying
 the contents of the first drive onto all other drives.
 For RAID4 or RAID5 this involves recalculating the parity for each
 stripe and making sure that the parity block has the correct data.
+This process, known as "resynchronising" or "resync" is performed in
+the background.  The array can still be used, though possibly with
+reduced performance.
 
 If a RAID4 or RAID5 array is degraded (missing one drive) when it is
 restarted after an unclean shutdown, it cannot recalculate parity, and
 so it is possible that data might be undetectably corrupted.
-The md driver currently
+The 2.4 md driver 
 .B does not
-alert the operator to this condition.  It should probably fail to
+alert the operator to this condition.  The 2.5 md driver will fail to
 start an array in this condition without manual intervention.
 
 .SS RECOVERY
@@ -201,6 +204,39 @@ and
 .B speed_limit_max
 control files mentioned below.
 
+.SS KERNEL PARAMETERS
+
+The md driver recognised three different kernel parameters.
+.TP
+.B raid=noautodetect
+This will disable the normal detection of md arrays that happens at
+boot time.  If a drive is partitioned with MS-DOS style partitions,
+then if any of the 4 main partitions has a partition type of 0xFD,
+then that partition will normally be inspected to see if it is part of
+an MD array, and if any full arrays are found, they are started.  This
+kernel paramenter disables this behaviour.
+
+.TP
+.BI md= n , dev , dev ,...
+This tells the md driver to assemble
+.B /dev/md n
+from the listed devices.  It is only necessary to start the device
+holding the root filesystem this way.  Other arrays are best started
+once the system is booted.
+
+.TP
+.BI md= n , l , c , i , dev...
+This tells the md driver to assemble a legacy RAID0 or LINEAR array
+without a superblock.
+.I n
+gives the md device number,
+.I l
+gives the level, 0 for RAID0 or -1 for LINEAR,
+.I c
+gives the chunk size as a base-2 logarithm offset by twelve, so 0
+means 4K, 1 means 8K.
+.I i
+is ignored (legacy support).
 
 .SH FILES
 .TP
diff --git a/md_p.h b/md_p.h
index 99479b4..bd9ccb1 100644 (file)
--- a/md_p.h
+++ b/md_p.h
@@ -163,6 +163,10 @@ typedef struct mdp_superblock_s {
 
 } mdp_super_t;
 
+#ifdef __TINYC__
+typedef unsigned long long __u64;
+#endif
+
 static inline __u64 md_event(mdp_super_t *sb) {
        __u64 ev = sb->events_hi;
        return (ev<<32)| sb->events_lo;
diff --git a/mdadm.8 b/mdadm.8
index a64ae65..c25dd7d 100644 (file)
--- a/mdadm.8
+++ b/mdadm.8
@@ -53,7 +53,7 @@ is a single program and not a collection of programs.
 .IP \(bu 4
 .B mdadm
 can perform (almost) all of its functions without having a
-configuration file.  Also
+configuration file and does not use one by default.  Also
 .B mdadm
 helps with management of the configuration
 file.
@@ -63,6 +63,14 @@ can provide information about your arrays (through Query, Detail, and Examine)
 that
 .B  raidtools
 cannot.
+.P
+.I mdadm
+does not use
+.IR /etc/raidtab ,
+the
+.B raidtools
+configuration file, at all.  It has a different configuration file
+with a different format and an different purpose.
 
 .SH MODES
 mdadm has 6 major modes of operation:
@@ -98,7 +106,11 @@ superblocks, erasing old superblocks and stopping active arrays.
 
 .TP
 .B "Follow or Monitor"
-Monitor one or more md devices and act on any state changes.
+Monitor one or more md devices and act on any state changes.  This is
+only meaningful for raid1, raid5 or multipath arrays as only these have
+interesting state.  raid0 or linear never have missing, spare, or
+failed drives, so there is nothing to monitor.  
+
 
 .SH OPTIONS
 
@@ -165,6 +177,15 @@ the exact meaning of this option in different contexts.
 .BR -c ", " --config=
 Specify the config file.  Default is
 .BR /etc/mdadm.conf .
+If the config file given is
+.B partitions
+then nothing will be read, but
+.I mdadm
+will act as though the config file contained exactly
+.B "DEVICE partitions"
+and will read
+.B /proc/partitions
+to find a list of devices to scan.
 
 .TP
 .BR -s ", " --scan
@@ -217,12 +238,21 @@ same as --parity
 
 .TP
 .BR -n ", " --raid-devices=
-number of active devices in array.
+Specify the number of active devices in the array.  This, plus the
+number of spare devices (see below) must equal the number of
+.I component-devices
+(including
+.B missing 
+devices) that are listed on the command line.
 
 .TP
 .BR -x ", " --spare-devices=
-number of spare (eXtra) devices in initial array.  Spares can be added
-and removed later.
+Specify the number of spare (eXtra) devices in the initial array.
+Spares can also be added
+and removed later.  The number of component devices listed
+on the command line must equal the number of raid devices plus the
+number of spare devices. 
+
 
 .TP
 .BR -z ", " --size=
@@ -262,6 +292,33 @@ With
 .B --run
 an attempt will be made to start it anyway.
 
+.TP
+.BR -U ", " --update=
+Update the superblock on each device while assembling the array.  The
+argument given to this flag can be either
+.B sparc2.2
+or
+.BR super-minor .
+
+The
+.B sparc2.2
+option will  adjust the superblock of an array what was created on a Sparc
+machine running a patched 2.2 Linux kernel.  This kernel got the
+alignment of part of the superblock wrong.  You can use the
+.B "--examine --sparc2.2"
+option to
+.I mdadm
+to see what effect this would have.
+
+The
+.B super-minor
+option will update the
+.B "prefered minor"
+field on each superblock to match the minor number of the array being
+assembled.  This is not need on 2.6 and later kernels as they make
+this adjustment automatically.
+
+
 .SH For Manage mode:
 
 .TP
@@ -282,6 +339,20 @@ mark listed devices as faulty.
 .BR --set-faulty
 same as --fail.
 
+.SH For Examine mode:
+
+.TP
+.B --sparc2.2
+In an array was created on a 2.2 Linux kernel patched with RAID
+support, the superblock will have been created incorrectly, or at
+least incompatibly with 2.4 and later kernels.  Using the
+.B --sparc2.2
+flag with
+.B --examine
+will fix the superblock before displaying it.  If this appears to do
+the right thing, then the array can be successfully assembled using
+.BR "--assemble --update=sparc2.2" .
+
 .SH For Misc mode:
 
 .TP
@@ -329,7 +400,11 @@ again.  The default is 60 seconds.
 .HP 12
 Usage:
 .B mdadm --assemble
-.I device options...
+.I md-device options-and-component-devices...
+.HP 12
+Usage:
+.B mdadm --assemble --scan
+.I  md-devices-and-options...
 .HP 12
 Usage:
 .B mdadm --assemble --scan
@@ -340,22 +415,26 @@ This usage assembles one or more raid arrays from pre-existing components.
 For each array, mdadm needs to know the md device, the identity of the
 array, and a number of component-devices. These can be found in a number of ways.
 
-The md device is either given before 
-.B --scan
-or is found from the config file. In the latter case, multiple md devices
-can be started with a single mdadm command.
+In the first usage example (without the
+.BR --scan )
+the first device given is the md device.
+In the second usage example, all devices listed are treated as md
+devices and assembly is attempted.
+In the third (where no devices are listed) all md devices that are
+listed in the configuration file are assembled.
 
 The identity can be given with the 
 .B --uuid
 option, with the
 .B --super-minor
-option, can be found in in the config file, or will be taken from the
+option, can be found  in the config file, or will be taken from the
 super block on the first component-device listed on the command line.
 
 Devices can be given on the 
 .B --assemble
-command line or from the config file. Only devices which have an md
-superblock which contains the right identity will be considered for any device.
+command line or in the config file. Only devices which have an md
+superblock which contains the right identity will be considered for
+any array.
 
 The config file is only used if explicitly named with 
 .B --config
@@ -470,7 +549,7 @@ This usage will allow individual devices in an array to be failed,
 removed or added.  It is possible to perform multiple operations with
 on command. For example:
 .br
-.B "  mdadm /dev/md0 -f /dev/hda1 -r /dev/hda1 /a /dev/hda1"
+.B "  mdadm /dev/md0 -f /dev/hda1 -r /dev/hda1 -a /dev/hda1"
 .br
 will firstly mark
 .B /dev/hda1
@@ -706,62 +785,83 @@ the original array.
 
 .SH EXAMPLES
 
-To find out if a devices is a raid array or part of one:
+.B "  mdadm --query /dev/name-of-device"
 .br
-.B "  mdadm -Q /dev/name-of-device"
+This will find out if a given device is a raid array, or is part of
+one, and will provide brief information about the device.
 
-To assemble and start all array listed in the standard config file:
+.B "  mdadm --assemble --scan"
 .br
-.B "  mdadm -As"
+This will assemble and start all arrays listed in the standard confile
+file.  This command will typically go in a system startup file.
 
-To shut down all arrays (that are not still in used):
-.br
 .B "  mdadm --stop --scan"
+.br
+This will shut down all array that can be shut down (i.e. are not
+currently in used).  This will typically going in a system shutdown script.
 
-To monitor all arrays if (and only if) an email address or program
-was given in the config file, but poll every 2 minutes:
+.B "  mdadm --follow --scan --delay=120"
 .br
-.B "  mdadm -Fs --delay=120"
+If (and only if) there is an Email address or program given in the
+standard config file, then
+monitor the status of all arrays listed in that file by
+polling them ever 2 minutes.
 
-To create /dev/md0 as a RAID1 array with /dev/hda1 and /dev/hdc1:
+.B "  mdadm --create /dev/md0 --level=1 --raid-devices=2 /dev/hd[ac]1"
 .br
-.B "  mdadm -C /dev/md0 -l1 -n2 /dev/hd[ac]1"
+Create /dev/md0 as a RAID1 array consisting of /dev/hda1 and /dev/hdc1.
 
-To create prototype a config file that describes currently
-active arrays that are known to be made from partitions of
-IDE or SCSI drives:
 .br
 .B "  echo 'DEVICE /dev/hd*[0-9] /dev/sd*[0-9]' > mdadm.conf"
 .br
 .B "  mdadm --detail --scan >> mdadm.conf"
 .br
+This will create a prototype config file that describes currently
+active arrays that are known to be made from partitions of IDE or SCSI drives.
 This file should be reviewed before being used as it may
 contain unwanted detail.
 
-To find out what raid arrays could be assembled from existing
-IDE and SCSI whole drives (not partitions):
-.br
 .B "  echo 'DEVICE /dev/hd[a-z] /dev/sd*[a-z]' > mdadm.conf"
 .br
-.B "  mdadm -Es -c mdadm.conf >> mdadm.conf"
+.B "  mdadm --examine --scan --config=mdadm.conf >> mdadm.conf"
+.ber
+This will find what arrays could be assembled from existign IDE and
+SCSI whole drives (not partitions) and store the information is the
+format of a config file.
 This file is very likely to contain unwanted detail, particularly
 the
 .B devices=
-entries.
+entries.  It should be reviewed and edited before being used as an
+actual config file.
 
-To get help about Create mode:
+.B "  mdadm --examine --brief --scan --config=partitions"
 .br
-.B "  mdadm --create --help"
+.B "  mdadm -Ebsc partitions"
+.br
+Create a list of devices by reading
+.BR /proc/partitions ,
+scan these for RAID superblocks, and printout a brief listing of all
+that was found.
 
-To get help about the format of the config file:
+.B "  mdadm -Ac partitions -m 0 /dev/md0"
 .br
-.B "  mdadm --config --help"
+Scan all partitions and devices listed in
+.BR /proc/partitions
+and assemble
+.B /dev/md0
+out of all such devices with a RAID superblock with a minor number of 0.
 
-To get general help:
+.B "  mdadm --create --help"
 .br
-.B "  mdadm --help"
+Providew help about the Create mode.
 
+.B "  mdadm --config --help"
+.br
+Provide help about the format of the config file.
 
+.B "  mdadm --help"
+.br
+Provide general help.
 
 
 .SH FILES
diff --git a/mdadm.c b/mdadm.c
index 95e7005..c437378 100644 (file)
--- a/mdadm.c
+++ b/mdadm.c
@@ -65,6 +65,7 @@ int main(int argc, char *argv[])
        struct mddev_ident_s ident;
        char *configfile = NULL;
        char *cp;
+       char *update = NULL;
        int scan = 0;
        char devmode = 0;
        int runstop = 0;
@@ -369,6 +370,19 @@ int main(int argc, char *argv[])
                        }
                        continue;
 
+               case O(ASSEMBLE,'U'): /* update the superblock */
+                       if (update) {
+                               fprintf(stderr, Name ": Can only update one aspect of superblock, both %s and %s given.\n",
+                                       update, optarg);
+                               exit(2);
+                       }
+                       update = optarg;
+                       if (strcmp(update, "sparc2.2")==0) continue;
+                       if (strcmp(update, "super-minor") == 0)
+                               continue;
+                       fprintf(stderr, Name ": '--update %s' invalid.  Only 'sparc2.2' or 'super-minor' supported\n",update);
+                       exit(2);
+
                case O(ASSEMBLE,'c'): /* config file */
                case O(MISC, 'c'):
                case O(MONITOR,'c'):
@@ -489,13 +503,6 @@ int main(int argc, char *argv[])
                        }
                        SparcAdjust = 1;
                        continue;
-               case O(MISC,23):
-                       if (devmode != 'E') {
-                               fprintf(stderr, Name ": --sparc2.2update only allowed with --examine\n");
-                               exit(2);
-                       }
-                       SparcAdjust = 2;
-                       continue;
                }
                /* We have now processed all the valid options. Anything else is
                 * an error
@@ -548,8 +555,12 @@ int main(int argc, char *argv[])
                if (!scan)
                        rv = Assemble(devlist->devname, mdfd, &ident, configfile,
                                      devlist->next,
-                                     readonly, runstop, verbose, force);
-               else if (devs_found>0)
+                                     readonly, runstop, update, verbose, force);
+               else if (devs_found>0) {
+                       if (update && devs_found > 1) {
+                               fprintf(stderr, Name ": can only update a single array at a time\n");
+                               exit(1);
+                       }
                        for (dv = devlist ; dv ; dv=dv->next) {
                                mddev_ident_t array_ident = conf_get_ident(configfile, dv->devname);
                                mdfd = open_mddev(dv->devname);
@@ -565,9 +576,9 @@ int main(int argc, char *argv[])
                                }
                                rv |= Assemble(dv->devname, mdfd, array_ident, configfile,
                                               NULL,
-                                              readonly, runstop, verbose, force);
+                                              readonly, runstop, update, verbose, force);
                        }
-               else {
+               else {
                        mddev_ident_t array_list =  conf_get_ident(configfile, NULL);
                        if (!array_list) {
                                fprintf(stderr, Name ": No arrays found in config file\n");
@@ -586,7 +597,7 @@ int main(int argc, char *argv[])
                                        rv |= Assemble(array_list->devname, mdfd,
                                                       array_list, configfile,
                                                       NULL,
-                                                      readonly, runstop, verbose, force);
+                                                      readonly, runstop, NULL, verbose, force);
                                }
                }
                break;
index 65c97b7..09c7989 100644 (file)
 # Arrays can currently be identified by using a UUID, superblock minor number,
 # or a listing of devices.
 #
-#      super-minor is usally the minor number of the metadevice
+#      super-minor is usually the minor number of the metadevice
 #      UUID is the Universally Unique Identifier for the array
 # Each can be obtained using
 #
 #      mdadm -D <md>
 #
 #ARRAY /dev/md0 UUID=3aaa0122:29827cfa:5331ad66:ca767371
-#ARRAY /dev/md1 superminor=1
+#ARRAY /dev/md1 super-minor=1
 #ARRAY /dev/md2 devices=/dev/hda1,/dev/hda2
 #
 # ARRAY lines can also specify a "spare-group" for each array.  mdadm --monitor
index e11f9d5..90ff6cc 100644 (file)
@@ -45,6 +45,22 @@ and each device name can contain wild cards as defined by
 
 Also, there may be several device lines present in the file.
 
+Alternatively, a
+.B device
+line can contain the word
+.BR partitions .
+This will cause
+.I mdadm
+to read
+.I /proc/partitions
+and include all devices and partitions found there-in.
+.I mdadm
+does not use the names from
+.I /proc/partitions
+but only the major and minor device numbers.  It scans
+.I /dev
+to find the name that matches the numbers.
+
 For example:
 .IP
 DEVICE /dev/hda* /dev/hdc*
@@ -52,6 +68,8 @@ DEVICE /dev/hda* /dev/hdc*
 DEV    /dev/sd*
 .br
 DEVICE /dev/discs/disc*/disc
+.br
+DEVICE partitions
 
 .TP
 .B ARRAY
diff --git a/mdadm.h b/mdadm.h
index 50860ed..2f813c1 100644 (file)
--- a/mdadm.h
+++ b/mdadm.h
@@ -150,6 +150,7 @@ extern int Assemble(char *mddev, int mdfd,
                    char *conffile,
                    mddev_dev_t devlist,
                    int readonly, int runstop,
+                   char *update,
                    int verbose, int force);
 
 extern int Build(char *mddev, int mdfd, int chunk, int level,
index 04d6ec2..0657c76 100644 (file)
@@ -1,6 +1,6 @@
 Summary:     mdadm is used for controlling Linux md devices (aka RAID arrays)
 Name:        mdadm
-Version:     1.0.1
+Version:     1.0.9
 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/
diff --git a/mdadm.static b/mdadm.static
new file mode 100755 (executable)
index 0000000..cd31ad7
Binary files /dev/null and b/mdadm.static differ
diff --git a/test b/test
new file mode 100644 (file)
index 0000000..fac0f33
--- /dev/null
+++ b/test
@@ -0,0 +1,2 @@
+dev partitions
+array /dev/md0 super-minor=6
diff --git a/util.c b/util.c
index f2d16be..e65d238 100644 (file)
--- a/util.c
+++ b/util.c
@@ -91,7 +91,8 @@ int md_get_version(int fd)
 
     if (ioctl(fd, RAID_VERSION, &vers) == 0)
        return  (vers.major*10000) + (vers.minor*100) + vers.patchlevel;
-
+    if (errno == EACCES)
+           return -1;
     if (MAJOR(stb.st_rdev) == MD_MAJOR)
        return (3600);
     return -1;
@@ -212,6 +213,8 @@ int load_super(int fd, mdp_super_t *super)
 
        offset *= 512;
 
+       ioctl(fd, BLKFLSBUF, 0); /* make sure we read current data */
+
        if (lseek64(fd, offset, 0)< 0LL)
                return 3;
 
@@ -314,7 +317,7 @@ int check_raid(int fd, char *name)
        if (load_super(fd, &super))
                return 0;
        /* Looks like a raid array .. */
-       fprintf(stderr, Name ": %s appear to be part of a raid array:\n",
+       fprintf(stderr, Name ": %s appears to be part of a raid array:\n",
                name);
        crtime = super.ctime;
        fprintf(stderr, "    level=%d devices=%d ctime=%s",
@@ -375,6 +378,16 @@ struct devmap {
 } *devlist = NULL;
 int devlist_ready = 0;
 
+#ifdef UCLIBC
+char *map_dev(int major, int minor)
+{
+#if 0
+       fprintf(stderr, "Warning - fail to map %d,%d to a device name\n",
+               major, minor);
+#endif
+       return NULL;
+}
+#else
 #define  __USE_XOPEN_EXTENDED
 #include <ftw.h>
 
@@ -410,6 +423,7 @@ char *map_dev(int major, int minor)
     return NULL;
 }
 
+#endif
 
 int calc_sb_csum(mdp_super_t *super)
 {
@@ -446,7 +460,7 @@ char *human_size(long long bytes)
                        (long)(bytes>>30),
                        (long)(((bytes>>10)&0xfffff)+0x100000/200)/(0x100000/100),
                        (long)(bytes/1000LL/1000LL/1000LL),
-                       (long)((((bytes/1000)%1000000)+50000)/10000)
+                       (long)((((bytes/1000)%1000000)+5000)/10000)
                        );
        return buf;
 }