Esempio n. 1
0
void TWPartition::Setup_Image(bool Display_Error) {
	Display_Name = Mount_Point.substr(1, Mount_Point.size() - 1);
	Backup_Name = Display_Name;
	if (Fstab_File_System == "emmc")
		Backup_Method = DD;
	else if (Fstab_File_System == "mtd" || Fstab_File_System == "bml")
		Backup_Method = FLASH_UTILS;
	else
		LOGI("Unhandled file system '%s' on image '%s'\n", Fstab_File_System.c_str(), Display_Name.c_str());
	if (Find_Partition_Size()) {
		Used = Size;
		Backup_Size = Size;
	} else {
		if (Display_Error)
			LOGE("Unable to find parition size for '%s'\n", Mount_Point.c_str());
		else
			LOGI("Unable to find parition size for '%s'\n", Mount_Point.c_str());
	}
}
Esempio n. 2
0
int check_backup_size(const char* backup_path) {
    // these are the size stats for backup_path we previously refreshed by calling Get_Size_Via_statfs()
    int total_mb = (int)(Total_Size / 1048576LLU);
    int used_mb = (int)(Used_Size / 1048576LLU);
    int free_mb = (int)(Free_Size / 1048576LLU);
    int free_percent = free_mb * 100 / total_mb;
    Before_Used_Size = Used_Size; // save Used_Size to refresh data written stats later
    Backup_Size = 0;

    // supported nandroid partitions
    char* Base_Partitions_List[BASE_PARTITIONS_NUM] = {
            "/recovery",
            BOOT_PARTITION_MOUNT_POINT,
            "/wimax",
            "/modem",
            "/radio",
            "/efs",
            "/misc",
            "/system",
            "/preload",
            "/data",
            "/datadata",
            "/cache",
            "/sd-ext"
    };

    int items_num = BASE_PARTITIONS_NUM + MAX_EXTRA_NANDROID_PARTITIONS + 1;
    char* Partitions_List[items_num];
    int i;
    for (i = 0; i < BASE_PARTITIONS_NUM; ++i) {
        Partitions_List[i] = Base_Partitions_List[i];
    }

    int extra_partitions_num = get_extra_partitions_state();
    for (i = 0; i < extra_partitions_num; ++i) {
        Partitions_List[BASE_PARTITIONS_NUM + i] = extra_partition[i].mount_point;
    }

    Partitions_List[BASE_PARTITIONS_NUM + extra_partitions_num] = NULL;

    int preload_status = 0;
    if ((is_custom_backup && backup_preload) || (!is_custom_backup && nandroid_add_preload.value))
        preload_status = 1;

    int Base_Partitions_Backup_Status[] = {
            backup_recovery,
            backup_boot,
            backup_wimax,
            backup_modem,
            backup_radio,
            backup_efs,
            backup_misc,
            backup_system,
            preload_status,
            backup_data,
            backup_data,
            backup_cache,
            backup_sdext,
    };

    LOGI("Checking needed space for backup '%s'\n", backup_path);
    // calculate needed space for backup
    // assume recovery and wimax always use a raw backup mode (Is_Image() = 0)
    char skipped_parts[1024] = "";
    int ret = 0;
    Volume* vol;

    for (i = 0; Partitions_List[i] != NULL; ++i) {
        if (i >= BASE_PARTITIONS_NUM) {
            if (!extra_partition[i - BASE_PARTITIONS_NUM].backup_state)
                continue;
        } else if (!Base_Partitions_Backup_Status[i]) {
            continue;
        }

        // size of /data will be calculated later for /data/media devices to subtract sdcard size from it
        if (strcmp(Partitions_List[i], "/data") == 0 && is_data_media())
            continue;

        // redundant but keep for compatibility:
        // has_datadata() does a volume_for_path() != NULL check
        if (strcmp(Partitions_List[i], "/datadata") == 0 && !has_datadata())
            continue;

        vol = volume_for_path(Partitions_List[i]);
        if (vol == NULL) continue;

        if (Is_Image(Partitions_List[i]) == 0) {
            if (Find_Partition_Size(Partitions_List[i]) == 0) {
                Backup_Size += Total_Size;
                LOGI("%s backup size (/proc)=%lluMb\n", Partitions_List[i], Total_Size / 1048576LLU); // debug
            } else {
                ret++;
                strcat(skipped_parts, " - ");
                strcat(skipped_parts, Partitions_List[i]);
            }
        } else if (Is_File_System(Partitions_List[i]) == 0) {
            // Get_Size_Via_statfs() will ensure vol->mount_point != NULL
            if (0 == ensure_path_mounted(vol->mount_point) && 0 == Get_Size_Via_statfs(vol->mount_point)) {
                Backup_Size += Used_Size;
                LOGI("%s backup size (stat)=%lluMb\n", Partitions_List[i], Used_Size / 1048576LLU); // debug
            } else {
                ret++;
                strcat(skipped_parts, " - ");
                strcat(skipped_parts, Partitions_List[i]);
            }
        } else {
            ret++;
            strcat(skipped_parts, " - Unknown file system: ");
            strcat(skipped_parts, Partitions_List[i]);
        }
    }

    // handle special partitions and folders:
    // handle /data and /data/media partitions size for /data/media devices
    unsigned long long data_backup_size = 0;
    unsigned long long data_used_bytes = 0;
    unsigned long long data_media_size = 0;
    if (is_data_media() && (backup_data || backup_data_media)) {
        if (0 == ensure_path_mounted("/data") && 0 == Get_Size_Via_statfs("/data")) {
            data_media_size = Get_Folder_Size("/data/media");
            data_used_bytes = Get_Folder_Size("/data");
            data_backup_size = data_used_bytes - data_media_size;
            LOGI("/data: tot size=%lluMb, free=%lluMb, backup size=%lluMb, used=%lluMb, media=%lluMb\n",
                    Total_Size/1048576LLU, Free_Size/1048576LLU, data_backup_size/1048576LLU,
                    data_used_bytes/1048576LLU, data_media_size/1048576LLU);
        } else {
            if (backup_data) {
                strcat(skipped_parts, " - /data");
                ret++;
            }
            if (backup_data_media) {
                strcat(skipped_parts, " - /data/media");
                ret++;
            }
        }
    }

    if (backup_data)
        Backup_Size += data_backup_size;

    // check if we are also backing up /data/media
    // if backup_path is same as /data/media, ignore this as it will not be processed by nandroid_backup_datamedia()
    if (backup_data_media && !is_data_media_volume_path(backup_path)) {
        Backup_Size += data_media_size;
        LOGI("included /data/media size\n"); // debug
    }

    // .android_secure size calculation
    // set_android_secure_path() will mount tmp so no need to remount before calling Get_Folder_Size(tmp)
    char tmp[PATH_MAX];
    set_android_secure_path(tmp);
    if (backup_data && android_secure_ext) {
        unsigned long long andsec_size;
        andsec_size = Get_Folder_Size(tmp);
        Backup_Size += andsec_size;
        LOGI("%s backup size=%lluMb\n", tmp, andsec_size / 1048576LLU); // debug
    }

    // check if we have the needed space
    int backup_size_mb = (int)(Backup_Size / 1048576LLU);
    ui_print("\n>> Free space: %dMb (%d%%)\n", free_mb, free_percent);
    ui_print(">> Needed space: %dMb\n", backup_size_mb);
    if (ret)
        ui_print(">> Unknown partitions size (%d):%s\n", ret, skipped_parts);

    // dedupe wrapper needs less space than actual backup size (incremental backups)
    // only check free space in Mb if we use tar or tar.gz as a default format
    // also, add extra 50 Mb for security measures
    if (free_percent < 3 || (default_backup_handler != dedupe_compress_wrapper && free_mb < backup_size_mb + 50)) {
        LOGW("Low space for backup!\n");
        if (!ui_is_initialized()) {
            // do not prompt when it is an "adb shell nandroid backup" command
            LOGW("\n>>> Backup could fail with I/O error!! <<<\n\n");
        } else if (nand_prompt_on_low_space.value && !confirm_selection("Low free space! Continue anyway?", "Yes - Continue Nandroid Job"))
            return -1;
    }

    return 0;
}