diff --git a/srcpkgs/dmraid/dmraid.rshlibs b/srcpkgs/dmraid/dmraid.rshlibs new file mode 100644 index 0000000000..3355432811 --- /dev/null +++ b/srcpkgs/dmraid/dmraid.rshlibs @@ -0,0 +1,5 @@ +libdevmapper-event.so.1.02 +libdevmapper.so.1.02 +libdl.so.2 +libc.so.6 +libpthread.so.0 diff --git a/srcpkgs/dmraid/files/dmraid-activate b/srcpkgs/dmraid/files/dmraid-activate new file mode 100644 index 0000000000..f4202896e1 --- /dev/null +++ b/srcpkgs/dmraid/files/dmraid-activate @@ -0,0 +1,291 @@ +#!/bin/sh +# +# dmraid-activate: Script to reformat the output of dmraid to be useful with +# udev. +# +# (c) 2008 Canonical Ltd. +# +# 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., +# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + +# Arguments: $1 = Name of array you want activated. +activate_array () +{ + Raid_Setinfo=$(dmraid -i -si "$1") + if [ -z "$Raid_Setinfo" ]; then + log_error "Cannot retrieve RAID set information for $1" + return 1 + fi + + Raid_Type=$(dmraid -i -si -ct "$1") + Raid_Nodevs=$(dmraid -i -si -cd "$1") + + case "$Raid_Type" in + stripe) + if [ "$Raid_Nodevs" -lt 2 ]; then + if [ -n "$Degraded" ]; then + log_error "Cannot bring up a RAID0 array in degraded mode, not all devices present." + fi + return 2 + fi + ;; + mirror) + if [ "$Raid_Nodevs" -lt 2 ]; then + if [ -z "$Degraded" ]; then + log_error "Raid set $Raid_Name is degraded. Not activating" + return 2 + else + log_warning "Activating $Raid_Name in degraded mode" + Return_Val=3 + fi + fi + ;; + raid5_*) + modprobe -q dm_raid45 + if [ "$Raid_Nodevs" -lt 3 ]; then + if [ -z "$Degraded" ]; then + log_error "Raid set $Raid_Name is degraded. Not activating" + return 2 + else + log_warning "Activating $Raid_Name in degraded mode" + Return_Val=3 + fi + fi + ;; + esac + + # At this point we have the required number of devs, or the user wants the + # array brought up in degraded mode, except in the case of striped arrays. + # We need to know the root device for determining if the -Z flag can be used + # (see #533848 and LP: 392510) + if [ -z "$ROOT" ]; then + for x in $(cat /proc/cmdline); do + case $x in + root=*) + ROOT=${x#root=} + ;; + esac + done + case "$ROOT" in + LABEL=*) + ROOT=$(readlink -f /dev/disk/by-uuid/${ROOT#LABEL=}) + ;; + UUID=*) + ROOT=$(readlink -f /dev/disk/by-uuid/${ROOT#UUID=}) + ;; + esac + else + ROOT=$(readlink -f $ROOT) + fi + + if (echo $ROOT | grep -q $1) ; then + dmraid -i -ay -Z "$1" + else + dmraid -i -ay "$1" + fi + + return $Return_Val +} + +log_warning() +{ + if type logger > /dev/null ; then + logger -t dmraid-activate "WARNING: $1" + else + echo "dmraid-activate: WARNING: $1" + fi +} + +log_error() +{ + if type logger > /dev/null ; then + logger -t dmraid-activate "ERROR: $1" + else + echo "dmraid-activate: ERROR: $1" + fi +} + +ddf1_virtual_drive_names() +{ + ddf1_awk_script="$(cat <<'EOF' +BEGIN { + section = "" + disk_ref = "" + guid_i = 0 + + # Heximal to decimal conversion array + for (i = 0; i <= 9; i++) hex2dec[i] = i + hex2dec["a"] = 10; hex2dec["b"] = 11; hex2dec["c"] = 12 + hex2dec["e"] = 13; hex2dec["d"] = 14; hex2dec["f"] = 15; +} + +function section_begins(name) +{ + section = name + vd_guid = "" + drive_map = 0 +} + +function extract_vd_guid(line, g) +{ + g = substr(line, match(line,/\[[0-9a-f ]+\]$/)+1, RLENGTH-2) + gsub(/ /, "", g) + # IF LSI, do timestamp substitution to get persistent name, see + # 19_ddf1_lsi_persistent_name.patch + if (g ~ /^4c5349/) + g = substr(g, 1, 32) "47114711" substr(g, 41) + return g +} + +function extract_vd_name(line, hex, n, max, i, d1, d2, sed) +{ + n = tolower(substr(line, match(line,/\[[0-9a-f ]+\]$/)+1, RLENGTH-2)) + max = split(n, hex, / /) + + if (max <= 0 || hex[0] == "00") return "" + + # Convert name from hex to string (16 bytes) + n = "" + for (i = 1; i <= max; i++) { + d1 = hex2dec[substr(hex[i], 1, 1)] + d2 = hex2dec[substr(hex[i], 2, 1)] + if ((d1 + d2) == 0) break + n = n sprintf("%c", d1 * 16 + d2) + } + # Shell-escape single quotes in the name + gsub(/'/,"'\\''", n) + # Finally strip non-graph chars from the end of the string + # mawk does not support character classes. Use sed. + sed = "echo '" n "' | sed 's/[^[:graph:]]\+$//'" + sed | getline n + close(sed) + return n +} + +{ + if (!/^0x/ && / at /) { + # Section begins + section_begins(substr($0, 1, match($0, / at /)-1)) + } else if (section == "Disk Data" && /^0x020 reference:[ \t]*[0-9A-Fx]+/) { + disk_ref = $3 + sub(/^0x/, "", disk_ref) + } else if (disk_ref) { + # We need to parse 'Virtual Drive' sections in order to extract VD + # names + if (section == "Virtual Drive") { + if (/^0x000 guid:/) { + vd_guid = extract_vd_guid($0) + } else if (/^0x030 name:/) { + vd_name = extract_vd_name($0) + if (vd_name) + vd_names[vd_guid] = vd_name + } + } else if (section == "Virtual Drive Config Record") { + if (/^0x008 guid:/) { + vd_guid = extract_vd_guid($0) + } else if (drive_map) { + # 0: 4BCBB980 @ 0 + if ($2 == disk_ref) { + guids[guid_i] = vd_guid + guid_i++ + } + } else if (vd_guid) { + drive_map = /^Drive map:/ + } + } + } +} +END { + # Print discovered virtual drive names (or GUIDs) which belong to this + # physical drive + for (guid_i in guids) { + guid = guids[guid_i] + if (guid in vd_names) { + print vd_names[guid] + } else { + print guid + } + } +} +EOF +)" + dmraid -i -n "$1" | awk "$ddf1_awk_script" +} + +if grep -qs "\" /proc/cmdline; then + log_warning "dmraid disabled by boot option" + exit 0 +fi + +modprobe -q dm_mod + +if [ -z "$1" ] || [ "$1" = "--degraded" ] && [ "$#" -lt 2 ]; then + echo "Node name not specified." >&2 + exit 1 +fi + +if [ "$1" = "--degraded" ]; then + Degraded=1 + Node_Name=$2 +else + Node_Name=$1 +fi + +Raid_Name=$(dmraid -i -r -cr /dev/$Node_Name | grep -vi "No RAID disks" | grep -vi "formats discovered") + +if [ -z "$Raid_Name" ]; then + exit 0 +fi + +newline=" +" + +case "$Raid_Name" in + isw_*) + # We need a special case for isw arrays, since it is possible to have several + # subsets of a RAID group, of varying RAID types. + Isw_Group_Name=$Raid_Name + Isw_Subsets=$(dmraid -i -n "/dev/$Node_Name" | grep volume | sed 's/.*volume: " *\(.*\)"$/\1/') + + for isw_subset in $Isw_Subsets + do + activate_array "${Isw_Group_Name}_${isw_subset}" + done + break + ;; + .ddf1_disks) + # Dummy name for the main DDF1 group. Needs special handling to + # find RAID subsets (name or GUID) for this physical drive + Ddf1_names=`ddf1_virtual_drive_names "/dev/$Node_Name"` + + # Returned names might contain space characters. Therefore + # split fields at new line. Use $IFS to avoid forking a new shell + save_IFS="$IFS" + IFS="$newline" + for ddf1_name in $Ddf1_names + do + IFS="$save_IFS" + activate_array "ddf1_${ddf1_name}" + IFS="$newline" + done + IFS="$save_IFS" + break + ;; + *) + activate_array "$Raid_Name" + break + ;; +esac + +exit $Return_Val diff --git a/srcpkgs/dmraid/files/dmraid.initramfs-hook b/srcpkgs/dmraid/files/dmraid.initramfs-hook new file mode 100644 index 0000000000..76369611bd --- /dev/null +++ b/srcpkgs/dmraid/files/dmraid.initramfs-hook @@ -0,0 +1,32 @@ +#!/bin/sh + +PREREQ="" + +prereqs() +{ + echo "$PREREQ" +} + +case $1 in +# get pre-requisites +prereqs) + prereqs + exit 0 + ;; +esac + +. /usr/share/initramfs-tools/hook-functions + +if [ -x /usr/sbin/dmraid ]; then + force_load dm-mod + force_load dm-mirror + force_load dm-raid45 + copy_exec /usr/sbin/dmraid sbin + copy_exec /usr/sbin/dmraid-activate sbin + mkdir -p ${DESTDIR}/lib/udev/rules.d + for f in 10-dm 13-dm-disk 95-dm-notify; do + cp -p /lib/udev/rules.d/${f}.rules ${DESTDIR}/lib/udev/rules.d + done +fi + +exit 0 diff --git a/srcpkgs/dmraid/files/dmraid.initramfs-local-top b/srcpkgs/dmraid/files/dmraid.initramfs-local-top new file mode 100644 index 0000000000..d162b5a3f0 --- /dev/null +++ b/srcpkgs/dmraid/files/dmraid.initramfs-local-top @@ -0,0 +1,25 @@ +#!/bin/sh + +# local-top script for dmraid. + +PREREQS="" +prereqs() +{ + echo $PREREQS +} + +case $1 in +# get pre-requisites +prereqs) + prereqs + exit 0 + ;; +esac + +# Activate any dmraid arrays that were not identified by udev and vol_id. + +if devices=$(dmraid -r -c); then + for dev in $devices; do + dmraid-activate $dev + done +fi diff --git a/srcpkgs/dmraid/files/dmraid.service b/srcpkgs/dmraid/files/dmraid.service new file mode 100644 index 0000000000..920e90fa1d --- /dev/null +++ b/srcpkgs/dmraid/files/dmraid.service @@ -0,0 +1,16 @@ +[Unit] +Description=Assemble FakeRAID arrays +DefaultDependencies=no +Requires=udev-settle.service +After=udev-settle.service +Before=basic.target shutdown.target +Conflicts=shutdown.target + +[Service] +ExecStart=/usr/sbin/dmraid --ignorelocking --activate y +Type=oneshot +TimeoutSec=0 +RemainAfterExit=true + +[Install] +WantedBy=basic.target diff --git a/srcpkgs/dmraid/patches/04_do_not_use_p_for_partition.patch b/srcpkgs/dmraid/patches/04_do_not_use_p_for_partition.patch new file mode 100644 index 0000000000..3298d1b10d --- /dev/null +++ b/srcpkgs/dmraid/patches/04_do_not_use_p_for_partition.patch @@ -0,0 +1,13 @@ +Author: Giuseppe Iuculano +Description: Removed "p" from device name. A proper upgrade script is needed before using it. +--- 1.0.0.rc16-3/dmraid/lib/format/partition/dos.c ++++ 1.0.0.rc16-3/dmraid/lib/format/partition/dos.c +@@ -31,7 +31,7 @@ _name(struct lib_context *lc, struct rai + { + const char *base = get_basename(lc, rd->di->path); + +- return type ? snprintf(str, len, "%s%s%u", base, OPT_STR_PARTCHAR(lc), ++ return type ? snprintf(str, len, "%s%u", base, + partition) : snprintf(str, len, "%s", base); + } + diff --git a/srcpkgs/dmraid/patches/12_support_virtio_devices.patch b/srcpkgs/dmraid/patches/12_support_virtio_devices.patch new file mode 100644 index 0000000000..52ed62ee5e --- /dev/null +++ b/srcpkgs/dmraid/patches/12_support_virtio_devices.patch @@ -0,0 +1,13 @@ +Author: Luke Yelavich +Description: Support for checking virtio devices for dmraid metadata. +--- 1.0.0.rc16-3/dmraid/lib/device/scan.c ++++ 1.0.0.rc16-3/dmraid/lib/device/scan.c +@@ -174,7 +174,7 @@ interested(struct lib_context *lc, char + * Whole IDE and SCSI disks only. + */ + return (!isdigit(name[strlen(name) - 1]) && +- (*(name + 1) == 'd' && (*name == 'h' || *name == 's'))) ++ (*(name + 1) == 'd' && (*name == 'h' || *name == 's' || *name == 'v'))) + #ifdef DMRAID_TEST + /* + * Include dm devices for testing. diff --git a/srcpkgs/dmraid/patches/15_activate_multiple_raid_sets.patch b/srcpkgs/dmraid/patches/15_activate_multiple_raid_sets.patch new file mode 100644 index 0000000000..6c5ca4ef68 --- /dev/null +++ b/srcpkgs/dmraid/patches/15_activate_multiple_raid_sets.patch @@ -0,0 +1,12 @@ +Continue onto all raid sets instead of returning after processing the first. (LP: #401713) +--- 1.0.0.rc16-3/dmraid/lib/metadata/metadata.c ++++ 1.0.0.rc16-3/dmraid/lib/metadata/metadata.c +@@ -839,7 +839,7 @@ _discover_partitions(struct lib_context + */ + if (T_GROUP(rs)) { + _discover_partitions(lc, &rs->sets); +- return; ++ continue; + } + + /* diff --git a/srcpkgs/dmraid/patches/15_isw_incorrect_status_fix.patch b/srcpkgs/dmraid/patches/15_isw_incorrect_status_fix.patch new file mode 100644 index 0000000000..fcf51aadb5 --- /dev/null +++ b/srcpkgs/dmraid/patches/15_isw_incorrect_status_fix.patch @@ -0,0 +1,322 @@ +Patch include: + fix for "Incorrect status displayed when disk is missing" issue. + fix for "Missing supported RAID configuration in "-l" option" - Bugzilla bug +479395 + fix for "Wrong disk layout in raid01" - no Bugzilla bug. +--- 1.0.0.rc16-3/dmraid/lib/format/ataraid/isw.c ++++ 1.0.0.rc16-3/dmraid/lib/format/ataraid/isw.c +@@ -4,8 +4,11 @@ + * Copyright (C) 2004-2008 Heinz Mauelshagen, Red Hat GmbH. + * All rights reserved. + * +- * Copyright (C) 2007,2008 Intel Corporation. All rights reserved. ++ * Copyright (C) 2007,2009 Intel Corporation. All rights reserved. + * November, 2007 - additions for Create, Delete, Rebuild & Raid 10. ++ * March, 2008 - additions for hot-spare check ++ * August, 2008 - support for Activation, Rebuild checks ++ * January, 2009 - additions for Activation, Rebuild check + * + * See file LICENSE at the top of this source tree for license information. + */ +@@ -162,7 +165,7 @@ name(struct lib_context *lc, struct raid + + while (i--) { + if (disk == isw->disk + i) { +- id = i / 2; ++ id = i % 2; + goto ok; + } + } +@@ -479,7 +482,7 @@ isw_read_extended(struct lib_context *lc + /* Read extended metadata to offset ISW_DISK_BLOCK_SIZE */ + if (blocks > 1 && + !read_file(lc, handler, di->path, +- (void *) isw_tmp + ISW_DISK_BLOCK_SIZE, ++ (void *) (((uint8_t*)isw_tmp) + ISW_DISK_BLOCK_SIZE), + *size - ISW_DISK_BLOCK_SIZE, *isw_sboffset)) { + dbg_free(isw_tmp); + isw_tmp = NULL; +@@ -708,6 +711,7 @@ super_created(struct raid_set *super, vo + super->stride = ((struct isw_dev *) private)->vol.map.blocks_per_strip; + } + ++ + /* + * rs_group contains the top-level group RAID set (type: t_group) on entry + * and shall be returned on success (or NULL on error). +@@ -1112,6 +1116,15 @@ isw_metadata_handler(struct lib_context + + break; /* case GET_REBUILD_DRIVE_NO */ + ++ case ALLOW_ACTIVATE: /* same as ALLOW_REBUILD */ ++ case ALLOW_REBUILD: ++ /* Do not allow activate or rebuild, if the log is non-empty */ ++ isw = META (rd, isw); ++ ret = !isw->bbm_log_size; /* Is log empty */ ++ if (!ret) ++ log_err(lc, "BBM entries detected!"); ++ break; /* case ALLOW_REBUILD */ ++ + default: + LOG_ERR(lc, 0, "%u not yet supported", command); + +@@ -1144,16 +1157,25 @@ check_rd(struct lib_context *lc, struct + struct raid_dev *rd, void *context) + { + struct isw_dev *dev = rd->private.ptr; +- +- /* FIXME: more status checks ? */ +- if (dev->status) { ++ if (dev == NULL) ++ if (rd->type == t_spare) return 1; ++ else { ++ LOG_ERR(lc, 0, "No information about %s device on %s " ++ "in RAID set \"%s\"", ++ handler, rd->di->path, rs->name); ++ return 0; ++ } ++ /* if disk is ready to read and write return 1 */ ++ if ((dev->status & ISW_DEV_READ_COALESCING) ++ && (dev->status & ISW_DEV_WRITE_COALESCING)) { ++ return 1; ++ } ++ else { + LOG_ERR(lc, 0, "%s device for volume \"%s\" broken on %s " + "in RAID set \"%s\"", + handler, dev->volume, rd->di->path, rs->name); +- ++ return 0; + } +- +- return 1; + } + + static int +@@ -1622,6 +1644,7 @@ _isw_create_first_volume(struct lib_cont + isw->attributes = MPB_ATTRIB_CHECKSUM_VERIFY; + isw->num_raid_devs = (rs->type == ISW_T_SPARE) ? 0 : 1; + isw->family_num = isw->orig_family_num = _checksum(isw) + time(NULL); ++ isw->bbm_log_size = 0; + isw->check_sum = 0; + isw->check_sum = _checksum(isw); + return isw; +@@ -1719,6 +1742,7 @@ _isw_create_second_volume(struct lib_con + isw->generation_num++; + isw->attributes = MPB_ATTRIB_CHECKSUM_VERIFY; + isw->num_raid_devs++; ++ isw->bbm_log_size = 0; + isw->check_sum = 0; + isw->check_sum = _checksum(isw); + return isw; +@@ -1941,6 +1965,8 @@ _isw_log(struct lib_context *lc, struct + DP("error_log_pos: %u", isw, isw->error_log_pos); + DP("cache_size: %u", isw, isw->cache_size); + DP("orig_family_num: %u", isw, isw->orig_family_num); ++ DP ("power_cycle_count: %u", isw, isw->power_cycle_count); ++ DP ("bbm_log_size: %u", isw, isw->bbm_log_size); + + for (i = 0; i < ISW_FILLERS; i++) { + if (isw->filler[i]) +@@ -2296,7 +2322,7 @@ isw_delete(struct lib_context *lc, struc + static struct dmraid_format isw_format = { + .name = HANDLER, + .descr = "Intel Software RAID", +- .caps = "0,1,01", ++ .caps = "0,1,5,01", + .format = FMT_RAID, + .read = isw_read, + .write = isw_write, +--- 1.0.0.rc16-3/dmraid/lib/format/format.c ++++ 1.0.0.rc16-3/dmraid/lib/format/format.c +@@ -260,6 +260,7 @@ write_metadata(struct lib_context *lc, c + return 1; + } + ++ + /* + * Check devices in a RAID set. + * +@@ -277,7 +278,7 @@ _check_raid_set(struct lib_context *lc, + void *context), + void *f_check_context, const char *handler) + { +- unsigned int devs; ++ unsigned int dev_tot_qan; + uint64_t sectors; + struct raid_dev *rd; + +@@ -285,36 +286,73 @@ _check_raid_set(struct lib_context *lc, + return; + + sectors = total_sectors(lc, rs); +- rs->total_devs = devs = count_devs(lc, rs, ct_dev); ++ rs->total_devs = dev_tot_qan = count_devs(lc, rs, ct_dev); + list_for_each_entry(rd, &rs->devs, devs) { +- unsigned int devices = f_devices(rd, f_devices_context); ++ unsigned int dev_found_qan = f_devices(rd, f_devices_context); + /* FIXME: error if the metadatas aren't all the same? */ +- rs->found_devs = devices; ++ rs->found_devs = dev_found_qan; + + log_dbg(lc, "checking %s device \"%s\"", handler, rd->di->path); +- if (T_SPARE(rd) && rs->type == t_raid1 && /* FIXME: rs->type check ? */ +- rd->sectors != sectors) { +- rd->status = s_inconsistent; +- log_err(lc, "%s: size mismatch in set \"%s\", spare " +- "\"%s\"", handler, rs->name, rd->di->path); +- continue; +- } +- +- if (devs != devices && +- f_check && !f_check(lc, rs, rd, f_check_context)) { +- rd->status = s_broken; +- log_err(lc, "%s: wrong # of devices in RAID " +- "set \"%s\" [%u/%u] on %s", +- handler, rs->name, devs, devices, rd->di->path); +- } else +- rd->status = s_ok; ++ /* if disks number of found disks equals disk expected status status OK */ ++ if ((dev_tot_qan == dev_found_qan) && f_check ++ && f_check(lc, rs, rd, f_check_context)) { ++ rd->status = s_ok; ++ } ++ else { ++ if(dev_tot_qan != dev_found_qan) { ++ log_err(lc, "%s: wrong # of devices in RAID " ++ "set \"%s\" [%u/%u] on %s", ++ handler, rs->name, dev_tot_qan, dev_found_qan, rd->di->path); ++ } ++ /* if number of disks is incorrect, status depends on raid type: */ ++ switch(rs->type) { ++ case t_linear: ++ case t_raid0: /* raid 0 - always broken */ ++ rd->status = s_broken; ++ break; ++ case t_raid1: /* raid 1 - if at least 1 disk- inconsintent */ ++ if(dev_tot_qan >= 1) ++ rd->status = s_inconsistent; ++ else if (T_SPARE(rd) && rd->sectors != sectors) { ++ rd->status = s_inconsistent; ++ log_err(lc, "%s: size mismatch in set \"%s\", spare " ++ "\"%s\"", handler, rs->name, rd->di->path); ++ } ++ else rd->status = s_broken; ++ break; ++ case t_raid4: ++ case t_raid5_ls: ++ case t_raid5_rs: ++ case t_raid5_la: ++ case t_raid5_ra: /* raid 4/5 - if 1 disk missing- inconsistent */ ++ if((dev_tot_qan == (dev_found_qan-1) && dev_tot_qan > 1 ++ && f_check && f_check(lc, rs, rd, f_check_context)) ++ || (dev_tot_qan > dev_found_qan)) ++ rd->status = s_inconsistent; ++ else rd->status = s_broken; ++ break; ++ case t_raid6: /* raid 6 - if up to 2 disks missing- inconsistent */ ++ if((dev_tot_qan >= (dev_found_qan-2) ++ && f_check && f_check(lc, rs, rd, f_check_context)) ++ || (dev_tot_qan > dev_found_qan)) ++ rd->status = s_inconsistent; ++ else rd->status = s_broken; ++ break; ++ ++ case t_spare: /* spare - always broken */ ++ rd->status = s_broken; ++ break; ++ default: /* other - undef */ ++ rd->status = s_undef; ++ } ++ } + } + } + + /* + * Update RAID set state based on operational subsets/devices. + * +- * In case of a RAID set hierachy, check availability of subsets ++ f a RAID set hierachy, check availability of subsets + * and set superset to broken in case *all* subsets are broken. + * If at least one is still available, set to inconsistent. + * +@@ -323,12 +361,19 @@ _check_raid_set(struct lib_context *lc, + */ + static void + _set_rs_status(struct lib_context *lc, struct raid_set *rs, +- unsigned int i, unsigned int operational) ++ unsigned int i, unsigned int operational, ++ unsigned int inconsist, unsigned int subsets_raid01) + { +- if (operational == i) ++ if (subsets_raid01 == 1) { ++ rs->status = s_broken; ++ return; ++ } ++ if (operational == i) + rs->status = s_ok; + else if (operational) + rs->status = s_inconsistent; ++ else if (inconsist) ++ rs->status = s_inconsistent; + else + rs->status = s_broken; + +@@ -338,26 +383,30 @@ _set_rs_status(struct lib_context *lc, s + static int + set_rs_status(struct lib_context *lc, struct raid_set *rs) + { +- unsigned int i = 0, operational = 0; ++ unsigned int i = 0, operational = 0, subsets_raid01 = 0, inconsist = 0; + struct raid_set *r; + struct raid_dev *rd; + + /* Set status of subsets. */ + list_for_each_entry(r, &rs->sets, list) { + /* Check subsets to set status of superset. */ +- i++; ++ if((rs->type == t_raid0) && (r->type == t_raid1)) ++ subsets_raid01++; /* Count subsets for raid 01 */ ++ i++; /* Count subsets*/ + if (S_OK(r->status) || S_INCONSISTENT(r->status)) +- operational++; ++ operational++; /* Count operational subsets*/ + } + + /* Check status of devices... */ + list_for_each_entry(rd, &rs->devs, devs) { +- i++; ++ i++; /* Count disks*/ + if (S_OK(rd->status)) +- operational++; ++ operational++; /* Count disks in "ok" raid*/ ++ if (S_INCONSISTENT(rd->status)) ++ inconsist++; /* Count disks in degraded raid*/ + } + +- _set_rs_status(lc, rs, i, operational); ++ _set_rs_status(lc, rs, i, operational, inconsist, subsets_raid01); + return S_BROKEN(rs->status) ? 0 : 1; + } + +--- 1.0.0.rc16-3/dmraid/include/dmraid/format.h ++++ 1.0.0.rc16-3/dmraid/include/dmraid/format.h +@@ -75,6 +75,8 @@ enum handler_commands { + GET_REBUILD_DRIVE, + GET_REBUILD_DRIVE_NO, + CHECK_HOT_SPARE, ++ ALLOW_ACTIVATE, ++ ALLOW_REBUILD, + /* ... */ + }; + +--- 1.0.0.rc16-3/dmraid/lib/format/ataraid/isw.h ++++ 1.0.0.rc16-3/dmraid/lib/format/ataraid/isw.h +@@ -188,6 +188,8 @@ struct isw_dev { + + struct isw { + int8_t sig[MAX_SIGNATURE_LENGTH]; /* 0x0 - 0x1F */ ++ uint32_t bbm_log_size; ++ uint32_t power_cycle_count; + uint32_t check_sum; /* 0x20 - 0x23 MPB Checksum */ + uint32_t mpb_size; /* 0x24 - 0x27 Size of MPB */ + uint32_t family_num; /* 0x28 - 0x2B Checksum from first time this config was written */ diff --git a/srcpkgs/dmraid/patches/17_isw-probe-hpa.patch b/srcpkgs/dmraid/patches/17_isw-probe-hpa.patch new file mode 100644 index 0000000000..fcc0dd1f5d --- /dev/null +++ b/srcpkgs/dmraid/patches/17_isw-probe-hpa.patch @@ -0,0 +1,144 @@ +Probe isw disks with [some] HPA awareness, thanks to Robert Collins . (LP: #372170) +--- 1.0.0.rc16-3/dmraid/lib/format/ataraid/isw.c ++++ 1.0.0.rc16-3/dmraid/lib/format/ataraid/isw.c +@@ -353,6 +353,7 @@ raiddev(struct isw *isw, unsigned i) + enum convert { FULL, FIRST, LAST }; + #if BYTE_ORDER == LITTLE_ENDIAN + # define to_cpu(x, y) ++# define CVT16(x) + #else + /* + * We can differ from the read_raid_dev template here, +@@ -547,15 +548,16 @@ disk_ok(struct lib_context *lc, struct d + } + + static void * +-isw_read_metadata(struct lib_context *lc, struct dev_info *di, +- size_t * sz, uint64_t * offset, union read_info *info) ++isw_try_sboffset(struct lib_context *lc, struct dev_info *di, ++ size_t * sz, uint64_t * offset, union read_info *info, ++ uint64_t const isw_sboffset) + { + size_t size = ISW_DISK_BLOCK_SIZE; +- uint64_t isw_sboffset = ISW_CONFIGOFFSET(di); + struct isw *isw; ++ uint64_t temp_isw_sboffset = isw_sboffset; + + if (!(isw = alloc_private_and_read(lc, handler, size, +- di->path, isw_sboffset))) ++ di->path, temp_isw_sboffset))) + goto out; + + /* +@@ -565,9 +567,15 @@ isw_read_metadata(struct lib_context *lc + to_cpu(isw, FIRST); + + /* Check Signature and read optional extended metadata. */ +- if (!is_isw(lc, di, isw) || +- !isw_read_extended(lc, di, &isw, &isw_sboffset, &size)) ++ if (!is_isw(lc, di, isw)) { ++ log_dbg(lc, "not isw at %ld", isw_sboffset); + goto bad; ++ } ++ if (!isw_read_extended(lc, di, &isw, &temp_isw_sboffset, &size)) { ++ log_err(lc, "isw metadata, but extended read failed at %ld", ++ isw_sboffset); ++ goto bad; ++ } + + /* + * Now that we made sure, that we've got all the +@@ -578,6 +586,8 @@ isw_read_metadata(struct lib_context *lc + if (disk_ok(lc, di, isw)) { + *sz = size; + *offset = info->u64 = isw_sboffset; ++ log_dbg(lc, "isw metadata found at %ld from probe at %ld\n", ++ *offset, isw_sboffset); + goto out; + } + +@@ -589,6 +599,54 @@ out: + return (void *) isw; + } + ++/* HPA on a disk shifts everything down. This is a 'works-enough' approach to ++ * handling that. There is a better long term approach requiring kernel ++ * patches - see the lkml patches for alt_size. ++ */ ++static void * ++isw_try_hpa(struct lib_context *lc, struct dev_info *di, ++ size_t * sz, uint64_t * offset, union read_info *info) ++{ ++ struct isw10 *isw10; ++ void *result = NULL; ++ uint64_t actual_offset; ++ if (!(isw10 = alloc_private_and_read(lc, handler, ISW_DISK_BLOCK_SIZE, ++ di->path, ISW_10_CONFIGOFFSET(di)))) ++ goto out; ++ if (strncmp((const char *)isw10->sig, ISW10_SIGNATURE, ISW10_SIGNATURE_SIZE)) ++ goto out_free; ++ log_dbg(lc, "Found isw 10 gafr signature."); ++ CVT16(isw10->offset); ++ actual_offset = isw10->offset + 2; ++ log_dbg(lc, "isw 10 sector offset calculated at %hd.", actual_offset); ++ if (actual_offset > di->sectors) ++ goto out_free; ++ result = isw_try_sboffset(lc, di, sz, offset, info, ++ ISW_SECTOR_TO_OFFSET(di->sectors - actual_offset)); ++ out_free: ++ dbg_free(isw10); ++ out: ++ return result; ++} ++ ++ ++static void * ++isw_read_metadata(struct lib_context *lc, struct dev_info *di, ++ size_t * sz, uint64_t * offset, union read_info *info) ++{ ++ void *result; ++ if ((result = isw_try_sboffset( ++ lc, di, sz, offset, info, ISW_CONFIGOFFSET(di)))) ++ return result; ++ if ((result = isw_try_hpa(lc, di, sz, offset, info))) ++ return result; ++ log_dbg(lc, "isw trying hard coded -2115 offset."); ++ if ((result = isw_try_sboffset( ++ lc, di, sz, offset, info, (di->sectors - 2115)*512))) ++ return result; ++ return NULL; ++} ++ + static int setup_rd(struct lib_context *lc, struct raid_dev *rd, + struct dev_info *di, void *meta, union read_info *info); + static struct raid_dev * +--- 1.0.0.rc16-3/dmraid/lib/format/ataraid/isw.h ++++ 1.0.0.rc16-3/dmraid/lib/format/ataraid/isw.h +@@ -36,8 +36,11 @@ + + /* Intel metadata offset in bytes */ + #define ISW_CONFIGSECTOR(di) ((di)->sectors - 2) +-#define ISW_CONFIGOFFSET(di) (ISW_CONFIGSECTOR(di) << 9) ++#define ISW_SECTOR_TO_OFFSET(sector) ((sector) << 9) ++#define ISW_CONFIGOFFSET(di) (ISW_SECTOR_TO_OFFSET(ISW_CONFIGSECTOR(di))) + #define ISW_DATAOFFSET 0 /* Data offset in sectors */ ++#define ISW_10_CONFIGSECTOR(di) ((di)->sectors - 1) ++#define ISW_10_CONFIGOFFSET(di) (ISW_SECTOR_TO_OFFSET(ISW_10_CONFIGSECTOR(di))) + + #define MPB_SIGNATURE "Intel Raid ISM Cfg Sig. " + #define MPB_SIGNATURE_SIZE (sizeof(MPB_SIGNATURE) - 1) +@@ -222,6 +225,14 @@ struct isw { + // here comes isw_dev[num_raid_devs] + } __attribute__ ((packed)); + ++#define ISW10_SIGNATURE "$GAFR\x10" ++#define ISW10_SIGNATURE_SIZE (sizeof(ISW10_SIGNATURE) - 1) ++struct isw10 { ++ int8_t sig[ISW10_SIGNATURE_SIZE]; ++ uint32_t offset; /* offset to real data, in sectors back */ ++} __attribute__ ((packed)); ++ ++ + #endif + + int register_isw(struct lib_context *lc); diff --git a/srcpkgs/dmraid/patches/20_fix_isw_sectors_calculation.patch b/srcpkgs/dmraid/patches/20_fix_isw_sectors_calculation.patch new file mode 100644 index 0000000000..ac1949ae53 --- /dev/null +++ b/srcpkgs/dmraid/patches/20_fix_isw_sectors_calculation.patch @@ -0,0 +1,14 @@ +Fix isw raid0 incorrect sectors calculation, thanks to Valentin Pavlyuchenko +--- 1.0.0.rc16-3/dmraid/lib/format/ataraid/isw.c ++++ 1.0.0.rc16-3/dmraid/lib/format/ataraid/isw.c +@@ -776,7 +776,9 @@ _create_rd(struct lib_context *lc, + r->di = rd->di; + r->fmt = rd->fmt; + r->offset = dev->vol.map[0].pba_of_lba0; +- if ((r->sectors = dev->vol.map[0].blocks_per_member - RAID_DS_JOURNAL)) ++ //fix bugs on ICH10R ++ //if ((r->sectors = dev->vol.map[0].blocks_per_member - RAID_DS_JOURNAL)) ++ if ((r->sectors = dev->vol.map[0].blocks_per_member)) + goto out; + + log_zero_sectors(lc, rd->di->path, handler); diff --git a/srcpkgs/dmraid/patches/series b/srcpkgs/dmraid/patches/series new file mode 100644 index 0000000000..5d7281b0e3 --- /dev/null +++ b/srcpkgs/dmraid/patches/series @@ -0,0 +1,5 @@ +04_do_not_use_p_for_partition.patch +12_support_virtio_devices.patch +17_isw-probe-hpa.patch +15_activate_multiple_raid_sets.patch +20_fix_isw_sectors_calculation.patch diff --git a/srcpkgs/dmraid/template b/srcpkgs/dmraid/template new file mode 100644 index 0000000000..3799c4272c --- /dev/null +++ b/srcpkgs/dmraid/template @@ -0,0 +1,52 @@ +# Template file for 'dmraid' +pkgname=dmraid +_distver=1.0.0.rc16 +_patchver=3 +version="${_distver}_${_patchver}" +wrksrc="${pkgname}" +build_wrksrc="${_distver}-${_patchver}/${pkgname}" +homepage="http://people.redhat.com/~heinzm/sw/dmraid/" +distfiles="${homepage}/src/dmraid-${_distver}-${_patchver}.tar.bz2" +build_style=gnu-configure +configure_args="--enable-led --enable-intel_led --enable-shared_lib" +short_desc="Device mapper RAID interface" +maintainer="Juan RP " +license="GPL-2, LGPL-2.1" +checksum=93421bd169d71ff5e7d2db95b62b030bfa205a12010b6468dcdef80337d6fbd8 +long_desc=" + dmraid discovers, activates, deactivates and displays properties of software RAID sets + (eg, ATARAID) and contained DOS partitions. + + dmraid uses the Linux device-mapper to create devices with respective mappings + for the ATARAID sets discovered. + + The following formats are supported: + + Highpoint HPT37X/HPT45X + Intel Software RAID + LSI Logic MegaRAID + NVidia NForce RAID (nvraid) + Promise FastTrack + Silicon Image(tm) Medley(tm) + VIA Software RAID" + +systemd_services="dmraid.service off" +shlib_depends="device-mapper>=2.02.95_3" +triggers="initramfs-tools" + +Add_dependency build device-mapper-devel ">=2.02.95_1" + +post_install() { + rm -rf ${DESTDIR}/usr/include + rm -f ${DESTDIR}/usr/lib/*.a + + # Install initramfs-tools stuff. + vinstall ${FILESDIR}/dmraid.initramfs-hook 755 \ + usr/share/initramfs-tools/hooks dmraid + vinstall ${FILESDIR}/dmraid.initramfs-local-top 755 \ + usr/share/initramfs-tools/scripts/local-top dmraid + # Install dmraid-activate from Debian. + vinstall ${FILESDIR}/dmraid-activate 755 usr/sbin + # systemd service. + vinstall ${FILESDIR}/dmraid.service 644 lib/systemd/system +}