int ubi_format(const char *mount_point) { //Detach UBI volume before formating printf("It's in ubi_format!!\n"); const char* partition_name; char mtd_dev_name[20]; const MtdPartition *partition; int32_t mtd_num; int32_t ubi_num = -1; if (!strcmp(mount_point, "/system")) { ubi_num = 0; partition_name = "system"; } if (!strcmp(mount_point, "/data")) { ubi_num = 1; partition_name = "userdata"; } if (!strcmp(mount_point, "/cache") || !strcmp(mount_point, "/.cache")) { ubi_num = 2; partition_name = "cache"; } if (ubi_num != -1) { ubi_detach_dev(ubi_num); printf("Back to ubi_format!!\n"); } else { printf("Can not find a ubi device![%s], error:%s\n", mount_point, strerror(errno)); return -1; } //Run-time get mtd_dev_name mtd_scan_partitions(); partition = mtd_find_partition_by_name(partition_name); if (partition == NULL) { LOGE("failed to find \"%s\" partition to mount at \"%s\"\n", partition_name,mount_point); return -1; } mtd_num = mtd_part_to_number(partition); printf("mtd_num = %d\n", mtd_num); sprintf(mtd_dev_name, "/dev/mtd/mtd%d", mtd_num); printf("Formatting %s -> %s\n", mount_point, mtd_dev_name); const char* binary_path = "/sbin/ubiformat"; const char* skip_questions = "-y"; int check; check = chmod(binary_path, 0777); printf("chmod = %d\n", check); const char** args = (const char**)malloc(sizeof(char*) * 4); args[0] = binary_path; args[1] = (const char *)mtd_dev_name; args[2] = skip_questions; args[3] = NULL; pid_t pid = fork(); if (pid == 0) { execv(binary_path, (char* const*)args); fprintf(stdout, "E:Can't run %s (%s)\n", binary_path, strerror(errno)); _exit(-1); } int status; waitpid(pid, &status, 0); if (!WIFEXITED(status) || WEXITSTATUS(status) != 0) { LOGE("Error in ubiformat\n(Status %d)\n", WEXITSTATUS(status)); return -1; } //Attatch UBI device & Make UBI volume int n = -1; n = ubi_attach_mtd_user(mount_point); if ((n != -1) && (n < 4)) { printf("Try to attatch /dev/ubi%d_0... volume is attached \n", n); } else { LOGE("failed to attach /dev/ubi%d_0%s\n", n); return -1; } return 0; }
int format_root_device(const char *root) { /* See if this root is already mounted. */ const MountedVolume *volume; char *filesystem; char *device; int ret = scan_mounted_volumes(); if (ret < 0) { LOGD(TAG "format_root_device: load mount info fail\n", root); return false; } volume = find_mounted_volume_by_mount_point(root); if (volume == NULL) { LOGD(TAG "The path %s is unmounted\n", root); return 0; } filesystem = strdup(volume->filesystem); device = strdup(volume->device); ret = unmount_mounted_volume(volume); if (ret < 0) { LOGD(TAG "format_root_device: can't unmount \"%s\"\n", root); return false; } LOGD(TAG "format_root_device : unmount %s scucess, type is %s\n", root, filesystem); if (!strcmp(filesystem, "yaffs2")) { LOGD(TAG "format yaffs2 partitions\n", root); /* Format the device. */ mtd_scan_partitions(); const MtdPartition *partition = NULL; if(!strcmp(root, DATA_PARTITION)) { LOGD(TAG "find the partition name is %s", root); partition = mtd_find_partition_by_name("userdata"); } if (partition == NULL) { LOGD(TAG "format_root_device: can't find mtd partition \"%s\"\n", root); return false; } MtdWriteContext *write = mtd_write_partition(partition); if (write == NULL) { LOGD(TAG "format_root_device: can't open \"%s\"\n", root); return false; } else if (mtd_erase_blocks(write, -1) == (off_t) - 1) { LOGD(TAG "format_root_device: can't erase \"%s\"\n", root); mtd_write_close(write); return false; } else if (mtd_write_close(write)) { LOGD(TAG "format_root_device: can't close \"%s\"\n", root); return false; } else { ret= true; } } else { if (!strcmp(filesystem, "ubifs")) { int ubi_num = -1, ubi_dev; int mtd_num = -1; char path[128]; char mtd_dev_name[128]; const char *binary_path = "/system/bin/ubiformat"; sscanf(device, "/dev/ubi%d_0", &ubi_num); if (ubi_num >= 0 && ubi_num <= 32) { LOGD(TAG "format_root_device: detach ubi device /dev/ubi%d_0\n", ubi_num); } else { LOGD(TAG "Can not find parse ubi num :%s\n", device); return false; } sprintf(path, "/sys/class/ubi/ubi%d/mtd_num", ubi_num); ubi_dev = open(path, O_RDONLY); if (ubi_dev != -1) { ret = read(ubi_dev, path, sizeof(path)); close(ubi_dev); if (ret > 0) { mtd_num = atoi(path); LOGD(TAG " %s mtd_num is %d \n", device, mtd_num); sprintf(mtd_dev_name, "/dev/mtd/mtd%d", mtd_num); } else { LOGD(TAG " read %s fail! \n", path); return false; } } else { LOGD(TAG " open %s fail! \n", path); return false; } ret = ubi_detach_dev(ubi_num); if (ret != 0) { LOGD(TAG "format_root_device: detach ubi device /dev/ubi%d_0 fail!ret=%d\n", ubi_num, ret); return false; } //int check; //check = chmod(binary_path, 0777); //printf("chmod = %d\n", check); const char **args = (const char **)malloc(sizeof(char *) * 3); args[0] = binary_path; args[1] = mtd_dev_name; args[2] = NULL; pid_t pid = fork(); if (pid == 0) { execv(binary_path, (char *const *)args); fprintf(stdout, "E:Can't run %s (%s)\n", binary_path, strerror(errno)); _exit(-1); } int status; waitpid(pid, &status, 0); if (!WIFEXITED(status) || WEXITSTATUS(status) != 0) { LOGE("Error in ubiformat\n(Status %d)\n", WEXITSTATUS(status)); return false; } ret=true; } else { LOGD(TAG "format_root_device : unsupport filesystem %s\n", filesystem); return false; } } free(filesystem); free(device); return ret; }
int ensure_path_mounted(const char* path) { Volume* v = volume_for_path(path); if (v == NULL) { LOGE("unknown volume for path [%s]\n", path); return -1; } if (strcmp(v->fs_type, "ramdisk") == 0) { // the ramdisk is always mounted. return 0; } int result; result = scan_mounted_volumes(); if (result < 0) { LOGE("failed to scan mounted volumes\n"); return -1; } const MountedVolume* mv = find_mounted_volume_by_mount_point(v->mount_point); if (mv) { #if defined(CACHE_MERGE_SUPPORT) if (strncmp(path, "/cache", 6) == 0) { if (symlink(DATA_CACHE_ROOT, "/cache")) { if (errno != EEXIST) { LOGE("create symlink from %s to %s failed(%s)\n", DATA_CACHE_ROOT, "/cache", strerror(errno)); return -1; } } } #endif // volume is already mounted return 0; } mkdir(v->mount_point, 0755); // in case it doesn't already exist #if defined (UBIFS_SUPPORT) if (strcmp(v->fs_type, "ubifs") == 0) { printf("Trying to mount %s \n", v->mount_point); //Attatch UBI device & Make UBI volum int n = -1; n = ubi_attach_mtd_user(v->mount_point); if ((n != -1) && (n < 4)) { printf("Try to attatch %s \n", v->blk_device); printf("/dev/ubi%d_0 is attached \n", n); } else { LOGE("failed to attach %s\n", v->blk_device); } //Mount UBI volume const unsigned long flags = MS_NOATIME | MS_NODEV | MS_NODIRATIME; char tmp[64]; sprintf(tmp, "/dev/ubi%d_0", n); wait_for_file(tmp, 5); result = mount(tmp, v->mount_point, v->fs_type, flags, ""); if (result < 0) { ubi_detach_dev(n); return -1; } else if (result == 0) { goto mount_done; //Volume successfully mounted } } #endif if (strcmp(v->fs_type, "yaffs2") == 0) { // mount an MTD partition as a YAFFS2 filesystem. mtd_scan_partitions(); const MtdPartition* partition; partition = mtd_find_partition_by_name(v->blk_device); if (partition == NULL) { LOGE("failed to find \"%s\" partition to mount at \"%s\"\n", v->blk_device, v->mount_point); return -1; } return mtd_mount_partition(partition, v->mount_point, v->fs_type, 0); } else if (strcmp(v->fs_type, "ext4") == 0 || strcmp(v->fs_type, "squashfs") == 0 || strcmp(v->fs_type, "vfat") == 0) { mt_ensure_dev_ready(v->mount_point); result = mount(v->blk_device, v->mount_point, v->fs_type, v->flags, v->fs_options); if (result == 0) { goto mount_done; } else { result = mt_ensure_path_mounted(v); if (result == 0) goto mount_done; } LOGE("failed to mount %s (%s)\n", v->mount_point, strerror(errno)); return -1; } LOGE("unknown fs_type \"%s\" for %s\n", v->fs_type, v->mount_point); return -1; mount_done: #if defined(CACHE_MERGE_SUPPORT) if (strcmp(v->mount_point, "/data") == 0) { if (mkdir(DATA_CACHE_ROOT, 0770)) { if (errno != EEXIST) { LOGE("mkdir %s error: %s\n", DATA_CACHE_ROOT, strerror(errno)); return -1; } else if (need_clear_cache) { LOGI("cache exists, clear it...\n"); if (remove_dir(DATA_CACHE_ROOT)) { LOGE("remove_dir %s error: %s\n", DATA_CACHE_ROOT, strerror(errno)); return -1; } if (mkdir(DATA_CACHE_ROOT, 0770) != 0) { LOGE("mkdir %s error: %s\n", DATA_CACHE_ROOT, strerror(errno)); return -1; } } } if (symlink(DATA_CACHE_ROOT, "/cache")) { if (errno != EEXIST) { LOGE("create symlink from %s to %s failed(%s)\n", DATA_CACHE_ROOT, "/cache", strerror(errno)); return -1; } } need_clear_cache = 0; } #endif return 0; }