devices/loopback: since file on close

On rare occasions, when trying to mount a file system via the
loopback device that was created in the stage before the mount
fails with `wrong fs type, bad option, bad superblock on ...`.
It is not yet fully clear why this appears since in theory the
kernel should handle the sequence of operations we do, but it
might be down to the caching or bugs in the underlying file-
system.
To mitigate with potential caching issue we therefore now sync
the file that is backing the loopback device after the device
has been closed. In order to not have to re-open the file we
keep the file descriptor around as long as the loopback device
is open.
This commit is contained in:
Christian Kellner 2021-07-07 12:48:00 +00:00 committed by Tom Gundersen
parent 23628b3f62
commit 83fc64c565

View file

@ -55,6 +55,7 @@ class LoopbackService(devices.DeviceService):
def __init__(self, args: argparse.Namespace):
super().__init__(args)
self.fd = None
self.lo = None
self.ctl = loop.LoopControl()
@ -97,8 +98,12 @@ class LoopbackService(devices.DeviceService):
path = os.path.join(tree, filename.lstrip("/"))
with open(path, "r+b") as fd:
self.lo = self.make_loop(fd.fileno(), start, size)
self.fd = os.open(path, os.O_RDWR | os.O_CLOEXEC)
try:
self.lo = self.make_loop(self.fd, start, size)
except Exception as error: # pylint: disable: broad-except
self.close()
raise error from None
dir_fd = -1
try:
@ -123,6 +128,14 @@ class LoopbackService(devices.DeviceService):
self.lo.close()
self.lo = None
if self.fd is not None:
fd = self.fd
self.fd = None
try:
os.fsync(fd)
finally:
os.close(fd)
def main():
service = LoopbackService.from_args(sys.argv[1:])