Sunday, October 28, 2007

Laptop HDD bug

There have been issues on broken HDD on laptop with the recent Ubuntu release installed. Basically it's related to APM feature (which might be specific to the BIOS) whereby the head is retracted when it is on idle state. It is solved by setting off the APM: hdparm -B 255 /dev/hda1. More infos:
http://paul.luon.net/journal/hacking/BrokenHDDs.html
https://bugs.launchpad.net/ubuntu/+source/acpi-support/+bug/59695
http://ubuntudemon.wordpress.com/2007/10/26/laptop-hardrive-killer-bug/
I've created a script using Python to check the load cycle count of your hdd and whether it has increased by 90 on a daily basis. There is not much comment, apart from the beginning lines and I don't intend to add any more comments on it.
To use it, you'll have to run it at least twice. The first time, it will create a timestamp and save the initial load cycle count of your hard drives. The next time, preferably after several hours (or days), it'll check on whether the load cycle has increased by a significant number (90 cycles on a daily basis) and let you know if it has. That simple, cool (or useless) huh !
# The script is used to check whether harddrive load cycle count has increased by 90 cycles
# on a daily basis (24 hour)
# it doesn't run as a daemon
# to run : python hdcheck.py
# it will create 2 files:
# -timestamp.dat is used to check the delta time since the first run
# -lcc.dat is used to check the increase in load cycle count
# The next time you run it, it will check the current load cycle count and do the calculation
# To start anew delete those 2 files, and rerun
# GAH_2007

import re
import os
import time
import datetime
import cPickle

put, get = os.popen4("df")
dev = []
current_lcc = {}
for dfout in get.readlines():
p = re.compile("/dev/\w\w\w[1-9]")
m = p.match(dfout)
if m:
dev.append(m.group())
for ent in dev:
put, get = os.popen4 ("smartctl -a "+ent+ "| grep Load_Cycle_Count")
for smartctlout in get.readlines():
p = re.compile("\d*\n")
m = p.findall(smartctlout)
p = re.compile("\d*")
n = p.match(m[0])
if n:
current_lcc[ent] = n.group()
time = time.mktime(datetime.datetime.now().timetuple())/3600.0
delta_time = 0
try:
f = open ("timestamp.dat", "r")
timestamp = cPickle.load(f)
f.close()
delta_time = time - timestamp
except:
timestamp = 0
if (timestamp):
print "Time since the first run is", delta_time, "hour"
else:
try:
f = open ("timestamp.dat", "w")
cPickle.dump(time, f)
f.close()
except:
print "unable to save timestamp"

try:
f = open ("lcc.dat", "r")
previous_lcc = cPickle.load(f)
f.close()
lcc_increase = {}
except:
previous_lcc = 0

if (previous_lcc):
for dev in current_lcc.keys():
lcc_increase[dev] = eval(current_lcc[dev]) - eval(previous_lcc[dev])
else:
try:
f = open ("lcc.dat", "w")
cPickle.dump(current_lcc, f)
f.close()
except:
print "unable to save current load cycle count data"

if (timestamp and previous_lcc):
for dev in current_lcc.keys():
lcc_increase_daily = lcc_increase[dev] * 24.0 / delta_time
print dev + " load cycle count increases by "+ str(lcc_increase[dev])+ " cycles("+str(lcc_increase_daily)+" on daily basis)"
if (lcc_increase_daily > 90):
print " Load cycle count increase by more than 90 !!"

No comments: