-
Notifications
You must be signed in to change notification settings - Fork 1
/
launch_daemonsu.sh
267 lines (217 loc) · 7.08 KB
/
launch_daemonsu.sh
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
#!/system/bin/sh
MODE=$1
log_print() {
echo "($MODE) $1"
echo "($MODE) $1" >> /dev/.launch_daemonsu.log
log -p i -t launch_daemonsu "($MODE) $1"
}
log_print "start"
if [ `mount | grep " /data " >/dev/null 2>&1; echo $?` -ne 0 ]; then
# /data not mounted yet, we will be called again later
log_print "abort: /data not mounted #1"
exit
fi
if [ `mount | grep " /data " | grep "tmpfs" >/dev/null 2>&1; echo $?` -eq 0 ]; then
# /data not mounted yet, we will be called again later
log_print "abort: /data not mounted #2"
exit
fi
if [ `cat /proc/mounts | grep /su >/dev/null 2>&1; echo $?` -eq 0 ]; then
if [ -d "/su/bin" ]; then
if [ `ps | grep -v "launch_daemonsu.sh" | grep "daemonsu" >/dev/null 2>&1; echo $?` -eq 0 ]; then
# nothing to do here
log_print "abort: daemonsu already running"
exit
fi
fi
fi
setprop sukernel.daemonsu.launch $MODE
loopsetup() {
LOOPDEVICE=
for DEV in $(ls /dev/block/loop*); do
if [ `losetup $DEV $1 >/dev/null 2>&1; echo $?` -eq 0 ]; then
LOOPDEVICE=$DEV
break
fi
done
log_print "loopsetup($1): $LOOPDEVICE"
}
resize() {
if [ `ls -l /data/su.img | grep " 33554432 " >/dev/null 2>&1; echo $?` -eq 0 ]; then
log_print "resizing /data/su.img from 32M to 96M"
e2fsck -p -f /data/su.img
resize2fs /data/su.img 96M
fi
}
if [ ! -d "/su/bin" ]; then
log_print "/su not mounted yet"
# not mounted yet, do our thing
REBOOT=false
# copy boot image backups
log_print "copying boot image backups from /cache to /data"
cp -f /cache/stock_boot_* /data/. 2>/dev/null
if [ -f "/data/su.img" ]; then
log_print "/data/su.img found"
e2fsck -p -f /data/su.img
# make sure the image is the right size
resize
fi
# newer image in /cache ?
# only used if recovery couldn't mount /data
if [ -f "/cache/su.img" ]; then
log_print "/cache/su.img found"
e2fsck -p -f /cache/su.img
OVERWRITE=true
if [ -f "/data/su.img" ]; then
# attempt merge, this will fail pre-M
# will probably also fail with /system installed busybox,
# but then again, is there anything busybox doesn't break?
# falls back to overwrite
log_print "/data/su.img found"
log_print "attempting merge"
mkdir /cache/data_img
mkdir /cache/cache_img
# setup loop devices
loopsetup /data/su.img
LOOPDATA=$LOOPDEVICE
log_print "$LOOPDATA /data/su.img"
loopsetup /cache/su.img
LOOPCACHE=$LOOPDEVICE
log_print "$LOOPCACHE /cache/su.img"
if [ ! -z "$LOOPDATA" ]; then
if [ ! -z "$LOOPCACHE" ]; then
# if loop devices have been setup, mount images
OK=true
if [ `mount -t ext4 -o rw,noatime $LOOPDATA /cache/data_img >/dev/null 2>&1; echo $?` -ne 0 ]; then
OK=false
fi
if [ `mount -t ext4 -o rw,noatime $LOOPCACHE /cache/cache_img >/dev/null 2>&1; echo $?` -ne 0 ]; then
OK=false
fi
if ($OK); then
# if mounts have succeeded, merge the images
if [ `cp -af /cache/cache_img/. /cache/data_img >/dev/null 2>&1; echo $?` -eq 0 ]; then
log_print "merge complete"
OVERWRITE=false
fi
fi
umount /cache/data_img
umount /cache/cache_img
fi
fi
losetup -d $LOOPDATA
losetup -d $LOOPCACHE
rmdir /cache/data_img
rmdir /cache/cache_img
fi
if ($OVERWRITE); then
# no /data/su.img or merge failed, replace
log_print "replacing /data/su.img with /cache/su.img"
mv /cache/su.img /data/su.img
# make sure the new image is the right size
resize
fi
rm /cache/su.img
fi
# do we have an APK to install ?
if [ -f "/cache/SuperSU.apk" ]; then
cp /cache/SuperSU.apk /data/SuperSU.apk
rm /cache/SuperSU.apk
fi
if [ -f "/data/SuperSU.apk" ]; then
log_print "installing SuperSU APK in /data"
APKPATH=eu.chainfire.supersu-1
for i in `ls /data/app | grep eu.chainfire.supersu- | grep -v eu.chainfire.supersu.pro`; do
if [ `cat /data/system/packages.xml | grep $i >/dev/null 2>&1; echo $?` -eq 0 ]; then
APKPATH=$i
break;
fi
done
rm -rf /data/app/eu.chainfire.supersu-*
log_print "target path: /data/app/$APKPATH"
mkdir /data/app/$APKPATH
chown 1000.1000 /data/app/$APKPATH
chmod 0755 /data/app/$APKPATH
chcon u:object_r:apk_data_file:s0 /data/app/$APKPATH
cp /data/SuperSU.apk /data/app/$APKPATH/base.apk
chown 1000.1000 /data/app/$APKPATH/base.apk
chmod 0644 /data/app/$APKPATH/base.apk
chcon u:object_r:apk_data_file:s0 /data/app/$APKPATH/base.apk
rm /data/SuperSU.apk
sync
# just in case
REBOOT=true
fi
# sometimes we need to reboot, make it so
if ($REBOOT); then
log_print "rebooting"
if [ "$MODE" = "post-fs-data" ]; then
# avoid device freeze (reason unknown)
sh -c "sleep 5; reboot" &
else
reboot
fi
exit
fi
# losetup is unreliable pre-M
if [ `cat /proc/mounts | grep /su >/dev/null 2>&1; echo $?` -ne 0 ]; then
loopsetup /data/su.img
if [ ! -z "$LOOPDEVICE" ]; then
mount -t ext4 -o rw,noatime $LOOPDEVICE /su
fi
fi
# trigger mount, should also work pre-M, but on post-fs-data trigger may
# be processed only after this script runs, causing a fallback to service launch
if [ `cat /proc/mounts | grep /su >/dev/null 2>&1; echo $?` -ne 0 ]; then
chcon u:object_r:system_data_file:s0 /data/su.img
chmod 0600 /data/su.img
setprop sukernel.mount 1
sleep 1
fi
# exit if all mount attempts have failed, script is likely to be called again
if [ `cat /proc/mounts | grep /su >/dev/null 2>&1; echo $?` -ne 0 ]; then
log_print "abort: mount failed"
exit
fi
# if other su binaries exist, route them to ours
mount -o bind /su/bin/su /sbin/su 2>/dev/null
mount -o bind /su/bin/su /system/bin/su 2>/dev/null
mount -o bind /su/bin/su /system/xbin/su 2>/dev/null
# poor man's overlay on /system/xbin
if [ -d "/su/xbin_bind" ]; then
cp -f -a /system/xbin/. /su/xbin_bind
rm -rf /su/xbin_bind/su
ln -s /su/bin/su /su/xbin_bind/su
mount -o bind /su/xbin_bind /system/xbin
fi
fi
# start daemon
if [ "$MODE" != "post-fs-data" ]; then
# if launched by service, replace this process (exec)
log_print "exec daemonsu"
exec /su/bin/daemonsu --auto-daemon
else
# if launched by exec, fork (non-exec) and wait for su.d to complete executing
log_print "fork daemonsu"
/su/bin/daemonsu --auto-daemon
# wait for a while for su.d to complete
if [ -d "/su/su.d" ]; then
log_print "waiting for su.d"
for i in 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16; do
# su.d finished ?
if [ -f "/dev/.su.d.complete" ]; then
break
fi
for j in 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16; do
# su.d finished ?
if [ -f "/dev/.su.d.complete" ]; then
break
fi
# sleep 16ms if usleep supported, warm up the CPU if not
# 16*16*16ms=4s maximum if usleep supported, else much shorter
usleep 16000
done
done
fi
log_print "end"
fi