int nandroid_restore_datamedia(const char* backup_path) { char tmp[PATH_MAX]; ui_print("\n>> Restoring /data/media...\n"); if (is_data_media_volume_path(backup_path)) { // non fatal failure LOGE(" - can't restore folder to its self, skipping...\n"); return 0; } Volume *v = volume_for_path("/data"); if (v == NULL) return -1; sprintf(tmp, "%s/%s", get_primary_storage_path(), NANDROID_HIDE_PROGRESS_FILE); ensure_path_mounted(tmp); int callback = !file_found(tmp); struct stat s; char backup_file_image[PATH_MAX]; const char *filesystems[] = { "yaffs2", "ext2", "ext3", "ext4", "vfat", "exfat", "rfs", "f2fs", "auto", NULL }; const char *filesystem; int i = 0; nandroid_restore_handler restore_handler = NULL; while ((filesystem = filesystems[i]) != NULL) { sprintf(backup_file_image, "%s/datamedia.%s.tar", backup_path, filesystem); if (0 == stat(backup_file_image, &s)) { restore_handler = tar_extract_wrapper; sprintf(tmp, "cd / ; set -o pipefail ; cat %s* | tar -xpv ; exit $?", backup_file_image); break; } sprintf(backup_file_image, "%s/datamedia.%s.tar.gz", backup_path, filesystem); if (0 == stat(backup_file_image, &s)) { restore_handler = tar_gzip_extract_wrapper; sprintf(tmp, "cd / ; set -o pipefail ; cat %s* | pigz -d -c | tar -xpv ; exit $?", backup_file_image); break; } i++; } if (filesystem == NULL || restore_handler == NULL) { LOGE("No backup found, skipping...\n"); return 0; } if (0 != format_unknown_device(NULL, "/data/media", NULL)) return print_and_error("Error while erasing /data/media\n", NANDROID_ERROR_GENERAL); // data can be unmounted by format_unknown_device() if (0 != ensure_path_mounted("/data")) return -1; if (0 != do_tar_extract(tmp, backup_file_image, "/data", callback)) return print_and_error("Failed to restore /data/media!\n", NANDROID_ERROR_GENERAL); ui_print("Restore of /data/media completed.\n"); return 0; }
int device_truedualboot_format_volume(const char* volume) { if(strcmp(volume, "/data") != 0) return 1; if(is_force_raw_format_enabled() || !dualboot_is_tdb_enabled()) return 1; int rc = format_unknown_device(NULL, volume, NULL); return rc>0?-rc:rc; }
int format_device(const char *device, const char *path, const char *fs_type) { Volume* v = volume_for_path(path); if (v == NULL) { // silent failure for sd-ext if (strcmp(path, "/sd-ext") == 0) return -1; LOGE("unknown volume \"%s\"\n", path); return -1; } if (is_data_media_volume_path(path)) { return format_unknown_device(NULL, path, NULL); } if (strstr(path, "/data") == path && is_data_media()) { return format_unknown_device(NULL, path, NULL); } if (strcmp(fs_type, "ramdisk") == 0) { // you can't format the ramdisk. LOGE("can't format_volume \"%s\"", path); return -1; } if (strcmp(fs_type, "rfs") == 0) { if (ensure_path_unmounted(path) != 0) { LOGE("format_volume failed to unmount \"%s\"\n", v->mount_point); return -1; } if (0 != format_rfs_device(device, path)) { LOGE("format_volume: format_rfs_device failed on %s\n", device); return -1; } return 0; } if (strcmp(v->mount_point, path) != 0) { return format_unknown_device(v->device, path, NULL); } if (ensure_path_unmounted(path) != 0) { LOGE("format_volume failed to unmount \"%s\"\n", v->mount_point); return -1; } if (strcmp(fs_type, "yaffs2") == 0 || strcmp(fs_type, "mtd") == 0) { mtd_scan_partitions(); const MtdPartition* partition = mtd_find_partition_by_name(device); if (partition == NULL) { LOGE("format_volume: no MTD partition \"%s\"\n", device); return -1; } MtdWriteContext *write = mtd_write_partition(partition); if (write == NULL) { LOGW("format_volume: can't open MTD \"%s\"\n", device); return -1; } else if (mtd_erase_blocks(write, -1) == (off_t) -1) { LOGW("format_volume: can't erase MTD \"%s\"\n", device); mtd_write_close(write); return -1; } else if (mtd_write_close(write)) { LOGW("format_volume: can't close MTD \"%s\"\n",device); return -1; } return 0; } if (strcmp(fs_type, "ext4") == 0) { int length = 0; if (strcmp(v->fs_type, "ext4") == 0) { // Our desired filesystem matches the one in fstab, respect v->length length = v->length; } reset_ext4fs_info(); int result = make_ext4fs(device, length, v->mount_point, sehandle); if (result != 0) { LOGE("format_volume: make_extf4fs failed on %s\n", device); return -1; } return 0; } return format_unknown_device(device, path, fs_type); }
int format_volume(const char* volume) { Volume* v = volume_for_path(volume); if (v == NULL) { // no /sdcard? let's assume /data/media if (strstr(volume, "/sdcard") == volume && is_data_media()) { return format_unknown_device(NULL, volume, NULL); } // silent failure for sd-ext if (strcmp(volume, "/sd-ext") == 0) return -1; LOGE("unknown volume \"%s\"\n", volume); return -1; } if (strcmp(v->fs_type, "ramdisk") == 0) { // you can't format the ramdisk. LOGE("can't format_volume \"%s\"", volume); return -1; } if (strcmp(v->mount_point, volume) != 0) { #if 0 LOGE("can't give path \"%s\" to format_volume\n", volume); return -1; #endif return format_unknown_device(v->device, volume, NULL); } if (ensure_path_unmounted(volume) != 0) { LOGE("format_volume failed to unmount \"%s\"\n", v->mount_point); return -1; } if (strcmp(v->fs_type, "yaffs2") == 0 || strcmp(v->fs_type, "mtd") == 0) { mtd_scan_partitions(); const MtdPartition* partition = mtd_find_partition_by_name(v->device); if (partition == NULL) { LOGE("format_volume: no MTD partition \"%s\"\n", v->device); return -1; } MtdWriteContext *write = mtd_write_partition(partition); // MtdWriteContext *write = mtd_write_partition(v->device); if (write == NULL) { LOGW("format_volume: can't open MTD \"%s\"\n", v->device); return -1; } else if (mtd_erase_blocks(write, -1) == (off_t) -1) { LOGW("format_volume: can't erase MTD \"%s\"\n", v->device); mtd_write_close(write); return -1; } else if (mtd_write_close(write)) { LOGW("format_volume: can't close MTD \"%s\"\n", v->device); return -1; } return 0; } if (strcmp(v->fs_type, "ext4") == 0) { reset_ext4fs_info(); int result = make_ext4fs(v->device, NULL, NULL, 0, 0, 0); if (result != 0) { LOGE("format_volume: make_extf4fs failed on %s\n", v->device); return -1; } return 0; } #if 0 LOGE("format_volume: fs_type \"%s\" unsupported\n", v->fs_type); return -1; #endif return format_unknown_device(v->device, volume, v->fs_type); }
void show_partition_menu() { static char* headers[] = { "Mounts and Storage Menu", "", NULL }; typedef char* string; string mounts[MOUNTABLE_COUNT][3] = { { "mount /system", "unmount /system", "SYSTEM:" }, { "mount /data", "unmount /data", "DATA:" }, { "mount /cache", "unmount /cache", "CACHE:" }, { "mount /sdcard", "unmount /sdcard", "SDCARD:" }, #ifdef BOARD_HAS_SDCARD_INTERNAL { "mount /emmc", "unmount /emmc", "SDINTERNAL:" }, #endif { "mount /sd-ext", "unmount /sd-ext", "SDEXT:" } }; string mtds[MTD_COUNT][2] = { { "format boot", "BOOT:" }, { "format system", "SYSTEM:" }, { "format data", "DATA:" }, { "format cache", "CACHE:" }, }; string mmcs[MMC_COUNT][3] = { { "format sdcard", "SDCARD:" }, #ifdef BOARD_HAS_SDCARD_INTERNAL { "format internal sdcard", "SDINTERNAL:" }, #endif { "format sd-ext", "SDEXT:" } }; static char* confirm_format = "Confirm format?"; static char* confirm = "Yes - Format"; for (;;) { int ismounted[MOUNTABLE_COUNT]; int i; static string options[MOUNTABLE_COUNT + MTD_COUNT + MMC_COUNT + 1 + 1]; // mountables, format mtds, format mmcs, usb storage, null for (i = 0; i < MOUNTABLE_COUNT; i++) { ismounted[i] = is_root_path_mounted(mounts[i][2]); options[i] = ismounted[i] ? mounts[i][1] : mounts[i][0]; } for (i = 0; i < MTD_COUNT; i++) { options[MOUNTABLE_COUNT + i] = mtds[i][0]; } for (i = 0; i < MMC_COUNT; i++) { options[MOUNTABLE_COUNT + MTD_COUNT + i] = mmcs[i][0]; } options[MOUNTABLE_COUNT + MTD_COUNT + MMC_COUNT] = "mount USB storage"; options[MOUNTABLE_COUNT + MTD_COUNT + MMC_COUNT + 1] = NULL; int chosen_item = get_menu_selection(headers, options, 0); if (chosen_item == GO_BACK) break; if (chosen_item == MOUNTABLE_COUNT + MTD_COUNT + MMC_COUNT) { show_mount_usb_storage_menu(); } else if (chosen_item < MOUNTABLE_COUNT) { if (ismounted[chosen_item]) { if (0 != ensure_root_path_unmounted(mounts[chosen_item][2])) ui_print("Error unmounting %s!\n", mounts[chosen_item][2]); } else { if (0 != ensure_root_path_mounted(mounts[chosen_item][2])) ui_print("Error mounting %s!\n", mounts[chosen_item][2]); } } else if (chosen_item < MOUNTABLE_COUNT + MTD_COUNT) { chosen_item = chosen_item - MOUNTABLE_COUNT; if (!confirm_selection(confirm_format, confirm)) continue; ui_print("Formatting %s...\n", mtds[chosen_item][1]); if (0 != format_root_device(mtds[chosen_item][1])) ui_print("Error formatting %s!\n", mtds[chosen_item][1]); else ui_print("Done.\n"); } else if (chosen_item < MOUNTABLE_COUNT + MTD_COUNT + MMC_COUNT) { chosen_item = chosen_item - MOUNTABLE_COUNT - MTD_COUNT; if (!confirm_selection(confirm_format, confirm)) continue; ui_print("Formatting %s...\n", mmcs[chosen_item][1]); if (0 != format_unknown_device(mmcs[chosen_item][1])) ui_print("Error formatting %s!\n", mmcs[chosen_item][1]); else ui_print("Done.\n"); } } }
int format_volume(const char* volume) { Volume* v = volume_for_path(volume); if (v == NULL) { // silent failure for sd-ext if (strcmp(volume, "/sd-ext") == 0) return -1; LOGE("unknown volume \"%s\"\n", volume); return -1; } if (is_data_media_volume_path(volume)) { return format_unknown_device(NULL, volume, NULL); } // check to see if /data is being formatted, and if it is /data/media // Note: the /sdcard check is redundant probably, just being safe. if (strstr(volume, "/data") == volume && is_data_media() && !handle_data_media) { return format_unknown_device(NULL, volume, NULL); } if (strcmp(v->fs_type, "ramdisk") == 0) { // you can't format the ramdisk. LOGE("can't format_volume \"%s\"", volume); return -1; } if (strcmp(v->mount_point, volume) != 0) { #if 0 LOGE("can't give path \"%s\" to format_volume\n", volume); return -1; #endif return format_unknown_device(v->device, volume, NULL); } if (ensure_path_unmounted(volume) != 0) { LOGE("format_volume failed to unmount \"%s\"\n", v->mount_point); return -1; } if (strcmp(v->fs_type, "yaffs2") == 0 || strcmp(v->fs_type, "mtd") == 0) { mtd_scan_partitions(); const MtdPartition* partition = mtd_find_partition_by_name(v->device); if (partition == NULL) { LOGE("format_volume: no MTD partition \"%s\"\n", v->device); return -1; } MtdWriteContext *write = mtd_write_partition(partition); if (write == NULL) { LOGW("format_volume: can't open MTD \"%s\"\n", v->device); return -1; } else if (mtd_erase_blocks(write, -1) == (off_t) -1) { LOGW("format_volume: can't erase MTD \"%s\"\n", v->device); mtd_write_close(write); return -1; } else if (mtd_write_close(write)) { LOGW("format_volume: can't close MTD \"%s\"\n", v->device); return -1; } return 0; } if (strcmp(v->fs_type, "ext4") == 0) { int result = make_ext4fs(v->device, v->length, volume, sehandle); if (result != 0) { LOGE("format_volume: make_extf4fs failed on %s\n", v->device); return -1; } return 0; } #if 0 LOGE("format_volume: fs_type \"%s\" unsupported\n", v->fs_type); return -1; #endif return format_unknown_device(v->device, volume, v->fs_type); }
void wipe_data(int confirm) { if (confirm) { static char** title_headers = NULL; if (title_headers == NULL) { char* headers[] = { "Confirm wipe of all user data?", " THIS CAN NOT BE UNDONE.", "", NULL }; title_headers = prepend_title((const char**)headers); } char* items[] = { " No", #if TARGET_BOOTLOADER_BOARD_NAME == otter " Yes -- delete all user data", // [1] #else " No", " No", " No", " No", " No", " No", " Yes -- delete all user data", // [7] " No", " No", " No", #endif NULL }; int chosen_item = get_menu_selection(title_headers, items, 1, 0); #if TARGET_BOOTLOADER_BOARD_NAME == otter if (chosen_item != 1) { #else if (chosen_itme != 7) { #endif return; } } ui_print("\n-- Wiping data...\n"); device_wipe_data(); erase_volume("/data"); erase_volume("/cache"); if (has_datadata()) { erase_volume("/datadata"); } #if TARGET_BOOTLOADER_BOARD_NAME != otter // ToDo: make this check for the partition rather then the device erase_volume("/sd-ext"); #endif erase_volume("/sdcard/.android_secure"); ui_print("%s\n", datawipecomplete); } void erase_cache(int orscallback) { if(orscallback) { if(orswipeprompt && !confirm_selection("Confirm wipe?","Yes - Wipe Cache")) { ui_print("Skipping cache wipe...\n"); return; } } else if (!confirm_selection("Confirm wipe?", "Yes - Wipe Cache")) { return; } ui_print("\n-- Wiping cache...\n"); erase_volume("/cache"); ui_print("%s\n", cachewipecomplete); if (!ui_text_visible()) return; } void erase_dalvik_cache(int orscallback) { if(orscallback) { if(orswipeprompt && !confirm_selection("Confirm wipe?", "Yes - Wipe Dalvik Cache")) { ui_print("Skipping dalvik cache wipe...\n"); return; } } else if (!confirm_selection( "Confirm wipe?", "Yes - Wipe Dalvik Cache")) { return; } if (0 != ensure_path_mounted("/data")) { return; } #if TARGET_BOOTLOADER_BOARD_NAME != otter ensure_path_mounted("/sd-ext"); #endif ensure_path_mounted("/cache"); __system("rm -r /data/dalvik-cache"); __system("rm -r /cache/dalvik-cache"); #if TARGET_BOOTLOADER_BOARD_NAME != otter __system("rm -r /sd-ext/dalvik-cache"); #endif ui_print("Dalvik Cache wiped.\n"); ensure_path_unmounted("/data"); } void wipe_all(int orscallback) { if(orscallback) { if(orswipeprompt && !confirm_selection("Confirm wipe all?", "Yes - Wipe All")) { ui_print("Skipping full wipe...\n"); return; } } else if (!confirm_selection("Confirm wipe all?", "Yes - Wipe All")) { return; } ui_print("\n-- Wiping system, data, cache...\n"); erase_volume("/system"); erase_volume("/data"); erase_volume("/cache"); ui_print("\nFull wipe complete!\n"); if (!ui_text_visible()) return; } int format_device(const char *device, const char *path, const char *fs_type) { Volume* v = volume_for_path(path); if (v == NULL) { // no /sdcard? let's assume /data/media if (strstr(path, "/sdcard") == path && is_data_media()) { return format_unknown_device(NULL, path, NULL); } // silent failure for sd-ext if (strcmp(path, "/sd-ext") == 0) return -1; LOGE("unknown volume \"%s\"\n", path); return -1; } if (strcmp(fs_type, "ramdisk") == 0) { // you can't format the ramdisk. LOGE("can't format_volume \"%s\"", path); return -1; } if (strcmp(fs_type, "rfs") == 0) { if (ensure_path_unmounted(path) != 0) { LOGE("format_volume failed to unmount \"%s\"\n", v->mount_point); return -1; } if (0 != format_rfs_device(device, path)) { LOGE("format_volume: format_rfs_device failed on %s\n", device); return -1; } return 0; } if (strcmp(v->mount_point, path) != 0) { return format_unknown_device(v->device, path, NULL); } if (ensure_path_unmounted(path) != 0) { LOGE("format_volume failed to unmount \"%s\"\n", v->mount_point); return -1; } if (strcmp(fs_type, "yaffs2") == 0 || strcmp(fs_type, "mtd") == 0) { mtd_scan_partitions(); const MtdPartition* partition = mtd_find_partition_by_name(device); if (partition == NULL) { LOGE("format_volume: no MTD partition \"%s\"\n", device); return -1; } MtdWriteContext *write = mtd_write_partition(partition); if (write == NULL) { LOGW("format_volume: can't open MTD \"%s\"\n", device); return -1; } else if (mtd_erase_blocks(write, -1) == (off_t) -1) { LOGW("format_volume: can't erase MTD \"%s\"\n", device); mtd_write_close(write); return -1; } else if (mtd_write_close(write)) { LOGW("format_volume: can't close MTD \"%s\"\n",device); return -1; } return 0; } if (strcmp(fs_type, "ext4") == 0) { int length = 0; if (strcmp(v->fs_type, "ext4") == 0) { // Our desired filesystem matches the one in fstab, respect v->length length = v->length; } reset_ext4fs_info(); int result = make_ext4fs(device, length, v->mount_point, sehandle); if (result != 0) { LOGE("format_volume: make_extf4fs failed on %s\n", device); return -1; } return 0; } return format_unknown_device(device, path, fs_type); }
int format_volume(const char* volume) { if (is_data_media_volume_path(volume)) { return format_unknown_device(NULL, volume, NULL); } // check to see if /data is being formatted, and if it is /data/media // Note: the /sdcard check is redundant probably, just being safe. if (strstr(volume, "/data") == volume && is_data_media() && !ignore_data_media) { return format_unknown_device(NULL, volume, NULL); } Volume* v = volume_for_path(volume); if (v == NULL) { // silent failure for sd-ext if (strcmp(volume, "/sd-ext") != 0) LOGE("unknown volume '%s'\n", volume); return -1; } // silent failure to format non existing sd-ext when defined in recovery.fstab if (strcmp(volume, "/sd-ext") == 0) { struct stat s; if (0 != stat(v->blk_device, &s)) { LOGI("Skipping format of sd-ext\n"); return -1; } } // Only use vold format for exact matches otherwise /sdcard will be // formatted instead of /storage/sdcard0/.android_secure if (fs_mgr_is_voldmanaged(v) && strcmp(volume, v->mount_point) == 0) { if (ensure_path_unmounted(volume) != 0) { LOGE("format_volume failed to unmount %s", v->mount_point); } return vold_format_volume(v->mount_point, 1) == CommandOkay ? 0 : -1; } if (strcmp(v->fs_type, "ramdisk") == 0) { // you can't format the ramdisk. LOGE("can't format_volume \"%s\"", volume); return -1; } if (strcmp(v->mount_point, volume) != 0) { #if 0 LOGE("can't give path \"%s\" to format_volume\n", volume); return -1; #endif return format_unknown_device(v->blk_device, volume, NULL); } if (ensure_path_unmounted(volume) != 0) { LOGE("format_volume failed to unmount \"%s\"\n", v->mount_point); return -1; } if (strcmp(v->fs_type, "yaffs2") == 0 || strcmp(v->fs_type, "mtd") == 0) { mtd_scan_partitions(); const MtdPartition* partition = mtd_find_partition_by_name(v->blk_device); if (partition == NULL) { LOGE("format_volume: no MTD partition \"%s\"\n", v->blk_device); return -1; } MtdWriteContext *write = mtd_write_partition(partition); if (write == NULL) { LOGW("format_volume: can't open MTD \"%s\"\n", v->blk_device); return -1; } else if (mtd_erase_blocks(write, -1) == (off_t) -1) { LOGW("format_volume: can't erase MTD \"%s\"\n", v->blk_device); mtd_write_close(write); return -1; } else if (mtd_write_close(write)) { LOGW("format_volume: can't close MTD \"%s\"\n", v->blk_device); return -1; } return 0; } if (strcmp(v->fs_type, "ext4") == 0) { int result = make_ext4fs(v->blk_device, v->length, volume, sehandle); if (result != 0) { LOGE("format_volume: make_extf4fs failed on %s\n", v->blk_device); return -1; } return 0; } #ifdef USE_F2FS if (strcmp(v->fs_type, "f2fs") == 0) { int result = make_f2fs_main(v->blk_device, v->mount_point); if (result != 0) { LOGE("format_volume: mkfs.f2f2 failed on %s\n", v->blk_device); return -1; } return 0; } #endif #if 0 LOGE("format_volume: fs_type \"%s\" unsupported\n", v->fs_type); return -1; #endif return format_unknown_device(v->blk_device, volume, v->fs_type); }