]> glassweightruler.freedombox.rocks Git - waydroid.git/commitdiff
lxc: Create session-specific mount entries
authorAlessandro Astone <ales.astone@gmail.com>
Sat, 21 Jan 2023 23:13:08 +0000 (00:13 +0100)
committerAlessandro Astone <ales.astone@gmail.com>
Sun, 22 Jan 2023 14:38:06 +0000 (15:38 +0100)
Closes: #704
data/configs/config_base
tools/actions/container_manager.py
tools/helpers/lxc.py

index 27e070fba4dce87e46d37cce1d0ceed021c960b4..99fd198f526c43436df18f69a68791dbfce0b814 100644 (file)
@@ -12,6 +12,7 @@ lxc.mount.auto = cgroup:ro sys:ro proc
 lxc.console.path = none
 
 lxc.include = /var/lib/waydroid/lxc/waydroid/config_nodes
+lxc.include = /var/lib/waydroid/lxc/waydroid/config_session
 
 lxc.hook.post-stop = /dev/null
 
index 0092f1e61e5c6898a27550b96563561a5496a879..e537e1843a7eb715d36ecbe004c3f44cc258fcde 100644 (file)
@@ -145,10 +145,6 @@ def do_start(args, session):
 
     helpers.protocol.set_aidl_version(args)
 
-    # Mount data
-    helpers.mount.bind(args, session["waydroid_data"],
-                       tools.config.defaults["data"])
-
     # Cgroup hacks
     if which("start"):
         command = ["start", "cgroup-lite"]
@@ -165,6 +161,14 @@ def do_start(args, session):
     # 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"])
+
     helpers.lxc.start(args)
     services.hardware_manager.start(args)
 
@@ -200,8 +204,11 @@ def stop(args, quit_session=True):
         # 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:
             if quit_session:
index c0ac9d122da5dba67eb76ad40076fc1b15d8e1dc..0221d0b46aa49c0948a96e9f1e3f32d26c204f0c 100644 (file)
@@ -21,22 +21,24 @@ def get_lxc_version(args):
     else:
         return 0
 
+def add_node_entry(nodes, src, dist, mnt_type, options, check):
+    if check and not os.path.exists(src):
+        return False
+    entry = "lxc.mount.entry = "
+    entry += src + " "
+    if dist is None:
+        dist = src[1:]
+    entry += dist + " "
+    entry += mnt_type + " "
+    entry += options
+    nodes.append(entry)
+    return True
 
 def generate_nodes_lxc_config(args):
+    nodes = []
     def make_entry(src, dist=None, mnt_type="none", options="bind,create=file,optional 0 0", check=True):
-        if check and not os.path.exists(src):
-            return False
-        entry = "lxc.mount.entry = "
-        entry += src + " "
-        if dist is None:
-            dist = src[1:]
-        entry += dist + " "
-        entry += mnt_type + " "
-        entry += options
-        nodes.append(entry)
-        return True
+        return add_node_entry(nodes, src, dist, mnt_type, options, check)
 
-    nodes = []
     # Necessary dev nodes
     make_entry("tmpfs", "dev", "tmpfs", "nosuid 0 0", False)
     make_entry("/dev/zero")
@@ -84,19 +86,10 @@ def generate_nodes_lxc_config(args):
     # Low memory killer sys node
     make_entry("/sys/module/lowmemorykiller", options="bind,create=dir,optional 0 0")
 
-    # Mount /data
-    make_entry("tmpfs", "mnt", "tmpfs", "mode=0755,uid=0,gid=1000", False)
-    make_entry(tools.config.defaults["data"], "data", options="bind 0 0", check=False)
-
     # Mount host permissions
     make_entry(tools.config.defaults["host_perms"],
                "vendor/etc/host-permissions", options="bind,optional 0 0")
 
-    # Recursive mount /run to provide necessary host sockets
-    make_entry("/run", options="rbind,create=dir 0 0")
-    # And /dev/shm
-    make_entry("/dev/shm", options="rbind,create=dir,optional 0 0")
-
     # Necessary sw_sync node for HWC
     make_entry("/dev/sw_sync")
     make_entry("/sys/kernel/debug", options="rbind,create=dir,optional 0 0")
@@ -118,14 +111,10 @@ def generate_nodes_lxc_config(args):
     make_entry("/mnt/wslg", "mnt_extra/wslg",
                options="rbind,create=dir,optional 0 0")
 
-    # var
-    make_entry("tmpfs", "var", "tmpfs", "nodev 0 0", False)
-    make_entry("/var/run", options="rbind,create=dir,optional 0 0")
-
-    # tmp
+    # Make a tmpfs at every possible rootfs mountpoint
     make_entry("tmpfs", "tmp", "tmpfs", "nodev 0 0", False)
-    for n in glob.glob("/tmp/run-*"):
-        make_entry(n, options="rbind,create=dir,optional 0 0")
+    make_entry("tmpfs", "var", "tmpfs", "nodev 0 0", False)
+    make_entry("tmpfs", "run", "tmpfs", "nodev 0 0", False)
 
     # NFC config
     make_entry("/system/etc/libnfc-nci.conf", options="bind,optional 0 0")
@@ -185,6 +174,43 @@ def set_lxc_config(args):
     command = ["mv", config_nodes_tmp_path, lxc_path]
     tools.helpers.run.user(args, command)
 
+    # Create empty file
+    open(os.path.join(lxc_path, "config_session"), mode="w").close()
+
+def generate_session_lxc_config(args, session):
+    nodes = []
+    def make_entry(src, dist=None, mnt_type="none", options="rbind,create=file 0 0"):
+        if any(x in src for x in ["\n", "\r"]):
+            logging.warning("User-provided mount path contains illegal character")
+            return False
+        if dist is None and (not os.path.exists(src) or
+                             str(os.stat(src).st_uid) != session["user_id"]):
+            logging.warning("User-provided mount path is not owned by user")
+            return False
+        return add_node_entry(nodes, src, dist, mnt_type, options, check=False)
+
+    # Make sure XDG_RUNTIME_DIR exists
+    if not make_entry("tmpfs", session["xdg_runtime_dir"], options="create=dir 0 0"):
+        raise OSError("Failed to create XDG_RUNTIME_DIR mount point")
+
+    wayland_socket = os.path.realpath(os.path.join(session["xdg_runtime_dir"], session["wayland_display"]))
+    if not make_entry(wayland_socket):
+        raise OSError("Failed to bind Wayland socket")
+
+    pulse_socket = os.path.join(session["pulse_runtime_path"], "native")
+    make_entry(pulse_socket)
+
+    if not make_entry(session["waydroid_data"], "data", options="rbind 0 0"):
+        raise OSError("Failed to bind userdata")
+
+    lxc_path = tools.config.defaults["lxc"] + "/waydroid"
+    config_nodes_tmp_path = args.work + "/config_session"
+    config_nodes = open(config_nodes_tmp_path, "w")
+    for node in nodes:
+        config_nodes.write(node + "\n")
+    config_nodes.close()
+    command = ["mv", config_nodes_tmp_path, lxc_path]
+    tools.helpers.run.user(args, command)
 
 def make_base_props(args):
     def find_hal(hardware):