Skip to content

Commit

Permalink
chore(usbf): create a loopback device when a file is used
Browse files Browse the repository at this point in the history
When a file is used as backing store for the shared storage,
create a loopback device to make sure writes are contained
within the limits of the file.

Signed-off-by: Cedric Hombourger <[email protected]>
  • Loading branch information
chombourger committed Jan 15, 2024
1 parent c6c8fad commit 8ee75a5
Show file tree
Hide file tree
Showing 3 changed files with 31 additions and 7 deletions.
1 change: 1 addition & 0 deletions .github/wordlist.txt
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,7 @@ JQC
keyrings
kvm
LEDs
loopback
LTS
maxdepth
microSD
Expand Down
12 changes: 7 additions & 5 deletions docs/config.rst
Original file line number Diff line number Diff line change
Expand Up @@ -396,13 +396,15 @@ configuration to expose either a file or a physical device or partition to
the DUT as a Mass Storage device. The following settings are supported:

* ``device``: string [optional]
Block device for the shared storage as seen on the host. This is the
same as ``file`` but a warning will be issued if the specified file
is not a block device. When both ``device`` and ``file`` are set,
``file`` will be used.
Block device for the shared storage as seen on the host. A systemd
dependency is added to ensure the service is started only after the
specified block device was found. A warning is issued if the input
is not a block device.

* ``file``: string [optional]
File or block device for the shared storage as seen on the host.
File for the shared storage: a loopback device will be created to make
sure that writes to the shared storage do not cause this file to
expand and leave the host without free space.

Timeout settings
----------------
Expand Down
25 changes: 23 additions & 2 deletions mtda/storage/usbf.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
# System imports
import os
import stat
import subprocess

# Local imports
import mtda.constants as CONSTS
Expand All @@ -26,9 +27,23 @@ def __init__(self, mtda):
super().__init__(mtda)
self.device = None
self.file = None
self.loop = None
self.mode = CONSTS.STORAGE.ON_HOST
Composite.mtda = mtda

def cleanup(self):
self.mtda.debug(3, "storage.usbf.cleanup()")

result = None
if self.loop is not None:
self.mtda.debug(2, "storage.usbf.cleanup(): "
"removing {}".format(self.loop))
cmd = ['/usr/sbin/losetup', '-d', self.loop]
self.loop = subprocess.check_call(cmd)

self.mtda.debug(3, "storage.usbf.cleanup(): {}".format(result))
return result

""" Configure this storage controller from the provided configuration"""
def configure(self, conf):
self.mtda.debug(3, "storage.usbf.configure()")
Expand All @@ -44,8 +59,14 @@ def configure(self, conf):
"both 'file' ({}) and 'device' ({}) are set, "
"using 'file'".format(self.file, self.device))
self.device = None

if self.file is None and self.device is not None:
elif self.device is None:
import atexit
cmd = ['/usr/sbin/losetup', '-f', '--show', self.file]
self.loop = subprocess.check_output(cmd).decode("utf-8").strip()
atexit.register(self.cleanup)
self.mtda.debug(2, "storage.usbf.configure(): created loopback "
"device {} for {}".format(self.loop, self.file))
else:
self.file = self.device

if self.file is not None:
Expand Down

0 comments on commit 8ee75a5

Please sign in to comment.