pmbootstrap-meow/pmb/install/losetup.py
Daniele Debernardi d3dc3b2c98
pmb.chroot.shutdown: losetup with auto_init=False (MR 1912)
Do not go through the pmb.chroot.init() code path when running
pmb.install.losetup.umount() inside pmb.chroot.shutdown(). This is not
necessary, as pmb.install.losetup.umount() only gets called if the
chroot is already initialized and /dev/loop-control is mounted inside
the chroot.

Not going through this code path is important for the upcoming workdir
migration patch. Without this fix, it will fail with the following if
running "pmbootstrap install" before the work migration:

ERROR: Could not figure out on which release channel the 'native' chroot is
2020-05-17 08:08:45 +02:00

80 lines
2.4 KiB
Python

# Copyright 2020 Oliver Smith
# SPDX-License-Identifier: GPL-3.0-or-later
import glob
import json
import logging
import os
import time
import pmb.helpers.mount
import pmb.helpers.run
import pmb.chroot
def init(args):
if not os.path.isdir("/sys/module/loop"):
pmb.helpers.run.root(args, ["modprobe", "loop"])
loopdevices = [loopdev for loopdev in glob.glob("/dev/loop*") if not os.path.isdir(loopdev)]
for loopdev in loopdevices:
pmb.helpers.mount.bind_file(args, loopdev,
args.work + "/chroot_native/" + loopdev)
def mount(args, img_path):
"""
:param img_path: Path to the img file inside native chroot.
"""
logging.debug("(native) mount " + img_path + " (loop)")
# Try to mount multiple times (let the kernel module initialize #1594)
for i in range(0, 5):
# Retry
if i > 0:
logging.debug("loop module might not be initialized yet, retry in"
" one second...")
time.sleep(1)
# Mount and return on success
init(args)
losetup_cmd = ["losetup", "-f", img_path]
sector_size = args.deviceinfo["rootfs_image_sector_size"]
if sector_size:
losetup_cmd += ["-b", str(int(sector_size))]
pmb.chroot.root(args, losetup_cmd, check=False)
if device_by_back_file(args, img_path):
return
# Failure: raise exception
raise RuntimeError("Failed to mount loop device: " + img_path)
def device_by_back_file(args, back_file, auto_init=True):
"""
Get the /dev/loopX device, that points to a specific image file.
"""
# Get list from losetup
losetup_output = pmb.chroot.root(args, ["losetup", "--json", "--list"],
output_return=True, auto_init=auto_init)
if not losetup_output:
return None
# Find the back_file
losetup = json.loads(losetup_output)
for loopdevice in losetup["loopdevices"]:
if loopdevice["back-file"] == back_file:
return loopdevice["name"]
return None
def umount(args, img_path, auto_init=True):
"""
:param img_path: Path to the img file inside native chroot.
"""
device = device_by_back_file(args, img_path, auto_init)
if not device:
return
logging.debug("(native) umount " + device)
pmb.chroot.root(args, ["losetup", "-d", device], auto_init=auto_init)