]> glassweightruler.freedombox.rocks Git - waydroid.git/blob - tools/actions/container_manager.py
Remove RW image overlay when upgrading images
[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 services.hardware_manager.start(args)
169
170 def stop(args):
171 try:
172 services.hardware_manager.stop(args)
173 status = helpers.lxc.status(args)
174 if status != "STOPPED":
175 helpers.lxc.stop(args)
176 while helpers.lxc.status(args) != "STOPPED":
177 pass
178
179 # Networking
180 command = [tools.config.tools_src +
181 "/data/scripts/waydroid-net.sh", "stop"]
182 tools.helpers.run.user(args, command, check=False)
183
184 #TODO: remove NFC hacks
185 if which("start"):
186 command = ["start", "nfcd"]
187 tools.helpers.run.user(args, command, check=False)
188
189 # Sensors
190 if which("waydroid-sensord"):
191 command = ["pidof", "waydroid-sensord"]
192 pid = tools.helpers.run.user(args, command, check=False, output_return=True).strip()
193 if pid:
194 command = ["kill", "-9", pid]
195 tools.helpers.run.user(args, command, check=False)
196
197 # Umount rootfs
198 helpers.images.umount_rootfs(args)
199
200 # Umount data
201 helpers.mount.umount_all(args, tools.config.defaults["data"])
202
203 if "session" in args:
204 try:
205 os.kill(int(args.session["pid"]), signal.SIGUSR1)
206 except:
207 pass
208 del args.session
209 except:
210 pass
211
212 def restart(args):
213 status = helpers.lxc.status(args)
214 if status == "RUNNING":
215 helpers.lxc.stop(args)
216 helpers.lxc.start(args)
217 else:
218 logging.error("WayDroid container is {}".format(status))
219
220 def freeze(args):
221 status = helpers.lxc.status(args)
222 if status == "RUNNING":
223 helpers.lxc.freeze(args)
224 while helpers.lxc.status(args) == "RUNNING":
225 pass
226 else:
227 logging.error("WayDroid container is {}".format(status))
228
229 def unfreeze(args):
230 status = helpers.lxc.status(args)
231 if status == "FROZEN":
232 helpers.lxc.unfreeze(args)
233 while helpers.lxc.status(args) == "FROZEN":
234 pass