]> glassweightruler.freedombox.rocks Git - waydroid.git/blob - tools/actions/container_manager.py
container: Umount on stop
[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 helpers.mount.umount_all(args, "/sys/fs/cgroup/schedtune")
141
142 #TODO: remove NFC hacks
143 if which("stop"):
144 command = ["stop", "nfcd"]
145 tools.helpers.run.user(args, command, check=False)
146
147 # Set permissions
148 set_permissions()
149
150 helpers.lxc.start(args)
151 session_cfg["session"]["state"] = helpers.lxc.status(args)
152 timeout = 10
153 while session_cfg["session"]["state"] != "RUNNING" and timeout > 0:
154 session_cfg["session"]["state"] = helpers.lxc.status(args)
155 logging.info(
156 "waiting {} seconds for container to start...".format(timeout))
157 timeout = timeout - 1
158 time.sleep(1)
159 if session_cfg["session"]["state"] != "RUNNING":
160 raise OSError("container failed to start")
161 tools.config.save_session(session_cfg)
162
163 services.hardware_manager.start(args)
164
165 signal.signal(signal.SIGINT, signal_handler)
166 while os.path.exists(tools.config.session_defaults["config_path"]):
167 session_cfg = tools.config.load_session()
168 if session_cfg["session"]["state"] == "STOPPED":
169 services.hardware_manager.stop(args)
170 sys.exit(0)
171 elif session_cfg["session"]["state"] == "UNFREEZE":
172 session_cfg["session"]["state"] = helpers.lxc.status(args)
173 tools.config.save_session(session_cfg)
174 unfreeze(args)
175 time.sleep(1)
176
177 logging.warning("session manager stopped, stopping container and waiting...")
178 stop(args)
179 services.hardware_manager.stop(args)
180 start(args)
181 else:
182 logging.error("WayDroid container is {}".format(status))
183
184 def stop(args):
185 status = helpers.lxc.status(args)
186 if status != "STOPPED":
187 helpers.lxc.stop(args)
188 if os.path.exists(tools.config.session_defaults["config_path"]):
189 session_cfg = tools.config.load_session()
190 session_cfg["session"]["state"] = helpers.lxc.status(args)
191 tools.config.save_session(session_cfg)
192
193 # Networking
194 command = [tools.config.tools_src +
195 "/data/scripts/waydroid-net.sh", "stop"]
196 tools.helpers.run.user(args, command, check=False)
197
198 #TODO: remove NFC hacks
199 if which("start"):
200 command = ["start", "nfcd"]
201 tools.helpers.run.user(args, command, check=False)
202
203 # Sensors
204 if which("waydroid-sensord"):
205 command = ["pidof", "waydroid-sensord"]
206 pid = tools.helpers.run.user(args, command, check=False, output_return=True)
207 if pid:
208 command = ["kill", "-9", pid]
209 tools.helpers.run.user(args, command, check=False)
210
211 # Umount rootfs
212 helpers.images.umount_rootfs(args)
213
214 # Umount data
215 helpers.mount.umount_all(args, tools.config.defaults["data"])
216
217 else:
218 logging.error("WayDroid container is {}".format(status))
219
220 def restart(args):
221 status = helpers.lxc.status(args)
222 if status == "RUNNING":
223 helpers.lxc.stop(args)
224 helpers.lxc.start(args)
225 else:
226 logging.error("WayDroid container is {}".format(status))
227
228 def freeze(args):
229 status = helpers.lxc.status(args)
230 if status == "RUNNING":
231 helpers.lxc.freeze(args)
232 if os.path.exists(tools.config.session_defaults["config_path"]):
233 session_cfg = tools.config.load_session()
234 session_cfg["session"]["state"] = helpers.lxc.status(args)
235 tools.config.save_session(session_cfg)
236 else:
237 logging.error("WayDroid container is {}".format(status))
238
239 def unfreeze(args):
240 status = helpers.lxc.status(args)
241 if status == "FROZEN":
242 helpers.lxc.unfreeze(args)
243 if os.path.exists(tools.config.session_defaults["config_path"]):
244 session_cfg = tools.config.load_session()
245 session_cfg["session"]["state"] = helpers.lxc.status(args)
246 tools.config.save_session(session_cfg)
247 else:
248 logging.error("WayDroid container is {}".format(status))