Delete Harddisk.py

This commit is contained in:
gutosie
2020-05-11 16:50:17 +03:00
committed by GitHub
parent 433f1e7151
commit 363ea9872a

View File

@@ -1,968 +0,0 @@
# -*- coding: utf-8 -*-
#from __future__ import print_function
#from Plugins.Extensions.NeoBoot.__init__ import _
import os
import time
from Tools.Directories import fileExists, pathExists#, fileCheck
from Tools.CList import CList
from Components.SystemInfo import SystemInfo
from Components.Console import Console
from Task import LoggingTask
import Task
def readFile(filename):
file = open(filename)
data = file.read().strip()
file.close()
return data
def getProcMounts():
try:
mounts = open('/proc/mounts', 'r')
except IOError as ex:
print '[Harddisk] Failed to open /proc/mounts', ex
return []
result = [ line.strip().split(' ') for line in mounts ]
for item in result:
item[1] = item[1].replace('\\040', ' ')
return result
def getNonNetworkMediaMounts():
return [ x[1] for x in getProcMounts() if x[1].startswith('/media/') and not x[0].startswith('//') ]
def isFileSystemSupported(filesystem):
try:
for fs in open('/proc/filesystems', 'r'):
if fs.strip().endswith(filesystem):
return True
return False
except Exception as ex:
print '[Harddisk] Failed to read /proc/filesystems:', ex
def findMountPoint(path):
path = os.path.abspath(path)
while not os.path.ismount(path):
path = os.path.dirname(path)
return path
DEVTYPE_UDEV = 0
DEVTYPE_DEVFS = 1
class Harddisk():
def __init__(self, device, removable = False):
self.device = device
if os.access('/dev/.udev', 0):
self.type = DEVTYPE_UDEV
elif os.access('/dev/.devfsd', 0):
self.type = DEVTYPE_DEVFS
else:
print '[Harddisk] Unable to determine structure of /dev'
self.type = -1
self.card = False
self.max_idle_time = 0
self.idle_running = False
self.last_access = time.time()
self.last_stat = 0
self.timer = None
self.is_sleeping = False
self.dev_path = ''
self.disk_path = ''
self.mount_path = None
self.mount_device = None
self.phys_path = os.path.realpath(self.sysfsPath('device'))
self.removable = removable
self.internal = 'pci' in self.phys_path or 'ahci' in self.phys_path or 'sata' in self.phys_path
try:
data = open('/sys/block/%s/queue/rotational' % device, 'r').read().strip()
self.rotational = int(data)
except:
self.rotational = True
if self.type == DEVTYPE_UDEV:
self.dev_path = '/dev/' + self.device
self.disk_path = self.dev_path
self.card = 'sdhci' in self.phys_path
elif self.type == DEVTYPE_DEVFS:
tmp = readFile(self.sysfsPath('dev')).split(':')
s_major = int(tmp[0])
s_minor = int(tmp[1])
for disc in os.listdir('/dev/discs'):
dev_path = os.path.realpath('/dev/discs/' + disc)
disk_path = dev_path + '/disc'
try:
rdev = os.stat(disk_path).st_rdev
except OSError:
continue
if s_major == os.major(rdev) and s_minor == os.minor(rdev):
self.dev_path = dev_path
self.disk_path = disk_path
break
self.card = self.device[:2] == 'hd' and 'host0' not in self.dev_path
print '[Harddisk] new device', self.device, '->', self.dev_path, '->', self.disk_path
if not removable and not self.card:
self.startIdle()
return
def __lt__(self, ob):
return self.device < ob.device
def partitionPath(self, n):
if self.type == DEVTYPE_UDEV:
if self.dev_path.startswith('/dev/mmcblk0'):
return self.dev_path + 'p' + n
else:
return self.dev_path + n
elif self.type == DEVTYPE_DEVFS:
return self.dev_path + '/part' + n
def sysfsPath(self, filename):
return os.path.join('/sys/block/', self.device, filename)
def stop(self):
if self.timer:
self.timer.stop()
self.timer.callback.remove(self.runIdle)
def bus(self):
ret = _('External')
if self.type == DEVTYPE_UDEV:
type_name = ' (SD/MMC)'
elif self.type == DEVTYPE_DEVFS:
type_name = ' (CF)'
if self.card:
ret += type_name
else:
if self.internal:
ret = _('Internal')
if not self.rotational:
ret += ' (SSD)'
return ret
def diskSize(self):
cap = 0
try:
line = readFile(self.sysfsPath('size'))
cap = int(line)
return cap / 1000 * 512 / 1000
except:
dev = self.findMount()
if dev:
try:
stat = os.statvfs(dev)
cap = int(stat.f_blocks * stat.f_bsize)
return cap / 1000 / 1000
except:
pass
return cap
def capacity(self):
cap = self.diskSize()
if cap == 0:
return ''
if cap < 1000:
return _('%03d MB') % cap
return _('%d.%03d GB') % (cap / 1000, cap % 1000)
def model(self):
try:
if self.device[:2] == 'hd':
return readFile('/proc/ide/' + self.device + '/model')
if self.device[:2] == 'sd':
vendor = readFile(self.sysfsPath('device/vendor'))
model = readFile(self.sysfsPath('device/model'))
return vendor + '(' + model + ')'
if self.device.startswith('mmcblk0'):
return readFile(self.sysfsPath('device/name'))
raise Exception, '[Harddisk] no hdX or sdX or mmcX'
except Exception as e:
print '[Harddisk] Failed to get model:', e
return '-?-'
def free(self):
dev = self.findMount()
if dev:
try:
stat = os.statvfs(dev)
return stat.f_bfree / 1000 * (stat.f_bsize / 1024)
except:
pass
return -1
def numPartitions(self):
numPart = -1
if self.type == DEVTYPE_UDEV:
try:
devdir = os.listdir('/dev')
except OSError:
return -1
for filename in devdir:
if filename.startswith(self.device):
numPart += 1
elif self.type == DEVTYPE_DEVFS:
try:
idedir = os.listdir(self.dev_path)
except OSError:
return -1
for filename in idedir:
if filename.startswith('disc'):
numPart += 1
if filename.startswith('part'):
numPart += 1
return numPart
def mountDevice(self):
for parts in getProcMounts():
if os.path.realpath(parts[0]).startswith(self.dev_path):
self.mount_device = parts[0]
self.mount_path = parts[1]
return parts[1]
return None
def enumMountDevices(self):
for parts in getProcMounts():
if os.path.realpath(parts[0]).startswith(self.dev_path):
yield parts[1]
def findMount(self):
if self.mount_path is None:
return self.mountDevice()
else:
return self.mount_path
def unmount(self):
dev = self.mountDevice()
if dev is None:
return 0
else:
cmd = 'umount ' + dev
print '[Harddisk]', cmd
res = os.system(cmd)
return res >> 8
def createPartition(self):
cmd = 'printf "8,\n;0,0\n;0,0\n;0,0\ny\n" | sfdisk -f -uS ' + self.disk_path
res = os.system(cmd)
return res >> 8
def mkfs(self):
return 1
def mount(self):
if self.mount_device is None:
dev = self.partitionPath('1')
else:
dev = self.mount_device
try:
fstab = open('/etc/fstab')
lines = fstab.readlines()
fstab.close()
except IOError:
return -1
for line in lines:
parts = line.strip().split(' ')
fspath = os.path.realpath(parts[0])
if fspath == dev:
print '[Harddisk] mounting:', fspath
cmd = 'mount -t auto ' + fspath
res = os.system(cmd)
return res >> 8
res = -1
if self.type == DEVTYPE_UDEV:
res = os.system('hdparm -z ' + self.disk_path)
from time import sleep
sleep(3)
return res >> 8
def fsck(self):
return 1
def killPartitionTable(self):
zero = 512 * '\x00'
h = open(self.dev_path, 'wb')
for i in range(9):
h.write(zero)
h.close()
def killPartition(self, n):
zero = 512 * '\x00'
part = self.partitionPath(n)
h = open(part, 'wb')
for i in range(3):
h.write(zero)
h.close()
def createInitializeJob(self):
job = Task.Job(_('Initializing storage device...'))
size = self.diskSize()
print '[HD] size: %s MB' % size
task = UnmountTask(job, self)
task = Task.PythonTask(job, _('Removing partition table'))
task.work = self.killPartitionTable
task.weighting = 1
task = Task.LoggingTask(job, _('Rereading partition table'))
task.weighting = 1
task.setTool('hdparm')
task.args.append('-z')
task.args.append(self.disk_path)
task = Task.ConditionTask(job, _('Waiting for partition'), timeoutCount=20)
task.check = lambda : not os.path.exists(self.partitionPath('1'))
task.weighting = 1
if os.path.exists('/usr/sbin/parted'):
use_parted = True
elif size > 2097151:
addInstallTask(job, 'parted')
use_parted = True
else:
use_parted = False
task = Task.LoggingTask(job, _('Creating partition'))
task.weighting = 5
if use_parted:
task.setTool('parted')
if size < 1024:
alignment = 'min'
else:
alignment = 'opt'
if size > 2097151:
parttype = 'gpt'
else:
parttype = 'msdos'
task.args += ['-a',
alignment,
'-s',
self.disk_path,
'mklabel',
parttype,
'mkpart',
'primary',
'0%',
'100%']
else:
task.setTool('sfdisk')
task.args.append('-f')
task.args.append('-uS')
task.args.append(self.disk_path)
if size > 128000:
print '[HD] Detected >128GB disk, using 4k alignment'
task.initial_input = '8,,L\n;0,0\n;0,0\n;0,0\ny\n'
else:
task.initial_input = ',,L\n;\n;\n;\ny\n'
task = Task.ConditionTask(job, _('Waiting for partition'))
task.check = lambda : os.path.exists(self.partitionPath('1'))
task.weighting = 1
task = MkfsTask(job, _('Creating filesystem'))
big_o_options = ['dir_index']
if isFileSystemSupported('ext4'):
task.setTool('mkfs.ext4')
if size > 20000:
try:
version = map(int, open('/proc/version', 'r').read().split(' ', 4)[2].split('.', 2)[:2])
if version[0] > 3 or version[0] > 2 and version[1] >= 2:
task.args += ['-C', '262144']
big_o_options.append('bigalloc')
except Exception as ex:
print 'Failed to detect Linux version:', ex
else:
task.setTool('mkfs.ext3')
if size > 250000:
task.args += ['-T',
'largefile',
'-N',
'262144']
big_o_options.append('sparse_super')
elif size > 16384:
task.args += ['-T', 'largefile']
big_o_options.append('sparse_super')
elif size > 2048:
task.args += ['-T',
'largefile',
'-N',
str(size * 32)]
task.args += ['-m0',
'-O',
','.join(big_o_options),
self.partitionPath('1')]
task = MountTask(job, self)
task.weighting = 3
task = Task.ConditionTask(job, _('Waiting for mount'), timeoutCount=20)
task.check = self.mountDevice
task.weighting = 1
return job
def initialize(self):
return -5
def check(self):
return -5
def createCheckJob(self):
job = Task.Job(_('Checking filesystem...'))
if self.findMount():
UnmountTask(job, self)
dev = self.mount_device
else:
dev = self.partitionPath('1')
task = Task.LoggingTask(job, 'fsck')
task.setTool('fsck.ext3')
task.args.append('-f')
task.args.append('-p')
task.args.append(dev)
MountTask(job, self)
task = Task.ConditionTask(job, _('Waiting for mount'))
task.check = self.mountDevice
return job
def getDeviceDir(self):
return self.dev_path
def getDeviceName(self):
return self.disk_path
def readStats(self):
try:
l = open('/sys/block/%s/stat' % self.device).read()
except IOError:
return (-1, -1)
data = l.split(None, 5)
return (int(data[0]), int(data[4]))
def startIdle(self):
from enigma import eTimer
if self.bus() == _('External'):
Console().ePopen(('sdparm',
'sdparm',
'--set=SCT=0',
self.disk_path))
else:
Console().ePopen(('hdparm',
'hdparm',
'-S0',
self.disk_path))
self.timer = eTimer()
self.timer.callback.append(self.runIdle)
self.idle_running = True
self.setIdleTime(self.max_idle_time)
def runIdle(self):
if not self.max_idle_time:
return
t = time.time()
idle_time = t - self.last_access
stats = self.readStats()
l = sum(stats)
if l != self.last_stat and l >= 0:
self.last_stat = l
self.last_access = t
idle_time = 0
self.is_sleeping = False
if idle_time >= self.max_idle_time and not self.is_sleeping:
self.setSleep()
self.is_sleeping = True
def setSleep(self):
if self.bus() == _('External'):
Console().ePopen(('sdparm',
'sdparm',
'--flexible',
'--readonly',
'--command=stop',
self.disk_path))
else:
Console().ePopen(('hdparm',
'hdparm',
'-y',
self.disk_path))
def setIdleTime(self, idle):
self.max_idle_time = idle
if self.idle_running:
if not idle:
self.timer.stop()
else:
self.timer.start(idle * 100, False)
def isSleeping(self):
return self.is_sleeping
class Partition():
def __init__(self, mountpoint, device = None, description = '', force_mounted = False):
self.mountpoint = mountpoint
self.description = description
self.force_mounted = mountpoint and force_mounted
self.is_hotplug = force_mounted
self.device = device
def __str__(self):
return 'Partition(mountpoint=%s,description=%s,device=%s)' % (self.mountpoint, self.description, self.device)
def stat(self):
if self.mountpoint:
return os.statvfs(self.mountpoint)
raise OSError, 'Device %s is not mounted' % self.device
def free(self):
try:
s = self.stat()
return s.f_bavail * s.f_bsize
except OSError:
return None
return None
def total(self):
try:
s = self.stat()
return s.f_blocks * s.f_bsize
except OSError:
return None
return None
def tabbedDescription(self):
if self.mountpoint.startswith('/media/net') or self.mountpoint.startswith('/media/autofs'):
return self.description
return self.description + '\t' + self.mountpoint
def mounted(self, mounts = None):
if self.force_mounted:
return True
else:
if self.mountpoint:
if mounts is None:
mounts = getProcMounts()
for parts in mounts:
if self.mountpoint.startswith(parts[1]):
return True
return False
def filesystem(self, mounts = None):
if self.mountpoint:
if mounts is None:
mounts = getProcMounts()
for fields in mounts:
if self.mountpoint.endswith('/') and not self.mountpoint == '/':
if fields[1] + '/' == self.mountpoint:
return fields[2]
elif fields[1] == self.mountpoint:
return fields[2]
return ''
def addInstallTask(job, package):
task = Task.LoggingTask(job, 'update packages')
task.setTool('opkg')
task.args.append('update')
task = Task.LoggingTask(job, 'Install ' + package)
task.setTool('opkg')
task.args.append('install')
task.args.append(package)
class HarddiskManager():
def __init__(self):
self.hdd = []
self.cd = ''
self.partitions = []
self.devices_scanned_on_init = []
self.on_partition_list_change = CList()
self.enumerateBlockDevices()
p = (('/media/hdd', _('Hard disk')),
('/media/card', _('Card')),
('/media/cf', _('Compact flash')),
('/media/mmc1', _('MMC card')),
('/media/net', _('Network mount')),
('/media/net1', _('Network mount %s') % '1'),
('/media/net2', _('Network mount %s') % '2'),
('/media/net3', _('Network mount %s') % '3'),
('/media/ram', _('Ram disk')),
('/media/usb', _('USB stick')),
('/media/usb1', _('USB1 stick')),
('/media/usb2', _('USB2 stick')),
('/', _('Internal flash')))
known = set([ os.path.normpath(a.mountpoint) for a in self.partitions if a.mountpoint ])
for m, d in p:
if m not in known and os.path.ismount(m):
self.partitions.append(Partition(mountpoint=m, description=d))
def getBlockDevInfo(self, blockdev):
HasMMC = fileExists('/proc/cmdline') and 'root=/dev/mmcblk' in open('/proc/cmdline', 'r').read()
devpath = '/sys/block/' + blockdev
error = False
removable = False
blacklisted = False
is_cdrom = False
partitions = []
try:
if os.path.exists(devpath + '/removable'):
removable = bool(int(readFile(devpath + '/removable')))
if os.path.exists(devpath + '/dev'):
dev = int(readFile(devpath + '/dev').split(':')[0])
else:
dev = None
blacklisted = dev in [1,
7,
31,
253,
254] + (['HasMMC'] and [179] or [])
if blockdev[0:2] == 'sr':
is_cdrom = True
if blockdev[0:2] == 'hd':
try:
media = readFile('/proc/ide/%s/media' % blockdev)
if 'cdrom' in media:
is_cdrom = True
except IOError:
error = True
if not is_cdrom and os.path.exists(devpath):
for partition in os.listdir(devpath):
if partition[0:len(blockdev)] != blockdev:
continue
partitions.append(partition)
else:
self.cd = blockdev
except IOError:
error = True
medium_found = True
try:
open('/dev/' + blockdev).close()
except IOError as err:
if err.errno == 159:
medium_found = False
return (error,
blacklisted,
removable,
is_cdrom,
partitions,
medium_found)
def enumerateBlockDevices(self):
print '[Harddisk] enumerating block devices...'
for blockdev in os.listdir('/sys/block'):
error, blacklisted, removable, is_cdrom, partitions, medium_found = self.addHotplugPartition(blockdev)
if not error and not blacklisted and medium_found:
for part in partitions:
self.addHotplugPartition(part)
self.devices_scanned_on_init.append((blockdev,
removable,
is_cdrom,
medium_found))
def getAutofsMountpoint(self, device):
r = self.getMountpoint(device)
if r is None:
return '/media/' + device
else:
return r
def getMountpoint(self, device):
dev = '/dev/%s' % device
for item in getProcMounts():
if item[0] == dev:
return item[1]
return None
def addHotplugPartition(self, device, physdev = None):
if not physdev:
dev, part = self.splitDeviceName(device)
try:
physdev = os.path.realpath('/sys/block/' + dev + '/device')[4:]
except OSError:
physdev = dev
print "couldn't determine blockdev physdev for device", device
error, blacklisted, removable, is_cdrom, partitions, medium_found = self.getBlockDevInfo(device)
if not blacklisted and medium_found:
description = self.getUserfriendlyDeviceName(device, physdev)
p = Partition(mountpoint=self.getMountpoint(device), description=description, force_mounted=True, device=device)
self.partitions.append(p)
if p.mountpoint:
self.on_partition_list_change('add', p)
l = len(device)
if l and (not device[l - 1].isdigit() or device == 'mmcblk0'):
self.hdd.append(Harddisk(device, removable))
self.hdd.sort()
SystemInfo['Harddisk'] = True
return (error,
blacklisted,
removable,
is_cdrom,
partitions,
medium_found)
def addHotplugAudiocd(self, device, physdev = None):
if not physdev:
dev, part = self.splitDeviceName(device)
try:
physdev = os.path.realpath('/sys/block/' + dev + '/device')[4:]
except OSError:
physdev = dev
print "couldn't determine blockdev physdev for device", device
error, blacklisted, removable, is_cdrom, partitions, medium_found = self.getBlockDevInfo(device)
if not blacklisted and medium_found:
description = self.getUserfriendlyDeviceName(device, physdev)
p = Partition(mountpoint='/media/audiocd', description=description, force_mounted=True, device=device)
self.partitions.append(p)
self.on_partition_list_change('add', p)
SystemInfo['Harddisk'] = False
return (error,
blacklisted,
removable,
is_cdrom,
partitions,
medium_found)
def removeHotplugPartition(self, device):
for x in self.partitions[:]:
if x.device == device:
self.partitions.remove(x)
if x.mountpoint:
self.on_partition_list_change('remove', x)
l = len(device)
if l and not device[l - 1].isdigit():
for hdd in self.hdd:
if hdd.device == device:
hdd.stop()
self.hdd.remove(hdd)
break
SystemInfo['Harddisk'] = len(self.hdd) > 0
def HDDCount(self):
return len(self.hdd)
def HDDList(self):
list = []
for hd in self.hdd:
hdd = hd.model() + ' - ' + hd.bus()
cap = hd.capacity()
if cap != '':
hdd += ' (' + cap + ')'
list.append((hdd, hd))
return list
def getCD(self):
return self.cd
def getMountedPartitions(self, onlyhotplug = False, mounts = None):
if mounts is None:
mounts = getProcMounts()
parts = [ x for x in self.partitions if (x.is_hotplug or not onlyhotplug) and x.mounted(mounts) ]
devs = set([ x.device for x in parts ])
for devname in devs.copy():
if not devname:
continue
dev, part = self.splitDeviceName(devname)
if part and dev in devs:
devs.remove(dev)
return [ x for x in parts if not x.device or x.device in devs ]
def splitDeviceName(self, devname):
dev = devname[:3]
part = devname[3:]
for p in part:
if not p.isdigit():
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 = readFile('/sys' + phys + '/model')
except IOError as s:
print "couldn't read model: ", s
if part and part != 1:
description += _(' (Partition %d)') % part
return description
def addMountedPartition(self, device, desc):
for x in self.partitions:
if x.mountpoint == device:
return
self.partitions.append(Partition(mountpoint=device, description=desc))
def removeMountedPartition(self, mountpoint):
for x in self.partitions[:]:
if x.mountpoint == mountpoint:
self.partitions.remove(x)
self.on_partition_list_change('remove', x)
def setDVDSpeed(self, device, speed = 0):
ioctl_flag = int(21282)
if not device.startswith('/'):
device = '/dev/' + device
try:
from fcntl import ioctl
cd = open(device)
ioctl(cd.fileno(), ioctl_flag, speed)
cd.close()
except Exception as ex:
print '[Harddisk] Failed to set %s speed to %s' % (device, speed), ex
class UnmountTask(Task.LoggingTask):
def __init__(self, job, hdd):
Task.LoggingTask.__init__(self, job, _('Unmount'))
self.hdd = hdd
self.mountpoints = []
def prepare(self):
try:
dev = self.hdd.disk_path.split('/')[-1]
open('/dev/nomount.%s' % dev, 'wb').close()
except Exception as e:
print 'ERROR: Failed to create /dev/nomount file:', e
self.setTool('umount')
self.args.append('-f')
for dev in self.hdd.enumMountDevices():
self.args.append(dev)
self.postconditions.append(Task.ReturncodePostcondition())
self.mountpoints.append(dev)
if not self.mountpoints:
print 'UnmountTask: No mountpoints found?'
self.cmd = 'true'
self.args = [self.cmd]
def afterRun(self):
for path in self.mountpoints:
try:
os.rmdir(path)
except Exception as ex:
print "Failed to remove path '%s':" % path, ex
class MountTask(Task.LoggingTask):
def __init__(self, job, hdd):
Task.LoggingTask.__init__(self, job, _('Mount'))
self.hdd = hdd
def prepare(self):
try:
dev = self.hdd.disk_path.split('/')[-1]
os.unlink('/dev/nomount.%s' % dev)
except Exception as e:
print 'ERROR: Failed to remove /dev/nomount file:', e
if self.hdd.mount_device is None:
dev = self.hdd.partitionPath('1')
else:
dev = self.hdd.mount_device
fstab = open('/etc/fstab')
lines = fstab.readlines()
fstab.close()
for line in lines:
parts = line.strip().split(' ')
fspath = os.path.realpath(parts[0])
if os.path.realpath(fspath) == dev:
self.setCmdline('mount -t auto ' + fspath)
self.postconditions.append(Task.ReturncodePostcondition())
return
if self.hdd.type == DEVTYPE_UDEV:
self.setCmdline('sleep 2; hdparm -z ' + self.hdd.disk_path)
self.postconditions.append(Task.ReturncodePostcondition())
return
class MkfsTask(Task.LoggingTask):
def prepare(self):
self.fsck_state = None
return
def processOutput(self, data):
print '[Mkfs]', data
if 'Writing inode tables:' in data:
self.fsck_state = 'inode'
elif 'Creating journal' in data:
self.fsck_state = 'journal'
self.setProgress(80)
elif 'Writing superblocks ' in data:
self.setProgress(95)
elif self.fsck_state == 'inode':
if '/' in data:
try:
d = data.strip(' \x08\r\n').split('/', 1)
if '\x08' in d[1]:
d[1] = d[1].split('\x08', 1)[0]
self.setProgress(80 * int(d[0]) / int(d[1]))
except Exception as e:
print '[Mkfs] E:', e
return
self.log.append(data)
harddiskmanager = HarddiskManager()
def isSleepStateDevice(device):
ret = os.popen('hdparm -C %s' % device).read()
if 'SG_IO' in ret or 'HDIO_DRIVE_CMD' in ret:
return None
elif 'drive state is: standby' in ret or 'drive state is: idle' in ret:
return True
elif 'drive state is: active/idle' in ret:
return False
else:
return None
def internalHDDNotSleeping(external = False):
state = False
if harddiskmanager.HDDCount():
for hdd in harddiskmanager.HDDList():
if hdd[1].internal or external:
if hdd[1].idle_running and hdd[1].max_idle_time and not hdd[1].isSleeping():
state = True
return state
harddiskmanager = HarddiskManager()
SystemInfo['ext4'] = isFileSystemSupported('ext4') or isFileSystemSupported('ext3')