mdadm-1.4.0
This commit is contained in:
parent
aa88f531b4
commit
feb716e9c3
|
@ -0,0 +1,29 @@
|
|||
Subject: ANNOUNCE: mdadm 1.4.0 - A tools for managing Soft RAID under Linux
|
||||
|
||||
|
||||
I am pleased to announce the availability of
|
||||
mdadm version 1.4.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.4.0 adds:
|
||||
SparesMissing event in --monitor mode if a number of spares is declared
|
||||
in mdadm.conf, but that number of spares isn't found.
|
||||
--update=summaries option for --assemble mode to update some summary information
|
||||
in the superblock
|
||||
--test option for --detail to get a useful exit status.
|
||||
|
||||
Development of mdadm is sponsored by CSE@UNSW:
|
||||
The School of Computer Science and Engineering
|
||||
at
|
||||
The University of New South Wales
|
||||
|
||||
NeilBrown 29 Oct 2003
|
27
Assemble.c
27
Assemble.c
|
@ -292,6 +292,33 @@ int Assemble(char *mddev, int mdfd,
|
|||
fprintf(stderr, Name ": updating superblock of %s with minor number %d\n",
|
||||
devname, super.md_minor);
|
||||
}
|
||||
if (strcmp(update, "summaries") == 0) {
|
||||
/* set nr_disks, active_disks, working_disks,
|
||||
* failed_disks, spare_disks based on disks[]
|
||||
* array in superblock.
|
||||
* Also make sure extra slots aren't 'failed'
|
||||
*/
|
||||
super.nr_disks = super.active_disks =
|
||||
super.working_disks = super.failed_disks =
|
||||
super.spare_disks = 0;
|
||||
for (i=0; i < MD_SB_DISKS ; i++)
|
||||
if (super.disks[i].major ||
|
||||
super.disks[i].minor) {
|
||||
int state = super.disks[i].state;
|
||||
if (state & (1<<MD_DISK_REMOVED))
|
||||
continue;
|
||||
super.nr_disks++;
|
||||
if (state & (1<<MD_DISK_ACTIVE))
|
||||
super.active_disks++;
|
||||
if (state & (1<<MD_DISK_FAULTY))
|
||||
super.failed_disks++;
|
||||
else
|
||||
super.working_disks++;
|
||||
if (state == 0)
|
||||
super.spare_disks++;
|
||||
} else if (i >= super.raid_disks && super.disks[i].number == 0)
|
||||
super.disks[i].state = 0;
|
||||
}
|
||||
super.sb_csum = calc_sb_csum(&super);
|
||||
dfd = open(devname, O_RDWR, 0);
|
||||
if (dfd < 0)
|
||||
|
|
12
ChangeLog
12
ChangeLog
|
@ -1,3 +1,15 @@
|
|||
Changes Prior to 1.4.0 release
|
||||
- Document fact that creating a raid5 array really creates a
|
||||
degraded array with a spare.
|
||||
- Add "spares=" tag to config file and generate it wit --detail and
|
||||
--examine
|
||||
- Add "SparesMissing" event when --monitor first sees an array and
|
||||
it doesn't have the enough spare devices.
|
||||
- Add --update=summaries for --assemble to update summary
|
||||
information in superblock, and correct other inconsistancies in
|
||||
the superblock.
|
||||
- Add --test option to --detail to set a meaningful exit status.
|
||||
|
||||
Changes Prior to 1.3.0 release
|
||||
- Make 'size' and unsigned long in Create to allow creation of
|
||||
larger arrays.
|
||||
|
|
24
Detail.c
24
Detail.c
|
@ -31,7 +31,7 @@
|
|||
#include "md_p.h"
|
||||
#include "md_u.h"
|
||||
|
||||
int Detail(char *dev, int brief)
|
||||
int Detail(char *dev, int brief, int test)
|
||||
{
|
||||
/*
|
||||
* Print out details for an md array by using
|
||||
|
@ -45,27 +45,29 @@ int Detail(char *dev, int brief)
|
|||
time_t atime;
|
||||
char *c;
|
||||
char *devices = NULL;
|
||||
int spares = 0;
|
||||
|
||||
mdp_super_t super;
|
||||
int have_super = 0;
|
||||
int rv = test ? 4 : 1;
|
||||
|
||||
if (fd < 0) {
|
||||
fprintf(stderr, Name ": cannot open %s: %s\n",
|
||||
dev, strerror(errno));
|
||||
return 1;
|
||||
return rv;
|
||||
}
|
||||
vers = md_get_version(fd);
|
||||
if (vers < 0) {
|
||||
fprintf(stderr, Name ": %s does not appear to be an md device\n",
|
||||
dev);
|
||||
close(fd);
|
||||
return 1;
|
||||
return rv;
|
||||
}
|
||||
if (vers < 9000) {
|
||||
fprintf(stderr, Name ": cannot get detail for md device %s: driver version too old.\n",
|
||||
dev);
|
||||
close(fd);
|
||||
return 1;
|
||||
return rv;
|
||||
}
|
||||
if (ioctl(fd, GET_ARRAY_INFO, &array)<0) {
|
||||
if (errno == ENODEV)
|
||||
|
@ -75,8 +77,9 @@ int Detail(char *dev, int brief)
|
|||
fprintf(stderr, Name ": cannot get array detail for %s: %s\n",
|
||||
dev, strerror(errno));
|
||||
close(fd);
|
||||
return 1;
|
||||
return rv;
|
||||
}
|
||||
rv = 0;
|
||||
/* Ok, we have some info to print... */
|
||||
c = map_num(pers, array.level);
|
||||
if (brief)
|
||||
|
@ -162,7 +165,12 @@ 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 (disk.state == 0) { printf(" spare"); spares++; }
|
||||
}
|
||||
if (test && d < array.raid_disks && disk.state & (1<<MD_DISK_FAULTY)) {
|
||||
if ((rv & 1) && (array.level ==4 || array.level == 5))
|
||||
rv |= 2;
|
||||
rv |= 1;
|
||||
}
|
||||
if ((dv=map_dev(disk.major, disk.minor))) {
|
||||
if (brief) {
|
||||
|
@ -188,6 +196,7 @@ int Detail(char *dev, int brief)
|
|||
}
|
||||
if (!brief) printf("\n");
|
||||
}
|
||||
if (spares && brief) printf(" spares=%d", spares);
|
||||
if (have_super) {
|
||||
if (brief) printf(" UUID=");
|
||||
else printf(" UUID : ");
|
||||
|
@ -201,5 +210,6 @@ int Detail(char *dev, int brief)
|
|||
}
|
||||
if (brief && devices) printf("\n devices=%s", devices);
|
||||
if (brief) printf("\n");
|
||||
return 0;
|
||||
if (test && (rv&2)) rv &= ~1;
|
||||
return rv;
|
||||
}
|
||||
|
|
|
@ -60,6 +60,7 @@ int Examine(mddev_dev_t devlist, int brief, int scan, int SparcAdjust)
|
|||
char *c;
|
||||
int rv = 0;
|
||||
int err;
|
||||
int spares = 0;
|
||||
|
||||
struct array {
|
||||
mdp_super_t super;
|
||||
|
@ -205,7 +206,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 (dp->state == 0) { printf(" spare"); spares++; }
|
||||
if ((dv=map_dev(dp->major, dp->minor)))
|
||||
printf(" %s", dv);
|
||||
printf("\n");
|
||||
|
@ -237,6 +238,7 @@ int Examine(mddev_dev_t devlist, int brief, int scan, int SparcAdjust)
|
|||
char *d;
|
||||
printf("ARRAY /dev/md%d level=%s num-devices=%d UUID=",
|
||||
ap->super.md_minor, c?c:"-unknown-", ap->super.raid_disks);
|
||||
if (spares) printf(" spares=%d", spares);
|
||||
if (ap->super.minor_version >= 90)
|
||||
printf("%08x:%08x:%08x:%08x", ap->super.set_uuid0, ap->super.set_uuid1,
|
||||
ap->super.set_uuid2, ap->super.set_uuid3);
|
||||
|
|
2
Makefile
2
Makefile
|
@ -96,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 *.orig *.porig *.rej
|
||||
rm -f mdadm $(OBJS) core *.man mdadm.tcc mdadm.uclibc mdadm.static *.orig *.porig *.rej *.alt
|
||||
|
||||
dist : clean
|
||||
./makedist
|
||||
|
|
|
@ -97,6 +97,7 @@ int Monitor(mddev_dev_t devlist,
|
|||
int err;
|
||||
char *spare_group;
|
||||
int active, working, failed, spare, raid;
|
||||
int expected_spares;
|
||||
int devstate[MD_SB_DISKS];
|
||||
int devid[MD_SB_DISKS];
|
||||
int percent;
|
||||
|
@ -151,6 +152,7 @@ int Monitor(mddev_dev_t devlist,
|
|||
st->err = 0;
|
||||
st->devnum = -1;
|
||||
st->percent = -2;
|
||||
st->expected_spares = mdlist->spare_disks;
|
||||
if (mdlist->spare_group)
|
||||
st->spare_group = strdup(mdlist->spare_group);
|
||||
else
|
||||
|
@ -169,6 +171,7 @@ int Monitor(mddev_dev_t devlist,
|
|||
st->err = 0;
|
||||
st->devnum = -1;
|
||||
st->percent = -2;
|
||||
st->expected_spares = -1;
|
||||
st->spare_group = NULL;
|
||||
statelist = st;
|
||||
}
|
||||
|
@ -248,6 +251,10 @@ int Monitor(mddev_dev_t devlist,
|
|||
)
|
||||
alert("DegradedArray", dev, NULL, mailaddr, alert_cmd);
|
||||
|
||||
if (st->utime == 0 && /* new array */
|
||||
st->expected_spares > 0 &&
|
||||
array.spare_disks < st->expected_spares)
|
||||
alert("SparesMissing", dev, NULL, mailaddr, alert_cmd);
|
||||
if (mse &&
|
||||
st->percent == -1 &&
|
||||
mse->percent >= 0)
|
||||
|
|
10
ReadMe.c
10
ReadMe.c
|
@ -29,7 +29,7 @@
|
|||
|
||||
#include "mdadm.h"
|
||||
|
||||
char Version[] = Name " - v1.3.0 - 29 Jul 2003\n";
|
||||
char Version[] = Name " - v1.4.0 - 29 Oct 2003\n";
|
||||
/*
|
||||
* File: ReadMe.c
|
||||
*
|
||||
|
@ -86,7 +86,7 @@ char Version[] = Name " - v1.3.0 - 29 Jul 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:sarfRSow1";
|
||||
char short_options[]="-ABCDEFGQhVvbc:l:p:m:n:x:u:c:d:z:U:sarfRSow1t";
|
||||
struct option long_options[] = {
|
||||
{"manage", 0, 0, '@'},
|
||||
{"misc", 0, 0, '#'},
|
||||
|
@ -141,6 +141,7 @@ struct option long_options[] = {
|
|||
/* For Detail/Examine */
|
||||
{"brief", 0, 0, 'b'},
|
||||
{"sparc2.2", 0, 0, 22},
|
||||
{"test", 0, 0, 't'},
|
||||
|
||||
/* For Follow/monitor */
|
||||
{"mail", 1, 0, 'm'},
|
||||
|
@ -221,7 +222,7 @@ char OptionHelp[] =
|
|||
" --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"
|
||||
" --update= -U : Update superblock: one of sparc2.2, super-minor or summaries\n"
|
||||
"\n"
|
||||
" For detail or examine:\n"
|
||||
" --brief -b : Just print device name and UUID\n"
|
||||
|
@ -344,7 +345,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"
|
||||
" --update= -U : Update superblock: one of sparc2.2, super-minor or summaries\n"
|
||||
;
|
||||
|
||||
char Help_manage[] =
|
||||
|
@ -385,6 +386,7 @@ char Help_misc[] =
|
|||
" --stop -S : deactivate array, releasing all resources\n"
|
||||
" --readonly -o : mark array as readonly\n"
|
||||
" --readwrite -w : mark array as readwrite\n"
|
||||
" --test -t : exit status 0 if ok, 1 if degrade, 2 if dead, 4 if missing\n"
|
||||
;
|
||||
|
||||
char Help_monitor[] =
|
||||
|
|
8
config.c
8
config.c
|
@ -265,6 +265,7 @@ void arrayline(char *line)
|
|||
mis.super_minor = -1;
|
||||
mis.level = -10;
|
||||
mis.raid_disks = -1;
|
||||
mis.spare_disks = -1;
|
||||
mis.devices = NULL;
|
||||
mis.devname = NULL;
|
||||
mis.spare_group = NULL;
|
||||
|
@ -315,10 +316,13 @@ void arrayline(char *line)
|
|||
mis.level = map_name(pers, w+6);
|
||||
} else if (strncasecmp(w, "disks=", 6) == 0 ) {
|
||||
/* again, for compat */
|
||||
mis.raid_disks = atoi(w+6);
|
||||
mis.raid_disks = atoi(w+6);
|
||||
} else if (strncasecmp(w, "num-devices=", 12) == 0 ) {
|
||||
/* again, for compat */
|
||||
mis.raid_disks = atoi(w+12);
|
||||
mis.raid_disks = atoi(w+12);
|
||||
} else if (strncasecmp(w, "spares=", 7) == 0 ) {
|
||||
/* for warning if not all spares present */
|
||||
mis.spare_disks = atoi(w+7);
|
||||
} else {
|
||||
fprintf(stderr, Name ": unrecognised word on ARRAY line: %s\n",
|
||||
w);
|
||||
|
|
52
mdadm.8
52
mdadm.8
|
@ -1,5 +1,5 @@
|
|||
.\" -*- nroff -*-
|
||||
.TH MDADM 8 "" v1.3.0
|
||||
.TH MDADM 8 "" v1.4.0
|
||||
.SH NAME
|
||||
mdadm \- manage MD devices
|
||||
.I aka
|
||||
|
@ -328,8 +328,9 @@ 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
|
||||
argument given to this flag can be one of
|
||||
.BR sparc2.2 ,
|
||||
.BR summaries ,
|
||||
or
|
||||
.BR super-minor .
|
||||
|
||||
|
@ -348,9 +349,13 @@ The
|
|||
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
|
||||
assembled. This is not needed on 2.6 and later kernels as they make
|
||||
this adjustment automatically.
|
||||
|
||||
The
|
||||
.B summaries
|
||||
option will correct the summaries in the superblock. That is the
|
||||
counts of total, working, active, failed, and spare devices.
|
||||
|
||||
.SH For Manage mode:
|
||||
|
||||
|
@ -412,6 +417,14 @@ over-written with zeros. With
|
|||
the block where the superblock would be is over-written even if it
|
||||
doesn't appear to be valid.
|
||||
|
||||
.TP
|
||||
.BR -t ", " --test
|
||||
When used with
|
||||
.BR --detail ,
|
||||
the exit status of
|
||||
.I mdadm
|
||||
is set to reflect the status of the device.
|
||||
|
||||
.SH For Monitor mode:
|
||||
.TP
|
||||
.BR -m ", " --mail
|
||||
|
@ -582,6 +595,15 @@ For a RAID1 array, only one real device needs to be given. All of the
|
|||
others can be
|
||||
"\fBmissing\fP".
|
||||
|
||||
When creating a RAID5 array,
|
||||
.B mdadm
|
||||
will automatically create a degraded array with an extra spare drive.
|
||||
This is because building the spare into a degraded array is in general faster than resyncing
|
||||
the parity on a non-degraded, but not clean, array. This feature can
|
||||
be over-ridden with the
|
||||
-I --force
|
||||
option.
|
||||
|
||||
'''If the
|
||||
'''.B --size
|
||||
'''option is given, it is not necessary to list any component-devices in this command.
|
||||
|
@ -651,6 +673,28 @@ or
|
|||
will cause the output to be less detailed and the format to be
|
||||
suitable for inclusion in
|
||||
.BR /etc/mdadm.conf .
|
||||
The exit status of
|
||||
.I mdadm
|
||||
will normally be 0 unless
|
||||
.I mdadm
|
||||
failed to get useful information about the device(s). However if the
|
||||
.B --test
|
||||
option is given, then the exit status will be:
|
||||
.RS
|
||||
.TP
|
||||
0
|
||||
The array is functioning normally.
|
||||
.TP
|
||||
1
|
||||
The array has at least one failed device.
|
||||
.TP
|
||||
2
|
||||
The array has multiple failed devices and hence is unusable (raid4 or
|
||||
raid5).
|
||||
.TP
|
||||
4
|
||||
There was an error while trying to get information about the device.
|
||||
.RE
|
||||
|
||||
.TP
|
||||
--examine
|
||||
|
|
12
mdadm.c
12
mdadm.c
|
@ -78,6 +78,7 @@ int main(int argc, char *argv[])
|
|||
int verbose = 0;
|
||||
int brief = 0;
|
||||
int force = 0;
|
||||
int test = 0;
|
||||
|
||||
char *mailaddr = NULL;
|
||||
char *program = NULL;
|
||||
|
@ -397,7 +398,9 @@ int main(int argc, char *argv[])
|
|||
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);
|
||||
if (strcmp(update, "summaries")==0)
|
||||
continue;
|
||||
fprintf(stderr, Name ": '--update %s' invalid. Only 'sparc2.2', 'super-minor' or 'summaries' supported\n",update);
|
||||
exit(2);
|
||||
|
||||
case O(ASSEMBLE,'c'): /* config file */
|
||||
|
@ -517,6 +520,9 @@ int main(int argc, char *argv[])
|
|||
}
|
||||
devmode = opt;
|
||||
continue;
|
||||
case O(MISC,'t'):
|
||||
test = 1;
|
||||
continue;
|
||||
|
||||
case O(MISC, 22):
|
||||
if (devmode != 'E') {
|
||||
|
@ -683,7 +689,7 @@ int main(int argc, char *argv[])
|
|||
continue;
|
||||
}
|
||||
if (devmode == 'D')
|
||||
rv |= Detail(name, !verbose);
|
||||
rv |= Detail(name, !verbose, test);
|
||||
else if (devmode=='S') {
|
||||
mdfd = open_mddev(name);
|
||||
if (mdfd >= 0)
|
||||
|
@ -699,7 +705,7 @@ int main(int argc, char *argv[])
|
|||
for (dv=devlist ; dv; dv=dv->next) {
|
||||
switch(dv->disposition) {
|
||||
case 'D':
|
||||
rv |= Detail(dv->devname, brief); continue;
|
||||
rv |= Detail(dv->devname, brief, test); continue;
|
||||
case 'K': /* Zero superblock */
|
||||
rv |= Kill(dv->devname, force); continue;
|
||||
case 'Q':
|
||||
|
|
3
mdadm.h
3
mdadm.h
|
@ -96,6 +96,7 @@ typedef struct mddev_ident_s {
|
|||
*/
|
||||
int level; /* -10 if not set */
|
||||
int raid_disks; /* -1 if not set */
|
||||
int spare_disks; /* -1 if not set */
|
||||
char *spare_group;
|
||||
struct mddev_ident_s *next;
|
||||
} *mddev_ident_t;
|
||||
|
@ -163,7 +164,7 @@ extern int Create(char *mddev, int mdfd,
|
|||
int subdevs, mddev_dev_t devlist,
|
||||
int runstop, int verbose, int force);
|
||||
|
||||
extern int Detail(char *dev, int brief);
|
||||
extern int Detail(char *dev, int brief, int test);
|
||||
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,
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
Summary: mdadm is used for controlling Linux md devices (aka RAID arrays)
|
||||
Name: mdadm
|
||||
Version: 1.3.0
|
||||
Version: 1.4.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/
|
||||
|
|
Loading…
Reference in New Issue