Release 1.8.1 after some man page updates and other fixes.
Signed-off-by: Neil Brown <neilb@cse.unsw.edu.au>
This commit is contained in:
parent
024ce7fe2b
commit
570c054247
4
Create.c
4
Create.c
|
@ -205,9 +205,9 @@ int Create(struct supertype *st, char *mddev, int mdfd,
|
|||
}
|
||||
else {
|
||||
ldsize = dsize;
|
||||
dsize <<= 9;
|
||||
ldsize <<= 9;
|
||||
}
|
||||
freesize = st->ss->avail_size(ldsize);
|
||||
freesize = st->ss->avail_size(ldsize >> 9);
|
||||
if (freesize == 0) {
|
||||
fprintf(stderr, Name ": %s is too small: %luK\n",
|
||||
dname, (unsigned long)(ldsize>>10));
|
||||
|
|
2
Makefile
2
Makefile
|
@ -62,7 +62,7 @@ OBJS = mdadm.o config.o mdstat.o ReadMe.o util.o Manage.o Assemble.o Build.o \
|
|||
SRCS = mdadm.c config.c mdstat.c ReadMe.c util.c Manage.c Assemble.c Build.c \
|
||||
Create.c Detail.c Examine.c Grow.c Monitor.c dlink.c Kill.c Query.c mdopen.c super0.c super1.c
|
||||
|
||||
ASSEMBLE_SRCS := mdassemble.c Assemble.c config.c dlink.c util.c
|
||||
ASSEMBLE_SRCS := mdassemble.c Assemble.c config.c dlink.c util.c super0.c super1.c
|
||||
ifdef MDASSEMBLE_AUTO
|
||||
ASSEMBLE_SRCS += mdopen.c mdstat.c
|
||||
ASSEMBLE_FLAGS = -DMDASSEMBLE_AUTO
|
||||
|
|
71
md.4
71
md.4
|
@ -16,7 +16,7 @@ Array of Independent Devices.
|
|||
.B md
|
||||
supports RAID levels 1 (mirroring) 4 (striped array with parity
|
||||
device), 5 (striped array with distributed parity information) and 6
|
||||
(striped array with distributed dual redundancy information.) If a
|
||||
(striped array with distributed dual redundancy information.) If
|
||||
some number of underlying devices fails while using one of these
|
||||
levels, the array will continue to function; this number is one for
|
||||
RAID levels 4 and 5, two for RAID level 6, and all but one (N-1) for
|
||||
|
@ -24,24 +24,42 @@ RAID level 1.
|
|||
.PP
|
||||
.B md
|
||||
also supports a number of pseudo RAID (non-redundant) configurations
|
||||
including RAID0 (striped array), LINEAR (catenated array) and
|
||||
MULTIPATH (a set of different interfaces to the same device).
|
||||
including RAID0 (striped array), LINEAR (catenated array),
|
||||
MULTIPATH (a set of different interfaces to the same device),
|
||||
and FAULTY (a layer over a single device into which errors can be injected).
|
||||
|
||||
.SS MD SUPER BLOCK
|
||||
With the exception of Legacy Arrays described below, each device that
|
||||
is incorporated into an MD array has a
|
||||
.I super block
|
||||
written towards the end of the device. This superblock records
|
||||
information about the structure and state of the array so that the
|
||||
array can be reliably re-assembled after a shutdown.
|
||||
Each device in an array may have a
|
||||
.I superblock
|
||||
which records information about the structure and state of the array.
|
||||
This allows the array to be reliably re-assembled after a shutdown.
|
||||
|
||||
The superblock is 4K long and is written into a 64K aligned block that
|
||||
From Linux kernel version 2.6.10,
|
||||
.B md
|
||||
provides support for two different formats of this superblock, and
|
||||
other formats can be added. Prior to this release, only one format is
|
||||
supported.
|
||||
|
||||
The common format - known as version 0.90 - has
|
||||
a superblock that is 4K long and is written into a 64K aligned block that
|
||||
starts at least 64K and less than 128K from the end of the device
|
||||
(i.e. to get the address of the superblock round the size of the
|
||||
device down to a multiple of 64K and then subtract 64K).
|
||||
The available size of each device is the amount of space before the
|
||||
super block, so between 64K and 128K is lost when a device in
|
||||
incorporated into an MD array.
|
||||
This superblock stores multi-byte fields in a processor-dependant
|
||||
manner, so arrays cannot easily be moved between computers with
|
||||
different processors.
|
||||
|
||||
The new format - known as version 1 - has a superblock that is
|
||||
normally 1K long, but can be longer. It is normally stored between 8K
|
||||
and 12K from the end of the device, on a 4K boundary, though
|
||||
variations can be stored at the start of the device (version 1.1) or 4K from
|
||||
the start of the device (version 1.2).
|
||||
This superblock format stores multibyte data in a
|
||||
processor-independant format and has supports upto hundreds of
|
||||
component devices (version 0.90 only supports 28).
|
||||
|
||||
The superblock contains, among other things:
|
||||
.TP
|
||||
|
@ -53,17 +71,34 @@ UUID
|
|||
a 128 bit Universally Unique Identifier that identifies the array that
|
||||
this device is part of.
|
||||
|
||||
.SS LEGACY ARRAYS
|
||||
.SS ARRAYS WITHOUT SUPERBLOCKS
|
||||
While it is usually best to create arrays with superblocks so that
|
||||
they can be assembled reliably, there are some circumstances where an
|
||||
array without superblocks in preferred. This include:
|
||||
.TP
|
||||
LEGACY ARRAYS
|
||||
Early versions of the
|
||||
.B md
|
||||
driver only supported Linear and Raid0 configurations and so
|
||||
did not use an MD superblock (as there is no state that needs to be
|
||||
recorded). While it is strongly recommended that all newly created
|
||||
arrays utilise a superblock to help ensure that they are assembled
|
||||
properly, the
|
||||
driver only supported Linear and Raid0 configurations and did not use
|
||||
a superblock (which is less critical with these configurations).
|
||||
While such arrays should be rebuilt with superblocks if possible,
|
||||
.B md
|
||||
driver still supports legacy linear and raid0 md arrays that
|
||||
do not have a superblock.
|
||||
continues to support them.
|
||||
.TP
|
||||
FAULTY
|
||||
Being a largely transparent layer over a different device, the FAULTY
|
||||
personality doesn't gain anything from having a superblock.
|
||||
.TP
|
||||
MULTIPATH
|
||||
It is often possible to detect devices which are different paths to
|
||||
the same storage directly rather than having a distinctive superblock
|
||||
written to the device and searched for on all paths. In this case,
|
||||
a MULTIPATH array with no superblock makes sense.
|
||||
.TP
|
||||
RAID1
|
||||
In some configurations it might be desired to create a raid1
|
||||
configuration that does use a superblock, and to maintain the state of
|
||||
the array elsewhere. While not encouraged, this is supported.
|
||||
|
||||
.SS LINEAR
|
||||
|
||||
|
|
22
mdadm.8
22
mdadm.8
|
@ -1,5 +1,5 @@
|
|||
.\" -*- nroff -*-
|
||||
.TH MDADM 8 "" v1.11.0
|
||||
.TH MDADM 8 "" v1.11.1
|
||||
.SH NAME
|
||||
mdadm \- manage MD devices
|
||||
.I aka
|
||||
|
@ -92,7 +92,7 @@ information so as to assemble a faulty array.
|
|||
|
||||
.TP
|
||||
.B Build
|
||||
Build a legacy array without per-device superblocks.
|
||||
Build an array without per-device superblocks.
|
||||
|
||||
.TP
|
||||
.B Create
|
||||
|
@ -234,6 +234,24 @@ in which case
|
|||
says to get a list of array devices from
|
||||
.BR /proc/mdstat .
|
||||
|
||||
.TP
|
||||
.B -e ", " --metadata=
|
||||
Declare the style of superblock (raid metadata) to be used. The
|
||||
default is 0.90 for --create, and to guess for other operations.
|
||||
|
||||
Options are:
|
||||
.RS
|
||||
.IP "0, 0.90, default"
|
||||
Use the original 0.90 format superblock. This format limits arrays to
|
||||
28 componenet devices and limits component devices of levels 1 and
|
||||
greater to 2 terabytes.
|
||||
.IP "1, 1.0, 1.1, 1.2"
|
||||
Use the new version-1 format superblock. This has few restrictions.
|
||||
The different subversion store the superblock at different locations
|
||||
on the device, either at the end (for 1.0), at the start (for 1.1) or
|
||||
4K from the start (for 1.2).
|
||||
.RE
|
||||
|
||||
.SH For create or build:
|
||||
|
||||
.TP
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
Summary: mdadm is used for controlling Linux md devices (aka RAID arrays)
|
||||
Name: mdadm
|
||||
Version: 1.11.0
|
||||
Version: 1.11.1
|
||||
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/
|
||||
|
|
|
@ -95,7 +95,7 @@ int main() {
|
|||
if (ioctl(mdfd, GET_ARRAY_INFO, &array)>=0)
|
||||
/* already assembled, skip */
|
||||
continue;
|
||||
rv |= Assemble(array_list->devname, mdfd,
|
||||
rv |= Assemble(array_list->st, array_list->devname, mdfd,
|
||||
array_list, configfile,
|
||||
NULL,
|
||||
readonly, runstop, NULL, verbose, force);
|
||||
|
|
1
super0.c
1
super0.c
|
@ -415,6 +415,7 @@ static int store_super0(int fd, void *sbv)
|
|||
if (write(fd, super, sizeof(*super)) != sizeof(*super))
|
||||
return 4;
|
||||
|
||||
fsync(fd);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
35
super1.c
35
super1.c
|
@ -83,7 +83,9 @@ struct mdp_superblock_1 {
|
|||
__u16 dev_roles[0]; /* role in array, or 0xffff for a spare, or 0xfffe for faulty */
|
||||
};
|
||||
|
||||
#ifndef offsetof
|
||||
#define offsetof(t,f) ((int)&(((t*)0)->f))
|
||||
#endif
|
||||
static unsigned int calc_sb_1_csum(struct mdp_superblock_1 * sb)
|
||||
{
|
||||
unsigned int disk_csum, csum;
|
||||
|
@ -139,11 +141,11 @@ static void examine_super1(void *sbv)
|
|||
printf(" Raid Level : %s\n", c?c:"-unknown-");
|
||||
printf(" Raid Devices : %d\n", __le32_to_cpu(sb->raid_disks));
|
||||
printf("\n");
|
||||
printf(" Device Size : %llu%s\n", sb->data_size, human_size(sb->data_size<<9));
|
||||
printf(" Device Size : %llu%s\n", (unsigned long long)sb->data_size, human_size(sb->data_size<<9));
|
||||
if (sb->data_offset)
|
||||
printf(" Data Offset : %llu sectors\n", __le64_to_cpu(sb->data_offset));
|
||||
printf(" Data Offset : %llu sectors\n", (unsigned long long)__le64_to_cpu(sb->data_offset));
|
||||
if (sb->super_offset)
|
||||
printf(" Super Offset : %llu sectors\n", __le64_to_cpu(sb->super_offset));
|
||||
printf(" Super Offset : %llu sectors\n", (unsigned long long)__le64_to_cpu(sb->super_offset));
|
||||
printf(" Device UUID : ");
|
||||
for (i=0; i<16; i++) {
|
||||
printf("%02x", sb->set_uuid[i]);
|
||||
|
@ -159,7 +161,7 @@ static void examine_super1(void *sbv)
|
|||
else
|
||||
printf(" Checksum : %x - expected %x\n", __le32_to_cpu(sb->sb_csum),
|
||||
__le32_to_cpu(calc_sb_1_csum(sb)));
|
||||
printf(" Events : %llu\n", __le64_to_cpu(sb->events));
|
||||
printf(" Events : %llu\n", (unsigned long long)__le64_to_cpu(sb->events));
|
||||
printf("\n");
|
||||
if (__le32_to_cpu(sb->level) == 5) {
|
||||
c = map_num(r5layout, __le32_to_cpu(sb->layout));
|
||||
|
@ -235,7 +237,7 @@ static void detail_super1(void *sbv)
|
|||
printf("%02x", sb->set_uuid[i]);
|
||||
if ((i&3)==0 && i != 0) printf(":");
|
||||
}
|
||||
printf("\n Events : %llu\n\n", __le64_to_cpu(sb->events));
|
||||
printf("\n Events : %llu\n\n", (unsigned long long)__le64_to_cpu(sb->events));
|
||||
}
|
||||
|
||||
static void brief_detail_super1(void *sbv)
|
||||
|
@ -452,6 +454,7 @@ static int store_super1(int fd, void *sbv)
|
|||
if (write(fd, sb, sbsize) != sbsize)
|
||||
return 4;
|
||||
|
||||
fsync(fd);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -575,15 +578,33 @@ static int load_super1(struct supertype *st, int fd, void **sbp, char *devname)
|
|||
|
||||
|
||||
if (st->ss == NULL) {
|
||||
/* guess... */
|
||||
int bestvers = -1;
|
||||
__u64 bestctime = 0;
|
||||
/* guess... choose latest ctime */
|
||||
st->ss = &super1;
|
||||
for (st->minor_version = 0; st->minor_version <= 2 ; st->minor_version++) {
|
||||
switch(load_super1(st, fd, sbp, devname)) {
|
||||
case 0: return 0; /* good */
|
||||
case 0: super = *sbp;
|
||||
if (bestvers == -1 ||
|
||||
bestctime < __le64_to_cpu(super->ctime)) {
|
||||
bestvers = st->minor_version;
|
||||
bestctime = __le64_to_cpu(super->ctime);
|
||||
}
|
||||
free(super);
|
||||
*sbp = NULL;
|
||||
break;
|
||||
case 1: st->ss = NULL; return 1; /*bad device */
|
||||
case 2: break; /* bad, try next */
|
||||
}
|
||||
}
|
||||
if (bestvers != -1) {
|
||||
int rv;
|
||||
st->minor_version = bestvers;
|
||||
st->ss = &super1;
|
||||
rv = load_super1(st, fd, sbp, devname);
|
||||
if (rv) st->ss = NULL;
|
||||
return rv;
|
||||
}
|
||||
st->ss = NULL;
|
||||
return 2;
|
||||
}
|
||||
|
|
27
util.c
27
util.c
|
@ -386,6 +386,15 @@ unsigned long calc_csum(void *super, int bytes)
|
|||
for(i=0; i<bytes/4; i++)
|
||||
newcsum+= superc[i];
|
||||
csum = (newcsum& 0xffffffff) + (newcsum>>32);
|
||||
#ifdef __alpha__
|
||||
/* The in-kernel checksum calculation is always 16bit on
|
||||
* the alpha, though it is 32 bit on i386...
|
||||
* I wonder what it is elsewhere... (it uses and API in
|
||||
* a way that it shouldn't).
|
||||
*/
|
||||
csum = (csum & 0xffff) + (csum >> 16);
|
||||
csum = (csum & 0xffff) + (csum >> 16);
|
||||
#endif
|
||||
return csum;
|
||||
}
|
||||
|
||||
|
@ -544,6 +553,8 @@ struct supertype *guess_super(int fd)
|
|||
*/
|
||||
struct superswitch *ss;
|
||||
struct supertype *st;
|
||||
unsigned long besttime = 0;
|
||||
int bestsuper = -1;
|
||||
|
||||
void *sbp = NULL;
|
||||
int i;
|
||||
|
@ -554,10 +565,26 @@ struct supertype *guess_super(int fd)
|
|||
int rv;
|
||||
ss = superlist[i];
|
||||
rv = ss->load_super(st, fd, &sbp, NULL);
|
||||
if (rv == 0) {
|
||||
struct mdinfo info;
|
||||
ss->getinfo_super(&info, sbp);
|
||||
if (bestsuper == -1 ||
|
||||
besttime < info.array.ctime) {
|
||||
bestsuper = i;
|
||||
besttime = info.array.ctime;
|
||||
st->ss = NULL;
|
||||
}
|
||||
free(sbp);
|
||||
}
|
||||
}
|
||||
if (bestsuper != -1) {
|
||||
int rv;
|
||||
rv = superlist[bestsuper]->load_super(st, fd, &sbp, NULL);
|
||||
if (rv == 0) {
|
||||
free(sbp);
|
||||
return st;
|
||||
}
|
||||
}
|
||||
free(st);
|
||||
return NULL;
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue