int format_root_device(const char *root)
{
    /* Don't try to format a mounted device. */
    int ret = ensure_root_path_unmounted(root);  
    if (ret < 0) {
        LOGD(LOG_TAG "format_root_device: can't unmount \"%s\"\n", root);
        return -1;
    }

    if (!strcmp(root, "/data")) {
	  int result = make_ext4fs("/emmc@usrdata", 0);
	  if (result != 0) {	
		LOGE("format_volume: make_extf4fs failed on /emmc@usrdata\n");
	    	return -1;
    	  }
    }	else if (!strcmp(root, "/cache")) {
    	
	   int  result = make_ext4fs("/emmc@cache", 0);
	   if (result != 0) {	
			LOGE("format_volume: make_extf4fs failed on /emmc@cache\n");
	    		return -1;
    	   }

    }

    return 0;
}
Esempio n. 2
0
int format_volume(const char* volume) {
    Volume* v = volume_for_path(volume);
    char value[PROPERTY_VALUE_MAX];

    if (v == NULL) {
        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) {
        LOGE("can't give path \"%s\" to format_volume\n", volume);
        return -1;
    }

    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) {
            LOGE("format_volume: can't open MTD \"%s\"\n", v->device);
            return -1;
        } else if (mtd_erase_blocks(write, -1) == (off_t) -1) {
            LOGE("format_volume: can't erase MTD \"%s\"\n", v->device);
            mtd_write_close(write);
            return -1;
        } else if (mtd_write_close(write)) {
            LOGE("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, NULL);
        if (result != 0) {
            // If v->length is <= 0 the fs is not created by make_ext4fs.
            LOGE("format_volume: make_extf4fs failed on %s\n", v->device);
            return -1;
        }
        return 0;
    }

    LOGE("format_volume: fs_type \"%s\" unsupported\n", v->fs_type);
    return -1;
}
Esempio n. 3
0
int format_root_device(const char *root)
{
    /* Don't try to format a mounted device. */
    int ret = ensure_root_path_unmounted(root);  
    if (ret < 0) 
    {
        LOGD(TAG "format_root_device: can't unmount \"%s\"\n", root);
        return false;
    }
#if 1
        int fd;
        struct msdc_ioctl msdc_io;

        fd = open("/dev/misc-sd", O_RDONLY);
        if (fd < 0) {
            LOGE("open: /dev/misc-sd failed\n");
            return -1;
        }
        
        msdc_io.opcode = MSDC_ERASE_PARTITION;
        if (!strcmp(root, "/cache")) {
            msdc_io.buffer = (unsigned int*) "cache";
            msdc_io.total_size = 6;
        } else if (!strcmp(root, "/data")) {
            msdc_io.buffer = (unsigned int*) "usrdata";
            msdc_io.total_size = 8;
        }

        ioctl(fd, 0, &msdc_io);
        close(fd);
#endif
    if (!strcmp(root, "/data")) {
	    int result = make_ext4fs("/emmc@usrdata", 0, 0, 0);
	    if (result != 0) {	
		LOGE("format_volume: make_extf4fs failed on /emmc@usrdata\n");
	    	return -1;
    	    }
    }	

    return 0;
}
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);
}
Esempio n. 5
0
// format(fs_type, partition_type, location, fs_size, mount_point)
//
//    fs_type="yaffs2" partition_type="MTD"     location=partition fs_size=<bytes> mount_point=<location>
//    fs_type="ext4"   partition_type="EMMC"    location=device    fs_size=<bytes> mount_point=<location>
//    if fs_size == 0, then make_ext4fs uses the entire partition.
//    if fs_size > 0, that is the size to use
//    if fs_size < 0, then reserve that many bytes at the end of the partition
Value* FormatFn(const char* name, State* state, int argc, Expr* argv[]) {
    char* result = NULL;
    if (argc != 5) {
        return ErrorAbort(state, "%s() expects 5 args, got %d", name, argc);
    }
    char* fs_type;
    char* partition_type;
    char* location;
    char* fs_size;
    char* mount_point;

    if (ReadArgs(state, argv, 5, &fs_type, &partition_type, &location, &fs_size, &mount_point) < 0) {
        return NULL;
    }

    if (strlen(fs_type) == 0) {
        ErrorAbort(state, "fs_type argument to %s() can't be empty", name);
        goto done;
    }
    if (strlen(partition_type) == 0) {
        ErrorAbort(state, "partition_type argument to %s() can't be empty",
                   name);
        goto done;
    }
    if (strlen(location) == 0) {
        ErrorAbort(state, "location argument to %s() can't be empty", name);
        goto done;
    }

    if (strlen(mount_point) == 0) {
        ErrorAbort(state, "mount_point argument to %s() can't be empty", name);
        goto done;
    }

    if (strcmp(partition_type, "MTD") == 0) {
        mtd_scan_partitions();
        const MtdPartition* mtd = mtd_find_partition_by_name(location);
        if (mtd == NULL) {
            fprintf(stderr, "%s: no mtd partition named \"%s\"",
                    name, location);
            result = strdup("");
            goto done;
        }
        MtdWriteContext* ctx = mtd_write_partition(mtd);
        if (ctx == NULL) {
            fprintf(stderr, "%s: can't write \"%s\"", name, location);
            result = strdup("");
            goto done;
        }
        if (mtd_erase_blocks(ctx, -1) == -1) {
            mtd_write_close(ctx);
            fprintf(stderr, "%s: failed to erase \"%s\"", name, location);
            result = strdup("");
            goto done;
        }
        if (mtd_write_close(ctx) != 0) {
            fprintf(stderr, "%s: failed to close \"%s\"", name, location);
            result = strdup("");
            goto done;
        }
        result = location;
#ifdef USE_EXT4
    } else if (strcmp(fs_type, "ext4") == 0) {
        int status = make_ext4fs(location, atoll(fs_size), mount_point, sehandle);
        if (status != 0) {
            fprintf(stderr, "%s: make_ext4fs failed (%d) on %s",
                    name, status, location);
            result = strdup("");
            goto done;
        }
        result = location;
#endif
    } else {
        fprintf(stderr, "%s: unsupported fs_type \"%s\" partition_type \"%s\"",
                name, fs_type, partition_type);
    }

done:
    free(fs_type);
    free(partition_type);
    if (result != location) free(location);
    return StringValue(result);
}
Esempio n. 6
0
int format_volume(const char* volume) {
    Volume* v = volume_for_path(volume);
    if (v == NULL) {
        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) {
        LOGE("can't give path \"%s\" to format_volume\n", volume);
        return -1;
    }

    if (ensure_path_unmounted(volume) != 0) {
        LOGE("format_volume failed to unmount \"%s\"\n", v->mount_point);
        return -1;
    }
    if(!strcmp(v->fs_type, "ubifs"))
    {
    const MtdPartition *partition;
	mtd_scan_partitions();
    if(strcmp(v->mount_point, "/data"))
        partition = mtd_find_partition_by_name(&v->mount_point[1]);
    else
        partition = mtd_find_partition_by_name("userdata");
        if (partition == NULL) {
            LOGE("format_volume: %s cat't find mtd partition\n", v->mount_point);
            return -1;
	        }else{
	        if (strcmp(v->mount_point, "/system") == 0 ||
	            strcmp(v->mount_point, "/cache") == 0 ||
	            strcmp(v->mount_point, "/data") == 0 ){
	            
	           char cmd_line[128];
	            int  ubi_vol = 1;
	//            bool b_org_mounted = false;
	            int status;

	            ui_print("format partition: %s \n", v->mount_point);
#if 1      
	            if (strcmp(v->mount_point, "/system") == 0){
	                ubi_vol = 1;
	            }else if (strcmp(v->mount_point, "/data") == 0){
	            	ubi_vol = 2;
	            }else if(strcmp(v->mount_point, "/cache") == 0){
	                ubi_vol = 3;
	            }else{
	            	ubi_vol = 4; //perm partition
	            }
#endif

				//vapor : it is not properly, so we mask it.
	            //if (ensure_path_mounted(v->mount_point) == 0)  
	            {
	                fprintf(stderr,"umount /%s\r\n", v->mount_point);
	                umount(v->mount_point);
	            }
	            
	            memset(cmd_line, 0, 128);
	            sprintf(cmd_line, "/format.sh %d %d %s", partition->device_index, ubi_vol, partition->name);
                format_ubifs(cmd_line);
	            ui_print("format partition: %s complete\n", v->device);
	        	return 0;
	   		 }
	    	}
		}
	    else 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 0
	    else if (strcmp(v->fs_type, "ext4") == 0) {
	        int result = make_ext4fs(v->device, v->length);
	        if (result != 0) {
	            LOGE("format_volume: make_extf4fs failed on %s\n", v->device);
	            return -1;
	        }
	        return 0;
	    }
#endif
    LOGE("format_volume: fs_type \"%s\" unsupported\n", v->fs_type);
    return -1;
}
Esempio n. 7
0
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);
}
Esempio n. 8
0
int format_volume(const char* volume) {
    Volume* v = volume_for_path(volume);
    if (v == NULL) {
        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) {
        LOGE("can't give path \"%s\" to format_volume\n", volume);
        return -1;
    }

    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 || strcmp(v->fs_type, "f2fs") == 0) {
        // if there's a key_loc that looks like a path, it should be a
        // block device for storing encryption metadata.  wipe it too.
        if (v->key_loc != NULL && v->key_loc[0] == '/') {
            LOGI("wiping %s\n", v->key_loc);
            int fd = open(v->key_loc, O_WRONLY | O_CREAT, 0644);
            if (fd < 0) {
                LOGE("format_volume: failed to open %s\n", v->key_loc);
                return -1;
            }
            wipe_block_device(fd, get_file_size(fd));
            close(fd);
        }

        ssize_t length = 0;
        if (v->length != 0) {
            length = v->length;
        } else if (v->key_loc != NULL && strcmp(v->key_loc, "footer") == 0) {
            length = -CRYPT_FOOTER_OFFSET;
        }
        int result;
        if (strcmp(v->fs_type, "ext4") == 0) {
            result = make_ext4fs(v->blk_device, length, volume, sehandle);
        } else {   /* Has to be f2fs because we checked earlier. */
            if (v->key_loc != NULL && strcmp(v->key_loc, "footer") == 0 && length < 0) {
                LOGE("format_volume: crypt footer + negative length (%zd) not supported on %s\n", length, v->fs_type);
                return -1;
            }
            if (length < 0) {
                LOGE("format_volume: negative length (%zd) not supported on %s\n", length, v->fs_type);
                return -1;
            }
            char *num_sectors;
            if (asprintf(&num_sectors, "%zd", length / 512) <= 0) {
                LOGE("format_volume: failed to create %s command for %s\n", v->fs_type, v->blk_device);
                return -1;
            }
            const char *f2fs_path = "/sbin/mkfs.f2fs";
            const char* const f2fs_argv[] = {"mkfs.f2fs", "-t", "-d1", v->blk_device, num_sectors, NULL};

            result = exec_cmd(f2fs_path, (char* const*)f2fs_argv);
            free(num_sectors);
        }
        if (result != 0) {
            LOGE("format_volume: make %s failed on %s with %d(%s)\n", v->fs_type, v->blk_device, result, strerror(errno));
            return -1;
        }
        return 0;
    }

    LOGE("format_volume: fs_type \"%s\" unsupported\n", v->fs_type);
    return -1;
}
Esempio n. 9
0
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);
}
Esempio n. 11
0
int format_volume(const char* volume) {
    Volume* v = volume_for_path(volume);
    if (v == NULL) {
        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) {
        LOGE("can't give path \"%s\" to format_volume\n", volume);
        return -1;
    }

    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) {
        if (fs_mgr_is_encryptable(v) &&
            (v->length == 0) &&
            (v->key_loc != NULL) &&
            !strcmp(v->key_loc, KEY_IN_FOOTER)) {
            if (get_block_device_size(v->blk_device, &v->length) == 0) {
                v->length -= CRYPT_FOOTER_OFFSET;
            }
        }

        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_UBIFS
    if (strcmp(v->fs_type, "ubifs") == 0) {
        int ret;
        LOGW("formating by ubiVolumeFormat");
        ret = ubiVolumeFormat(v->blk_device);
        if (ret != 0) {
            LOGE("ubiVolumeFormat return error:%d", ret);
            return -1;
        }
            return 0;
    }
#endif

    LOGE("format_volume: fs_type \"%s\" unsupported\n", v->fs_type);
    return -1;
}
Esempio n. 12
0
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);
}
Esempio n. 13
0
int format_volume(const char* volume) {

    time_t start, end;
    start = time((time_t *)NULL);
    printf("format %s start=%u\n", volume, (unsigned int)start);

#if defined(CACHE_MERGE_SUPPORT)
    char *target_volume = (char *)volume;

    if (strcmp(target_volume, "/cache") == 0) {
        // we cannot mount data since partition size changed
        // clear cache folder when data mounted
        if (part_size_changed) {
            LOGI("partition size changed, clear cache folder when data mounted...\n");
            need_clear_cache = 1;

            // change format volume name to format actual cache partition
            target_volume = "/.cache";
        } else {
            // clear DATA_CACHE_ROOT
            if (ensure_path_mounted(DATA_CACHE_ROOT) != 0) {
                LOGE("Can't mount %s while clearing cache!\n", DATA_CACHE_ROOT);
                return -1;
            }
            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("Can't mkdir %s (%s)\n", DATA_CACHE_ROOT, strerror(errno));
                return -1;
            }
            LOGI("format cache successfully!\n");

            end = time((time_t *)NULL);
            printf("format end=%u duration=%u\n", (unsigned int)end, (unsigned int)(end - start));
            return 0;
        }
    }

    Volume* v = volume_for_path(target_volume);
    if (v == NULL) {
        LOGE("unknown volume \"%s\"\n", target_volume);
        return -1;
    }
    if (strcmp(v->fs_type, "ramdisk") == 0) {
        // you can't format the ramdisk.
        LOGE("can't format_volume \"%s\"", target_volume);
        return -1;
    }
    if (strcmp(v->mount_point, target_volume) != 0) {
        LOGE("can't give path \"%s\" to format_volume\n", target_volume);
        return -1;
    }

    if (ensure_path_unmounted(target_volume) != 0) {
        LOGE("format_volume failed to unmount \"%s\"\n", v->mount_point);
        return -1;
    }
#else
    Volume* v = volume_for_path(volume);
    if (v == NULL) {
        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) {
        LOGE("can't give path \"%s\" to format_volume\n", volume);
        return -1;
    }

    if (ensure_path_unmounted(volume) != 0) {
        LOGE("format_volume failed to unmount \"%s\"\n", v->mount_point);
        return -1;
    }
#endif

#if defined (UBIFS_SUPPORT)
    if (strcmp(v->fs_type, "ubifs") == 0) {

        int ret;
        ret = ubi_format(v->mount_point);

        if (!ret) {
            end = time((time_t *)NULL);
            printf("format end=%u duration=%u\n", (unsigned int)end, (unsigned int)(end - start));
            return 0;
        } else {
            LOGE("Ubiformat failed on \"%s\"\n", v->mount_point);
        }


#if 0

        int ret;
        //Remove volume
        if(ubi_rmvol_user(v->mount_point)!=0){
            LOGE("failed to remove %s\n", v->blk_device);
            return -1;
        }

        //Make volume
        ret = ubi_mkvol_user(v->mount_point);
        if(!ret){
            printf("%s volume made\n", v->blk_device);
            return 0;
        }
#endif
    }
#endif

    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;
        }

        end = time((time_t *)NULL);
        printf("format end=%u duration=%u\n", (unsigned int)end, (unsigned int)(end - start));
        return 0;
    }

    if (strcmp(v->fs_type, "ext4") == 0 || strcmp(v->fs_type, "f2fs") == 0) {
        if (!mt_is_support_gpt()) {
#if defined(HAVE_ANDROID_OS) && !defined(ARCH_X86) //wschen 2012-07-10
            int fd;
            struct msdc_ioctl msdc_io;

            fd = open("/dev/misc-sd", O_RDONLY);
            if (fd < 0) {
                LOGE("open: /dev/misc-sd failed\n");
                return -1;
            }

            msdc_io.opcode = MSDC_ERASE_PARTITION;
#if defined(CACHE_MERGE_SUPPORT)
            if (!strcmp(target_volume, "/.cache")) {
                msdc_io.buffer = (unsigned int*) "cache";
                msdc_io.total_size = 6;
            } else if (!strcmp(target_volume, "/data")) {
                msdc_io.buffer = (unsigned int*) "usrdata";
                msdc_io.total_size = 8;
            }
#else
            if (!strcmp(volume, "/cache")) {
                msdc_io.buffer = (unsigned int*) "cache";
                msdc_io.total_size = 6;
            } else if (!strcmp(volume, "/data")) {
                msdc_io.buffer = (unsigned int*) "usrdata";
                msdc_io.total_size = 8;
            }
#endif
            ioctl(fd, 0, &msdc_io);
            close(fd);
#endif
        } // end of not support_gpt

        // if there's a key_loc that looks like a path, it should be a
        // block device for storing encryption metadata.  wipe it too.
        if (v->key_loc != NULL && v->key_loc[0] == '/') {
            LOGI("wiping %s\n", v->key_loc);
            int fd = open(v->key_loc, O_WRONLY | O_CREAT, 0644);
            if (fd < 0) {
                LOGE("format_volume: failed to open %s\n", v->key_loc);
                return -1;
            }
            wipe_block_device(fd, get_file_size(fd));
            close(fd);
        }

#ifndef CRYPT_FOOTER_OFFSET
#define CRYPT_FOOTER_OFFSET (0)
#endif

        ssize_t length = 0;
        if (v->length != 0) {
            length = v->length;
        } else if (v->key_loc != NULL && strcmp(v->key_loc, "footer") == 0) {
            length = -CRYPT_FOOTER_OFFSET;
        }

        int result = 0;
        if (strcmp(v->fs_type, "ext4") == 0) {

#if defined(CACHE_MERGE_SUPPORT)
            result = make_ext4fs(v->blk_device, length, target_volume, sehandle);
#else
            LOGE("Before make_ext4fs v->blk_device:%s length:%lld volume=%s\n", v->blk_device, length, volume);
            result = make_ext4fs(v->blk_device, length, volume, sehandle);
#endif

        } else {   /* Has to be f2fs because we checked earlier. */
            if (v->key_loc != NULL && strcmp(v->key_loc, "footer") == 0 && length < 0) {
                LOGE("format_volume: crypt footer + negative length (%zd) not supported on %s\n", length, v->fs_type);
                return -1;
            }
            if (length < 0) {
                LOGE("format_volume: negative length (%zd) not supported on %s\n", length, v->fs_type);
                return -1;
            }
            char *num_sectors;
            if (asprintf(&num_sectors, "%zd", length / 512) <= 0) {
                LOGE("format_volume: failed to create %s command for %s\n", v->fs_type, v->blk_device);
                return -1;
            }
            const char *f2fs_path = "/sbin/mkfs.f2fs";
            const char* const f2fs_argv[] = {"mkfs.f2fs", "-t", "-d1", v->blk_device, num_sectors, NULL};

            result = exec_cmd(f2fs_path, (char* const*)f2fs_argv);
            free(num_sectors);
        }

        if (result != 0) {
            LOGE("format_volume: make %s failed on %s with %d(%s)\n", v->fs_type, v->blk_device, result, strerror(errno));
            return -1;
        }

        end = time((time_t *)NULL);
        printf("format end=%u duration=%u\n", (unsigned int)end, (unsigned int)(end - start));
        return 0;
    }

    LOGE("format_volume: fs_type \"%s\" unsupported\n", v->fs_type);
    return -1;
}
Esempio n. 14
0
int format_volume(const char* volume, bool force) {
    if (strcmp(volume, "media") == 0) {
        if (!is_data_media()) {
            return 0;
        }
        if (ensure_path_mounted("/data") != 0) {
            LOGE("format_volume failed to mount /data\n");
            return -1;
        }
        int rc = 0;
        rc = rmtree_except("/data/media", NULL);
        ensure_path_unmounted("/data");
        return rc;
    }

    fstab_rec* v = volume_for_path(volume);
    if (v == NULL) {
        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) {
        LOGE("can't give path \"%s\" to format_volume\n", volume);
        return -1;
    }

    if (strcmp(volume, "/data") == 0 && is_data_media() && !force) {
        if (ensure_path_mounted("/data") == 0) {
            // Preserve .layout_version to avoid "nesting bug"
            LOGI("Preserving layout version\n");
            unsigned char layout_buf[256];
            ssize_t layout_buflen = -1;
            int fd;
            fd = open("/data/.layout_version", O_RDONLY);
            if (fd != -1) {
                layout_buflen = read(fd, layout_buf, sizeof(layout_buf));
                close(fd);
            }

            int rc = rmtree_except("/data", "media");

            // Restore .layout_version
            if (layout_buflen > 0) {
                LOGI("Restoring layout version\n");
                fd = open("/data/.layout_version", O_WRONLY | O_CREAT | O_EXCL, 0600);
                if (fd != -1) {
                    write(fd, layout_buf, layout_buflen);
                    close(fd);
                }
            }

            ensure_path_unmounted(volume);

            return rc;
        }
        LOGE("format_volume failed to mount /data, formatting instead\n");
    }

    if (ensure_path_unmounted(volume) != 0) {
        LOGE("format_volume failed to unmount \"%s\"\n", v->mount_point);
        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);
    }

    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 || strcmp(v->fs_type, "f2fs") == 0) {
        // if there's a key_loc that looks like a path, it should be a
        // block device for storing encryption metadata.  wipe it too.
        if (v->key_loc != NULL && v->key_loc[0] == '/') {
            LOGI("wiping %s\n", v->key_loc);
            int fd = open(v->key_loc, O_WRONLY | O_CREAT, 0644);
            if (fd < 0) {
                LOGE("format_volume: failed to open %s\n", v->key_loc);
                return -1;
            }
            wipe_block_device(fd, get_file_size(fd));
            close(fd);
        }

        ssize_t length = 0;
        if (v->length != 0) {
            length = v->length;
        } else if (v->key_loc != NULL && strcmp(v->key_loc, "footer") == 0) {
            length = -CRYPT_FOOTER_OFFSET;
        }
        int result;
        if (strcmp(v->fs_type, "ext4") == 0) {
            result = make_ext4fs(v->blk_device, length, volume, sehandle);
        } else {   /* Has to be f2fs because we checked earlier. */
            char bytes_reserved[10] = {0};
            if (v->key_loc != NULL && strcmp(v->key_loc, "footer") == 0) {
                snprintf(bytes_reserved, sizeof(bytes_reserved), "%d", CRYPT_FOOTER_OFFSET);
            }
            char *num_sectors;
            if (asprintf(&num_sectors, "%zd", length / 512) <= 0) {
                LOGE("format_volume: failed to create %s command for %s\n", v->fs_type, v->blk_device);
                return -1;
            }
            const char *f2fs_path = "/sbin/mkfs.f2fs";
            const char* const f2fs_argv[] = {"mkfs.f2fs", "-t", "-d1", "-r",
                bytes_reserved, v->blk_device, num_sectors, NULL};

            result = exec_cmd(f2fs_path, (char* const*)f2fs_argv);
            free(num_sectors);
        }
        if (result != 0) {
            LOGE("format_volume: make %s failed on %s with %d(%s)\n", v->fs_type, v->blk_device, result, strerror(errno));
            return -1;
        }
        return 0;
    }

    LOGE("format_volume: fs_type \"%s\" unsupported\n", v->fs_type);
    return -1;
}
Esempio n. 15
0
int format_volume(const char* volume) {
    Volume* v = volume_for_path(volume);
    if (v == NULL) {
        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) {
        LOGE("can't give path \"%s\" to format_volume\n", volume);
        return -1;
    }

    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) {
#if 1 //wschen 2012-02-14
        int fd;
        struct msdc_ioctl msdc_io;

        fd = open("/dev/misc-sd", O_RDONLY);
        if (fd < 0) {
            LOGE("open: /dev/misc-sd failed\n");
            return -1;
        }

        msdc_io.opcode = MSDC_ERASE_PARTITION;
        if (!strcmp(volume, "/cache")) {
            msdc_io.buffer = (unsigned int*) "cache";
            msdc_io.total_size = 6;
        } else if (!strcmp(volume, "/data")) {
            msdc_io.buffer = (unsigned int*) "usrdata";
            msdc_io.total_size = 8;
        }

        ioctl(fd, 0, &msdc_io);
        close(fd);
#endif

        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;
    }

    LOGE("format_volume: fs_type \"%s\" unsupported\n", v->fs_type);
    return -1;
}