X-Git-Url: https://git.cweiske.de/enigma2.git/blobdiff_plain/0621e74942fa09f300e8b63d5e586db4575ba180..337572d8d61c37c2121a96ec7ab79e191eaa2e29:/lib/python/Components/Harddisk.py diff --git a/lib/python/Components/Harddisk.py b/lib/python/Components/Harddisk.py index d739e984..404baafa 100644 --- a/lib/python/Components/Harddisk.py +++ b/lib/python/Components/Harddisk.py @@ -2,7 +2,8 @@ from os import system, listdir, statvfs, popen, makedirs, readlink, stat, major, from Tools.Directories import SCOPE_HDD, resolveFilename from Tools.CList import CList from SystemInfo import SystemInfo -import string +import string, time +from Components.Console import Console def tryOpen(filename): try: @@ -18,6 +19,8 @@ class Harddisk: tmp = procfile.readline().split(':') s_major = int(tmp[0]) s_minor = int(tmp[1]) + self.max_idle_time = 0 + self.idle_running = False for disc in listdir("/dev/discs"): path = readlink('/dev/discs/'+disc) devidex = '/dev/discs/'+disc+'/' @@ -28,6 +31,7 @@ class Harddisk: self.devidex = devidex self.devidex2 = devidex2 print "new Harddisk", device, '->', self.devidex, '->', self.devidex2 + self.startIdle() break def __lt__(self, ob): @@ -93,7 +97,7 @@ class Harddisk: line = procfile.readline() if line == "": break - if line.startswith(self.devidex): + if line.startswith(self.devidex) or line.startswith(self.devidex2): parts = line.strip().split(" ") try: stat = statvfs(parts[1]) @@ -126,7 +130,7 @@ class Harddisk: cmd = "/bin/umount" for line in procfile: - if line.startswith(self.devidex): + if line.startswith(self.devidex) or line.startswith(self.devidex2): parts = line.split() cmd = ' '.join([cmd, parts[1]]) @@ -213,6 +217,64 @@ class Harddisk: def getDeviceName(self): return self.getDeviceDir() + "disc" + # the HDD idle poll daemon. + # as some harddrives have a buggy standby timer, we are doing this by hand here. + # first, we disable the hardware timer. then, we check every now and then if + # any access has been made to the disc. If there has been no access over a specifed time, + # we set the hdd into standby. + def readStats(self): + l = open("/sys/block/%s/stat" % self.device).read() + nr_read = int(l[:8].strip()) + nr_write = int(l[4*9:4*9+8].strip()) + return nr_read, nr_write + + def startIdle(self): + self.last_access = time.time() + self.last_stat = 0 + self.is_sleeping = False + from enigma import eTimer + + # disable HDD standby timer + Console().ePopen(("hdparm", "hdparm", "-S0", (self.devidex + "disc"))) + self.timer = eTimer() + self.timer.callback.append(self.runIdle) + self.idle_running = True + self.setIdleTime(self.max_idle_time) # kick the idle polling loop + + def runIdle(self): + if not self.max_idle_time: + return + t = time.time() + + idle_time = t - self.last_access + + l = sum(self.readStats()) + + if l != self.last_stat: # access + self.last_stat = l + self.last_access = t + self.idle_time = 0 + self.is_sleeping = False + + #print "[IDLE]", idle_time, self.max_idle_time, self.is_sleeping + if idle_time >= self.max_idle_time and not self.is_sleeping: + self.setSleep() + self.is_sleeping = True + + def setSleep(self): + Console().ePopen(("hdparm", "hdparm", "-y", (self.devidex + "disc"))) + + def setIdleTime(self, idle): + self.max_idle_time = idle + if self.idle_running: + if not idle: + self.timer.stop() + else: + self.timer.start(idle * 250, False) # poll 4 times per period. + + def isSleeping(self): + return self.is_sleeping + class Partition: def __init__(self, mountpoint, device = None, description = "", force_mounted = False): self.mountpoint = mountpoint @@ -252,9 +314,10 @@ class Partition: DEVICEDB = \ { # dm8000: - "devices/platform/brcm-ehci.0/usb1/1-1/1-1.1/1-1.1:1.0": "Front USB Slot", - "devices/platform/brcm-ehci.0/usb1/1-1/1-1.2/1-1.2:1.0": "Back, upper USB Slot", - "devices/platform/brcm-ehci.0/usb1/1-1/1-1.3/1-1.3:1.0": "Back, lower USB Slot", + "/devices/platform/brcm-ehci.0/usb1/1-1/1-1.1/1-1.1:1.0": "Front USB Slot", + "/devices/platform/brcm-ehci.0/usb1/1-1/1-1.2/1-1.2:1.0": "Back, upper USB Slot", + "/devices/platform/brcm-ehci.0/usb1/1-1/1-1.3/1-1.3:1.0": "Back, lower USB Slot", + "/devices/platform/brcm-ehci-1.1/usb2/2-1/2-1:1.0/host1/target1:0:0/1:0:0:0": "DVD Drive", } class HarddiskManager: @@ -352,14 +415,10 @@ class HarddiskManager: if not physdev: dev, part = self.splitDeviceName(device) try: - physdev = readlink("/sys/block/" + dev + "/device")[6:] + physdev = readlink("/sys/block/" + dev + "/device")[5:] except OSError: - print "couldn't determine blockdev physdev for device", dev, "try", device, "now" - try: - physdev = readlink("/sys/block/" + device + "/device")[6:] - except OSError: - physdev = dev - print "couldn't determine blockdev physdev for device", device + physdev = dev + print "couldn't determine blockdev physdev for device", device # device is the device name, without /dev # physdev is the physical device path, which we (might) use to determine the userfriendly name @@ -423,22 +482,21 @@ class HarddiskManager: return [x for x in parts if not x.device or x.device in devs] def splitDeviceName(self, devname): - dev = "" - part = "" - for i in devname: - if i in string.digits: - part += i - else: - dev += i + # this works for: sdaX, hdaX, sr0 (which is in fact dev="sr0", part=""). It doesn't work for other names like mtdblock3, but they are blacklisted anyway. + dev = devname[:3] + part = devname[3:] + for p in part: + if p not in string.digits: + return devname, 0 return dev, part and int(part) or 0 def getUserfriendlyDeviceName(self, dev, phys): dev, part = self.splitDeviceName(dev) description = "External Storage %s" % dev try: - description = open("/sys/" + phys + "/model").read().strip() + description = open("/sys" + phys + "/model").read().strip() except IOError, s: - print "couldn't read model (from /sys/" + phys + "/model): ", s + print "couldn't read model: ", s for physdevprefix, pdescription in DEVICEDB.items(): if phys.startswith(physdevprefix): description = pdescription