aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorPapoteur <papoteur@mageia.org>2020-10-17 10:18:02 +0200
committerPapoteur <papoteur@mageia.org>2020-10-17 12:42:56 +0200
commit6fd912ea3a1cf98005ec6f4f5f71685d65308770 (patch)
treeb47348d5c55f5e45d48886426c896eb73c26a00f
parentf2736c1d1f1bb972e7742e9b65ccd03d1b73be58 (diff)
downloadisodumper-6fd912ea3a1cf98005ec6f4f5f71685d65308770.tar
isodumper-6fd912ea3a1cf98005ec6f4f5f71685d65308770.tar.gz
isodumper-6fd912ea3a1cf98005ec6f4f5f71685d65308770.tar.bz2
isodumper-6fd912ea3a1cf98005ec6f4f5f71685d65308770.tar.xz
isodumper-6fd912ea3a1cf98005ec6f4f5f71685d65308770.zip
Use udisks2 to unmount partitions
Unmount encrypted partitions too Add complete traceback when error occur in event loop
-rwxr-xr-xbackend/magiback8
-rwxr-xr-xbackend/raw_write.py32
-rwxr-xr-xlib/isodumper.py63
3 files changed, 57 insertions, 46 deletions
diff --git a/backend/magiback b/backend/magiback
index 7deab33..7485773 100755
--- a/backend/magiback
+++ b/backend/magiback
@@ -23,11 +23,6 @@ class Isodumper(raw_write.Dumper):
<arg type='s' name='target' direction='in'/>
<arg type='x' name='size' direction='in'/>
</method>
- <method name='do_unmount'>
- <arg type='s' name='device' direction='in'/>
- <arg type='b' name='success' direction='out'/>
- <arg type='s' name='message' direction='out'/>
- </method>
<method name='do_format'>
<arg type='s' name='device' direction='in'/>
<arg type='s' name='format' direction='in'/>
@@ -127,9 +122,6 @@ class Isodumper(raw_write.Dumper):
def progress(self):
return self._progress
- def do_unmount(self, device):
- return self._do_unmount([device])
-
def get_sum(self, source):
self.key_thread = threading.Thread(target=self._get_sum, args=(source,))
self.key_thread.start()
diff --git a/backend/raw_write.py b/backend/raw_write.py
index 87f17a5..cd80b85 100755
--- a/backend/raw_write.py
+++ b/backend/raw_write.py
@@ -123,38 +123,6 @@ class Dumper(object):
logging.debug(self.return_message)
return
- def _do_unmount(self, target):
- target = target[0]
- logging.debug("Starting unmounting")
- message = _("No partition is mounted.")
- retcode = 0
- try:
- lines = [line.strip("\n").split(" ") for line in open ("/etc/mtab", "r").readlines()]
- mounts = [mount for mount in lines if mount[0].startswith(target)]
- except:
- message = _('Could not read mtab ! {} {}'.format(os.getuid(),target))
- return False, message
- if mounts:
- message =_("Unmounting all partitions of {}:\n").format(target)
- print(message)
- for mount in mounts:
- message +=_("Trying to unmount {}...\n").format(mount[0])
- try:
- retcode = call('umount '+mount[0], shell=True)
- if retcode == 32:
- message += _('Partition {} is busy').format(mount[0])
- elif retcode< 0:
- message += _('Error, umount {} was terminated by signal {}').format(mount[0],retcode)
- elif retcode == 0:
- message += _('{} successfully unmounted').format(mount[0])
- else:
- message += _('Error, umount returned {}').format(str(retcode))
- except OSError as e:
- message += _('Execution failed: {}').format(str(e))
- print(message, file=sys.stderr)
- logging.info(message)
- return not bool(retcode), message
-
def _get_sum(self, source):
self.return_state = False
logging.debug("Starting getting sum")
diff --git a/lib/isodumper.py b/lib/isodumper.py
index 6e111b1..ffc56cc 100755
--- a/lib/isodumper.py
+++ b/lib/isodumper.py
@@ -68,10 +68,10 @@ class UDisks2(object):
self.iface = self.bus.get(self.SERVICE)
except :
raise NoUDisks2()
+ self._udisks2_obj_manager = self.iface["org.freedesktop.DBus.ObjectManager"]
def find_devices(self):
- _udisks2_obj_manager = self.iface["org.freedesktop.DBus.ObjectManager"]
- objects=_udisks2_obj_manager.GetManagedObjects()
+ objects = self._udisks2_obj_manager.GetManagedObjects()
re_drive = re.compile('(?P<path>.*?/drives/(?P<id>.*))')
re_block = re.compile('(?P<path>.*?/block_devices/(?P<id>.*))')
devs= [m.groupdict() for m in
@@ -104,6 +104,38 @@ class UDisks2(object):
list.append(item)
return list
+ def do_unmount(self, target):
+ # keep only the end, like sdb
+ target = os.path.basename(target)
+ objects = self._udisks2_obj_manager.GetManagedObjects()
+ re_drive = re.compile('(?P<path>.*?/drives/(?P<id>.*))')
+ re_block = re.compile('(?P<path>.*?/block_devices/(?P<id>.*))')
+ blocks = [m.groupdict() for m in
+ [re_block.match(path) for path in (objects.keys())]
+ if m]
+ for block in blocks:
+ if (self.SERVICE + '.Partition' in objects[block['path']]): # we skip non partition blocks
+ # Table should be something like '/org/freedesktop/UDisks2/block_devices/sdb'
+ if objects[block['path']][self.SERVICE + '.Partition']['Table'].split('/')[-1] == target :
+ print("Unmounting: {}".format(block['path'].split('/')[-1]))
+ if (self.SERVICE + '.Encrypted' in objects[block['path']]): # Is the partition encrypted ?
+ path_to_encrypted = objects[block['path']][self.SERVICE + '.Encrypted']['CleartextDevice']
+ print(path_to_encrypted)
+ if path_to_encrypted != '/' :
+ iface = self.bus.get(self.SERVICE, path_to_encrypted)
+ fs = iface[self.SERVICE + '.Filesystem']
+ if fs.MountPoints : # partition is mounted
+ fs.Unmount({})
+ iface = self.bus.get(self.SERVICE, block['path'])
+ fs = iface[self.SERVICE + '.Encrypted']
+ fs.Lock({})
+ else:
+ iface = self.bus.get(self.SERVICE, block['path'])
+ fs = iface[self.SERVICE + '.Filesystem']
+ if fs.MountPoints : # partition is mounted
+ fs.Unmount({})
+ return True, ""
+
def eject(self, device):
''' device is expected like /dev/sda'''
block = os.path.basename(device)
@@ -139,6 +171,22 @@ class IsoDumper(object):
self.devicelist.addItem(str(name+' ('+path.lstrip()+') ' + self.sizeof_fmt(size)),False)
return True
+ def udev_wait(self, operation):
+ wait = Popen(["udevadm","settle","--timeout=15"], stderr=PIPE)
+ outs, errs = wait.communicate()
+ working=True
+ while working:
+ time.sleep(0.5)
+ wait.poll()
+ rc=wait.returncode
+ if not (rc is None):
+ wait = None
+ working= False
+ if rc != 0:
+ self.return_state = False
+ self.return_message = _("Timeout reached when {}".format(operation))
+ return False
+ return True
def update_list(self ):
self.devicelist.deleteAllItems()
@@ -210,7 +258,7 @@ class IsoDumper(object):
self.ima.setDisabled()
self.writebt.setDisabled()
self.devicelist.setEnabled()
- self.progress.setLabel("")
+ self.progress.setLabel(_("Progress"))
self.progress.setValue(0)
self.progress.setDisabled()
self.refreshbt.setEnabled()
@@ -312,7 +360,8 @@ class IsoDumper(object):
self.logger(_('Executing copy from ')+source+_(' to ')+target)
bus = SystemBus()
iface = bus.get("org.mageia.Magiback", "Isodumper")
- success, message = iface.do_unmount(target)
+ success, message = self.u.do_unmount(target)
+ self.udev_wait(_("unmounting"))
if success:
# Writing step
iface.do_write(source, target, b)
@@ -372,7 +421,8 @@ class IsoDumper(object):
time.sleep(.5)
self.logger(_("Added persistent partition"))
# Unmount if partitions are automatically mounted and then eject
- success, message = iface.do_unmount(target)
+ success, message = self.u.do_unmount(target)
+ self.udev_wait(_("unmounting"))
if success:
self.u.eject(target)
self.success()
@@ -779,7 +829,8 @@ exFAT, NTFS or ext. You can specify a volume name and the format in a new dialog
try:
self.handleevent()
except Exception as e:
- print(str(e))
+ import traceback
+ traceback.print_exc()
yui.YDialog.deleteAllDialogs()