Re: Machine affected Dell Inspiron 1525

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



Pedro Gomez Salazar wrote:
> Hi!
> 
> Machine affected:
> Dell Inspiron 1525
> HD: WD1600BEVT
> System: Kubuntu 8:04
> 
> 
> Fix?
> hdparm -B 254
> in rc.local
> 
> bug?
> hddtemp /dev/sda
> 45-46 Celsius
> 
> In Windows Vista
> Count increse 4 o 5 cycles in hour..
> HDD temp: 39-40 Celsius

Please test the attached script and configuration file remove the
problem.  Thanks.

-- 
tejun
#! /bin/bash
#
# storage-fixup			- Tejun Heo <teheo@xxxxxxx>
#
# Script to issue fix up commands for weird disks.  This is primarily
# to adjust ATA APM setting.  Some laptop BIOSen set this value too
# aggressively causing frequent head unloads which can kill the drive
# quickly.  This script should be called during boot and resume.  It
# examines rules from /etc/stroage-fixup.conf and executes matching
# commands.
#
# In stroage-fixup.conf, empty lines and lines starting w/ # are
# ignored.  Each line starts with rule, dmi, ata or act.
#
# rule RULENAME
#	Starts a rule.  $RULENAME can't contain whitespaces.
#
# dmi KEY PATTERN
#	Checks whether DMI value for KEY matches PATTERN.  If not, the
#	rule is skipped.
#
# ata KEY PATTERN
#	Checks whether ATA value for KEY matches PATTERN.  If not, the
#	rule is skipped.  KEY can be one of model, rev and serial.
#
# act ACTION
#	Executes ACTION on matched devices.  ACTION can contain $DEV
#	which will be substituted with device file of matching device.
#
# sact ACTION
#	Silent version of "act".  Useful when the action to take is
#	printing out a warning message.
#
# PATTERN is bash extglob pattern.
#
# For example, the following (useless) rule disables APM on the first
# harddrive of my machine.
#
# rule p5w64
# dmi baseboard-product-name	P5W64 WS Pro
# dmi baseboard-manufacturer	ASUSTeK Computer INC.
# ata model                     WDC WD5000YS-01M
# ata serial                    *WMANU1217262
# act hdparm -B 255 $DEV
#
# Release under BSD license.  See LICENSE.
#

declare usage="
Usage: storage-fixup [-h] [-V] [-v] [-b] [-c config_file] [-m max_devs]

       -h      Print this help message and exit
       -V      Print version and exit
       -v      Verbose
       -d      Dry run, don't actually execute action
       -c      Use config_file instead of /etc/storage-fixup.conf
       -m      Maximum number of allowed devices (default=64, 0 for unlimited)
"

declare dmidecode=${DMIDECODE:-dmidecode}
declare hdparm=${HDPARM:-hdparm}
declare sg_inq=${HDPARM:-sg_inq}
declare sed=${SED:-sed}

declare version=0.2
declare conf_file=/etc/storage-fixup.conf
declare max_devs=64

declare newline=$'\n'
declare dry_run=0 verbose=0 lineno=0 skip=0 rule_name="" reply
declare -a storage_devs
declare -a match_cache
declare -a matches

log() {
    echo "storage-fixup: $@"
}

warn() {
   log "$@" 1>&2
}

debug() {
    if [ $verbose -ne 0 ]; then
	warn "$@"
    fi
}

trim() {
    local str="$1"

    str="${str##*([[:blank:]])}"
    str="${str%%*([[:blank:]])}"
    echo -n "$str"
}

#
# search_match_cache - search match cache
# @type: type of match
# @key: key of property to search
# @idx: index of device to search for
#
# Searches match cache and returns 0 if found, 1 if @type:@key
# properties are cached but matching entry is not found, 2 if
# @type:@key properties are not cached yet.  On success, the matched
# property is returned in $reply.
#
search_match_cache() {
    local type="$1" key=$(trim "$2") idx="$3"
    local i key_found=0 cache len match

    reply=

    for ((i=0;i<${#match_cache[@]};i++)); do
	cache=${match_cache[i]}
	len=${#cache}

	match="${cache#$type:$key:?(-)+([0-9]) }"
	if [ ${#match} -ne $len ]; then
	    key_found=1
	fi

	match="${cache#$type:$key:$idx }"
	if [ ${#match} -ne $len ]; then
	    reply="$match"
	    return 0
	fi
    done

    if [ $key_found -eq 1 ]; then
	return 1
    else
	return 2
    fi
}

#
# add_to_match_cache - add entry to match cache
# @type: type of match
# @key: key of the entry to be added
# @idx: index of device to add entry for
# @property: property of the entry to be added
#
# Add $property for $type:$key:$idx.
#
add_to_match_cache() {
    local type="$1" key=$(trim "$2") idx="$3" property=$(trim "$4")

    match_cache+=("$type:$key:$idx $property")
    debug "C $type:$key:$idx $property"
    reply="$property"
    return 0
}

#
# do_dmi - perform DMI match
# @key: DMI key to be passed as --string argument to dmidecode
# @pattern: glob pattern to match
#
# Returns 0 on match, 1 on mismatch, 2 on invalid match (triggers
# warning).
#
do_dmi() {
    local key="$1" pattern="$2"
    local ret val

    if [ -z "$key" -o -z "$pattern" ]; then
	return 1
    fi

    search_match_cache dmi "$key" 0
    ret=$?
    if [ $ret -eq 2 ]; then
	val=$($dmidecode --string "$key")
	if [ "$?" -ne 0 ]; then
	    add_to_match_cache dmi "$key" -1
	    return 2
	fi
	add_to_match_cache dmi "$key" 0 "$val"
    elif [ $ret -eq 1 ]; then
	return 2
    fi

    if [ -z "${reply##$pattern}" ]; then
	debug "Y $lineno $rule_name dmi $key=$pattern"
	return 0
    fi

    debug "N $lineno $rule_name dmi $key=$pattern"
    return 1
}

#
# do_storage - perform storage match
# @type: ata or scsi
# @key: ata key - model, rev or serial for both ata and scsi or vendor for scsi
# @pattern: glob pattern to match
#
# Returns 0 on match, 1 on mismatch, 2 on invalid match (triggers
# warning).
#
do_storage() {
    local type="$1" key="$2" pattern="$3" idx
    local -a old_matches=("${matches[@]}")

    if [ -z "$key" -o -z "$pattern" ]; then
	return 1
    fi

    matches=()
    for idx in ${old_matches[@]}; do
	if search_match_cache $type "$key" $idx; then
	    if [ $? -eq 0 -a -z "${reply##$pattern}" ]; then
		matches+=($idx)
	    fi
	fi
    done

    if [ ${#matches[@]} -eq 0 ]; then
	debug "N $lineno $rule_name $type:$key=$pattern"
	return 1
    fi

    debug "Y $lineno $rule_name $type nr_devs=${#matches[@]} $type:$key"
    return 0
}

#
# do_act - execute action
# @act: action to execute
#
# Execute @act for each device in $matches.  "$DEV" in @act is
# substituted with the /dev node of each match.  If $dry_run is set,
# the action is logged but not actually executed.
#
# Returns 0.
#
do_act() {
    local act="$1" verbose="$2"
    local id dev

    for idx in ${matches[@]}; do
	DEV=${storage_devs[idx]}
	if [ $dry_run -eq 0 ]; then
	    if [ $verbose -ne 0 ]; then
		eval log "$rule_name: executing \"$act\""
	    fi
	    eval "$act"
	else
	    eval log "$rule_name: dry-run \"$act\""
	fi
    done

    return 0
}

#
# Execution starts here
#
shopt -s extglob

while getopts "dvVc:m:h" option; do
    case $option in
	d)
	    dry_run=1;;
	v)
	    verbose=1;;
	V)
	    echo "$version"
	    exit 0;;
	c)
	    conf_file=$OPTARG;;
	m)
	    max_devs=$((OPTARG+0));;
	*)
	    echo "$usage" 2>&1
	    exit 1;;
    esac
done

# what storage devices do we have?
storage_devs=($(ls /dev/[sh]d+([a-z]) /dev/sr+([0-9]) 2> /dev/null))
debug "I ${#storage_devs[@]} storage devices"

if [ $max_devs -ne 0 -a ${#storage_devs[@]} -gt $max_devs ]; then
    warn "nr_storage_devs=${#storage_devs[@]} > limit=$max_devs, skipping"
    exit 1
fi

# populate storage info
for ((i=0;i<${#storage_devs};i++)); do
    output=$($hdparm -i ${storage_devs[i]} 2> /dev/null)
    if [ $? -eq 0 ]; then
	MODEL=
	REV=
	SERIAL=
	eval $(echo "$output" | $sed -nr 's/^\s*Model=\s*(.*\S|\s*)\s*,\s*FwRev=\s*(.*\S|\s*)\s*,\s*SerialNo=\s*(.*\S|\s*)\s*$/MODEL=\"\1\"\nREV=\"\2\"\nSERIAL=\"\3\"/p')
	add_to_match_cache ata model $i "$MODEL"
	add_to_match_cache ata rev $i "$REV"
	add_to_match_cache ata serial $i "$SERIAL"
    fi

    output=$($sg_inq ${storage_devs[i]} 2> /dev/null)
    if [ $? -eq 0 ]; then
	VENDOR=
	MODEL=
	REV=
	SERIAL=
	eval $(echo "$output" | $sed -nr 's/^\s*Vendor identification:\s*(.*\S|\s*)\s*$/VENDOR=\"\1\"/p')
	eval $(echo "$output" | $sed -nr 's/^\s*Product identification:\s*(.*\S|\s*)\s*$/MODEL=\"\1\"/p')
	eval $(echo "$output" | $sed -nr 's/^\s*Product revision level:\s*(.*\S|\s*)\s*$/REV=\"\1\"/p')
	eval $(echo "$output" | $sed -nr 's/^\s*Unit serial number:\s*(.*\S|\s*)\s*$/SERIAL=\"\1\"/p')
	add_to_match_cache scsi vendor $i "$VENDOR"
	add_to_match_cache scsi model $i "$MODEL"
	add_to_match_cache scsi rev $i "$REV"
	add_to_match_cache scsi serial $i "$SERIAL"
    fi
done

while read f0 f1 f2; do
    true $((lineno++))
    if [ -z ${f0###*} ]; then
	continue
    fi

    if [ "$f0" = rule ]; then
	rule_name=$f1
	skip=0
	matches=($(seq 0 $((${#storage_devs[@]}-1))))
	continue
    fi

    if [ $skip -ne 0 ]; then
	continue
    fi

    case "$f0" in
    dmi)
	    do_dmi "$f1" "$f2"
	    ;;
    ata)
	    do_storage ata "$f1" "$f2"
	    ;;
    scsi)
	    do_storage scsi "$f1" "$f2"
	    ;;
    act)
	    do_act "$f1 $f2" 1
	    ;;
    sact)
	    do_act "$f1 $f2" 0
	    ;;
    *)
	    false
	    ;;
    esac

    ret=$?
    if [ $ret -ne 0 ]; then
	if [ $ret -eq 2 ]; then
	    warn "malformed line $lineno \"$f0 $f1 $f2\","\
	         "skipping rule $rule_name" 2>&1
	fi
	skip=1
    fi
done < $conf_file
#
# /etc/storage-fixup.conf - Configuration file for storage-fixup
#
# Blank lines and lines starting with # are ignored.  Please read
# comment at the top of storage-fixup for more information.
#
# Drive model patterns are generalized to cover drives from the same
# family.  Drive manufacturers usually have datasheets or web pages
# listing all models of the same family.
#
# The DMI part is difficult to generalize as there's no such
# information.  We'll have to generalize as we collect entries.
#
# If you have a harddrive which does crazy unloading but not listed
# here, please write to linux-ide@xxxxxxxxxxxxxxx with the outputs of
# "dmidecode" and "hdparm -I DRIVE" attached.  On a laptop the DRIVE
# is usually /dev/sda.
#

# Reported drive model: Hitachi HTS722020K9SA00
rule tp-t60
dmi system-manufacturer		LENOVO
dmi system-product-name		1952W5R
dmi system-version		ThinkPad T60
ata model			Hitachi HTS7220*K9*A*
act hdparm -B 255 $DEV

# Reported drive model: SAMSUNG HM250JI
rule hp-dv6500
dmi system-manufacturer		Hewlett-Packard
dmi system-product-name		HP Pavilion dv6500 Notebook PC
dmi system-version		Rev 1
ata model			SAMSUNG HM*I
act hdparm -B 255 $DEV

# Reported drive model: TOSHIBA MK1637GSX
rule hp-dv9500
dmi system-manufacturer		Hewlett-Packard
dmi system-product-name		HP Pavilion dv9500 Notebook PC
dmi system-version		Rev 1
ata model			TOSHIBA MK*37GSX
act hdparm -B 254 $DEV

# Reported drive model: ST9100824AS
rule dell-e1505
dmi system-manufacturer		Dell Inc.
dmi system-product-name		MM061
ata model			ST9*AS
act hdparm -B 255 $DEV

# Reported drive model: ST9120822AS
rule dell-Vostro-1400
dmi system-manufacturer		Dell Inc.
dmi system-product-name		Vostro 1400
ata model			ST9*AS
act hdparm -B 254 $DEV

# Reported drive model: WDC WD1600BEVT-75ZCT0
rule dell-inspiron-1525
dmi system-manufacturer		Dell Inc.
dmi system-product-name		Inspiron 1525
ata model			WDC WD*BEVT*
act hdparm -B 255 $DEV

# Reported drive model: Toshiba MK2546GSX
rule samsung-q45
dmi system-manufacturer		SAMSUNG ELECTRONICS CO., LTD.
dmi system-product-name		SQ45S70S
ata model			TOSHIBA MK*46GSX
act hdparm -B 254 $DEV

# Reported drive model: FUJITSU MHV2080BHPL
rule macmini1_1
dmi system-manufacturer		Apple Computer, Inc.
dmi system-product-name		Macmini1,1
ata model			FUJITSU MHV2*
act hdparm -B 255 $DEV

# Reported drive model: WDC WD1200BEVE-00WZT0
rule acer-aspire-1690
dmi system-manufacturer		Acer, inc.
dmi system-product-name		Aspire 1690
ata model			WDC WD*BEVE*
act hdparm -B 255 $DEV

[Index of Archives]     [Linux Filesystems]     [Linux SCSI]     [Linux RAID]     [Git]     [Kernel Newbies]     [Linux Newbie]     [Security]     [Netfilter]     [Bugtraq]     [Yosemite News]     [MIPS Linux]     [ARM Linux]     [Linux Security]     [Samba]     [Device Mapper]

  Powered by Linux