From 4f09ed47aee9d5896a7bbf29e629186e5ce0f28962f2fa1e5e6033eac7c2dcf5 Mon Sep 17 00:00:00 2001 From: OBS User autobuild Date: Tue, 29 Jun 2010 14:43:02 +0000 Subject: [PATCH] Accepting request 42186 from Base:System Copy from Base:System/mdadm based on submit request 42186 from user michal-m OBS-URL: https://build.opensuse.org/request/show/42186 OBS-URL: https://build.opensuse.org/package/show/openSUSE:Factory/mdadm?expand=0&rev=43 --- IMSM-part.patch | 63 ++++++++++++++ bitmap-4k-boundary.patch | 40 +++++++++ container-argv-check | 32 +++++++ fix-dup.patch | 142 +++++++++++++++++++++++++++++++ mdadm.changes | 38 +++++++++ mdadm.spec | 12 ++- mdmon-0.9-superblock-crash.patch | 22 +++++ mkinitrd-boot.sh | 101 ++++++++++++++++------ 8 files changed, 422 insertions(+), 28 deletions(-) create mode 100644 IMSM-part.patch create mode 100644 bitmap-4k-boundary.patch create mode 100644 container-argv-check create mode 100644 fix-dup.patch create mode 100644 mdmon-0.9-superblock-crash.patch diff --git a/IMSM-part.patch b/IMSM-part.patch new file mode 100644 index 0000000..02cb68b --- /dev/null +++ b/IMSM-part.patch @@ -0,0 +1,63 @@ +--- + mdadm.h | 1 + + super-intel.c | 4 ++++ + util.c | 25 +++++++++++++++++++++++++ + 3 files changed, 30 insertions(+) + +--- mdadm-3.0.3.orig/mdadm.h ++++ mdadm-3.0.3/mdadm.h +@@ -820,6 +820,7 @@ extern int enough(int level, int raid_di + extern int ask(char *mesg); + extern unsigned long long get_component_size(int fd); + extern void remove_partitions(int fd); ++extern int test_partition(int fd); + extern unsigned long long calc_array_size(int level, int raid_disks, int layout, + int chunksize, unsigned long long devsize); + extern int flush_metadata_updates(struct supertype *st); +--- mdadm-3.0.3.orig/super-intel.c ++++ mdadm-3.0.3/super-intel.c +@@ -2582,6 +2582,10 @@ static int load_super_imsm(struct supert + return 0; + #endif + ++ if (test_partition(fd)) ++ /* IMSM not allowed on partitions */ ++ return 1; ++ + free_super_imsm(st); + + super = alloc_super(0); +--- mdadm-3.0.3.orig/util.c ++++ mdadm-3.0.3/util.c +@@ -168,6 +168,31 @@ void remove_partitions(int fd) + #endif + } + ++int test_partition(int fd) ++{ ++ /* Check if fd is a whole-disk or a partition. ++ * BLKPG will return EINVAL on a partition, and BLKPG_DEL_PARTITION ++ * will return ENXIO on an invalid partition number. ++ */ ++ struct blkpg_ioctl_arg a; ++ struct blkpg_partition p; ++ a.op = BLKPG_DEL_PARTITION; ++ a.data = (void*)&p; ++ a.datalen = sizeof(p); ++ a.flags = 0; ++ memset(a.data, 0, a.datalen); ++ p.pno = 1<<30; ++ if (ioctl(fd, BLKPG, &a) == 0) ++ /* Very unlikely, but not a partition */ ++ return 0; ++ if (errno == ENXIO) ++ /* not a partition */ ++ return 0; ++ ++ return 1; ++} ++ ++ + int enough(int level, int raid_disks, int layout, int clean, + char *avail, int avail_disks) + { diff --git a/bitmap-4k-boundary.patch b/bitmap-4k-boundary.patch new file mode 100644 index 0000000..7b3734f --- /dev/null +++ b/bitmap-4k-boundary.patch @@ -0,0 +1,40 @@ +From: NeilBrown + +Some devices (dasd!) have 4K sectors, so metadata must be +aligned on 4K boundaries. +superblock already is, but bitmap might not be. So force the +bitmap to a 4K boundary for v1.x metadata +It already is for v1.1 and v1.2, so just fix for v1.0 + +(Note that v0.90 already uses a 4K boundary too). + +Signed-off-by: NeilBrown + +diff --git a/super1.c b/super1.c +index fee22a9..66e9771 100644 +--- a/super1.c ++++ b/super1.c +@@ -1437,11 +1437,6 @@ add_internal_bitmap1(struct supertype *st, + */ + offset = 0; + room = choose_bm_space(__le64_to_cpu(sb->size)); +- if (room == 4*2) { +- /* make it 3K after the superblock */ +- room = 3*2; +- offset = 2; +- } + } else { + room = __le64_to_cpu(sb->super_offset) + - __le64_to_cpu(sb->data_offset) +@@ -1498,8 +1493,9 @@ add_internal_bitmap1(struct supertype *st, + + if (offset == 0) { + bits = (size*512) / chunk + 1; +- room = ((bits+7)/8 + sizeof(bitmap_super_t) +511)/512; +- offset = -room; ++ /* Align bitmap space to a 4K boundary as some devices need that */ ++ room = ((bits+7)/8 + sizeof(bitmap_super_t) +4095)/4096; ++ offset = -room * 8; /* *8 to convert 4K blocks to sectors */ + } + + sb->bitmap_offset = __cpu_to_le32(offset); diff --git a/container-argv-check b/container-argv-check new file mode 100644 index 0000000..b37c87e --- /dev/null +++ b/container-argv-check @@ -0,0 +1,32 @@ +From 4c1c3ad8cf69763a4c8c4ba692a8cb93327a4abf Mon Sep 17 00:00:00 2001 +From: NeilBrown +Date: Wed, 24 Feb 2010 11:43:59 +1100 +Subject: [PATCH] Assemble: check inargv before complaining about stray arguments. +References: bnc#598827 + +If --assemble is given a container and some other devices to assemble +an array from, it complains with an error because that doesn't make +sense. +However it currently also complains if the list of devices was extract +from the config file rather than being given on the command line. +That is not appropriate. + +So add an '&& inargv' test to ensure that we are really complaining +about the right thing. + +Signed-off-by: NeilBrown +Acked-by: Dan Williams + +diff --git a/Assemble.c b/Assemble.c +index e4d6181..23cc438 100644 +--- a/Assemble.c ++++ b/Assemble.c +@@ -434,7 +434,7 @@ int Assemble(struct supertype *st, char *mddev, + } + } + st = tst; tst = NULL; +- if (!auto_assem && tmpdev->next != NULL) { ++ if (!auto_assem && inargv && tmpdev->next != NULL) { + fprintf(stderr, Name ": %s is a container, but is not " + "only device given: confused and aborting\n", + devname); diff --git a/fix-dup.patch b/fix-dup.patch new file mode 100644 index 0000000..743f748 --- /dev/null +++ b/fix-dup.patch @@ -0,0 +1,142 @@ +From: Dan Williams +References: bnc#587925 +Subject: Create: cleanup after failed create in duplicated array member case + + +mdadm prevents creation when device names are duplicated on the command +line, but leaves the partially created array intact. Detect this case +in the error code from add_to_super() and cleanup the partially created +array. The imsm handler is updated to report this conflict in +add_to_super_imsm_volume(). + +Note that since neither mdmon, nor userspace for that matter, ever saw an +active array we only need to perform a subset of the cleanup actions. +So call ioctl(STOP_ARRAY) directly and arrange for Create() to cleanup +the map file rather than calling Manage_runstop(). + +Reported-by: Krzysztof Wojcik +Signed-off-by: Dan Williams +--- + + Create.c | 10 ++++++++-- + Manage.c | 8 +++----- + mapfile.c | 10 ++++++++++ + mdadm.h | 1 + + super-intel.c | 11 ++++++++++- + 5 files changed, 32 insertions(+), 8 deletions(-) + + +--- mdadm-3.0.3.orig/Create.c ++++ mdadm-3.0.3/Create.c +@@ -755,8 +755,10 @@ int Create(struct supertype *st, char *m + if (fd >= 0) + remove_partitions(fd); + if (st->ss->add_to_super(st, &inf->disk, +- fd, dv->devname)) ++ fd, dv->devname)) { ++ ioctl(mdfd, STOP_ARRAY, NULL); + goto abort; ++ } + st->ss->getinfo_super(st, inf); + safe_mode_delay = inf->safe_mode_delay; + +@@ -860,7 +862,7 @@ int Create(struct supertype *st, char *m + if (ioctl(mdfd, RUN_ARRAY, ¶m)) { + fprintf(stderr, Name ": RUN_ARRAY failed: %s\n", + strerror(errno)); +- Manage_runstop(mddev, mdfd, -1, 0); ++ ioctl(mdfd, STOP_ARRAY, NULL); + goto abort; + } + } +@@ -881,6 +883,10 @@ int Create(struct supertype *st, char *m + return 0; + + abort: ++ map_lock(&map); ++ map_remove(&map, fd2devnum(mdfd)); ++ map_unlock(&map); ++ + if (mdfd >= 0) + close(mdfd); + return 1; +--- mdadm-3.0.3.orig/Manage.c ++++ mdadm-3.0.3/Manage.c +@@ -277,11 +277,9 @@ int Manage_runstop(char *devname, int fd + + if (quiet <= 0) + fprintf(stderr, Name ": stopped %s\n", devname); +- if (devnum != NoMdDev) { +- map_delete(&map, devnum); +- map_write(map); +- map_free(map); +- } ++ map_lock(&map); ++ map_remove(&map, devnum); ++ map_unlock(&map); + } + return 0; + } +--- mdadm-3.0.3.orig/mapfile.c ++++ mdadm-3.0.3/mapfile.c +@@ -239,6 +239,16 @@ void map_delete(struct map_ent **mapp, i + } + } + ++void map_remove(struct map_ent **mapp, int devnum) ++{ ++ if (devnum == NoMdDev) ++ return; ++ ++ map_delete(mapp, devnum); ++ map_write(*mapp); ++ map_free(*mapp); ++} ++ + struct map_ent *map_by_uuid(struct map_ent **map, int uuid[4]) + { + struct map_ent *mp; +--- mdadm-3.0.3.orig/mdadm.h ++++ mdadm-3.0.3/mdadm.h +@@ -324,6 +324,7 @@ struct map_ent { + }; + extern int map_update(struct map_ent **mpp, int devnum, char *metadata, + int uuid[4], char *path); ++extern void map_remove(struct map_ent **map, int devnum); + extern struct map_ent *map_by_uuid(struct map_ent **map, int uuid[4]); + extern struct map_ent *map_by_devnum(struct map_ent **map, int devnum); + extern struct map_ent *map_by_name(struct map_ent **map, char *name); +--- mdadm-3.0.3.orig/super-intel.c ++++ mdadm-3.0.3/super-intel.c +@@ -2817,7 +2817,7 @@ static int init_super_imsm_volume(struct + map->num_members = info->raid_disks; + for (i = 0; i < map->num_members; i++) { + /* initialized in add_to_super */ +- set_imsm_ord_tbl_ent(map, i, 0); ++ set_imsm_ord_tbl_ent(map, i, IMSM_ORD_REBUILD); + } + mpb->num_raid_devs++; + +@@ -2895,6 +2895,7 @@ static int add_to_super_imsm_volume(stru + struct dl *dl; + struct imsm_dev *dev; + struct imsm_map *map; ++ int slot; + + dev = get_imsm_dev(super, super->current_vol); + map = get_imsm_map(dev, 0); +@@ -2929,6 +2930,14 @@ static int add_to_super_imsm_volume(stru + dl->index = super->anchor->num_disks; + super->anchor->num_disks++; + } ++ /* Check the device has not already been added */ ++ slot = get_imsm_disk_slot(map, dl->index); ++ if (slot >= 0 && ++ (get_imsm_ord_tbl_ent(dev, slot) & IMSM_ORD_REBUILD) == 0) { ++ fprintf(stderr, Name ": %s has been included in this array twice\n", ++ devname); ++ return 1; ++ } + set_imsm_ord_tbl_ent(map, dk->number, dl->index); + dl->disk.status = CONFIGURED_DISK; + diff --git a/mdadm.changes b/mdadm.changes index c6cf9b6..0a99039 100644 --- a/mdadm.changes +++ b/mdadm.changes @@ -3,6 +3,32 @@ Tue Jun 1 15:09:53 CEST 2010 - mmarek@suse.cz - mkinitrd-setup.sh: Fix for empty $md_devs variable. +------------------------------------------------------------------- +Fri Apr 23 10:57:57 UTC 2010 - nfbrown@novell.com + +- IMSM-part.patch - never try to include partitions in an + IMSM array - bnc#597787 +- container-argv-check - avoid incorrect error message when + assembling multiple containers - bnc#598827 + +------------------------------------------------------------------- +Thu Apr 22 15:04:30 CEST 2010 - mmarek@suse.cz + +- mkinitrd-boot.sh: Fix booting with root=/dev/disk/by-id/md-uuid*, + run mdadm -v when linuxrc=trace is given (bnc#597787). + +------------------------------------------------------------------- +Mon Apr 19 05:36:23 UTC 2010 - nfbrown@novell.com + +- fix-dup.patch: revised version to make sure partial + device is destroyed properly (bnc#587925). + +------------------------------------------------------------------- +Fri Mar 26 16:00:05 CET 2010 - mmarek@suse.cz + +- fix-dup.patch: catch attempts to add the same disk twice + (bnc#587925). + ------------------------------------------------------------------- Wed Mar 24 17:37:27 CET 2010 - mmarek@suse.cz @@ -16,6 +42,12 @@ Tue Mar 23 14:49:38 CET 2010 - mmarek@suse.cz option doesn't directly refer to md (bnc#589676, bnc#586837, bnc#583424). +------------------------------------------------------------------- +Mon Mar 22 16:30:11 CET 2010 - mmarek@suse.cz + +- mdmon: Fix crash if /proc/mdstat lists 0.9 superblocks + (bnc#589447). + ------------------------------------------------------------------- Thu Mar 11 10:18:18 CET 2010 - mmarek@suse.cz @@ -38,6 +70,12 @@ Mon Feb 22 15:14:03 CET 2010 - mmarek@suse.cz - mkinitrd-setup.sh: call mdadm --scan only if necessary (bnc#581769). +------------------------------------------------------------------- +Fri Feb 19 12:10:11 CET 2010 - mmarek@suse.cz + +- bitmap-4k-boundary.patch: Alling the internal bitmap on 4K + boundary (bnc#577468). + Fri Jan 15 17:37:26 CET 2010 - mmarek@suse.cz - fix modprobe invocation in boot.md (bnc#565293). diff --git a/mdadm.spec b/mdadm.spec index 94b0595..b74ff1f 100644 --- a/mdadm.spec +++ b/mdadm.spec @@ -20,7 +20,7 @@ Name: mdadm Version: 3.0.3 -Release: 6 +Release: 7 BuildRequires: sgmltool PreReq: %fillup_prereq %insserv_prereq Obsoletes: raidtools @@ -38,6 +38,11 @@ Source4: boot.md Source5: mkinitrd-setup.sh Source6: mkinitrd-boot.sh Source7: 64-md-raid.rules +Patch1: bitmap-4k-boundary.patch +Patch2: mdmon-0.9-superblock-crash.patch +Patch3: fix-dup.patch +Patch4: IMSM-part.patch +Patch5: container-argv-check %description Mdadm is a program that can be used to control Linux md devices. It is @@ -52,6 +57,11 @@ Authors: %prep %setup -q -a1 +%patch1 -p1 +%patch2 -p1 +%patch3 -p1 +%patch4 -p1 +%patch5 -p1 %build %{suse_update_config -f} diff --git a/mdmon-0.9-superblock-crash.patch b/mdmon-0.9-superblock-crash.patch new file mode 100644 index 0000000..9945cee --- /dev/null +++ b/mdmon-0.9-superblock-crash.patch @@ -0,0 +1,22 @@ +From c4dc5c0aa7aa412bf85f0f6d646ea0c307eb4591 Mon Sep 17 00:00:00 2001 +From: Michal Marek +Date: Fri, 19 Mar 2010 11:59:20 +0100 +Subject: [PATCH] mdmon: Fix crash if /proc/mdstat lists 0.9 superblocks + +Signed-off-by: Michal Marek +--- + mdmon.c | 3 ++- + 1 file changed, 2 insertions(+), 1 deletion(-) + +--- mdadm-3.0.3.orig/mdmon.c ++++ mdadm-3.0.3/mdmon.c +@@ -313,7 +313,8 @@ int main(int argc, char *argv[]) + scan = 1; + mdstat = mdstat_read(0, 0); + for (e = mdstat; e; e = e->next) { +- if (strncmp(e->metadata_version, "external:", 9) == 0 && ++ if (e->metadata_version && ++ strncmp(e->metadata_version, "external:", 9) == 0 && + !is_subarray(&e->metadata_version[9])) { + devname = devnum2devname(e->devnum); + /* update cmdline so this mdmon instance can be diff --git a/mkinitrd-boot.sh b/mkinitrd-boot.sh index 5bfe0c5..01fddbd 100644 --- a/mkinitrd-boot.sh +++ b/mkinitrd-boot.sh @@ -12,7 +12,6 @@ ## ----------------------- ## ## need_mdadm=1 use MD raid -## md_uuid the uuid of the raid to activate ## # load the necessary module before we initialize the raid system @@ -38,9 +37,38 @@ if [ -f /sys/module/md_mod/parameters/start_ro ]; then echo 1 > /sys/module/md_mod/parameters/start_ro fi +if test -n "$debug_linuxrc"; then + mdadm="mdadm -v" +else + mdadm="mdadm" +fi + +# uuid -> array name +get_md_name() +{ + local uuid=$1 res + + if ! test -f /etc/mdadm.conf; then + return 1 + fi + res=$(sed -rn "s/^ARRAY +([^ ]+).* UUID=$uuid.*/\1/p" /etc/mdadm.conf) + case "$res" in + "" | \<* | *=*) + return 1 + ;; + /*) + echo "$res" + ;; + *) + echo "/dev/md/$res" + ;; + esac + return 0 +} + md_assemble() { - local dev=$1 mdconf container + local dev=$1 uuid mdconf container container_name if test -e "$dev"; then return @@ -48,12 +76,27 @@ md_assemble() case "$dev" in /dev/md[0-9]*p[0-9]*) dev=${dev%p[0-9]*} + ;; + /dev/md*) + ;; + /dev/disk/by-id/md-uuid-*) + uuid=${dev#/dev/disk/by-id/md-uuid-} + uuid=${uuid%-part*} + dev= + ;; + *) + return esac if test -f /etc/mdadm.conf; then mdconf="-c /etc/mdadm.conf" - container=$( \ - sed -rn "s:^ARRAY +$dev .*container=([^ ]*).*:\\1:p" \ - /etc/mdadm.conf) + local line + if test -n "$dev"; then + line=$(sed -rn "\:^ARRAY +$dev :p" /etc/mdadm.conf) + else + line=$(sed -rn "/^ARRAY .* UUID=$uuid/p" /etc/mdadm.conf) + fi + container=$(echo "$line" | \ + sed -rn 's/.* container=([^ ]*).*/\1/p') else mdconf="-c partitions" fi @@ -61,34 +104,38 @@ md_assemble() "") ;; /dev/*) - mdadm -A $mdconf $container + $mdadm -A $mdconf $container ;; [0-9a-f]*[0-9a-f]) - mdadm -A $mdconf --uuid="$container" /dev/md/container + container_name=$(get_md_name "$container") + if test -z "$container_name"; then + container_name=/dev/md/container + fi + $mdadm -A $mdconf --uuid="$container" "$container_name" ;; *) echo "unrecognized container for $dev: $container" - ;; esac - mdadm -A $mdconf $mdarg "$dev" + if test -n "$dev"; then + $mdadm -A $mdconf "$dev" + else + dev=$(get_md_name "$uuid") + if test -z "$dev"; then + # fallback + dev=/dev/md0 + fi + $mdadm -A $mdconf --uuid=$uuid "$dev" + fi } -if [ -n "$need_mdadm" ]; then - - if [ -n "$md_uuid" ] ; then - mdarg="--uuid=$md_uuid" - fi - - case $resumedev in - /dev/md*) - md_assemble "$resumedev" - esac - - if [ -n "$md_dev" ] ; then - md_assemble "$md_dev" - fi - for dev in $md_devs; do - md_assemble "$dev" - done - wait_for_events +md_assemble "$resumedev" +md_assemble "$rootdev" +if [ -n "$md_dev" ] ; then + md_assemble "$md_dev" fi +# assemble any md devices seen by setup-md.sh at initrd build time +for dev in $md_devs; do + md_assemble "$dev" +done + +wait_for_events