From fd828476e8cd8765907d79a9f8b160bf3ea028e7 Mon Sep 17 00:00:00 2001 From: Doug Ledford Date: Tue, 3 Jul 2007 20:04:11 +0000 Subject: [PATCH] - Fix a file leak issue when mdadm is in monitor mode - Update mdadm init script so that status will always run and so return codes are standards compliant - Fix assembly of version 1 superblock devices - Make the attempt to create an already running device have a clearer error message - Allow the creation of a degraded raid4 array like we allow for raid5 - Make mdadm actually pay attention to raid4 devices when in monitor mode - Make the mdmonitor script use daemon() correctly - Fix a bug where manage mode would not add disks correctly under certain conditions - Resolves: bz244582, bz242688, bz230207, bz169596, bz171862, bz171938 - Resolves: bz174642, bz224272, bz186524 --- mdadm-2.6.2-assemble-ver1-superblock.patch | 80 ++++++++++++++++++++++ mdadm-2.6.2-create.patch | 26 +++++++ mdadm-2.6.2-file-leak.patch | 23 +++++++ mdadm-2.6.2-manage.patch | 50 ++++++++++++++ mdadm-2.6.2-raid4.patch | 53 ++++++++++++++ mdadm.spec | 28 +++++++- mdmonitor.init | 34 +++++---- 7 files changed, 278 insertions(+), 16 deletions(-) create mode 100644 mdadm-2.6.2-assemble-ver1-superblock.patch create mode 100644 mdadm-2.6.2-create.patch create mode 100644 mdadm-2.6.2-file-leak.patch create mode 100644 mdadm-2.6.2-manage.patch create mode 100644 mdadm-2.6.2-raid4.patch diff --git a/mdadm-2.6.2-assemble-ver1-superblock.patch b/mdadm-2.6.2-assemble-ver1-superblock.patch new file mode 100644 index 0000000..f8aa151 --- /dev/null +++ b/mdadm-2.6.2-assemble-ver1-superblock.patch @@ -0,0 +1,80 @@ +--- mdadm-2.6.2/super1.c.ver1 2007-05-21 00:25:40.000000000 -0400 ++++ mdadm-2.6.2/super1.c 2007-07-02 16:53:04.000000000 -0400 +@@ -152,9 +152,17 @@ static void examine_super1(void *sbv, ch + char *c; + int l = homehost ? strlen(homehost) : 0; + int layout; ++ unsigned long long sb_offset; + + printf(" Magic : %08x\n", __le32_to_cpu(sb->magic)); +- printf(" Version : %02d\n", 1); ++ printf(" Version : 1"); ++ sb_offset = __le64_to_cpu(sb->super_offset); ++ if (sb_offset <= 4) ++ printf(".1\n"); ++ else if (sb_offset <= 8) ++ printf(".2\n"); ++ else ++ printf(".0\n"); + printf(" Feature Map : 0x%x\n", __le32_to_cpu(sb->feature_map)); + printf(" Array UUID : "); + for (i=0; i<16; i++) { +@@ -337,6 +345,7 @@ static void brief_examine_super1(void *s + { + struct mdp_superblock_1 *sb = sbv; + int i; ++ unsigned long long sb_offset; + char *nm; + char *c=map_num(pers, __le32_to_cpu(sb->level)); + +@@ -348,9 +357,15 @@ static void brief_examine_super1(void *s + else + nm = "??"; + +- printf("ARRAY /dev/md/%s level=%s metadata=1 num-devices=%d UUID=", +- nm, +- c?c:"-unknown-", __le32_to_cpu(sb->raid_disks)); ++ printf("ARRAY /dev/md/%s level=%s ", nm, c?c:"-unknown-"); ++ sb_offset = __le64_to_cpu(sb->super_offset); ++ if (sb_offset <= 4) ++ printf("metadata=1.1 "); ++ else if (sb_offset <= 8) ++ printf("metadata=1.2 "); ++ else ++ printf("metadata=1.0 "); ++ printf("num-devices=%d UUID=", __le32_to_cpu(sb->raid_disks)); + for (i=0; i<16; i++) { + if ((i&3)==0 && i != 0) printf(":"); + printf("%02x", sb->set_uuid[i]); +@@ -975,7 +990,7 @@ static int load_super1(struct supertype + struct misc_dev_info *misc; + + +- if (st->ss == NULL) { ++ if (st->ss == NULL || st->minor_version == -1) { + int bestvers = -1; + __u64 bestctime = 0; + /* guess... choose latest ctime */ +@@ -1123,9 +1138,7 @@ static struct supertype *match_metadata_ + + st->ss = &super1; + st->max_devs = 384; +- if (strcmp(arg, "1") == 0 || +- strcmp(arg, "1.0") == 0 || +- strcmp(arg, "default/large") == 0) { ++ if (strcmp(arg, "1.0") == 0) { + st->minor_version = 0; + return st; + } +@@ -1137,6 +1150,11 @@ static struct supertype *match_metadata_ + st->minor_version = 2; + return st; + } ++ if (strcmp(arg, "1") == 0 || ++ strcmp(arg, "default/large") == 0) { ++ st->minor_version = -1; ++ return st; ++ } + + free(st); + return NULL; diff --git a/mdadm-2.6.2-create.patch b/mdadm-2.6.2-create.patch new file mode 100644 index 0000000..227c241 --- /dev/null +++ b/mdadm-2.6.2-create.patch @@ -0,0 +1,26 @@ +--- mdadm-2.6.2/Create.c.info 2007-07-03 10:18:38.000000000 -0400 ++++ mdadm-2.6.2/Create.c 2007-07-03 11:06:23.000000000 -0400 +@@ -81,6 +81,14 @@ int Create(struct supertype *st, char *m + if (vers < 9000) { + fprintf(stderr, Name ": Create requires md driver version 0.90.0 or later\n"); + return 1; ++ } else { ++ mdu_array_info_t inf; ++ memset(&inf, 0, sizeof(inf)); ++ ioctl(mdfd, GET_ARRAY_INFO, &inf); ++ if (inf.working_disks != 0) { ++ fprintf(stderr, Name ": another array by this name already running.\n"); ++ return 1; ++ } + } + if (level == UnSet) { + fprintf(stderr, +@@ -225,7 +233,7 @@ int Create(struct supertype *st, char *m + } + if (st->ss->major != 0 || + st->minor_version != 90) +- fprintf(stderr, Name ": Defaulting to verion %d.%d metadata\n", ++ fprintf(stderr, Name ": Defaulting to version %d.%d metadata\n", + st->ss->major, + st->minor_version); + } diff --git a/mdadm-2.6.2-file-leak.patch b/mdadm-2.6.2-file-leak.patch new file mode 100644 index 0000000..7ada947 --- /dev/null +++ b/mdadm-2.6.2-file-leak.patch @@ -0,0 +1,23 @@ +--- mdadm-2.6.2/mdstat.c.fileleak 2007-07-02 12:25:01.000000000 -0400 ++++ mdadm-2.6.2/mdstat.c 2007-07-02 12:25:04.000000000 -0400 +@@ -114,6 +114,8 @@ struct mdstat_ent *mdstat_read(int hold, + f = fopen("/proc/mdstat", "r"); + if (f == NULL) + return NULL; ++ else ++ fcntl(fileno(f), F_SETFD, FD_CLOEXEC); + + all = NULL; + end = &all; +@@ -221,8 +223,10 @@ struct mdstat_ent *mdstat_read(int hold, + end = &ent->next; + } + } +- if (hold && mdstat_fd == -1) ++ if (hold && mdstat_fd == -1) { + mdstat_fd = dup(fileno(f)); ++ fcntl(mdstat_fd, F_SETFD, FD_CLOEXEC); ++ } + fclose(f); + + /* If we might want to start array, diff --git a/mdadm-2.6.2-manage.patch b/mdadm-2.6.2-manage.patch new file mode 100644 index 0000000..ff69232 --- /dev/null +++ b/mdadm-2.6.2-manage.patch @@ -0,0 +1,50 @@ +--- mdadm-2.6.2/mdadm.h.manage 2007-07-03 15:37:10.000000000 -0400 ++++ mdadm-2.6.2/mdadm.h 2007-07-03 15:37:53.000000000 -0400 +@@ -155,6 +155,7 @@ enum mode { + }; + + extern char short_options[]; ++extern char short_bitmap_options[]; + extern char short_bitmap_auto_options[]; + extern struct option long_options[]; + extern char Version[], Usage[], Help[], OptionHelp[], +--- mdadm-2.6.2/mdadm.c.manage 2007-07-03 13:21:40.000000000 -0400 ++++ mdadm-2.6.2/mdadm.c 2007-07-03 15:35:54.000000000 -0400 +@@ -180,7 +180,7 @@ int main(int argc, char *argv[]) + switch(opt) { + case '@': /* just incase they say --manage */ + newmode = MANAGE; +- shortopt = short_bitmap_auto_options; ++ shortopt = short_bitmap_options; + break; + case 'a': + case 'r': +@@ -188,7 +188,7 @@ int main(int argc, char *argv[]) + case ReAdd: /* re-add */ + if (!mode) { + newmode = MANAGE; +- shortopt = short_bitmap_auto_options; ++ shortopt = short_bitmap_options; + } + break; + +@@ -196,7 +196,7 @@ int main(int argc, char *argv[]) + case 'B': newmode = BUILD; shortopt = short_bitmap_auto_options; break; + case 'C': newmode = CREATE; shortopt = short_bitmap_auto_options; break; + case 'F': newmode = MONITOR;break; +- case 'G': newmode = GROW; shortopt = short_bitmap_auto_options; break; ++ case 'G': newmode = GROW; shortopt = short_bitmap_options; break; + case 'I': newmode = INCREMENTAL; break; + case AutoDetect: + newmode = AUTODETECT; break; +--- mdadm-2.6.2/ReadMe.c.manage 2007-07-03 15:37:35.000000000 -0400 ++++ mdadm-2.6.2/ReadMe.c 2007-07-03 15:36:00.000000000 -0400 +@@ -87,6 +87,8 @@ char Version[] = Name " - v2.6.2 - 21st + */ + + char short_options[]="-ABCDEFGIQhVXWvqbc:i:l:p:m:n:x:u:c:d:z:U:sarfRSow1tye:"; ++char short_bitmap_options[]= ++ "-ABCDEFGIQhVXWvqb:c:i:l:p:m:n:x:u:c:d:z:U:sarfRSow1tye:"; + char short_bitmap_auto_options[]= + "-ABCDEFGIQhVXWvqb:c:i:l:p:m:n:x:u:c:d:z:U:sa:rfRSow1tye:"; + diff --git a/mdadm-2.6.2-raid4.patch b/mdadm-2.6.2-raid4.patch new file mode 100644 index 0000000..2205596 --- /dev/null +++ b/mdadm-2.6.2-raid4.patch @@ -0,0 +1,53 @@ +--- mdadm-2.6.2/Monitor.c.raid4 2007-07-03 12:10:34.000000000 -0400 ++++ mdadm-2.6.2/Monitor.c 2007-07-03 12:28:30.000000000 -0400 +@@ -244,8 +244,10 @@ int Monitor(mddev_dev_t devlist, + close(fd); + continue; + } +- if (array.level != 1 && array.level != 5 && array.level != -4 && +- array.level != 6 && array.level != 10) { ++ /* It's much easier to list what array levels can't ++ * have a device disappear than all of them that can ++ */ ++ if (array.level == 0 || array.level == -1) { + if (!st->err) + alert("DeviceDisappeared", dev, "Wrong-Level", + mailaddr, mailfrom, alert_cmd, dosyslog); +@@ -399,9 +401,8 @@ int Monitor(mddev_dev_t devlist, + struct mdstat_ent *mse; + for (mse=mdstat; mse; mse=mse->next) + if (mse->devnum != MAXINT && +- (strcmp(mse->level, "raid1")==0 || +- strcmp(mse->level, "raid5")==0 || +- strcmp(mse->level, "multipath")==0) ++ (strcmp(mse->level, "raid0")!=0 && ++ strcmp(mse->level, "linear")!=0) + ) { + struct state *st = malloc(sizeof *st); + mdu_array_info_t array; +--- mdadm-2.6.2/Create.c.raid4 2007-07-03 11:47:26.000000000 -0400 ++++ mdadm-2.6.2/Create.c 2007-07-03 11:47:26.000000000 -0400 +@@ -313,12 +313,13 @@ int Create(struct supertype *st, char *m + } + } + +- /* If this is raid5, we want to configure the last active slot ++ /* If this is raid4/5, we want to configure the last active slot + * as missing, so that a reconstruct happens (faster than re-parity) + * FIX: Can we do this for raid6 as well? + */ + if (assume_clean==0 && force == 0 && first_missing >= raiddisks) { + switch ( level ) { ++ case 4: + case 5: + insert_point = raiddisks-1; + sparedisks++; +@@ -343,7 +344,7 @@ int Create(struct supertype *st, char *m + array.md_minor = minor(stb.st_rdev); + array.not_persistent = 0; + /*** FIX: Need to do something about RAID-6 here ***/ +- if ( ( (level == 5) && ++ if ( ( (level == 4 || level == 5) && + (insert_point < raiddisks || first_missing < raiddisks) ) + || + ( level == 6 && missing_disks == 2) diff --git a/mdadm.spec b/mdadm.spec index 453cd98..26a7941 100644 --- a/mdadm.spec +++ b/mdadm.spec @@ -1,7 +1,7 @@ Summary: The mdadm program controls Linux md devices (software RAID arrays) Name: mdadm Version: 2.6.2 -Release: 1%{?dist} +Release: 2%{?dist} Source: http://www.cse.unsw.edu.au/~neilb/source/mdadm/mdadm-%{version}.tgz Source1: mdmonitor.init Patch1: mdadm-2.5.2-s390-build.patch @@ -9,6 +9,11 @@ Patch2: mdadm-2.5.2-static.patch Patch3: mdadm-2.2-nodiet.patch Patch4: mdadm-2.5.2-cflags.patch Patch5: mdadm-2.6.1-build.patch +Patch6: mdadm-2.6.2-file-leak.patch +Patch7: mdadm-2.6.2-assemble-ver1-superblock.patch +Patch8: mdadm-2.6.2-create.patch +Patch9: mdadm-2.6.2-raid4.patch +Patch10: mdadm-2.6.2-manage.patch URL: http://www.cse.unsw.edu.au/~neilb/source/mdadm/ License: GPL Group: System Environment/Base @@ -32,6 +37,11 @@ file can be used to help with some common tasks. %patch3 -p1 -b .nodiet %patch4 -p1 -b .cflags %patch5 -p1 -b .build +%patch6 -p1 -b .leak +%patch7 -p1 -b .ver1 +%patch8 -p1 -b .create +%patch9 -p1 -b .raid4 +%patch10 -p1 -b .manage %build make %{?_smp_mflags} CXFLAGS="$RPM_OPT_FLAGS" SYSCONFDIR="%{_sysconfdir}" MDASSEMBLE_AUTO=1 mdassemble.static mdassemble mdadm.static mdadm @@ -79,6 +89,21 @@ fi %attr(0700,root,root) %dir /var/run/mdadm %changelog +* Mon Jul 02 2007 Doug Ledford - 2.6.2-2 +- Fix a file leak issue when mdadm is in monitor mode +- Update mdadm init script so that status will always run and so + return codes are standards compliant +- Fix assembly of version 1 superblock devices +- Make the attempt to create an already running device have a clearer + error message +- Allow the creation of a degraded raid4 array like we allow for raid5 +- Make mdadm actually pay attention to raid4 devices when in monitor mode +- Make the mdmonitor script use daemon() correctly +- Fix a bug where manage mode would not add disks correctly under certain + conditions +- Resolves: bz244582, bz242688, bz230207, bz169596, bz171862, bz171938 +- Resolves: bz174642, bz224272, bz186524 + * Mon Jul 02 2007 Doug Ledford - 2.6.2-1 - Update to latest upstream - Remove requirement for /usr/sbin/sendmail - it's optional and not on by @@ -101,6 +126,7 @@ fi * Sat Mar 31 2007 Doug Ledford - 2.6.1-1 - Update to latest upstream version +- Resolves: bz233422 * Fri Jan 26 2007 Doug Ledford - 2.6-1 - Update to latest upstream version diff --git a/mdmonitor.init b/mdmonitor.init index 2897d20..7b35798 100755 --- a/mdmonitor.init +++ b/mdmonitor.init @@ -10,20 +10,16 @@ # Copyright 2002 Red Hat, Inc. +PIDFILE=/var/run/mdadm/mdadm.pid PATH=/sbin:/usr/sbin:$PATH RETVAL=0 -OPTIONS="--monitor --scan -f --pid-file=/var/run/mdadm/mdadm.pid" +OPTIONS="--monitor --scan -f --pid-file=$PIDFILE" prog=mdmonitor # Source function library. . /etc/rc.d/init.d/functions -# Make sure configuration file exists and has information we can use -# MAILADDR or PROGRAM or both must be set in order to run mdadm --monitor -[ -f /etc/mdadm.conf ] || exit 0 -grep '^\(MAILADDR\|PROGRAM\) .' /etc/mdadm.conf >/dev/null 2>&1 || exit 0 - usage () { @@ -34,8 +30,15 @@ usage () start () { +# Make sure configuration file exists and has information we can use +# MAILADDR or PROGRAM or both must be set in order to run mdadm --monitor + [ -f /etc/mdadm.conf ] || return 6 + grep '^\(MAILADDR\|PROGRAM\) .' /etc/mdadm.conf >/dev/null 2>&1 || return 6 + if [ -f "$PIDFILE" ]; then + checkpid `cat $PIDFILE` && return 0 + fi echo -n $"Starting $prog: " - daemon --check --user=root mdadm ${OPTIONS} + daemon --user=root mdadm ${OPTIONS} ret=$? [ $ret -eq "0" ] && touch /var/lock/subsys/$prog echo @@ -44,7 +47,7 @@ start () stop () { - [ -f /var/lock/subsys/$prog ] || return 0 + [ -f /var/lock/subsys/$prog ] || return 7 echo -n "Killing $prog: " killproc mdadm echo @@ -59,17 +62,18 @@ restart () condrestart () { - [ -e /var/lock/subsys/$prog ] && restart + [ -e /var/lock/subsys/$prog ] && restart || return 0 } case "$1" in - start) start ;; - stop) stop ;; - status) status mdadm ;; - restart|reload) restart ;; - condrestart) condrestart ;; - *) usage ;; + start) start; RETVAL=$? ;; + stop) stop; RETVAL=$? ;; + status) status mdadm; RETVAL=$? ;; + restart) restart; RETVAL=$? ;; + reload) RETVAL=3 ;; + condrestart) condrestart; RETVAL=$? ;; + *) usage ; RETVAL=2 ;; esac exit $RETVAL