forked from Mirror/pmbootstrap
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
86 lines
3.1 KiB
Python
86 lines
3.1 KiB
Python
# Copyright 2020 Oliver Smith
|
|
# SPDX-License-Identifier: GPL-3.0-or-later
|
|
import logging
|
|
import glob
|
|
import os
|
|
import socket
|
|
from contextlib import closing
|
|
|
|
import pmb.chroot
|
|
import pmb.chroot.distccd
|
|
import pmb.helpers.mount
|
|
import pmb.install.losetup
|
|
import pmb.parse.arch
|
|
|
|
|
|
def kill_adb(args):
|
|
"""
|
|
Kill adb daemon if it's running.
|
|
"""
|
|
port = 5038
|
|
with closing(socket.socket(socket.AF_INET, socket.SOCK_STREAM)) as sock:
|
|
if sock.connect_ex(("127.0.0.1", port)) == 0:
|
|
pmb.chroot.root(args, ["adb", "-P", str(port), "kill-server"])
|
|
|
|
|
|
def shutdown_cryptsetup_device(args, name):
|
|
"""
|
|
:param name: cryptsetup device name, usually "pm_crypt" in pmbootstrap
|
|
"""
|
|
if not os.path.exists(args.work + "/chroot_native/dev/mapper/" + name):
|
|
return
|
|
pmb.chroot.apk.install(args, ["cryptsetup"])
|
|
status = pmb.chroot.root(args, ["cryptsetup", "status", name],
|
|
output_return=True, check=False)
|
|
if not status:
|
|
logging.warning("WARNING: Failed to run cryptsetup to get the status"
|
|
" for " + name + ", assuming it is not mounted"
|
|
" (shutdown fails later if it is)!")
|
|
return
|
|
|
|
if status.startswith("/dev/mapper/" + name + " is active."):
|
|
pmb.chroot.root(args, ["cryptsetup", "luksClose", name])
|
|
elif status.startswith("/dev/mapper/" + name + " is inactive."):
|
|
# When "cryptsetup status" fails, the device is not mounted and we
|
|
# have a left over file (#83)
|
|
pmb.chroot.root(args, ["rm", "/dev/mapper/" + name])
|
|
else:
|
|
raise RuntimeError("Failed to parse 'cryptsetup status' output!")
|
|
|
|
|
|
def shutdown(args, only_install_related=False):
|
|
pmb.chroot.distccd.stop(args)
|
|
|
|
# Stop adb server
|
|
kill_adb(args)
|
|
|
|
# Umount installation-related paths (order is important!)
|
|
pmb.helpers.mount.umount_all(args, args.work +
|
|
"/chroot_native/mnt/install")
|
|
shutdown_cryptsetup_device(args, "pm_crypt")
|
|
|
|
# Umount all losetup mounted images
|
|
chroot = args.work + "/chroot_native"
|
|
if pmb.helpers.mount.ismount(chroot + "/dev/loop-control"):
|
|
pattern = chroot + "/home/pmos/rootfs/*.img"
|
|
for path_outside in glob.glob(pattern):
|
|
path = path_outside[len(chroot):]
|
|
pmb.install.losetup.umount(args, path, auto_init=False)
|
|
|
|
# Umount device rootfs chroot
|
|
chroot_rootfs = args.work + "/chroot_rootfs_" + args.device
|
|
if os.path.exists(chroot_rootfs):
|
|
pmb.helpers.mount.umount_all(args, chroot_rootfs)
|
|
|
|
if not only_install_related:
|
|
# Umount all folders inside args.work
|
|
# The folders are explicitly iterated over, so folders symlinked inside
|
|
# args.work get umounted as well (used in test_pkgrel_bump.py, #1595)
|
|
for path in glob.glob(args.work + "/*"):
|
|
pmb.helpers.mount.umount_all(args, path)
|
|
|
|
# Clean up the rest
|
|
for arch in pmb.config.build_device_architectures:
|
|
if pmb.parse.arch.cpu_emulation_required(args, arch):
|
|
pmb.chroot.binfmt.unregister(args, arch)
|
|
logging.debug("Shutdown complete")
|