]> 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 req_cnt;
        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)
-                       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;
+                       }
                if (devices[j].events+event_margin >=
                    devices[most_recent].events) {
                        devices[j].uptodate = 1;
@@ -535,6 +539,17 @@ This doesnt work yet
                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) {
@@ -576,12 +591,14 @@ This doesnt work yet
                
                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 (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");
@@ -596,8 +613,18 @@ This doesnt work yet
                                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
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
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,
-          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)
 {
@@ -52,7 +52,7 @@ int Create(char *mddev, int mdfd,
         * 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;
@@ -115,10 +115,24 @@ int Create(char *mddev, int mdfd,
                        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 */
@@ -127,7 +141,7 @@ int Create(char *mddev, int mdfd,
        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)
@@ -153,7 +167,7 @@ int Create(char *mddev, int mdfd,
                        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);
@@ -164,7 +178,7 @@ int Create(char *mddev, int mdfd,
 
                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;
@@ -193,10 +207,10 @@ int Create(char *mddev, int mdfd,
                }
                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)) {
-               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;
        }
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 == 0) printf(" spare");
                }
                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 == 0) printf(" spare");
                                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
+CWFLAGS = -Wall -Werror -Wstrict-prototypes
 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
@@ -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 : 
-       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
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++) {
+                               disc.number = j;
                                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 period, int daemonise, int scan,
+           int period, int daemonise, int scan, int oneshot,
            char *config)
 {
        /*
@@ -176,6 +176,7 @@ int Monitor(mddev_dev_t devlist,
 
 
        while (! finished) {
+               int new_found = 0;
                struct state *st;
 
                if (mdstat)
@@ -241,6 +242,12 @@ int Monitor(mddev_dev_t devlist,
                                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)
@@ -323,6 +330,7 @@ int Monitor(mddev_dev_t devlist,
                                        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
@@ -374,8 +382,12 @@ int Monitor(mddev_dev_t devlist,
                                                close(fd2);
                                        }
                        }
-                                           
-               sleep(period);
+               if (!new_found) {
+                       if (oneshot)
+                               break;
+                       else
+                               sleep(period);
+               }
        }
        return 0;
 }
@@ -401,7 +413,9 @@ static void alert(char *event, char *dev, char *disc, char *mailaddr, char *cmd)
                        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];
index fd16d8a9e910f64e1b4bb4aed0986d738d71a62a..830a3b3ee27ed17eab57afb7a7b4b0af5f051423 100644 (file)
--- a/ReadMe.c
+++ b/ReadMe.c
@@ -29,7 +29,7 @@
 
 #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
  *
@@ -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.
  */
 
-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, '#'},
@@ -149,7 +149,7 @@ struct option long_options[] = {
     {"delay",     1, 0, 'd'},
     {"daemonise", 0, 0, 'f'},
     {"daemonize", 0, 0, 'f'},
-    
+    {"oneshot",   0, 0, '1'},
     
     {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"
-" 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"
-" 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"
-" 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"
@@ -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"
-"  --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"
-"   --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"
-"   --readonly        : start the array readonly - not supported yet.\n"
+"  --readonly    -o   : start the array readonly - not supported yet.\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"
+"  --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
 
 
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
-  ( 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
 
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
-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.
 
diff --git a/mdadm.8 b/mdadm.8
index a04f7a029c590eebbe97ad70244944339d217758..c9d164dede994e96044b40eb35596e7960ffbec3 100644 (file)
--- a/mdadm.8
+++ b/mdadm.8
@@ -1,5 +1,5 @@
 .\" -*- nroff -*-
-.TH MDADM 8 "" v1.2.0
+.TH MDADM 8 "" v1.3.0
 .SH NAME
 mdadm \- manage MD devices
 .I aka
@@ -232,9 +232,14 @@ Specify rounding factor for linear array (==chunk size)
 
 .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.
-Only the first 4 are valid when Building.
+
+When used with
+.IR --build ,
+only linear, raid0, 0, stripe are valid.
 
 .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)
-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=
@@ -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.
 
+.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
@@ -775,6 +798,15 @@ A new md array has been detected in the
 .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
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;
+       int oneshot = 0;
 
        int mdfd = -1;
 
@@ -320,6 +321,12 @@ int main(int argc, char *argv[])
                                        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;
 
@@ -341,6 +348,7 @@ int main(int argc, char *argv[])
                                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 */
@@ -441,7 +449,9 @@ int main(int argc, char *argv[])
                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.
@@ -717,7 +727,7 @@ int main(int argc, char *argv[])
                        break;
                }
                rv= Monitor(devlist, mailaddr, program,
-                           delay?delay:60, daemonise, scan, configfile);
+                           delay?delay:60, daemonise, scan, oneshot, configfile);
                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,
-                 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);
 
@@ -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,
-                  int period, int daemonise, int scan,
+                  int period, int daemonise, int scan, int oneshot,
                   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
-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/