]> glassweightruler.freedombox.rocks Git - waydroid.git/blobdiff - tools/actions/container_manager.py
hardware_manager: Prevent race-condition in upgrade check
[waydroid.git] / tools / actions / container_manager.py
index 29ba55268b64a1c6b3397828927dc71906150282..bcefc08eeaf5a77dbf0b4a3e2ee1d960081f59b1 100644 (file)
@@ -22,13 +22,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):
@@ -123,51 +130,68 @@ def start(args):
 
 def do_start(args, session):
     if "session" in args:
-        logging.info("Already tracking a session")
-        return
-
-    args.session = session
+        raise RuntimeError("Already tracking a 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)
 
+    # 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):
     try:
         services.hardware_manager.stop(args)
         status = helpers.lxc.status(args)
@@ -185,6 +209,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"):
@@ -197,14 +224,18 @@ 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:
+                try:
+                    os.kill(int(args.session["pid"]), signal.SIGUSR1)
+                except:
+                    pass
             del args.session
     except:
         pass