diff options
author | Papoteur <papoteur@mageia.org> | 2020-10-17 10:18:02 +0200 |
---|---|---|
committer | Papoteur <papoteur@mageia.org> | 2020-10-17 12:42:56 +0200 |
commit | 6fd912ea3a1cf98005ec6f4f5f71685d65308770 (patch) | |
tree | b47348d5c55f5e45d48886426c896eb73c26a00f | |
parent | f2736c1d1f1bb972e7742e9b65ccd03d1b73be58 (diff) | |
download | isodumper-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-x | backend/magiback | 8 | ||||
-rwxr-xr-x | backend/raw_write.py | 32 | ||||
-rwxr-xr-x | lib/isodumper.py | 63 |
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() |