remoteloop: don't use O_DIRECT on s390x
Using O_DIRECT to open the image partition and then using that fd
for the backing of the loopback device will break the mounting of
the formatted partition, i.e mount will fail with:
mount: /tmp/looptest-6qrtkp5e/mountpoint-root: wrong fs type,
bad option, bad superblock on /dev/loop0, missing codepage or
helper program, or other error.
Reproducible with the follow small-ish python script, executed via
'env PYTHONPATH=$(pwd) python3 looptest.py':
---- 8< ---- 8< ---- [ looptest.py ] ---- 8< ---- 8< ----
import contextlib
import json
import os
import subprocess
import stat
import tempfile
from osbuild import loop
@contextlib.contextmanager
def mount(source, dest):
subprocess.run(["mount", source, dest], check=True)
try:
yield dest
finally:
subprocess.run(["umount", "-R", dest], check=True)
@contextlib.contextmanager
def os_open(path, flags):
fd = os.open(path, flags)
try:
yield fd
finally:
os.close(fd)
def main():
size = 512 * 1024 * 1024
ptuuid = "0x14fc63d2"
with contextlib.ExitStack() as cm:
tmpdir = cm.enter_context(tempfile.TemporaryDirectory(prefix="looptest-"))
print(f"Temporary directory at {tmpdir}")
devdir = os.path.join(tmpdir, "dev")
os.makedirs(devdir, exist_ok=True)
dir_fd = cm.enter_context(os_open(devdir, os.O_DIRECTORY))
image = os.path.join(tmpdir, "image")
subprocess.run(["truncate", "--size", str(size), image], check=True)
table = f"label: mbr\nlabel-id: {ptuuid}\nbootable, type=83"
subprocess.run(["sfdisk", image], input=table, encoding='utf-8',
check=True)
# read it back
r = subprocess.run(["sfdisk", "--json", image],
stdout=subprocess.PIPE,
encoding='utf-8', check=True)
table = json.loads(r.stdout)["partitiontable"]
partitions = table["partitions"]
start = partitions[0]["start"] * 512
size = partitions[0]["size"] * 512
# fails here with os.O_DIRECT
image_fd = cm.enter_context(os_open(image, os.O_RDWR | os.O_DIRECT))
control = loop.LoopControl()
minor = control.get_unbound()
lo = loop.Loop(minor)
lo.set_fd(image_fd)
lo.set_status(offset=start, sizelimit=size, autoclear=True)
lo.mknod(dir_fd)
loopdev = f"/dev/loop{minor}"
# loopdev = os.path.join(devdir, lo.devname)
# os.chmod(loopdev, os.stat(loopdev).st_mode | stat.S_IRGRP)
subprocess.run(["ls", "-la", f"{devdir}"], check=True)
subprocess.run(["mkfs.ext4", loopdev],
input="y", encoding='utf-8', check=True)
subprocess.run(["blkid", loopdev], check=True)
mountpoint = os.path.join(tmpdir, "mountpoint-root")
os.makedirs(mountpoint, exist_ok=True)
cm.enter_context(mount(loopdev, mountpoint))
subprocess.run(["ls", "-la", tmpdir], check=True)
subprocess.run(["ls", "-la", mountpoint], check=True)
subprocess.run(["mount"], check=True)
if __name__ == '__main__':
main()