X-Git-Url: https://glassweightruler.freedombox.rocks/gitweb/waydroid.git/blobdiff_plain/ff4cf1c83f09e639504209dec68855cdf3c69bce..HEAD:/tools/actions/container_manager.py?ds=inline diff --git a/tools/actions/container_manager.py b/tools/actions/container_manager.py index e36cfbf..b14dd63 100644 --- a/tools/actions/container_manager.py +++ b/tools/actions/container_manager.py @@ -3,11 +3,8 @@ from shutil import which import logging import os -import time import glob import signal -import sys -import uuid import tools.config from tools import helpers from tools import services @@ -22,13 +19,20 @@ class DbusContainerManager(dbus.service.Object): self.looper = looper dbus.service.Object.__init__(self, bus, object_path) - @dbus.service.method("id.waydro.ContainerManager", in_signature='a{ss}', out_signature='') - def Start(self, session): + @dbus.service.method("id.waydro.ContainerManager", in_signature='a{ss}', out_signature='', sender_keyword="sender", connection_keyword="conn") + def Start(self, session, sender, conn): + dbus_info = dbus.Interface(conn.get_object("org.freedesktop.DBus", "/org/freedesktop/DBus/Bus", False), "org.freedesktop.DBus") + uid = dbus_info.GetConnectionUnixUser(sender) + if str(uid) not in ["0", session["user_id"]]: + raise RuntimeError("Cannot start a session on behalf of another user") + pid = dbus_info.GetConnectionUnixProcessID(sender) + if str(uid) != "0" and str(pid) != session["pid"]: + raise RuntimeError("Invalid session pid") do_start(self.args, session) - @dbus.service.method("id.waydro.ContainerManager", in_signature='', out_signature='') - def Stop(self): - stop(self.args) + @dbus.service.method("id.waydro.ContainerManager", in_signature='b', out_signature='') + def Stop(self, quit_session): + stop(self.args, quit_session) @dbus.service.method("id.waydro.ContainerManager", in_signature='', out_signature='') def Freeze(self): @@ -73,16 +77,19 @@ def set_permissions(args, perm_list=None, mode="777"): "/dev/mtk_cmdq", # Graphics - "/dev/dri", "/dev/graphics", "/dev/pvr_sync", "/dev/ion", ] + # DRM render nodes + perm_list.extend(glob.glob("/dev/dri/renderD*")) # Framebuffers perm_list.extend(glob.glob("/dev/fb*")) # Videos perm_list.extend(glob.glob("/dev/video*")) + # DMA-BUF Heaps + perm_list.extend(glob.glob("/dev/dma_heap/*")) for path in perm_list: chmod(path, mode) @@ -123,62 +130,72 @@ def start(args): def do_start(args, session): if "session" in args: - logging.info("Already tracking a session") - return + raise RuntimeError("Already tracking a session") - args.session = session + logging.info("Starting up container for a new session") # Networking command = [tools.config.tools_src + "/data/scripts/waydroid-net.sh", "start"] - tools.helpers.run.user(args, command, check=False) + tools.helpers.run.user(args, command) # Sensors if which("waydroid-sensord"): tools.helpers.run.user( args, ["waydroid-sensord", "/dev/" + args.HWBINDER_DRIVER], output="background") - # Mount rootfs - cfg = tools.config.load(args) - helpers.images.mount_rootfs(args, cfg["waydroid"]["images_path"], args.session) - - helpers.protocol.set_aidl_version(args) - - # Mount data - helpers.mount.bind(args, args.session["waydroid_data"], - tools.config.defaults["data"]) - # Cgroup hacks if which("start"): command = ["start", "cgroup-lite"] tools.helpers.run.user(args, command, check=False) + + # Keep schedtune around in case nesting is supported if os.path.ismount("/sys/fs/cgroup/schedtune"): - command = ["umount", "-l", "/sys/fs/cgroup/schedtune"] - tools.helpers.run.user(args, command, check=False) + try: + os.mkdir("/sys/fs/cgroup/schedtune/probe0") + os.mkdir("/sys/fs/cgroup/schedtune/probe0/probe1") + except: + command = ["umount", "-l", "/sys/fs/cgroup/schedtune"] + tools.helpers.run.user(args, command, check=False) + finally: + if os.path.exists("/sys/fs/cgroup/schedtune/probe0/probe1"): + os.rmdir("/sys/fs/cgroup/schedtune/probe0/probe1") + if os.path.exists("/sys/fs/cgroup/schedtune/probe0"): + os.rmdir("/sys/fs/cgroup/schedtune/probe0") #TODO: remove NFC hacks if which("stop"): command = ["stop", "nfcd"] tools.helpers.run.user(args, command, check=False) + elif which("systemctl") and (tools.helpers.run.user(args, ["systemctl", "is-active", "-q", "nfcd"], check=False) == 0): + command = ["systemctl", "stop", "nfcd"] + tools.helpers.run.user(args, command, check=False) # Set permissions set_permissions(args) - helpers.lxc.start(args) - lxc_status = helpers.lxc.status(args) - timeout = 10 - while lxc_status != "RUNNING" and timeout > 0: - lxc_status = helpers.lxc.status(args) - logging.info( - "waiting {} seconds for container to start...".format(timeout)) - timeout = timeout - 1 - time.sleep(1) - if lxc_status != "RUNNING": - raise OSError("container failed to start") + # Create session-specific LXC config file + helpers.lxc.generate_session_lxc_config(args, session) + # Backwards compatibility + with open(tools.config.defaults["lxc"] + "/waydroid/config") as f: + if "config_session" not in f.read(): + helpers.mount.bind(args, session["waydroid_data"], + tools.config.defaults["data"]) + + # Mount rootfs + cfg = tools.config.load(args) + helpers.images.mount_rootfs(args, cfg["waydroid"]["images_path"], session) + helpers.protocol.set_aidl_version(args) + + helpers.lxc.start(args) services.hardware_manager.start(args) -def stop(args): + args.session = session + +def stop(args, quit_session=True): + logging.info("Stopping container") + try: services.hardware_manager.stop(args) status = helpers.lxc.status(args) @@ -196,6 +213,9 @@ def stop(args): if which("start"): command = ["start", "nfcd"] tools.helpers.run.user(args, command, check=False) + elif which("systemctl") and (tools.helpers.run.user(args, ["systemctl", "is-enabled", "-q", "nfcd"], check=False) == 0): + command = ["systemctl", "start", "nfcd"] + tools.helpers.run.user(args, command, check=False) # Sensors if which("waydroid-sensord"): @@ -208,14 +228,19 @@ def stop(args): # Umount rootfs helpers.images.umount_rootfs(args) - # Umount data - helpers.mount.umount_all(args, tools.config.defaults["data"]) + # Backwards compatibility + try: + helpers.mount.umount_all(args, tools.config.defaults["data"]) + except: + pass if "session" in args: - try: - os.kill(int(args.session["pid"]), signal.SIGUSR1) - except: - pass + if quit_session: + logging.info("Terminating session because the container was stopped") + try: + os.kill(int(args.session["pid"]), signal.SIGUSR1) + except: + pass del args.session except: pass