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 {
|
else {
|
||||||
ldsize = dsize;
|
ldsize = dsize;
|
||||||
dsize <<= 9;
|
ldsize <<= 9;
|
||||||
}
|
}
|
||||||
freesize = st->ss->avail_size(ldsize);
|
freesize = st->ss->avail_size(ldsize >> 9);
|
||||||
if (freesize == 0) {
|
if (freesize == 0) {
|
||||||
fprintf(stderr, Name ": %s is too small: %luK\n",
|
fprintf(stderr, Name ": %s is too small: %luK\n",
|
||||||
dname, (unsigned long)(ldsize>>10));
|
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 \
|
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
|
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
|
ifdef MDASSEMBLE_AUTO
|
||||||
ASSEMBLE_SRCS += mdopen.c mdstat.c
|
ASSEMBLE_SRCS += mdopen.c mdstat.c
|
||||||
ASSEMBLE_FLAGS = -DMDASSEMBLE_AUTO
|
ASSEMBLE_FLAGS = -DMDASSEMBLE_AUTO
|
||||||
|
|
71
md.4
71
md.4
|
@ -16,7 +16,7 @@ Array of Independent Devices.
|
||||||
.B md
|
.B md
|
||||||
supports RAID levels 1 (mirroring) 4 (striped array with parity
|
supports RAID levels 1 (mirroring) 4 (striped array with parity
|
||||||
device), 5 (striped array with distributed parity information) and 6
|
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
|
some number of underlying devices fails while using one of these
|
||||||
levels, the array will continue to function; this number is one for
|
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
|
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
|
.PP
|
||||||
.B md
|
.B md
|
||||||
also supports a number of pseudo RAID (non-redundant) configurations
|
also supports a number of pseudo RAID (non-redundant) configurations
|
||||||
including RAID0 (striped array), LINEAR (catenated array) and
|
including RAID0 (striped array), LINEAR (catenated array),
|
||||||
MULTIPATH (a set of different interfaces to the same device).
|
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
|
.SS MD SUPER BLOCK
|
||||||
With the exception of Legacy Arrays described below, each device that
|
Each device in an array may have a
|
||||||
is incorporated into an MD array has a
|
.I superblock
|
||||||
.I super block
|
which records information about the structure and state of the array.
|
||||||
written towards the end of the device. This superblock records
|
This allows the array to be reliably re-assembled after a shutdown.
|
||||||
information about the structure and state of the array so that the
|
|
||||||
array can 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
|
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
|
(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).
|
device down to a multiple of 64K and then subtract 64K).
|
||||||
The available size of each device is the amount of space before the
|
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
|
super block, so between 64K and 128K is lost when a device in
|
||||||
incorporated into an MD array.
|
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:
|
The superblock contains, among other things:
|
||||||
.TP
|
.TP
|
||||||
|
@ -53,17 +71,34 @@ UUID
|
||||||
a 128 bit Universally Unique Identifier that identifies the array that
|
a 128 bit Universally Unique Identifier that identifies the array that
|
||||||
this device is part of.
|
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
|
Early versions of the
|
||||||
.B md
|
.B md
|
||||||
driver only supported Linear and Raid0 configurations and so
|
driver only supported Linear and Raid0 configurations and did not use
|
||||||
did not use an MD superblock (as there is no state that needs to be
|
a superblock (which is less critical with these configurations).
|
||||||
recorded). While it is strongly recommended that all newly created
|
While such arrays should be rebuilt with superblocks if possible,
|
||||||
arrays utilise a superblock to help ensure that they are assembled
|
|
||||||
properly, the
|
|
||||||
.B md
|
.B md
|
||||||
driver still supports legacy linear and raid0 md arrays that
|
continues to support them.
|
||||||
do not have a superblock.
|
.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
|
.SS LINEAR
|
||||||
|
|
||||||
|
|
22
mdadm.8
22
mdadm.8
|
@ -1,5 +1,5 @@
|
||||||
.\" -*- nroff -*-
|
.\" -*- nroff -*-
|
||||||
.TH MDADM 8 "" v1.11.0
|
.TH MDADM 8 "" v1.11.1
|
||||||
.SH NAME
|
.SH NAME
|
||||||
mdadm \- manage MD devices
|
mdadm \- manage MD devices
|
||||||
.I aka
|
.I aka
|
||||||
|
@ -92,7 +92,7 @@ information so as to assemble a faulty array.
|
||||||
|
|
||||||
.TP
|
.TP
|
||||||
.B Build
|
.B Build
|
||||||
Build a legacy array without per-device superblocks.
|
Build an array without per-device superblocks.
|
||||||
|
|
||||||
.TP
|
.TP
|
||||||
.B Create
|
.B Create
|
||||||
|
@ -234,6 +234,24 @@ in which case
|
||||||
says to get a list of array devices from
|
says to get a list of array devices from
|
||||||
.BR /proc/mdstat .
|
.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:
|
.SH For create or build:
|
||||||
|
|
||||||
.TP
|
.TP
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
Summary: mdadm is used for controlling Linux md devices (aka RAID arrays)
|
Summary: mdadm is used for controlling Linux md devices (aka RAID arrays)
|
||||||
Name: mdadm
|
Name: mdadm
|
||||||
Version: 1.11.0
|
Version: 1.11.1
|
||||||
Release: 1
|
Release: 1
|
||||||
Source: http://www.cse.unsw.edu.au/~neilb/source/mdadm/mdadm-%{version}.tgz
|
Source: http://www.cse.unsw.edu.au/~neilb/source/mdadm/mdadm-%{version}.tgz
|
||||||
URL: http://www.cse.unsw.edu.au/~neilb/source/mdadm/
|
URL: http://www.cse.unsw.edu.au/~neilb/source/mdadm/
|
||||||
|
|
|
@ -95,7 +95,7 @@ int main() {
|
||||||
if (ioctl(mdfd, GET_ARRAY_INFO, &array)>=0)
|
if (ioctl(mdfd, GET_ARRAY_INFO, &array)>=0)
|
||||||
/* already assembled, skip */
|
/* already assembled, skip */
|
||||||
continue;
|
continue;
|
||||||
rv |= Assemble(array_list->devname, mdfd,
|
rv |= Assemble(array_list->st, array_list->devname, mdfd,
|
||||||
array_list, configfile,
|
array_list, configfile,
|
||||||
NULL,
|
NULL,
|
||||||
readonly, runstop, NULL, verbose, force);
|
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))
|
if (write(fd, super, sizeof(*super)) != sizeof(*super))
|
||||||
return 4;
|
return 4;
|
||||||
|
|
||||||
|
fsync(fd);
|
||||||
return 0;
|
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 */
|
__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))
|
#define offsetof(t,f) ((int)&(((t*)0)->f))
|
||||||
|
#endif
|
||||||
static unsigned int calc_sb_1_csum(struct mdp_superblock_1 * sb)
|
static unsigned int calc_sb_1_csum(struct mdp_superblock_1 * sb)
|
||||||
{
|
{
|
||||||
unsigned int disk_csum, csum;
|
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 Level : %s\n", c?c:"-unknown-");
|
||||||
printf(" Raid Devices : %d\n", __le32_to_cpu(sb->raid_disks));
|
printf(" Raid Devices : %d\n", __le32_to_cpu(sb->raid_disks));
|
||||||
printf("\n");
|
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)
|
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)
|
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 : ");
|
printf(" Device UUID : ");
|
||||||
for (i=0; i<16; i++) {
|
for (i=0; i<16; i++) {
|
||||||
printf("%02x", sb->set_uuid[i]);
|
printf("%02x", sb->set_uuid[i]);
|
||||||
|
@ -159,7 +161,7 @@ static void examine_super1(void *sbv)
|
||||||
else
|
else
|
||||||
printf(" Checksum : %x - expected %x\n", __le32_to_cpu(sb->sb_csum),
|
printf(" Checksum : %x - expected %x\n", __le32_to_cpu(sb->sb_csum),
|
||||||
__le32_to_cpu(calc_sb_1_csum(sb)));
|
__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");
|
printf("\n");
|
||||||
if (__le32_to_cpu(sb->level) == 5) {
|
if (__le32_to_cpu(sb->level) == 5) {
|
||||||
c = map_num(r5layout, __le32_to_cpu(sb->layout));
|
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]);
|
printf("%02x", sb->set_uuid[i]);
|
||||||
if ((i&3)==0 && i != 0) printf(":");
|
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)
|
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)
|
if (write(fd, sb, sbsize) != sbsize)
|
||||||
return 4;
|
return 4;
|
||||||
|
|
||||||
|
fsync(fd);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -575,15 +578,33 @@ static int load_super1(struct supertype *st, int fd, void **sbp, char *devname)
|
||||||
|
|
||||||
|
|
||||||
if (st->ss == NULL) {
|
if (st->ss == NULL) {
|
||||||
/* guess... */
|
int bestvers = -1;
|
||||||
|
__u64 bestctime = 0;
|
||||||
|
/* guess... choose latest ctime */
|
||||||
st->ss = &super1;
|
st->ss = &super1;
|
||||||
for (st->minor_version = 0; st->minor_version <= 2 ; st->minor_version++) {
|
for (st->minor_version = 0; st->minor_version <= 2 ; st->minor_version++) {
|
||||||
switch(load_super1(st, fd, sbp, devname)) {
|
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 1: st->ss = NULL; return 1; /*bad device */
|
||||||
case 2: break; /* bad, try next */
|
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;
|
st->ss = NULL;
|
||||||
return 2;
|
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++)
|
for(i=0; i<bytes/4; i++)
|
||||||
newcsum+= superc[i];
|
newcsum+= superc[i];
|
||||||
csum = (newcsum& 0xffffffff) + (newcsum>>32);
|
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;
|
return csum;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -544,6 +553,8 @@ struct supertype *guess_super(int fd)
|
||||||
*/
|
*/
|
||||||
struct superswitch *ss;
|
struct superswitch *ss;
|
||||||
struct supertype *st;
|
struct supertype *st;
|
||||||
|
unsigned long besttime = 0;
|
||||||
|
int bestsuper = -1;
|
||||||
|
|
||||||
void *sbp = NULL;
|
void *sbp = NULL;
|
||||||
int i;
|
int i;
|
||||||
|
@ -554,10 +565,26 @@ struct supertype *guess_super(int fd)
|
||||||
int rv;
|
int rv;
|
||||||
ss = superlist[i];
|
ss = superlist[i];
|
||||||
rv = ss->load_super(st, fd, &sbp, NULL);
|
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) {
|
if (rv == 0) {
|
||||||
free(sbp);
|
free(sbp);
|
||||||
return st;
|
return st;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
free(st);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue