mdadm-1.7.0
This commit is contained in:
parent
dd0781e505
commit
e5329c3747
|
@ -0,0 +1,46 @@
|
|||
Subject: ANNOUNCE: mdadm 1.7.0 - A tool for managing Soft RAID under Linux
|
||||
|
||||
|
||||
I am pleased to announce the availability of
|
||||
mdadm version 1.7.0
|
||||
It is available at
|
||||
http://www.cse.unsw.edu.au/~neilb/source/mdadm/
|
||||
and
|
||||
http://www.{countrycode}.kernel.org/pub/linux/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.7.0 adds:
|
||||
- Support "--grow --add" to add a device to a linear array, if the
|
||||
kernel supports it. Not documented yet.
|
||||
- Restore support for uclibc which was broken recently.
|
||||
- Several improvements to the output of --detail, including
|
||||
reporting "resyncing" or "recovering" in the state.
|
||||
- Close filedescriptor at end of --detail (exit would have closed it
|
||||
anyway, so this isn't abig deal).
|
||||
- Report "Sync checkpoint" in --examine output if appropriate.
|
||||
- Add --update=resync for --assemble mode to for a resync when the
|
||||
array is assembled.
|
||||
- Add support for "raid10", which is under development in 2.6.
|
||||
Not documented yet.
|
||||
- --monitor now reads spare-group and spares info from config file
|
||||
even when names of arrays to scan are given on the command line
|
||||
|
||||
It is expected that the next full release of mdadm will be 2.0.0
|
||||
and it will have substantially re-written handling for superblocks and
|
||||
array creation. In particular, it will be able to work with the new
|
||||
superblock format (version 1) supported by 2.6.
|
||||
Prior to that, some point releases (1.7.1, 1.7.2 ...) may be released
|
||||
so that the changes can be tested by interrested parties.
|
||||
|
||||
Development of mdadm is sponsored by CSE@UNSW:
|
||||
The School of Computer Science and Engineering
|
||||
at
|
||||
The University of New South Wales
|
||||
|
||||
NeilBrown 11 August 2004
|
||||
|
|
@ -320,6 +320,11 @@ int Assemble(char *mddev, int mdfd,
|
|||
} else if (i >= super.raid_disks && super.disks[i].number == 0)
|
||||
super.disks[i].state = 0;
|
||||
}
|
||||
if (strcmp(update, "resync") == 0) {
|
||||
/* make sure resync happens */
|
||||
super.state &= ~(1<<MD_SB_CLEAN);
|
||||
super.recovery_cp = 0;
|
||||
}
|
||||
super.sb_csum = calc_sb_csum(&super);
|
||||
dfd = open(devname, O_RDWR, 0);
|
||||
if (dfd < 0)
|
||||
|
|
16
ChangeLog
16
ChangeLog
|
@ -1,3 +1,19 @@
|
|||
Changes Prior to this release
|
||||
- Support "--grow --add" to add a device to a linear array, if the
|
||||
kernel supports it. Not documented yet.
|
||||
- Restore support for uclibc which was broken recently.
|
||||
- Several improvements to the output of --detail, including
|
||||
reporting "resyncing" or "recovering" in the state.
|
||||
- Close filedescriptor at end of --detail (exit would have closed it
|
||||
anyway, so this isn't abig deal).
|
||||
- Report "Sync checkpoint" in --examine output if appropriate.
|
||||
- Add --update=resync for --assemble mode to for a resync when the
|
||||
array is assembled.
|
||||
- Add support for "raid10", which is under development in 2.6.
|
||||
Not documented yet.
|
||||
- --monitor now reads spare-group and spares info from config file
|
||||
even when names of arrays to scan are given on the command line
|
||||
|
||||
Changes Prior to 1.6.0 release
|
||||
- Device name given in -Eb is determined by examining /dev rather
|
||||
than assuming /dev/md%d
|
||||
|
|
15
Create.c
15
Create.c
|
@ -117,6 +117,12 @@ int Create(char *mddev, int mdfd,
|
|||
default: /* no layout */
|
||||
layout = 0;
|
||||
break;
|
||||
case 10:
|
||||
layout = 0x102; /* near=2, far=1 */
|
||||
if (verbose)
|
||||
fprintf(stderr,
|
||||
Name ": layout defaults to n1\n");
|
||||
break;
|
||||
case 5:
|
||||
case 6:
|
||||
layout = map_name(r5layout, "default");
|
||||
|
@ -126,9 +132,18 @@ int Create(char *mddev, int mdfd,
|
|||
break;
|
||||
}
|
||||
|
||||
if (level == 10)
|
||||
/* check layout fits in array*/
|
||||
if ((layout&255) * ((layout>>8)&255) > raiddisks) {
|
||||
fprintf(stderr, Name ": that layout requires at least %d devices\n",
|
||||
(layout&255) * ((layout>>8)&255));
|
||||
return 1;
|
||||
}
|
||||
|
||||
switch(level) {
|
||||
case 4:
|
||||
case 5:
|
||||
case 10:
|
||||
case 6:
|
||||
case 0:
|
||||
case -1: /* linear */
|
||||
|
|
113
Detail.c
113
Detail.c
|
@ -47,6 +47,9 @@ int Detail(char *dev, int brief, int test)
|
|||
char *devices = NULL;
|
||||
int spares = 0;
|
||||
struct stat stb;
|
||||
int is_26 = get_linux_version() >= 2006000;
|
||||
int is_rebuilding = 0;
|
||||
int failed = 0;
|
||||
|
||||
mdp_super_t super;
|
||||
int have_super = 0;
|
||||
|
@ -83,6 +86,34 @@ int Detail(char *dev, int brief, int test)
|
|||
if (fstat(fd, &stb) != 0 && !S_ISBLK(stb.st_mode))
|
||||
stb.st_rdev = 0;
|
||||
rv = 0;
|
||||
|
||||
/* try to load a superblock */
|
||||
for (d= 0; d<MD_SB_DISKS; d++) {
|
||||
mdu_disk_info_t disk;
|
||||
char *dv;
|
||||
disk.number = d;
|
||||
if (ioctl(fd, GET_DISK_INFO, &disk) < 0)
|
||||
continue;
|
||||
if (d >= array.raid_disks &&
|
||||
disk.major == 0 &&
|
||||
disk.minor == 0)
|
||||
continue;
|
||||
if ((dv=map_dev(disk.major, disk.minor))) {
|
||||
if (!have_super && (disk.state & (1<<MD_DISK_ACTIVE))) {
|
||||
/* try to read the superblock from this device
|
||||
* to get more info
|
||||
*/
|
||||
int fd2 = open(dv, O_RDONLY);
|
||||
if (fd2 >=0 &&
|
||||
load_super(fd2, &super) ==0 &&
|
||||
(unsigned long)super.ctime == (unsigned long)array.ctime &&
|
||||
(unsigned int)super.level == (unsigned int)array.level)
|
||||
have_super = 1;
|
||||
if (fd2 >= 0) close(fd2);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Ok, we have some info to print... */
|
||||
c = map_num(pers, array.level);
|
||||
if (brief)
|
||||
|
@ -132,7 +163,8 @@ int Detail(char *dev, int brief, int test)
|
|||
printf(" State : %s%s%s\n",
|
||||
(array.state&(1<<MD_SB_CLEAN))?"clean":"dirty",
|
||||
array.active_disks < array.raid_disks? ", degraded":"",
|
||||
(e && e->percent >= 0) ? ", recovering": "");
|
||||
(!e || e->percent < 0) ? "" :
|
||||
(e->resync) ? ", resyncing": ", recovering");
|
||||
printf(" Active Devices : %d\n", array.active_disks);
|
||||
printf("Working Devices : %d\n", array.working_disks);
|
||||
printf(" Failed Devices : %d\n", array.failed_disks);
|
||||
|
@ -142,24 +174,40 @@ int Detail(char *dev, int brief, int test)
|
|||
c = map_num(r5layout, array.layout);
|
||||
printf(" Layout : %s\n", c?c:"-unknown-");
|
||||
}
|
||||
if (array.level == 10) {
|
||||
printf(" Layout : near=%d, far=%d\n",
|
||||
array.layout&255, (array.layout>>8)&255);
|
||||
}
|
||||
switch (array.level) {
|
||||
case 0:
|
||||
case 4:
|
||||
case 5:
|
||||
printf(" Chunk Size : %dK\n", array.chunk_size/1024);
|
||||
case 10:
|
||||
case 6:
|
||||
printf(" Chunk Size : %dK\n\n", array.chunk_size/1024);
|
||||
break;
|
||||
case -1:
|
||||
printf(" Rounding : %dK\n", array.chunk_size/1024);
|
||||
printf(" Rounding : %dK\n\n", array.chunk_size/1024);
|
||||
break;
|
||||
default: break;
|
||||
}
|
||||
|
||||
printf("\n");
|
||||
|
||||
if (e && e->percent >= 0)
|
||||
if (e && e->percent >= 0) {
|
||||
printf(" Rebuild Status : %d%% complete\n\n", e->percent);
|
||||
is_rebuilding = 1;
|
||||
}
|
||||
free_mdstat(ms);
|
||||
|
||||
if (have_super) {
|
||||
printf(" UUID : ");
|
||||
if (super.minor_version >= 90)
|
||||
printf("%08x:%08x:%08x:%08x", super.set_uuid0, super.set_uuid1,
|
||||
super.set_uuid2, super.set_uuid3);
|
||||
else
|
||||
printf("%08x", super.set_uuid0);
|
||||
printf("\n Events : %d.%d\n\n", super.events_hi, super.events_lo);
|
||||
}
|
||||
|
||||
printf(" Number Major Minor RaidDevice State\n");
|
||||
}
|
||||
for (d= 0; d<MD_SB_DISKS; d++) {
|
||||
|
@ -177,14 +225,40 @@ int Detail(char *dev, int brief, int test)
|
|||
disk.minor == 0)
|
||||
continue;
|
||||
if (!brief) {
|
||||
printf(" %5d %5d %5d %5d ",
|
||||
disk.number, disk.major, disk.minor, disk.raid_disk);
|
||||
if (disk.state & (1<<MD_DISK_FAULTY)) printf(" faulty");
|
||||
if (disk.number == array.raid_disks) printf("\n");
|
||||
if (disk.raid_disk < 0)
|
||||
printf(" %5d %5d %5d - ",
|
||||
disk.number, disk.major, disk.minor);
|
||||
else
|
||||
printf(" %5d %5d %5d %5d ",
|
||||
disk.number, disk.major, disk.minor, disk.raid_disk);
|
||||
if (disk.state & (1<<MD_DISK_FAULTY)) {
|
||||
printf(" faulty");
|
||||
if (disk.raid_disk < array.raid_disks &&
|
||||
disk.raid_disk >= 0)
|
||||
failed++;
|
||||
}
|
||||
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"); spares++; }
|
||||
if (disk.state == 0) printf(" spare");
|
||||
if (disk.state == 0) {
|
||||
if (is_26) {
|
||||
if (disk.raid_disk < array.raid_disks && disk.raid_disk >= 0)
|
||||
printf(" rebuilding");
|
||||
} else if (is_rebuilding && failed) {
|
||||
/* Taking a bit of a risk here, we remove the
|
||||
* device from the array, and then put it back.
|
||||
* If this fails, we are rebuilding
|
||||
*/
|
||||
int err = ioctl(fd, HOT_REMOVE_DISK, MKDEV(disk.major, disk.minor));
|
||||
if (err == 0) ioctl(fd, HOT_ADD_DISK, MKDEV(disk.major, disk.minor));
|
||||
if (err && errno == EBUSY)
|
||||
printf(" rebuilding");
|
||||
}
|
||||
}
|
||||
}
|
||||
if (disk.state == 0) spares++;
|
||||
if (test && d < array.raid_disks && disk.state & (1<<MD_DISK_FAULTY)) {
|
||||
if ((rv & 1) && (array.level ==4 || array.level == 5))
|
||||
rv |= 2;
|
||||
|
@ -200,34 +274,21 @@ int Detail(char *dev, int brief, int test)
|
|||
devices = strdup(dv);
|
||||
} else
|
||||
printf(" %s", dv);
|
||||
if (!have_super && (disk.state & (1<<MD_DISK_ACTIVE))) {
|
||||
/* try to read the superblock from this device
|
||||
* to get more info
|
||||
*/
|
||||
int fd = open(dv, O_RDONLY);
|
||||
if (fd >=0 &&
|
||||
load_super(fd, &super) ==0 &&
|
||||
(unsigned long)super.ctime == (unsigned long)array.ctime &&
|
||||
(unsigned int)super.level == (unsigned int)array.level)
|
||||
have_super = 1;
|
||||
}
|
||||
}
|
||||
if (!brief) printf("\n");
|
||||
}
|
||||
if (spares && brief) printf(" spares=%d", spares);
|
||||
if (have_super) {
|
||||
if (brief) printf(" UUID=");
|
||||
else printf(" UUID : ");
|
||||
if (have_super && brief) {
|
||||
printf(" UUID=");
|
||||
if (super.minor_version >= 90)
|
||||
printf("%08x:%08x:%08x:%08x", super.set_uuid0, super.set_uuid1,
|
||||
super.set_uuid2, super.set_uuid3);
|
||||
else
|
||||
printf("%08x", super.set_uuid0);
|
||||
if (!brief)
|
||||
printf("\n Events : %d.%d\n", super.events_hi, super.events_lo);
|
||||
}
|
||||
if (brief && devices) printf("\n devices=%s", devices);
|
||||
if (brief) printf("\n");
|
||||
if (test && (rv&2)) rv &= ~1;
|
||||
close(fd);
|
||||
return rv;
|
||||
}
|
||||
|
|
10
Examine.c
10
Examine.c
|
@ -174,11 +174,20 @@ int Examine(mddev_dev_t devlist, int brief, int scan, int SparcAdjust)
|
|||
printf (" --- adjusting superblock for 2.2/sparc compatability ---\n");
|
||||
}
|
||||
printf(" Events : %d.%d\n", super.events_hi, super.events_lo);
|
||||
if (super.events_hi == super.cp_events_hi &&
|
||||
super.events_lo == super.cp_events_lo &&
|
||||
super.recovery_cp > 0 &&
|
||||
(super.state & (1<<MD_SB_CLEAN)) == 0 )
|
||||
printf("Sync checkpoint : %d KB (%d%%)\n", super.recovery_cp/2, super.recovery_cp/(super.size/100*2));
|
||||
printf("\n");
|
||||
if (super.level == 5) {
|
||||
c = map_num(r5layout, super.layout);
|
||||
printf(" Layout : %s\n", c?c:"-unknown-");
|
||||
}
|
||||
if (super.level == 10)
|
||||
printf(" Layout : near=%d, far=%d\n",
|
||||
super.layout&255, (super.layout>>8) & 255);
|
||||
|
||||
switch(super.level) {
|
||||
case 0:
|
||||
case 4:
|
||||
|
@ -209,6 +218,7 @@ int Examine(mddev_dev_t devlist, int brief, int scan, int SparcAdjust)
|
|||
if ((dv=map_dev(dp->major, dp->minor)))
|
||||
printf(" %s", dv);
|
||||
printf("\n");
|
||||
if (d == -1) printf("\n");
|
||||
}
|
||||
}
|
||||
if (SparcAdjust == 2) {
|
||||
|
|
|
@ -0,0 +1,192 @@
|
|||
/*
|
||||
* mdadm - manage Linux "md" devices aka RAID arrays.
|
||||
*
|
||||
* Copyright (C) 2001-2004 Neil Brown <neilb@cse.unsw.edu.au>
|
||||
*
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*
|
||||
* Author: Neil Brown
|
||||
* Email: <neilb@cse.unsw.edu.au>
|
||||
* Paper: Neil Brown
|
||||
* School of Computer Science and Engineering
|
||||
* The University of New South Wales
|
||||
* Sydney, 2052
|
||||
* Australia
|
||||
*/
|
||||
#include "mdadm.h"
|
||||
#include "dlink.h"
|
||||
|
||||
#if ! defined(__BIG_ENDIAN) && ! defined(__LITTLE_ENDIAN)
|
||||
#error no endian defined
|
||||
#endif
|
||||
#include "md_u.h"
|
||||
#include "md_p.h"
|
||||
|
||||
int Grow_Add_device(char *devname, int fd, char *newdev)
|
||||
{
|
||||
/* Add a device to an active array.
|
||||
* Currently, just extend a linear array.
|
||||
* This requires writing a new superblock on the
|
||||
* new device, calling the kernel to add the device,
|
||||
* and if that succeeds, update the superblock on
|
||||
* all other devices.
|
||||
* This means that we need to *find* all other devices.
|
||||
*/
|
||||
mdu_array_info_t array;
|
||||
mdu_disk_info_t disk;
|
||||
mdp_super_t super;
|
||||
struct stat stb;
|
||||
int nfd, fd2;
|
||||
int d, nd;
|
||||
|
||||
|
||||
if (ioctl(fd, GET_ARRAY_INFO, &array) < 0) {
|
||||
fprintf(stderr, Name ": cannot get array info for %s\n", devname);
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (array.level != -1) {
|
||||
fprintf(stderr, Name ": can only add devices to linear arrays\n");
|
||||
return 1;
|
||||
}
|
||||
|
||||
nfd = open(newdev, O_RDWR|O_EXCL);
|
||||
if (nfd < 0) {
|
||||
fprintf(stderr, Name ": cannot open %s\n", newdev);
|
||||
return 1;
|
||||
}
|
||||
fstat(nfd, &stb);
|
||||
if ((stb.st_mode & S_IFMT) != S_IFBLK) {
|
||||
fprintf(stderr, Name ": %s is not a block device!\n", newdev);
|
||||
close(nfd);
|
||||
return 1;
|
||||
}
|
||||
/* now check out all the devices and make sure we can read the superblock */
|
||||
for (d=0 ; d < array.raid_disks ; d++) {
|
||||
mdu_disk_info_t disk;
|
||||
char *dv;
|
||||
|
||||
disk.number = d;
|
||||
if (ioctl(fd, GET_DISK_INFO, &disk) < 0) {
|
||||
fprintf(stderr, Name ": cannot get device detail for device %d\n",
|
||||
d);
|
||||
return 1;
|
||||
}
|
||||
dv = map_dev(disk.major, disk.minor);
|
||||
if (!dv) {
|
||||
fprintf(stderr, Name ": cannot find device file for device %d\n",
|
||||
d);
|
||||
return 1;
|
||||
}
|
||||
fd2 = open(dv, O_RDWR);
|
||||
if (!fd2) {
|
||||
fprintf(stderr, Name ": cannot open device file %s\n", dv);
|
||||
return 1;
|
||||
}
|
||||
if (load_super(fd2, &super)) {
|
||||
fprintf(stderr, Name ": cannot find super block on %s\n", dv);
|
||||
close(fd2);
|
||||
return 1;
|
||||
}
|
||||
close(fd2);
|
||||
}
|
||||
/* Ok, looks good. Lets update the superblock and write it out to
|
||||
* newdev.
|
||||
*/
|
||||
|
||||
memset(&super.disks[d], 0, sizeof(super.disks[d]));
|
||||
super.disks[d].number = d;
|
||||
super.disks[d].major = MAJOR(stb.st_rdev);
|
||||
super.disks[d].minor = MINOR(stb.st_rdev);
|
||||
super.disks[d].raid_disk = d;
|
||||
super.disks[d].state = (1 << MD_DISK_SYNC) | (1 << MD_DISK_ACTIVE);
|
||||
|
||||
super.this_disk = super.disks[d];
|
||||
super.sb_csum = calc_sb_csum(&super);
|
||||
if (store_super(nfd, &super)) {
|
||||
fprintf(stderr, Name ": Cannot store new superblock on %s\n", newdev);
|
||||
close(nfd);
|
||||
return 1;
|
||||
}
|
||||
disk.number = d;
|
||||
disk.major = MAJOR(stb.st_rdev);
|
||||
disk.minor = MINOR(stb.st_rdev);
|
||||
disk.raid_disk = d;
|
||||
disk.state = (1 << MD_DISK_SYNC) | (1 << MD_DISK_ACTIVE);
|
||||
close(nfd);
|
||||
if (ioctl(fd, ADD_NEW_DISK, &disk) != 0) {
|
||||
fprintf(stderr, Name ": Cannot add new disk to this array\n");
|
||||
return 1;
|
||||
}
|
||||
/* Well, that seems to have worked.
|
||||
* Now go through and update all superblocks
|
||||
*/
|
||||
|
||||
if (ioctl(fd, GET_ARRAY_INFO, &array) < 0) {
|
||||
fprintf(stderr, Name ": cannot get array info for %s\n", devname);
|
||||
return 1;
|
||||
}
|
||||
|
||||
nd = d;
|
||||
for (d=0 ; d < array.raid_disks ; d++) {
|
||||
mdu_disk_info_t disk;
|
||||
char *dv;
|
||||
|
||||
disk.number = d;
|
||||
if (ioctl(fd, GET_DISK_INFO, &disk) < 0) {
|
||||
fprintf(stderr, Name ": cannot get device detail for device %d\n",
|
||||
d);
|
||||
return 1;
|
||||
}
|
||||
dv = map_dev(disk.major, disk.minor);
|
||||
if (!dv) {
|
||||
fprintf(stderr, Name ": cannot find device file for device %d\n",
|
||||
d);
|
||||
return 1;
|
||||
}
|
||||
fd2 = open(dv, O_RDWR);
|
||||
if (fd2 < 0) {
|
||||
fprintf(stderr, Name ": cannot open device file %s\n", dv);
|
||||
return 1;
|
||||
}
|
||||
if (load_super(fd2, &super)) {
|
||||
fprintf(stderr, Name ": cannot find super block on %s\n", dv);
|
||||
close(fd);
|
||||
return 1;
|
||||
}
|
||||
super.raid_disks = nd+1;
|
||||
super.nr_disks = nd+1;
|
||||
super.active_disks = nd+1;
|
||||
super.working_disks = nd+1;
|
||||
memset(&super.disks[nd], 0, sizeof(super.disks[nd]));
|
||||
super.disks[nd].number = nd;
|
||||
super.disks[nd].major = MAJOR(stb.st_rdev);
|
||||
super.disks[nd].minor = MINOR(stb.st_rdev);
|
||||
super.disks[nd].raid_disk = nd;
|
||||
super.disks[nd].state = (1 << MD_DISK_SYNC) | (1 << MD_DISK_ACTIVE);
|
||||
|
||||
super.this_disk = super.disks[d];
|
||||
super.sb_csum = calc_sb_csum(&super);
|
||||
if (store_super(fd2, &super)) {
|
||||
fprintf(stderr, Name ": Cannot store new superblock on %s\n", dv);
|
||||
close(fd2);
|
||||
return 1;
|
||||
}
|
||||
close(fd2);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
6
Makefile
6
Makefile
|
@ -30,7 +30,7 @@
|
|||
# define "CXFLAGS" to give extra flags to CC.
|
||||
# e.g. make CXFLAGS=-O to optimise
|
||||
TCC = tcc
|
||||
UCLIBC_GCC = i386-uclibc-gcc
|
||||
UCLIBC_GCC = $(shell for nm in i386-uclibc-linux-gcc i386-uclibc-gcc; do which $$nm > /dev/null && { echo $$nm ; exit; } ; done; echo false No uclibc found )
|
||||
|
||||
CC = gcc
|
||||
CXFLAGS = -ggdb
|
||||
|
@ -55,8 +55,8 @@ MAN8DIR = $(MANDIR)/man8
|
|||
|
||||
KLIBC=/home/src/klibc/klibc-0.77
|
||||
|
||||
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
|
||||
OBJS = mdadm.o config.o mdstat.o ReadMe.o util.o Manage.o Assemble.o Build.o Create.o Detail.o Examine.o Grow.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 Grow.c Monitor.c dlink.c Kill.c Query.c
|
||||
|
||||
all : mdadm mdadm.man md.man mdadm.conf.man
|
||||
|
||||
|
|
|
@ -163,6 +163,7 @@ int Monitor(mddev_dev_t devlist,
|
|||
} else {
|
||||
mddev_dev_t dv;
|
||||
for (dv=devlist ; dv; dv=dv->next) {
|
||||
mddev_ident_t mdlist = conf_get_ident(config, dv->devname);
|
||||
struct state *st = malloc(sizeof *st);
|
||||
if (st == NULL)
|
||||
continue;
|
||||
|
@ -174,6 +175,11 @@ int Monitor(mddev_dev_t devlist,
|
|||
st->percent = -2;
|
||||
st->expected_spares = -1;
|
||||
st->spare_group = NULL;
|
||||
if (mdlist) {
|
||||
st->expected_spares = mdlist->spare_disks;
|
||||
if (mdlist->spare_group)
|
||||
st->spare_group = strdup(mdlist->spare_group);
|
||||
}
|
||||
statelist = st;
|
||||
}
|
||||
}
|
||||
|
@ -216,7 +222,8 @@ int Monitor(mddev_dev_t devlist,
|
|||
close(fd);
|
||||
continue;
|
||||
}
|
||||
if (array.level != 1 && array.level != 5 && array.level != -4) {
|
||||
if (array.level != 1 && array.level != 5 && array.level != -4 &&
|
||||
array.level != 6 && array.level != 10) {
|
||||
if (!st->err)
|
||||
alert("DeviceDisappeared", dev, "Wrong-Level",
|
||||
mailaddr, alert_cmd);
|
||||
|
|
8
ReadMe.c
8
ReadMe.c
|
@ -29,7 +29,7 @@
|
|||
|
||||
#include "mdadm.h"
|
||||
|
||||
char Version[] = Name " - v1.6.0 - 4 June 2004\n";
|
||||
char Version[] = Name " - v1.7.0 - 11 August 2004\n";
|
||||
/*
|
||||
* File: ReadMe.c
|
||||
*
|
||||
|
@ -216,7 +216,7 @@ char OptionHelp[] =
|
|||
" --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/6 - optional\n"
|
||||
" --size= -z : Size (in K) of each drive in RAID1/4/5/6/10 - optional\n"
|
||||
" --force -f : Honour devices as listed on command line. Don't\n"
|
||||
" : insert a missing drive for RAID5.\n"
|
||||
" --auto(=p) -a : Automatically allocate new (partitioned) md array if needed.\n"
|
||||
|
@ -284,7 +284,7 @@ char Help_create[] =
|
|||
" --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/6 - optional\n"
|
||||
" --size= -z : Size (in K) of each drive in RAID1/4/5/6/10 - optional\n"
|
||||
" --force -f : Honour devices as listed on command line. Don't\n"
|
||||
" : insert a missing drive for RAID5.\n"
|
||||
" --run -R : insist of running the array even if not all\n"
|
||||
|
@ -508,6 +508,8 @@ mapping_t pers[] = {
|
|||
{ "mp", -4},
|
||||
{ "raid6", 6},
|
||||
{ "6", 6},
|
||||
{ "raid10", 10},
|
||||
{ "10", 10},
|
||||
{ NULL, 0}
|
||||
};
|
||||
|
||||
|
|
2
config.c
2
config.c
|
@ -364,7 +364,7 @@ void arrayline(char *line)
|
|||
}
|
||||
if (mis.devname == NULL)
|
||||
fprintf(stderr, Name ": ARRAY line with no device\n");
|
||||
else if (mis.uuid_set == 0 && mis.devices == NULL && mis.super_minor < 0)
|
||||
else if (mis.uuid_set == 0 && mis.devices == NULL && mis.super_minor == UnSet)
|
||||
fprintf(stderr, Name ": ARRAY line %s has no identity information.\n", mis.devname);
|
||||
else {
|
||||
mi = malloc(sizeof(*mi));
|
||||
|
|
|
@ -0,0 +1,43 @@
|
|||
|
||||
ANNOUNCE-1.0.0
|
||||
ANNOUNCE-1.1.0
|
||||
ANNOUNCE-1.2.0
|
||||
ANNOUNCE-1.3.0
|
||||
ANNOUNCE-1.4.0
|
||||
ANNOUNCE-1.5.0
|
||||
ANNOUNCE-1.6.0
|
||||
ANNOUNCE-1.7.0
|
||||
Assemble.c
|
||||
Build.c
|
||||
COPYING
|
||||
ChangeLog
|
||||
Create.c
|
||||
Detail.c
|
||||
Examine.c
|
||||
Grow.c
|
||||
INSTALL
|
||||
Kill.c
|
||||
Makefile
|
||||
Manage.c
|
||||
Monitor.c
|
||||
Query.c
|
||||
ReadMe.c
|
||||
TODO
|
||||
config.c
|
||||
dlink.c
|
||||
dlink.h
|
||||
inventory
|
||||
makedist
|
||||
md.4
|
||||
md_p.h
|
||||
md_u.h
|
||||
mdadm.8
|
||||
mdadm.c
|
||||
mdadm.conf-example
|
||||
mdadm.conf.5
|
||||
mdadm.h
|
||||
mdadm.spec
|
||||
mdassemble.c
|
||||
mdstat.c
|
||||
raid5extend.c
|
||||
util.c
|
12
makedist
12
makedist
|
@ -21,9 +21,13 @@ grep "^Version: *$version$" mdadm.spec > /dev/null 2>&1 ||
|
|||
if [ -f ANNOUNCE-$version ]
|
||||
then :
|
||||
else
|
||||
echo ANNONCE-$version does not exist
|
||||
echo ANNOUNCE-$version does not exist
|
||||
exit 1
|
||||
fi
|
||||
if grep "^ANNOUNCE-$version\$" inventory
|
||||
then :
|
||||
else { cat inventory ; echo ANNOUNCE-$version ; } | sort -o inventory
|
||||
fi
|
||||
|
||||
echo version = $version
|
||||
base=mdadm-$version.tgz
|
||||
|
@ -38,6 +42,12 @@ then
|
|||
( 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
|
||||
if tar tzf $target/$base | sed 's,[^/]*/,,' | sort | diff -u inventory -
|
||||
then : correct files found
|
||||
else echo "Extra files, or invertory is out-of-date"
|
||||
rm $target/$base
|
||||
exit 1
|
||||
fi
|
||||
|
||||
rpm -ta $target/$base
|
||||
find /home/neilb/src/RPM -name "*mdadm-$version-*" \
|
||||
|
|
7
md_p.h
7
md_p.h
|
@ -131,11 +131,16 @@ typedef struct mdp_superblock_s {
|
|||
#if __BYTE_ORDER == __BIG_ENDIAN
|
||||
__u32 events_hi; /* 7 high-order of superblock update count */
|
||||
__u32 events_lo; /* 8 low-order of superblock update count */
|
||||
__u32 cp_events_hi; /* 9 high-order of checkpoint update count */
|
||||
__u32 cp_events_lo; /* 10 low-order of checkpoint update count */
|
||||
#else
|
||||
__u32 events_lo; /* 7 low-order of superblock update count */
|
||||
__u32 events_hi; /* 8 high-order of superblock update count */
|
||||
__u32 cp_events_lo; /* 9 low-order of checkpoint update count */
|
||||
__u32 cp_events_hi; /* 10 high-order of checkpoint update count */
|
||||
#endif
|
||||
__u32 gstate_sreserved[MD_SB_GENERIC_STATE_WORDS - 9];
|
||||
__u32 recovery_cp; /* 11 recovery checkpoint sector count */
|
||||
__u32 gstate_sreserved[MD_SB_GENERIC_STATE_WORDS - 12];
|
||||
|
||||
/*
|
||||
* Personality information
|
||||
|
|
12
mdadm.8
12
mdadm.8
|
@ -1,5 +1,5 @@
|
|||
.\" -*- nroff -*-
|
||||
.TH MDADM 8 "" v1.6.0
|
||||
.TH MDADM 8 "" v1.7.0
|
||||
.SH NAME
|
||||
mdadm \- manage MD devices
|
||||
.I aka
|
||||
|
@ -407,6 +407,7 @@ Update the superblock on each device while assembling the array. The
|
|||
argument given to this flag can be one of
|
||||
.BR sparc2.2 ,
|
||||
.BR summaries ,
|
||||
.BR resync ,
|
||||
or
|
||||
.BR super-minor .
|
||||
|
||||
|
@ -428,6 +429,15 @@ field on each superblock to match the minor number of the array being
|
|||
assembled. This is not needed on 2.6 and later kernels as they make
|
||||
this adjustment automatically.
|
||||
|
||||
The
|
||||
.B resync
|
||||
option will cause the array to be marked
|
||||
.I dirty
|
||||
meaning that any redundancy in the array (e.g. parity for raid5,
|
||||
copies for raid1) may be incorrect. This will cause the raid system
|
||||
to perform a "resync" pass to make sure that all redundant information
|
||||
is correct.
|
||||
|
||||
The
|
||||
.B summaries
|
||||
option will correct the summaries in the superblock. That is the
|
||||
|
|
53
mdadm.c
53
mdadm.c
|
@ -235,6 +235,8 @@ int main(int argc, char *argv[])
|
|||
int daemonise = 0;
|
||||
int oneshot = 0;
|
||||
|
||||
int copies;
|
||||
|
||||
int mdfd = -1;
|
||||
|
||||
ident.uuid_set=0;
|
||||
|
@ -361,6 +363,10 @@ int main(int argc, char *argv[])
|
|||
fprintf(stderr, Name ": Must give one of -a/-r/-f for subsequent devices at %s\n", optarg);
|
||||
exit(2);
|
||||
}
|
||||
if (devs_found > 0 && mode == 'G' && !devmode) {
|
||||
fprintf(stderr, Name ": Must give one of -a for devices do add: %s\n", optarg);
|
||||
exit(2);
|
||||
}
|
||||
dv = malloc(sizeof(*dv));
|
||||
if (dv == NULL) {
|
||||
fprintf(stderr, Name ": malloc failed\n");
|
||||
|
@ -441,7 +447,7 @@ int main(int argc, char *argv[])
|
|||
continue;
|
||||
|
||||
case O(CREATE,'p'): /* raid5 layout */
|
||||
if (layout >= 0) {
|
||||
if (layout != UnSet) {
|
||||
fprintf(stderr,Name ": layout may only be sent once. "
|
||||
"Second value was %s\n", optarg);
|
||||
exit(2);
|
||||
|
@ -464,6 +470,21 @@ int main(int argc, char *argv[])
|
|||
exit(2);
|
||||
}
|
||||
break;
|
||||
|
||||
case 10:
|
||||
/* 'f' or 'n' followed by a number <= raid_disks */
|
||||
if ((optarg[0] != 'n' && optarg[0] != 'f') ||
|
||||
(copies = strtoul(optarg+1, &cp, 10)) < 1 ||
|
||||
copies > 200 ||
|
||||
*cp) {
|
||||
fprintf(stderr, Name ": layout for raid10 must be 'nNN' or 'fNN' where NN is a number, not %s\n", optarg);
|
||||
exit(2);
|
||||
}
|
||||
if (optarg[0] == 'n')
|
||||
layout = 256 + copies;
|
||||
else
|
||||
layout = 1 + (copies<<8);
|
||||
break;
|
||||
}
|
||||
continue;
|
||||
|
||||
|
@ -596,12 +617,15 @@ int main(int argc, char *argv[])
|
|||
exit(2);
|
||||
}
|
||||
update = optarg;
|
||||
if (strcmp(update, "sparc2.2")==0) continue;
|
||||
if (strcmp(update, "sparc2.2")==0)
|
||||
continue;
|
||||
if (strcmp(update, "super-minor") == 0)
|
||||
continue;
|
||||
if (strcmp(update, "summaries")==0)
|
||||
continue;
|
||||
fprintf(stderr, Name ": '--update %s' invalid. Only 'sparc2.2', 'super-minor' or 'summaries' supported\n",update);
|
||||
if (strcmp(update, "resync")==0)
|
||||
continue;
|
||||
fprintf(stderr, Name ": '--update %s' invalid. Only 'sparc2.2', 'super-minor', 'resync' or 'summaries' supported\n",update);
|
||||
exit(2);
|
||||
|
||||
case O(ASSEMBLE,'c'): /* config file */
|
||||
|
@ -663,6 +687,7 @@ int main(int argc, char *argv[])
|
|||
/* now the general management options. Some are applicable
|
||||
* to other modes. None have arguments.
|
||||
*/
|
||||
case O(GROW,'a'):
|
||||
case O(MANAGE,'a'): /* add a drive */
|
||||
devmode = 'a';
|
||||
continue;
|
||||
|
@ -944,16 +969,24 @@ int main(int argc, char *argv[])
|
|||
|
||||
case GROW:
|
||||
if (devs_found > 1) {
|
||||
fprintf(stderr, Name ": Only one device may be given for --grow\n");
|
||||
rv = 1;
|
||||
break;
|
||||
}
|
||||
if (size >= 0 && raiddisks) {
|
||||
|
||||
/* must be '-a'. */
|
||||
if (size >= 0 || raiddisks) {
|
||||
fprintf(stderr, Name ": --size, --raiddisks, and --add are exclusing in --grow mode\n");
|
||||
rv = 1;
|
||||
break;
|
||||
}
|
||||
for (dv=devlist->next; dv ; dv=dv->next) {
|
||||
rv = Grow_Add_device(devlist->devname, mdfd, dv->devname);
|
||||
if (rv)
|
||||
break;
|
||||
}
|
||||
} else if (size >= 0 && raiddisks) {
|
||||
fprintf(stderr, Name ": can only grow size OR raiddisks, not both\n");
|
||||
rv = 1;
|
||||
break;
|
||||
}
|
||||
rv = Manage_resize(devlist->devname, mdfd, size, raiddisks);
|
||||
} else
|
||||
rv = Manage_resize(devlist->devname, mdfd, size, raiddisks);
|
||||
break;
|
||||
}
|
||||
exit(rv);
|
||||
|
|
2
mdadm.h
2
mdadm.h
|
@ -136,6 +136,7 @@ struct mdstat_ent {
|
|||
char *level;
|
||||
char *pattern; /* U or up, _ for down */
|
||||
int percent; /* -1 if no resync */
|
||||
int resync; /* 1 if resync, 0 if recovery */
|
||||
struct mdstat_ent *next;
|
||||
};
|
||||
|
||||
|
@ -159,6 +160,7 @@ extern int Manage_runstop(char *devname, int fd, int runstop);
|
|||
extern int Manage_resize(char *devname, int fd, long long size, int raid_disks);
|
||||
extern int Manage_subdevs(char *devname, int fd,
|
||||
mddev_dev_t devlist);
|
||||
extern int Grow_Add_device(char *devname, int fd, char *newdev);
|
||||
|
||||
|
||||
extern int Assemble(char *mddev, int mdfd,
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
Summary: mdadm is used for controlling Linux md devices (aka RAID arrays)
|
||||
Name: mdadm
|
||||
Version: 1.6.0
|
||||
Version: 1.7.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/
|
||||
|
|
BIN
mdassemble
BIN
mdassemble
Binary file not shown.
6
mdstat.c
6
mdstat.c
|
@ -153,6 +153,7 @@ struct mdstat_ent *mdstat_read(int hold)
|
|||
ent->next = NULL;
|
||||
ent->percent = -1;
|
||||
ent->active = -1;
|
||||
ent->resync = 0;
|
||||
|
||||
ent->dev = strdup(line);
|
||||
ent->devnum = devnum;
|
||||
|
@ -179,6 +180,11 @@ struct mdstat_ent *mdstat_read(int hold)
|
|||
w[l-1] == '%' &&
|
||||
(eq=strchr(w, '=')) != NULL ) {
|
||||
ent->percent = atoi(eq+1);
|
||||
if (strncmp(w,"resync", 4)==0)
|
||||
ent->resync = 1;
|
||||
} else if (ent->percent == -1 &&
|
||||
strncmp(w, "resync", 4)==0) {
|
||||
ent->resync = 1;
|
||||
} else if (ent->percent == -1 &&
|
||||
w[0] >= '0' &&
|
||||
w[0] <= '9' &&
|
||||
|
|
53
util.c
53
util.c
|
@ -121,6 +121,8 @@ int get_linux_version()
|
|||
int enough(int level, int raid_disks, int avail_disks)
|
||||
{
|
||||
switch (level) {
|
||||
case 10: return 1; /* a lie, but it is hard to tell */
|
||||
|
||||
case -4:
|
||||
return avail_disks>= 1;
|
||||
case -1:
|
||||
|
@ -375,6 +377,32 @@ int map_name(mapping_t *map, char *name)
|
|||
return UnSet;
|
||||
}
|
||||
|
||||
|
||||
int is_standard(char *dev)
|
||||
{
|
||||
/* tests if dev is a "standard" md dev name.
|
||||
* i.e if the last component is "/dNN" or "/mdNN",
|
||||
* where NN is a string of digits
|
||||
*/
|
||||
dev = strrchr(dev, '/');
|
||||
if (!dev)
|
||||
return 0;
|
||||
if (strncmp(dev, "/d",2)==0)
|
||||
dev += 2;
|
||||
else if (strncmp(dev, "/md", 3)==0)
|
||||
dev += 3;
|
||||
else
|
||||
return 0;
|
||||
if (!*dev)
|
||||
return 0;
|
||||
while (isdigit(*dev))
|
||||
dev++;
|
||||
if (*dev)
|
||||
return 0;
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* convert a major/minor pair for a block device into a name in /dev, if possible.
|
||||
* On the first call, walk /dev collecting name.
|
||||
|
@ -421,31 +449,6 @@ int add_dev(const char *name, const struct stat *stb, int flag)
|
|||
return 0;
|
||||
}
|
||||
|
||||
int is_standard(char *dev)
|
||||
{
|
||||
/* tests if dev is a "standard" md dev name.
|
||||
* i.e if the last component is "/dNN" or "/mdNN",
|
||||
* where NN is a string of digits
|
||||
*/
|
||||
dev = strrchr(dev, '/');
|
||||
if (!dev)
|
||||
return 0;
|
||||
if (strncmp(dev, "/d",2)==0)
|
||||
dev += 2;
|
||||
else if (strncmp(dev, "/md", 3)==0)
|
||||
dev += 3;
|
||||
else
|
||||
return 0;
|
||||
if (!*dev)
|
||||
return 0;
|
||||
while (isdigit(*dev))
|
||||
dev++;
|
||||
if (*dev)
|
||||
return 0;
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Find a block device with the right major/minor number.
|
||||
* Avoid /dev/mdNN and /dev/md/dNN is possible
|
||||
|
|
Loading…
Reference in New Issue