]> glassweightruler.freedombox.rocks Git - waydroid.git/blob - tools/actions/container_manager.py
container: Use umount -l for schedtune
[waydroid.git] / tools / actions / container_manager.py
1 # Copyright 2021 Erfan Abdi
2 # SPDX-License-Identifier: GPL-3.0-or-later
3 from shutil import which
4 import logging
5 import os
6 import time
7 import glob
8 import signal
9 import sys
10 import tools.config
11 from tools import helpers
12 from tools import services
13
14
15 def start(args):
16 def make_prop(full_props_path):
17 def add_prop(key, cfg_key):
18 value = session_cfg["session"][cfg_key]
19 if value != "None":
20 value = value.replace("/mnt/", "/mnt_extra/")
21 props.append(key + "=" + value)
22
23 if not os.path.isfile(args.work + "/waydroid_base.prop"):
24 raise RuntimeError("waydroid_base.prop Not found")
25 with open(args.work + "/waydroid_base.prop") as f:
26 props = f.read().splitlines()
27 if not props:
28 raise RuntimeError("waydroid_base.prop is broken!!?")
29
30 add_prop("waydroid.host.user", "user_name")
31 add_prop("waydroid.host.uid", "user_id")
32 add_prop("waydroid.host.gid", "group_id")
33 add_prop("waydroid.xdg_runtime_dir", "xdg_runtime_dir")
34 add_prop("waydroid.pulse_runtime_path", "pulse_runtime_path")
35 add_prop("waydroid.wayland_display", "wayland_display")
36 if which("waydroid-sensord") is None:
37 props.append("waydroid.stub_sensors_hal=1")
38 dpi = session_cfg["session"]["lcd_density"]
39 if dpi != "0":
40 props.append("ro.sf.lcd_density=" + dpi)
41
42 final_props = open(full_props_path, "w")
43 for prop in props:
44 final_props.write(prop + "\n")
45 final_props.close()
46 os.chmod(full_props_path, 0o644)
47
48 def set_permissions(perm_list=None, mode="777"):
49 def chmod(path, mode):
50 if os.path.exists(path):
51 command = ["chmod", mode, "-R", path]
52 tools.helpers.run.user(args, command, check=False)
53
54 # Nodes list
55 if not perm_list:
56 perm_list = [
57 "/dev/ashmem",
58
59 # sw_sync for HWC
60 "/dev/sw_sync",
61 "/sys/kernel/debug/sync/sw_sync",
62
63 # Media
64 "/dev/Vcodec",
65 "/dev/MTK_SMI",
66 "/dev/mdp_sync",
67 "/dev/mtk_cmdq",
68
69 # Graphics
70 "/dev/dri",
71 "/dev/graphics",
72 ]
73
74 # Framebuffers
75 perm_list.extend(glob.glob("/dev/fb*"))
76 # Videos
77 perm_list.extend(glob.glob("/dev/video*"))
78
79 for path in perm_list:
80 chmod(path, mode)
81
82 def signal_handler(sig, frame):
83 services.hardware_manager.stop(args)
84 stop(args)
85 sys.exit(0)
86
87 status = helpers.lxc.status(args)
88 if status == "STOPPED":
89 # Load binder and ashmem drivers
90 cfg = tools.config.load(args)
91 if cfg["waydroid"]["vendor_type"] == "MAINLINE":
92 if helpers.drivers.probeBinderDriver(args) != 0:
93 logging.error("Failed to load Binder driver")
94 if helpers.drivers.probeAshmemDriver(args) != 0:
95 logging.error("Failed to load Ashmem driver")
96 helpers.drivers.loadBinderNodes(args)
97 set_permissions([
98 "/dev/" + args.BINDER_DRIVER,
99 "/dev/" + args.VNDBINDER_DRIVER,
100 "/dev/" + args.HWBINDER_DRIVER
101 ], "666")
102
103 if os.path.exists(tools.config.session_defaults["config_path"]):
104 session_cfg = tools.config.load_session()
105 if session_cfg["session"]["state"] != "STOPPED":
106 logging.warning("Found session config on state: {}, restart session".format(
107 session_cfg["session"]["state"]))
108 os.remove(tools.config.session_defaults["config_path"])
109 logging.debug("Container manager is waiting for session to load")
110 while not os.path.exists(tools.config.session_defaults["config_path"]):
111 time.sleep(1)
112
113 # Load session configs
114 session_cfg = tools.config.load_session()
115
116 # Generate props
117 make_prop(args.work + "/waydroid.prop")
118
119 # Networking
120 command = [tools.config.tools_src +
121 "/data/scripts/waydroid-net.sh", "start"]
122 tools.helpers.run.user(args, command, check=False)
123
124 # Sensors
125 if which("waydroid-sensord"):
126 tools.helpers.run.user(
127 args, ["waydroid-sensord", "/dev/" + args.HWBINDER_DRIVER], output="background")
128
129 # Mount rootfs
130 helpers.images.mount_rootfs(args, cfg["waydroid"]["images_path"])
131
132 # Mount data
133 helpers.mount.bind(args, session_cfg["session"]["waydroid_data"],
134 tools.config.defaults["data"])
135
136 # Cgroup hacks
137 if which("start"):
138 command = ["start", "cgroup-lite"]
139 tools.helpers.run.user(args, command, check=False)
140 command = ["umount", "-l", "/sys/fs/cgroup/schedtune"]
141 tools.helpers.run.user(args, command, check=False)
142
143 #TODO: remove NFC hacks
144 if which("stop"):
145 command = ["stop", "nfcd"]
146 tools.helpers.run.user(args, command, check=False)
147
148 # Set permissions
149 set_permissions()
150
151 helpers.lxc.start(args)
152 session_cfg["session"]["state"] = helpers.lxc.status(args)
153 timeout = 10
154 while session_cfg["session"]["state"] != "RUNNING" and timeout > 0:
155 session_cfg["session"]["state"] = helpers.lxc.status(args)
156 logging.info(
157 "waiting {} seconds for container to start...".format(timeout))
158 timeout = timeout - 1
159 time.sleep(1)
160 if session_cfg["session"]["state"] != "RUNNING":
161 raise OSError("container failed to start")
162 tools.config.save_session(session_cfg)
163
164 services.hardware_manager.start(args)
165
166 signal.signal(signal.SIGINT, signal_handler)
167 while os.path.exists(tools.config.session_defaults["config_path"]):
168 session_cfg = tools.config.load_session()
169 if session_cfg["session"]["state"] == "STOPPED":
170 services.hardware_manager.stop(args)
171 sys.exit(0)
172 elif session_cfg["session"]["state"] == "UNFREEZE":
173 session_cfg["session"]["state"] = helpers.lxc.status(args)
174 tools.config.save_session(session_cfg)
175 unfreeze(args)
176 time.sleep(1)
177
178 logging.warning("session manager stopped, stopping container and waiting...")
179 stop(args)
180 services.hardware_manager.stop(args)
181 start(args)
182 else:
183 logging.error("WayDroid container is {}".format(status))
184
185 def stop(args):
186 status = helpers.lxc.status(args)
187 if status != "STOPPED":
188 helpers.lxc.stop(args)
189 if os.path.exists(tools.config.session_defaults["config_path"]):
190 session_cfg = tools.config.load_session()
191 session_cfg["session"]["state"] = helpers.lxc.status(args)
192 tools.config.save_session(session_cfg)
193
194 # Networking
195 command = [tools.config.tools_src +
196 "/data/scripts/waydroid-net.sh", "stop"]
197 tools.helpers.run.user(args, command, check=False)
198
199 #TODO: remove NFC hacks
200 if which("start"):
201 command = ["start", "nfcd"]
202 tools.helpers.run.user(args, command, check=False)
203
204 # Sensors
205 if which("waydroid-sensord"):
206 command = ["pidof", "waydroid-sensord"]
207 pid = tools.helpers.run.user(args, command, check=False, output_return=True)
208 if pid:
209 command = ["kill", "-9", pid]
210 tools.helpers.run.user(args, command, check=False)
211
212 # Umount rootfs
213 helpers.images.umount_rootfs(args)
214
215 # Umount data
216 helpers.mount.umount_all(args, tools.config.defaults["data"])
217
218 else:
219 logging.error("WayDroid container is {}".format(status))
220
221 def restart(args):
222 status = helpers.lxc.status(args)
223 if status == "RUNNING":
224 helpers.lxc.stop(args)
225 helpers.lxc.start(args)
226 else:
227 logging.error("WayDroid container is {}".format(status))
228
229 def freeze(args):
230 status = helpers.lxc.status(args)
231 if status == "RUNNING":
232 helpers.lxc.freeze(args)
233 if os.path.exists(tools.config.session_defaults["config_path"]):
234 session_cfg = tools.config.load_session()
235 session_cfg["session"]["state"] = helpers.lxc.status(args)
236 tools.config.save_session(session_cfg)
237 else:
238 logging.error("WayDroid container is {}".format(status))
239
240 def unfreeze(args):
241 status = helpers.lxc.status(args)
242 if status == "FROZEN":
243 helpers.lxc.unfreeze(args)
244 if os.path.exists(tools.config.session_defaults["config_path"]):
245 session_cfg = tools.config.load_session()
246 session_cfg["session"]["state"] = helpers.lxc.status(args)
247 tools.config.save_session(session_cfg)
248 else:
249 logging.error("WayDroid container is {}".format(status))