linux-ide.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* Seagate HDD Frequent Head Unload - hdparm/dmidecode/smartctl output
@ 2008-07-26 13:34 Ivan N. Zlatev
  2008-07-28  7:28 ` Tejun Heo
  0 siblings, 1 reply; 8+ messages in thread
From: Ivan N. Zlatev @ 2008-07-26 13:34 UTC (permalink / raw)
  To: linux-ide; +Cc: teheo

[-- Attachment #1: Type: text/plain, Size: 531 bytes --]

I am having frequent head unloads on a Dell Vostro 1400 laptop with a 
Seagate HDD. As explained on the Wiki[1] I am attaching for you the 
output of:

    * hdparm -I
    * dmidecode
    * smartctl --all (in addition)

I hope this information is useful for you.

I am currently using a workaround to prevent the unloads as described 
here - http://en.opensuse.org/Disk_Power_Management .

[1] 
http://ata.wiki.kernel.org/index.php/Known_issues#Drives_which_perform_frequent_head_unloads_under_Linux

Kind Regards,
Ivan N. Zlatev


[-- Attachment #2: dmidecode-output.gz --]
[-- Type: application/x-gzip, Size: 3362 bytes --]

[-- Attachment #3: hdparm-output --]
[-- Type: text/plain, Size: 2039 bytes --]


/dev/sda:

ATA device, with non-removable media
	Model Number:       ST9120822AS                             
	Serial Number:      5LZ6PF8E
	Firmware Revision:  3.CDD   
Standards:
	Supported: 7 6 5 4 
	Likely used: 8
Configuration:
	Logical		max	current
	cylinders	16383	16383
	heads		16	16
	sectors/track	63	63
	--
	CHS current addressable sectors:   16514064
	LBA    user addressable sectors:  234441648
	LBA48  user addressable sectors:  234441648
	device size with M = 1024*1024:      114473 MBytes
	device size with M = 1000*1000:      120034 MBytes (120 GB)
Capabilities:
	LBA, IORDY(can be disabled)
	Queue depth: 32
	Standby timer values: spec'd by Standard, no device specific minimum
	R/W multiple sector transfer: Max = 16	Current = 8
	Advanced power management level: 128
	Recommended acoustic management value: 128, current value: 0
	DMA: mdma0 mdma1 mdma2 udma0 udma1 udma2 udma3 udma4 udma5 *udma6 
	     Cycle time: min=120ns recommended=120ns
	PIO: pio0 pio1 pio2 pio3 pio4 
	     Cycle time: no flow control=240ns  IORDY flow control=120ns
Commands/features:
	Enabled	Supported:
	   *	SMART feature set
	    	Security Mode feature set
	   *	Power Management feature set
	   *	Write cache
	   *	Look-ahead
	   *	Host Protected Area feature set
	   *	WRITE_BUFFER command
	   *	READ_BUFFER command
	   *	DOWNLOAD_MICROCODE
	   *	Advanced Power Management feature set
	    	SET_MAX security extension
	    	Automatic Acoustic Management feature set
	   *	48-bit Address feature set
	   *	Mandatory FLUSH_CACHE
	   *	FLUSH_CACHE_EXT
	   *	SMART error logging
	   *	SMART self-test
	   *	IDLE_IMMEDIATE with UNLOAD
	   *	SATA-I signaling speed (1.5Gb/s)
	   *	Native Command Queueing (NCQ)
	   *	Phy event counters
	    	Device-initiated interface power management
	   *	Software settings preservation
	   *	SMART Command Transport (SCT) feature set
Security: 
	Master password revision code = 65534
		supported
	not	enabled
	not	locked
		frozen
	not	expired: security count
	not	supported: enhanced erase
Checksum: correct

[-- Attachment #4: smartctl-info-output --]
[-- Type: text/plain, Size: 4905 bytes --]

smartctl 5.39 2008-05-08 21:56 [i686-pc-linux-gnu] (local build)
Copyright (C) 2002-8 by Bruce Allen, http://smartmontools.sourceforge.net

=== START OF INFORMATION SECTION ===
Model Family:     Seagate Momentus 5400.3
Device Model:     ST9120822AS
Serial Number:    5LZ6PF8E
Firmware Version: 3.CDD
User Capacity:    120,034,123,776 bytes
Device is:        In smartctl database [for details use: -P show]
ATA Version is:   7
ATA Standard is:  Exact ATA specification draft version not indicated
Local Time is:    Sat Jul 26 16:27:38 2008 EEST
SMART support is: Available - device has SMART capability.
SMART support is: Enabled

=== START OF READ SMART DATA SECTION ===
SMART overall-health self-assessment test result: PASSED

General SMART Values:
Offline data collection status:  (0x82)	Offline data collection activity
					was completed without error.
					Auto Offline Data Collection: Enabled.
Self-test execution status:      (   0)	The previous self-test routine completed
					without error or no self-test has ever 
					been run.
Total time to complete Offline 
data collection: 		 ( 426) seconds.
Offline data collection
capabilities: 			 (0x5b) SMART execute Offline immediate.
					Auto Offline data collection on/off support.
					Suspend Offline collection upon new
					command.
					Offline surface scan supported.
					Self-test supported.
					No Conveyance Self-test supported.
					Selective Self-test supported.
SMART capabilities:            (0x0003)	Saves SMART data before entering
					power-saving mode.
					Supports SMART auto save timer.
Error logging capability:        (0x01)	Error logging supported.
					No General Purpose Logging support.
Short self-test routine 
recommended polling time: 	 (   2) minutes.
Extended self-test routine
recommended polling time: 	 ( 111) minutes.
SCT capabilities: 	       (0x0001)	SCT Status supported.

SMART Attributes Data Structure revision number: 10
Vendor Specific SMART Attributes with Thresholds:
ID# ATTRIBUTE_NAME          FLAG     VALUE WORST THRESH TYPE      UPDATED  WHEN_FAILED RAW_VALUE
  1 Raw_Read_Error_Rate     0x000f   106   100   006    Pre-fail  Always       -       11829174
  3 Spin_Up_Time            0x0003   099   099   085    Pre-fail  Always       -       0
  4 Start_Stop_Count        0x0032   100   100   020    Old_age   Always       -       361
  5 Reallocated_Sector_Ct   0x0033   100   100   036    Pre-fail  Always       -       0
  7 Seek_Error_Rate         0x000f   076   060   030    Pre-fail  Always       -       49086662
  9 Power_On_Hours          0x0032   099   099   000    Old_age   Always       -       1662
 10 Spin_Retry_Count        0x0013   100   100   034    Pre-fail  Always       -       0
 12 Power_Cycle_Count       0x0032   100   100   020    Old_age   Always       -       374
187 Reported_Uncorrect      0x0032   100   100   000    Old_age   Always       -       0
189 High_Fly_Writes         0x003a   096   096   000    Old_age   Always       -       4
190 Airflow_Temperature_Cel 0x0022   057   046   045    Old_age   Always       -       43 (Lifetime Min/Max 43/45)
192 Power-Off_Retract_Count 0x0032   100   100   000    Old_age   Always       -       278
193 Load_Cycle_Count        0x0032   097   097   000    Old_age   Always       -       6611
194 Temperature_Celsius     0x0022   043   054   000    Old_age   Always       -       43 (0 14 0 0)
195 Hardware_ECC_Recovered  0x001a   082   060   000    Old_age   Always       -       216850924
197 Current_Pending_Sector  0x0012   100   100   000    Old_age   Always       -       0
198 Offline_Uncorrectable   0x0010   100   100   000    Old_age   Offline      -       0
199 UDMA_CRC_Error_Count    0x003e   200   200   000    Old_age   Always       -       0
200 Multi_Zone_Error_Rate   0x0000   100   253   000    Old_age   Offline      -       0
202 TA_Increase_Count       0x0032   100   253   000    Old_age   Always       -       0

SMART Error Log Version: 1
No Errors Logged

SMART Self-test log structure revision number 1
Num  Test_Description    Status                  Remaining  LifeTime(hours)  LBA_of_first_error
# 1  Short offline       Completed without error       00%      1478         -
# 2  Short offline       Completed without error       00%         1         -
# 3  Short offline       Completed without error       00%         0         -
# 4  Short offline       Completed without error       00%         0         -

SMART Selective self-test log data structure revision number 1
 SPAN  MIN_LBA  MAX_LBA  CURRENT_TEST_STATUS
    1        0        0  Not_testing
    2        0        0  Not_testing
    3        0        0  Not_testing
    4        0        0  Not_testing
    5        0        0  Not_testing
Selective self-test flags (0x0):
  After scanning selected spans, do NOT read-scan remainder of disk.
If Selective self-test is pending on power-up, resume after 0 minute delay.


^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: Seagate HDD Frequent Head Unload - hdparm/dmidecode/smartctl output
  2008-07-26 13:34 Seagate HDD Frequent Head Unload - hdparm/dmidecode/smartctl output Ivan N. Zlatev
@ 2008-07-28  7:28 ` Tejun Heo
  2008-07-28  9:04   ` Ivan N. Zlatev
  0 siblings, 1 reply; 8+ messages in thread
From: Tejun Heo @ 2008-07-28  7:28 UTC (permalink / raw)
  To: Ivan N. Zlatev; +Cc: linux-ide

[-- Attachment #1: Type: text/plain, Size: 804 bytes --]

Ivan N. Zlatev wrote:
> I am having frequent head unloads on a Dell Vostro 1400 laptop with a
> Seagate HDD. As explained on the Wiki[1] I am attaching for you the
> output of:
> 
>    * hdparm -I
>    * dmidecode
>    * smartctl --all (in addition)
> 
> I hope this information is useful for you.
> 
> I am currently using a workaround to prevent the unloads as described
> here - http://en.opensuse.org/Disk_Power_Management .
> 
> [1]
> http://ata.wiki.kernel.org/index.php/Known_issues#Drives_which_perform_frequent_head_unloads_under_Linux

Can you please test the attached storage-fixup.conf?  If you're on suse,
just do "zypper install storage-fixup" and replace
/etc/storage-fixup.conf with the attached file, remove the manual
workaround and see whether the problem is gone.

Thanks.

-- 
tejun

[-- Attachment #2: storage-fixup.conf --]
[-- Type: text/plain, Size: 1513 bytes --]

#
# /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@vger.kernel.org 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: 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 255 $DEV

^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: Seagate HDD Frequent Head Unload - hdparm/dmidecode/smartctl output
  2008-07-28  7:28 ` Tejun Heo
@ 2008-07-28  9:04   ` Ivan N. Zlatev
  2008-07-28  9:18     ` Tejun Heo
  0 siblings, 1 reply; 8+ messages in thread
From: Ivan N. Zlatev @ 2008-07-28  9:04 UTC (permalink / raw)
  To: Tejun Heo; +Cc: linux-ide

Tejun Heo wrote:
> Ivan N. Zlatev wrote:
>> I am having frequent head unloads on a Dell Vostro 1400 laptop with a
>> Seagate HDD. As explained on the Wiki[1] I am attaching for you the
>> output of:
>>
>>    * hdparm -I
>>    * dmidecode
>>    * smartctl --all (in addition)
>>
>> I hope this information is useful for you.
>>
>> I am currently using a workaround to prevent the unloads as described
>> here - http://en.opensuse.org/Disk_Power_Management .
>>
>> [1]
>> http://ata.wiki.kernel.org/index.php/Known_issues#Drives_which_perform_frequent_head_unloads_under_Linux
> 
> Can you please test the attached storage-fixup.conf?  If you're on suse,
> just do "zypper install storage-fixup" and replace
> /etc/storage-fixup.conf with the attached file, remove the manual
> workaround and see whether the problem is gone.
> 

I tested and it seems that the right value for my configuration is 254 
instead of 255. With 255 I still get spin downs.

BTW I noticed that on http://en.opensuse.org/Disk_Power_Management the 
script sets a combination of APM and spin-down time, e.g:

    [1] hdparm -q -B 200 -q -S 252 /dev/sda

With that I also don't get spin downs. So compared to:

    [2] hdparm  -B 254 /dev/sda

will [1] or [2] be better for the HDD in terms of power consumption and 
overheating? Would *not* disabling the APM for the HDD (is what 254/255 
do?), but setting the spin down timeout to something more sensible be 
better for the HDD? I have no idea if spinning down the head is the only 
thing HDDs do for power saving. I suppose you would know best?

Also on another note I accidentally saw two more potential entries for 
your storage-fixup on the linux-ide list (I do not know if you monitor it):

    * http://www.spinics.net/lists/linux-ide/msg24667.html
    * http://www.spinics.net/lists/linux-ide/msg24460.html

Kind Regards,
-- 
Ivan N. Zlatev

Web: http://www.i-nZ.net
"It's all some kind of whacked out conspiracy."


^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: Seagate HDD Frequent Head Unload - hdparm/dmidecode/smartctl output
  2008-07-28  9:04   ` Ivan N. Zlatev
@ 2008-07-28  9:18     ` Tejun Heo
  2008-08-02 13:01       ` Ivan N. Zlatev
  0 siblings, 1 reply; 8+ messages in thread
From: Tejun Heo @ 2008-07-28  9:18 UTC (permalink / raw)
  To: Ivan N. Zlatev; +Cc: linux-ide

Ivan N. Zlatev wrote:
> I tested and it seems that the right value for my configuration is 254
> instead of 255. With 255 I still get spin downs.

Ah... okay, so it should be 254.

> BTW I noticed that on http://en.opensuse.org/Disk_Power_Management the
> script sets a combination of APM and spin-down time, e.g:
> 
>    [1] hdparm -q -B 200 -q -S 252 /dev/sda
> 
> With that I also don't get spin downs. So compared to:
> 
>    [2] hdparm  -B 254 /dev/sda
> 
> will [1] or [2] be better for the HDD in terms of power consumption and
> overheating? Would *not* disabling the APM for the HDD (is what 254/255
> do?), but setting the spin down timeout to something more sensible be
> better for the HDD? I have no idea if spinning down the head is the only
> thing HDDs do for power saving. I suppose you would know best?

I have no idea at all.  The semantics for APM settings isn't strictly
defined so only the vendor knows what each range of values actually
does.  And devices don't even follow the loose definitions too well -
255 should stop unloading but it doesn't on some devices.

I'll set the value to 254 for your system for now.  If you find that 252
 or any other value is better, please lemme know.

> Also on another note I accidentally saw two more potential entries for
> your storage-fixup on the linux-ide list (I do not know if you monitor it):

I monitor the list but have accumulated quite some backlog during past
two weeks.  I'm going through them now.

>    * http://www.spinics.net/lists/linux-ide/msg24667.html
>    * http://www.spinics.net/lists/linux-ide/msg24460.html

Thanks a lot for the pointers & testing.

-- 
tejun

^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: Seagate HDD Frequent Head Unload - hdparm/dmidecode/smartctl output
  2008-07-28  9:18     ` Tejun Heo
@ 2008-08-02 13:01       ` Ivan N. Zlatev
  2008-08-03  8:23         ` Tejun Heo
  0 siblings, 1 reply; 8+ messages in thread
From: Ivan N. Zlatev @ 2008-08-02 13:01 UTC (permalink / raw)
  To: Tejun Heo; +Cc: linux-ide

Hi again,

It appears that the storage-fixup rule [1] doesn't work. Verbose
output below[2]. Also I saw that you use hdparm -i and sg_inq so
output from those for the HDD too. I badly failed to understand this
brainf*** called bash :-), so may be you can advice what's going
wrong? Thanks in advance.


[1]

# 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

[2]

[/home/ivanz]$ storage-fixup -v -d
storage-fixup: I 2 storage devices
storage-fixup: C ata:model:0 ST9120822AS
storage-fixup: C ata:rev:0 3.CDD
storage-fixup: C ata:serial:0 5LZ6PF8E
storage-fixup: C scsi:vendor:0 ATA
storage-fixup: C scsi:model:0 ST9120822AS
storage-fixup: C scsi:rev:0 3.CD
storage-fixup: C scsi:serial:0 5LZ6PF8E
storage-fixup: C ata:model:1 TSSTcorp DVD+/-RW TS-L632H
storage-fixup: C ata:rev:1 D200
storage-fixup: C ata:serial:1
storage-fixup: C scsi:vendor:1 TSSTcorp
storage-fixup: C scsi:model:1 DVD+-RW TS-L632H
storage-fixup: C scsi:rev:1 D200
storage-fixup: C scsi:serial:1
storage-fixup: C dmi:system-manufacturer:0 Dell Inc.
storage-fixup: N 22 tp-t60 dmi system-manufacturer=LENOVO
storage-fixup: N 30 hp-dv6500 dmi system-manufacturer=Hewlett-Packard
storage-fixup: Y 38 dell-e1505 dmi system-manufacturer=Dell Inc.
storage-fixup: C dmi:system-product-name:0 Vostro 1400
storage-fixup: N 39 dell-e1505 dmi system-product-name=MM061
storage-fixup: Y 45 dell-Vostro-1400 dmi system-manufacturer=Dell Inc.
storage-fixup: N 46 dell-Vostro-1400 dmi system-product-name=Vostro 1400

[3]

[/home/ivanz]$ sg_inq /dev/sda
standard INQUIRY:
  PQual=0  Device_type=0  RMB=0  version=0x05  [SPC-3]
  [AERC=0]  [TrmTsk=0]  NormACA=0  HiSUP=0  Resp_data_format=2
  SCCS=0  ACC=0  TPGS=0  3PC=0  Protect=0  BQue=0
  EncServ=0  MultiP=0  [MChngr=0]  [ACKREQQ=0]  Addr16=0
  [RelAdr=0]  WBus16=0  Sync=0  Linked=0  [TranDis=0]  CmdQue=0
  [SPI: Clocking=0x0  QAS=0  IUS=0]
    length=96 (0x60)   Peripheral device type: disk
 Vendor identification: ATA
 Product identification: ST9120822AS
 Product revision level: 3.CD
 Unit serial number:             5LZ6PF8E


[4]

[/home/ivanz]$ hdparm -i /dev/sda

/dev/sda:

 Model=ST9120822AS                             , FwRev=3.CDD   ,
SerialNo=            5LZ6PF8E
 Config={ HardSect NotMFM HdSw>15uSec Fixed DTR>10Mbs RotSpdTol>.5% }
 RawCHS=16383/16/63, TrkSize=0, SectSize=0, ECCbytes=4
 BuffType=unknown, BuffSize=8192kB, MaxMultSect=16, MultSect=?8?
 CurCHS=16383/16/63, CurSects=16514064, LBA=yes, LBAsects=234441648
 IORDY=on/off, tPIO={min:240,w/IORDY:120}, tDMA={min:120,rec:120}
 PIO modes:  pio0 pio1 pio2 pio3 pio4
 DMA modes:  mdma0 mdma1 mdma2
 UDMA modes: udma0 udma1 udma2 udma3 udma4 udma5 *udma6
 AdvancedPM=yes: unknown setting WriteCache=enabled
 Drive conforms to: Unspecified:  ATA/ATAPI-1,2,3,4,5,6,7

 * signifies the current active mode

^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: Seagate HDD Frequent Head Unload - hdparm/dmidecode/smartctl output
  2008-08-02 13:01       ` Ivan N. Zlatev
@ 2008-08-03  8:23         ` Tejun Heo
  2008-08-03 15:29           ` Ivan N. Zlatev
  0 siblings, 1 reply; 8+ messages in thread
From: Tejun Heo @ 2008-08-03  8:23 UTC (permalink / raw)
  To: Ivan N. Zlatev; +Cc: linux-ide

[-- Attachment #1: Type: text/plain, Size: 479 bytes --]

Ivan N. Zlatev wrote:
> Hi again,
> 
> It appears that the storage-fixup rule [1] doesn't work. Verbose
> output below[2]. Also I saw that you use hdparm -i and sg_inq so
> output from those for the HDD too. I badly failed to understand this
> brainf*** called bash :-), so may be you can advice what's going
> wrong? Thanks in advance.

Can you please the attached updated script?  The previous version failed
match if dmi string contains leading or trailing blanks.

-- 
tejun

[-- Attachment #2: storage-fixup --]
[-- Type: text/plain, Size: 8555 bytes --]

#! /bin/bash
#
# storage-fixup			- Tejun Heo <teheo@suse.de>
#
# 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

^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: Seagate HDD Frequent Head Unload - hdparm/dmidecode/smartctl output
  2008-08-03  8:23         ` Tejun Heo
@ 2008-08-03 15:29           ` Ivan N. Zlatev
  2008-08-03 22:42             ` Tejun Heo
  0 siblings, 1 reply; 8+ messages in thread
From: Ivan N. Zlatev @ 2008-08-03 15:29 UTC (permalink / raw)
  To: Tejun Heo; +Cc: linux-ide

On Sun, Aug 3, 2008 at 11:23 AM, Tejun Heo <teheo@suse.de> wrote:
> Ivan N. Zlatev wrote:
>> Hi again,
>>
>> It appears that the storage-fixup rule [1] doesn't work. Verbose
>> output below[2]. Also I saw that you use hdparm -i and sg_inq so
>> output from those for the HDD too. I badly failed to understand this
>> brainf*** called bash :-), so may be you can advice what's going
>> wrong? Thanks in advance.
>
> Can you please the attached updated script?  The previous version failed
> match if dmi string contains leading or trailing blanks.
>

That works, thanks. It might be a good idea to get storage-fixup
pushed as a compulsory update for openSUSE 11? Thanks again.

^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: Seagate HDD Frequent Head Unload - hdparm/dmidecode/smartctl output
  2008-08-03 15:29           ` Ivan N. Zlatev
@ 2008-08-03 22:42             ` Tejun Heo
  0 siblings, 0 replies; 8+ messages in thread
From: Tejun Heo @ 2008-08-03 22:42 UTC (permalink / raw)
  To: Ivan N. Zlatev; +Cc: linux-ide

Ivan N. Zlatev wrote:
> On Sun, Aug 3, 2008 at 11:23 AM, Tejun Heo <teheo@suse.de> wrote:
>> Ivan N. Zlatev wrote:
>>> Hi again,
>>>
>>> It appears that the storage-fixup rule [1] doesn't work. Verbose
>>> output below[2]. Also I saw that you use hdparm -i and sg_inq so
>>> output from those for the HDD too. I badly failed to understand this
>>> brainf*** called bash :-), so may be you can advice what's going
>>> wrong? Thanks in advance.
>> Can you please the attached updated script?  The previous version failed
>> match if dmi string contains leading or trailing blanks.
>>
> 
> That works, thanks. It might be a good idea to get storage-fixup
> pushed as a compulsory update for openSUSE 11? Thanks again.

Yeah, I'll see to it.

Thanks.

-- 
tejun

^ permalink raw reply	[flat|nested] 8+ messages in thread

end of thread, other threads:[~2008-08-03 22:43 UTC | newest]

Thread overview: 8+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2008-07-26 13:34 Seagate HDD Frequent Head Unload - hdparm/dmidecode/smartctl output Ivan N. Zlatev
2008-07-28  7:28 ` Tejun Heo
2008-07-28  9:04   ` Ivan N. Zlatev
2008-07-28  9:18     ` Tejun Heo
2008-08-02 13:01       ` Ivan N. Zlatev
2008-08-03  8:23         ` Tejun Heo
2008-08-03 15:29           ` Ivan N. Zlatev
2008-08-03 22:42             ` Tejun Heo

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).