]> git.ipfire.org Git - thirdparty/mdadm.git/commitdiff
mdadm-1.3.0 mdadm-1.3.0
authorNeil Brown <neilb@suse.de>
Mon, 28 Jul 2003 23:59:00 +0000 (23:59 +0000)
committerNeil Brown <neilb@suse.de>
Mon, 28 Jul 2003 23:59:00 +0000 (23:59 +0000)
17 files changed:
ANNOUNCE-1.3.0 [new file with mode: 0644]
Assemble.c
ChangeLog
Create.c
Detail.c
Examine.c
Makefile
Manage.c
Monitor.c
ReadMe.c
TODO
makedist
md.4
mdadm.8
mdadm.c
mdadm.h
mdadm.spec

diff --git a/ANNOUNCE-1.3.0 b/ANNOUNCE-1.3.0
new file mode 100644 (file)
index 0000000..e8cde14
--- /dev/null
@@ -0,0 +1,24 @@
+Subject:  ANNOUNCE: mdadm 1.3.0 - A tools for managing Soft RAID under Linux
+
+
+I am pleased to announce the availability of 
+   mdadm version 1.3.0
+It is available at
+   http://www.cse.unsw.edu.au/~neilb/source/mdadm/
+and
+   http://www.{countrycode}.kernel.org/pub/utils/raid/mdadm/
+
+as a source tar-ball and (at the first site) as an SRPM, and as an RPM for i386.
+
+mdadm is a tool for creating, managing and monitoring
+device arrays using the "md" driver in Linux, also
+known as Software RAID arrays.
+
+Release 1.3.0 is a bug-fix and minor feature update release over 1.2.0.
+
+Development of mdadm is sponsored by CSE@UNSW: 
+  The School of Computer Science and Engineering
+at
+  The University of New South Wales
+
+NeilBrown  29 Jul 2003
index 96e9ebe840b726965b485243328b5cc8a2caaad7..cddb76fafbc56897ea0135ea1e827c618d795c4b 100644 (file)
@@ -109,6 +109,7 @@ int Assemble(char *mddev, int mdfd,
        int *best = NULL; /* indexed by raid_disk */
        int bestcnt = 0;
        int devcnt = 0, okcnt, sparecnt;
        int *best = NULL; /* indexed by raid_disk */
        int bestcnt = 0;
        int devcnt = 0, okcnt, sparecnt;
+       int req_cnt;
        int i;
        int most_recent = 0;
        int chosen_drive;
        int i;
        int most_recent = 0;
        int chosen_drive;
@@ -365,8 +366,11 @@ int Assemble(char *mddev, int mdfd,
                 * as they don't make sense
                 */
                if (first_super.level != -4)
                 * as they don't make sense
                 */
                if (first_super.level != -4)
-                       if (!(devices[j].state & (1<<MD_DISK_SYNC)))
+                       if (!(devices[j].state & (1<<MD_DISK_SYNC))) {
+                               if (!(devices[j].state & (1<<MD_DISK_FAULTY)))
+                                       sparecnt++;
                                continue;
                                continue;
+                       }
                if (devices[j].events+event_margin >=
                    devices[most_recent].events) {
                        devices[j].uptodate = 1;
                if (devices[j].events+event_margin >=
                    devices[most_recent].events) {
                        devices[j].uptodate = 1;
@@ -535,6 +539,17 @@ This doesnt work yet
                change = 0;
        }
 
                change = 0;
        }
 
+       /* count number of in-sync devices according to the superblock.
+        * We must have this number to start the array without -s or -R
+        */
+       req_cnt = 0;
+       for (i=0; i<MD_SB_DISKS; i++)
+               if ((first_super.disks[i].state & (1<<MD_DISK_SYNC)) &&
+                   (first_super.disks[i].state & (1<<MD_DISK_ACTIVE)) &&
+                   !(first_super.disks[i].state & (1<<MD_DISK_FAULTY)))
+                       req_cnt ++;
+                                                                           
+
        /* Almost ready to actually *do* something */
        if (!old_linux) {
                if (ioctl(mdfd, SET_ARRAY_INFO, NULL) != 0) {
        /* Almost ready to actually *do* something */
        if (!old_linux) {
                if (ioctl(mdfd, SET_ARRAY_INFO, NULL) != 0) {
@@ -576,12 +591,14 @@ This doesnt work yet
                
                if (runstop == 1 ||
                    (runstop == 0 && 
                
                if (runstop == 1 ||
                    (runstop == 0 && 
-                    ( first_super.raid_disks == okcnt
-                      || (start_partial_ok && enough(first_super.level, first_super.raid_disks, okcnt)))
-                           )) {
+                    ( enough(first_super.level, first_super.raid_disks, okcnt) &&
+                      (okcnt >= req_cnt || start_partial_ok)
+                            ))) {
                        if (ioctl(mdfd, RUN_ARRAY, NULL)==0) {
                                fprintf(stderr, Name ": %s has been started with %d drive%s",
                                        mddev, okcnt, okcnt==1?"":"s");
                        if (ioctl(mdfd, RUN_ARRAY, NULL)==0) {
                                fprintf(stderr, Name ": %s has been started with %d drive%s",
                                        mddev, okcnt, okcnt==1?"":"s");
+                               if (okcnt < first_super.raid_disks) 
+                                       fprintf(stderr, " (out of %d)", first_super.raid_disks);
                                if (sparecnt)
                                        fprintf(stderr, " and %d spare%s", sparecnt, sparecnt==1?"":"s");
                                fprintf(stderr, ".\n");
                                if (sparecnt)
                                        fprintf(stderr, " and %d spare%s", sparecnt, sparecnt==1?"":"s");
                                fprintf(stderr, ".\n");
@@ -596,8 +613,18 @@ This doesnt work yet
                                mddev, okcnt, okcnt==1?"":"s");
                        return 0;
                }
                                mddev, okcnt, okcnt==1?"":"s");
                        return 0;
                }
-               fprintf(stderr, Name ": %s assembled from %d drive%s - not enough to start it (use --run to insist).\n",
-                       mddev, okcnt, okcnt==1?"":"s");
+               fprintf(stderr, Name ": %s assembled from %d drive%s", mddev, okcnt, okcnt==1?"":"s");
+               if (sparecnt)
+                       fprintf(stderr, " and %d spare%s", sparecnt, sparecnt==1?"":"s");
+               if (!enough(first_super.level, first_super.raid_disks, okcnt))
+                       fprintf(stderr, " - not enough to start the array.\n");
+               else {
+                       if (req_cnt == first_super.raid_disks)
+                               fprintf(stderr, " - need all %d to start it", req_cnt);
+                       else
+                               fprintf(stderr, " - need %d of %d to start", req_cnt, first_super.raid_disks);
+                       fprintf(stderr, " (use --run to insist).\n");
+               }
                return 1;
        } else {
                /* The "chosen_drive" is a good choice, and if necessary, the superblock has
                return 1;
        } else {
                /* The "chosen_drive" is a good choice, and if necessary, the superblock has
index e455eeff2405d61f1ea90b6c5903de8fdb5efff5..73dd5af398f5df5b76e1a5bdfdd384dabba7d730 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,28 @@
+Changes Prior to 1.3.0 release
+    -   Make 'size' and unsigned long in Create to allow creation of
+        larger arrays.
+    -   Explicitly flag spare devices as 'spare' in --detail and --examine
+        output.  Previously they simply had no flags lists.
+    -   Make MailCmd (for monitor) configurable in Makefile, and default
+        to "/usr/sbin/sendmail -t". Also split out the warning related
+       flags into CWFLAGS for easier build configurability.
+    -   Minor bugfix in Manage code.
+    -   --monitor now notices and reports degraded arrays at startup using
+        "DegradedArray" event, and also has a --oneshot option to only
+       report DegradedArrays, and then exit.
+    -   Small man-page clarification w.r.t. raid levels and raid4 in
+        particular.
+    -   Disallow creation of arrays with only one device as this is
+        probably a mistake.  --force will override this check.
+    -   Correct some misleading documentation in the "mdadm --create --help"
+       message.
+    -   Ignore chunksize if raid1 or multipath.
+    -   Explicit statement in man page that raid-disks cannot be changed
+        after array is created.
+    -   Improve message when attempting to start an array with
+        insufficient devices.  Instead of required the array to be full,
+       we only require it has as many active devices as last time.
+       
 Changes Prior to 1.2.0 release
     -   Fix bug where --daemonise required an argument.
     -   In --assemble --verbose, print appropriate message if device is
 Changes Prior to 1.2.0 release
     -   Fix bug where --daemonise required an argument.
     -   In --assemble --verbose, print appropriate message if device is
index 4d74fc14fd5c8aa9977b5f4994c9877736518116..3a98a917e294a6ab1dd731f9cda798eac7d977c4 100644 (file)
--- a/Create.c
+++ b/Create.c
@@ -32,7 +32,7 @@
 #include       "md_p.h"
 
 int Create(char *mddev, int mdfd,
 #include       "md_p.h"
 
 int Create(char *mddev, int mdfd,
-          int chunk, int level, int layout, int size, int raiddisks, int sparedisks,
+          int chunk, int level, int layout, unsigned long size, int raiddisks, int sparedisks,
           int subdevs, mddev_dev_t devlist,
           int runstop, int verbose, int force)
 {
           int subdevs, mddev_dev_t devlist,
           int runstop, int verbose, int force)
 {
@@ -52,7 +52,7 @@ int Create(char *mddev, int mdfd,
         * if runstop==run, or raiddisks diskswere used,
         * RUN_ARRAY
         */
         * if runstop==run, or raiddisks diskswere used,
         * RUN_ARRAY
         */
-       int minsize=0, maxsize=0;
+       unsigned long minsize=0, maxsize=0;
        char *mindisc = NULL;
        char *maxdisc = NULL;
        int dnum;
        char *mindisc = NULL;
        char *maxdisc = NULL;
        int dnum;
@@ -115,10 +115,24 @@ int Create(char *mddev, int mdfd,
                        break;
                }
 
                        break;
                }
 
-       if (chunk == 0) {
-               chunk = 64;
-               if (verbose)
-                       fprintf(stderr, Name ": chunk size defaults to 64K\n");
+       switch(level) {
+       case 4:
+       case 5:
+       case 0:
+       case -1: /* linear */
+               if (chunk == 0) {
+                       chunk = 64;
+                       if (verbose)
+                               fprintf(stderr, Name ": chunk size defaults to 64K\n");
+               }
+               break;
+       default: /* raid1, multipath */
+               if (chunk) {
+                       chunk = 0;
+                       if (verbose)
+                               fprintf(stderr, Name ": chunk size ignored for this level\n");
+               }
+               break;
        }
 
        /* now look at the subdevs */
        }
 
        /* now look at the subdevs */
@@ -127,7 +141,7 @@ int Create(char *mddev, int mdfd,
        dnum = 0;
        for (dv=devlist; dv; dv=dv->next, dnum++) {
                char *dname = dv->devname;
        dnum = 0;
        for (dv=devlist; dv; dv=dv->next, dnum++) {
                char *dname = dv->devname;
-               int dsize, freesize;
+               unsigned long dsize, freesize;
                int fd;
                if (strcasecmp(dname, "missing")==0) {
                        if (first_missing > dnum)
                int fd;
                if (strcasecmp(dname, "missing")==0) {
                        if (first_missing > dnum)
@@ -153,7 +167,7 @@ int Create(char *mddev, int mdfd,
                        continue;
                }
                if (dsize < MD_RESERVED_SECTORS*2) {
                        continue;
                }
                if (dsize < MD_RESERVED_SECTORS*2) {
-                       fprintf(stderr, Name ": %s is too small: %dK\n",
+                       fprintf(stderr, Name ": %s is too small: %luK\n",
                                dname, dsize/2);
                        fail = 1;
                        close(fd);
                                dname, dsize/2);
                        fail = 1;
                        close(fd);
@@ -164,7 +178,7 @@ int Create(char *mddev, int mdfd,
 
                if (size && freesize < size) {
                        fprintf(stderr, Name ": %s is smaller that given size."
 
                if (size && freesize < size) {
                        fprintf(stderr, Name ": %s is smaller that given size."
-                               " %dK < %dK + superblock\n", dname, freesize, size);
+                               " %luK < %luK + superblock\n", dname, freesize, size);
                        fail = 1;
                        close(fd);
                        continue;
                        fail = 1;
                        close(fd);
                        continue;
@@ -193,10 +207,10 @@ int Create(char *mddev, int mdfd,
                }
                size = minsize;
                if (verbose && level>0)
                }
                size = minsize;
                if (verbose && level>0)
-                       fprintf(stderr, Name ": size set to %dK\n", size);
+                       fprintf(stderr, Name ": size set to %luK\n", size);
        }
        if (level >= 1 && ((maxsize-size)*100 > maxsize)) {
        }
        if (level >= 1 && ((maxsize-size)*100 > maxsize)) {
-               fprintf(stderr, Name ": largest drive (%s) exceed size (%dK) by more than 1%%\n",
+               fprintf(stderr, Name ": largest drive (%s) exceed size (%luK) by more than 1%%\n",
                        maxdisc, size);
                warn = 1;
        }
                        maxdisc, size);
                warn = 1;
        }
index 180a6648b49dcd566e0b85a59d01fafc79d4d4cb..9b04efdaa02d56f9efb48f3f21b861731629dc8f 100644 (file)
--- a/Detail.c
+++ b/Detail.c
@@ -162,6 +162,7 @@ int Detail(char *dev, int brief)
                        if (disk.state & (1<<MD_DISK_ACTIVE)) printf(" active");
                        if (disk.state & (1<<MD_DISK_SYNC)) printf(" sync");
                        if (disk.state & (1<<MD_DISK_REMOVED)) printf(" removed");
                        if (disk.state & (1<<MD_DISK_ACTIVE)) printf(" active");
                        if (disk.state & (1<<MD_DISK_SYNC)) printf(" sync");
                        if (disk.state & (1<<MD_DISK_REMOVED)) printf(" removed");
+                       if (disk.state == 0) printf(" spare");
                }
                if ((dv=map_dev(disk.major, disk.minor))) {
                        if (brief) {
                }
                if ((dv=map_dev(disk.major, disk.minor))) {
                        if (brief) {
index 0270108924355a98ebdc330b814a6e6fffc18a66..6263866ec14e20b8c4f3bafdb664851571021fc0 100644 (file)
--- a/Examine.c
+++ b/Examine.c
@@ -205,6 +205,7 @@ int Examine(mddev_dev_t devlist, int brief, int scan, int SparcAdjust)
                                if (dp->state & (1<<MD_DISK_ACTIVE)) printf(" active");
                                if (dp->state & (1<<MD_DISK_SYNC)) printf(" sync");
                                if (dp->state & (1<<MD_DISK_REMOVED)) printf(" removed");
                                if (dp->state & (1<<MD_DISK_ACTIVE)) printf(" active");
                                if (dp->state & (1<<MD_DISK_SYNC)) printf(" sync");
                                if (dp->state & (1<<MD_DISK_REMOVED)) printf(" removed");
+                               if (dp->state == 0) printf(" spare");
                                if ((dv=map_dev(dp->major, dp->minor)))
                                        printf("   %s", dv);
                                printf("\n");
                                if ((dv=map_dev(dp->major, dp->minor)))
                                        printf("   %s", dv);
                                printf("\n");
index 9fb83ed946e1d4b54362376d1a6c768b995ba132..986c9794f4d271a3a1147df2a5d5ad09987fe613 100644 (file)
--- a/Makefile
+++ b/Makefile
@@ -34,9 +34,11 @@ UCLIBC_GCC = i386-uclibc-gcc
 
 CC = gcc
 CXFLAGS = -ggdb
 
 CC = gcc
 CXFLAGS = -ggdb
+CWFLAGS = -Wall -Werror -Wstrict-prototypes
 SYSCONFDIR = /etc
 CONFFILE = $(SYSCONFDIR)/mdadm.conf
 SYSCONFDIR = /etc
 CONFFILE = $(SYSCONFDIR)/mdadm.conf
-CFLAGS = -Wall -Werror -Wstrict-prototypes -DCONFFILE=\"$(CONFFILE)\" $(CXFLAGS)
+MAILCMD =/usr/sbin/sendmail -t
+CFLAGS = $(CWFLAGS) -DCONFFILE=\"$(CONFFILE)\" $(CXFLAGS) -DSendmail=\""$(MAILCMD)"\"
 
 # If you want a static binary, you might uncomment these
 # LDFLAGS = -static
 
 # If you want a static binary, you might uncomment these
 # LDFLAGS = -static
@@ -94,7 +96,7 @@ install : mdadm mdadm.8 md.4 mdadm.conf.5
        $(INSTALL) -D -m 644 mdadm.conf.5 $(DESTDIR)$(MAN5DIR)/mdadm.conf.5
 
 clean : 
        $(INSTALL) -D -m 644 mdadm.conf.5 $(DESTDIR)$(MAN5DIR)/mdadm.conf.5
 
 clean : 
-       rm -f mdadm $(OBJS) core *.man mdadm.tcc mdadm.uclibc mdadm.static
+       rm -f mdadm $(OBJS) core *.man mdadm.tcc mdadm.uclibc mdadm.static *.orig *.porig *.rej
 
 dist : clean
        ./makedist
 
 dist : clean
        ./makedist
index 34076cbfe63e0d7d13b64b984950902d72e1a2a5..0d8ad8d24134c0684148ad76e058c1dbcdd458a4 100644 (file)
--- a/Manage.c
+++ b/Manage.c
@@ -177,6 +177,7 @@ int Manage_subdevs(char *devname, int fd,
                         * in case
                         */
                        for (j=0; j<array.nr_disks; j++) {
                         * in case
                         */
                        for (j=0; j<array.nr_disks; j++) {
+                               disc.number = j;
                                if (ioctl(fd, GET_DISK_INFO, &disc))
                                        break;
                                if (disc.major==0 && disc.minor==0)
                                if (ioctl(fd, GET_DISK_INFO, &disc))
                                        break;
                                if (disc.major==0 && disc.minor==0)
index da73af6f3a7a5b18718771421b64336f530d8e55..3bc3263b198ea7ff1a895d85304e1ed90c733524 100644 (file)
--- a/Monitor.c
+++ b/Monitor.c
@@ -45,7 +45,7 @@ static char *percentalerts[] = {
 
 int Monitor(mddev_dev_t devlist,
            char *mailaddr, char *alert_cmd,
 
 int Monitor(mddev_dev_t devlist,
            char *mailaddr, char *alert_cmd,
-           int period, int daemonise, int scan,
+           int period, int daemonise, int scan, int oneshot,
            char *config)
 {
        /*
            char *config)
 {
        /*
@@ -176,6 +176,7 @@ int Monitor(mddev_dev_t devlist,
 
 
        while (! finished) {
 
 
        while (! finished) {
+               int new_found = 0;
                struct state *st;
 
                if (mdstat)
                struct state *st;
 
                if (mdstat)
@@ -241,6 +242,12 @@ int Monitor(mddev_dev_t devlist,
                                st->err = 0;
                                continue;
                        }
                                st->err = 0;
                                continue;
                        }
+                       if (st->utime == 0 && /* new array */
+                           mse &&      /* is in /proc/mdstat */
+                           mse->pattern && strchr(mse->pattern, '_') /* degraded */
+                               )
+                               alert("DegradedArray", dev, NULL, mailaddr, alert_cmd);
+
                        if (mse &&
                            st->percent == -1 && 
                            mse->percent >= 0)
                        if (mse &&
                            st->percent == -1 && 
                            mse->percent >= 0)
@@ -323,6 +330,7 @@ int Monitor(mddev_dev_t devlist,
                                        st->spare_group = NULL;
                                        statelist = st;
                                        alert("NewArray", st->devname, NULL, mailaddr, alert_cmd);
                                        st->spare_group = NULL;
                                        statelist = st;
                                        alert("NewArray", st->devname, NULL, mailaddr, alert_cmd);
+                                       new_found = 1;
                                }
                }
                /* If an array has active < raid && spare == 0 && spare_group != NULL
                                }
                }
                /* If an array has active < raid && spare == 0 && spare_group != NULL
@@ -374,8 +382,12 @@ int Monitor(mddev_dev_t devlist,
                                                close(fd2);
                                        }
                        }
                                                close(fd2);
                                        }
                        }
-                                           
-               sleep(period);
+               if (!new_found) {
+                       if (oneshot)
+                               break;
+                       else
+                               sleep(period);
+               }
        }
        return 0;
 }
        }
        return 0;
 }
@@ -401,7 +413,9 @@ static void alert(char *event, char *dev, char *disc, char *mailaddr, char *cmd)
                        exit(2);
                }
        }
                        exit(2);
                }
        }
-       if (mailaddr && strncmp(event, "Fail", 4)==0) {
+       if (mailaddr && 
+           (strncmp(event, "Fail", 4)==0 || 
+            strncmp(event, "Degrade", 7)==0)) {
                FILE *mp = popen(Sendmail, "w");
                if (mp) {
                        char hname[256];
                FILE *mp = popen(Sendmail, "w");
                if (mp) {
                        char hname[256];
index fd16d8a9e910f64e1b4bb4aed0986d738d71a62a..830a3b3ee27ed17eab57afb7a7b4b0af5f051423 100644 (file)
--- a/ReadMe.c
+++ b/ReadMe.c
@@ -29,7 +29,7 @@
 
 #include "mdadm.h"
 
 
 #include "mdadm.h"
 
-char Version[] = Name " - v1.2.0 - 13 Mar 2003\n";
+char Version[] = Name " - v1.3.0 - 29 Jul 2003\n";
 /*
  * File: ReadMe.c
  *
 /*
  * File: ReadMe.c
  *
@@ -86,7 +86,7 @@ char Version[] = Name " - v1.2.0 - 13 Mar 2003\n";
  *     This mode never exits but just monitors arrays and reports changes.
  */
 
  *     This mode never exits but just monitors arrays and reports changes.
  */
 
-char short_options[]="-ABCDEFGQhVvbc:l:p:m:n:x:u:c:d:z:U:sarfRSow";
+char short_options[]="-ABCDEFGQhVvbc:l:p:m:n:x:u:c:d:z:U:sarfRSow1";
 struct option long_options[] = {
     {"manage",    0, 0, '@'},
     {"misc",      0, 0, '#'},
 struct option long_options[] = {
     {"manage",    0, 0, '@'},
     {"misc",      0, 0, '#'},
@@ -149,7 +149,7 @@ struct option long_options[] = {
     {"delay",     1, 0, 'd'},
     {"daemonise", 0, 0, 'f'},
     {"daemonize", 0, 0, 'f'},
     {"delay",     1, 0, 'd'},
     {"daemonise", 0, 0, 'f'},
     {"daemonize", 0, 0, 'f'},
-    
+    {"oneshot",   0, 0, '1'},
     
     {0, 0, 0, 0}
 };
     
     {0, 0, 0, 0}
 };
@@ -248,16 +248,16 @@ char OptionHelp[] =
 char Help_create[] =
 "Usage:  mdadm --create device -chunk=X --level=Y --raid-devices=Z devices\n"
 "\n"
 char Help_create[] =
 "Usage:  mdadm --create device -chunk=X --level=Y --raid-devices=Z devices\n"
 "\n"
-" This usage will initialise a new md array and associate some\n"
-" devices with it.  If enough devices are given to complete the array,\n"
-" the array will be activated.  Otherwise it will be left inactive\n"
-" to be completed and activated by subsequent management commands.\n"
+" This usage will initialise a new md array, associate some\n"
+" devices with it, and activate the array.   In order to create an\n"
+" array with some devices missing, use the special word 'missing' in\n"
+" place of the relevant device name.\n"
 "\n"
 "\n"
-" As devices are added, they are checked to see if they already contain\n"
+" Before devices are added, they are checked to see if they already contain\n"
 " raid superblocks or filesystems.  They are also checked to see if\n"
 " the variance in device size exceeds 1%.\n"
 " raid superblocks or filesystems.  They are also checked to see if\n"
 " the variance in device size exceeds 1%.\n"
-" If any discrepancy is found, the array will not automatically\n"
-" be run, though the presence of a '--run' can override this\n"
+" If any discrepancy is found, the user will be prompted for confirmation\n"
+" before the array is created.  The presence of a '--run' can override this\n"
 " caution.\n"
 "\n"
 " If the --size option is given then only that many kilobytes of each\n"
 " caution.\n"
 "\n"
 " If the --size option is given then only that many kilobytes of each\n"
@@ -270,16 +270,16 @@ char Help_create[] =
 "  --chunk=      -c   : chunk size of kibibytes\n"
 "  --rounding=        : rounding factor for linear array (==chunk size)\n"
 "  --level=      -l   : raid level: 0,1,4,5,linear,multipath and synonyms\n"
 "  --chunk=      -c   : chunk size of kibibytes\n"
 "  --rounding=        : rounding factor for linear array (==chunk size)\n"
 "  --level=      -l   : raid level: 0,1,4,5,linear,multipath and synonyms\n"
-"  --parity=    -p   : raid5 parity algorithm: {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"
 "  --size=       -z   : Size (in K) of each drive in RAID1/4/5 - optional\n"
 "  --force       -f   : Honour devices as listed on command line.  Don't\n"
 "                     : insert a missing drive for RAID5.\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"
 "  --size=       -z   : Size (in K) of each drive in RAID1/4/5 - optional\n"
 "  --force       -f   : Honour devices as listed on command line.  Don't\n"
 "                     : insert a missing drive for RAID5.\n"
-"   --run             : insist of running the array even if not all\n"
+"  --run         -R   : insist of running the array even if not all\n"
 "                     : devices are present or some look odd.\n"
 "                     : devices are present or some look odd.\n"
-"   --readonly        : start the array readonly - not supported yet.\n"
+"  --readonly    -o   : start the array readonly - not supported yet.\n"
 "\n"
 ;
 
 "\n"
 ;
 
@@ -407,6 +407,7 @@ char Help_monitor[] =
 "  --config=     -c   : specify a different config file\n"
 "  --scan        -s   : find mail-address/program in config file\n"
 "  --daemonise   -f   : Fork and continue in child, parent exits\n"
 "  --config=     -c   : specify a different config file\n"
 "  --scan        -s   : find mail-address/program in config file\n"
 "  --daemonise   -f   : Fork and continue in child, parent exits\n"
+"  --oneshot     -1   : Check for degraded arrays, then exit\n"
 ;
 
 
 ;
 
 
diff --git a/TODO b/TODO
index 646095f8be09f6e91f39ceec130427cd3dbd7020..4cfa1ebe70fcb47ab5c85271e848e475311c0493 100644 (file)
--- a/TODO
+++ b/TODO
@@ -1,3 +1,5 @@
+* mdadm --monitor to monitor failed multipath paths and re-instate them.
+
 * Maybe make "--help" fit in 80x24 and have a --long-help with more info. DONE
 
 
 * Maybe make "--help" fit in 80x24 and have a --long-help with more info. DONE
 
 
index 63d958b97abfd37c018607ae1cebfe931545528e..0c307f9f2f6c6d591499ec29bdd6a306c9c869ad 100755 (executable)
--- a/makedist
+++ b/makedist
@@ -35,7 +35,7 @@ then
     exit 1
   fi
   trap "rm $target/$base; exit" 1 2 3
     exit 1
   fi
   trap "rm $target/$base; exit" 1 2 3
-  ( cd .. ; ln -s mdadm mdadm-$version ; tar chvf - --exclude="TAGS" --exclude='*,v' --exclude='*.o' --exclude mdadm --exclude=mdadm'.[^ch0-9]' --exclude=RCS mdadm-$version ; rm mdadm-$version ) | gzip --best > $target/$base
+  ( cd .. ; ln -s mdadm mdadm-$version ; tar chvf - --exclude="TAGS" --exclude='*~' --exclude=.patches --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
 
   chmod a+r $target/$base
   ls -l $target/$base
 
diff --git a/md.4 b/md.4
index 1ac98a3c14b274e91ed6c9d7c80355a9a0f47d1f..0dcff251a3ad271ec1c8270cd28c69d3043b7871 100644 (file)
--- a/md.4
+++ b/md.4
@@ -113,7 +113,8 @@ used.  Any extra space on other devices is wasted.
 .SS RAID4
 
 A RAID4 array is like a RAID0 array with an extra device for storing
 .SS RAID4
 
 A RAID4 array is like a RAID0 array with an extra device for storing
-parity.  Unlike RAID0, RAID4 also requires that all stripes span all
+parity. This device is the last of the active devices in the
+array. Unlike RAID0, RAID4 also requires that all stripes span all
 drives, so extra space on devices that are larger than the smallest is
 wasted.
 
 drives, so extra space on devices that are larger than the smallest is
 wasted.
 
diff --git a/mdadm.8 b/mdadm.8
index a04f7a029c590eebbe97ad70244944339d217758..c9d164dede994e96044b40eb35596e7960ffbec3 100644 (file)
--- a/mdadm.8
+++ b/mdadm.8
@@ -1,5 +1,5 @@
 .\" -*- nroff -*-
 .\" -*- nroff -*-
-.TH MDADM 8 "" v1.2.0
+.TH MDADM 8 "" v1.3.0
 .SH NAME
 mdadm \- manage MD devices
 .I aka
 .SH NAME
 mdadm \- manage MD devices
 .I aka
@@ -232,9 +232,14 @@ Specify rounding factor for linear array (==chunk size)
 
 .TP
 .BR -l ", " --level=
 
 .TP
 .BR -l ", " --level=
-Set raid level.  Options are: linear, raid0, 0, stripe, raid1, 1, mirror, raid5, 4,
+Set raid level.  When used with
+.IR --create ,
+options are: linear, raid0, 0, stripe, raid1, 1, mirror, raid5, 4,
 raid5, 5, multipath, mp.  Obviously some of these are synonymous.
 raid5, 5, multipath, mp.  Obviously some of these are synonymous.
-Only the first 4 are valid when Building.
+
+When used with
+.IR --build ,
+only linear, raid0, 0, stripe are valid.
 
 .TP
 .BR -p ", " --parity=
 
 .TP
 .BR -p ", " --parity=
@@ -255,7 +260,13 @@ 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 "\fBmissing\fP" devices)
 number of spare devices (see below) must equal the number of
 .I component-devices
 (including "\fBmissing\fP" devices)
-that are listed on the command line.
+that are listed on the command line.  Setting a value of 1 is probably
+a mistake and so requires that
+.B --force
+be specified first.  A value of 1 will then be allowed for linear,
+multipath, raid0 and raid1.  It is never allowed for raid4 or raid5.
+.br
+Note that this number cannot be changed once the array has been created.
 
 .TP
 .BR -x ", " --spare-devices=
 
 .TP
 .BR -x ", " --spare-devices=
@@ -429,6 +440,18 @@ This is useful with
 which will only continue monitoring if a mail address or alert program
 is found in the config file.
 
 which will only continue monitoring if a mail address or alert program
 is found in the config file.
 
+.TP
+.BR -1 ", " --oneshot
+Check arrays only once.  This will generate
+.B NewArray
+events and more significantly
+.B DegradedArray
+events.  Running
+.in +5
+.B "   mdadm --monitor --scan -1"
+.in -5
+from a cron script will ensure regular notification of any degraded arrays.
+
 .SH ASSEMBLE MODE
 
 .HP 12
 .SH ASSEMBLE MODE
 
 .HP 12
@@ -775,6 +798,15 @@ A new md array has been detected in the
 .B /proc/mdstat
 file.
 
 .B /proc/mdstat
 file.
 
+.TP
+.B DegradedArray
+A newly noticed array appears to be degraded.  This message is not
+generated when
+.I mdadm
+notices a drive failure which causes degradation, but only when
+.I mdadm
+notices that an array is degraded when it first sees the array.
+
 .TP
 .B MoveSpare
 A spare drive has been moved from one array in a
 .TP
 .B MoveSpare
 A spare drive has been moved from one array in a
diff --git a/mdadm.c b/mdadm.c
index 5c8e95681cd3cfe1d74974542ae44a2136377aac..f5da6fa8e0713adb5a1f419b65ac5405173f8a37 100644 (file)
--- a/mdadm.c
+++ b/mdadm.c
@@ -83,6 +83,7 @@ int main(int argc, char *argv[])
        char *program = NULL;
        int delay = 0;
        int daemonise = 0;
        char *program = NULL;
        int delay = 0;
        int daemonise = 0;
+       int oneshot = 0;
 
        int mdfd = -1;
 
 
        int mdfd = -1;
 
@@ -320,6 +321,12 @@ int main(int argc, char *argv[])
                                        optarg);
                                exit(2);
                        }
                                        optarg);
                                exit(2);
                        }
+                       if (raiddisks == 1 &&  !force) {
+                               fprintf(stderr, Name ": '1' is an unusual number of drives for an array, so it is probably\n"
+                                       "     a mistake.  If you really mean it you will need to specify --force before\n"
+                                       "     setting the number of drives.\n");
+                               exit(2);
+                       }
                        ident.raid_disks = raiddisks;
                        continue;
 
                        ident.raid_disks = raiddisks;
                        continue;
 
@@ -341,6 +348,7 @@ int main(int argc, char *argv[])
                                exit(2);
                        }
                        continue;
                                exit(2);
                        }
                        continue;
+               case O(BUILD,'f'): /* force honouring '-n 1' */
                case O(CREATE,'f'): /* force honouring of device list */
                case O(ASSEMBLE,'f'): /* force assembly */
                case O(MISC,'f'): /* force zero */
                case O(CREATE,'f'): /* force honouring of device list */
                case O(ASSEMBLE,'f'): /* force assembly */
                case O(MISC,'f'): /* force zero */
@@ -441,7 +449,9 @@ int main(int argc, char *argv[])
                case O(MONITOR,'f'): /* daemonise */
                        daemonise = 1;
                        continue;
                case O(MONITOR,'f'): /* daemonise */
                        daemonise = 1;
                        continue;
-                       
+               case O(MONITOR,'1'): /* oneshot */
+                       oneshot = 1;
+                       continue;
 
                        /* now the general management options.  Some are applicable
                         * to other modes. None have arguments.
 
                        /* now the general management options.  Some are applicable
                         * to other modes. None have arguments.
@@ -717,7 +727,7 @@ int main(int argc, char *argv[])
                        break;
                }
                rv= Monitor(devlist, mailaddr, program,
                        break;
                }
                rv= Monitor(devlist, mailaddr, program,
-                           delay?delay:60, daemonise, scan, configfile);
+                           delay?delay:60, daemonise, scan, oneshot, configfile);
                break;
        }
        exit(rv);
                break;
        }
        exit(rv);
diff --git a/mdadm.h b/mdadm.h
index 802c779d7566feac520925def7e5ba403c870a7c..6ce5facda8f166a2bc5ce190b019be6a95e7e637 100644 (file)
--- a/mdadm.h
+++ b/mdadm.h
@@ -159,7 +159,7 @@ extern int Build(char *mddev, int mdfd, int chunk, int level,
 
 
 extern int Create(char *mddev, int mdfd,
 
 
 extern int Create(char *mddev, int mdfd,
-                 int chunk, int level, int layout, int size, int raiddisks, int sparedisks,
+                 int chunk, int level, int layout, unsigned long size, int raiddisks, int sparedisks,
                  int subdevs, mddev_dev_t devlist,
                  int runstop, int verbose, int force);
 
                  int subdevs, mddev_dev_t devlist,
                  int runstop, int verbose, int force);
 
@@ -168,7 +168,7 @@ extern int Query(char *dev);
 extern int Examine(mddev_dev_t devlist, int brief, int scan, int SparcAdjust);
 extern int Monitor(mddev_dev_t devlist,
                   char *mailaddr, char *alert_cmd,
 extern int Examine(mddev_dev_t devlist, int brief, int scan, int SparcAdjust);
 extern int Monitor(mddev_dev_t devlist,
                   char *mailaddr, char *alert_cmd,
-                  int period, int daemonise, int scan,
+                  int period, int daemonise, int scan, int oneshot,
                   char *config);
 
 extern int Kill(char *dev, int force);
                   char *config);
 
 extern int Kill(char *dev, int force);
index 7da3c3d80202a93c51548b0960e15bd875794b74..f8498ed7f35f78a1d73f070b3a790be01eb79782 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.2.0
+Version:     1.3.0
 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/