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 <jvalleroy@mailbox.org>
Signed-off-by: Sunil Mohan Adapa <sunil@medhas.org>
Reviewed-by: James Valleroy <jvalleroy@mailbox.org>
This commit is contained in:
Sunil Mohan Adapa 2020-06-02 11:15:40 -07:00 committed by James Valleroy
parent 8c05fb0722
commit 426cef4c2c
No known key found for this signature in database
GPG Key ID: 77C0C75E7B650808

View File

@ -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)