mirror of
https://mojerepo.cf/NeoBoot/NeoBoot-9.git
synced 2025-10-27 06:16:05 +01:00
1049 lines
33 KiB
Python
1049 lines
33 KiB
Python
# -*- coding: utf-8 -*-
|
|
|
|
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
|
|
from Screens.Screen import Screen
|
|
from Components.ActionMap import ActionMap
|
|
from Components.MenuList import MenuList
|
|
from Components.Label import Label
|
|
from Components.Pixmap import Pixmap
|
|
from Screens.MessageBox import MessageBox
|
|
|
|
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']
|
|
|
|
###__blokada hash dla ext4 >>>
|
|
# 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')
|
|
|
|
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)
|
|
|
|
|
|
###########################__From HarddiskSetup_################################
|
|
class HarddiskSetup(Screen):
|
|
|
|
def __init__(self, session, hdd, action, text, question):
|
|
Screen.__init__(self, session)
|
|
self.action = action
|
|
self.question = question
|
|
self.setTitle(_('Setup hard disk'))
|
|
self['model'] = Label(_('Model: ') + hdd.model())
|
|
self['capacity'] = Label(_('Capacity: ') + hdd.capacity())
|
|
self['bus'] = Label(_('Bus: ') + hdd.bus())
|
|
self['key_red'] = Label(_('Cancel'))
|
|
self['key_green'] = Label(text)
|
|
self['actions'] = ActionMap(['OkCancelActions'], {'ok': self.hddQuestion,
|
|
'cancel': self.close})
|
|
self['shortcuts'] = ActionMap(['ShortcutActions'], {'red': self.close,
|
|
'green': self.hddQuestion})
|
|
|
|
def hddQuestion(self):
|
|
message = self.question + '\n' + _('You can continue watching TV etc. while this is running.')
|
|
self.session.openWithCallback(self.hddConfirmed, MessageBox, message)
|
|
|
|
def hddConfirmed(self, confirmed):
|
|
if not confirmed:
|
|
return
|
|
from Components.Task import job_manager
|
|
try:
|
|
job = self.action()
|
|
job_manager.AddJob(job, onSuccess=job_manager.popupTaskView)
|
|
from Screens.TaskView import JobView
|
|
self.session.open(JobView, job, afterEventChangeable=False)
|
|
except Exception as ex:
|
|
self.session.open(MessageBox, str(ex), type=MessageBox.TYPE_ERROR, timeout=10)
|
|
|
|
self.close()
|
|
|
|
|
|
class HarddiskSelection(Screen):
|
|
def __init__(self, session):
|
|
Screen.__init__(self, session)
|
|
self.setTitle(_('Select hard disk'))
|
|
self.skinName = 'HarddiskSelection'
|
|
if harddiskmanager.HDDCount() == 0:
|
|
tlist = []
|
|
tlist.append((_('no storage devices found'), 0))
|
|
self['hddlist'] = MenuList(tlist)
|
|
else:
|
|
self['hddlist'] = MenuList(harddiskmanager.HDDList())
|
|
self['key_red'] = Label(_('Cancel'))
|
|
self['key_green'] = Label(_('Select'))
|
|
self['actions'] = ActionMap(['OkCancelActions'], {'ok': self.okbuttonClick,
|
|
'cancel': self.close})
|
|
self['shortcuts'] = ActionMap(['ShortcutActions'], {'red': self.close,
|
|
'green': self.okbuttonClick})
|
|
|
|
def doIt(self, selection):
|
|
self.session.openWithCallback(self.close, HarddiskSetup, selection, action=selection.createInitializeJob, text=_('Initialize'), question=_('Do you really want to initialize the device?\nAll data on the disk will be lost!'))
|
|
|
|
def okbuttonClick(self):
|
|
selection = self['hddlist'].getCurrent()
|
|
if selection[1] != 0:
|
|
self.doIt(selection[1])
|
|
|
|
|
|
class HarddiskFsckSelection(HarddiskSelection):
|
|
|
|
def doIt(self, selection):
|
|
self.session.openWithCallback(self.close, HarddiskSetup, selection, action=selection.createCheckJob, text=_('Check'), question=_('Do you really want to check the filesystem?\nThis could take lots of time!'))
|
|
###########################__end HarddiskSetup_################################
|
|
|
|
|
|
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')
|