From 900968e382cdd2f1d3960b7d35064d46d1348517 Mon Sep 17 00:00:00 2001 From: Dan Williams Date: Mon, 10 Nov 2008 09:30:07 -0700 Subject: [PATCH 1/8] fix add_dev() handling of broken links Resolves issues like: mdadm -Ss mdadm: unable to open /dev/md/r1: No such file or directory ...where /dev/md/r1 points to a removed device. Signed-off-by: Dan Williams --- util.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/util.c b/util.c index a50036c..64100cf 100644 --- a/util.c +++ b/util.c @@ -433,8 +433,10 @@ int devlist_ready = 0; int add_dev(const char *name, const struct stat *stb, int flag, struct FTW *s) { struct stat st; + if (S_ISLNK(stb->st_mode)) { - stat(name, &st); + if (stat(name, &st) != 0) + return 0; stb = &st; } From 0e69da729dd75c3047f22230529d67563b6aeb59 Mon Sep 17 00:00:00 2001 From: NeilBrown Date: Fri, 28 Nov 2008 11:52:16 +1100 Subject: [PATCH 2/8] Fix typo in mdadm.conf.5 Debian Bug #506245 Signed-off-by: NeilBrown --- mdadm.conf.5 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/mdadm.conf.5 b/mdadm.conf.5 index 40295be..376b838 100644 --- a/mdadm.conf.5 +++ b/mdadm.conf.5 @@ -313,7 +313,7 @@ DEVICE /dev/sd[bcdjkl]1 .br DEVICE /dev/hda1 /dev/hdb1 -# /dev/md0 is known by its UID. +# /dev/md0 is known by its UUID. .br ARRAY /dev/md0 UUID=3aaa0122:29827cfa:5331ad66:ca767371 .br From ca01c83be52c55e34afe2a403873dc090e54553a Mon Sep 17 00:00:00 2001 From: NeilBrown Date: Fri, 28 Nov 2008 12:14:57 +1100 Subject: [PATCH 3/8] Release 2.6.8 --- ANNOUNCE-2.6.8 | 58 ++++++++++++++++++++++++++++++++++++++++++++++++++ ReadMe.c | 2 +- inventory | 2 ++ mdadm.8 | 2 +- mdadm.spec | 2 +- mdassemble.8 | 2 +- 6 files changed, 64 insertions(+), 4 deletions(-) create mode 100644 ANNOUNCE-2.6.8 diff --git a/ANNOUNCE-2.6.8 b/ANNOUNCE-2.6.8 new file mode 100644 index 0000000..55f484c --- /dev/null +++ b/ANNOUNCE-2.6.8 @@ -0,0 +1,58 @@ +Subject: ANNOUNCE: mdadm 2.6.8 - A tool for managing Soft RAID under Linux + +I am pleased to announce the availability of + mdadm version 2.6.8 + +It is available at the usual places: + countrycode=xx. + http://www.${countrycode}kernel.org/pub/linux/utils/raid/mdadm/ +and via git at + git://neil.brown.name/mdadm + http://neil.brown.name/git?p=mdadm + +mdadm is a tool for creating, managing and monitoring +device arrays using the "md" driver in Linux, also +known as Software RAID arrays. + +Release 2.6.8 contains various bug fixes and minor enhancements. +It is possibly that 2.6.8 will be the last release in the 2.x +series and very likely that there will never be a 2.7. +Hopefully 3.0 will be released soon making future development +of 2.6.x unnecessary. However if a need does arise for a 2.6.9 +it will be considered. + +Changelog Entries: + fix add_dev() handling of broken links + Assemble: allow --force to work even when event counts are 0. + mapfile: fix bug in testing for /var/run/mdadm/ + Incremental: change precedence order for autof setting. + Adjust major number testing to allow for extended minor number in 2.6.28 + Incremental: allow assembly of foreign array. + Incremental: fix setting of 'autof' flag. + Fix --incremental assembly of partitions arrays. + Fix NULL pointer oops + Fix bad metadata formatting + Allow WRITEMOSTLY to be cleared on --readd using --readwrite. + Remove .UR .UE macros from man page because the don't do what we want. + Grow: Fix linear-growth when devices are not all the same size. + Improve reporting of layout for raid10. + Manage: allow adding device that is just large enough to v1.x array. + Cosmetic cleanup of some messages. + Clean up usage of open() + Add support for distribution specific build extensions + Fix confusing usage in md.4 man page. + Describe the HOMEHOST entry in the mdadm.conf man page. + Some more cleanup of tests. + Add test for stoping and restarting a raid5 reshape. + Add "bitmap=" to "--detail --brief" output when relevant. + Improve error message when mdadm fails to stop an array. + Couple more man page fixes + Add text to man pages suggesting partition type to use for version 1.x metadata. + Italic/bold fixes in man pages. + Fix bug in forced assemble. + Fix an error when assembling arrays that are in the middle of a reshape. + +Development of mdadm is sponsored by + SUSE Labs, Novell Inc. + +NeilBrown 28th November 2008 diff --git a/ReadMe.c b/ReadMe.c index 0318894..88c4433 100644 --- a/ReadMe.c +++ b/ReadMe.c @@ -24,7 +24,7 @@ #include "mdadm.h" -char Version[] = Name " - v2.6.7 - 6th June 2008\n"; +char Version[] = Name " - v2.6.8 - 28th November 2008\n"; /* * File: ReadMe.c diff --git a/inventory b/inventory index 8c0a8d1..90f494d 100755 --- a/inventory +++ b/inventory @@ -22,6 +22,7 @@ ANNOUNCE-2.6.4 ANNOUNCE-2.6.5 ANNOUNCE-2.6.6 ANNOUNCE-2.6.7 +ANNOUNCE-2.6.8 Assemble.c bitmap.c bitmap.h @@ -120,6 +121,7 @@ tests/06update-uuid tests/06wrmostly tests/07autoassemble tests/07autodetect +tests/07reshape5intr tests/07testreshape5 tests/check tests/testdev diff --git a/mdadm.8 b/mdadm.8 index 054adda..56e6e95 100644 --- a/mdadm.8 +++ b/mdadm.8 @@ -5,7 +5,7 @@ .\" the Free Software Foundation; either version 2 of the License, or .\" (at your option) any later version. .\" See file COPYING in distribution for details. -.TH MDADM 8 "" v2.6.7 +.TH MDADM 8 "" v2.6.8 .SH NAME mdadm \- manage MD devices .I aka diff --git a/mdadm.spec b/mdadm.spec index 8e1a9bb..d682b40 100644 --- a/mdadm.spec +++ b/mdadm.spec @@ -1,6 +1,6 @@ Summary: mdadm is used for controlling Linux md devices (aka RAID arrays) Name: mdadm -Version: 2.6.7 +Version: 2.6.8 Release: 1 Source: http://www.kernel.org/pub/linux/utils/raid/mdadm/mdadm-%{version}.tgz URL: http://neil.brown.name/blog/mdadm diff --git a/mdassemble.8 b/mdassemble.8 index d60c775..1179244 100644 --- a/mdassemble.8 +++ b/mdassemble.8 @@ -1,5 +1,5 @@ .\" -*- nroff -*- -.TH MDASSEMBLE 8 "" v2.6.7 +.TH MDASSEMBLE 8 "" v2.6.8 .SH NAME mdassemble \- assemble MD devices .I aka From 504fb2e7f35884745d3f40ad037f42b4a515f33b Mon Sep 17 00:00:00 2001 From: NeilBrown Date: Thu, 18 Sep 2008 15:05:46 +1000 Subject: [PATCH 4/8] Allow --config in --incremental mode. --- mdadm.c | 1 + 1 file changed, 1 insertion(+) diff --git a/mdadm.c b/mdadm.c index af9627d..d680ea7 100644 --- a/mdadm.c +++ b/mdadm.c @@ -643,6 +643,7 @@ int main(int argc, char *argv[]) continue; case O(ASSEMBLE,'c'): /* config file */ + case O(INCREMENTAL, 'c'): case O(MISC, 'c'): case O(MONITOR,'c'): if (configfile) { From 22eba5121632c4b26541fbb04209a90b93c24bcc Mon Sep 17 00:00:00 2001 From: NeilBrown Date: Thu, 18 Dec 2008 14:04:45 +1100 Subject: [PATCH 5/8] Kill: Don't use O_EXCL when --force is used. We really want --zero-super --force to zero the superblock in all situations. So don't open with O_EXCL - trust the user. Signed-off-by: NeilBrown --- Kill.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Kill.c b/Kill.c index 0a2763e..b1e19b5 100644 --- a/Kill.c +++ b/Kill.c @@ -44,7 +44,7 @@ int Kill(char *dev, int force, int quiet) int fd, rv = 0; struct supertype *st; - fd = open(dev, O_RDWR|O_EXCL); + fd = open(dev, O_RDWR|(force ? 0 : O_EXCL)); if (fd < 0) { if (!quiet) fprintf(stderr, Name ": Couldn't open %s for write - not zeroing\n", From 4e9a6ff778cdc58dcc6897e74cf5ee1d3f73e1f7 Mon Sep 17 00:00:00 2001 From: NeilBrown Date: Thu, 18 Dec 2008 14:11:59 +1100 Subject: [PATCH 6/8] Assemble: don't assume array is 'clean' unless all devices think it is. This is only significant for --assemble --force where some old devices might be included into the array. If anything looks like it isn't clean, the kernel will not allow a degraded array to be started. Signed-off-by: NeilBrown --- Assemble.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/Assemble.c b/Assemble.c index 1d37870..3ee028b 100644 --- a/Assemble.c +++ b/Assemble.c @@ -749,6 +749,8 @@ int Assemble(struct supertype *st, char *mddev, int mdfd, continue; devices[j].i.disk.state = desired_state; + if (!(devices[j].i.array.state & 1)) + clean = 0; if (st->ss->update_super(st, &devices[j].i, "assemble", NULL, verbose, 0, NULL)) { From acee8e896406b686d4b4f12bb748352d20ef83a5 Mon Sep 17 00:00:00 2001 From: NeilBrown Date: Thu, 18 Dec 2008 14:24:41 +1100 Subject: [PATCH 7/8] Assemble: set stripe_cache_size properly when restarting a reshape. Reshape with large chunk size can require a large stripe_cache. We make this work when starting the reshape but not when restarting at assemble time. So fix that. Signed-off-by: NeilBrown --- Assemble.c | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/Assemble.c b/Assemble.c index 3ee028b..0cdeeda 100644 --- a/Assemble.c +++ b/Assemble.c @@ -934,6 +934,20 @@ int Assemble(struct supertype *st, char *mddev, int mdfd, fprintf(stderr, " and %d spare%s", sparecnt, sparecnt==1?"":"s"); fprintf(stderr, ".\n"); } + if (info.reshape_active && + info.array.level >= 4 && + info.array.level <= 6) { + /* might need to increase the size + * of the stripe cache - default is 256 + */ + if (256 < 4 * (info.array.chunk_size/4096)) { + struct mdinfo *sra = sysfs_read(mdfd, 0, 0); + if (sra) + sysfs_set_num(sra, NULL, + "stripe_cache_size", + (4 * info.array.chunk_size / 4096) + 1); + } + } if (must_close) { int usecs = 1; close(mdfd); From 3a56f223e94106102eed3fd2b08d3ecad353361b Mon Sep 17 00:00:00 2001 From: NeilBrown Date: Thu, 18 Dec 2008 16:23:46 +1100 Subject: [PATCH 8/8] map: rebuild map if it doesn't exist. It is possible for some arrays to be created e.g. by initrd, and so not get mentioned in /var/run/mdadm/map. As "-I" depends on things being listed in 'map', we create it by scanning all devices if it doesn't exist. Signed-off-by: NeilBrown --- Incremental.c | 47 --------------------------------------------- mapfile.c | 53 +++++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 53 insertions(+), 47 deletions(-) diff --git a/Incremental.c b/Incremental.c index 1d326fd..08e0e6f 100644 --- a/Incremental.c +++ b/Incremental.c @@ -603,53 +603,6 @@ static int count_active(struct supertype *st, int mdfd, char **availp, return cnt + cnt1; } -void RebuildMap(void) -{ - struct mdstat_ent *mdstat = mdstat_read(0, 0); - struct mdstat_ent *md; - struct map_ent *map = NULL; - int mdp = get_mdp_major(); - - for (md = mdstat ; md ; md = md->next) { - struct mdinfo *sra = sysfs_read(-1, md->devnum, GET_DEVS); - struct mdinfo *sd; - - for (sd = sra->devs ; sd ; sd = sd->next) { - char dn[30]; - int dfd; - int ok; - struct supertype *st; - char *path; - struct mdinfo info; - - sprintf(dn, "%d:%d", sd->disk.major, sd->disk.minor); - dfd = dev_open(dn, O_RDONLY); - if (dfd < 0) - continue; - st = guess_super(dfd); - if ( st == NULL) - ok = -1; - else - ok = st->ss->load_super(st, dfd, NULL); - close(dfd); - if (ok != 0) - continue; - st->ss->getinfo_super(st, &info); - if (md->devnum > 0) - path = map_dev(MD_MAJOR, md->devnum, 0); - else - path = map_dev(mdp, (-1-md->devnum)<< 6, 0); - map_add(&map, md->devnum, st->ss->major, - st->minor_version, - info.uuid, path ? : "/unknown"); - st->ss->free_super(st); - break; - } - } - map_write(map); - map_free(map); -} - int IncrementalScan(int verbose) { /* look at every device listed in the 'map' file. diff --git a/mapfile.c b/mapfile.c index f616f15..0d0aa39 100644 --- a/mapfile.c +++ b/mapfile.c @@ -111,6 +111,12 @@ void map_read(struct map_ent **melp) *melp = NULL; f = fopen("/var/run/mdadm/map", "r"); + if (!f) + f = fopen("/var/run/mdadm.map", "r"); + if (!f) { + RebuildMap(); + f = fopen("/var/run/mdadm/map", "r"); + } if (!f) f = fopen("/var/run/mdadm.map", "r"); if (!f) @@ -195,3 +201,50 @@ struct map_ent *map_by_uuid(struct map_ent **map, int uuid[4]) return NULL; } + +void RebuildMap(void) +{ + struct mdstat_ent *mdstat = mdstat_read(0, 0); + struct mdstat_ent *md; + struct map_ent *map = NULL; + int mdp = get_mdp_major(); + + for (md = mdstat ; md ; md = md->next) { + struct mdinfo *sra = sysfs_read(-1, md->devnum, GET_DEVS); + struct mdinfo *sd; + + for (sd = sra->devs ; sd ; sd = sd->next) { + char dn[30]; + int dfd; + int ok; + struct supertype *st; + char *path; + struct mdinfo info; + + sprintf(dn, "%d:%d", sd->disk.major, sd->disk.minor); + dfd = dev_open(dn, O_RDONLY); + if (dfd < 0) + continue; + st = guess_super(dfd); + if ( st == NULL) + ok = -1; + else + ok = st->ss->load_super(st, dfd, NULL); + close(dfd); + if (ok != 0) + continue; + st->ss->getinfo_super(st, &info); + if (md->devnum > 0) + path = map_dev(MD_MAJOR, md->devnum, 0); + else + path = map_dev(mdp, (-1-md->devnum)<< 6, 0); + map_add(&map, md->devnum, st->ss->major, + st->minor_version, + info.uuid, path ? : "/unknown"); + st->ss->free_super(st); + break; + } + } + map_write(map); + map_free(map); +}