static BlockDriverState *bdrv_new_open(const char *filename, const char *fmt, int flags) { BlockDriverState *bs; BlockDriver *drv; char password[256]; bs = bdrv_new(""); if (!bs) error("Not enough memory"); if (fmt) { drv = bdrv_find_format(fmt); if (!drv) error("Unknown file format '%s'", fmt); } else { drv = NULL; } if (bdrv_open(bs, filename, flags, drv) < 0) { error("Could not open '%s'", filename); } if (bdrv_is_encrypted(bs)) { printf("Disk image '%s' is encrypted.\n", filename); if (read_password(password, sizeof(password)) < 0) error("No password given"); if (bdrv_set_key(bs, password) < 0) error("invalid password"); } return bs; }
static BlockDriverState *bdrv_new_open(const char *filename, const char *fmt, int flags) { BlockDriverState *bs; BlockDriver *drv; char password[256]; int ret; bs = bdrv_new("image"); if (fmt) { drv = bdrv_find_format(fmt); if (!drv) { error_report("Unknown file format '%s'", fmt); goto fail; } } else { drv = NULL; } ret = bdrv_open(bs, filename, flags, drv); if (ret < 0) { error_report("Could not open '%s': %s", filename, strerror(-ret)); goto fail; } if (bdrv_is_encrypted(bs)) { printf("Disk image '%s' is encrypted.\n", filename); if (read_password(password, sizeof(password)) < 0) { error_report("No password given"); goto fail; } if (bdrv_set_key(bs, password) < 0) { error_report("invalid password"); goto fail; } } return bs; fail: if (bs) { bdrv_delete(bs); } return NULL; }
/** * bdrv_query_image_info: * @bs: block device to examine * @p_info: location to store image information * @errp: location to store error information * * Store "flat" image information in @p_info. * * "Flat" means it does *not* query backing image information, * i.e. (*pinfo)->has_backing_image will be set to false and * (*pinfo)->backing_image to NULL even when the image does in fact have * a backing image. * * @p_info will be set only on success. On error, store error in @errp. */ void bdrv_query_image_info(BlockDriverState *bs, ImageInfo **p_info, Error **errp) { int64_t size; const char *backing_filename; BlockDriverInfo bdi; int ret; Error *err = NULL; ImageInfo *info; aio_context_acquire(bdrv_get_aio_context(bs)); size = bdrv_getlength(bs); if (size < 0) { error_setg_errno(errp, -size, "Can't get image size '%s'", bs->exact_filename); goto out; } info = g_new0(ImageInfo, 1); info->filename = g_strdup(bs->filename); info->format = g_strdup(bdrv_get_format_name(bs)); info->virtual_size = size; info->actual_size = bdrv_get_allocated_file_size(bs); info->has_actual_size = info->actual_size >= 0; if (bdrv_is_encrypted(bs)) { info->encrypted = true; info->has_encrypted = true; } if (bdrv_get_info(bs, &bdi) >= 0) { if (bdi.cluster_size != 0) { info->cluster_size = bdi.cluster_size; info->has_cluster_size = true; } info->dirty_flag = bdi.is_dirty; info->has_dirty_flag = true; } info->format_specific = bdrv_get_specific_info(bs); info->has_format_specific = info->format_specific != NULL; backing_filename = bs->backing_file; if (backing_filename[0] != '\0') { char *backing_filename2 = g_malloc0(PATH_MAX); info->backing_filename = g_strdup(backing_filename); info->has_backing_filename = true; bdrv_get_full_backing_filename(bs, backing_filename2, PATH_MAX, &err); if (err) { /* Can't reconstruct the full backing filename, so we must omit * this field and apply a Best Effort to this query. */ g_free(backing_filename2); backing_filename2 = NULL; error_free(err); err = NULL; } /* Always report the full_backing_filename if present, even if it's the * same as backing_filename. That they are same is useful info. */ if (backing_filename2) { info->full_backing_filename = g_strdup(backing_filename2); info->has_full_backing_filename = true; } if (bs->backing_format[0]) { info->backing_filename_format = g_strdup(bs->backing_format); info->has_backing_filename_format = true; } g_free(backing_filename2); } ret = bdrv_query_snapshot_info_list(bs, &info->snapshots, &err); switch (ret) { case 0: if (info->snapshots) { info->has_snapshots = true; } break; /* recoverable error */ case -ENOMEDIUM: case -ENOTSUP: error_free(err); break; default: error_propagate(errp, err); qapi_free_ImageInfo(info); goto out; } *p_info = info; out: aio_context_release(bdrv_get_aio_context(bs)); }
/** * bdrv_query_image_info: * @bs: block device to examine * @p_info: location to store image information * @errp: location to store error information * * Store "flat" image information in @p_info. * * "Flat" means it does *not* query backing image information, * i.e. (*pinfo)->has_backing_image will be set to false and * (*pinfo)->backing_image to NULL even when the image does in fact have * a backing image. * * @p_info will be set only on success. On error, store error in @errp. */ void bdrv_query_image_info(BlockDriverState *bs, ImageInfo **p_info, Error **errp) { uint64_t total_sectors; const char *backing_filename; char backing_filename2[1024]; BlockDriverInfo bdi; int ret; Error *err = NULL; ImageInfo *info = g_new0(ImageInfo, 1); bdrv_get_geometry(bs, &total_sectors); info->filename = g_strdup(bs->filename); info->format = g_strdup(bdrv_get_format_name(bs)); info->virtual_size = total_sectors * 512; info->actual_size = bdrv_get_allocated_file_size(bs); info->has_actual_size = info->actual_size >= 0; if (bdrv_is_encrypted(bs)) { info->encrypted = true; info->has_encrypted = true; } if (bdrv_get_info(bs, &bdi) >= 0) { if (bdi.cluster_size != 0) { info->cluster_size = bdi.cluster_size; info->has_cluster_size = true; } info->dirty_flag = bdi.is_dirty; info->has_dirty_flag = true; } info->format_specific = bdrv_get_specific_info(bs); info->has_format_specific = info->format_specific != NULL; backing_filename = bs->backing_file; if (backing_filename[0] != '\0') { info->backing_filename = g_strdup(backing_filename); info->has_backing_filename = true; bdrv_get_full_backing_filename(bs, backing_filename2, sizeof(backing_filename2)); if (strcmp(backing_filename, backing_filename2) != 0) { info->full_backing_filename = g_strdup(backing_filename2); info->has_full_backing_filename = true; } if (bs->backing_format[0]) { info->backing_filename_format = g_strdup(bs->backing_format); info->has_backing_filename_format = true; } } ret = bdrv_query_snapshot_info_list(bs, &info->snapshots, &err); switch (ret) { case 0: if (info->snapshots) { info->has_snapshots = true; } break; /* recoverable error */ case -ENOMEDIUM: case -ENOTSUP: error_free(err); break; default: error_propagate(errp, err); qapi_free_ImageInfo(info); return; } *p_info = info; }
/** * bdrv_query_image_info: * @bs: block device to examine * @p_info: location to store image information * @errp: location to store error information * * Store "flat" image information in @p_info. * * "Flat" means it does *not* query backing image information, * i.e. (*pinfo)->has_backing_image will be set to false and * (*pinfo)->backing_image to NULL even when the image does in fact have * a backing image. * * @p_info will be set only on success. On error, store error in @errp. */ void bdrv_query_image_info(BlockDriverState *bs, ImageInfo **p_info, Error **errp) { int64_t size; const char *backing_filename; char backing_filename2[1024]; BlockDriverInfo bdi; int ret; Error *err = NULL; ImageInfo *info; #ifdef __linux__ int fd, attr; #endif size = bdrv_getlength(bs); if (size < 0) { error_setg_errno(errp, -size, "Can't get size of device '%s'", bdrv_get_device_name(bs)); return; } info = g_new0(ImageInfo, 1); info->filename = g_strdup(bs->filename); info->format = g_strdup(bdrv_get_format_name(bs)); info->virtual_size = size; info->actual_size = bdrv_get_allocated_file_size(bs); info->has_actual_size = info->actual_size >= 0; if (bdrv_is_encrypted(bs)) { info->encrypted = true; info->has_encrypted = true; } if (bdrv_get_info(bs, &bdi) >= 0) { if (bdi.cluster_size != 0) { info->cluster_size = bdi.cluster_size; info->has_cluster_size = true; } info->dirty_flag = bdi.is_dirty; info->has_dirty_flag = true; } info->format_specific = bdrv_get_specific_info(bs); info->has_format_specific = info->format_specific != NULL; #ifdef __linux__ /* get NOCOW info */ fd = qemu_open(bs->filename, O_RDONLY | O_NONBLOCK); if (fd >= 0) { if (ioctl(fd, FS_IOC_GETFLAGS, &attr) == 0 && (attr & FS_NOCOW_FL)) { info->has_nocow = true; info->nocow = true; } qemu_close(fd); } #endif backing_filename = bs->backing_file; if (backing_filename[0] != '\0') { info->backing_filename = g_strdup(backing_filename); info->has_backing_filename = true; bdrv_get_full_backing_filename(bs, backing_filename2, sizeof(backing_filename2)); if (strcmp(backing_filename, backing_filename2) != 0) { info->full_backing_filename = g_strdup(backing_filename2); info->has_full_backing_filename = true; } if (bs->backing_format[0]) { info->backing_filename_format = g_strdup(bs->backing_format); info->has_backing_filename_format = true; } } ret = bdrv_query_snapshot_info_list(bs, &info->snapshots, &err); switch (ret) { case 0: if (info->snapshots) { info->has_snapshots = true; } break; /* recoverable error */ case -ENOMEDIUM: case -ENOTSUP: error_free(err); break; default: error_propagate(errp, err); qapi_free_ImageInfo(info); return; } *p_info = info; }
/** * bdrv_query_image_info: * @bs: block device to examine * @p_info: location to store image information * @errp: location to store error information * * Store "flat" image information in @p_info. * * "Flat" means it does *not* query backing image information, * i.e. (*pinfo)->has_backing_image will be set to false and * (*pinfo)->backing_image to NULL even when the image does in fact have * a backing image. * * @p_info will be set only on success. On error, store error in @errp. */ void bdrv_query_image_info(BlockDriverState *bs, ImageInfo **p_info, Error **errp) { int64_t size; const char *backing_filename; BlockDriverInfo bdi; int ret; Error *err = NULL; ImageInfo *info; size = bdrv_getlength(bs); if (size < 0) { error_setg_errno(errp, -size, "Can't get size of device '%s'", bdrv_get_device_name(bs)); return; } info = g_new0(ImageInfo, 1); info->filename = g_strdup(bs->filename); info->format = g_strdup(bdrv_get_format_name(bs)); info->virtual_size = size; info->actual_size = bdrv_get_allocated_file_size(bs); info->has_actual_size = info->actual_size >= 0; if (bdrv_is_encrypted(bs)) { info->encrypted = true; info->has_encrypted = true; } if (bdrv_get_info(bs, &bdi) >= 0) { if (bdi.cluster_size != 0) { info->cluster_size = bdi.cluster_size; info->has_cluster_size = true; } info->dirty_flag = bdi.is_dirty; info->has_dirty_flag = true; } info->format_specific = bdrv_get_specific_info(bs); info->has_format_specific = info->format_specific != NULL; backing_filename = bs->backing_file; if (backing_filename[0] != '\0') { char *backing_filename2 = g_malloc0(PATH_MAX); info->backing_filename = g_strdup(backing_filename); info->has_backing_filename = true; bdrv_get_full_backing_filename(bs, backing_filename2, PATH_MAX, &err); if (err) { error_propagate(errp, err); qapi_free_ImageInfo(info); g_free(backing_filename2); return; } if (strcmp(backing_filename, backing_filename2) != 0) { info->full_backing_filename = g_strdup(backing_filename2); info->has_full_backing_filename = true; } if (bs->backing_format[0]) { info->backing_filename_format = g_strdup(bs->backing_format); info->has_backing_filename_format = true; } g_free(backing_filename2); } ret = bdrv_query_snapshot_info_list(bs, &info->snapshots, &err); switch (ret) { case 0: if (info->snapshots) { info->has_snapshots = true; } break; /* recoverable error */ case -ENOMEDIUM: case -ENOTSUP: error_free(err); break; default: error_propagate(errp, err); qapi_free_ImageInfo(info); return; } *p_info = info; }