mirror of https://gitee.com/openkylin/qemu.git
Merge remote-tracking branch 'kwolf/for-anthony' into staging
# By Fam Zheng (8) and others # Via Kevin Wolf * kwolf/for-anthony: vmdk: rename num_gtes_per_gte to num_gtes_per_gt vmdk: use heap allocation for whole_grain vmdk: check l1 size before opening image vmdk: check l2 table size when opening vmdk: check granularity field in opening qemu-iotests: add empty test case for vmdk qemu-iotests: add poke_file utility function vmdk: use unsigned values for on disk header fields vmdk: Make VMDK3Header and VmdkGrainMarker QEMU_PACKED sheepdog: add missing .bdrv_has_zero_init qemu-iotests: filter QEMU version in monitor banner iov: handle EOF in iov_send_recv ignore SIGPIPE in qemu-img and qemu-io qemu-img: Error out for excess arguments Message-id: 1375799990-995-1-git-send-email-kwolf@redhat.com Signed-off-by: Anthony Liguori <aliguori@us.ibm.com>
This commit is contained in:
commit
cafffa5454
|
@ -2347,6 +2347,7 @@ static BlockDriver bdrv_sheepdog = {
|
|||
.bdrv_file_open = sd_open,
|
||||
.bdrv_close = sd_close,
|
||||
.bdrv_create = sd_create,
|
||||
.bdrv_has_zero_init = bdrv_has_zero_init_1,
|
||||
.bdrv_getlength = sd_getlength,
|
||||
.bdrv_truncate = sd_truncate,
|
||||
|
||||
|
@ -2374,6 +2375,7 @@ static BlockDriver bdrv_sheepdog_tcp = {
|
|||
.bdrv_file_open = sd_open,
|
||||
.bdrv_close = sd_close,
|
||||
.bdrv_create = sd_create,
|
||||
.bdrv_has_zero_init = bdrv_has_zero_init_1,
|
||||
.bdrv_getlength = sd_getlength,
|
||||
.bdrv_truncate = sd_truncate,
|
||||
|
||||
|
|
115
block/vmdk.c
115
block/vmdk.c
|
@ -62,19 +62,20 @@ typedef struct {
|
|||
uint32_t cylinders;
|
||||
uint32_t heads;
|
||||
uint32_t sectors_per_track;
|
||||
} VMDK3Header;
|
||||
} QEMU_PACKED VMDK3Header;
|
||||
|
||||
typedef struct {
|
||||
uint32_t version;
|
||||
uint32_t flags;
|
||||
int64_t capacity;
|
||||
int64_t granularity;
|
||||
int64_t desc_offset;
|
||||
int64_t desc_size;
|
||||
int32_t num_gtes_per_gte;
|
||||
int64_t rgd_offset;
|
||||
int64_t gd_offset;
|
||||
int64_t grain_offset;
|
||||
uint64_t capacity;
|
||||
uint64_t granularity;
|
||||
uint64_t desc_offset;
|
||||
uint64_t desc_size;
|
||||
/* Number of GrainTableEntries per GrainTable */
|
||||
uint32_t num_gtes_per_gt;
|
||||
uint64_t rgd_offset;
|
||||
uint64_t gd_offset;
|
||||
uint64_t grain_offset;
|
||||
char filler[1];
|
||||
char check_bytes[4];
|
||||
uint16_t compressAlgorithm;
|
||||
|
@ -109,7 +110,7 @@ typedef struct VmdkExtent {
|
|||
|
||||
typedef struct BDRVVmdkState {
|
||||
CoMutex lock;
|
||||
int desc_offset;
|
||||
uint64_t desc_offset;
|
||||
bool cid_updated;
|
||||
uint32_t parent_cid;
|
||||
int num_extents;
|
||||
|
@ -131,7 +132,7 @@ typedef struct VmdkGrainMarker {
|
|||
uint64_t lba;
|
||||
uint32_t size;
|
||||
uint8_t data[0];
|
||||
} VmdkGrainMarker;
|
||||
} QEMU_PACKED VmdkGrainMarker;
|
||||
|
||||
enum {
|
||||
MARKER_END_OF_STREAM = 0,
|
||||
|
@ -385,15 +386,22 @@ static int vmdk_parent_open(BlockDriverState *bs)
|
|||
|
||||
/* Create and append extent to the extent array. Return the added VmdkExtent
|
||||
* address. return NULL if allocation failed. */
|
||||
static VmdkExtent *vmdk_add_extent(BlockDriverState *bs,
|
||||
static int vmdk_add_extent(BlockDriverState *bs,
|
||||
BlockDriverState *file, bool flat, int64_t sectors,
|
||||
int64_t l1_offset, int64_t l1_backup_offset,
|
||||
uint32_t l1_size,
|
||||
int l2_size, unsigned int cluster_sectors)
|
||||
int l2_size, uint64_t cluster_sectors,
|
||||
VmdkExtent **new_extent)
|
||||
{
|
||||
VmdkExtent *extent;
|
||||
BDRVVmdkState *s = bs->opaque;
|
||||
|
||||
if (cluster_sectors > 0x200000) {
|
||||
/* 0x200000 * 512Bytes = 1GB for one cluster is unrealistic */
|
||||
error_report("invalid granularity, image may be corrupt");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
s->extents = g_realloc(s->extents,
|
||||
(s->num_extents + 1) * sizeof(VmdkExtent));
|
||||
extent = &s->extents[s->num_extents];
|
||||
|
@ -416,7 +424,10 @@ static VmdkExtent *vmdk_add_extent(BlockDriverState *bs,
|
|||
extent->end_sector = extent->sectors;
|
||||
}
|
||||
bs->total_sectors = extent->end_sector;
|
||||
return extent;
|
||||
if (new_extent) {
|
||||
*new_extent = extent;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int vmdk_init_tables(BlockDriverState *bs, VmdkExtent *extent)
|
||||
|
@ -475,12 +486,17 @@ static int vmdk_open_vmdk3(BlockDriverState *bs,
|
|||
if (ret < 0) {
|
||||
return ret;
|
||||
}
|
||||
extent = vmdk_add_extent(bs,
|
||||
|
||||
ret = vmdk_add_extent(bs,
|
||||
bs->file, false,
|
||||
le32_to_cpu(header.disk_sectors),
|
||||
le32_to_cpu(header.l1dir_offset) << 9,
|
||||
0, 1 << 6, 1 << 9,
|
||||
le32_to_cpu(header.granularity));
|
||||
le32_to_cpu(header.granularity),
|
||||
&extent);
|
||||
if (ret < 0) {
|
||||
return ret;
|
||||
}
|
||||
ret = vmdk_init_tables(bs, extent);
|
||||
if (ret) {
|
||||
/* free extent allocated by vmdk_add_extent */
|
||||
|
@ -490,7 +506,7 @@ static int vmdk_open_vmdk3(BlockDriverState *bs,
|
|||
}
|
||||
|
||||
static int vmdk_open_desc_file(BlockDriverState *bs, int flags,
|
||||
int64_t desc_offset);
|
||||
uint64_t desc_offset);
|
||||
|
||||
static int vmdk_open_vmdk4(BlockDriverState *bs,
|
||||
BlockDriverState *file,
|
||||
|
@ -508,7 +524,7 @@ static int vmdk_open_vmdk4(BlockDriverState *bs,
|
|||
return ret;
|
||||
}
|
||||
if (header.capacity == 0) {
|
||||
int64_t desc_offset = le64_to_cpu(header.desc_offset);
|
||||
uint64_t desc_offset = le64_to_cpu(header.desc_offset);
|
||||
if (desc_offset) {
|
||||
return vmdk_open_desc_file(bs, flags, desc_offset << 9);
|
||||
}
|
||||
|
@ -570,23 +586,40 @@ static int vmdk_open_vmdk4(BlockDriverState *bs,
|
|||
return -ENOTSUP;
|
||||
}
|
||||
|
||||
l1_entry_sectors = le32_to_cpu(header.num_gtes_per_gte)
|
||||
if (le32_to_cpu(header.num_gtes_per_gt) > 512) {
|
||||
error_report("L2 table size too big");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
l1_entry_sectors = le32_to_cpu(header.num_gtes_per_gt)
|
||||
* le64_to_cpu(header.granularity);
|
||||
if (l1_entry_sectors == 0) {
|
||||
return -EINVAL;
|
||||
}
|
||||
l1_size = (le64_to_cpu(header.capacity) + l1_entry_sectors - 1)
|
||||
/ l1_entry_sectors;
|
||||
if (l1_size > 512 * 1024 * 1024) {
|
||||
/* although with big capacity and small l1_entry_sectors, we can get a
|
||||
* big l1_size, we don't want unbounded value to allocate the table.
|
||||
* Limit it to 512M, which is 16PB for default cluster and L2 table
|
||||
* size */
|
||||
error_report("L1 size too big");
|
||||
return -EFBIG;
|
||||
}
|
||||
if (le32_to_cpu(header.flags) & VMDK4_FLAG_RGD) {
|
||||
l1_backup_offset = le64_to_cpu(header.rgd_offset) << 9;
|
||||
}
|
||||
extent = vmdk_add_extent(bs, file, false,
|
||||
ret = vmdk_add_extent(bs, file, false,
|
||||
le64_to_cpu(header.capacity),
|
||||
le64_to_cpu(header.gd_offset) << 9,
|
||||
l1_backup_offset,
|
||||
l1_size,
|
||||
le32_to_cpu(header.num_gtes_per_gte),
|
||||
le64_to_cpu(header.granularity));
|
||||
le32_to_cpu(header.num_gtes_per_gt),
|
||||
le64_to_cpu(header.granularity),
|
||||
&extent);
|
||||
if (ret < 0) {
|
||||
return ret;
|
||||
}
|
||||
extent->compressed =
|
||||
le16_to_cpu(header.compressAlgorithm) == VMDK4_COMPRESSION_DEFLATE;
|
||||
extent->has_marker = le32_to_cpu(header.flags) & VMDK4_FLAG_MARKER;
|
||||
|
@ -702,8 +735,11 @@ static int vmdk_parse_extents(const char *desc, BlockDriverState *bs,
|
|||
/* FLAT extent */
|
||||
VmdkExtent *extent;
|
||||
|
||||
extent = vmdk_add_extent(bs, extent_file, true, sectors,
|
||||
0, 0, 0, 0, sectors);
|
||||
ret = vmdk_add_extent(bs, extent_file, true, sectors,
|
||||
0, 0, 0, 0, sectors, &extent);
|
||||
if (ret < 0) {
|
||||
return ret;
|
||||
}
|
||||
extent->flat_start_offset = flat_offset << 9;
|
||||
} else if (!strcmp(type, "SPARSE")) {
|
||||
/* SPARSE extent */
|
||||
|
@ -728,7 +764,7 @@ next_line:
|
|||
}
|
||||
|
||||
static int vmdk_open_desc_file(BlockDriverState *bs, int flags,
|
||||
int64_t desc_offset)
|
||||
uint64_t desc_offset)
|
||||
{
|
||||
int ret;
|
||||
char *buf = NULL;
|
||||
|
@ -807,16 +843,17 @@ static int get_whole_cluster(BlockDriverState *bs,
|
|||
uint64_t offset,
|
||||
bool allocate)
|
||||
{
|
||||
/* 128 sectors * 512 bytes each = grain size 64KB */
|
||||
uint8_t whole_grain[extent->cluster_sectors * 512];
|
||||
int ret = VMDK_OK;
|
||||
uint8_t *whole_grain = NULL;
|
||||
|
||||
/* we will be here if it's first write on non-exist grain(cluster).
|
||||
* try to read from parent image, if exist */
|
||||
if (bs->backing_hd) {
|
||||
int ret;
|
||||
|
||||
whole_grain =
|
||||
qemu_blockalign(bs, extent->cluster_sectors << BDRV_SECTOR_BITS);
|
||||
if (!vmdk_is_cid_valid(bs)) {
|
||||
return VMDK_ERROR;
|
||||
ret = VMDK_ERROR;
|
||||
goto exit;
|
||||
}
|
||||
|
||||
/* floor offset to cluster */
|
||||
|
@ -824,17 +861,21 @@ static int get_whole_cluster(BlockDriverState *bs,
|
|||
ret = bdrv_read(bs->backing_hd, offset >> 9, whole_grain,
|
||||
extent->cluster_sectors);
|
||||
if (ret < 0) {
|
||||
return VMDK_ERROR;
|
||||
ret = VMDK_ERROR;
|
||||
goto exit;
|
||||
}
|
||||
|
||||
/* Write grain only into the active image */
|
||||
ret = bdrv_write(extent->file, cluster_offset, whole_grain,
|
||||
extent->cluster_sectors);
|
||||
if (ret < 0) {
|
||||
return VMDK_ERROR;
|
||||
ret = VMDK_ERROR;
|
||||
goto exit;
|
||||
}
|
||||
}
|
||||
return VMDK_OK;
|
||||
exit:
|
||||
qemu_vfree(whole_grain);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int vmdk_L2update(VmdkExtent *extent, VmdkMetaData *m_data)
|
||||
|
@ -1371,12 +1412,12 @@ static int vmdk_create_extent(const char *filename, int64_t filesize,
|
|||
header.compressAlgorithm = compress ? VMDK4_COMPRESSION_DEFLATE : 0;
|
||||
header.capacity = filesize / 512;
|
||||
header.granularity = 128;
|
||||
header.num_gtes_per_gte = 512;
|
||||
header.num_gtes_per_gt = 512;
|
||||
|
||||
grains = (filesize / 512 + header.granularity - 1) / header.granularity;
|
||||
gt_size = ((header.num_gtes_per_gte * sizeof(uint32_t)) + 511) >> 9;
|
||||
gt_size = ((header.num_gtes_per_gt * sizeof(uint32_t)) + 511) >> 9;
|
||||
gt_count =
|
||||
(grains + header.num_gtes_per_gte - 1) / header.num_gtes_per_gte;
|
||||
(grains + header.num_gtes_per_gt - 1) / header.num_gtes_per_gt;
|
||||
gd_size = (gt_count * sizeof(uint32_t) + 511) >> 9;
|
||||
|
||||
header.desc_offset = 1;
|
||||
|
@ -1392,7 +1433,7 @@ static int vmdk_create_extent(const char *filename, int64_t filesize,
|
|||
header.flags = cpu_to_le32(header.flags);
|
||||
header.capacity = cpu_to_le64(header.capacity);
|
||||
header.granularity = cpu_to_le64(header.granularity);
|
||||
header.num_gtes_per_gte = cpu_to_le32(header.num_gtes_per_gte);
|
||||
header.num_gtes_per_gt = cpu_to_le32(header.num_gtes_per_gt);
|
||||
header.desc_offset = cpu_to_le64(header.desc_offset);
|
||||
header.desc_size = cpu_to_le64(header.desc_size);
|
||||
header.rgd_offset = cpu_to_le64(header.rgd_offset);
|
||||
|
|
21
qemu-img.c
21
qemu-img.c
|
@ -396,6 +396,9 @@ static int img_create(int argc, char **argv)
|
|||
}
|
||||
img_size = (uint64_t)sval;
|
||||
}
|
||||
if (optind != argc) {
|
||||
help();
|
||||
}
|
||||
|
||||
if (options && is_help_option(options)) {
|
||||
return print_block_option_help(filename, fmt);
|
||||
|
@ -573,7 +576,7 @@ static int img_check(int argc, char **argv)
|
|||
break;
|
||||
}
|
||||
}
|
||||
if (optind >= argc) {
|
||||
if (optind != argc - 1) {
|
||||
help();
|
||||
}
|
||||
filename = argv[optind++];
|
||||
|
@ -684,7 +687,7 @@ static int img_commit(int argc, char **argv)
|
|||
break;
|
||||
}
|
||||
}
|
||||
if (optind >= argc) {
|
||||
if (optind != argc - 1) {
|
||||
help();
|
||||
}
|
||||
filename = argv[optind++];
|
||||
|
@ -930,7 +933,7 @@ static int img_compare(int argc, char **argv)
|
|||
}
|
||||
|
||||
|
||||
if (optind > argc - 2) {
|
||||
if (optind != argc - 2) {
|
||||
help();
|
||||
}
|
||||
filename1 = argv[optind++];
|
||||
|
@ -1741,7 +1744,7 @@ static int img_info(int argc, char **argv)
|
|||
break;
|
||||
}
|
||||
}
|
||||
if (optind >= argc) {
|
||||
if (optind != argc - 1) {
|
||||
help();
|
||||
}
|
||||
filename = argv[optind++];
|
||||
|
@ -1842,7 +1845,7 @@ static int img_snapshot(int argc, char **argv)
|
|||
}
|
||||
}
|
||||
|
||||
if (optind >= argc) {
|
||||
if (optind != argc - 1) {
|
||||
help();
|
||||
}
|
||||
filename = argv[optind++];
|
||||
|
@ -1953,7 +1956,7 @@ static int img_rebase(int argc, char **argv)
|
|||
progress = 0;
|
||||
}
|
||||
|
||||
if ((optind >= argc) || (!unsafe && !out_baseimg)) {
|
||||
if ((optind != argc - 1) || (!unsafe && !out_baseimg)) {
|
||||
help();
|
||||
}
|
||||
filename = argv[optind++];
|
||||
|
@ -2232,7 +2235,7 @@ static int img_resize(int argc, char **argv)
|
|||
break;
|
||||
}
|
||||
}
|
||||
if (optind >= argc) {
|
||||
if (optind != argc - 1) {
|
||||
help();
|
||||
}
|
||||
filename = argv[optind++];
|
||||
|
@ -2319,6 +2322,10 @@ int main(int argc, char **argv)
|
|||
const img_cmd_t *cmd;
|
||||
const char *cmdname;
|
||||
|
||||
#ifdef CONFIG_POSIX
|
||||
signal(SIGPIPE, SIG_IGN);
|
||||
#endif
|
||||
|
||||
error_set_progname(argv[0]);
|
||||
|
||||
qemu_init_main_loop();
|
||||
|
|
|
@ -335,6 +335,10 @@ int main(int argc, char **argv)
|
|||
int opt_index = 0;
|
||||
int flags = BDRV_O_UNMAP;
|
||||
|
||||
#ifdef CONFIG_POSIX
|
||||
signal(SIGPIPE, SIG_IGN);
|
||||
#endif
|
||||
|
||||
progname = basename(argv[0]);
|
||||
|
||||
while ((c = getopt_long(argc, argv, sopt, lopt, &opt_index)) != -1) {
|
||||
|
|
|
@ -23,11 +23,11 @@ QEMU_PROG: -drive file=TEST_DIR/t.qcow2,format=qcow2,unknown_opt=foo: could not
|
|||
=== Enable and disable lazy refcounting on the command line, plus some invalid values ===
|
||||
|
||||
Testing: -drive file=TEST_DIR/t.qcow2,format=qcow2,lazy-refcounts=on
|
||||
QEMU 1.5.50 monitor - type 'help' for more information
|
||||
QEMU X.Y.Z monitor - type 'help' for more information
|
||||
(qemu) q[K[Dqu[K[D[Dqui[K[D[D[Dquit[K
|
||||
|
||||
Testing: -drive file=TEST_DIR/t.qcow2,format=qcow2,lazy-refcounts=off
|
||||
QEMU 1.5.50 monitor - type 'help' for more information
|
||||
QEMU X.Y.Z monitor - type 'help' for more information
|
||||
(qemu) q[K[Dqu[K[D[Dqui[K[D[D[Dquit[K
|
||||
|
||||
Testing: -drive file=TEST_DIR/t.qcow2,format=qcow2,lazy-refcounts=
|
||||
|
@ -51,72 +51,72 @@ QEMU_PROG: -drive file=TEST_DIR/t.qcow2,format=qcow2,lazy-refcounts=on: Lazy ref
|
|||
QEMU_PROG: -drive file=TEST_DIR/t.qcow2,format=qcow2,lazy-refcounts=on: could not open disk image TEST_DIR/t.qcow2: Invalid argument
|
||||
|
||||
Testing: -drive file=TEST_DIR/t.qcow2,format=qcow2,lazy-refcounts=off
|
||||
QEMU 1.5.50 monitor - type 'help' for more information
|
||||
QEMU X.Y.Z monitor - type 'help' for more information
|
||||
(qemu) q[K[Dqu[K[D[Dqui[K[D[D[Dquit[K
|
||||
|
||||
|
||||
=== No medium ===
|
||||
|
||||
Testing: -drive if=floppy
|
||||
QEMU 1.5.50 monitor - type 'help' for more information
|
||||
QEMU X.Y.Z monitor - type 'help' for more information
|
||||
(qemu) q[K[Dqu[K[D[Dqui[K[D[D[Dquit[K
|
||||
|
||||
Testing: -drive if=ide,media=cdrom
|
||||
QEMU 1.5.50 monitor - type 'help' for more information
|
||||
QEMU X.Y.Z monitor - type 'help' for more information
|
||||
(qemu) q[K[Dqu[K[D[Dqui[K[D[D[Dquit[K
|
||||
|
||||
Testing: -drive if=scsi,media=cdrom
|
||||
QEMU 1.5.50 monitor - type 'help' for more information
|
||||
QEMU X.Y.Z monitor - type 'help' for more information
|
||||
(qemu) q[K[Dqu[K[D[Dqui[K[D[D[Dquit[K
|
||||
|
||||
Testing: -drive if=ide
|
||||
QEMU 1.5.50 monitor - type 'help' for more information
|
||||
QEMU X.Y.Z monitor - type 'help' for more information
|
||||
(qemu) QEMU_PROG: Device needs media, but drive is empty
|
||||
QEMU_PROG: Device initialization failed.
|
||||
QEMU_PROG: Initialization of device ide-hd failed
|
||||
|
||||
Testing: -drive if=virtio
|
||||
QEMU 1.5.50 monitor - type 'help' for more information
|
||||
QEMU X.Y.Z monitor - type 'help' for more information
|
||||
(qemu) QEMU_PROG: -drive if=virtio: Device needs media, but drive is empty
|
||||
QEMU_PROG: -drive if=virtio: Device initialization failed.
|
||||
QEMU_PROG: -drive if=virtio: Device initialization failed.
|
||||
QEMU_PROG: -drive if=virtio: Device 'virtio-blk-pci' could not be initialized
|
||||
|
||||
Testing: -drive if=scsi
|
||||
QEMU 1.5.50 monitor - type 'help' for more information
|
||||
QEMU X.Y.Z monitor - type 'help' for more information
|
||||
(qemu) QEMU_PROG: -drive if=scsi: Device needs media, but drive is empty
|
||||
QEMU_PROG: -drive if=scsi: Device initialization failed.
|
||||
QEMU_PROG: Device initialization failed.
|
||||
QEMU_PROG: Initialization of device lsi53c895a failed
|
||||
|
||||
Testing: -drive if=none,id=disk -device ide-cd,drive=disk
|
||||
QEMU 1.5.50 monitor - type 'help' for more information
|
||||
QEMU X.Y.Z monitor - type 'help' for more information
|
||||
(qemu) q[K[Dqu[K[D[Dqui[K[D[D[Dquit[K
|
||||
|
||||
Testing: -drive if=none,id=disk -device lsi53c895a -device scsi-cd,drive=disk
|
||||
QEMU 1.5.50 monitor - type 'help' for more information
|
||||
QEMU X.Y.Z monitor - type 'help' for more information
|
||||
(qemu) q[K[Dqu[K[D[Dqui[K[D[D[Dquit[K
|
||||
|
||||
Testing: -drive if=none,id=disk -device ide-drive,drive=disk
|
||||
QEMU 1.5.50 monitor - type 'help' for more information
|
||||
QEMU X.Y.Z monitor - type 'help' for more information
|
||||
(qemu) QEMU_PROG: -device ide-drive,drive=disk: Device needs media, but drive is empty
|
||||
QEMU_PROG: -device ide-drive,drive=disk: Device initialization failed.
|
||||
QEMU_PROG: -device ide-drive,drive=disk: Device 'ide-drive' could not be initialized
|
||||
|
||||
Testing: -drive if=none,id=disk -device ide-hd,drive=disk
|
||||
QEMU 1.5.50 monitor - type 'help' for more information
|
||||
QEMU X.Y.Z monitor - type 'help' for more information
|
||||
(qemu) QEMU_PROG: -device ide-hd,drive=disk: Device needs media, but drive is empty
|
||||
QEMU_PROG: -device ide-hd,drive=disk: Device initialization failed.
|
||||
QEMU_PROG: -device ide-hd,drive=disk: Device 'ide-hd' could not be initialized
|
||||
|
||||
Testing: -drive if=none,id=disk -device lsi53c895a -device scsi-disk,drive=disk
|
||||
QEMU 1.5.50 monitor - type 'help' for more information
|
||||
QEMU X.Y.Z monitor - type 'help' for more information
|
||||
(qemu) QEMU_PROG: -device scsi-disk,drive=disk: Device needs media, but drive is empty
|
||||
QEMU_PROG: -device scsi-disk,drive=disk: Device initialization failed.
|
||||
QEMU_PROG: -device scsi-disk,drive=disk: Device 'scsi-disk' could not be initialized
|
||||
|
||||
Testing: -drive if=none,id=disk -device lsi53c895a -device scsi-hd,drive=disk
|
||||
QEMU 1.5.50 monitor - type 'help' for more information
|
||||
QEMU X.Y.Z monitor - type 'help' for more information
|
||||
(qemu) QEMU_PROG: -device scsi-hd,drive=disk: Device needs media, but drive is empty
|
||||
QEMU_PROG: -device scsi-hd,drive=disk: Device initialization failed.
|
||||
QEMU_PROG: -device scsi-hd,drive=disk: Device 'scsi-hd' could not be initialized
|
||||
|
@ -125,77 +125,77 @@ QEMU_PROG: -device scsi-hd,drive=disk: Device 'scsi-hd' could not be initialized
|
|||
=== Read-only ===
|
||||
|
||||
Testing: -drive file=TEST_DIR/t.qcow2,if=floppy,readonly=on
|
||||
QEMU 1.5.50 monitor - type 'help' for more information
|
||||
QEMU X.Y.Z monitor - type 'help' for more information
|
||||
(qemu) q[K[Dqu[K[D[Dqui[K[D[D[Dquit[K
|
||||
|
||||
Testing: -drive file=TEST_DIR/t.qcow2,if=ide,media=cdrom,readonly=on
|
||||
QEMU 1.5.50 monitor - type 'help' for more information
|
||||
QEMU X.Y.Z monitor - type 'help' for more information
|
||||
(qemu) q[K[Dqu[K[D[Dqui[K[D[D[Dquit[K
|
||||
|
||||
Testing: -drive file=TEST_DIR/t.qcow2,if=scsi,media=cdrom,readonly=on
|
||||
QEMU 1.5.50 monitor - type 'help' for more information
|
||||
QEMU X.Y.Z monitor - type 'help' for more information
|
||||
(qemu) q[K[Dqu[K[D[Dqui[K[D[D[Dquit[K
|
||||
|
||||
Testing: -drive file=TEST_DIR/t.qcow2,if=ide,readonly=on
|
||||
QEMU_PROG: -drive file=TEST_DIR/t.qcow2,if=ide,readonly=on: read-only not supported by this bus type
|
||||
|
||||
Testing: -drive file=TEST_DIR/t.qcow2,if=virtio,readonly=on
|
||||
QEMU 1.5.50 monitor - type 'help' for more information
|
||||
QEMU X.Y.Z monitor - type 'help' for more information
|
||||
(qemu) q[K[Dqu[K[D[Dqui[K[D[D[Dquit[K
|
||||
|
||||
Testing: -drive file=TEST_DIR/t.qcow2,if=scsi,readonly=on
|
||||
QEMU 1.5.50 monitor - type 'help' for more information
|
||||
QEMU X.Y.Z monitor - type 'help' for more information
|
||||
(qemu) q[K[Dqu[K[D[Dqui[K[D[D[Dquit[K
|
||||
|
||||
Testing: -drive file=TEST_DIR/t.qcow2,if=none,id=disk,readonly=on -device ide-cd,drive=disk
|
||||
QEMU 1.5.50 monitor - type 'help' for more information
|
||||
QEMU X.Y.Z monitor - type 'help' for more information
|
||||
(qemu) q[K[Dqu[K[D[Dqui[K[D[D[Dquit[K
|
||||
|
||||
Testing: -drive file=TEST_DIR/t.qcow2,if=none,id=disk,readonly=on -device lsi53c895a -device scsi-cd,drive=disk
|
||||
QEMU 1.5.50 monitor - type 'help' for more information
|
||||
QEMU X.Y.Z monitor - type 'help' for more information
|
||||
(qemu) q[K[Dqu[K[D[Dqui[K[D[D[Dquit[K
|
||||
|
||||
Testing: -drive file=TEST_DIR/t.qcow2,if=none,id=disk,readonly=on -device ide-drive,drive=disk
|
||||
QEMU 1.5.50 monitor - type 'help' for more information
|
||||
QEMU X.Y.Z monitor - type 'help' for more information
|
||||
(qemu) QEMU_PROG: -device ide-drive,drive=disk: Can't use a read-only drive
|
||||
QEMU_PROG: -device ide-drive,drive=disk: Device initialization failed.
|
||||
QEMU_PROG: -device ide-drive,drive=disk: Device 'ide-drive' could not be initialized
|
||||
|
||||
Testing: -drive file=TEST_DIR/t.qcow2,if=none,id=disk,readonly=on -device ide-hd,drive=disk
|
||||
QEMU 1.5.50 monitor - type 'help' for more information
|
||||
QEMU X.Y.Z monitor - type 'help' for more information
|
||||
(qemu) QEMU_PROG: -device ide-hd,drive=disk: Can't use a read-only drive
|
||||
QEMU_PROG: -device ide-hd,drive=disk: Device initialization failed.
|
||||
QEMU_PROG: -device ide-hd,drive=disk: Device 'ide-hd' could not be initialized
|
||||
|
||||
Testing: -drive file=TEST_DIR/t.qcow2,if=none,id=disk,readonly=on -device lsi53c895a -device scsi-disk,drive=disk
|
||||
QEMU 1.5.50 monitor - type 'help' for more information
|
||||
QEMU X.Y.Z monitor - type 'help' for more information
|
||||
(qemu) q[K[Dqu[K[D[Dqui[K[D[D[Dquit[K
|
||||
|
||||
Testing: -drive file=TEST_DIR/t.qcow2,if=none,id=disk,readonly=on -device lsi53c895a -device scsi-hd,drive=disk
|
||||
QEMU 1.5.50 monitor - type 'help' for more information
|
||||
QEMU X.Y.Z monitor - type 'help' for more information
|
||||
(qemu) q[K[Dqu[K[D[Dqui[K[D[D[Dquit[K
|
||||
|
||||
|
||||
=== Cache modes ===
|
||||
|
||||
Testing: -drive media=cdrom,cache=none
|
||||
QEMU 1.5.50 monitor - type 'help' for more information
|
||||
QEMU X.Y.Z monitor - type 'help' for more information
|
||||
(qemu) q[K[Dqu[K[D[Dqui[K[D[D[Dquit[K
|
||||
|
||||
Testing: -drive media=cdrom,cache=directsync
|
||||
QEMU 1.5.50 monitor - type 'help' for more information
|
||||
QEMU X.Y.Z monitor - type 'help' for more information
|
||||
(qemu) q[K[Dqu[K[D[Dqui[K[D[D[Dquit[K
|
||||
|
||||
Testing: -drive media=cdrom,cache=writeback
|
||||
QEMU 1.5.50 monitor - type 'help' for more information
|
||||
QEMU X.Y.Z monitor - type 'help' for more information
|
||||
(qemu) q[K[Dqu[K[D[Dqui[K[D[D[Dquit[K
|
||||
|
||||
Testing: -drive media=cdrom,cache=writethrough
|
||||
QEMU 1.5.50 monitor - type 'help' for more information
|
||||
QEMU X.Y.Z monitor - type 'help' for more information
|
||||
(qemu) q[K[Dqu[K[D[Dqui[K[D[D[Dquit[K
|
||||
|
||||
Testing: -drive media=cdrom,cache=unsafe
|
||||
QEMU 1.5.50 monitor - type 'help' for more information
|
||||
QEMU X.Y.Z monitor - type 'help' for more information
|
||||
(qemu) q[K[Dqu[K[D[Dqui[K[D[D[Dquit[K
|
||||
|
||||
Testing: -drive media=cdrom,cache=invalid_value
|
||||
|
@ -205,7 +205,7 @@ QEMU_PROG: -drive media=cdrom,cache=invalid_value: invalid cache option
|
|||
=== Specifying the protocol layer ===
|
||||
|
||||
Testing: -drive file=TEST_DIR/t.qcow2,file.driver=file
|
||||
QEMU 1.5.50 monitor - type 'help' for more information
|
||||
QEMU X.Y.Z monitor - type 'help' for more information
|
||||
(qemu) q[K[Dqu[K[D[Dqui[K[D[D[Dquit[K
|
||||
|
||||
Testing: -drive file=TEST_DIR/t.qcow2,file.driver=qcow2
|
||||
|
|
|
@ -0,0 +1,72 @@
|
|||
#!/bin/bash
|
||||
#
|
||||
# Test case for vmdk
|
||||
#
|
||||
# Copyright (C) 2013 Red Hat, Inc.
|
||||
#
|
||||
# This program is free software; you can redistribute it and/or modify
|
||||
# it under the terms of the GNU General Public License as published by
|
||||
# the Free Software Foundation; either version 2 of the License, or
|
||||
# (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
#
|
||||
|
||||
# creator
|
||||
owner=famz@redhat.com
|
||||
|
||||
seq=`basename $0`
|
||||
echo "QA output created by $seq"
|
||||
|
||||
here=`pwd`
|
||||
tmp=/tmp/$$
|
||||
status=1 # failure is the default!
|
||||
|
||||
_cleanup()
|
||||
{
|
||||
_cleanup_test_img
|
||||
}
|
||||
trap "_cleanup; exit \$status" 0 1 2 3 15
|
||||
|
||||
# get standard environment, filters and checks
|
||||
. ./common.rc
|
||||
. ./common.filter
|
||||
|
||||
# This tests vmdk-specific low-level functionality
|
||||
_supported_fmt vmdk
|
||||
_supported_proto generic
|
||||
_supported_os Linux
|
||||
|
||||
capacity_offset=16
|
||||
granularity_offset=20
|
||||
grain_table_size_offset=44
|
||||
|
||||
echo "=== Testing invalid granularity ==="
|
||||
echo
|
||||
_make_test_img 64M
|
||||
poke_file "$TEST_IMG" "$granularity_offset" "\xff\xff\xff\xff\xff\xff\xff\xff"
|
||||
{ $QEMU_IO -c "read 0 512" $TEST_IMG; } 2>&1 | _filter_qemu_io | _filter_testdir
|
||||
|
||||
echo "=== Testing too big L2 table size ==="
|
||||
echo
|
||||
_make_test_img 64M
|
||||
poke_file "$TEST_IMG" "$grain_table_size_offset" "\xff\xff\xff\xff"
|
||||
{ $QEMU_IO -c "read 0 512" $TEST_IMG; } 2>&1 | _filter_qemu_io | _filter_testdir
|
||||
|
||||
echo "=== Testing too big L1 table size ==="
|
||||
echo
|
||||
_make_test_img 64M
|
||||
poke_file "$TEST_IMG" "$capacity_offset" "\xff\xff\xff\xff"
|
||||
poke_file "$TEST_IMG" "$grain_table_size_offset" "\x01\x00\x00\x00"
|
||||
{ $QEMU_IO -c "read 0 512" $TEST_IMG; } 2>&1 | _filter_qemu_io | _filter_testdir
|
||||
|
||||
# success, all done
|
||||
echo "*** done"
|
||||
rm -f $seq.full
|
||||
status=0
|
|
@ -0,0 +1,20 @@
|
|||
QA output created by 059
|
||||
=== Testing invalid granularity ===
|
||||
|
||||
Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=67108864
|
||||
invalid granularity, image may be corrupt
|
||||
qemu-io: can't open device TEST_DIR/t.vmdk
|
||||
no file open, try 'help open'
|
||||
=== Testing too big L2 table size ===
|
||||
|
||||
Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=67108864
|
||||
L2 table size too big
|
||||
qemu-io: can't open device TEST_DIR/t.vmdk
|
||||
no file open, try 'help open'
|
||||
=== Testing too big L1 table size ===
|
||||
|
||||
Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=67108864
|
||||
L1 size too big
|
||||
qemu-io: can't open device TEST_DIR/t.vmdk
|
||||
no file open, try 'help open'
|
||||
*** done
|
|
@ -155,7 +155,8 @@ _filter_qemu_io()
|
|||
# replace occurrences of QEMU_PROG with "qemu"
|
||||
_filter_qemu()
|
||||
{
|
||||
sed -e "s#\\(^\\|(qemu) \\)$(basename $QEMU_PROG):#\1QEMU_PROG:#"
|
||||
sed -e "s#\\(^\\|(qemu) \\)$(basename $QEMU_PROG):#\1QEMU_PROG:#" \
|
||||
-e 's#^QEMU [0-9]\+\.[0-9]\+\.[0-9]\+ monitor#QEMU X.Y.Z monitor#'
|
||||
}
|
||||
|
||||
# make sure this script returns success
|
||||
|
|
|
@ -34,6 +34,12 @@ dd()
|
|||
fi
|
||||
}
|
||||
|
||||
# poke_file 'test.img' 512 '\xff\xfe'
|
||||
poke_file()
|
||||
{
|
||||
printf "$3" | dd "of=$1" bs=1 "seek=$2" conv=notrunc &>/dev/null
|
||||
}
|
||||
|
||||
# we need common.config
|
||||
if [ "$iam" != "check" ]
|
||||
then
|
||||
|
|
|
@ -63,3 +63,4 @@
|
|||
054 rw auto
|
||||
055 rw auto
|
||||
056 rw auto backing
|
||||
059 rw auto
|
||||
|
|
|
@ -202,6 +202,12 @@ ssize_t iov_send_recv(int sockfd, struct iovec *iov, unsigned iov_cnt,
|
|||
return -1;
|
||||
}
|
||||
|
||||
if (ret == 0 && !do_send) {
|
||||
/* recv returns 0 when the peer has performed an orderly
|
||||
* shutdown. */
|
||||
break;
|
||||
}
|
||||
|
||||
/* Prepare for the next iteration */
|
||||
offset += ret;
|
||||
total += ret;
|
||||
|
|
Loading…
Reference in New Issue