1*4882a593Smuzhiyun /*
2*4882a593Smuzhiyun * Copyright (C) 2007 The Android Open Source Project
3*4882a593Smuzhiyun *
4*4882a593Smuzhiyun * Licensed under the Apache License, Version 2.0 (the "License");
5*4882a593Smuzhiyun * you may not use this file except in compliance with the License.
6*4882a593Smuzhiyun * You may obtain a copy of the License at
7*4882a593Smuzhiyun *
8*4882a593Smuzhiyun * http://www.apache.org/licenses/LICENSE-2.0
9*4882a593Smuzhiyun *
10*4882a593Smuzhiyun * Unless required by applicable law or agreed to in writing, software
11*4882a593Smuzhiyun * distributed under the License is distributed on an "AS IS" BASIS,
12*4882a593Smuzhiyun * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13*4882a593Smuzhiyun * See the License for the specific language governing permissions and
14*4882a593Smuzhiyun * limitations under the License.
15*4882a593Smuzhiyun */
16*4882a593Smuzhiyun
17*4882a593Smuzhiyun #include <errno.h>
18*4882a593Smuzhiyun #include <stdlib.h>
19*4882a593Smuzhiyun #include <string.h>
20*4882a593Smuzhiyun #include <sys/mount.h>
21*4882a593Smuzhiyun #include <sys/stat.h>
22*4882a593Smuzhiyun #include <sys/types.h>
23*4882a593Smuzhiyun #include <unistd.h>
24*4882a593Smuzhiyun #include <ctype.h>
25*4882a593Smuzhiyun
26*4882a593Smuzhiyun #include "mtdutils/mtdutils.h"
27*4882a593Smuzhiyun #include "mtdutils/mounts.h"
28*4882a593Smuzhiyun #include "roots.h"
29*4882a593Smuzhiyun #include "common.h"
30*4882a593Smuzhiyun #include "rktools.h"
31*4882a593Smuzhiyun #include "mtdutils/rk29.h"
32*4882a593Smuzhiyun
33*4882a593Smuzhiyun static int num_volumes = 0;
34*4882a593Smuzhiyun static Volume* device_volumes = NULL;
35*4882a593Smuzhiyun static char mount_point[256] = {0};
36*4882a593Smuzhiyun
37*4882a593Smuzhiyun #define VOLUME_TO_LABEL(v) ((strrchr(v->mount_point, '/') ? : "/unknown") + 1)
38*4882a593Smuzhiyun
get_link_path(const char * linkpath,char * buf,int count)39*4882a593Smuzhiyun char * get_link_path(const char* linkpath, char * buf, int count)
40*4882a593Smuzhiyun {
41*4882a593Smuzhiyun int i;
42*4882a593Smuzhiyun int rslt;
43*4882a593Smuzhiyun char path[256];
44*4882a593Smuzhiyun
45*4882a593Smuzhiyun memset(path, 0, sizeof(path));
46*4882a593Smuzhiyun strcpy(path, linkpath);
47*4882a593Smuzhiyun for (i = strlen(linkpath); i > 0; i--) {
48*4882a593Smuzhiyun if (path[i] == '/') {
49*4882a593Smuzhiyun path[i] = '\0';
50*4882a593Smuzhiyun break;
51*4882a593Smuzhiyun }
52*4882a593Smuzhiyun }
53*4882a593Smuzhiyun
54*4882a593Smuzhiyun rslt = readlink(path, buf, count - 1);
55*4882a593Smuzhiyun if (rslt < 0 || (rslt >= count - 1)) {
56*4882a593Smuzhiyun // printf("No link to path [%s]!!! \n", path);
57*4882a593Smuzhiyun return NULL;
58*4882a593Smuzhiyun }
59*4882a593Smuzhiyun
60*4882a593Smuzhiyun if (buf[0] != '/') {
61*4882a593Smuzhiyun char tmp[256];
62*4882a593Smuzhiyun memset(tmp, 0, sizeof(tmp));
63*4882a593Smuzhiyun memcpy(tmp, buf, strlen(buf));
64*4882a593Smuzhiyun
65*4882a593Smuzhiyun memset(buf, 0, sizeof(buf));
66*4882a593Smuzhiyun memcpy(buf + 1, tmp, strlen(tmp));
67*4882a593Smuzhiyun
68*4882a593Smuzhiyun buf[0] = '/';
69*4882a593Smuzhiyun }
70*4882a593Smuzhiyun
71*4882a593Smuzhiyun // printf("buf = %s \n", buf);
72*4882a593Smuzhiyun return buf;
73*4882a593Smuzhiyun }
74*4882a593Smuzhiyun
get_mounted_device_from_path(const char * path)75*4882a593Smuzhiyun const char* get_mounted_device_from_path(const char* path)
76*4882a593Smuzhiyun {
77*4882a593Smuzhiyun const MountedVolume *volume;
78*4882a593Smuzhiyun
79*4882a593Smuzhiyun int result = scan_mounted_volumes();
80*4882a593Smuzhiyun if (result < 0) {
81*4882a593Smuzhiyun LOGE("failed to scan mounted volumes\n");
82*4882a593Smuzhiyun return NULL;
83*4882a593Smuzhiyun }
84*4882a593Smuzhiyun
85*4882a593Smuzhiyun volume = find_mounted_volume_by_mount_point(path);
86*4882a593Smuzhiyun if (!volume) {
87*4882a593Smuzhiyun LOGE("failed to get volume from %s\n", path);
88*4882a593Smuzhiyun return NULL;
89*4882a593Smuzhiyun }
90*4882a593Smuzhiyun
91*4882a593Smuzhiyun return volume->device;
92*4882a593Smuzhiyun }
93*4882a593Smuzhiyun
load_volume_table()94*4882a593Smuzhiyun void load_volume_table()
95*4882a593Smuzhiyun {
96*4882a593Smuzhiyun int alloc = 2;
97*4882a593Smuzhiyun device_volumes = malloc(alloc * sizeof(Volume));
98*4882a593Smuzhiyun
99*4882a593Smuzhiyun // Insert an entry for /tmp, which is the ramdisk and is always mounted.
100*4882a593Smuzhiyun device_volumes[0].mount_point = "/tmp";
101*4882a593Smuzhiyun device_volumes[0].fs_type = "ramdisk";
102*4882a593Smuzhiyun device_volumes[0].device = NULL;
103*4882a593Smuzhiyun device_volumes[0].device2 = NULL;
104*4882a593Smuzhiyun device_volumes[0].option = NULL;
105*4882a593Smuzhiyun device_volumes[0].dump = NULL;
106*4882a593Smuzhiyun device_volumes[0].pass = NULL;
107*4882a593Smuzhiyun num_volumes = 1;
108*4882a593Smuzhiyun
109*4882a593Smuzhiyun FILE* fstab = fopen("/etc/fstab", "r");
110*4882a593Smuzhiyun if (fstab == NULL) {
111*4882a593Smuzhiyun LOGE("failed to open /etc/fstab (%d)\n", errno);
112*4882a593Smuzhiyun return;
113*4882a593Smuzhiyun }
114*4882a593Smuzhiyun
115*4882a593Smuzhiyun char buffer[1024];
116*4882a593Smuzhiyun char file_system[1024];
117*4882a593Smuzhiyun char mount_point[1024];
118*4882a593Smuzhiyun char fs_type[1024];
119*4882a593Smuzhiyun char option[1024];
120*4882a593Smuzhiyun char dump[1024];
121*4882a593Smuzhiyun char pass[1024];
122*4882a593Smuzhiyun char device[1024];
123*4882a593Smuzhiyun int i;
124*4882a593Smuzhiyun while (fgets(buffer, sizeof(buffer) - 1, fstab)) {
125*4882a593Smuzhiyun i = sscanf(buffer, "%s %s %s %s %s %s", file_system,
126*4882a593Smuzhiyun mount_point, fs_type, option, dump, pass);
127*4882a593Smuzhiyun if (file_system[0] == '#') continue;
128*4882a593Smuzhiyun //printf("load_volume_table file_system:%s, mount_point:%s, fs_type:%s, option:%s, dump:%s, pass:%s\n", file_system, mount_point, fs_type, option, dump, pass);
129*4882a593Smuzhiyun /* HACK: Convert *LABEL to "by-name" symlink */
130*4882a593Smuzhiyun if (strstr(file_system, "LABEL="))
131*4882a593Smuzhiyun snprintf(device, sizeof(device), "/dev/block/by-name/%s",
132*4882a593Smuzhiyun strstr(file_system, "LABEL=") + strlen("LABEL="));
133*4882a593Smuzhiyun else
134*4882a593Smuzhiyun strcpy(device, file_system);
135*4882a593Smuzhiyun
136*4882a593Smuzhiyun if (i == 6) {
137*4882a593Smuzhiyun while (num_volumes >= alloc) {
138*4882a593Smuzhiyun alloc *= 2;
139*4882a593Smuzhiyun device_volumes = realloc(device_volumes, alloc * sizeof(Volume));
140*4882a593Smuzhiyun }
141*4882a593Smuzhiyun device_volumes[num_volumes].mount_point = strdup(mount_point);
142*4882a593Smuzhiyun device_volumes[num_volumes].fs_type = strdup(fs_type);
143*4882a593Smuzhiyun device_volumes[num_volumes].option = strdup(option);
144*4882a593Smuzhiyun device_volumes[num_volumes].dump = strdup(dump);
145*4882a593Smuzhiyun device_volumes[num_volumes].pass = strdup(pass);
146*4882a593Smuzhiyun device_volumes[num_volumes].device = strdup(device);;
147*4882a593Smuzhiyun device_volumes[num_volumes].device2 = NULL;
148*4882a593Smuzhiyun ++num_volumes;
149*4882a593Smuzhiyun } else {
150*4882a593Smuzhiyun LOGE("skipping malformed recovery.fstab line: %s\n", buffer);
151*4882a593Smuzhiyun }
152*4882a593Smuzhiyun }
153*4882a593Smuzhiyun
154*4882a593Smuzhiyun fclose(fstab);
155*4882a593Smuzhiyun
156*4882a593Smuzhiyun printf("recovery filesystem table\n");
157*4882a593Smuzhiyun printf("=========================\n");
158*4882a593Smuzhiyun for (i = 0; i < num_volumes; ++i) {
159*4882a593Smuzhiyun Volume* v = &device_volumes[i];
160*4882a593Smuzhiyun printf(" %d %s %s %s %s %s %s\n", i, v->device, v->mount_point, v->fs_type, v->option, v->dump, v->pass);
161*4882a593Smuzhiyun }
162*4882a593Smuzhiyun printf("\n");
163*4882a593Smuzhiyun }
164*4882a593Smuzhiyun
volume_for_path(const char * path)165*4882a593Smuzhiyun Volume* volume_for_path(const char* path)
166*4882a593Smuzhiyun {
167*4882a593Smuzhiyun int i;
168*4882a593Smuzhiyun
169*4882a593Smuzhiyun memset(mount_point, 0, sizeof(mount_point));
170*4882a593Smuzhiyun char* tmp = get_link_path(path, mount_point, 1024);
171*4882a593Smuzhiyun
172*4882a593Smuzhiyun // if ( tmp != NULL)
173*4882a593Smuzhiyun // printf(" ### get mount_ponit = %s ### \n", mount_point);
174*4882a593Smuzhiyun
175*4882a593Smuzhiyun for (i = 0; i < num_volumes; ++i) {
176*4882a593Smuzhiyun Volume* v = device_volumes + i;
177*4882a593Smuzhiyun int len = strlen(v->mount_point);
178*4882a593Smuzhiyun if (strncmp(path, v->mount_point, len) == 0 &&
179*4882a593Smuzhiyun (path[len] == '\0' || path[len] == '/')) {
180*4882a593Smuzhiyun //printf(" ===path = %s, v-mount_point = %s ===\n",path, v->mount_point);
181*4882a593Smuzhiyun return v;
182*4882a593Smuzhiyun } else {
183*4882a593Smuzhiyun //add by chad.ma for symbol link file. eg. sdcard/ --->mnt/sdcard
184*4882a593Smuzhiyun if (!tmp)
185*4882a593Smuzhiyun continue;
186*4882a593Smuzhiyun
187*4882a593Smuzhiyun //printf(" # v->mount_point = %s\n", v->mount_point);
188*4882a593Smuzhiyun if (strncmp(mount_point, v->mount_point, len) == 0 &&
189*4882a593Smuzhiyun (path[len] == '\0' || path[len] == '/')) {
190*4882a593Smuzhiyun return v;
191*4882a593Smuzhiyun }
192*4882a593Smuzhiyun }
193*4882a593Smuzhiyun }
194*4882a593Smuzhiyun return NULL;
195*4882a593Smuzhiyun }
196*4882a593Smuzhiyun
ensure_path_mounted(const char * path)197*4882a593Smuzhiyun int ensure_path_mounted(const char* path)
198*4882a593Smuzhiyun {
199*4882a593Smuzhiyun if (access(path, F_OK) == 0)
200*4882a593Smuzhiyun return 0;
201*4882a593Smuzhiyun
202*4882a593Smuzhiyun Volume* v = volume_for_path(path);
203*4882a593Smuzhiyun if (v == NULL) {
204*4882a593Smuzhiyun if (mount_point[0] != 0) {
205*4882a593Smuzhiyun int result = scan_mounted_volumes();
206*4882a593Smuzhiyun if (result < 0) {
207*4882a593Smuzhiyun LOGE("failed to scan mounted volumes\n");
208*4882a593Smuzhiyun return -1;
209*4882a593Smuzhiyun }
210*4882a593Smuzhiyun
211*4882a593Smuzhiyun const MountedVolume* mv =
212*4882a593Smuzhiyun find_mounted_volume_by_mount_point(mount_point);
213*4882a593Smuzhiyun if (mv) {
214*4882a593Smuzhiyun // volume is already mounted
215*4882a593Smuzhiyun LOGI("%s already mounted \n", path);
216*4882a593Smuzhiyun return 0;
217*4882a593Smuzhiyun }
218*4882a593Smuzhiyun }
219*4882a593Smuzhiyun
220*4882a593Smuzhiyun LOGE("unknown volume for path [%s]\n", path);
221*4882a593Smuzhiyun return -1;
222*4882a593Smuzhiyun }
223*4882a593Smuzhiyun if (strcmp(v->fs_type, "ramdisk") == 0) {
224*4882a593Smuzhiyun // the ramdisk is always mounted.
225*4882a593Smuzhiyun return 0;
226*4882a593Smuzhiyun }
227*4882a593Smuzhiyun
228*4882a593Smuzhiyun int result;
229*4882a593Smuzhiyun result = scan_mounted_volumes();
230*4882a593Smuzhiyun if (result < 0) {
231*4882a593Smuzhiyun LOGE("failed to scan mounted volumes\n");
232*4882a593Smuzhiyun return -1;
233*4882a593Smuzhiyun }
234*4882a593Smuzhiyun
235*4882a593Smuzhiyun const MountedVolume* mv =
236*4882a593Smuzhiyun find_mounted_volume_by_mount_point(v->mount_point);
237*4882a593Smuzhiyun if (mv) {
238*4882a593Smuzhiyun // volume is already mounted
239*4882a593Smuzhiyun return 0;
240*4882a593Smuzhiyun }
241*4882a593Smuzhiyun
242*4882a593Smuzhiyun mkdir(v->mount_point, 0755); // in case it doesn't already exist
243*4882a593Smuzhiyun
244*4882a593Smuzhiyun if (strcmp(v->fs_type, "yaffs2") == 0) {
245*4882a593Smuzhiyun // mount an MTD partition as a YAFFS2 filesystem.
246*4882a593Smuzhiyun mtd_scan_partitions();
247*4882a593Smuzhiyun const MtdPartition* partition;
248*4882a593Smuzhiyun partition = mtd_find_partition_by_name(v->device);
249*4882a593Smuzhiyun if (partition == NULL) {
250*4882a593Smuzhiyun LOGE("failed to find \"%s\" partition to mount at \"%s\"\n",
251*4882a593Smuzhiyun v->device, v->mount_point);
252*4882a593Smuzhiyun return -1;
253*4882a593Smuzhiyun }
254*4882a593Smuzhiyun return mtd_mount_partition(partition, v->mount_point, v->fs_type, 0);
255*4882a593Smuzhiyun } else if (strcmp(v->fs_type, "ext4") == 0 ||
256*4882a593Smuzhiyun strcmp(v->fs_type, "vfat") == 0 ||
257*4882a593Smuzhiyun strcmp(v->fs_type, "ext2") == 0) {
258*4882a593Smuzhiyun char *blk_device;
259*4882a593Smuzhiyun blk_device = (char*)v->device;
260*4882a593Smuzhiyun if (strcmp("/mnt/sdcard", v->mount_point) == 0) {
261*4882a593Smuzhiyun blk_device = getenv(SD_POINT_NAME);
262*4882a593Smuzhiyun if (blk_device == NULL) {
263*4882a593Smuzhiyun setFlashPoint();
264*4882a593Smuzhiyun blk_device = getenv(SD_POINT_NAME);
265*4882a593Smuzhiyun }
266*4882a593Smuzhiyun result = mount(blk_device, v->mount_point, v->fs_type,
267*4882a593Smuzhiyun MS_NOATIME | MS_NODEV | MS_NODIRATIME, "");
268*4882a593Smuzhiyun if (result == 0) return 0;
269*4882a593Smuzhiyun }
270*4882a593Smuzhiyun result = mount(v->device, v->mount_point, v->fs_type,
271*4882a593Smuzhiyun MS_NOATIME | MS_NODEV | MS_NODIRATIME, "");
272*4882a593Smuzhiyun if (result == 0) return 0;
273*4882a593Smuzhiyun
274*4882a593Smuzhiyun if (v->device2) {
275*4882a593Smuzhiyun LOGW("failed to mount %s (%s); trying %s\n",
276*4882a593Smuzhiyun v->device, strerror(errno), v->device2);
277*4882a593Smuzhiyun result = mount(v->device2, v->mount_point, v->fs_type,
278*4882a593Smuzhiyun MS_NOATIME | MS_NODEV | MS_NODIRATIME, "");
279*4882a593Smuzhiyun if (result == 0) return 0;
280*4882a593Smuzhiyun }
281*4882a593Smuzhiyun LOGE("failed to mount %s (%s)\n", v->mount_point, strerror(errno));
282*4882a593Smuzhiyun return -1;
283*4882a593Smuzhiyun }
284*4882a593Smuzhiyun
285*4882a593Smuzhiyun LOGE("unknown fs_type \"%s\" for %s\n", v->fs_type, v->mount_point);
286*4882a593Smuzhiyun return -1;
287*4882a593Smuzhiyun }
288*4882a593Smuzhiyun
ensure_ex_path_unmounted(const char * path)289*4882a593Smuzhiyun int ensure_ex_path_unmounted(const char* path)
290*4882a593Smuzhiyun {
291*4882a593Smuzhiyun int result;
292*4882a593Smuzhiyun
293*4882a593Smuzhiyun result = scan_mounted_volumes();
294*4882a593Smuzhiyun if (result < 0) {
295*4882a593Smuzhiyun LOGE("unknown volume for path [%s]\n", path);
296*4882a593Smuzhiyun return -1;
297*4882a593Smuzhiyun }
298*4882a593Smuzhiyun
299*4882a593Smuzhiyun const MountedVolume* mv =
300*4882a593Smuzhiyun find_mounted_volume_by_mount_point(path);
301*4882a593Smuzhiyun if (mv == NULL) {
302*4882a593Smuzhiyun LOGE("path: %s is already unmounted or not existed\n");
303*4882a593Smuzhiyun return 0;
304*4882a593Smuzhiyun }
305*4882a593Smuzhiyun
306*4882a593Smuzhiyun return unmount_mounted_volume(mv);
307*4882a593Smuzhiyun }
308*4882a593Smuzhiyun
ensure_path_unmounted(const char * path)309*4882a593Smuzhiyun int ensure_path_unmounted(const char* path)
310*4882a593Smuzhiyun {
311*4882a593Smuzhiyun Volume* v = volume_for_path(path);
312*4882a593Smuzhiyun if (v == NULL) {
313*4882a593Smuzhiyun LOGE("unknown volume for path [%s]\n", path);
314*4882a593Smuzhiyun return -1;
315*4882a593Smuzhiyun }
316*4882a593Smuzhiyun if (strcmp(v->fs_type, "ramdisk") == 0) {
317*4882a593Smuzhiyun // the ramdisk is always mounted; you can't unmount it.
318*4882a593Smuzhiyun return -1;
319*4882a593Smuzhiyun }
320*4882a593Smuzhiyun
321*4882a593Smuzhiyun int result;
322*4882a593Smuzhiyun result = scan_mounted_volumes();
323*4882a593Smuzhiyun if (result < 0) {
324*4882a593Smuzhiyun LOGE("failed to scan mounted volumes\n");
325*4882a593Smuzhiyun return -1;
326*4882a593Smuzhiyun }
327*4882a593Smuzhiyun
328*4882a593Smuzhiyun const MountedVolume* mv =
329*4882a593Smuzhiyun find_mounted_volume_by_mount_point(v->mount_point);
330*4882a593Smuzhiyun if (mv == NULL) {
331*4882a593Smuzhiyun // volume is already unmounted
332*4882a593Smuzhiyun return 0;
333*4882a593Smuzhiyun }
334*4882a593Smuzhiyun
335*4882a593Smuzhiyun return unmount_mounted_volume(mv);
336*4882a593Smuzhiyun }
337*4882a593Smuzhiyun
format_volume(const char * volume)338*4882a593Smuzhiyun int format_volume(const char* volume)
339*4882a593Smuzhiyun {
340*4882a593Smuzhiyun Volume* v = volume_for_path(volume);
341*4882a593Smuzhiyun const char *label;
342*4882a593Smuzhiyun
343*4882a593Smuzhiyun if (v == NULL) {
344*4882a593Smuzhiyun LOGE("unknown volume \"%s\"\n", volume);
345*4882a593Smuzhiyun return -1;
346*4882a593Smuzhiyun }
347*4882a593Smuzhiyun if (strcmp(v->fs_type, "ramdisk") == 0) {
348*4882a593Smuzhiyun // you can't format the ramdisk.
349*4882a593Smuzhiyun LOGE("can't format_volume \"%s\"", volume);
350*4882a593Smuzhiyun return -1;
351*4882a593Smuzhiyun }
352*4882a593Smuzhiyun if (strcmp(v->mount_point, volume) != 0) {
353*4882a593Smuzhiyun LOGE("can't give path \"%s\" to format_volume\n", volume);
354*4882a593Smuzhiyun return -1;
355*4882a593Smuzhiyun }
356*4882a593Smuzhiyun
357*4882a593Smuzhiyun if (ensure_path_unmounted(volume) != 0) {
358*4882a593Smuzhiyun LOGE("format_volume failed to unmount \"%s\"\n", v->mount_point);
359*4882a593Smuzhiyun return -1;
360*4882a593Smuzhiyun }
361*4882a593Smuzhiyun
362*4882a593Smuzhiyun label = VOLUME_TO_LABEL(v);
363*4882a593Smuzhiyun
364*4882a593Smuzhiyun if (strcmp(v->fs_type, "yaffs2") == 0 || strcmp(v->fs_type, "mtd") == 0 || strcmp(v->fs_type, "ubifs") == 0 ) {
365*4882a593Smuzhiyun mtd_scan_partitions();
366*4882a593Smuzhiyun char filepath[20];
367*4882a593Smuzhiyun if (strstr(v->device, "userdata") != NULL) {
368*4882a593Smuzhiyun strcpy(filepath, "userdata");
369*4882a593Smuzhiyun LOGW("change v->device from %s to %s.\n", v->device, filepath);
370*4882a593Smuzhiyun } else {
371*4882a593Smuzhiyun strcpy(filepath, v->device);
372*4882a593Smuzhiyun }
373*4882a593Smuzhiyun
374*4882a593Smuzhiyun const MtdPartition* partition = mtd_find_partition_by_name(filepath);
375*4882a593Smuzhiyun if (partition == NULL) {
376*4882a593Smuzhiyun LOGE("format_volume: no MTD partition \"%s\"\n", v->device);
377*4882a593Smuzhiyun return -1;
378*4882a593Smuzhiyun }
379*4882a593Smuzhiyun
380*4882a593Smuzhiyun MtdWriteContext *write = mtd_write_partition(partition);
381*4882a593Smuzhiyun if (write == NULL) {
382*4882a593Smuzhiyun LOGW("format_volume: can't open MTD \"%s\"\n", v->device);
383*4882a593Smuzhiyun return -1;
384*4882a593Smuzhiyun } else if (mtd_erase_blocks(write, -1) == (off_t) -1) {
385*4882a593Smuzhiyun LOGW("format_volume: can't erase MTD \"%s\"\n", v->device);
386*4882a593Smuzhiyun mtd_write_close(write);
387*4882a593Smuzhiyun return -1;
388*4882a593Smuzhiyun } else if (mtd_write_close(write)) {
389*4882a593Smuzhiyun LOGW("format_volume: can't close MTD \"%s\"\n", v->device);
390*4882a593Smuzhiyun return -1;
391*4882a593Smuzhiyun }
392*4882a593Smuzhiyun return 0;
393*4882a593Smuzhiyun }
394*4882a593Smuzhiyun
395*4882a593Smuzhiyun if (strcmp(v->fs_type, "ext4") == 0) {
396*4882a593Smuzhiyun int result = make_ext4(v->device, label);
397*4882a593Smuzhiyun if (result != 0) {
398*4882a593Smuzhiyun LOGE("format_volume: make_extf4 failed on %s\n", v->device);
399*4882a593Smuzhiyun return -1;
400*4882a593Smuzhiyun }
401*4882a593Smuzhiyun return 0;
402*4882a593Smuzhiyun }
403*4882a593Smuzhiyun
404*4882a593Smuzhiyun if (strcmp(v->fs_type, "ext2") == 0) {
405*4882a593Smuzhiyun int result = make_ext2(v->device, label);
406*4882a593Smuzhiyun if (result != 0) {
407*4882a593Smuzhiyun LOGE("format_volume: make_extf2 failed on %s\n", v->device);
408*4882a593Smuzhiyun return -1;
409*4882a593Smuzhiyun }
410*4882a593Smuzhiyun return 0;
411*4882a593Smuzhiyun }
412*4882a593Smuzhiyun if (strcmp(v->fs_type, "vfat") == 0) {
413*4882a593Smuzhiyun int result = make_vfat(v->device, label);
414*4882a593Smuzhiyun if (result != 0) {
415*4882a593Smuzhiyun LOGE("format_volume: make_vfat failed on %s\n", v->device);
416*4882a593Smuzhiyun return -1;
417*4882a593Smuzhiyun }
418*4882a593Smuzhiyun return 0;
419*4882a593Smuzhiyun }
420*4882a593Smuzhiyun
421*4882a593Smuzhiyun if (strcmp(v->fs_type, "ntfs") == 0) {
422*4882a593Smuzhiyun int result = make_ntfs(v->device, label);
423*4882a593Smuzhiyun if (result != 0) {
424*4882a593Smuzhiyun LOGE("format_volume: make_ntfs failed on %s\n", v->device);
425*4882a593Smuzhiyun return -1;
426*4882a593Smuzhiyun }
427*4882a593Smuzhiyun return 0;
428*4882a593Smuzhiyun }
429*4882a593Smuzhiyun
430*4882a593Smuzhiyun LOGE("format_volume: fs_type \"%s\" unsupported\n", v->fs_type);
431*4882a593Smuzhiyun return -1;
432*4882a593Smuzhiyun }
433*4882a593Smuzhiyun
resize_volume(const char * volume)434*4882a593Smuzhiyun int resize_volume(const char* volume)
435*4882a593Smuzhiyun {
436*4882a593Smuzhiyun Volume* v = volume_for_path(volume);
437*4882a593Smuzhiyun if (v == NULL) {
438*4882a593Smuzhiyun LOGE("unknown volume \"%s\"\n", volume);
439*4882a593Smuzhiyun return -1;
440*4882a593Smuzhiyun }
441*4882a593Smuzhiyun if (strcmp(v->fs_type, "ramdisk") == 0) {
442*4882a593Smuzhiyun // you can't format the ramdisk.
443*4882a593Smuzhiyun LOGE("can't format_volume \"%s\"", volume);
444*4882a593Smuzhiyun return -1;
445*4882a593Smuzhiyun }
446*4882a593Smuzhiyun if (strcmp(v->mount_point, volume) != 0) {
447*4882a593Smuzhiyun LOGE("can't give path \"%s\" to format_volume\n", volume);
448*4882a593Smuzhiyun return -1;
449*4882a593Smuzhiyun }
450*4882a593Smuzhiyun
451*4882a593Smuzhiyun if (ensure_path_unmounted(volume) != 0) {
452*4882a593Smuzhiyun LOGE("format_volume failed to unmount \"%s\"\n", v->mount_point);
453*4882a593Smuzhiyun return -1;
454*4882a593Smuzhiyun }
455*4882a593Smuzhiyun
456*4882a593Smuzhiyun if ((strcmp(v->fs_type, "ext4") == 0) || (strcmp(v->fs_type, "ext2") == 0)) {
457*4882a593Smuzhiyun int result = rk_check_and_resizefs(v->device);
458*4882a593Smuzhiyun if (result != 0) {
459*4882a593Smuzhiyun LOGE("resize_volume: resizefs failed on %s\n", v->device);
460*4882a593Smuzhiyun return -1;
461*4882a593Smuzhiyun }
462*4882a593Smuzhiyun return 0;
463*4882a593Smuzhiyun }
464*4882a593Smuzhiyun
465*4882a593Smuzhiyun LOGE("format_volume: fs_type \"%s\" unsupported\n", v->fs_type);
466*4882a593Smuzhiyun return -1;
467*4882a593Smuzhiyun }
468*4882a593Smuzhiyun
469