lars
1c8db28989
simple partitioning interface finished order in navigation bar changed ignore extended partitions (in container list)
118 lines
4.2 KiB
Python
118 lines
4.2 KiB
Python
import logging
|
|
import os
|
|
import re
|
|
|
|
logger = logging.getLogger("CryptoBox")
|
|
|
|
|
|
def getAvailablePartitions():
|
|
"retrieve a list of all available containers"
|
|
ret_list = []
|
|
try:
|
|
"the following reads all lines of /proc/partitions and adds the mentioned devices"
|
|
fpart = open("/proc/partitions", "r")
|
|
try:
|
|
line = fpart.readline()
|
|
while line:
|
|
p_details = line.split()
|
|
if (len(p_details) == 4):
|
|
"the following code prevents double entries like /dev/hda and /dev/hda1"
|
|
(p_major, p_minor, p_size, p_device) = p_details
|
|
## ignore lines with: invalid minor/major or extend partitions (size=1)
|
|
if re.search('^[0-9]*$', p_major) and re.search('^[0-9]*$', p_minor) and (p_size != "1"):
|
|
p_parent = re.sub('[1-9]?[0-9]$', '', p_device)
|
|
if p_parent == p_device:
|
|
if [e for e in ret_list if re.search('^' + p_parent + '[1-9]?[0-9]$', e)]:
|
|
"major partition - its children are already in the list"
|
|
pass
|
|
else:
|
|
"major partition - but there are no children for now"
|
|
ret_list.append(p_device)
|
|
else:
|
|
"minor partition - remove parent if necessary"
|
|
if p_parent in ret_list: ret_list.remove(p_parent)
|
|
ret_list.append(p_device)
|
|
line = fpart.readline()
|
|
finally:
|
|
fpart.close()
|
|
return map(getAbsoluteDeviceName, ret_list)
|
|
except IOError:
|
|
logger.warning("Could not read /proc/partitions")
|
|
return []
|
|
|
|
|
|
def getAbsoluteDeviceName(shortname):
|
|
""" returns the absolute file name of a device (e.g.: "hda1" -> "/dev/hda1")
|
|
this does also work for device mapper devices
|
|
if the result is non-unique, one arbitrary value is returned"""
|
|
if re.search('^/', shortname): return shortname
|
|
default = os.path.join("/dev", shortname)
|
|
if os.path.exists(default): return default
|
|
result = findMajorMinorOfDevice(shortname)
|
|
"if no valid major/minor was found -> exit"
|
|
if not result: return default
|
|
(major, minor) = result
|
|
"for device-mapper devices (major == 254) ..."
|
|
if major == 254:
|
|
result = findMajorMinorDeviceName("/dev/mapper", major, minor)
|
|
if result: return result[0]
|
|
"now check all files in /dev"
|
|
result = findMajorMinorDeviceName("/dev", major, minor)
|
|
if result: return result[0]
|
|
return default
|
|
|
|
|
|
def findMajorMinorOfDevice(device):
|
|
"return the major/minor numbers of a block device by querying /sys/block/?/dev"
|
|
if not os.path.exists(os.path.join(os.path.sep,"sys","block",device)): return None
|
|
blockdev_info_file = os.path.join(os.path.join(os.path.sep,"sys","block", device), "dev")
|
|
try:
|
|
f_blockdev_info = open(blockdev_info_file, "r")
|
|
blockdev_info = f_blockdev_info.read()
|
|
f_blockdev_info.close()
|
|
(str_major, str_minor) = blockdev_info.split(":")
|
|
"numeric conversion"
|
|
try:
|
|
major = int(str_major)
|
|
minor = int(str_minor)
|
|
return (major, minor)
|
|
except ValueError:
|
|
"unknown device numbers -> stop guessing"
|
|
return None
|
|
except IOError:
|
|
pass
|
|
|
|
|
|
def findMajorMinorDeviceName(dir, major, minor):
|
|
"returns the names of devices with the specified major and minor number"
|
|
collected = []
|
|
try:
|
|
subdirs = [os.path.join(dir, e) for e in os.listdir(dir) if (not os.path.islink(os.path.join(dir, e))) and os.path.isdir(os.path.join(dir, e))]
|
|
"do a recursive call to parse the directory tree"
|
|
for dirs in subdirs:
|
|
collected.extend(findMajorMinorDeviceName(dirs, major, minor))
|
|
"filter all device inodes in this directory"
|
|
collected.extend([os.path.realpath(os.path.join(dir, e)) for e in os.listdir(dir) if (os.major(os.stat(os.path.join(dir, e)).st_rdev) == major) and (os.minor(os.stat(os.path.join(dir, e)).st_rdev) == minor)])
|
|
## remove double entries
|
|
result = []
|
|
for e in collected:
|
|
if e not in result: result.append(e)
|
|
return result
|
|
except OSError:
|
|
return []
|
|
|
|
|
|
def getParentBlockDevices():
|
|
devs = []
|
|
for line in file("/proc/partitions"):
|
|
p_details = line.split()
|
|
## we expect four values - otherwise continue with next iteration
|
|
if len(p_details) != 4: continue
|
|
(p_major, p_minor, p_size, p_device) = p_details
|
|
## we expect numeric values in the first two columns
|
|
if re.search(u'\D',p_major) or re.search(u'\D',p_minor): continue
|
|
## now let us check, if it is a (parent) block device or a partition
|
|
if not os.path.isdir(os.path.join(os.path.sep, "sys", "block", p_device)): continue
|
|
devs.append(p_device)
|
|
return map(getAbsoluteDeviceName, devs)
|
|
|