]> glassweightruler.freedombox.rocks Git - waydroid.git/blob - tools/actions/container_manager.py
tools: Remove umask 0
[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 uuid
11 import tools.config
12 from tools import helpers
13 from tools import services
14 import dbus
15 import dbus.service
16 import dbus.exceptions
17 from gi.repository import GLib
18
19 class DbusContainerManager(dbus.service.Object):
20 def __init__(self, looper, bus, object_path, args):
21 self.args = args
22 self.looper = looper
23 dbus.service.Object.__init__(self, bus, object_path)
24
25 @dbus.service.method("id.waydro.ContainerManager", in_signature='a{ss}', out_signature='')
26 def Start(self, session):
27 do_start(self.args, session)
28
29 @dbus.service.method("id.waydro.ContainerManager", in_signature='', out_signature='')
30 def Stop(self):
31 stop(self.args)
32
33 @dbus.service.method("id.waydro.ContainerManager", in_signature='', out_signature='')
34 def Freeze(self):
35 freeze(self.args)
36
37 @dbus.service.method("id.waydro.ContainerManager", in_signature='', out_signature='')
38 def Unfreeze(self):
39 unfreeze(self.args)
40
41 @dbus.service.method("id.waydro.ContainerManager", in_signature='', out_signature='a{ss}')
42 def GetSession(self):
43 try:
44 session = self.args.session
45 session["state"] = helpers.lxc.status(self.args)
46 return session
47 except AttributeError:
48 return {}
49
50 def service(args, looper):
51 dbus_obj = DbusContainerManager(looper, dbus.SystemBus(), '/ContainerManager', args)
52 looper.run()
53
54 def set_permissions(args, perm_list=None, mode="777"):
55 def chmod(path, mode):
56 if os.path.exists(path):
57 command = ["chmod", mode, "-R", path]
58 tools.helpers.run.user(args, command, check=False)
59
60 # Nodes list
61 if not perm_list:
62 perm_list = [
63 "/dev/ashmem",
64
65 # sw_sync for HWC
66 "/dev/sw_sync",
67 "/sys/kernel/debug/sync/sw_sync",
68
69 # Media
70 "/dev/Vcodec",
71 "/dev/MTK_SMI",
72 "/dev/mdp_sync",
73 "/dev/mtk_cmdq",
74
75 # Graphics
76 "/dev/dri",
77 "/dev/graphics",
78 "/dev/pvr_sync",
79 "/dev/ion",
80 ]
81
82 # Framebuffers
83 perm_list.extend(glob.glob("/dev/fb*"))
84 # Videos
85 perm_list.extend(glob.glob("/dev/video*"))
86
87 for path in perm_list:
88 chmod(path, mode)
89
90 def start(args):
91 try:
92 name = dbus.service.BusName("id.waydro.Container", dbus.SystemBus(), do_not_queue=True)
93 except dbus.exceptions.NameExistsException:
94 logging.error("Container service is already running")
95 return
96
97 status = helpers.lxc.status(args)
98 if status == "STOPPED":
99 # Load binder and ashmem drivers
100 cfg = tools.config.load(args)
101 if cfg["waydroid"]["vendor_type"] == "MAINLINE":
102 if helpers.drivers.probeBinderDriver(args) != 0:
103 logging.error("Failed to load Binder driver")
104 helpers.drivers.probeAshmemDriver(args)
105 helpers.drivers.loadBinderNodes(args)
106 set_permissions(args, [
107 "/dev/" + args.BINDER_DRIVER,
108 "/dev/" + args.VNDBINDER_DRIVER,
109 "/dev/" + args.HWBINDER_DRIVER
110 ], "666")
111
112 mainloop = GLib.MainLoop()
113
114 def sigint_handler(data):
115 stop(args)
116 mainloop.quit()
117
118 GLib.unix_signal_add(GLib.PRIORITY_HIGH, signal.SIGINT, sigint_handler, None)
119 GLib.unix_signal_add(GLib.PRIORITY_HIGH, signal.SIGTERM, sigint_handler, None)
120 service(args, mainloop)
121 else:
122 logging.error("WayDroid container is {}".format(status))
123
124 def do_start(args, session):
125 if "session" in args:
126 logging.info("Already tracking a session")
127 return
128
129 args.session = session
130
131 # Networking
132 command = [tools.config.tools_src +
133 "/data/scripts/waydroid-net.sh", "start"]
134 tools.helpers.run.user(args, command, check=False)
135
136 # Sensors
137 if which("waydroid-sensord"):
138 tools.helpers.run.user(
139 args, ["waydroid-sensord", "/dev/" + args.HWBINDER_DRIVER], output="background")
140
141 # Mount rootfs
142 cfg = tools.config.load(args)
143 helpers.images.mount_rootfs(args, cfg["waydroid"]["images_path"], args.session)
144
145 helpers.protocol.set_aidl_version(args)
146
147 # Mount data
148 helpers.mount.bind(args, args.session["waydroid_data"],
149 tools.config.defaults["data"])
150
151 # Cgroup hacks
152 if which("start"):
153 command = ["start", "cgroup-lite"]
154 tools.helpers.run.user(args, command, check=False)
155 if os.path.ismount("/sys/fs/cgroup/schedtune"):
156 command = ["umount", "-l", "/sys/fs/cgroup/schedtune"]
157 tools.helpers.run.user(args, command, check=False)
158
159 #TODO: remove NFC hacks
160 if which("stop"):
161 command = ["stop", "nfcd"]
162 tools.helpers.run.user(args, command, check=False)
163
164 # Set permissions
165 set_permissions(args)
166
167 helpers.lxc.start(args)
168 lxc_status = helpers.lxc.status(args)
169 timeout = 10
170 while lxc_status != "RUNNING" and timeout > 0:
171 lxc_status = helpers.lxc.status(args)
172 logging.info(
173 "waiting {} seconds for container to start...".format(timeout))
174 timeout = timeout - 1
175 time.sleep(1)
176 if lxc_status != "RUNNING":
177 raise OSError("container failed to start")
178
179 services.hardware_manager.start(args)
180
181 def stop(args):
182 try:
183 services.hardware_manager.stop(args)
184 status = helpers.lxc.status(args)
185 if status != "STOPPED":
186 helpers.lxc.stop(args)
187 while helpers.lxc.status(args) != "STOPPED":
188 pass
189
190 # Networking
191 command = [tools.config.tools_src +
192 "/data/scripts/waydroid-net.sh", "stop"]
193 tools.helpers.run.user(args, command, check=False)
194
195 #TODO: remove NFC hacks
196 if which("start"):
197 command = ["start", "nfcd"]
198 tools.helpers.run.user(args, command, check=False)
199
200 # Sensors
201 if which("waydroid-sensord"):
202 command = ["pidof", "waydroid-sensord"]
203 pid = tools.helpers.run.user(args, command, check=False, output_return=True).strip()
204 if pid:
205 command = ["kill", "-9", pid]
206 tools.helpers.run.user(args, command, check=False)
207
208 # Umount rootfs
209 helpers.images.umount_rootfs(args)
210
211 # Umount data
212 helpers.mount.umount_all(args, tools.config.defaults["data"])
213
214 if "session" in args:
215 try:
216 os.kill(int(args.session["pid"]), signal.SIGUSR1)
217 except:
218 pass
219 del args.session
220 except:
221 pass
222
223 def restart(args):
224 status = helpers.lxc.status(args)
225 if status == "RUNNING":
226 helpers.lxc.stop(args)
227 helpers.lxc.start(args)
228 else:
229 logging.error("WayDroid container is {}".format(status))
230
231 def freeze(args):
232 status = helpers.lxc.status(args)
233 if status == "RUNNING":
234 helpers.lxc.freeze(args)
235 while helpers.lxc.status(args) == "RUNNING":
236 pass
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 while helpers.lxc.status(args) == "FROZEN":
245 pass