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)
|
} else if (i >= super.raid_disks && super.disks[i].number == 0)
|
||||||
super.disks[i].state = 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);
|
super.sb_csum = calc_sb_csum(&super);
|
||||||
dfd = open(devname, O_RDWR, 0);
|
dfd = open(devname, O_RDWR, 0);
|
||||||
if (dfd < 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
|
Changes Prior to 1.6.0 release
|
||||||
- Device name given in -Eb is determined by examining /dev rather
|
- Device name given in -Eb is determined by examining /dev rather
|
||||||
than assuming /dev/md%d
|
than assuming /dev/md%d
|
||||||
|
|
15
Create.c
15
Create.c
|
@ -117,6 +117,12 @@ int Create(char *mddev, int mdfd,
|
||||||
default: /* no layout */
|
default: /* no layout */
|
||||||
layout = 0;
|
layout = 0;
|
||||||
break;
|
break;
|
||||||
|
case 10:
|
||||||
|
layout = 0x102; /* near=2, far=1 */
|
||||||
|
if (verbose)
|
||||||
|
fprintf(stderr,
|
||||||
|
Name ": layout defaults to n1\n");
|
||||||
|
break;
|
||||||
case 5:
|
case 5:
|
||||||
case 6:
|
case 6:
|
||||||
layout = map_name(r5layout, "default");
|
layout = map_name(r5layout, "default");
|
||||||
|
@ -126,9 +132,18 @@ int Create(char *mddev, int mdfd,
|
||||||
break;
|
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) {
|
switch(level) {
|
||||||
case 4:
|
case 4:
|
||||||
case 5:
|
case 5:
|
||||||
|
case 10:
|
||||||
case 6:
|
case 6:
|
||||||
case 0:
|
case 0:
|
||||||
case -1: /* linear */
|
case -1: /* linear */
|
||||||
|
|
113
Detail.c
113
Detail.c
|
@ -47,6 +47,9 @@ int Detail(char *dev, int brief, int test)
|
||||||
char *devices = NULL;
|
char *devices = NULL;
|
||||||
int spares = 0;
|
int spares = 0;
|
||||||
struct stat stb;
|
struct stat stb;
|
||||||
|
int is_26 = get_linux_version() >= 2006000;
|
||||||
|
int is_rebuilding = 0;
|
||||||
|
int failed = 0;
|
||||||
|
|
||||||
mdp_super_t super;
|
mdp_super_t super;
|
||||||
int have_super = 0;
|
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))
|
if (fstat(fd, &stb) != 0 && !S_ISBLK(stb.st_mode))
|
||||||
stb.st_rdev = 0;
|
stb.st_rdev = 0;
|
||||||
rv = 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... */
|
/* Ok, we have some info to print... */
|
||||||
c = map_num(pers, array.level);
|
c = map_num(pers, array.level);
|
||||||
if (brief)
|
if (brief)
|
||||||
|
@ -132,7 +163,8 @@ int Detail(char *dev, int brief, int test)
|
||||||
printf(" State : %s%s%s\n",
|
printf(" State : %s%s%s\n",
|
||||||
(array.state&(1<<MD_SB_CLEAN))?"clean":"dirty",
|
(array.state&(1<<MD_SB_CLEAN))?"clean":"dirty",
|
||||||
array.active_disks < array.raid_disks? ", degraded":"",
|
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(" Active Devices : %d\n", array.active_disks);
|
||||||
printf("Working Devices : %d\n", array.working_disks);
|
printf("Working Devices : %d\n", array.working_disks);
|
||||||
printf(" Failed Devices : %d\n", array.failed_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);
|
c = map_num(r5layout, array.layout);
|
||||||
printf(" Layout : %s\n", c?c:"-unknown-");
|
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) {
|
switch (array.level) {
|
||||||
case 0:
|
case 0:
|
||||||
case 4:
|
case 4:
|
||||||
case 5:
|
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;
|
break;
|
||||||
case -1:
|
case -1:
|
||||||
printf(" Rounding : %dK\n", array.chunk_size/1024);
|
printf(" Rounding : %dK\n\n", array.chunk_size/1024);
|
||||||
break;
|
break;
|
||||||
default: break;
|
default: break;
|
||||||
}
|
}
|
||||||
|
|
||||||
printf("\n");
|
if (e && e->percent >= 0) {
|
||||||
|
|
||||||
if (e && e->percent >= 0)
|
|
||||||
printf(" Rebuild Status : %d%% complete\n\n", e->percent);
|
printf(" Rebuild Status : %d%% complete\n\n", e->percent);
|
||||||
|
is_rebuilding = 1;
|
||||||
|
}
|
||||||
free_mdstat(ms);
|
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");
|
printf(" Number Major Minor RaidDevice State\n");
|
||||||
}
|
}
|
||||||
for (d= 0; d<MD_SB_DISKS; d++) {
|
for (d= 0; d<MD_SB_DISKS; d++) {
|
||||||
|
@ -177,14 +225,40 @@ int Detail(char *dev, int brief, int test)
|
||||||
disk.minor == 0)
|
disk.minor == 0)
|
||||||
continue;
|
continue;
|
||||||
if (!brief) {
|
if (!brief) {
|
||||||
printf(" %5d %5d %5d %5d ",
|
if (disk.number == array.raid_disks) printf("\n");
|
||||||
disk.number, disk.major, disk.minor, disk.raid_disk);
|
if (disk.raid_disk < 0)
|
||||||
if (disk.state & (1<<MD_DISK_FAULTY)) printf(" faulty");
|
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_ACTIVE)) printf(" active");
|
||||||
if (disk.state & (1<<MD_DISK_SYNC)) printf(" sync");
|
if (disk.state & (1<<MD_DISK_SYNC)) printf(" sync");
|
||||||
if (disk.state & (1<<MD_DISK_REMOVED)) printf(" removed");
|
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 (test && d < array.raid_disks && disk.state & (1<<MD_DISK_FAULTY)) {
|
||||||
if ((rv & 1) && (array.level ==4 || array.level == 5))
|
if ((rv & 1) && (array.level ==4 || array.level == 5))
|
||||||
rv |= 2;
|
rv |= 2;
|
||||||
|
@ -200,34 +274,21 @@ int Detail(char *dev, int brief, int test)
|
||||||
devices = strdup(dv);
|
devices = strdup(dv);
|
||||||
} else
|
} else
|
||||||
printf(" %s", dv);
|
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 (!brief) printf("\n");
|
||||||
}
|
}
|
||||||
if (spares && brief) printf(" spares=%d", spares);
|
if (spares && brief) printf(" spares=%d", spares);
|
||||||
if (have_super) {
|
if (have_super && brief) {
|
||||||
if (brief) printf(" UUID=");
|
printf(" UUID=");
|
||||||
else printf(" UUID : ");
|
|
||||||
if (super.minor_version >= 90)
|
if (super.minor_version >= 90)
|
||||||
printf("%08x:%08x:%08x:%08x", super.set_uuid0, super.set_uuid1,
|
printf("%08x:%08x:%08x:%08x", super.set_uuid0, super.set_uuid1,
|
||||||
super.set_uuid2, super.set_uuid3);
|
super.set_uuid2, super.set_uuid3);
|
||||||
else
|
else
|
||||||
printf("%08x", super.set_uuid0);
|
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 && devices) printf("\n devices=%s", devices);
|
||||||
if (brief) printf("\n");
|
if (brief) printf("\n");
|
||||||
if (test && (rv&2)) rv &= ~1;
|
if (test && (rv&2)) rv &= ~1;
|
||||||
|
close(fd);
|
||||||
return rv;
|
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 (" --- adjusting superblock for 2.2/sparc compatability ---\n");
|
||||||
}
|
}
|
||||||
printf(" Events : %d.%d\n", super.events_hi, super.events_lo);
|
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");
|
printf("\n");
|
||||||
if (super.level == 5) {
|
if (super.level == 5) {
|
||||||
c = map_num(r5layout, super.layout);
|
c = map_num(r5layout, super.layout);
|
||||||
printf(" Layout : %s\n", c?c:"-unknown-");
|
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) {
|
switch(super.level) {
|
||||||
case 0:
|
case 0:
|
||||||
case 4:
|
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)))
|
if ((dv=map_dev(dp->major, dp->minor)))
|
||||||
printf(" %s", dv);
|
printf(" %s", dv);
|
||||||
printf("\n");
|
printf("\n");
|
||||||
|
if (d == -1) printf("\n");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (SparcAdjust == 2) {
|
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.
|
# define "CXFLAGS" to give extra flags to CC.
|
||||||
# e.g. make CXFLAGS=-O to optimise
|
# e.g. make CXFLAGS=-O to optimise
|
||||||
TCC = tcc
|
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
|
CC = gcc
|
||||||
CXFLAGS = -ggdb
|
CXFLAGS = -ggdb
|
||||||
|
@ -55,8 +55,8 @@ MAN8DIR = $(MANDIR)/man8
|
||||||
|
|
||||||
KLIBC=/home/src/klibc/klibc-0.77
|
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
|
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 Monitor.c dlink.c Kill.c Query.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
|
||||||
|
|
||||||
all : mdadm mdadm.man md.man mdadm.conf.man
|
all : mdadm mdadm.man md.man mdadm.conf.man
|
||||||
|
|
||||||
|
|
|
@ -163,6 +163,7 @@ int Monitor(mddev_dev_t devlist,
|
||||||
} else {
|
} else {
|
||||||
mddev_dev_t dv;
|
mddev_dev_t dv;
|
||||||
for (dv=devlist ; dv; dv=dv->next) {
|
for (dv=devlist ; dv; dv=dv->next) {
|
||||||
|
mddev_ident_t mdlist = conf_get_ident(config, dv->devname);
|
||||||
struct state *st = malloc(sizeof *st);
|
struct state *st = malloc(sizeof *st);
|
||||||
if (st == NULL)
|
if (st == NULL)
|
||||||
continue;
|
continue;
|
||||||
|
@ -174,6 +175,11 @@ int Monitor(mddev_dev_t devlist,
|
||||||
st->percent = -2;
|
st->percent = -2;
|
||||||
st->expected_spares = -1;
|
st->expected_spares = -1;
|
||||||
st->spare_group = NULL;
|
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;
|
statelist = st;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -216,7 +222,8 @@ int Monitor(mddev_dev_t devlist,
|
||||||
close(fd);
|
close(fd);
|
||||||
continue;
|
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)
|
if (!st->err)
|
||||||
alert("DeviceDisappeared", dev, "Wrong-Level",
|
alert("DeviceDisappeared", dev, "Wrong-Level",
|
||||||
mailaddr, alert_cmd);
|
mailaddr, alert_cmd);
|
||||||
|
|
8
ReadMe.c
8
ReadMe.c
|
@ -29,7 +29,7 @@
|
||||||
|
|
||||||
#include "mdadm.h"
|
#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
|
* File: ReadMe.c
|
||||||
*
|
*
|
||||||
|
@ -216,7 +216,7 @@ char OptionHelp[] =
|
||||||
" --layout= : same as --parity\n"
|
" --layout= : same as --parity\n"
|
||||||
" --raid-devices= -n : number of active devices in array\n"
|
" --raid-devices= -n : number of active devices in array\n"
|
||||||
" --spare-devices= -x: number of spares (eXtras) devices in initial 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"
|
" --force -f : Honour devices as listed on command line. Don't\n"
|
||||||
" : insert a missing drive for RAID5.\n"
|
" : insert a missing drive for RAID5.\n"
|
||||||
" --auto(=p) -a : Automatically allocate new (partitioned) md array if needed.\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"
|
" --layout= : same as --parity\n"
|
||||||
" --raid-devices= -n : number of active devices in array\n"
|
" --raid-devices= -n : number of active devices in array\n"
|
||||||
" --spare-devices= -x: number of spares (eXtras) devices in initial 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"
|
" --force -f : Honour devices as listed on command line. Don't\n"
|
||||||
" : insert a missing drive for RAID5.\n"
|
" : insert a missing drive for RAID5.\n"
|
||||||
" --run -R : insist of running the array even if not all\n"
|
" --run -R : insist of running the array even if not all\n"
|
||||||
|
@ -508,6 +508,8 @@ mapping_t pers[] = {
|
||||||
{ "mp", -4},
|
{ "mp", -4},
|
||||||
{ "raid6", 6},
|
{ "raid6", 6},
|
||||||
{ "6", 6},
|
{ "6", 6},
|
||||||
|
{ "raid10", 10},
|
||||||
|
{ "10", 10},
|
||||||
{ NULL, 0}
|
{ NULL, 0}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
2
config.c
2
config.c
|
@ -364,7 +364,7 @@ void arrayline(char *line)
|
||||||
}
|
}
|
||||||
if (mis.devname == NULL)
|
if (mis.devname == NULL)
|
||||||
fprintf(stderr, Name ": ARRAY line with no device\n");
|
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);
|
fprintf(stderr, Name ": ARRAY line %s has no identity information.\n", mis.devname);
|
||||||
else {
|
else {
|
||||||
mi = malloc(sizeof(*mi));
|
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 ]
|
if [ -f ANNOUNCE-$version ]
|
||||||
then :
|
then :
|
||||||
else
|
else
|
||||||
echo ANNONCE-$version does not exist
|
echo ANNOUNCE-$version does not exist
|
||||||
exit 1
|
exit 1
|
||||||
fi
|
fi
|
||||||
|
if grep "^ANNOUNCE-$version\$" inventory
|
||||||
|
then :
|
||||||
|
else { cat inventory ; echo ANNOUNCE-$version ; } | sort -o inventory
|
||||||
|
fi
|
||||||
|
|
||||||
echo version = $version
|
echo version = $version
|
||||||
base=mdadm-$version.tgz
|
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
|
( 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
|
chmod a+r $target/$base
|
||||||
ls -l $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
|
rpm -ta $target/$base
|
||||||
find /home/neilb/src/RPM -name "*mdadm-$version-*" \
|
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
|
#if __BYTE_ORDER == __BIG_ENDIAN
|
||||||
__u32 events_hi; /* 7 high-order of superblock update count */
|
__u32 events_hi; /* 7 high-order of superblock update count */
|
||||||
__u32 events_lo; /* 8 low-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
|
#else
|
||||||
__u32 events_lo; /* 7 low-order of superblock update count */
|
__u32 events_lo; /* 7 low-order of superblock update count */
|
||||||
__u32 events_hi; /* 8 high-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
|
#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
|
* Personality information
|
||||||
|
|
12
mdadm.8
12
mdadm.8
|
@ -1,5 +1,5 @@
|
||||||
.\" -*- nroff -*-
|
.\" -*- nroff -*-
|
||||||
.TH MDADM 8 "" v1.6.0
|
.TH MDADM 8 "" v1.7.0
|
||||||
.SH NAME
|
.SH NAME
|
||||||
mdadm \- manage MD devices
|
mdadm \- manage MD devices
|
||||||
.I aka
|
.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
|
argument given to this flag can be one of
|
||||||
.BR sparc2.2 ,
|
.BR sparc2.2 ,
|
||||||
.BR summaries ,
|
.BR summaries ,
|
||||||
|
.BR resync ,
|
||||||
or
|
or
|
||||||
.BR super-minor .
|
.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
|
assembled. This is not needed on 2.6 and later kernels as they make
|
||||||
this adjustment automatically.
|
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
|
The
|
||||||
.B summaries
|
.B summaries
|
||||||
option will correct the summaries in the superblock. That is the
|
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 daemonise = 0;
|
||||||
int oneshot = 0;
|
int oneshot = 0;
|
||||||
|
|
||||||
|
int copies;
|
||||||
|
|
||||||
int mdfd = -1;
|
int mdfd = -1;
|
||||||
|
|
||||||
ident.uuid_set=0;
|
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);
|
fprintf(stderr, Name ": Must give one of -a/-r/-f for subsequent devices at %s\n", optarg);
|
||||||
exit(2);
|
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));
|
dv = malloc(sizeof(*dv));
|
||||||
if (dv == NULL) {
|
if (dv == NULL) {
|
||||||
fprintf(stderr, Name ": malloc failed\n");
|
fprintf(stderr, Name ": malloc failed\n");
|
||||||
|
@ -441,7 +447,7 @@ int main(int argc, char *argv[])
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
case O(CREATE,'p'): /* raid5 layout */
|
case O(CREATE,'p'): /* raid5 layout */
|
||||||
if (layout >= 0) {
|
if (layout != UnSet) {
|
||||||
fprintf(stderr,Name ": layout may only be sent once. "
|
fprintf(stderr,Name ": layout may only be sent once. "
|
||||||
"Second value was %s\n", optarg);
|
"Second value was %s\n", optarg);
|
||||||
exit(2);
|
exit(2);
|
||||||
|
@ -464,6 +470,21 @@ int main(int argc, char *argv[])
|
||||||
exit(2);
|
exit(2);
|
||||||
}
|
}
|
||||||
break;
|
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;
|
continue;
|
||||||
|
|
||||||
|
@ -596,12 +617,15 @@ int main(int argc, char *argv[])
|
||||||
exit(2);
|
exit(2);
|
||||||
}
|
}
|
||||||
update = optarg;
|
update = optarg;
|
||||||
if (strcmp(update, "sparc2.2")==0) continue;
|
if (strcmp(update, "sparc2.2")==0)
|
||||||
|
continue;
|
||||||
if (strcmp(update, "super-minor") == 0)
|
if (strcmp(update, "super-minor") == 0)
|
||||||
continue;
|
continue;
|
||||||
if (strcmp(update, "summaries")==0)
|
if (strcmp(update, "summaries")==0)
|
||||||
continue;
|
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);
|
exit(2);
|
||||||
|
|
||||||
case O(ASSEMBLE,'c'): /* config file */
|
case O(ASSEMBLE,'c'): /* config file */
|
||||||
|
@ -663,6 +687,7 @@ int main(int argc, char *argv[])
|
||||||
/* now the general management options. Some are applicable
|
/* now the general management options. Some are applicable
|
||||||
* to other modes. None have arguments.
|
* to other modes. None have arguments.
|
||||||
*/
|
*/
|
||||||
|
case O(GROW,'a'):
|
||||||
case O(MANAGE,'a'): /* add a drive */
|
case O(MANAGE,'a'): /* add a drive */
|
||||||
devmode = 'a';
|
devmode = 'a';
|
||||||
continue;
|
continue;
|
||||||
|
@ -944,16 +969,24 @@ int main(int argc, char *argv[])
|
||||||
|
|
||||||
case GROW:
|
case GROW:
|
||||||
if (devs_found > 1) {
|
if (devs_found > 1) {
|
||||||
fprintf(stderr, Name ": Only one device may be given for --grow\n");
|
|
||||||
rv = 1;
|
/* must be '-a'. */
|
||||||
break;
|
if (size >= 0 || raiddisks) {
|
||||||
}
|
fprintf(stderr, Name ": --size, --raiddisks, and --add are exclusing in --grow mode\n");
|
||||||
if (size >= 0 && raiddisks) {
|
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");
|
fprintf(stderr, Name ": can only grow size OR raiddisks, not both\n");
|
||||||
rv = 1;
|
rv = 1;
|
||||||
break;
|
break;
|
||||||
}
|
} else
|
||||||
rv = Manage_resize(devlist->devname, mdfd, size, raiddisks);
|
rv = Manage_resize(devlist->devname, mdfd, size, raiddisks);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
exit(rv);
|
exit(rv);
|
||||||
|
|
2
mdadm.h
2
mdadm.h
|
@ -136,6 +136,7 @@ struct mdstat_ent {
|
||||||
char *level;
|
char *level;
|
||||||
char *pattern; /* U or up, _ for down */
|
char *pattern; /* U or up, _ for down */
|
||||||
int percent; /* -1 if no resync */
|
int percent; /* -1 if no resync */
|
||||||
|
int resync; /* 1 if resync, 0 if recovery */
|
||||||
struct mdstat_ent *next;
|
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_resize(char *devname, int fd, long long size, int raid_disks);
|
||||||
extern int Manage_subdevs(char *devname, int fd,
|
extern int Manage_subdevs(char *devname, int fd,
|
||||||
mddev_dev_t devlist);
|
mddev_dev_t devlist);
|
||||||
|
extern int Grow_Add_device(char *devname, int fd, char *newdev);
|
||||||
|
|
||||||
|
|
||||||
extern int Assemble(char *mddev, int mdfd,
|
extern int Assemble(char *mddev, int mdfd,
|
||||||
|
|
|
@ -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.6.0
|
Version: 1.7.0
|
||||||
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/
|
||||||
|
|
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->next = NULL;
|
||||||
ent->percent = -1;
|
ent->percent = -1;
|
||||||
ent->active = -1;
|
ent->active = -1;
|
||||||
|
ent->resync = 0;
|
||||||
|
|
||||||
ent->dev = strdup(line);
|
ent->dev = strdup(line);
|
||||||
ent->devnum = devnum;
|
ent->devnum = devnum;
|
||||||
|
@ -179,6 +180,11 @@ struct mdstat_ent *mdstat_read(int hold)
|
||||||
w[l-1] == '%' &&
|
w[l-1] == '%' &&
|
||||||
(eq=strchr(w, '=')) != NULL ) {
|
(eq=strchr(w, '=')) != NULL ) {
|
||||||
ent->percent = atoi(eq+1);
|
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 &&
|
} else if (ent->percent == -1 &&
|
||||||
w[0] >= '0' &&
|
w[0] >= '0' &&
|
||||||
w[0] <= '9' &&
|
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)
|
int enough(int level, int raid_disks, int avail_disks)
|
||||||
{
|
{
|
||||||
switch (level) {
|
switch (level) {
|
||||||
|
case 10: return 1; /* a lie, but it is hard to tell */
|
||||||
|
|
||||||
case -4:
|
case -4:
|
||||||
return avail_disks>= 1;
|
return avail_disks>= 1;
|
||||||
case -1:
|
case -1:
|
||||||
|
@ -375,6 +377,32 @@ int map_name(mapping_t *map, char *name)
|
||||||
return UnSet;
|
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.
|
* convert a major/minor pair for a block device into a name in /dev, if possible.
|
||||||
* On the first call, walk /dev collecting name.
|
* 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;
|
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.
|
* Find a block device with the right major/minor number.
|
||||||
* Avoid /dev/mdNN and /dev/md/dNN is possible
|
* Avoid /dev/mdNN and /dev/md/dNN is possible
|
||||||
|
|
Loading…
Reference in New Issue