blob: 249033f6909d7be77d812dc00537208ecced041b
1 | #include <errno.h> |
2 | #include <stdlib.h> |
3 | #include <string.h> |
4 | #include <sys/mount.h> |
5 | #include <sys/stat.h> |
6 | #include <sys/types.h> |
7 | #include <sys/wait.h> |
8 | #include <unistd.h> |
9 | #include <ctype.h> |
10 | #include <fcntl.h> |
11 | #include <fs_mgr.h> |
12 | #include "install.h" |
13 | #include "ui.h" |
14 | #include <dirent.h> |
15 | #include "bootloader_message/bootloader_message.h" |
16 | #include "recovery_amlogic.h" |
17 | |
18 | #include "ubootenv/set_display_mode.h" |
19 | |
20 | extern "C" { |
21 | #include "ubootenv/uboot_env.h" |
22 | } |
23 | |
24 | #define LOGE(...) ui_print("E:" __VA_ARGS__) |
25 | #define LOGW(...) fprintf(stdout, "W:" __VA_ARGS__) |
26 | #define LOGI(...) fprintf(stdout, "I:" __VA_ARGS__) |
27 | |
28 | static const int MAX_ARGS = 100; |
29 | static const int MAX_ARG_LENGTH = 4096; |
30 | #define NUM_OF_BLKDEVICE_TO_ENUM 3 |
31 | #define NUM_OF_PARTITION_TO_ENUM 6 |
32 | |
33 | static const char *UDISK_COMMAND_FILE = "/udisk/factory_update_param.aml"; |
34 | static const char *SDCARD_COMMAND_FILE = "/sdcard/factory_update_param.aml"; |
35 | |
36 | void setup_cache_mounts() { |
37 | int ret = 0; |
38 | ret = ensure_path_mounted("/cache"); |
39 | if (ret != 0) { |
40 | format_volume("/cache"); |
41 | } |
42 | } |
43 | |
44 | |
45 | |
46 | static int mount_fs_rdonly(char *device_name, Volume *vol, const char *fs_type) { |
47 | if (!mount(device_name, vol->mount_point, fs_type, |
48 | MS_NOATIME | MS_NODEV | MS_NODIRATIME | MS_RDONLY, 0)) { |
49 | LOGW("successful to mount %s on %s by read-only\n", |
50 | device_name, vol->mount_point); |
51 | return 0; |
52 | } else { |
53 | LOGE("failed to mount %s on %s by read-only (%s)\n", |
54 | device_name, vol->mount_point, strerror(errno)); |
55 | } |
56 | |
57 | return -1; |
58 | } |
59 | |
60 | int auto_mount_fs(char *device_name, Volume *vol) { |
61 | if (access(device_name, F_OK)) { |
62 | return -1; |
63 | } |
64 | |
65 | if (!strcmp(vol->fs_type, "auto")) { |
66 | if (!mount(device_name, vol->mount_point, "vfat", |
67 | MS_NOATIME | MS_NODEV | MS_NODIRATIME, "")) { |
68 | goto auto_mounted; |
69 | } else { |
70 | if (strstr(vol->mount_point, "sdcard")) { |
71 | LOGW("failed to mount %s on %s (%s).try read-only ...\n", |
72 | device_name, vol->mount_point, strerror(errno)); |
73 | if (!mount_fs_rdonly(device_name, vol, "vfat")) { |
74 | goto auto_mounted; |
75 | } |
76 | } |
77 | } |
78 | |
79 | if (!mount(device_name, vol->mount_point, "ntfs", |
80 | MS_NOATIME | MS_NODEV | MS_NODIRATIME, "")) { |
81 | goto auto_mounted; |
82 | } else { |
83 | if (strstr(vol->mount_point, "sdcard")) { |
84 | LOGW("failed to mount %s on %s (%s).try read-only ...\n", |
85 | device_name, vol->mount_point, strerror(errno)); |
86 | if (!mount_fs_rdonly(device_name, vol, "ntfs")) { |
87 | goto auto_mounted; |
88 | } |
89 | } |
90 | } |
91 | |
92 | if (!mount(device_name, vol->mount_point, "exfat", |
93 | MS_NOATIME | MS_NODEV | MS_NODIRATIME, "")) { |
94 | goto auto_mounted; |
95 | } else { |
96 | if (strstr(vol->mount_point, "sdcard")) { |
97 | LOGW("failed to mount %s on %s (%s).try read-only ...\n", |
98 | device_name, vol->mount_point, strerror(errno)); |
99 | if (!mount_fs_rdonly(device_name, vol, "exfat")) { |
100 | goto auto_mounted; |
101 | } |
102 | } |
103 | } |
104 | } else { |
105 | if(!mount(device_name, vol->mount_point, vol->fs_type, |
106 | MS_NOATIME | MS_NODEV | MS_NODIRATIME, "")) { |
107 | goto auto_mounted; |
108 | } else { |
109 | if (strstr(vol->mount_point, "sdcard")) { |
110 | LOGW("failed to mount %s on %s (%s).try read-only ...\n", |
111 | device_name, vol->mount_point, strerror(errno)); |
112 | if (!mount_fs_rdonly(device_name, vol, vol->fs_type)) { |
113 | goto auto_mounted; |
114 | } |
115 | } |
116 | } |
117 | } |
118 | |
119 | return -1; |
120 | |
121 | auto_mounted: |
122 | return 0; |
123 | } |
124 | |
125 | int customize_smart_device_mounted( |
126 | Volume *vol) { |
127 | int i = 0, j = 0; |
128 | int first_position = 0; |
129 | int second_position = 0; |
130 | char * tmp = NULL; |
131 | char *mounted_device = NULL; |
132 | char device_name[256] = {0}; |
133 | char device_boot[256] = {0}; |
134 | const char *usb_device = "/dev/block/sd"; |
135 | const char *sdcard_device = "/dev/block/mmcblk"; |
136 | |
137 | if (vol->blk_device != NULL) { |
138 | int num = 0; |
139 | const char *blk_device = vol->blk_device; |
140 | for (; *blk_device != '\0'; blk_device ++) { |
141 | if (*blk_device == '#') { |
142 | num ++; |
143 | } |
144 | } |
145 | |
146 | /* |
147 | * Contain two '#' for blk_device name in recovery.fstab |
148 | * such as /dev/block/sd## (udisk) |
149 | * such as /dev/block/mmcblk#p# (sdcard) |
150 | */ |
151 | if (num != 2) { |
152 | return 1; // Don't contain two '#' |
153 | } |
154 | |
155 | if (access(vol->mount_point, F_OK)) { |
156 | mkdir(vol->mount_point, 0755); |
157 | } |
158 | |
159 | // find '#' position |
160 | if (strchr(vol->blk_device, '#')) { |
161 | tmp = strchr(vol->blk_device, '#'); |
162 | first_position = tmp - vol->blk_device; |
163 | if (strlen(tmp+1) > 0 && strchr(tmp+1, '#')) { |
164 | tmp = strchr(tmp+1, '#'); |
165 | second_position = tmp - vol->blk_device; |
166 | } |
167 | } |
168 | |
169 | if (!first_position || !second_position) { |
170 | LOGW("decompose blk_device error(%s) in recovery.fstab\n", |
171 | vol->blk_device); |
172 | return -1; |
173 | } |
174 | |
175 | int copy_len = (strlen(vol->blk_device) < sizeof(device_name)) ? |
176 | strlen(vol->blk_device) : sizeof(device_name); |
177 | |
178 | for (i = 0; i < NUM_OF_BLKDEVICE_TO_ENUM; i ++) { |
179 | memset(device_name, '\0', sizeof(device_name)); |
180 | strncpy(device_name, vol->blk_device, copy_len); |
181 | |
182 | if (!strncmp(device_name, sdcard_device, strlen(sdcard_device))) { |
183 | // start from '0' for mmcblk0p# |
184 | device_name[first_position] = '0' + i; |
185 | } else if (!strncmp(device_name, usb_device, strlen(usb_device))) { |
186 | // start from 'a' for sda# |
187 | device_name[first_position] = 'a' + i; |
188 | } |
189 | |
190 | for (j = 1; j <= NUM_OF_PARTITION_TO_ENUM; j ++) { |
191 | device_name[second_position] = '0' + j; |
192 | if (!access(device_name, F_OK)) { |
193 | LOGW("try mount %s ...\n", device_name); |
194 | if (!auto_mount_fs(device_name, vol)) { |
195 | mounted_device = device_name; |
196 | LOGW("successful to mount %s\n", device_name); |
197 | goto mounted; |
198 | } |
199 | } |
200 | } |
201 | |
202 | if (!strncmp(device_name, sdcard_device, strlen(sdcard_device))) { |
203 | // mmcblk0p1->mmcblk0 |
204 | device_name[strlen(device_name) - 2] = '\0'; |
205 | sprintf(device_boot, "%s%s", device_name, "boot0"); |
206 | // TODO: Here,need to distinguish between cards and flash at best |
207 | } else if (!strncmp(device_name, usb_device, strlen(usb_device))) { |
208 | // sda1->sda |
209 | device_name[strlen(device_name) - 1] = '\0'; |
210 | } |
211 | |
212 | if (!access(device_name, F_OK)) { |
213 | if (strlen(device_boot) && (!access(device_boot, F_OK))) { |
214 | continue; |
215 | } |
216 | |
217 | LOGW("try mount %s ...\n", device_name); |
218 | if (!auto_mount_fs(device_name, vol)) { |
219 | mounted_device = device_name; |
220 | LOGW("successful to mount %s\n", device_name); |
221 | goto mounted; |
222 | } |
223 | } |
224 | } |
225 | } else { |
226 | LOGE("Can't get blk_device\n"); |
227 | } |
228 | |
229 | return -1; |
230 | |
231 | mounted: |
232 | return 0; |
233 | } |
234 | |
235 | int smart_device_mounted(Volume *vol) { |
236 | int i = 0, len = 0; |
237 | char * tmp = NULL; |
238 | char device_name[256] = {0}; |
239 | char *mounted_device = NULL; |
240 | |
241 | mkdir(vol->mount_point, 0755); |
242 | |
243 | if (vol->blk_device != NULL) { |
244 | int ret = customize_smart_device_mounted(vol); |
245 | if (ret <= 0) { |
246 | return ret; |
247 | } |
248 | } |
249 | |
250 | if (vol->blk_device != NULL) { |
251 | tmp = strchr(vol->blk_device, '#'); |
252 | len = tmp - vol->blk_device; |
253 | if (tmp && len < 255) { |
254 | strncpy(device_name, vol->blk_device, len); |
255 | for (i = 1; i <= NUM_OF_PARTITION_TO_ENUM; i++) { |
256 | device_name[len] = '0' + i; |
257 | device_name[len + 1] = '\0'; |
258 | LOGW("try mount %s ...\n", device_name); |
259 | if (!access(device_name, F_OK)) { |
260 | if (!auto_mount_fs(device_name, vol)) { |
261 | mounted_device = device_name; |
262 | LOGW("successful to mount %s\n", device_name); |
263 | goto mounted; |
264 | } |
265 | } |
266 | } |
267 | |
268 | const char *mmcblk = "/dev/block/mmcblk"; |
269 | if (!strncmp(device_name, mmcblk, strlen(mmcblk))) { |
270 | device_name[len - 1] = '\0'; |
271 | } else { |
272 | device_name[len] = '\0'; |
273 | } |
274 | |
275 | LOGW("try mount %s ...\n", device_name); |
276 | if (!access(device_name, F_OK)) { |
277 | if (!auto_mount_fs(device_name, vol)) { |
278 | mounted_device = device_name; |
279 | LOGW("successful to mount %s\n", device_name); |
280 | goto mounted; |
281 | } |
282 | } |
283 | } else { |
284 | LOGW("try mount %s ...\n", vol->blk_device); |
285 | strncpy(device_name, vol->blk_device, sizeof(device_name)); |
286 | if (!access(device_name, F_OK)) { |
287 | if (!auto_mount_fs(device_name, vol)) { |
288 | mounted_device = device_name; |
289 | LOGW("successful to mount %s\n", device_name); |
290 | goto mounted; |
291 | } |
292 | } |
293 | } |
294 | } |
295 | |
296 | return -1; |
297 | |
298 | mounted: |
299 | return 0; |
300 | } |
301 | |
302 | |
303 | //return value |
304 | // 0 mount OK |
305 | // -1 mount Faile |
306 | // 2 ignorel |
307 | int ensure_path_mounted_extra(Volume *v) { |
308 | Volume* vUsb = volume_for_path("/udisk"); |
309 | char tmp[128] = {0}; |
310 | |
311 | if (strcmp(v->fs_type, "ext4") == 0) { |
312 | if (strstr(v->mount_point, "system")) { |
313 | if (!mount(v->blk_device, v->mount_point, v->fs_type, |
314 | MS_NOATIME | MS_NODEV | MS_NODIRATIME | MS_RDONLY, "")) { |
315 | return 0; |
316 | } |
317 | } else { |
318 | if (!mount(v->blk_device, v->mount_point, v->fs_type, |
319 | MS_NOATIME | MS_NODEV | MS_NODIRATIME, "discard")) { |
320 | return 0; |
321 | } |
322 | } |
323 | LOGE("failed to mount %s (%s)\n", v->mount_point, strerror(errno)); |
324 | return -1; |
325 | } else if (strcmp(v->fs_type, "vfat") == 0 || |
326 | strcmp(v->fs_type, "auto") == 0 ) { |
327 | if (strstr(v->mount_point, "sdcard") || strstr(v->mount_point, "udisk")) { |
328 | int time_out = 2000000; |
329 | while (time_out) { |
330 | if (!smart_device_mounted(v)) { |
331 | return 0; |
332 | } |
333 | usleep(100000); |
334 | time_out -= 100000; |
335 | } |
336 | } else { |
337 | if (!mount(v->blk_device, v->mount_point, v->fs_type, |
338 | MS_NOATIME | MS_NODEV | MS_NODIRATIME | MS_RDONLY, "")) { |
339 | return 0; |
340 | } |
341 | } |
342 | LOGE("failed to mount %s (%s)\n", v->mount_point, strerror(errno)); |
343 | return -1; |
344 | } else { |
345 | return 2;//not deal |
346 | } |
347 | } |
348 | |
349 | void amlogic_init() { |
350 | set_display_mode("/etc/mesondisplay.cfg"); |
351 | sleep(1); |
352 | } |
353 | |
354 | void amlogic_get_args(std::vector<std::string>& args) { |
355 | |
356 | if (args.size() == 1) { |
357 | std::string content; |
358 | if (ensure_path_mounted(UDISK_COMMAND_FILE) == 0 && |
359 | android::base::ReadFileToString(UDISK_COMMAND_FILE, &content)) { |
360 | |
361 | std::vector<std::string> tokens = android::base::Split(content, "\n"); |
362 | for (auto it = tokens.begin(); it != tokens.end(); it++) { |
363 | // Skip empty and '\0'-filled tokens. |
364 | if (!it->empty() && (*it)[0] != '\0') { |
365 | args.push_back(std::move(*it)); |
366 | } |
367 | } |
368 | LOG(INFO) << "Got " << args.size() << " arguments from " << UDISK_COMMAND_FILE; |
369 | } |
370 | } |
371 | |
372 | if (args.size() == 1) { |
373 | std::string content; |
374 | if (ensure_path_mounted(SDCARD_COMMAND_FILE) == 0 && |
375 | android::base::ReadFileToString(SDCARD_COMMAND_FILE, &content)) { |
376 | |
377 | std::vector<std::string> tokens = android::base::Split(content, "\n"); |
378 | for (auto it = tokens.begin(); it != tokens.end(); it++) { |
379 | // Skip empty and '\0'-filled tokens. |
380 | if (!it->empty() && (*it)[0] != '\0') { |
381 | args.push_back(std::move(*it)); |
382 | } |
383 | } |
384 | LOG(INFO) << "Got " << args.size() << " arguments from " << SDCARD_COMMAND_FILE; |
385 | } |
386 | } |
387 | |
388 | if (args.size() == 1) { |
389 | args.push_back(std::move("--show_text")); |
390 | } |
391 | |
392 | } |
393 |