mdadm-1.3.0

This commit is contained in:
Neil Brown 2003-07-28 23:59:00 +00:00
parent 56eedc1a3f
commit aa88f531b4
17 changed files with 202 additions and 47 deletions

24
ANNOUNCE-1.3.0 Normal file
View File

@ -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

View 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

View File

@ -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

View File

@ -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;
}

View File

@ -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) {

View File

@ -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");

View File

@ -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

View File

@ -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)

View File

@ -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];

View File

@ -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"
;

2
TODO
View File

@ -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

View File

@ -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

3
md.4
View File

@ -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.

40
mdadm.8
View File

@ -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

14
mdadm.c
View File

@ -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);

View File

@ -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);

View 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/