Merge branch 'fixes' into for-neil
This commit is contained in:
commit
d19e3cfb66
34
Grow.c
34
Grow.c
|
@ -546,7 +546,13 @@ int Grow_reshape(char *devname, int fd, int quiet, char *backup_file,
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
sra = sysfs_read(fd, 0, GET_LEVEL);
|
sra = sysfs_read(fd, 0, GET_LEVEL);
|
||||||
frozen = freeze_array(sra);
|
if (sra)
|
||||||
|
frozen = freeze_array(sra);
|
||||||
|
else {
|
||||||
|
fprintf(stderr, Name ": failed to read sysfs parameters for %s\n",
|
||||||
|
devname);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
if (frozen < 0) {
|
if (frozen < 0) {
|
||||||
fprintf(stderr, Name ": %s is performing resync/recovery and cannot"
|
fprintf(stderr, Name ": %s is performing resync/recovery and cannot"
|
||||||
" be reshaped\n", devname);
|
" be reshaped\n", devname);
|
||||||
|
@ -948,6 +954,13 @@ int Grow_reshape(char *devname, int fd, int quiet, char *backup_file,
|
||||||
GET_COMPONENT|GET_DEVS|GET_OFFSET|GET_STATE|
|
GET_COMPONENT|GET_DEVS|GET_OFFSET|GET_STATE|
|
||||||
GET_CACHE);
|
GET_CACHE);
|
||||||
|
|
||||||
|
if (!sra) {
|
||||||
|
fprintf(stderr, Name ": %s: Cannot get array details from sysfs\n",
|
||||||
|
devname);
|
||||||
|
rv = 1;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
if (ndata == odata) {
|
if (ndata == odata) {
|
||||||
/* Make 'blocks' bigger for better throughput, but
|
/* Make 'blocks' bigger for better throughput, but
|
||||||
* not so big that we reject it below.
|
* not so big that we reject it below.
|
||||||
|
@ -960,13 +973,6 @@ int Grow_reshape(char *devname, int fd, int quiet, char *backup_file,
|
||||||
fprintf(stderr, Name ": Need to backup %luK of critical "
|
fprintf(stderr, Name ": Need to backup %luK of critical "
|
||||||
"section..\n", blocks/2);
|
"section..\n", blocks/2);
|
||||||
|
|
||||||
if (!sra) {
|
|
||||||
fprintf(stderr, Name ": %s: Cannot get array details from sysfs\n",
|
|
||||||
devname);
|
|
||||||
rv = 1;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (blocks >= sra->component_size/2) {
|
if (blocks >= sra->component_size/2) {
|
||||||
fprintf(stderr, Name ": %s: Something wrong - reshape aborted\n",
|
fprintf(stderr, Name ": %s: Something wrong - reshape aborted\n",
|
||||||
devname);
|
devname);
|
||||||
|
@ -1970,6 +1976,12 @@ int Grow_continue(int mdfd, struct supertype *st, struct mdinfo *info,
|
||||||
int cache;
|
int cache;
|
||||||
int done = 0;
|
int done = 0;
|
||||||
|
|
||||||
|
sra = sysfs_read(-1, devname2devnum(info->sys_name),
|
||||||
|
GET_COMPONENT|GET_DEVS|GET_OFFSET|GET_STATE|
|
||||||
|
GET_CACHE);
|
||||||
|
if (!sra)
|
||||||
|
return 1;
|
||||||
|
|
||||||
err = sysfs_set_str(info, NULL, "array_state", "readonly");
|
err = sysfs_set_str(info, NULL, "array_state", "readonly");
|
||||||
if (err)
|
if (err)
|
||||||
return err;
|
return err;
|
||||||
|
@ -1990,7 +2002,6 @@ int Grow_continue(int mdfd, struct supertype *st, struct mdinfo *info,
|
||||||
ochunk = info->array.chunk_size;
|
ochunk = info->array.chunk_size;
|
||||||
nchunk = info->new_chunk;
|
nchunk = info->new_chunk;
|
||||||
|
|
||||||
|
|
||||||
a = (ochunk/512) * odata;
|
a = (ochunk/512) * odata;
|
||||||
b = (nchunk/512) * ndata;
|
b = (nchunk/512) * ndata;
|
||||||
/* Find GCD */
|
/* Find GCD */
|
||||||
|
@ -2003,11 +2014,6 @@ int Grow_continue(int mdfd, struct supertype *st, struct mdinfo *info,
|
||||||
/* LCM == product / GCD */
|
/* LCM == product / GCD */
|
||||||
blocks = (ochunk/512) * (nchunk/512) * odata * ndata / a;
|
blocks = (ochunk/512) * (nchunk/512) * odata * ndata / a;
|
||||||
|
|
||||||
sra = sysfs_read(-1, devname2devnum(info->sys_name),
|
|
||||||
GET_COMPONENT|GET_DEVS|GET_OFFSET|GET_STATE|
|
|
||||||
GET_CACHE);
|
|
||||||
|
|
||||||
|
|
||||||
if (ndata == odata)
|
if (ndata == odata)
|
||||||
while (blocks * 32 < sra->component_size &&
|
while (blocks * 32 < sra->component_size &&
|
||||||
blocks < 16*1024*2)
|
blocks < 16*1024*2)
|
||||||
|
|
|
@ -258,6 +258,15 @@ int Incremental(char *devname, int verbose, int runstop,
|
||||||
autof = ci->autof;
|
autof = ci->autof;
|
||||||
|
|
||||||
if (st->ss->container_content && st->loaded_container) {
|
if (st->ss->container_content && st->loaded_container) {
|
||||||
|
if ((runstop > 0 && info.container_enough >= 0) ||
|
||||||
|
info.container_enough > 0)
|
||||||
|
/* pass */;
|
||||||
|
else {
|
||||||
|
if (verbose)
|
||||||
|
fprintf(stderr, Name ": not enough devices to start the container\n");
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
/* This is a pre-built container array, so we do something
|
/* This is a pre-built container array, so we do something
|
||||||
* rather different.
|
* rather different.
|
||||||
*/
|
*/
|
||||||
|
@ -360,6 +369,8 @@ int Incremental(char *devname, int verbose, int runstop,
|
||||||
strcpy(chosen_name, devnum2devname(mp->devnum));
|
strcpy(chosen_name, devnum2devname(mp->devnum));
|
||||||
|
|
||||||
sra = sysfs_read(mdfd, fd2devnum(mdfd), (GET_DEVS | GET_STATE));
|
sra = sysfs_read(mdfd, fd2devnum(mdfd), (GET_DEVS | GET_STATE));
|
||||||
|
if (!sra)
|
||||||
|
return 2;
|
||||||
|
|
||||||
if (sra->devs) {
|
if (sra->devs) {
|
||||||
sprintf(dn, "%d:%d", sra->devs->disk.major,
|
sprintf(dn, "%d:%d", sra->devs->disk.major,
|
||||||
|
@ -428,8 +439,6 @@ int Incremental(char *devname, int verbose, int runstop,
|
||||||
chosen_name, info.array.working_disks);
|
chosen_name, info.array.working_disks);
|
||||||
wait_for(chosen_name, mdfd);
|
wait_for(chosen_name, mdfd);
|
||||||
close(mdfd);
|
close(mdfd);
|
||||||
if (runstop < 0)
|
|
||||||
return 0; /* don't try to assemble */
|
|
||||||
rv = Incremental(chosen_name, verbose, runstop,
|
rv = Incremental(chosen_name, verbose, runstop,
|
||||||
NULL, homehost, require_homehost, autof);
|
NULL, homehost, require_homehost, autof);
|
||||||
if (rv == 1)
|
if (rv == 1)
|
||||||
|
@ -443,8 +452,7 @@ int Incremental(char *devname, int verbose, int runstop,
|
||||||
active_disks = count_active(st, mdfd, &avail, &info);
|
active_disks = count_active(st, mdfd, &avail, &info);
|
||||||
if (enough(info.array.level, info.array.raid_disks,
|
if (enough(info.array.level, info.array.raid_disks,
|
||||||
info.array.layout, info.array.state & 1,
|
info.array.layout, info.array.state & 1,
|
||||||
avail, active_disks) == 0 ||
|
avail, active_disks) == 0) {
|
||||||
(runstop < 0 && active_disks < info.array.raid_disks)) {
|
|
||||||
free(avail);
|
free(avail);
|
||||||
if (verbose >= 0)
|
if (verbose >= 0)
|
||||||
fprintf(stderr, Name
|
fprintf(stderr, Name
|
||||||
|
@ -580,6 +588,9 @@ static int count_active(struct supertype *st, int mdfd, char **availp,
|
||||||
struct mdinfo *sra = sysfs_read(mdfd, -1, GET_DEVS | GET_STATE);
|
struct mdinfo *sra = sysfs_read(mdfd, -1, GET_DEVS | GET_STATE);
|
||||||
char *avail = NULL;
|
char *avail = NULL;
|
||||||
|
|
||||||
|
if (!sra)
|
||||||
|
return 0;
|
||||||
|
|
||||||
for (d = sra->devs ; d ; d = d->next) {
|
for (d = sra->devs ; d ; d = d->next) {
|
||||||
char dn[30];
|
char dn[30];
|
||||||
int dfd;
|
int dfd;
|
||||||
|
|
16
Makefile
16
Makefile
|
@ -48,9 +48,15 @@ CWFLAGS += -Wp,-D_FORTIFY_SOURCE=2 -O
|
||||||
endif
|
endif
|
||||||
|
|
||||||
ifdef DEBIAN
|
ifdef DEBIAN
|
||||||
CPPFLAGS= -DDEBIAN
|
CPPFLAGS := -DDEBIAN
|
||||||
else
|
else
|
||||||
CPPFLAGS=
|
CPPFLAGS :=
|
||||||
|
endif
|
||||||
|
ifdef DEFAULT_OLD_METADATA
|
||||||
|
CPPFLAG += -DDEFAULT_OLD_METADATA
|
||||||
|
DEFAULT_METADATA=0.90
|
||||||
|
else
|
||||||
|
DEFAULT_METADATA=1.2
|
||||||
endif
|
endif
|
||||||
|
|
||||||
SYSCONFDIR = /etc
|
SYSCONFDIR = /etc
|
||||||
|
@ -151,8 +157,9 @@ mdadm.O2 : $(SRCS) mdadm.h mdmon.O2
|
||||||
mdmon.O2 : $(MON_SRCS) mdadm.h mdmon.h
|
mdmon.O2 : $(MON_SRCS) mdadm.h mdmon.h
|
||||||
$(CC) -o mdmon.O2 $(CFLAGS) -DHAVE_STDINT_H -O2 -D_FORTIFY_SOURCE=2 $(MON_SRCS)
|
$(CC) -o mdmon.O2 $(CFLAGS) -DHAVE_STDINT_H -O2 -D_FORTIFY_SOURCE=2 $(MON_SRCS)
|
||||||
|
|
||||||
|
# use '-z now' to guarantee no dynamic linker interactions with the monitor thread
|
||||||
mdmon : $(MON_OBJS)
|
mdmon : $(MON_OBJS)
|
||||||
$(CC) $(LDFLAGS) -o mdmon $(MON_OBJS) $(LDLIBS)
|
$(CC) $(LDFLAGS) -z now -o mdmon $(MON_OBJS) $(LDLIBS)
|
||||||
msg.o: msg.c msg.h
|
msg.o: msg.c msg.h
|
||||||
|
|
||||||
test_stripe : restripe.c mdadm.h
|
test_stripe : restripe.c mdadm.h
|
||||||
|
@ -180,6 +187,9 @@ mdassemble.klibc : $(ASSEMBLE_SRCS) mdadm.h
|
||||||
rm -f $(OBJS)
|
rm -f $(OBJS)
|
||||||
$(KLIBC_GCC) $(ASSEMBLE_FLAGS) -o mdassemble $(ASSEMBLE_SRCS)
|
$(KLIBC_GCC) $(ASSEMBLE_FLAGS) -o mdassemble $(ASSEMBLE_SRCS)
|
||||||
|
|
||||||
|
mdadm.8 : mdadm.8.in
|
||||||
|
sed -e 's/{DEFAULT_METADATA}/$(DEFAULT_METADATA)/g' mdadm.8.in > mdadm.8
|
||||||
|
|
||||||
mdadm.man : mdadm.8
|
mdadm.man : mdadm.8
|
||||||
nroff -man mdadm.8 > mdadm.man
|
nroff -man mdadm.8 > mdadm.man
|
||||||
|
|
||||||
|
|
|
@ -391,6 +391,7 @@ int Monitor(mddev_dev_t devlist,
|
||||||
)
|
)
|
||||||
alert("FailSpare", dev, dv, mailaddr, mailfrom, alert_cmd, dosyslog);
|
alert("FailSpare", dev, dv, mailaddr, mailfrom, alert_cmd, dosyslog);
|
||||||
else if (i < (unsigned)array.raid_disks &&
|
else if (i < (unsigned)array.raid_disks &&
|
||||||
|
! (newstate & (1<<MD_DISK_REMOVED)) &&
|
||||||
(((st->devstate[i]&change)&(1<<MD_DISK_FAULTY)) ||
|
(((st->devstate[i]&change)&(1<<MD_DISK_FAULTY)) ||
|
||||||
((newstate&change)&(1<<MD_DISK_ACTIVE)) ||
|
((newstate&change)&(1<<MD_DISK_ACTIVE)) ||
|
||||||
((newstate&change)&(1<<MD_DISK_SYNC)))
|
((newstate&change)&(1<<MD_DISK_SYNC)))
|
||||||
|
|
|
@ -315,7 +315,7 @@ static void manage_container(struct mdstat_ent *mdstat,
|
||||||
* To see what is removed and what is added.
|
* To see what is removed and what is added.
|
||||||
* These need to be remove from, or added to, the array
|
* These need to be remove from, or added to, the array
|
||||||
*/
|
*/
|
||||||
mdi = sysfs_read(-1, mdstat->devnum, GET_DEVS|SKIP_GONE_DEVS);
|
mdi = sysfs_read(-1, mdstat->devnum, GET_DEVS);
|
||||||
if (!mdi) {
|
if (!mdi) {
|
||||||
/* invalidate the current count so we can try again */
|
/* invalidate the current count so we can try again */
|
||||||
container->devcnt = -1;
|
container->devcnt = -1;
|
||||||
|
|
|
@ -368,7 +368,7 @@ void RebuildMap(void)
|
||||||
}
|
}
|
||||||
|
|
||||||
for (md = mdstat ; md ; md = md->next) {
|
for (md = mdstat ; md ; md = md->next) {
|
||||||
struct mdinfo *sra = sysfs_read(-1, md->devnum, GET_DEVS|SKIP_GONE_DEVS);
|
struct mdinfo *sra = sysfs_read(-1, md->devnum, GET_DEVS);
|
||||||
struct mdinfo *sd;
|
struct mdinfo *sd;
|
||||||
|
|
||||||
if (!sra)
|
if (!sra)
|
||||||
|
@ -486,7 +486,8 @@ void RebuildMap(void)
|
||||||
for (md = mdstat ; md ; md = md->next) {
|
for (md = mdstat ; md ; md = md->next) {
|
||||||
struct mdinfo *sra = sysfs_read(-1, md->devnum,
|
struct mdinfo *sra = sysfs_read(-1, md->devnum,
|
||||||
GET_VERSION);
|
GET_VERSION);
|
||||||
sysfs_uevent(sra, "change");
|
if (sra)
|
||||||
|
sysfs_uevent(sra, "change");
|
||||||
sysfs_free(sra);
|
sysfs_free(sra);
|
||||||
}
|
}
|
||||||
map_free(map);
|
map_free(map);
|
||||||
|
|
|
@ -299,7 +299,7 @@ says to get a list of array devices from
|
||||||
.TP
|
.TP
|
||||||
.BR \-e ", " \-\-metadata=
|
.BR \-e ", " \-\-metadata=
|
||||||
Declare the style of RAID metadata (superblock) to be used. The
|
Declare the style of RAID metadata (superblock) to be used. The
|
||||||
default is 1.2 for
|
default is {DEFAULT_METADATA} for
|
||||||
.BR \-\-create ,
|
.BR \-\-create ,
|
||||||
and to guess for other operations.
|
and to guess for other operations.
|
||||||
The default can be overridden by setting the
|
The default can be overridden by setting the
|
||||||
|
@ -311,16 +311,24 @@ keyword in
|
||||||
|
|
||||||
Options are:
|
Options are:
|
||||||
.RS
|
.RS
|
||||||
|
.ie '{DEFAULT_METADATA}'0.90'
|
||||||
|
.IP "0, 0.90, default"
|
||||||
|
.el
|
||||||
.IP "0, 0.90"
|
.IP "0, 0.90"
|
||||||
|
..
|
||||||
Use the original 0.90 format superblock. This format limits arrays to
|
Use the original 0.90 format superblock. This format limits arrays to
|
||||||
28 component devices and limits component devices of levels 1 and
|
28 component devices and limits component devices of levels 1 and
|
||||||
greater to 2 terabytes.
|
greater to 2 terabytes.
|
||||||
|
.ie '{DEFAULT_METADATA}'0.90'
|
||||||
|
.IP "1, 1.0, 1.1, 1.2"
|
||||||
|
.el
|
||||||
.IP "1, 1.0, 1.1, 1.2 default"
|
.IP "1, 1.0, 1.1, 1.2 default"
|
||||||
|
..
|
||||||
Use the new version-1 format superblock. This has few restrictions.
|
Use the new version-1 format superblock. This has few restrictions.
|
||||||
The different sub-versions store the superblock at different locations
|
The different sub-versions store the superblock at different locations
|
||||||
on the device, either at the end (for 1.0), at the start (for 1.1) or
|
on the device, either at the end (for 1.0), at the start (for 1.1) or
|
||||||
4K from the start (for 1.2). '1' is equivalent to '1.0', 'default' is
|
4K from the start (for 1.2). "1" is equivalent to "1.0".
|
||||||
equivalent to '1.2'.
|
'if '{DEFAULT_METADATA}'1.2' "default" is equivalent to "1.2".
|
||||||
.IP ddf
|
.IP ddf
|
||||||
Use the "Industry Standard" DDF (Disk Data Format) format defined by
|
Use the "Industry Standard" DDF (Disk Data Format) format defined by
|
||||||
SNIA.
|
SNIA.
|
||||||
|
@ -462,8 +470,9 @@ When used with
|
||||||
.BR \-\-build ,
|
.BR \-\-build ,
|
||||||
only linear, stripe, raid0, 0, raid1, multipath, mp, and faulty are valid.
|
only linear, stripe, raid0, 0, raid1, multipath, mp, and faulty are valid.
|
||||||
|
|
||||||
Not yet supported with
|
Can be used with
|
||||||
.BR \-\-grow .
|
.B \-\-grow
|
||||||
|
to change the RAID level in some cases. See LEVEL CHANGES below.
|
||||||
|
|
||||||
.TP
|
.TP
|
||||||
.BR \-p ", " \-\-layout=
|
.BR \-p ", " \-\-layout=
|
||||||
|
@ -1233,11 +1242,6 @@ uses to help track which arrays are currently being assembled.
|
||||||
Run any array assembled as soon as a minimal number of devices are
|
Run any array assembled as soon as a minimal number of devices are
|
||||||
available, rather than waiting until all expected devices are present.
|
available, rather than waiting until all expected devices are present.
|
||||||
|
|
||||||
.TP
|
|
||||||
.B \-\-no\-degraded
|
|
||||||
This allows the hot-plug system to prevent arrays from running when it knows
|
|
||||||
that more disks may arrive later in the discovery process.
|
|
||||||
|
|
||||||
.TP
|
.TP
|
||||||
.BR \-\-scan ", " \-s
|
.BR \-\-scan ", " \-s
|
||||||
Only meaningful with
|
Only meaningful with
|
1
mdadm.c
1
mdadm.c
|
@ -691,7 +691,6 @@ int main(int argc, char *argv[])
|
||||||
" 'summaries', 'homehost', 'byteorder', 'devicesize'.\n");
|
" 'summaries', 'homehost', 'byteorder', 'devicesize'.\n");
|
||||||
exit(outf == stdout ? 0 : 2);
|
exit(outf == stdout ? 0 : 2);
|
||||||
|
|
||||||
case O(INCREMENTAL,NoDegraded):
|
|
||||||
case O(ASSEMBLE,NoDegraded): /* --no-degraded */
|
case O(ASSEMBLE,NoDegraded): /* --no-degraded */
|
||||||
runstop = -1; /* --stop isn't allowed for --assemble,
|
runstop = -1; /* --stop isn't allowed for --assemble,
|
||||||
* so we overload slightly */
|
* so we overload slightly */
|
||||||
|
|
5
mdadm.h
5
mdadm.h
|
@ -205,7 +205,9 @@ struct mdinfo {
|
||||||
int container_member; /* for assembling external-metatdata arrays
|
int container_member; /* for assembling external-metatdata arrays
|
||||||
* This is to be used internally by metadata
|
* This is to be used internally by metadata
|
||||||
* handler only */
|
* handler only */
|
||||||
|
int container_enough; /* flag external handlers can set to
|
||||||
|
* indicate that subarrays have not enough (-1),
|
||||||
|
* enough to start (0), or all expected disks (1) */
|
||||||
char sys_name[20];
|
char sys_name[20];
|
||||||
struct mdinfo *devs;
|
struct mdinfo *devs;
|
||||||
struct mdinfo *next;
|
struct mdinfo *next;
|
||||||
|
@ -405,7 +407,6 @@ enum sysfs_read_flags {
|
||||||
GET_SIZE = (1 << 12),
|
GET_SIZE = (1 << 12),
|
||||||
GET_STATE = (1 << 13),
|
GET_STATE = (1 << 13),
|
||||||
GET_ERROR = (1 << 14),
|
GET_ERROR = (1 << 14),
|
||||||
SKIP_GONE_DEVS = (1 << 15),
|
|
||||||
};
|
};
|
||||||
|
|
||||||
/* If fd >= 0, get the array it is open on,
|
/* If fd >= 0, get the array it is open on,
|
||||||
|
|
3
mdmon.c
3
mdmon.c
|
@ -373,8 +373,7 @@ static int mdmon(char *devname, int devnum, int must_fork, int takeover)
|
||||||
exit(3);
|
exit(3);
|
||||||
}
|
}
|
||||||
|
|
||||||
mdi = sysfs_read(mdfd, container->devnum,
|
mdi = sysfs_read(mdfd, container->devnum, GET_VERSION|GET_LEVEL|GET_DEVS);
|
||||||
GET_VERSION|GET_LEVEL|GET_DEVS|SKIP_GONE_DEVS);
|
|
||||||
|
|
||||||
if (!mdi) {
|
if (!mdi) {
|
||||||
fprintf(stderr, "mdmon: failed to load sysfs info for %s\n",
|
fprintf(stderr, "mdmon: failed to load sysfs info for %s\n",
|
||||||
|
|
|
@ -1365,6 +1365,7 @@ static void getinfo_super_ddf(struct supertype *st, struct mdinfo *info)
|
||||||
(ddf->anchor.guid+16));
|
(ddf->anchor.guid+16));
|
||||||
info->array.utime = 0;
|
info->array.utime = 0;
|
||||||
info->array.chunk_size = 0;
|
info->array.chunk_size = 0;
|
||||||
|
info->container_enough = 0;
|
||||||
|
|
||||||
|
|
||||||
info->disk.major = 0;
|
info->disk.major = 0;
|
||||||
|
@ -2814,14 +2815,8 @@ static int load_super_ddf_all(struct supertype *st, int fd,
|
||||||
int seq;
|
int seq;
|
||||||
char nm[20];
|
char nm[20];
|
||||||
int dfd;
|
int dfd;
|
||||||
int devnum = fd2devnum(fd);
|
|
||||||
enum sysfs_read_flags flags;
|
|
||||||
|
|
||||||
flags = GET_LEVEL|GET_VERSION|GET_DEVS|GET_STATE;
|
sra = sysfs_read(fd, 0, GET_LEVEL|GET_VERSION|GET_DEVS|GET_STATE);
|
||||||
if (mdmon_running(devnum))
|
|
||||||
flags |= SKIP_GONE_DEVS;
|
|
||||||
|
|
||||||
sra = sysfs_read(fd, 0, flags);
|
|
||||||
if (!sra)
|
if (!sra)
|
||||||
return 1;
|
return 1;
|
||||||
if (sra->array.major_version != -1 ||
|
if (sra->array.major_version != -1 ||
|
||||||
|
|
115
super-intel.c
115
super-intel.c
|
@ -357,7 +357,6 @@ static struct imsm_disk *__get_imsm_disk(struct imsm_super *mpb, __u8 index)
|
||||||
return &mpb->disk[index];
|
return &mpb->disk[index];
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifndef MDASSEMBLE
|
|
||||||
/* retrieve a disk from the parsed metadata */
|
/* retrieve a disk from the parsed metadata */
|
||||||
static struct imsm_disk *get_imsm_disk(struct intel_super *super, __u8 index)
|
static struct imsm_disk *get_imsm_disk(struct intel_super *super, __u8 index)
|
||||||
{
|
{
|
||||||
|
@ -369,7 +368,6 @@ static struct imsm_disk *get_imsm_disk(struct intel_super *super, __u8 index)
|
||||||
|
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
#endif
|
|
||||||
|
|
||||||
/* generate a checksum directly from the anchor when the anchor is known to be
|
/* generate a checksum directly from the anchor when the anchor is known to be
|
||||||
* up-to-date, currently only at load or write_super after coalescing
|
* up-to-date, currently only at load or write_super after coalescing
|
||||||
|
@ -1547,6 +1545,20 @@ static void fixup_container_spare_uuid(struct mdinfo *inf)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static __u8 imsm_check_degraded(struct intel_super *super, struct imsm_dev *dev, int failed);
|
||||||
|
static int imsm_count_failed(struct intel_super *super, struct imsm_dev *dev);
|
||||||
|
|
||||||
|
static struct imsm_disk *get_imsm_missing(struct intel_super *super, __u8 index)
|
||||||
|
{
|
||||||
|
struct dl *d;
|
||||||
|
|
||||||
|
for (d = super->missing; d; d = d->next)
|
||||||
|
if (d->index == index)
|
||||||
|
return &d->disk;
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
static void getinfo_super_imsm(struct supertype *st, struct mdinfo *info)
|
static void getinfo_super_imsm(struct supertype *st, struct mdinfo *info)
|
||||||
{
|
{
|
||||||
struct intel_super *super = st->sb;
|
struct intel_super *super = st->sb;
|
||||||
|
@ -1581,6 +1593,53 @@ static void getinfo_super_imsm(struct supertype *st, struct mdinfo *info)
|
||||||
info->name[0] = 0;
|
info->name[0] = 0;
|
||||||
info->recovery_start = MaxSector;
|
info->recovery_start = MaxSector;
|
||||||
|
|
||||||
|
/* do we have the all the insync disks that we expect? */
|
||||||
|
if (st->loaded_container) {
|
||||||
|
struct imsm_super *mpb = super->anchor;
|
||||||
|
int max_enough = -1, i;
|
||||||
|
|
||||||
|
for (i = 0; i < mpb->num_raid_devs; i++) {
|
||||||
|
struct imsm_dev *dev = get_imsm_dev(super, i);
|
||||||
|
int failed, enough, j, missing = 0;
|
||||||
|
struct imsm_map *map;
|
||||||
|
__u8 state;
|
||||||
|
|
||||||
|
failed = imsm_count_failed(super, dev);
|
||||||
|
state = imsm_check_degraded(super, dev, failed);
|
||||||
|
map = get_imsm_map(dev, dev->vol.migr_state);
|
||||||
|
|
||||||
|
/* any newly missing disks?
|
||||||
|
* (catches single-degraded vs double-degraded)
|
||||||
|
*/
|
||||||
|
for (j = 0; j < map->num_members; j++) {
|
||||||
|
__u32 ord = get_imsm_ord_tbl_ent(dev, i);
|
||||||
|
__u32 idx = ord_to_idx(ord);
|
||||||
|
|
||||||
|
if (!(ord & IMSM_ORD_REBUILD) &&
|
||||||
|
get_imsm_missing(super, idx)) {
|
||||||
|
missing = 1;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (state == IMSM_T_STATE_FAILED)
|
||||||
|
enough = -1;
|
||||||
|
else if (state == IMSM_T_STATE_DEGRADED &&
|
||||||
|
(state != map->map_state || missing))
|
||||||
|
enough = 0;
|
||||||
|
else /* we're normal, or already degraded */
|
||||||
|
enough = 1;
|
||||||
|
|
||||||
|
/* in the missing/failed disk case check to see
|
||||||
|
* if at least one array is runnable
|
||||||
|
*/
|
||||||
|
max_enough = max(max_enough, enough);
|
||||||
|
}
|
||||||
|
dprintf("%s: enough: %d\n", __func__, max_enough);
|
||||||
|
info->container_enough = max_enough;
|
||||||
|
} else
|
||||||
|
info->container_enough = -1;
|
||||||
|
|
||||||
if (super->disks) {
|
if (super->disks) {
|
||||||
__u32 reserved = imsm_reserved_sectors(super, super->disks);
|
__u32 reserved = imsm_reserved_sectors(super, super->disks);
|
||||||
|
|
||||||
|
@ -2707,14 +2766,9 @@ static int load_super_imsm_all(struct supertype *st, int fd, void **sbp,
|
||||||
int retry;
|
int retry;
|
||||||
int err = 0;
|
int err = 0;
|
||||||
int i;
|
int i;
|
||||||
enum sysfs_read_flags flags;
|
|
||||||
|
|
||||||
flags = GET_LEVEL|GET_VERSION|GET_DEVS|GET_STATE;
|
|
||||||
if (mdmon_running(devnum))
|
|
||||||
flags |= SKIP_GONE_DEVS;
|
|
||||||
|
|
||||||
/* check if 'fd' an opened container */
|
/* check if 'fd' an opened container */
|
||||||
sra = sysfs_read(fd, 0, flags);
|
sra = sysfs_read(fd, 0, GET_LEVEL|GET_VERSION|GET_DEVS|GET_STATE);
|
||||||
if (!sra)
|
if (!sra)
|
||||||
return 1;
|
return 1;
|
||||||
|
|
||||||
|
@ -4231,6 +4285,15 @@ static void update_recovery_start(struct imsm_dev *dev, struct mdinfo *array)
|
||||||
rebuild = d;
|
rebuild = d;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!rebuild) {
|
||||||
|
/* (?) none of the disks are marked with
|
||||||
|
* IMSM_ORD_REBUILD, so assume they are missing and the
|
||||||
|
* disk_ord_tbl was not correctly updated
|
||||||
|
*/
|
||||||
|
dprintf("%s: failed to locate out-of-sync disk\n", __func__);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
units = __le32_to_cpu(dev->vol.curr_migr_unit);
|
units = __le32_to_cpu(dev->vol.curr_migr_unit);
|
||||||
rebuild->recovery_start = units * blocks_per_migr_unit(dev);
|
rebuild->recovery_start = units * blocks_per_migr_unit(dev);
|
||||||
}
|
}
|
||||||
|
@ -4362,24 +4425,6 @@ static struct mdinfo *container_content_imsm(struct supertype *st)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
#ifndef MDASSEMBLE
|
|
||||||
static int imsm_open_new(struct supertype *c, struct active_array *a,
|
|
||||||
char *inst)
|
|
||||||
{
|
|
||||||
struct intel_super *super = c->sb;
|
|
||||||
struct imsm_super *mpb = super->anchor;
|
|
||||||
|
|
||||||
if (atoi(inst) >= mpb->num_raid_devs) {
|
|
||||||
fprintf(stderr, "%s: subarry index %d, out of range\n",
|
|
||||||
__func__, atoi(inst));
|
|
||||||
return -ENODEV;
|
|
||||||
}
|
|
||||||
|
|
||||||
dprintf("imsm: open_new %s\n", inst);
|
|
||||||
a->info.container_member = atoi(inst);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
static __u8 imsm_check_degraded(struct intel_super *super, struct imsm_dev *dev, int failed)
|
static __u8 imsm_check_degraded(struct intel_super *super, struct imsm_dev *dev, int failed)
|
||||||
{
|
{
|
||||||
struct imsm_map *map = get_imsm_map(dev, 0);
|
struct imsm_map *map = get_imsm_map(dev, 0);
|
||||||
|
@ -4478,6 +4523,24 @@ static int imsm_count_failed(struct intel_super *super, struct imsm_dev *dev)
|
||||||
return failed;
|
return failed;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifndef MDASSEMBLE
|
||||||
|
static int imsm_open_new(struct supertype *c, struct active_array *a,
|
||||||
|
char *inst)
|
||||||
|
{
|
||||||
|
struct intel_super *super = c->sb;
|
||||||
|
struct imsm_super *mpb = super->anchor;
|
||||||
|
|
||||||
|
if (atoi(inst) >= mpb->num_raid_devs) {
|
||||||
|
fprintf(stderr, "%s: subarry index %d, out of range\n",
|
||||||
|
__func__, atoi(inst));
|
||||||
|
return -ENODEV;
|
||||||
|
}
|
||||||
|
|
||||||
|
dprintf("imsm: open_new %s\n", inst);
|
||||||
|
a->info.container_member = atoi(inst);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
static int is_resyncing(struct imsm_dev *dev)
|
static int is_resyncing(struct imsm_dev *dev)
|
||||||
{
|
{
|
||||||
struct imsm_map *migr_map;
|
struct imsm_map *migr_map;
|
||||||
|
|
6
super0.c
6
super0.c
|
@ -922,7 +922,11 @@ static struct supertype *match_metadata_desc0(char *arg)
|
||||||
while (arg[0] == '0' && arg[1] == '0')
|
while (arg[0] == '0' && arg[1] == '0')
|
||||||
arg++;
|
arg++;
|
||||||
if (strcmp(arg, "0") == 0 ||
|
if (strcmp(arg, "0") == 0 ||
|
||||||
strcmp(arg, "0.90") == 0
|
#ifdef DEFAULT_OLD_METADATA /* ifndef in super1.c */
|
||||||
|
strcmp(arg, "default") == 0 ||
|
||||||
|
#endif /* DEFAULT_OLD_METADATA */
|
||||||
|
strcmp(arg, "0.90") == 0 ||
|
||||||
|
strcmp(arg, "") == 0 /* no metadata - i.e. non_persistent */
|
||||||
)
|
)
|
||||||
return st;
|
return st;
|
||||||
|
|
||||||
|
|
5
super1.c
5
super1.c
|
@ -1375,14 +1375,15 @@ static struct supertype *match_metadata_desc1(char *arg)
|
||||||
return st;
|
return st;
|
||||||
}
|
}
|
||||||
if (strcmp(arg, "1.1") == 0 ||
|
if (strcmp(arg, "1.1") == 0 ||
|
||||||
strcmp(arg, "1.01") == 0 ||
|
strcmp(arg, "1.01") == 0
|
||||||
strcmp(arg, "") == 0 /* no metadata */
|
|
||||||
) {
|
) {
|
||||||
st->minor_version = 1;
|
st->minor_version = 1;
|
||||||
return st;
|
return st;
|
||||||
}
|
}
|
||||||
if (strcmp(arg, "1.2") == 0 ||
|
if (strcmp(arg, "1.2") == 0 ||
|
||||||
|
#ifndef DEFAULT_OLD_METADATA /* ifdef in super0.c */
|
||||||
strcmp(arg, "default") == 0 ||
|
strcmp(arg, "default") == 0 ||
|
||||||
|
#endif /* DEFAULT_OLD_METADATA */
|
||||||
strcmp(arg, "1.02") == 0) {
|
strcmp(arg, "1.02") == 0) {
|
||||||
st->minor_version = 2;
|
st->minor_version = 2;
|
||||||
return st;
|
return st;
|
||||||
|
|
20
sysfs.c
20
sysfs.c
|
@ -273,22 +273,20 @@ struct mdinfo *sysfs_read(int fd, int devnum, unsigned long options)
|
||||||
|
|
||||||
strcpy(dbase, "block/dev");
|
strcpy(dbase, "block/dev");
|
||||||
if (load_sys(fname, buf)) {
|
if (load_sys(fname, buf)) {
|
||||||
|
/* assume this is a stale reference to a hot
|
||||||
|
* removed device
|
||||||
|
*/
|
||||||
free(dev);
|
free(dev);
|
||||||
if (options & SKIP_GONE_DEVS)
|
continue;
|
||||||
continue;
|
|
||||||
else
|
|
||||||
goto abort;
|
|
||||||
}
|
}
|
||||||
sscanf(buf, "%d:%d", &dev->disk.major, &dev->disk.minor);
|
sscanf(buf, "%d:%d", &dev->disk.major, &dev->disk.minor);
|
||||||
|
|
||||||
/* special case check for block devices that can go 'offline' */
|
/* special case check for block devices that can go 'offline' */
|
||||||
if (options & SKIP_GONE_DEVS) {
|
strcpy(dbase, "block/device/state");
|
||||||
strcpy(dbase, "block/device/state");
|
if (load_sys(fname, buf) == 0 &&
|
||||||
if (load_sys(fname, buf) == 0 &&
|
strncmp(buf, "offline", 7) == 0) {
|
||||||
strncmp(buf, "offline", 7) == 0) {
|
free(dev);
|
||||||
free(dev);
|
continue;
|
||||||
continue;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* finally add this disk to the array */
|
/* finally add this disk to the array */
|
||||||
|
|
6
util.c
6
util.c
|
@ -1669,7 +1669,11 @@ int mdmon_pid(int devnum)
|
||||||
char pid[10];
|
char pid[10];
|
||||||
int fd;
|
int fd;
|
||||||
int n;
|
int n;
|
||||||
sprintf(path, "%s/%s.pid", pid_dir, devnum2devname(devnum));
|
char *devname = devnum2devname(devnum);
|
||||||
|
|
||||||
|
sprintf(path, "%s/%s.pid", pid_dir, devname);
|
||||||
|
free(devname);
|
||||||
|
|
||||||
fd = open(path, O_RDONLY | O_NOATIME, 0);
|
fd = open(path, O_RDONLY | O_NOATIME, 0);
|
||||||
|
|
||||||
if (fd < 0)
|
if (fd < 0)
|
||||||
|
|
Loading…
Reference in New Issue