From 426cef4c2cda2fadbe0ba103ed324fe612088f14 Mon Sep 17 00:00:00 2001 From: Sunil Mohan Adapa Date: Tue, 2 Jun 2020 11:15:40 -0700 Subject: [PATCH] storage: Don't auto-mount loopback devices except in develop mode In the event containers are being used on the server with images, attempting to auto-mounting loop devices could interfere with their operation. We currently don't have a use case where a user would want to auto-mount loop devices. Initially suggested in https://salsa.debian.org/freedombox-team/freedombox/-/issues/1854 Tests performed: - Add a loopback device as follows and observe that is automatically mounted. dd if=/dev/zero of=/tmp/test_disk bs=1M count=100 mkfs.ext4 /tmp/test_disk losetup loop0 /tmp/test_disk umount /dev/loop0 losetup -d /dev/loop0 - Add a loopback device as follows and observe that both partitions are mounted. dd if=/dev/zero of=/tmp/test_disk bs=1M count=100 parted /tmp/test_disk mklabel gpt mkpart Part1 ext4 0% 50% mkpart Part2 ext4 50% 100% kpartx -avs /tmp/test_disk mkfs.ext4 /dev/mapper/loop0p1 mkfs.ext4 /dev/mapper/loop0p2 umount /dev/mapper/loop0p1 umount /dev/mapper/loop0p2 kpartx -dvs /tmp/test_disk - When --develop is removed or when code is modified to negate the not condition, the partitions are not auto-mounted in the above cases. Reported-by: James Valleroy Signed-off-by: Sunil Mohan Adapa Reviewed-by: James Valleroy --- plinth/modules/storage/udisks2.py | 29 ++++++++++++++++++++++++++++- 1 file changed, 28 insertions(+), 1 deletion(-) diff --git a/plinth/modules/storage/udisks2.py b/plinth/modules/storage/udisks2.py index a9448431d..794ca2464 100644 --- a/plinth/modules/storage/udisks2.py +++ b/plinth/modules/storage/udisks2.py @@ -6,7 +6,7 @@ Handle disk operations using UDisk2 DBus API. import logging import threading -from plinth import actions +from plinth import actions, cfg from plinth.errors import ActionError from plinth.utils import import_from_gi @@ -21,6 +21,7 @@ _INTERFACES = { 'Drive': 'org.freedesktop.UDisks2.Drive', 'Filesystem': 'org.freedesktop.UDisks2.Filesystem', 'Job': 'org.freedesktop.UDisks2.Job', + 'Loop': 'org.freedesktop.UDisks2.Loop', 'Manager': 'org.freedesktop.UDisks2.Manager', 'ObjectManager': 'org.freedesktop.DBus.ObjectManager', 'Partition': 'org.freedesktop.UDisks2.Partition', @@ -114,6 +115,7 @@ class Partition(Proxy): interface = _INTERFACES['Partition'] properties = { 'number': ('u', 'Number'), + 'table': ('o', 'Table'), } @@ -123,6 +125,12 @@ class Filesystem(Proxy): properties = {'mount_points': ('aay', 'MountPoints')} +class Loop(Proxy): + """Abstraction for UDisks2 Loop.""" + interface = _INTERFACES['Loop'] + properties = {'backing_file': ('ay', 'BackingFile')} + + def get_disks(): """List devices that can be ejected.""" devices = [] @@ -226,6 +234,19 @@ def _on_filesystem_added(object_path, _interfaces): threading.Thread(target=_consider_for_mounting, args=[object_path]).start() +def _is_loop_device(object_path): + """Return if the block device is a loop device backed by a file.""" + loop = Loop(object_path) + if loop.backing_file: + return True + + partition_table = Partition(object_path).table + if partition_table: + return _is_loop_device(partition_table) + + return False + + def _consider_for_mounting(object_path): """Check if the block device needs mounting and mount it.""" block_device = BlockDevice(object_path) @@ -254,6 +275,12 @@ def _consider_for_mounting(object_path): block_device.id, block_device.preferred_device) return + # Ignore loopback devices except in development mode. + if _is_loop_device(object_path) and not cfg.develop: + logger.info('Ignoring loop device in production mode: %s %s', + block_device.id, block_device.preferred_device) + return + _mount(object_path)