mdadm-1.0.9

This commit is contained in:
Neil Brown 2003-02-12 00:17:26 +00:00
parent bd526cee92
commit 5787fa4906
21 changed files with 454 additions and 99 deletions

View File

@ -35,6 +35,7 @@ int Assemble(char *mddev, int mdfd,
mddev_ident_t ident, char *conffile,
mddev_dev_t devlist,
int readonly, int runstop,
char *update,
int verbose, int force)
{
/*
@ -72,7 +73,7 @@ int Assemble(char *mddev, int mdfd,
* For each device:
* Check superblock - discard if bad
* Check uuid (set if we don't have one) - discard if no match
* Check superblock similarity if we have a superbloc - discard if different
* Check superblock similarity if we have a superblock - discard if different
* Record events, devicenum, utime
* This should give us a list of devices for the array
* We should collect the most recent event and utime numbers
@ -103,8 +104,8 @@ int Assemble(char *mddev, int mdfd,
time_t utime;
int uptodate;
int raid_disk;
} devices[MD_SB_DISKS];
int best[MD_SB_DISKS]; /* indexed by raid_disk */
} *devices;
int *best; /* indexed by raid_disk */
int devcnt = 0, okcnt, sparecnt;
int i;
int most_recent = 0;
@ -112,6 +113,8 @@ int Assemble(char *mddev, int mdfd,
int change = 0;
int inargv = 0;
int start_partial_ok = force || devlist==NULL;
int num_devs;
mddev_dev_t tmpdev;
vers = md_get_version(mdfd);
if (vers <= 0) {
@ -153,8 +156,16 @@ int Assemble(char *mddev, int mdfd,
devlist = conf_get_devs(conffile);
else inargv = 1;
tmpdev = devlist; num_devs = 0;
while (tmpdev) {
num_devs++;
tmpdev = tmpdev->next;
}
best = malloc(num_devs * sizeof(*best));
devices = malloc(num_devs * sizeof(*devices));
first_super.md_magic = 0;
for (i=0; i<MD_SB_DISKS; i++)
for (i=0; i<num_devs; i++)
best[i] = -1;
if (verbose)
@ -245,11 +256,48 @@ int Assemble(char *mddev, int mdfd,
return 1;
}
/* this is needed until we get a more relaxed super block format */
if (devcnt >= MD_SB_DISKS) {
fprintf(stderr, Name ": ouch - too many devices appear to be in this array. Ignoring %s\n",
devname);
continue;
}
/* looks like a good enough match to update the super block if needed */
if (update) {
if (strcmp(update, "sparc2.2")==0 ) {
/* 2.2 sparc put the events in the wrong place
* So we copy the tail of the superblock
* up 4 bytes before continuing
*/
__u32 *sb32 = (__u32*)&super;
memcpy(sb32+MD_SB_GENERIC_CONSTANT_WORDS+7,
sb32+MD_SB_GENERIC_CONSTANT_WORDS+7+1,
(MD_SB_WORDS - (MD_SB_GENERIC_CONSTANT_WORDS+7+1))*4);
fprintf (stderr, Name ": adjusting superblock of %s for 2.2/sparc compatability.\n",
devname);
}
if (strcmp(update, "super-minor") ==0) {
struct stat stb2;
fstat(mdfd, &stb2);
super.md_minor = MINOR(stb2.st_rdev);
if (verbose)
fprintf(stderr, Name ": updating superblock of %s with minor number %d\n",
devname, super.md_minor);
}
super.sb_csum = calc_sb_csum(&super);
dfd = open(devname, O_RDWR, 0);
if (dfd < 0)
fprintf(stderr, Name ": Cannot open %s for superblock update\n",
devname);
else if (store_super(dfd, &super))
fprintf(stderr, Name ": Could not re-write superblock on %s.\n",
devname);
if (dfd >= 0)
close(dfd);
}
if (verbose)
fprintf(stderr, Name ": %s is identified as a member of %s, slot %d.\n",
devname, mddev, super.this_disk.raid_disk);
@ -267,8 +315,12 @@ int Assemble(char *mddev, int mdfd,
> devices[most_recent].events)
most_recent = devcnt;
}
i = devices[devcnt].raid_disk;
if (i>=0 && i < MD_SB_DISKS)
if (super.level == -4)
/* with multipath, the raid_disk from the superblock is meaningless */
i = devcnt;
else
i = devices[devcnt].raid_disk;
if (i>=0 && i < num_devs)
if (best[i] == -1
|| devices[best[i]].events < devices[devcnt].events)
best[i] = devcnt;
@ -286,7 +338,7 @@ int Assemble(char *mddev, int mdfd,
*/
okcnt = 0;
sparecnt=0;
for (i=0; i< MD_SB_DISKS;i++) {
for (i=0; i< num_devs ;i++) {
int j = best[i];
int event_margin = !force;
if (j < 0) continue;
@ -337,6 +389,10 @@ int Assemble(char *mddev, int mdfd,
}
super.events_hi = (devices[most_recent].events>>32)&0xFFFFFFFF;
super.events_lo = (devices[most_recent].events)&0xFFFFFFFF;
if (super.level == 5 || super.level == 4) {
/* need to force clean */
super.state = 0;
}
super.sb_csum = calc_sb_csum(&super);
/*DRYRUN*/ if (store_super(fd, &super)) {
close(fd);
@ -358,7 +414,7 @@ int Assemble(char *mddev, int mdfd,
* superblock.
*/
chosen_drive = -1;
for (i=0; chosen_drive < 0 && i<MD_SB_DISKS; i++) {
for (i=0; chosen_drive < 0 && i<num_devs; i++) {
int j = best[i];
int fd;
if (j<0)
@ -380,7 +436,7 @@ int Assemble(char *mddev, int mdfd,
close(fd);
}
for (i=0; i<MD_SB_DISKS; i++) {
for (i=0; i<num_devs; i++) {
int j = best[i];
int desired_state;
@ -457,9 +513,9 @@ This doesnt work yet
return 1;
}
/* First, add the raid disks, but add the chosen one last */
for (i=0; i<=MD_SB_DISKS; i++) {
for (i=0; i<= num_devs; i++) {
int j;
if (i < MD_SB_DISKS) {
if (i < num_devs) {
j = best[i];
if (j == chosen_drive)
continue;

View File

@ -1,7 +1,37 @@
Changes Prior to this release
Changes Prior to 1.0.9 release
- Documentation updates including kernel parameters documented
in md.4
- --assemble --force for raid4/5 will mark clean, needed for 2.5
- --detail prints out the events counter as well
- flush device before reading superblock to be sure to get
current data
- added mdadm.static target to makefile for static linking
- --monitor was ignoring /dev/md0 due to off-by-one error
- Fix assorted typos
- Fix printing of Gibibytes - calc was wrong.
- Fix printing of Array Size in --detail when very big.
- --monitor no longer tries to work for raid0 or linear as these
have nothing to be monitors.
- The word 'partitions' on a DEVICE line will cause all partitions
listed in /proc/partitions to be considered
- If the config file is called 'partitions' then it will be treated
as though it contained exactly 'device partitions' so e.g.
mdadm -Ebsc partitions
will fill all raid partitions easily.
- successfully assemble multipath devices by ignoring raid_disk
value from superblock (it is always the same).
- --assemble not tied to MD_SB_DISKS limit quite so much
- Support compiling with tcc
- Support compiling with uclibc - just skip scan of /dev
- Add --update= option for Assemble mode. Either sparc2.2
or super-minor updates are possible. See mdadm.8
Changes Prior to 1.0.1 release
- Round off MB/GiB etc values instead of round down.
- Add --sparc2.2 option to examine to shift superblock around
and --sparc2.2update to rewrite the superblock
- Fix assorted typos in online help
Changes Prior to 1.0.0 release
- Allow --config with Misc mode (for --examine --scan)

View File

@ -102,7 +102,7 @@ int Detail(char *dev, int brief)
printf(" Creation Time : %.24s\n", ctime(&atime));
printf(" Raid Level : %s\n", c?c:"-unknown-");
if (larray_size)
printf(" Array Size : %ld%s\n", (long)(larray_size>>10), human_size(larray_size));
printf(" Array Size : %llu%s\n", (larray_size>>10), human_size(larray_size));
if (array.level >= 1)
printf(" Device Size : %d%s\n", array.size, human_size((long long)array.size<<10));
printf(" Raid Devices : %d\n", array.raid_disks);
@ -164,7 +164,7 @@ int Detail(char *dev, int brief)
}
if ((dv=map_dev(disk.major, disk.minor))) {
if (!brief) printf(" %s", dv);
if (!have_super) {
if (!have_super && (disk.state & (1<<MD_DISK_ACTIVE))) {
/* try to read the superblock from this device
* to get more info
*/
@ -186,7 +186,8 @@ int Detail(char *dev, int brief)
super.set_uuid2, super.set_uuid3);
else
printf("%08x", super.set_uuid0);
if (!brief) printf("\n");
if (!brief)
printf("\n Events : %d.%d\n", super.events_hi, super.events_lo);
}
if (brief) printf("\n");
return 0;

View File

@ -170,7 +170,7 @@ int Examine(mddev_dev_t devlist, int brief, int scan, int SparcAdjust)
__u32 *sb32 = (__u32*)&super;
memcpy(sb32+MD_SB_GENERIC_CONSTANT_WORDS+7,
sb32+MD_SB_GENERIC_CONSTANT_WORDS+7+1,
MD_SB_WORDS - (MD_SB_GENERIC_CONSTANT_WORDS+7+1));
(MD_SB_WORDS - (MD_SB_GENERIC_CONSTANT_WORDS+7+1))*4);
printf (" --- adjusting superblock for 2.2/sparc compatability ---\n");
}
printf(" Events : %d.%d\n", super.events_hi, super.events_lo);

View File

@ -29,6 +29,9 @@
# define "CXFLAGS" to give extra flags to CC.
# e.g. make CXFLAGS=-O to optimise
TCC = tcc
UCLIBC_GCC = i386-uclibc-gcc
CC = gcc
CXFLAGS = -ggdb
SYSCONFDIR = /etc
@ -48,12 +51,24 @@ MAN5DIR = $(MANDIR)/man5
MAN8DIR = $(MANDIR)/man8
OBJS = mdadm.o config.o mdstat.o ReadMe.o util.o Manage.o Assemble.o Build.o Create.o Detail.o Examine.o Monitor.o dlink.o Kill.o Query.o
SRCS = mdadm.c config.c mdstat.c ReadMe.c util.c Manage.c Assemble.c Build.c Create.c Detail.c Examine.c Monitor.c dlink.c Kill.c Query.c
all : mdadm mdadm.man md.man mdadm.conf.man
everything: all mdadm.static mdadm.tcc mdadm.uclibc
mdadm : $(OBJS)
$(CC) $(LDFLAGS) -o mdadm $^
mdadm.static : $(OBJS)
$(CC) $(LDFLAGS) --static -o mdadm.static $^
mdadm.tcc : $(SRCS) mdadm.h
$(TCC) -o mdadm.tcc $(SRCS)
mdadm.uclibc : $(SRCS) mdadm.h
$(UCLIBC_GCC) -DUCLIBC -o mdadm.uclibc $(SRCS)
mdadm.man : mdadm.8
nroff -man mdadm.8 > mdadm.man
@ -72,7 +87,7 @@ install : mdadm mdadm.8 md.4 mdadm.conf.5
$(INSTALL) -D -m 644 mdadm.conf.5 $(DESTDIR)$(MAN5DIR)/mdadm.conf.5
clean :
rm -f mdadm $(OBJS) core *.man
rm -f mdadm $(OBJS) core *.man mdadm.tcc mdadm.uclibc
dist : clean
./makedist

View File

@ -182,6 +182,14 @@ int Monitor(mddev_dev_t devlist,
close(fd);
continue;
}
if (array.level != 1 && array.level != 5 && array.level != -4) {
if (!st->err)
alert("DeviceDisappeared", dev, "Wrong-Level",
mailaddr, alert_cmd);
st->err = 1;
close(fd);
continue;
}
if (st->devnum < 0) {
struct stat stb;
if (fstat(fd, &stb) == 0 &&
@ -229,7 +237,7 @@ int Monitor(mddev_dev_t devlist,
if (ioctl(fd, GET_DISK_INFO, &disc)>= 0) {
newstate = disc.state;
dv = map_dev(disc.major, disc.minor);
} else if (mse && i < strlen(mse->pattern))
} else if (mse && mse->pattern && i < strlen(mse->pattern))
switch(mse->pattern[i]) {
case 'U': newstate = 6 /* ACTIVE/SYNC */; break;
case '_': newstate = 0; break;
@ -271,7 +279,11 @@ int Monitor(mddev_dev_t devlist,
if (scan) {
struct mdstat_ent *mse;
for (mse=mdstat; mse; mse=mse->next)
if (mse->devnum > 0) {
if (mse->devnum >= 0 &&
(strcmp(mse->level, "raid1")==0 ||
strcmp(mse->level, "raid5")==0 ||
strcmp(mse->level, "multipath")==0)
) {
struct state *st = malloc(sizeof *st);
if (st == NULL)
continue;

View File

@ -29,7 +29,7 @@
#include "mdadm.h"
char Version[] = Name " - v1.0.1 - 20 May 2002\n";
char Version[] = Name " - v1.0.9 - 12 Feb 2003\n";
/*
* File: ReadMe.c
*
@ -60,14 +60,14 @@ char Version[] = Name " - v1.0.1 - 20 May 2002\n";
/*
* mdadm has 6 major modes of operation:
* 1/ Create
* This mode is used to create a new array with a superbock
* This mode is used to create a new array with a superblock
* It can progress in several step create-add-add-run
* or it can all happen with one command
* 2/ Assemble
* This mode is used to assemble the parts of a previously created
* array into an active array. Components can be explicitly given
* or can be searched for. mdadm (optionally) check that the components
* do form a bonafide array, and can, on request, fiddle superblock
* do form a bona-fide array, and can, on request, fiddle superblock
* version numbers so as to assemble a faulty array.
* 3/ Build
* This is for building legacy arrays without superblocks
@ -86,7 +86,7 @@ char Version[] = Name " - v1.0.1 - 20 May 2002\n";
* This mode never exits but just monitors arrays and reports changes.
*/
char short_options[]="-ABCDEFGQhVvbc:l:p:m:n:x:u:c:d:z:sarfRSow";
char short_options[]="-ABCDEFGQhVvbc:l:p:m:n:x:u:c:d:z:U:sarfRSow";
struct option long_options[] = {
{"manage", 0, 0, '@'},
{"misc", 0, 0, '#'},
@ -112,7 +112,7 @@ struct option long_options[] = {
{"chunk", 1, 0, 'c'},
{"rounding", 1, 0, 'c'}, /* for linear, chunk is really a rounding number */
{"level", 1, 0, 'l'}, /* 0,1,4,5,linear */
{"parity", 1, 0, 'p'}, /* {left,right}-{a,}symetric */
{"parity", 1, 0, 'p'}, /* {left,right}-{a,}symmetric */
{"layout", 1, 0, 'p'},
{"raid-disks",1, 0, 'n'},
{"raid-devices",1, 0, 'n'},
@ -126,6 +126,7 @@ struct option long_options[] = {
{"config", 1, 0, 'c'},
{"scan", 0, 0, 's'},
{"force", 0, 0, 'f'},
{"update", 1, 0, 'U'},
/* Management */
{"add", 0, 0, 'a'},
{"remove", 0, 0, 'r'},
@ -139,7 +140,6 @@ struct option long_options[] = {
/* For Detail/Examine */
{"brief", 0, 0, 'b'},
{"sparc2.2", 0, 0, 22},
{"sparc2.2update", 0, 0, 23},
/* For Follow/monitor */
{"mail", 1, 0, 'm'},
@ -164,7 +164,7 @@ char Help[] =
" mdadm --misc options... devices\n"
" mdadm --monitor options...\n"
" mdadm device options...\n"
" mdadm is used for building, manageing, and monitoring\n"
" mdadm is used for building, managing, and monitoring\n"
" Linux md devices (aka RAID arrays)\n"
" For detail help on the above major modes use --help after the mode\n"
" e.g.\n"
@ -186,7 +186,7 @@ char Help[] =
" --build -B : Build a legacy array\n"
" --create -C : Create a new array\n"
" --detail -D : Display details of an array\n"
" --examine -E : Examine superblock on an array componenet\n"
" --examine -E : Examine superblock on an array component\n"
" --monitor -F : monitor (follow) some arrays\n"
" --query -Q : Display general information about how a\n"
" device relates to the md driver\n"
@ -195,9 +195,9 @@ char Help[] =
"\n"
" For create or build:\n"
" --chunk= -c : chunk size of kibibytes\n"
" --rounding= : rounding factor for linear array (==chunck size)\n"
" --rounding= : rounding factor for linear array (==chunk size)\n"
" --level= -l : raid level: 0,1,4,5,linear,mp. 0 or linear for build\n"
" --paritiy= -p : raid5 parity algorith: {left,right}-{,a}symmetric\n"
" --parity= -p : raid5 parity algorithm: {left,right}-{,a}symmetric\n"
" --layout= : same as --parity\n"
" --raid-devices= -n : number of active devices in array\n"
" --spare-devices= -x: number of spares (eXtras) devices in initial array\n"
@ -213,6 +213,7 @@ char Help[] =
" --config= -c : config file\n"
" --scan -s : scan config file for missing information\n"
" --force -f : Assemble the array even if some superblocks appear out-of-date\n"
" --update= -U : Update superblock: either sparc2.2 or super-minor\n"
"\n"
" For detail or examine:\n"
" --brief -b : Just print device name and UUID\n"
@ -229,7 +230,7 @@ char Help[] =
" --fail -f : mark subsequent devices a faulty\n"
" --set-faulty : same as --fail\n"
" --run -R : start a partially built array\n"
" --stop -S : deactive array, releasing all resources\n"
" --stop -S : deactivate array, releasing all resources\n"
" --readonly -o : mark array as readonly\n"
" --readwrite -w : mark array as readwrite\n"
" --zero-superblock : erase the MD superblock from a device.\n"
@ -259,9 +260,9 @@ char Help_create[] =
"\n"
" Options that are valid with --create (-C) are:\n"
" --chunk= -c : chunk size of kibibytes\n"
" --rounding= : rounding factor for linear array (==chunck size)\n"
" --rounding= : rounding factor for linear array (==chunk size)\n"
" --level= -l : raid level: 0,1,4,5,linear,multipath and synonyms\n"
" --paritiy= -p : raid5 parity algorith: {left,right}-{,a}symmetric\n"
" --parity= -p : raid5 parity algorithm: {left,right}-{,a}symmetric\n"
" --layout= : same as --parity\n"
" --raid-devices= -n : number of active devices in array\n"
" --spare-devices= -x: number of spares (eXtras) devices in initial array\n"
@ -287,7 +288,7 @@ char Help_build[] =
" All devices must be listed and the array will be started once complete.\n"
" Options that are valid with --build (-B) are:\n"
" --chunk= -c : chunk size of kibibytes\n"
" --rounding= : rounding factor for linear array (==chunck size)\n"
" --rounding= : rounding factor for linear array (==chunk size)\n"
" --level= -l : 0, raid0, or linear\n"
" --raid-devices= -n : number of active devices in array\n"
;
@ -335,6 +336,7 @@ char Help_assemble[] =
" for a full array are present\n"
" --force -f : Assemble the array even if some superblocks appear\n"
" : out-of-date. This involves modifying the superblocks.\n"
" --update= -U : Update superblock: either sparc2.2 or super-minor\n"
;
char Help_manage[] =
@ -352,7 +354,7 @@ char Help_manage[] =
" --fail -f : mark subsequent devices a faulty\n"
" --set-faulty : same as --fail\n"
" --run -R : start a partially built array\n"
" --stop -S : deactive array, releasing all resources\n"
" --stop -S : deactivate array, releasing all resources\n"
" --readonly -o : mark array as readonly\n"
" --readwrite -w : mark array as readwrite\n"
;
@ -369,10 +371,10 @@ char Help_misc[] =
" --query -Q : Display general information about how a\n"
" device relates to the md driver\n"
" --detail -D : Display details of an array\n"
" --examine -E : Examine superblock on an array componenet\n"
" --examine -E : Examine superblock on an array component\n"
" --zero-superblock : erase the MD superblock from a device.\n"
" --run -R : start a partially built array\n"
" --stop -S : deactive array, releasing all resources\n"
" --stop -S : deactivate array, releasing all resources\n"
" --readonly -o : mark array as readonly\n"
" --readwrite -w : mark array as readwrite\n"
;
@ -422,7 +424,7 @@ char Help_config[] =
" array. The identity can be given as a UUID with a word starting 'uuid=', or\n"
" as a minor-number stored in the superblock using 'super-minor=', or as a list\n"
" of devices. This is given as a comma separated list of names, possibly\n"
" containing wildcards, preceeded by 'devices='. If multiple critea are given,\n"
" containing wildcards, preceded by 'devices='. If multiple critea are given,\n"
" than a device must match all of them to be considered.\n"
"\n"
" A mailaddr line starts with the word 'mailaddr' and should contain exactly\n"

19
TODO
View File

@ -1,3 +1,22 @@
* --assemble could have a --update option.
following word can be:
sparc2.2
super-minor
* mdadm /dev/md11, where md11 is raid0 can segfault, particularly when looking in the
[UU_UUU] string ... which doesn't exist !
It should be more sensible. DONE
Example:
from Raimund Sacherer <raimund.sacherer@ngit.at>
mke2fs -m0 -q /dev/ram1 300
mount -n -t ext2 /dev/ram1 /tmp
echo DEVICE /dev/[sh]* >> /tmp/mdadm.conf
mdadm -Esb /dev/[sh]* 2>/dev/null >> /tmp/mdadm.conf
mdadm -ARsc /tmp/mdadm.conf
umount /tmp
?? Allow -S /dev/md? - current complains subsequent not a/d/r - DONE

View File

@ -201,6 +201,33 @@ struct conf_dev {
char *name;
} *cdevlist = NULL;
void load_partitions(void)
{
FILE *f = fopen("/proc/partitions", "r");
char buf[1024];
if (f == NULL) {
fprintf(stderr, Name ": cannot open /proc/partitions\n");
return;
}
while (fgets(buf, 1024, f)) {
int major, minor;
char *name;
buf[1023] = '\0';
if (buf[0] != ' ')
continue;
if (sscanf(buf, " %d %d ", &major, &minor) != 2)
continue;
name = map_dev(major, minor);
if (name) {
struct conf_dev *cd;
cd = malloc(sizeof(*cd));
cd->name = strdup(name);
cd->next = cdevlist;
cdevlist = cd;
}
}
}
void devline(char *line)
@ -214,6 +241,9 @@ void devline(char *line)
cd->name = strdup(w);
cd->next = cdevlist;
cdevlist = cd;
} else if (strcasecmp(w, "partitions") == 0) {
/* read /proc/partitions, and look major/minor up in /dev */
load_partitions();
} else {
fprintf(stderr, Name ": unreconised word on DEVICE line: %s\n",
w);
@ -349,6 +379,10 @@ void load_conffile(char *conffile)
if (conffile == NULL)
conffile = DefaultConfFile;
if (strcmp(conffile, "partitions")==0) {
load_partitions();
return;
}
f = fopen(conffile, "r");
if (f ==NULL)
return;

View File

@ -21,7 +21,7 @@ then
exit 1
fi
trap "rm $target/$base; exit" 1 2 3
( cd .. ; ln -s mdadm mdadm-$version ; tar czhvf - --exclude='*,v' --exclude='*.o' --exclude mdadm --exclude=RCS mdadm-$version ; rm mdadm-$version ) > $target/$base
( cd .. ; ln -s mdadm mdadm-$version ; tar chvf - --exclude='*,v' --exclude='*.o' --exclude mdadm --exclude=mdadm'.[^ch0-9]' --exclude=RCS mdadm-$version ; rm mdadm-$version ) | gzip --best > $target/$base
chmod a+r $target/$base
ls -l $target/$base

42
md.4
View File

@ -99,7 +99,7 @@ still have remaining space.
.SS RAID1
A RAID1 array is also known as a mirrored set (though mirrors tend to
provide reflect images, which RAID1 does not) or a plex.
provide reflected images, which RAID1 does not) or a plex.
Once initialised, each device in a RAID1 array contains exactly the
same data. Changes are written to all devices in parallel. Data is
@ -171,13 +171,16 @@ correct any possibly inconsistency. For RAID1, this involves copying
the contents of the first drive onto all other drives.
For RAID4 or RAID5 this involves recalculating the parity for each
stripe and making sure that the parity block has the correct data.
This process, known as "resynchronising" or "resync" is performed in
the background. The array can still be used, though possibly with
reduced performance.
If a RAID4 or RAID5 array is degraded (missing one drive) when it is
restarted after an unclean shutdown, it cannot recalculate parity, and
so it is possible that data might be undetectably corrupted.
The md driver currently
The 2.4 md driver
.B does not
alert the operator to this condition. It should probably fail to
alert the operator to this condition. The 2.5 md driver will fail to
start an array in this condition without manual intervention.
.SS RECOVERY
@ -201,6 +204,39 @@ and
.B speed_limit_max
control files mentioned below.
.SS KERNEL PARAMETERS
The md driver recognised three different kernel parameters.
.TP
.B raid=noautodetect
This will disable the normal detection of md arrays that happens at
boot time. If a drive is partitioned with MS-DOS style partitions,
then if any of the 4 main partitions has a partition type of 0xFD,
then that partition will normally be inspected to see if it is part of
an MD array, and if any full arrays are found, they are started. This
kernel paramenter disables this behaviour.
.TP
.BI md= n , dev , dev ,...
This tells the md driver to assemble
.B /dev/md n
from the listed devices. It is only necessary to start the device
holding the root filesystem this way. Other arrays are best started
once the system is booted.
.TP
.BI md= n , l , c , i , dev...
This tells the md driver to assemble a legacy RAID0 or LINEAR array
without a superblock.
.I n
gives the md device number,
.I l
gives the level, 0 for RAID0 or -1 for LINEAR,
.I c
gives the chunk size as a base-2 logarithm offset by twelve, so 0
means 4K, 1 means 8K.
.I i
is ignored (legacy support).
.SH FILES
.TP

4
md_p.h
View File

@ -163,6 +163,10 @@ typedef struct mdp_superblock_s {
} mdp_super_t;
#ifdef __TINYC__
typedef unsigned long long __u64;
#endif
static inline __u64 md_event(mdp_super_t *sb) {
__u64 ev = sb->events_hi;
return (ev<<32)| sb->events_lo;

182
mdadm.8
View File

@ -53,7 +53,7 @@ is a single program and not a collection of programs.
.IP \(bu 4
.B mdadm
can perform (almost) all of its functions without having a
configuration file. Also
configuration file and does not use one by default. Also
.B mdadm
helps with management of the configuration
file.
@ -63,6 +63,14 @@ can provide information about your arrays (through Query, Detail, and Examine)
that
.B raidtools
cannot.
.P
.I mdadm
does not use
.IR /etc/raidtab ,
the
.B raidtools
configuration file, at all. It has a different configuration file
with a different format and an different purpose.
.SH MODES
mdadm has 6 major modes of operation:
@ -98,7 +106,11 @@ superblocks, erasing old superblocks and stopping active arrays.
.TP
.B "Follow or Monitor"
Monitor one or more md devices and act on any state changes.
Monitor one or more md devices and act on any state changes. This is
only meaningful for raid1, raid5 or multipath arrays as only these have
interesting state. raid0 or linear never have missing, spare, or
failed drives, so there is nothing to monitor.
.SH OPTIONS
@ -165,6 +177,15 @@ the exact meaning of this option in different contexts.
.BR -c ", " --config=
Specify the config file. Default is
.BR /etc/mdadm.conf .
If the config file given is
.B partitions
then nothing will be read, but
.I mdadm
will act as though the config file contained exactly
.B "DEVICE partitions"
and will read
.B /proc/partitions
to find a list of devices to scan.
.TP
.BR -s ", " --scan
@ -217,12 +238,21 @@ same as --parity
.TP
.BR -n ", " --raid-devices=
number of active devices in array.
Specify the number of active devices in the array. This, plus the
number of spare devices (see below) must equal the number of
.I component-devices
(including
.B missing
devices) that are listed on the command line.
.TP
.BR -x ", " --spare-devices=
number of spare (eXtra) devices in initial array. Spares can be added
and removed later.
Specify the number of spare (eXtra) devices in the initial array.
Spares can also be added
and removed later. The number of component devices listed
on the command line must equal the number of raid devices plus the
number of spare devices.
.TP
.BR -z ", " --size=
@ -262,6 +292,33 @@ With
.B --run
an attempt will be made to start it anyway.
.TP
.BR -U ", " --update=
Update the superblock on each device while assembling the array. The
argument given to this flag can be either
.B sparc2.2
or
.BR super-minor .
The
.B sparc2.2
option will adjust the superblock of an array what was created on a Sparc
machine running a patched 2.2 Linux kernel. This kernel got the
alignment of part of the superblock wrong. You can use the
.B "--examine --sparc2.2"
option to
.I mdadm
to see what effect this would have.
The
.B super-minor
option will update the
.B "prefered minor"
field on each superblock to match the minor number of the array being
assembled. This is not need on 2.6 and later kernels as they make
this adjustment automatically.
.SH For Manage mode:
.TP
@ -282,6 +339,20 @@ mark listed devices as faulty.
.BR --set-faulty
same as --fail.
.SH For Examine mode:
.TP
.B --sparc2.2
In an array was created on a 2.2 Linux kernel patched with RAID
support, the superblock will have been created incorrectly, or at
least incompatibly with 2.4 and later kernels. Using the
.B --sparc2.2
flag with
.B --examine
will fix the superblock before displaying it. If this appears to do
the right thing, then the array can be successfully assembled using
.BR "--assemble --update=sparc2.2" .
.SH For Misc mode:
.TP
@ -329,7 +400,11 @@ again. The default is 60 seconds.
.HP 12
Usage:
.B mdadm --assemble
.I device options...
.I md-device options-and-component-devices...
.HP 12
Usage:
.B mdadm --assemble --scan
.I md-devices-and-options...
.HP 12
Usage:
.B mdadm --assemble --scan
@ -340,22 +415,26 @@ This usage assembles one or more raid arrays from pre-existing components.
For each array, mdadm needs to know the md device, the identity of the
array, and a number of component-devices. These can be found in a number of ways.
The md device is either given before
.B --scan
or is found from the config file. In the latter case, multiple md devices
can be started with a single mdadm command.
In the first usage example (without the
.BR --scan )
the first device given is the md device.
In the second usage example, all devices listed are treated as md
devices and assembly is attempted.
In the third (where no devices are listed) all md devices that are
listed in the configuration file are assembled.
The identity can be given with the
.B --uuid
option, with the
.B --super-minor
option, can be found in in the config file, or will be taken from the
option, can be found in the config file, or will be taken from the
super block on the first component-device listed on the command line.
Devices can be given on the
.B --assemble
command line or from the config file. Only devices which have an md
superblock which contains the right identity will be considered for any device.
command line or in the config file. Only devices which have an md
superblock which contains the right identity will be considered for
any array.
The config file is only used if explicitly named with
.B --config
@ -470,7 +549,7 @@ This usage will allow individual devices in an array to be failed,
removed or added. It is possible to perform multiple operations with
on command. For example:
.br
.B " mdadm /dev/md0 -f /dev/hda1 -r /dev/hda1 /a /dev/hda1"
.B " mdadm /dev/md0 -f /dev/hda1 -r /dev/hda1 -a /dev/hda1"
.br
will firstly mark
.B /dev/hda1
@ -706,62 +785,83 @@ the original array.
.SH EXAMPLES
To find out if a devices is a raid array or part of one:
.B " mdadm --query /dev/name-of-device"
.br
.B " mdadm -Q /dev/name-of-device"
This will find out if a given device is a raid array, or is part of
one, and will provide brief information about the device.
To assemble and start all array listed in the standard config file:
.B " mdadm --assemble --scan"
.br
.B " mdadm -As"
This will assemble and start all arrays listed in the standard confile
file. This command will typically go in a system startup file.
To shut down all arrays (that are not still in used):
.br
.B " mdadm --stop --scan"
To monitor all arrays if (and only if) an email address or program
was given in the config file, but poll every 2 minutes:
.br
.B " mdadm -Fs --delay=120"
This will shut down all array that can be shut down (i.e. are not
currently in used). This will typically going in a system shutdown script.
To create /dev/md0 as a RAID1 array with /dev/hda1 and /dev/hdc1:
.B " mdadm --follow --scan --delay=120"
.br
.B " mdadm -C /dev/md0 -l1 -n2 /dev/hd[ac]1"
If (and only if) there is an Email address or program given in the
standard config file, then
monitor the status of all arrays listed in that file by
polling them ever 2 minutes.
.B " mdadm --create /dev/md0 --level=1 --raid-devices=2 /dev/hd[ac]1"
.br
Create /dev/md0 as a RAID1 array consisting of /dev/hda1 and /dev/hdc1.
To create prototype a config file that describes currently
active arrays that are known to be made from partitions of
IDE or SCSI drives:
.br
.B " echo 'DEVICE /dev/hd*[0-9] /dev/sd*[0-9]' > mdadm.conf"
.br
.B " mdadm --detail --scan >> mdadm.conf"
.br
This will create a prototype config file that describes currently
active arrays that are known to be made from partitions of IDE or SCSI drives.
This file should be reviewed before being used as it may
contain unwanted detail.
To find out what raid arrays could be assembled from existing
IDE and SCSI whole drives (not partitions):
.br
.B " echo 'DEVICE /dev/hd[a-z] /dev/sd*[a-z]' > mdadm.conf"
.br
.B " mdadm -Es -c mdadm.conf >> mdadm.conf"
.B " mdadm --examine --scan --config=mdadm.conf >> mdadm.conf"
.ber
This will find what arrays could be assembled from existign IDE and
SCSI whole drives (not partitions) and store the information is the
format of a config file.
This file is very likely to contain unwanted detail, particularly
the
.B devices=
entries.
entries. It should be reviewed and edited before being used as an
actual config file.
To get help about Create mode:
.B " mdadm --examine --brief --scan --config=partitions"
.br
.B " mdadm -Ebsc partitions"
.br
Create a list of devices by reading
.BR /proc/partitions ,
scan these for RAID superblocks, and printout a brief listing of all
that was found.
.B " mdadm -Ac partitions -m 0 /dev/md0"
.br
Scan all partitions and devices listed in
.BR /proc/partitions
and assemble
.B /dev/md0
out of all such devices with a RAID superblock with a minor number of 0.
.B " mdadm --create --help"
To get help about the format of the config file:
.br
Providew help about the Create mode.
.B " mdadm --config --help"
To get general help:
.br
Provide help about the format of the config file.
.B " mdadm --help"
.br
Provide general help.
.SH FILES

35
mdadm.c
View File

@ -65,6 +65,7 @@ int main(int argc, char *argv[])
struct mddev_ident_s ident;
char *configfile = NULL;
char *cp;
char *update = NULL;
int scan = 0;
char devmode = 0;
int runstop = 0;
@ -369,6 +370,19 @@ int main(int argc, char *argv[])
}
continue;
case O(ASSEMBLE,'U'): /* update the superblock */
if (update) {
fprintf(stderr, Name ": Can only update one aspect of superblock, both %s and %s given.\n",
update, optarg);
exit(2);
}
update = optarg;
if (strcmp(update, "sparc2.2")==0) continue;
if (strcmp(update, "super-minor") == 0)
continue;
fprintf(stderr, Name ": '--update %s' invalid. Only 'sparc2.2' or 'super-minor' supported\n",update);
exit(2);
case O(ASSEMBLE,'c'): /* config file */
case O(MISC, 'c'):
case O(MONITOR,'c'):
@ -489,13 +503,6 @@ int main(int argc, char *argv[])
}
SparcAdjust = 1;
continue;
case O(MISC,23):
if (devmode != 'E') {
fprintf(stderr, Name ": --sparc2.2update only allowed with --examine\n");
exit(2);
}
SparcAdjust = 2;
continue;
}
/* We have now processed all the valid options. Anything else is
* an error
@ -548,8 +555,12 @@ int main(int argc, char *argv[])
if (!scan)
rv = Assemble(devlist->devname, mdfd, &ident, configfile,
devlist->next,
readonly, runstop, verbose, force);
else if (devs_found>0)
readonly, runstop, update, verbose, force);
else if (devs_found>0) {
if (update && devs_found > 1) {
fprintf(stderr, Name ": can only update a single array at a time\n");
exit(1);
}
for (dv = devlist ; dv ; dv=dv->next) {
mddev_ident_t array_ident = conf_get_ident(configfile, dv->devname);
mdfd = open_mddev(dv->devname);
@ -565,9 +576,9 @@ int main(int argc, char *argv[])
}
rv |= Assemble(dv->devname, mdfd, array_ident, configfile,
NULL,
readonly, runstop, verbose, force);
readonly, runstop, update, verbose, force);
}
else {
} else {
mddev_ident_t array_list = conf_get_ident(configfile, NULL);
if (!array_list) {
fprintf(stderr, Name ": No arrays found in config file\n");
@ -586,7 +597,7 @@ int main(int argc, char *argv[])
rv |= Assemble(array_list->devname, mdfd,
array_list, configfile,
NULL,
readonly, runstop, verbose, force);
readonly, runstop, NULL, verbose, force);
}
}
break;

View File

@ -32,14 +32,14 @@
# Arrays can currently be identified by using a UUID, superblock minor number,
# or a listing of devices.
#
# super-minor is usally the minor number of the metadevice
# super-minor is usually the minor number of the metadevice
# UUID is the Universally Unique Identifier for the array
# Each can be obtained using
#
# mdadm -D <md>
#
#ARRAY /dev/md0 UUID=3aaa0122:29827cfa:5331ad66:ca767371
#ARRAY /dev/md1 superminor=1
#ARRAY /dev/md1 super-minor=1
#ARRAY /dev/md2 devices=/dev/hda1,/dev/hda2
#
# ARRAY lines can also specify a "spare-group" for each array. mdadm --monitor

View File

@ -45,6 +45,22 @@ and each device name can contain wild cards as defined by
Also, there may be several device lines present in the file.
Alternatively, a
.B device
line can contain the word
.BR partitions .
This will cause
.I mdadm
to read
.I /proc/partitions
and include all devices and partitions found there-in.
.I mdadm
does not use the names from
.I /proc/partitions
but only the major and minor device numbers. It scans
.I /dev
to find the name that matches the numbers.
For example:
.IP
DEVICE /dev/hda* /dev/hdc*
@ -52,6 +68,8 @@ DEVICE /dev/hda* /dev/hdc*
DEV /dev/sd*
.br
DEVICE /dev/discs/disc*/disc
.br
DEVICE partitions
.TP
.B ARRAY

View File

@ -150,6 +150,7 @@ extern int Assemble(char *mddev, int mdfd,
char *conffile,
mddev_dev_t devlist,
int readonly, int runstop,
char *update,
int verbose, int force);
extern int Build(char *mddev, int mdfd, int chunk, int level,

View File

@ -1,6 +1,6 @@
Summary: mdadm is used for controlling Linux md devices (aka RAID arrays)
Name: mdadm
Version: 1.0.1
Version: 1.0.9
Release: 1
Source: http://www.cse.unsw.edu.au/~neilb/source/mdadm/mdadm-%{version}.tgz
URL: http://www.cse.unsw.edu.au/~neilb/source/mdadm/

BIN
mdadm.static Executable file

Binary file not shown.

2
test Normal file
View File

@ -0,0 +1,2 @@
dev partitions
array /dev/md0 super-minor=6

20
util.c
View File

@ -91,7 +91,8 @@ int md_get_version(int fd)
if (ioctl(fd, RAID_VERSION, &vers) == 0)
return (vers.major*10000) + (vers.minor*100) + vers.patchlevel;
if (errno == EACCES)
return -1;
if (MAJOR(stb.st_rdev) == MD_MAJOR)
return (3600);
return -1;
@ -212,6 +213,8 @@ int load_super(int fd, mdp_super_t *super)
offset *= 512;
ioctl(fd, BLKFLSBUF, 0); /* make sure we read current data */
if (lseek64(fd, offset, 0)< 0LL)
return 3;
@ -314,7 +317,7 @@ int check_raid(int fd, char *name)
if (load_super(fd, &super))
return 0;
/* Looks like a raid array .. */
fprintf(stderr, Name ": %s appear to be part of a raid array:\n",
fprintf(stderr, Name ": %s appears to be part of a raid array:\n",
name);
crtime = super.ctime;
fprintf(stderr, " level=%d devices=%d ctime=%s",
@ -375,6 +378,16 @@ struct devmap {
} *devlist = NULL;
int devlist_ready = 0;
#ifdef UCLIBC
char *map_dev(int major, int minor)
{
#if 0
fprintf(stderr, "Warning - fail to map %d,%d to a device name\n",
major, minor);
#endif
return NULL;
}
#else
#define __USE_XOPEN_EXTENDED
#include <ftw.h>
@ -410,6 +423,7 @@ char *map_dev(int major, int minor)
return NULL;
}
#endif
int calc_sb_csum(mdp_super_t *super)
{
@ -446,7 +460,7 @@ char *human_size(long long bytes)
(long)(bytes>>30),
(long)(((bytes>>10)&0xfffff)+0x100000/200)/(0x100000/100),
(long)(bytes/1000LL/1000LL/1000LL),
(long)((((bytes/1000)%1000000)+50000)/10000)
(long)((((bytes/1000)%1000000)+5000)/10000)
);
return buf;
}