Compare commits
46 Commits
pull-input
...
pull-usb-2
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
a49923d283 | ||
|
|
1ae3f2f178 | ||
|
|
c6c598ca5f | ||
|
|
3424c8a9c8 | ||
|
|
072035eba1 | ||
|
|
c7b45f1282 | ||
|
|
cdc8845331 | ||
|
|
d1129a8ad9 | ||
|
|
23994a5f52 | ||
|
|
200650d49f | ||
|
|
e71fc0bae7 | ||
|
|
5f1525a685 | ||
|
|
339f06a3bc | ||
|
|
6bb6f6cd9e | ||
|
|
242fbc19ef | ||
|
|
bc78a01319 | ||
|
|
90c647db8d | ||
|
|
16aaf975ee | ||
|
|
9c057d0b68 | ||
|
|
32f6439cf7 | ||
|
|
66176fc6a7 | ||
|
|
c23fb11bbb | ||
|
|
bab246db1d | ||
|
|
9bdfb9e8ac | ||
|
|
0211b9becc | ||
|
|
7fa84cd8d4 | ||
|
|
5ceb77652e | ||
|
|
538a467329 | ||
|
|
de5f107744 | ||
|
|
01a780d51a | ||
|
|
bc8995cafa | ||
|
|
3e7cac31d6 | ||
|
|
01310e2aa7 | ||
|
|
33e5702889 | ||
|
|
8b4aaba736 | ||
|
|
e7658fcc4c | ||
|
|
52e38eb051 | ||
|
|
2b1c2e8e5f | ||
|
|
c954f09ee5 | ||
|
|
09230cb867 | ||
|
|
c0bc0fa352 | ||
|
|
6dc64780c2 | ||
|
|
502356eeeb | ||
|
|
9a41826f38 | ||
|
|
218fd37c68 | ||
|
|
d1fc684f36 |
@@ -121,11 +121,19 @@ file_backend_instance_init(Object *o)
|
||||
set_mem_path, NULL);
|
||||
}
|
||||
|
||||
static void file_backend_instance_finalize(Object *o)
|
||||
{
|
||||
HostMemoryBackendFile *fb = MEMORY_BACKEND_FILE(o);
|
||||
|
||||
g_free(fb->mem_path);
|
||||
}
|
||||
|
||||
static const TypeInfo file_backend_info = {
|
||||
.name = TYPE_MEMORY_BACKEND_FILE,
|
||||
.parent = TYPE_MEMORY_BACKEND,
|
||||
.class_init = file_backend_class_init,
|
||||
.instance_init = file_backend_instance_init,
|
||||
.instance_finalize = file_backend_instance_finalize,
|
||||
.instance_size = sizeof(HostMemoryBackendFile),
|
||||
};
|
||||
|
||||
|
||||
@@ -820,7 +820,7 @@ int blk_write_zeroes(BlockBackend *blk, int64_t sector_num,
|
||||
int nb_sectors, BdrvRequestFlags flags)
|
||||
{
|
||||
return blk_rw(blk, sector_num, NULL, nb_sectors, blk_write_entry,
|
||||
BDRV_REQ_ZERO_WRITE);
|
||||
flags | BDRV_REQ_ZERO_WRITE);
|
||||
}
|
||||
|
||||
static void error_callback_bh(void *opaque)
|
||||
@@ -852,6 +852,7 @@ BlockAIOCB *blk_abort_aio_request(BlockBackend *blk,
|
||||
typedef struct BlkAioEmAIOCB {
|
||||
BlockAIOCB common;
|
||||
BlkRwCo rwco;
|
||||
int bytes;
|
||||
bool has_returned;
|
||||
QEMUBH* bh;
|
||||
} BlkAioEmAIOCB;
|
||||
@@ -877,7 +878,7 @@ static void blk_aio_complete_bh(void *opaque)
|
||||
blk_aio_complete(opaque);
|
||||
}
|
||||
|
||||
static BlockAIOCB *blk_aio_prwv(BlockBackend *blk, int64_t offset,
|
||||
static BlockAIOCB *blk_aio_prwv(BlockBackend *blk, int64_t offset, int bytes,
|
||||
QEMUIOVector *qiov, CoroutineEntry co_entry,
|
||||
BdrvRequestFlags flags,
|
||||
BlockCompletionFunc *cb, void *opaque)
|
||||
@@ -893,6 +894,7 @@ static BlockAIOCB *blk_aio_prwv(BlockBackend *blk, int64_t offset,
|
||||
.flags = flags,
|
||||
.ret = NOT_DONE,
|
||||
};
|
||||
acb->bytes = bytes;
|
||||
acb->bh = NULL;
|
||||
acb->has_returned = false;
|
||||
|
||||
@@ -913,7 +915,8 @@ static void blk_aio_read_entry(void *opaque)
|
||||
BlkAioEmAIOCB *acb = opaque;
|
||||
BlkRwCo *rwco = &acb->rwco;
|
||||
|
||||
rwco->ret = blk_co_preadv(rwco->blk, rwco->offset, rwco->qiov->size,
|
||||
assert(rwco->qiov->size == acb->bytes);
|
||||
rwco->ret = blk_co_preadv(rwco->blk, rwco->offset, acb->bytes,
|
||||
rwco->qiov, rwco->flags);
|
||||
blk_aio_complete(acb);
|
||||
}
|
||||
@@ -923,8 +926,8 @@ static void blk_aio_write_entry(void *opaque)
|
||||
BlkAioEmAIOCB *acb = opaque;
|
||||
BlkRwCo *rwco = &acb->rwco;
|
||||
|
||||
rwco->ret = blk_co_pwritev(rwco->blk, rwco->offset,
|
||||
rwco->qiov ? rwco->qiov->size : 0,
|
||||
assert(!rwco->qiov || rwco->qiov->size == acb->bytes);
|
||||
rwco->ret = blk_co_pwritev(rwco->blk, rwco->offset, acb->bytes,
|
||||
rwco->qiov, rwco->flags);
|
||||
blk_aio_complete(acb);
|
||||
}
|
||||
@@ -937,8 +940,10 @@ BlockAIOCB *blk_aio_write_zeroes(BlockBackend *blk, int64_t sector_num,
|
||||
return blk_abort_aio_request(blk, cb, opaque, -EINVAL);
|
||||
}
|
||||
|
||||
return blk_aio_prwv(blk, sector_num << BDRV_SECTOR_BITS, NULL,
|
||||
blk_aio_write_entry, BDRV_REQ_ZERO_WRITE, cb, opaque);
|
||||
return blk_aio_prwv(blk, sector_num << BDRV_SECTOR_BITS,
|
||||
nb_sectors << BDRV_SECTOR_BITS, NULL,
|
||||
blk_aio_write_entry, flags | BDRV_REQ_ZERO_WRITE,
|
||||
cb, opaque);
|
||||
}
|
||||
|
||||
int blk_pread(BlockBackend *blk, int64_t offset, void *buf, int count)
|
||||
@@ -994,7 +999,8 @@ BlockAIOCB *blk_aio_readv(BlockBackend *blk, int64_t sector_num,
|
||||
return blk_abort_aio_request(blk, cb, opaque, -EINVAL);
|
||||
}
|
||||
|
||||
return blk_aio_prwv(blk, sector_num << BDRV_SECTOR_BITS, iov,
|
||||
assert(nb_sectors << BDRV_SECTOR_BITS == iov->size);
|
||||
return blk_aio_prwv(blk, sector_num << BDRV_SECTOR_BITS, iov->size, iov,
|
||||
blk_aio_read_entry, 0, cb, opaque);
|
||||
}
|
||||
|
||||
@@ -1006,7 +1012,8 @@ BlockAIOCB *blk_aio_writev(BlockBackend *blk, int64_t sector_num,
|
||||
return blk_abort_aio_request(blk, cb, opaque, -EINVAL);
|
||||
}
|
||||
|
||||
return blk_aio_prwv(blk, sector_num << BDRV_SECTOR_BITS, iov,
|
||||
assert(nb_sectors << BDRV_SECTOR_BITS == iov->size);
|
||||
return blk_aio_prwv(blk, sector_num << BDRV_SECTOR_BITS, iov->size, iov,
|
||||
blk_aio_write_entry, 0, cb, opaque);
|
||||
}
|
||||
|
||||
@@ -1446,7 +1453,7 @@ int coroutine_fn blk_co_write_zeroes(BlockBackend *blk, int64_t sector_num,
|
||||
|
||||
return blk_co_pwritev(blk, sector_num << BDRV_SECTOR_BITS,
|
||||
nb_sectors << BDRV_SECTOR_BITS, NULL,
|
||||
BDRV_REQ_ZERO_WRITE);
|
||||
flags | BDRV_REQ_ZERO_WRITE);
|
||||
}
|
||||
|
||||
int blk_write_compressed(BlockBackend *blk, int64_t sector_num,
|
||||
|
||||
102
block/vpc.c
102
block/vpc.c
@@ -45,34 +45,34 @@ enum vhd_type {
|
||||
VHD_DIFFERENCING = 4,
|
||||
};
|
||||
|
||||
// Seconds since Jan 1, 2000 0:00:00 (UTC)
|
||||
/* Seconds since Jan 1, 2000 0:00:00 (UTC) */
|
||||
#define VHD_TIMESTAMP_BASE 946684800
|
||||
|
||||
#define VHD_CHS_MAX_C 65535LL
|
||||
#define VHD_CHS_MAX_H 16
|
||||
#define VHD_CHS_MAX_S 255
|
||||
|
||||
#define VHD_MAX_SECTORS (65535LL * 255 * 255)
|
||||
#define VHD_MAX_SECTORS 0xff000000 /* 2040 GiB max image size */
|
||||
#define VHD_MAX_GEOMETRY (VHD_CHS_MAX_C * VHD_CHS_MAX_H * VHD_CHS_MAX_S)
|
||||
|
||||
#define VPC_OPT_FORCE_SIZE "force_size"
|
||||
|
||||
// always big-endian
|
||||
/* always big-endian */
|
||||
typedef struct vhd_footer {
|
||||
char creator[8]; // "conectix"
|
||||
char creator[8]; /* "conectix" */
|
||||
uint32_t features;
|
||||
uint32_t version;
|
||||
|
||||
// Offset of next header structure, 0xFFFFFFFF if none
|
||||
/* Offset of next header structure, 0xFFFFFFFF if none */
|
||||
uint64_t data_offset;
|
||||
|
||||
// Seconds since Jan 1, 2000 0:00:00 (UTC)
|
||||
/* Seconds since Jan 1, 2000 0:00:00 (UTC) */
|
||||
uint32_t timestamp;
|
||||
|
||||
char creator_app[4]; // "vpc "
|
||||
char creator_app[4]; /* e.g., "vpc " */
|
||||
uint16_t major;
|
||||
uint16_t minor;
|
||||
char creator_os[4]; // "Wi2k"
|
||||
char creator_os[4]; /* "Wi2k" */
|
||||
|
||||
uint64_t orig_size;
|
||||
uint64_t current_size;
|
||||
@@ -83,29 +83,29 @@ typedef struct vhd_footer {
|
||||
|
||||
uint32_t type;
|
||||
|
||||
// Checksum of the Hard Disk Footer ("one's complement of the sum of all
|
||||
// the bytes in the footer without the checksum field")
|
||||
/* Checksum of the Hard Disk Footer ("one's complement of the sum of all
|
||||
the bytes in the footer without the checksum field") */
|
||||
uint32_t checksum;
|
||||
|
||||
// UUID used to identify a parent hard disk (backing file)
|
||||
/* UUID used to identify a parent hard disk (backing file) */
|
||||
uint8_t uuid[16];
|
||||
|
||||
uint8_t in_saved_state;
|
||||
} QEMU_PACKED VHDFooter;
|
||||
|
||||
typedef struct vhd_dyndisk_header {
|
||||
char magic[8]; // "cxsparse"
|
||||
char magic[8]; /* "cxsparse" */
|
||||
|
||||
// Offset of next header structure, 0xFFFFFFFF if none
|
||||
/* Offset of next header structure, 0xFFFFFFFF if none */
|
||||
uint64_t data_offset;
|
||||
|
||||
// Offset of the Block Allocation Table (BAT)
|
||||
/* Offset of the Block Allocation Table (BAT) */
|
||||
uint64_t table_offset;
|
||||
|
||||
uint32_t version;
|
||||
uint32_t max_table_entries; // 32bit/entry
|
||||
uint32_t max_table_entries; /* 32bit/entry */
|
||||
|
||||
// 2 MB by default, must be a power of two
|
||||
/* 2 MB by default, must be a power of two */
|
||||
uint32_t block_size;
|
||||
|
||||
uint32_t checksum;
|
||||
@@ -113,7 +113,7 @@ typedef struct vhd_dyndisk_header {
|
||||
uint32_t parent_timestamp;
|
||||
uint32_t reserved;
|
||||
|
||||
// Backing file name (in UTF-16)
|
||||
/* Backing file name (in UTF-16) */
|
||||
uint8_t parent_name[512];
|
||||
|
||||
struct {
|
||||
@@ -238,6 +238,7 @@ static int vpc_open(BlockDriverState *bs, QDict *options, int flags,
|
||||
|
||||
ret = bdrv_pread(bs->file->bs, 0, s->footer_buf, HEADER_SIZE);
|
||||
if (ret < 0) {
|
||||
error_setg(errp, "Unable to read VHD header");
|
||||
goto fail;
|
||||
}
|
||||
|
||||
@@ -246,9 +247,11 @@ static int vpc_open(BlockDriverState *bs, QDict *options, int flags,
|
||||
int64_t offset = bdrv_getlength(bs->file->bs);
|
||||
if (offset < 0) {
|
||||
ret = offset;
|
||||
error_setg(errp, "Invalid file size");
|
||||
goto fail;
|
||||
} else if (offset < HEADER_SIZE) {
|
||||
ret = -EINVAL;
|
||||
error_setg(errp, "File too small for a VHD header");
|
||||
goto fail;
|
||||
}
|
||||
|
||||
@@ -275,9 +278,9 @@ static int vpc_open(BlockDriverState *bs, QDict *options, int flags,
|
||||
/* Write 'checksum' back to footer, or else will leave it with zero. */
|
||||
footer->checksum = cpu_to_be32(checksum);
|
||||
|
||||
// The visible size of a image in Virtual PC depends on the geometry
|
||||
// rather than on the size stored in the footer (the size in the footer
|
||||
// is too large usually)
|
||||
/* The visible size of a image in Virtual PC depends on the geometry
|
||||
rather than on the size stored in the footer (the size in the footer
|
||||
is too large usually) */
|
||||
bs->total_sectors = (int64_t)
|
||||
be16_to_cpu(footer->cyls) * footer->heads * footer->secs_per_cyl;
|
||||
|
||||
@@ -299,6 +302,8 @@ static int vpc_open(BlockDriverState *bs, QDict *options, int flags,
|
||||
* 'qem2' : current_size QEMU (uses current_size)
|
||||
* 'win ' : current_size Hyper-V
|
||||
* 'd2v ' : current_size Disk2vhd
|
||||
* 'tap\0' : current_size XenServer
|
||||
* 'CTXS' : current_size XenConverter
|
||||
*
|
||||
* The user can override the table values via drive options, however
|
||||
* even with an override we will still use current_size for images
|
||||
@@ -306,15 +311,17 @@ static int vpc_open(BlockDriverState *bs, QDict *options, int flags,
|
||||
*/
|
||||
use_chs = (!!strncmp(footer->creator_app, "win ", 4) &&
|
||||
!!strncmp(footer->creator_app, "qem2", 4) &&
|
||||
!!strncmp(footer->creator_app, "d2v ", 4)) || s->force_use_chs;
|
||||
!!strncmp(footer->creator_app, "d2v ", 4) &&
|
||||
!!strncmp(footer->creator_app, "CTXS", 4) &&
|
||||
!!memcmp(footer->creator_app, "tap", 4)) || s->force_use_chs;
|
||||
|
||||
if (!use_chs || bs->total_sectors == VHD_MAX_GEOMETRY || s->force_use_sz) {
|
||||
bs->total_sectors = be64_to_cpu(footer->current_size) /
|
||||
BDRV_SECTOR_SIZE;
|
||||
}
|
||||
|
||||
/* Allow a maximum disk size of approximately 2 TB */
|
||||
if (bs->total_sectors >= VHD_MAX_SECTORS) {
|
||||
/* Allow a maximum disk size of 2040 GiB */
|
||||
if (bs->total_sectors > VHD_MAX_SECTORS) {
|
||||
ret = -EFBIG;
|
||||
goto fail;
|
||||
}
|
||||
@@ -323,12 +330,14 @@ static int vpc_open(BlockDriverState *bs, QDict *options, int flags,
|
||||
ret = bdrv_pread(bs->file->bs, be64_to_cpu(footer->data_offset), buf,
|
||||
HEADER_SIZE);
|
||||
if (ret < 0) {
|
||||
error_setg(errp, "Error reading dynamic VHD header");
|
||||
goto fail;
|
||||
}
|
||||
|
||||
dyndisk_header = (VHDDynDiskHeader *) buf;
|
||||
|
||||
if (strncmp(dyndisk_header->magic, "cxsparse", 8)) {
|
||||
error_setg(errp, "Invalid header magic");
|
||||
ret = -EINVAL;
|
||||
goto fail;
|
||||
}
|
||||
@@ -344,16 +353,14 @@ static int vpc_open(BlockDriverState *bs, QDict *options, int flags,
|
||||
s->max_table_entries = be32_to_cpu(dyndisk_header->max_table_entries);
|
||||
|
||||
if ((bs->total_sectors * 512) / s->block_size > 0xffffffffU) {
|
||||
ret = -EINVAL;
|
||||
goto fail;
|
||||
}
|
||||
if (s->max_table_entries > (VHD_MAX_SECTORS * 512) / s->block_size) {
|
||||
error_setg(errp, "Too many blocks");
|
||||
ret = -EINVAL;
|
||||
goto fail;
|
||||
}
|
||||
|
||||
computed_size = (uint64_t) s->max_table_entries * s->block_size;
|
||||
if (computed_size < bs->total_sectors * 512) {
|
||||
error_setg(errp, "Page table too small");
|
||||
ret = -EINVAL;
|
||||
goto fail;
|
||||
}
|
||||
@@ -370,6 +377,7 @@ static int vpc_open(BlockDriverState *bs, QDict *options, int flags,
|
||||
|
||||
s->pagetable = qemu_try_blockalign(bs->file->bs, pagetable_size);
|
||||
if (s->pagetable == NULL) {
|
||||
error_setg(errp, "Unable to allocate memory for page table");
|
||||
ret = -ENOMEM;
|
||||
goto fail;
|
||||
}
|
||||
@@ -379,6 +387,7 @@ static int vpc_open(BlockDriverState *bs, QDict *options, int flags,
|
||||
ret = bdrv_pread(bs->file->bs, s->bat_offset, s->pagetable,
|
||||
pagetable_size);
|
||||
if (ret < 0) {
|
||||
error_setg(errp, "Error reading pagetable");
|
||||
goto fail;
|
||||
}
|
||||
|
||||
@@ -457,16 +466,16 @@ static inline int64_t get_sector_offset(BlockDriverState *bs,
|
||||
pageentry_index = (offset % s->block_size) / 512;
|
||||
|
||||
if (pagetable_index >= s->max_table_entries || s->pagetable[pagetable_index] == 0xffffffff)
|
||||
return -1; // not allocated
|
||||
return -1; /* not allocated */
|
||||
|
||||
bitmap_offset = 512 * (uint64_t) s->pagetable[pagetable_index];
|
||||
block_offset = bitmap_offset + s->bitmap_size + (512 * pageentry_index);
|
||||
|
||||
// We must ensure that we don't write to any sectors which are marked as
|
||||
// unused in the bitmap. We get away with setting all bits in the block
|
||||
// bitmap each time we write to a new block. This might cause Virtual PC to
|
||||
// miss sparse read optimization, but it's not a problem in terms of
|
||||
// correctness.
|
||||
/* We must ensure that we don't write to any sectors which are marked as
|
||||
unused in the bitmap. We get away with setting all bits in the block
|
||||
bitmap each time we write to a new block. This might cause Virtual PC to
|
||||
miss sparse read optimization, but it's not a problem in terms of
|
||||
correctness. */
|
||||
if (write && (s->last_bitmap_offset != bitmap_offset)) {
|
||||
uint8_t bitmap[s->bitmap_size];
|
||||
|
||||
@@ -512,18 +521,18 @@ static int64_t alloc_block(BlockDriverState* bs, int64_t sector_num)
|
||||
int ret;
|
||||
uint8_t bitmap[s->bitmap_size];
|
||||
|
||||
// Check if sector_num is valid
|
||||
/* Check if sector_num is valid */
|
||||
if ((sector_num < 0) || (sector_num > bs->total_sectors))
|
||||
return -1;
|
||||
|
||||
// Write entry into in-memory BAT
|
||||
/* Write entry into in-memory BAT */
|
||||
index = (sector_num * 512) / s->block_size;
|
||||
if (s->pagetable[index] != 0xFFFFFFFF)
|
||||
return -1;
|
||||
|
||||
s->pagetable[index] = s->free_data_block_offset / 512;
|
||||
|
||||
// Initialize the block's bitmap
|
||||
/* Initialize the block's bitmap */
|
||||
memset(bitmap, 0xff, s->bitmap_size);
|
||||
ret = bdrv_pwrite_sync(bs->file->bs, s->free_data_block_offset, bitmap,
|
||||
s->bitmap_size);
|
||||
@@ -531,13 +540,13 @@ static int64_t alloc_block(BlockDriverState* bs, int64_t sector_num)
|
||||
return ret;
|
||||
}
|
||||
|
||||
// Write new footer (the old one will be overwritten)
|
||||
/* Write new footer (the old one will be overwritten) */
|
||||
s->free_data_block_offset += s->block_size + s->bitmap_size;
|
||||
ret = rewrite_footer(bs);
|
||||
if (ret < 0)
|
||||
goto fail;
|
||||
|
||||
// Write BAT entry to disk
|
||||
/* Write BAT entry to disk */
|
||||
bat_offset = s->bat_offset + (4 * index);
|
||||
bat_value = cpu_to_be32(s->pagetable[index]);
|
||||
ret = bdrv_pwrite_sync(bs->file->bs, bat_offset, &bat_value, 4);
|
||||
@@ -718,7 +727,7 @@ static int64_t coroutine_fn vpc_co_get_block_status(BlockDriverState *bs,
|
||||
* Note that the geometry doesn't always exactly match total_sectors but
|
||||
* may round it down.
|
||||
*
|
||||
* Returns 0 on success, -EFBIG if the size is larger than ~2 TB. Override
|
||||
* Returns 0 on success, -EFBIG if the size is larger than 2040 GiB. Override
|
||||
* the hardware EIDE and ATA-2 limit of 16 heads (max disk size of 127 GB)
|
||||
* and instead allow up to 255 heads.
|
||||
*/
|
||||
@@ -770,7 +779,7 @@ static int create_dynamic_disk(BlockBackend *blk, uint8_t *buf,
|
||||
int ret;
|
||||
int64_t offset = 0;
|
||||
|
||||
// Write the footer (twice: at the beginning and at the end)
|
||||
/* Write the footer (twice: at the beginning and at the end) */
|
||||
block_size = 0x200000;
|
||||
num_bat_entries = (total_sectors + block_size / 512) / (block_size / 512);
|
||||
|
||||
@@ -785,7 +794,7 @@ static int create_dynamic_disk(BlockBackend *blk, uint8_t *buf,
|
||||
goto fail;
|
||||
}
|
||||
|
||||
// Write the initial BAT
|
||||
/* Write the initial BAT */
|
||||
offset = 3 * 512;
|
||||
|
||||
memset(buf, 0xFF, 512);
|
||||
@@ -797,7 +806,7 @@ static int create_dynamic_disk(BlockBackend *blk, uint8_t *buf,
|
||||
offset += 512;
|
||||
}
|
||||
|
||||
// Prepare the Dynamic Disk Header
|
||||
/* Prepare the Dynamic Disk Header */
|
||||
memset(buf, 0, 1024);
|
||||
|
||||
memcpy(dyndisk_header->magic, "cxsparse", 8);
|
||||
@@ -814,7 +823,7 @@ static int create_dynamic_disk(BlockBackend *blk, uint8_t *buf,
|
||||
|
||||
dyndisk_header->checksum = cpu_to_be32(vpc_checksum(buf, 1024));
|
||||
|
||||
// Write the header
|
||||
/* Write the header */
|
||||
offset = 512;
|
||||
|
||||
ret = blk_pwrite(blk, offset, buf, 1024);
|
||||
@@ -874,6 +883,7 @@ static int vpc_create(const char *filename, QemuOpts *opts, Error **errp)
|
||||
} else if (!strcmp(disk_type_param, "fixed")) {
|
||||
disk_type = VHD_FIXED;
|
||||
} else {
|
||||
error_setg(errp, "Invalid disk type, %s", disk_type_param);
|
||||
ret = -EINVAL;
|
||||
goto out;
|
||||
}
|
||||
@@ -922,8 +932,9 @@ static int vpc_create(const char *filename, QemuOpts *opts, Error **errp)
|
||||
|
||||
if ((int64_t)cyls * heads * secs_per_cyl == VHD_MAX_GEOMETRY) {
|
||||
total_sectors = total_size / BDRV_SECTOR_SIZE;
|
||||
/* Allow a maximum disk size of approximately 2 TB */
|
||||
/* Allow a maximum disk size of 2040 GiB */
|
||||
if (total_sectors > VHD_MAX_SECTORS) {
|
||||
error_setg(errp, "Disk size is too large, max size is 2040 GiB");
|
||||
ret = -EFBIG;
|
||||
goto out;
|
||||
}
|
||||
@@ -974,6 +985,9 @@ static int vpc_create(const char *filename, QemuOpts *opts, Error **errp)
|
||||
} else {
|
||||
ret = create_fixed_disk(blk, buf, total_size);
|
||||
}
|
||||
if (ret < 0) {
|
||||
error_setg(errp, "Unable to create or write VHD header");
|
||||
}
|
||||
|
||||
out:
|
||||
blk_unref(blk);
|
||||
|
||||
@@ -364,7 +364,7 @@ Message types
|
||||
Equivalent ioctl: VHOST_SET_VRING_NUM
|
||||
Master payload: vring state description
|
||||
|
||||
Sets the number of vrings for this owner.
|
||||
Set the size of the queue.
|
||||
|
||||
* VHOST_USER_SET_VRING_ADDR
|
||||
|
||||
@@ -438,7 +438,7 @@ Message types
|
||||
Slave payload: u64
|
||||
|
||||
Query how many queues the backend supports. This request should be
|
||||
sent only when VHOST_USER_PROTOCOL_F_MQ is set in quried protocol
|
||||
sent only when VHOST_USER_PROTOCOL_F_MQ is set in queried protocol
|
||||
features by VHOST_USER_GET_PROTOCOL_FEATURES.
|
||||
|
||||
* VHOST_USER_SET_VRING_ENABLE
|
||||
|
||||
@@ -46,6 +46,7 @@
|
||||
#include "exec/address-spaces.h"
|
||||
#include "qemu/host-utils.h"
|
||||
#include "hw/sysbus.h"
|
||||
#include "sysemu/sysemu.h"
|
||||
|
||||
#define PFLASH_BUG(fmt, ...) \
|
||||
do { \
|
||||
@@ -97,6 +98,7 @@ struct pflash_t {
|
||||
MemoryRegion mem;
|
||||
char *name;
|
||||
void *storage;
|
||||
VMChangeStateEntry *vmstate;
|
||||
};
|
||||
|
||||
static int pflash_post_load(void *opaque, int version_id);
|
||||
@@ -944,13 +946,25 @@ MemoryRegion *pflash_cfi01_get_memory(pflash_t *fl)
|
||||
return &fl->mem;
|
||||
}
|
||||
|
||||
static void postload_update_cb(void *opaque, int running, RunState state)
|
||||
{
|
||||
pflash_t *pfl = opaque;
|
||||
|
||||
/* This is called after bdrv_invalidate_cache_all. */
|
||||
qemu_del_vm_change_state_handler(pfl->vmstate);
|
||||
pfl->vmstate = NULL;
|
||||
|
||||
DPRINTF("%s: updating bdrv for %s\n", __func__, pfl->name);
|
||||
pflash_update(pfl, 0, pfl->sector_len * pfl->nb_blocs);
|
||||
}
|
||||
|
||||
static int pflash_post_load(void *opaque, int version_id)
|
||||
{
|
||||
pflash_t *pfl = opaque;
|
||||
|
||||
if (!pfl->ro) {
|
||||
DPRINTF("%s: updating bdrv for %s\n", __func__, pfl->name);
|
||||
pflash_update(pfl, 0, pfl->sector_len * pfl->nb_blocs);
|
||||
pfl->vmstate = qemu_add_vm_change_state_handler(postload_update_cb,
|
||||
pfl);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -2167,6 +2167,11 @@ build_dsdt(GArray *table_data, GArray *linker,
|
||||
0, pci->w64.begin, pci->w64.end - 1, 0,
|
||||
pci->w64.end - pci->w64.begin));
|
||||
}
|
||||
|
||||
if (misc->tpm_version != TPM_VERSION_UNSPEC) {
|
||||
aml_append(crs, aml_memory32_fixed(TPM_TIS_ADDR_BASE,
|
||||
TPM_TIS_ADDR_SIZE, AML_READ_WRITE));
|
||||
}
|
||||
aml_append(scope, aml_name_decl("_CRS", crs));
|
||||
|
||||
/* reserve GPE0 block resources */
|
||||
@@ -2343,7 +2348,12 @@ build_dsdt(GArray *table_data, GArray *linker,
|
||||
crs = aml_resource_template();
|
||||
aml_append(crs, aml_memory32_fixed(TPM_TIS_ADDR_BASE,
|
||||
TPM_TIS_ADDR_SIZE, AML_READ_WRITE));
|
||||
aml_append(crs, aml_irq_no_flags(TPM_TIS_IRQ));
|
||||
/*
|
||||
FIXME: TPM_TIS_IRQ=5 conflicts with PNP0C0F irqs,
|
||||
Rewrite to take IRQ from TPM device model and
|
||||
fix default IRQ value there to use some unused IRQ
|
||||
*/
|
||||
/* aml_append(crs, aml_irq_no_flags(TPM_TIS_IRQ)); */
|
||||
aml_append(dev, aml_name_decl("_CRS", crs));
|
||||
aml_append(scope, dev);
|
||||
}
|
||||
|
||||
@@ -375,15 +375,18 @@ static void ide_atapi_cmd_check_status(IDEState *s)
|
||||
}
|
||||
/* ATAPI DMA support */
|
||||
|
||||
/* XXX: handle read errors */
|
||||
static void ide_atapi_cmd_read_dma_cb(void *opaque, int ret)
|
||||
{
|
||||
IDEState *s = opaque;
|
||||
int data_offset, n;
|
||||
|
||||
if (ret < 0) {
|
||||
ide_atapi_io_error(s, ret);
|
||||
goto eot;
|
||||
if (ide_handle_rw_error(s, -ret, ide_dma_cmd_to_retry(s->dma_cmd))) {
|
||||
if (s->bus->error_status) {
|
||||
return;
|
||||
}
|
||||
goto eot;
|
||||
}
|
||||
}
|
||||
|
||||
if (s->io_buffer_size > 0) {
|
||||
@@ -481,21 +484,16 @@ static void ide_atapi_cmd_read(IDEState *s, int lba, int nb_sectors,
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/* Called by *_restart_bh when the transfer function points
|
||||
* to ide_atapi_cmd
|
||||
*/
|
||||
void ide_atapi_dma_restart(IDEState *s)
|
||||
{
|
||||
/*
|
||||
* I'm not sure we have enough stored to restart the command
|
||||
* safely, so give the guest an error it should recover from.
|
||||
* I'm assuming most guests will try to recover from something
|
||||
* listed as a medium error on a CD; it seems to work on Linux.
|
||||
* This would be more of a problem if we did any other type of
|
||||
* DMA operation.
|
||||
* At this point we can just re-evaluate the packet command and start over.
|
||||
* The presence of ->dma_cb callback in the pre_save ensures that the packet
|
||||
* command has been completely sent and we can safely restart command.
|
||||
*/
|
||||
ide_atapi_cmd_error(s, MEDIUM_ERROR, ASC_NO_SEEK_COMPLETE);
|
||||
s->unit = s->bus->retry_unit;
|
||||
s->bus->dma->ops->restart_dma(s->bus->dma);
|
||||
ide_atapi_cmd(s);
|
||||
}
|
||||
|
||||
static inline uint8_t ide_atapi_set_profile(uint8_t *buf, uint8_t *index,
|
||||
|
||||
@@ -57,7 +57,6 @@ static const int smart_attributes[][12] = {
|
||||
{ 190, 0x03, 0x00, 0x45, 0x45, 0x1f, 0x00, 0x1f, 0x1f, 0x00, 0x00, 0x32},
|
||||
};
|
||||
|
||||
static int ide_handle_rw_error(IDEState *s, int error, int op);
|
||||
static void ide_dummy_transfer_stop(IDEState *s);
|
||||
|
||||
static void padstr(char *str, const char *src, int len)
|
||||
@@ -773,7 +772,7 @@ void ide_dma_error(IDEState *s)
|
||||
ide_set_irq(s->bus);
|
||||
}
|
||||
|
||||
static int ide_handle_rw_error(IDEState *s, int error, int op)
|
||||
int ide_handle_rw_error(IDEState *s, int error, int op)
|
||||
{
|
||||
bool is_read = (op & IDE_RETRY_READ) != 0;
|
||||
BlockErrorAction action = blk_get_error_action(s->blk, is_read, error);
|
||||
@@ -783,8 +782,10 @@ static int ide_handle_rw_error(IDEState *s, int error, int op)
|
||||
s->bus->error_status = op;
|
||||
} else if (action == BLOCK_ERROR_ACTION_REPORT) {
|
||||
block_acct_failed(blk_get_stats(s->blk), &s->acct);
|
||||
if (op & IDE_RETRY_DMA) {
|
||||
if (IS_IDE_RETRY_DMA(op)) {
|
||||
ide_dma_error(s);
|
||||
} else if (IS_IDE_RETRY_ATAPI(op)) {
|
||||
ide_atapi_io_error(s, -error);
|
||||
} else {
|
||||
ide_rw_error(s);
|
||||
}
|
||||
@@ -804,14 +805,7 @@ static void ide_dma_cb(void *opaque, int ret)
|
||||
return;
|
||||
}
|
||||
if (ret < 0) {
|
||||
int op = IDE_RETRY_DMA;
|
||||
|
||||
if (s->dma_cmd == IDE_DMA_READ)
|
||||
op |= IDE_RETRY_READ;
|
||||
else if (s->dma_cmd == IDE_DMA_TRIM)
|
||||
op |= IDE_RETRY_TRIM;
|
||||
|
||||
if (ide_handle_rw_error(s, -ret, op)) {
|
||||
if (ide_handle_rw_error(s, -ret, ide_dma_cmd_to_retry(s->dma_cmd))) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
@@ -879,6 +873,8 @@ static void ide_dma_cb(void *opaque, int ret)
|
||||
ide_issue_trim, ide_dma_cb, s,
|
||||
DMA_DIRECTION_TO_DEVICE);
|
||||
break;
|
||||
default:
|
||||
abort();
|
||||
}
|
||||
return;
|
||||
|
||||
@@ -1641,6 +1637,9 @@ static bool cmd_packet(IDEState *s, uint8_t cmd)
|
||||
|
||||
s->status = READY_STAT | SEEK_STAT;
|
||||
s->atapi_dma = s->feature & 1;
|
||||
if (s->atapi_dma) {
|
||||
s->dma_cmd = IDE_DMA_ATAPI;
|
||||
}
|
||||
s->nsector = 1;
|
||||
ide_transfer_start(s, s->io_buffer, ATAPI_PACKET_SIZE,
|
||||
ide_atapi_cmd);
|
||||
@@ -2525,15 +2524,13 @@ static void ide_restart_bh(void *opaque)
|
||||
if (s->bus->dma->ops->restart) {
|
||||
s->bus->dma->ops->restart(s->bus->dma);
|
||||
}
|
||||
}
|
||||
|
||||
if (error_status & IDE_RETRY_DMA) {
|
||||
} else if (IS_IDE_RETRY_DMA(error_status)) {
|
||||
if (error_status & IDE_RETRY_TRIM) {
|
||||
ide_restart_dma(s, IDE_DMA_TRIM);
|
||||
} else {
|
||||
ide_restart_dma(s, is_read ? IDE_DMA_READ : IDE_DMA_WRITE);
|
||||
}
|
||||
} else if (error_status & IDE_RETRY_PIO) {
|
||||
} else if (IS_IDE_RETRY_PIO(error_status)) {
|
||||
if (is_read) {
|
||||
ide_sector_read(s);
|
||||
} else {
|
||||
@@ -2541,15 +2538,11 @@ static void ide_restart_bh(void *opaque)
|
||||
}
|
||||
} else if (error_status & IDE_RETRY_FLUSH) {
|
||||
ide_flush_cache(s);
|
||||
} else if (IS_IDE_RETRY_ATAPI(error_status)) {
|
||||
assert(s->end_transfer_func == ide_atapi_cmd);
|
||||
ide_atapi_dma_restart(s);
|
||||
} else {
|
||||
/*
|
||||
* We've not got any bits to tell us about ATAPI - but
|
||||
* we do have the end_transfer_func that tells us what
|
||||
* we're trying to do.
|
||||
*/
|
||||
if (s->end_transfer_func == ide_atapi_cmd) {
|
||||
ide_atapi_dma_restart(s);
|
||||
}
|
||||
abort();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -338,6 +338,7 @@ enum ide_dma_cmd {
|
||||
IDE_DMA_READ,
|
||||
IDE_DMA_WRITE,
|
||||
IDE_DMA_TRIM,
|
||||
IDE_DMA_ATAPI,
|
||||
};
|
||||
|
||||
#define ide_cmd_is_read(s) \
|
||||
@@ -506,13 +507,45 @@ struct IDEDevice {
|
||||
};
|
||||
|
||||
/* These are used for the error_status field of IDEBus */
|
||||
#define IDE_RETRY_MASK 0xf8
|
||||
#define IDE_RETRY_DMA 0x08
|
||||
#define IDE_RETRY_PIO 0x10
|
||||
#define IDE_RETRY_ATAPI 0x20 /* reused IDE_RETRY_READ bit */
|
||||
#define IDE_RETRY_READ 0x20
|
||||
#define IDE_RETRY_FLUSH 0x40
|
||||
#define IDE_RETRY_TRIM 0x80
|
||||
#define IDE_RETRY_HBA 0x100
|
||||
|
||||
#define IS_IDE_RETRY_DMA(_status) \
|
||||
((_status) & IDE_RETRY_DMA)
|
||||
|
||||
#define IS_IDE_RETRY_PIO(_status) \
|
||||
((_status) & IDE_RETRY_PIO)
|
||||
|
||||
/*
|
||||
* The method of the IDE_RETRY_ATAPI determination is to use a previously
|
||||
* impossible bit combination as a new status value.
|
||||
*/
|
||||
#define IS_IDE_RETRY_ATAPI(_status) \
|
||||
(((_status) & IDE_RETRY_MASK) == IDE_RETRY_ATAPI)
|
||||
|
||||
static inline uint8_t ide_dma_cmd_to_retry(uint8_t dma_cmd)
|
||||
{
|
||||
switch (dma_cmd) {
|
||||
case IDE_DMA_READ:
|
||||
return IDE_RETRY_DMA | IDE_RETRY_READ;
|
||||
case IDE_DMA_WRITE:
|
||||
return IDE_RETRY_DMA;
|
||||
case IDE_DMA_TRIM:
|
||||
return IDE_RETRY_DMA | IDE_RETRY_TRIM;
|
||||
case IDE_DMA_ATAPI:
|
||||
return IDE_RETRY_ATAPI;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static inline IDEState *idebus_active_if(IDEBus *bus)
|
||||
{
|
||||
return bus->ifs + bus->unit;
|
||||
@@ -597,4 +630,6 @@ void ide_bus_new(IDEBus *idebus, size_t idebus_size, DeviceState *dev,
|
||||
int bus_id, int max_units);
|
||||
IDEDevice *ide_create_drive(IDEBus *bus, int unit, DriveInfo *drive);
|
||||
|
||||
int ide_handle_rw_error(IDEState *s, int error, int op);
|
||||
|
||||
#endif /* HW_IDE_INTERNAL_H */
|
||||
|
||||
@@ -346,6 +346,8 @@ static void pmac_ide_transfer_cb(void *opaque, int ret)
|
||||
case IDE_DMA_TRIM:
|
||||
pmac_dma_trim(s->blk, offset, io->len, pmac_ide_transfer_cb, io);
|
||||
break;
|
||||
default:
|
||||
abort();
|
||||
}
|
||||
|
||||
return;
|
||||
|
||||
@@ -308,6 +308,10 @@ static void ide_bmdma_pre_save(void *opaque)
|
||||
BMDMAState *bm = opaque;
|
||||
uint8_t abused_bits = BM_MIGRATION_COMPAT_STATUS_BITS;
|
||||
|
||||
if (!(bm->status & BM_STATUS_DMAING) && bm->dma_cb) {
|
||||
bm->bus->error_status =
|
||||
ide_dma_cmd_to_retry(bmdma_active_if(bm)->dma_cmd);
|
||||
}
|
||||
bm->migration_retry_unit = bm->bus->retry_unit;
|
||||
bm->migration_retry_sector_num = bm->bus->retry_sector_num;
|
||||
bm->migration_retry_nsector = bm->bus->retry_nsector;
|
||||
|
||||
@@ -189,6 +189,7 @@ int pci_piix3_xen_ide_unplug(DeviceState *dev)
|
||||
idedev = pci_ide->bus[di->bus].slave;
|
||||
}
|
||||
idedev->conf.blk = NULL;
|
||||
monitor_remove_blk(blk);
|
||||
blk_unref(blk);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -872,6 +872,8 @@ static void ivshmem_common_realize(PCIDevice *dev, Error **errp)
|
||||
s->ivshmem_bar2 = host_memory_backend_get_memory(s->hostmem,
|
||||
&error_abort);
|
||||
} else {
|
||||
assert(s->server_chr);
|
||||
|
||||
IVSHMEM_DPRINTF("using shared memory server (socket = %s)\n",
|
||||
s->server_chr->filename);
|
||||
|
||||
@@ -1051,10 +1053,24 @@ static void ivshmem_plain_init(Object *obj)
|
||||
&error_abort);
|
||||
}
|
||||
|
||||
static void ivshmem_plain_realize(PCIDevice *dev, Error **errp)
|
||||
{
|
||||
IVShmemState *s = IVSHMEM_COMMON(dev);
|
||||
|
||||
if (!s->hostmem) {
|
||||
error_setg(errp, "You must specify a 'memdev'");
|
||||
return;
|
||||
}
|
||||
|
||||
ivshmem_common_realize(dev, errp);
|
||||
}
|
||||
|
||||
static void ivshmem_plain_class_init(ObjectClass *klass, void *data)
|
||||
{
|
||||
DeviceClass *dc = DEVICE_CLASS(klass);
|
||||
PCIDeviceClass *k = PCI_DEVICE_CLASS(klass);
|
||||
|
||||
k->realize = ivshmem_plain_realize;
|
||||
dc->props = ivshmem_plain_properties;
|
||||
dc->vmsd = &ivshmem_plain_vmsd;
|
||||
}
|
||||
@@ -1099,10 +1115,24 @@ static void ivshmem_doorbell_init(Object *obj)
|
||||
s->legacy_size = SIZE_MAX; /* whatever the server sends */
|
||||
}
|
||||
|
||||
static void ivshmem_doorbell_realize(PCIDevice *dev, Error **errp)
|
||||
{
|
||||
IVShmemState *s = IVSHMEM_COMMON(dev);
|
||||
|
||||
if (!s->server_chr) {
|
||||
error_setg(errp, "You must specify a 'chardev'");
|
||||
return;
|
||||
}
|
||||
|
||||
ivshmem_common_realize(dev, errp);
|
||||
}
|
||||
|
||||
static void ivshmem_doorbell_class_init(ObjectClass *klass, void *data)
|
||||
{
|
||||
DeviceClass *dc = DEVICE_CLASS(klass);
|
||||
PCIDeviceClass *k = PCI_DEVICE_CLASS(klass);
|
||||
|
||||
k->realize = ivshmem_doorbell_realize;
|
||||
dc->props = ivshmem_doorbell_properties;
|
||||
dc->vmsd = &ivshmem_doorbell_vmsd;
|
||||
}
|
||||
|
||||
@@ -86,7 +86,7 @@ static int tpm_passthrough_unix_write(int fd, const uint8_t *buf, uint32_t len)
|
||||
int ret, remain;
|
||||
|
||||
remain = len;
|
||||
while (len > 0) {
|
||||
while (remain > 0) {
|
||||
ret = write(fd, buf, remain);
|
||||
if (ret < 0) {
|
||||
if (errno != EINTR && errno != EAGAIN) {
|
||||
|
||||
@@ -1397,7 +1397,7 @@ static int ehci_process_itd(EHCIState *ehci,
|
||||
{
|
||||
USBDevice *dev;
|
||||
USBEndpoint *ep;
|
||||
uint32_t i, len, pid, dir, devaddr, endp, xfers = 0;
|
||||
uint32_t i, len, pid, dir, devaddr, endp;
|
||||
uint32_t pg, off, ptr1, ptr2, max, mult;
|
||||
|
||||
ehci->periodic_sched_active = PERIODIC_ACTIVE;
|
||||
@@ -1489,10 +1489,9 @@ static int ehci_process_itd(EHCIState *ehci,
|
||||
ehci_raise_irq(ehci, USBSTS_INT);
|
||||
}
|
||||
itd->transact[i] &= ~ITD_XACT_ACTIVE;
|
||||
xfers++;
|
||||
}
|
||||
}
|
||||
return xfers ? 0 : -1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
@@ -2011,6 +2010,7 @@ static int ehci_state_writeback(EHCIQueue *q)
|
||||
static void ehci_advance_state(EHCIState *ehci, int async)
|
||||
{
|
||||
EHCIQueue *q = NULL;
|
||||
int itd_count = 0;
|
||||
int again;
|
||||
|
||||
do {
|
||||
@@ -2035,10 +2035,12 @@ static void ehci_advance_state(EHCIState *ehci, int async)
|
||||
|
||||
case EST_FETCHITD:
|
||||
again = ehci_state_fetchitd(ehci, async);
|
||||
itd_count++;
|
||||
break;
|
||||
|
||||
case EST_FETCHSITD:
|
||||
again = ehci_state_fetchsitd(ehci, async);
|
||||
itd_count++;
|
||||
break;
|
||||
|
||||
case EST_ADVANCEQUEUE:
|
||||
@@ -2087,7 +2089,8 @@ static void ehci_advance_state(EHCIState *ehci, int async)
|
||||
break;
|
||||
}
|
||||
|
||||
if (again < 0) {
|
||||
if (again < 0 || itd_count > 16) {
|
||||
/* TODO: notify guest (raise HSE irq?) */
|
||||
fprintf(stderr, "processing error - resetting ehci HC\n");
|
||||
ehci_reset(ehci);
|
||||
again = 0;
|
||||
|
||||
@@ -19,7 +19,6 @@
|
||||
#include "qemu-common.h"
|
||||
#include "hw/virtio/virtio.h"
|
||||
#include "hw/i386/pc.h"
|
||||
#include "cpu.h"
|
||||
#include "sysemu/balloon.h"
|
||||
#include "hw/virtio/virtio-balloon.h"
|
||||
#include "sysemu/kvm.h"
|
||||
@@ -35,12 +34,14 @@
|
||||
#include "hw/virtio/virtio-bus.h"
|
||||
#include "hw/virtio/virtio-access.h"
|
||||
|
||||
#define BALLOON_PAGE_SIZE (1 << VIRTIO_BALLOON_PFN_SHIFT)
|
||||
|
||||
static void balloon_page(void *addr, int deflate)
|
||||
{
|
||||
#if defined(__linux__)
|
||||
if (!qemu_balloon_is_inhibited() && (!kvm_enabled() ||
|
||||
kvm_has_sync_mmu())) {
|
||||
qemu_madvise(addr, TARGET_PAGE_SIZE,
|
||||
qemu_madvise(addr, BALLOON_PAGE_SIZE,
|
||||
deflate ? QEMU_MADV_WILLNEED : QEMU_MADV_DONTNEED);
|
||||
}
|
||||
#endif
|
||||
|
||||
23
nbd/client.c
23
nbd/client.c
@@ -192,13 +192,18 @@ static int nbd_receive_list(QIOChannel *ioc, char **name, Error **errp)
|
||||
return -1;
|
||||
}
|
||||
} else if (type == NBD_REP_SERVER) {
|
||||
if (len < sizeof(namelen) || len > NBD_MAX_BUFFER_SIZE) {
|
||||
error_setg(errp, "incorrect option length");
|
||||
return -1;
|
||||
}
|
||||
if (read_sync(ioc, &namelen, sizeof(namelen)) != sizeof(namelen)) {
|
||||
error_setg(errp, "failed to read option name length");
|
||||
return -1;
|
||||
}
|
||||
namelen = be32_to_cpu(namelen);
|
||||
if (len != (namelen + sizeof(namelen))) {
|
||||
error_setg(errp, "incorrect option mame length");
|
||||
len -= sizeof(namelen);
|
||||
if (len < namelen) {
|
||||
error_setg(errp, "incorrect option name length");
|
||||
return -1;
|
||||
}
|
||||
if (namelen > 255) {
|
||||
@@ -214,6 +219,20 @@ static int nbd_receive_list(QIOChannel *ioc, char **name, Error **errp)
|
||||
return -1;
|
||||
}
|
||||
(*name)[namelen] = '\0';
|
||||
len -= namelen;
|
||||
if (len) {
|
||||
char *buf = g_malloc(len + 1);
|
||||
if (read_sync(ioc, buf, len) != len) {
|
||||
error_setg(errp, "failed to read export description");
|
||||
g_free(*name);
|
||||
g_free(buf);
|
||||
*name = NULL;
|
||||
return -1;
|
||||
}
|
||||
buf[len] = '\0';
|
||||
TRACE("Ignoring export description: %s", buf);
|
||||
g_free(buf);
|
||||
}
|
||||
} else {
|
||||
error_setg(errp, "Unexpected reply type %x expected %x",
|
||||
type, NBD_REP_SERVER);
|
||||
|
||||
15
nbd/server.c
15
nbd/server.c
@@ -449,11 +449,19 @@ static int nbd_negotiate_options(NBDClient *client)
|
||||
client->ioc = QIO_CHANNEL(tioc);
|
||||
break;
|
||||
|
||||
case NBD_OPT_EXPORT_NAME:
|
||||
/* No way to return an error to client, so drop connection */
|
||||
TRACE("Option 0x%x not permitted before TLS", clientflags);
|
||||
return -EINVAL;
|
||||
|
||||
default:
|
||||
TRACE("Option 0x%x not permitted before TLS", clientflags);
|
||||
if (nbd_negotiate_drop_sync(client->ioc, length) != length) {
|
||||
return -EIO;
|
||||
}
|
||||
nbd_negotiate_send_rep(client->ioc, NBD_REP_ERR_TLS_REQD,
|
||||
clientflags);
|
||||
return -EINVAL;
|
||||
break;
|
||||
}
|
||||
} else if (fixedNewstyle) {
|
||||
switch (clientflags) {
|
||||
@@ -471,6 +479,9 @@ static int nbd_negotiate_options(NBDClient *client)
|
||||
return nbd_negotiate_handle_export_name(client, length);
|
||||
|
||||
case NBD_OPT_STARTTLS:
|
||||
if (nbd_negotiate_drop_sync(client->ioc, length) != length) {
|
||||
return -EIO;
|
||||
}
|
||||
if (client->tlscreds) {
|
||||
TRACE("TLS already enabled");
|
||||
nbd_negotiate_send_rep(client->ioc, NBD_REP_ERR_INVALID,
|
||||
@@ -480,7 +491,7 @@ static int nbd_negotiate_options(NBDClient *client)
|
||||
nbd_negotiate_send_rep(client->ioc, NBD_REP_ERR_POLICY,
|
||||
clientflags);
|
||||
}
|
||||
return -EINVAL;
|
||||
break;
|
||||
default:
|
||||
TRACE("Unsupported option 0x%x", clientflags);
|
||||
if (nbd_negotiate_drop_sync(client->ioc, length) != length) {
|
||||
|
||||
@@ -1416,6 +1416,7 @@ struct aio_ctx {
|
||||
int vflag;
|
||||
int Cflag;
|
||||
int Pflag;
|
||||
int zflag;
|
||||
BlockAcctCookie acct;
|
||||
int pattern;
|
||||
struct timeval t1;
|
||||
@@ -1446,8 +1447,10 @@ static void aio_write_done(void *opaque, int ret)
|
||||
print_report("wrote", &t2, ctx->offset, ctx->qiov.size,
|
||||
ctx->qiov.size, 1, ctx->Cflag);
|
||||
out:
|
||||
qemu_io_free(ctx->buf);
|
||||
qemu_iovec_destroy(&ctx->qiov);
|
||||
if (!ctx->zflag) {
|
||||
qemu_io_free(ctx->buf);
|
||||
qemu_iovec_destroy(&ctx->qiov);
|
||||
}
|
||||
g_free(ctx);
|
||||
}
|
||||
|
||||
@@ -1612,6 +1615,7 @@ static void aio_write_help(void)
|
||||
" -P, -- use different pattern to fill file\n"
|
||||
" -C, -- report statistics in a machine parsable format\n"
|
||||
" -q, -- quiet mode, do not show I/O statistics\n"
|
||||
" -z, -- write zeroes using blk_aio_write_zeroes\n"
|
||||
"\n");
|
||||
}
|
||||
|
||||
@@ -1622,7 +1626,7 @@ static const cmdinfo_t aio_write_cmd = {
|
||||
.cfunc = aio_write_f,
|
||||
.argmin = 2,
|
||||
.argmax = -1,
|
||||
.args = "[-Cq] [-P pattern ] off len [len..]",
|
||||
.args = "[-Cqz] [-P pattern ] off len [len..]",
|
||||
.oneline = "asynchronously writes a number of bytes",
|
||||
.help = aio_write_help,
|
||||
};
|
||||
@@ -1634,7 +1638,7 @@ static int aio_write_f(BlockBackend *blk, int argc, char **argv)
|
||||
struct aio_ctx *ctx = g_new0(struct aio_ctx, 1);
|
||||
|
||||
ctx->blk = blk;
|
||||
while ((c = getopt(argc, argv, "CqP:")) != -1) {
|
||||
while ((c = getopt(argc, argv, "CqP:z")) != -1) {
|
||||
switch (c) {
|
||||
case 'C':
|
||||
ctx->Cflag = 1;
|
||||
@@ -1649,6 +1653,9 @@ static int aio_write_f(BlockBackend *blk, int argc, char **argv)
|
||||
return 0;
|
||||
}
|
||||
break;
|
||||
case 'z':
|
||||
ctx->zflag = 1;
|
||||
break;
|
||||
default:
|
||||
g_free(ctx);
|
||||
return qemuio_command_usage(&aio_write_cmd);
|
||||
@@ -1660,6 +1667,18 @@ static int aio_write_f(BlockBackend *blk, int argc, char **argv)
|
||||
return qemuio_command_usage(&aio_write_cmd);
|
||||
}
|
||||
|
||||
if (ctx->zflag && optind != argc - 2) {
|
||||
printf("-z supports only a single length parameter\n");
|
||||
g_free(ctx);
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (ctx->zflag && ctx->Pflag) {
|
||||
printf("-z and -P cannot be specified at the same time\n");
|
||||
g_free(ctx);
|
||||
return 0;
|
||||
}
|
||||
|
||||
ctx->offset = cvtnum(argv[optind]);
|
||||
if (ctx->offset < 0) {
|
||||
print_cvtnum_err(ctx->offset, argv[optind]);
|
||||
@@ -1676,19 +1695,33 @@ static int aio_write_f(BlockBackend *blk, int argc, char **argv)
|
||||
return 0;
|
||||
}
|
||||
|
||||
nr_iov = argc - optind;
|
||||
ctx->buf = create_iovec(blk, &ctx->qiov, &argv[optind], nr_iov, pattern);
|
||||
if (ctx->buf == NULL) {
|
||||
block_acct_invalid(blk_get_stats(blk), BLOCK_ACCT_WRITE);
|
||||
g_free(ctx);
|
||||
return 0;
|
||||
}
|
||||
if (ctx->zflag) {
|
||||
int64_t count = cvtnum(argv[optind]);
|
||||
if (count < 0) {
|
||||
print_cvtnum_err(count, argv[optind]);
|
||||
return 0;
|
||||
}
|
||||
|
||||
gettimeofday(&ctx->t1, NULL);
|
||||
block_acct_start(blk_get_stats(blk), &ctx->acct, ctx->qiov.size,
|
||||
BLOCK_ACCT_WRITE);
|
||||
blk_aio_writev(blk, ctx->offset >> 9, &ctx->qiov,
|
||||
ctx->qiov.size >> 9, aio_write_done, ctx);
|
||||
ctx->qiov.size = count;
|
||||
blk_aio_write_zeroes(blk, ctx->offset >> 9, count >> 9, 0,
|
||||
aio_write_done, ctx);
|
||||
} else {
|
||||
nr_iov = argc - optind;
|
||||
ctx->buf = create_iovec(blk, &ctx->qiov, &argv[optind], nr_iov,
|
||||
pattern);
|
||||
if (ctx->buf == NULL) {
|
||||
block_acct_invalid(blk_get_stats(blk), BLOCK_ACCT_WRITE);
|
||||
g_free(ctx);
|
||||
return 0;
|
||||
}
|
||||
|
||||
gettimeofday(&ctx->t1, NULL);
|
||||
block_acct_start(blk_get_stats(blk), &ctx->acct, ctx->qiov.size,
|
||||
BLOCK_ACCT_WRITE);
|
||||
|
||||
blk_aio_writev(blk, ctx->offset >> 9, &ctx->qiov,
|
||||
ctx->qiov.size >> 9, aio_write_done, ctx);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
@@ -215,7 +215,7 @@ static int find_partition(BlockBackend *blk, int partition,
|
||||
|
||||
static void termsig_handler(int signum)
|
||||
{
|
||||
state = TERMINATE;
|
||||
atomic_cmpxchg(&state, RUNNING, TERMINATE);
|
||||
qemu_notify_event();
|
||||
}
|
||||
|
||||
|
||||
@@ -347,9 +347,4 @@ struct tcpcb *tcp_drop(struct tcpcb *tp, int err);
|
||||
#define max(x,y) ((x) > (y) ? (x) : (y))
|
||||
#endif
|
||||
|
||||
#ifdef _WIN32
|
||||
#undef errno
|
||||
#define errno (WSAGetLastError())
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
@@ -659,6 +659,7 @@ findso:
|
||||
}
|
||||
|
||||
if ((tcp_fconnect(so, so->so_ffamily) == -1) &&
|
||||
(errno != EAGAIN) &&
|
||||
(errno != EINPROGRESS) && (errno != EWOULDBLOCK)
|
||||
) {
|
||||
uint8_t code;
|
||||
|
||||
@@ -158,9 +158,8 @@ void sparc_cpu_do_interrupt(CPUState *cs)
|
||||
} else if ((intno & 0x1c0) == TT_FILL) {
|
||||
cpu_set_cwp(env, cpu_cwp_inc(env, env->cwp + 1));
|
||||
}
|
||||
env->tbr &= ~0x7fffULL;
|
||||
env->tbr |= ((env->tl > 1) ? 1 << 14 : 0) | (intno << 5);
|
||||
env->pc = env->tbr;
|
||||
env->pc = env->tbr & ~0x7fffULL;
|
||||
env->pc |= ((env->tl > 1) ? 1 << 14 : 0) | (intno << 5);
|
||||
env->npc = env->pc + 4;
|
||||
cs->exception_index = -1;
|
||||
}
|
||||
|
||||
@@ -2059,11 +2059,11 @@ void helper_ldda_asi(CPUSPARCState *env, target_ulong addr, int asi, int rd)
|
||||
bswap64s(&env->gregs[rd + 1]);
|
||||
}
|
||||
} else {
|
||||
env->regwptr[rd] = cpu_ldq_nucleus(env, addr);
|
||||
env->regwptr[rd + 1] = cpu_ldq_nucleus(env, addr + 8);
|
||||
env->regwptr[rd - 8] = cpu_ldq_nucleus(env, addr);
|
||||
env->regwptr[rd + 1 - 8] = cpu_ldq_nucleus(env, addr + 8);
|
||||
if (asi == 0x2c) {
|
||||
bswap64s(&env->regwptr[rd]);
|
||||
bswap64s(&env->regwptr[rd + 1]);
|
||||
bswap64s(&env->regwptr[rd - 8]);
|
||||
bswap64s(&env->regwptr[rd + 1 - 8]);
|
||||
}
|
||||
}
|
||||
break;
|
||||
@@ -2076,8 +2076,8 @@ void helper_ldda_asi(CPUSPARCState *env, target_ulong addr, int asi, int rd)
|
||||
env->gregs[rd] = helper_ld_asi(env, addr, asi, 4, 0);
|
||||
env->gregs[rd + 1] = helper_ld_asi(env, addr + 4, asi, 4, 0);
|
||||
} else {
|
||||
env->regwptr[rd] = helper_ld_asi(env, addr, asi, 4, 0);
|
||||
env->regwptr[rd + 1] = helper_ld_asi(env, addr + 4, asi, 4, 0);
|
||||
env->regwptr[rd - 8] = helper_ld_asi(env, addr, asi, 4, 0);
|
||||
env->regwptr[rd + 1 - 8] = helper_ld_asi(env, addr + 4, asi, 4, 0);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -25,7 +25,6 @@ seq=`basename $0`
|
||||
echo "QA output created by $seq"
|
||||
|
||||
here=`pwd`
|
||||
tmp=/tmp/$$
|
||||
status=1 # failure is the default!
|
||||
|
||||
_cleanup()
|
||||
|
||||
@@ -25,7 +25,6 @@ seq=`basename $0`
|
||||
echo "QA output created by $seq"
|
||||
|
||||
here=`pwd`
|
||||
tmp=/tmp/$$
|
||||
status=1 # failure is the default!
|
||||
|
||||
_cleanup()
|
||||
|
||||
@@ -25,7 +25,6 @@ seq=`basename $0`
|
||||
echo "QA output created by $seq"
|
||||
|
||||
here=`pwd`
|
||||
tmp=/tmp/$$
|
||||
status=1 # failure is the default!
|
||||
|
||||
_cleanup()
|
||||
|
||||
@@ -25,7 +25,6 @@ seq=`basename $0`
|
||||
echo "QA output created by $seq"
|
||||
|
||||
here=`pwd`
|
||||
tmp=/tmp/$$
|
||||
status=1 # failure is the default!
|
||||
|
||||
_cleanup()
|
||||
|
||||
@@ -28,7 +28,6 @@ seq=`basename $0`
|
||||
echo "QA output created by $seq"
|
||||
|
||||
here=`pwd`
|
||||
tmp=/tmp/$$
|
||||
status=1 # failure is the default!
|
||||
|
||||
_cleanup()
|
||||
|
||||
@@ -25,7 +25,6 @@ seq=`basename $0`
|
||||
echo "QA output created by $seq"
|
||||
|
||||
here=`pwd`
|
||||
tmp=/tmp/$$
|
||||
status=1 # failure is the default!
|
||||
|
||||
_cleanup()
|
||||
|
||||
@@ -25,7 +25,6 @@ seq=`basename $0`
|
||||
echo "QA output created by $seq"
|
||||
|
||||
here=`pwd`
|
||||
tmp=/tmp/$$
|
||||
status=1 # failure is the default!
|
||||
|
||||
_cleanup()
|
||||
|
||||
@@ -25,7 +25,6 @@ seq=`basename $0`
|
||||
echo "QA output created by $seq"
|
||||
|
||||
here=`pwd`
|
||||
tmp=/tmp/$$
|
||||
status=1 # failure is the default!
|
||||
|
||||
_cleanup()
|
||||
|
||||
@@ -25,7 +25,6 @@ seq=`basename $0`
|
||||
echo "QA output created by $seq"
|
||||
|
||||
here=`pwd`
|
||||
tmp=/tmp/$$
|
||||
status=1 # failure is the default!
|
||||
|
||||
_cleanup()
|
||||
|
||||
@@ -25,7 +25,6 @@ seq=`basename $0`
|
||||
echo "QA output created by $seq"
|
||||
|
||||
here=`pwd`
|
||||
tmp=/tmp/$$
|
||||
status=1 # failure is the default!
|
||||
|
||||
_cleanup()
|
||||
|
||||
@@ -27,7 +27,6 @@ seq=`basename $0`
|
||||
echo "QA output created by $seq"
|
||||
|
||||
here=`pwd`
|
||||
tmp=/tmp/$$
|
||||
status=1 # failure is the default!
|
||||
|
||||
_cleanup()
|
||||
|
||||
@@ -25,7 +25,6 @@ seq=`basename $0`
|
||||
echo "QA output created by $seq"
|
||||
|
||||
here=`pwd`
|
||||
tmp=/tmp/$$
|
||||
status=1 # failure is the default!
|
||||
|
||||
_cleanup()
|
||||
|
||||
@@ -27,7 +27,6 @@ seq=`basename $0`
|
||||
echo "QA output created by $seq"
|
||||
|
||||
here=`pwd`
|
||||
tmp=/tmp/$$
|
||||
status=1 # failure is the default!
|
||||
|
||||
_cleanup()
|
||||
|
||||
@@ -25,7 +25,6 @@ seq=`basename $0`
|
||||
echo "QA output created by $seq"
|
||||
|
||||
here=`pwd`
|
||||
tmp=/tmp/$$
|
||||
status=1 # failure is the default!
|
||||
|
||||
_cleanup()
|
||||
|
||||
@@ -25,7 +25,6 @@ seq=`basename $0`
|
||||
echo "QA output created by $seq"
|
||||
|
||||
here=`pwd`
|
||||
tmp=/tmp/$$
|
||||
status=1 # failure is the default!
|
||||
|
||||
_cleanup()
|
||||
|
||||
@@ -25,7 +25,6 @@ seq=`basename $0`
|
||||
echo "QA output created by $seq"
|
||||
|
||||
here=`pwd`
|
||||
tmp=/tmp/$$
|
||||
status=1 # failure is the default!
|
||||
|
||||
_cleanup()
|
||||
|
||||
@@ -27,7 +27,6 @@ seq=`basename $0`
|
||||
echo "QA output created by $seq"
|
||||
|
||||
here=`pwd`
|
||||
tmp=/tmp/$$
|
||||
status=1 # failure is the default!
|
||||
|
||||
_cleanup()
|
||||
|
||||
@@ -25,7 +25,6 @@ seq=`basename $0`
|
||||
echo "QA output created by $seq"
|
||||
|
||||
here=`pwd`
|
||||
tmp=/tmp/$$
|
||||
status=1 # failure is the default!
|
||||
|
||||
_cleanup()
|
||||
|
||||
@@ -25,7 +25,6 @@ seq=`basename $0`
|
||||
echo "QA output created by $seq"
|
||||
|
||||
here=`pwd`
|
||||
tmp=/tmp/$$
|
||||
status=1 # failure is the default!
|
||||
|
||||
_cleanup()
|
||||
|
||||
@@ -27,7 +27,6 @@ seq=`basename $0`
|
||||
echo "QA output created by $seq"
|
||||
|
||||
here=`pwd`
|
||||
tmp=/tmp/$$
|
||||
status=1 # failure is the default!
|
||||
|
||||
_cleanup()
|
||||
|
||||
@@ -25,7 +25,6 @@ seq=`basename $0`
|
||||
echo "QA output created by $seq"
|
||||
|
||||
here=`pwd`
|
||||
tmp=/tmp/$$
|
||||
status=1 # failure is the default!
|
||||
|
||||
_cleanup()
|
||||
|
||||
@@ -25,7 +25,6 @@ seq=`basename $0`
|
||||
echo "QA output created by $seq"
|
||||
|
||||
here=`pwd`
|
||||
tmp=/tmp/$$
|
||||
status=1 # failure is the default!
|
||||
|
||||
_cleanup()
|
||||
|
||||
@@ -25,7 +25,6 @@ seq=`basename $0`
|
||||
echo "QA output created by $seq"
|
||||
|
||||
here=`pwd`
|
||||
tmp=/tmp/$$
|
||||
status=1 # failure is the default!
|
||||
|
||||
_cleanup()
|
||||
|
||||
@@ -25,7 +25,6 @@ seq=`basename $0`
|
||||
echo "QA output created by $seq"
|
||||
|
||||
here=`pwd`
|
||||
tmp=/tmp/$$
|
||||
status=1 # failure is the default!
|
||||
|
||||
_cleanup()
|
||||
|
||||
@@ -25,7 +25,6 @@ seq=`basename $0`
|
||||
echo "QA output created by $seq"
|
||||
|
||||
here=`pwd`
|
||||
tmp=/tmp/$$
|
||||
status=1 # failure is the default!
|
||||
|
||||
_cleanup()
|
||||
|
||||
@@ -28,7 +28,6 @@ seq=`basename $0`
|
||||
echo "QA output created by $seq"
|
||||
|
||||
here=`pwd`
|
||||
tmp=/tmp/$$
|
||||
status=1 # failure is the default!
|
||||
|
||||
_cleanup()
|
||||
|
||||
@@ -25,7 +25,6 @@ seq=`basename $0`
|
||||
echo "QA output created by $seq"
|
||||
|
||||
here=`pwd`
|
||||
tmp=/tmp/$$
|
||||
status=1 # failure is the default!
|
||||
|
||||
_cleanup()
|
||||
|
||||
@@ -25,7 +25,6 @@ seq=`basename $0`
|
||||
echo "QA output created by $seq"
|
||||
|
||||
here=`pwd`
|
||||
tmp=/tmp/$$
|
||||
status=1 # failure is the default!
|
||||
|
||||
_cleanup()
|
||||
|
||||
@@ -27,7 +27,6 @@ seq=`basename $0`
|
||||
echo "QA output created by $seq"
|
||||
|
||||
here=`pwd`
|
||||
tmp=/tmp/$$
|
||||
status=1 # failure is the default!
|
||||
|
||||
_cleanup()
|
||||
|
||||
@@ -25,7 +25,6 @@ seq=`basename $0`
|
||||
echo "QA output created by $seq"
|
||||
|
||||
here=`pwd`
|
||||
tmp=/tmp/$$
|
||||
status=1 # failure is the default!
|
||||
|
||||
_cleanup()
|
||||
@@ -57,12 +56,13 @@ do_test()
|
||||
} | $QEMU_IO
|
||||
}
|
||||
|
||||
for write_zero_cmd in "write -z" "aio_write -z"; do
|
||||
for align in 512 4k; do
|
||||
echo
|
||||
echo "== preparing image =="
|
||||
do_test $align "write -P 0xa 0x200 0x400" "$TEST_IMG" | _filter_qemu_io
|
||||
do_test $align "write -P 0xa 0x20000 0x600" "$TEST_IMG" | _filter_qemu_io
|
||||
do_test $align "write -z 0x400 0x20000" "$TEST_IMG" | _filter_qemu_io
|
||||
do_test $align "$write_zero_cmd 0x400 0x20000" "$TEST_IMG" | _filter_qemu_io
|
||||
|
||||
echo
|
||||
echo "== verifying patterns (1) =="
|
||||
@@ -73,7 +73,7 @@ for align in 512 4k; do
|
||||
echo
|
||||
echo "== rewriting zeroes =="
|
||||
do_test $align "write -P 0xb 0x10000 0x10000" "$TEST_IMG" | _filter_qemu_io
|
||||
do_test $align "write -z 0x10000 0x10000" "$TEST_IMG" | _filter_qemu_io
|
||||
do_test $align "$write_zero_cmd 0x10000 0x10000" "$TEST_IMG" | _filter_qemu_io
|
||||
|
||||
echo
|
||||
echo "== verifying patterns (2) =="
|
||||
@@ -82,7 +82,7 @@ for align in 512 4k; do
|
||||
echo
|
||||
echo "== rewriting unaligned zeroes =="
|
||||
do_test $align "write -P 0xb 0x0 0x1000" "$TEST_IMG" | _filter_qemu_io
|
||||
do_test $align "write -z 0x200 0x200" "$TEST_IMG" | _filter_qemu_io
|
||||
do_test $align "$write_zero_cmd 0x200 0x200" "$TEST_IMG" | _filter_qemu_io
|
||||
|
||||
echo
|
||||
echo "== verifying patterns (3) =="
|
||||
@@ -92,6 +92,7 @@ for align in 512 4k; do
|
||||
|
||||
echo
|
||||
done
|
||||
done
|
||||
|
||||
# success, all done
|
||||
echo "*** done"
|
||||
|
||||
@@ -42,6 +42,88 @@ read 3072/3072 bytes at offset 1024
|
||||
3 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
|
||||
|
||||
|
||||
== preparing image ==
|
||||
wrote 1024/1024 bytes at offset 512
|
||||
1 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
|
||||
wrote 1536/1536 bytes at offset 131072
|
||||
1.500 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
|
||||
wrote 131072/131072 bytes at offset 1024
|
||||
128 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
|
||||
|
||||
== verifying patterns (1) ==
|
||||
read 512/512 bytes at offset 512
|
||||
512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
|
||||
read 131072/131072 bytes at offset 1024
|
||||
128 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
|
||||
read 512/512 bytes at offset 132096
|
||||
512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
|
||||
|
||||
== rewriting zeroes ==
|
||||
wrote 65536/65536 bytes at offset 65536
|
||||
64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
|
||||
wrote 65536/65536 bytes at offset 65536
|
||||
64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
|
||||
|
||||
== verifying patterns (2) ==
|
||||
read 131072/131072 bytes at offset 1024
|
||||
128 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
|
||||
|
||||
== rewriting unaligned zeroes ==
|
||||
wrote 4096/4096 bytes at offset 0
|
||||
4 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
|
||||
wrote 512/512 bytes at offset 512
|
||||
512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
|
||||
|
||||
== verifying patterns (3) ==
|
||||
read 512/512 bytes at offset 0
|
||||
512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
|
||||
read 512/512 bytes at offset 512
|
||||
512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
|
||||
read 3072/3072 bytes at offset 1024
|
||||
3 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
|
||||
|
||||
|
||||
== preparing image ==
|
||||
wrote 1024/1024 bytes at offset 512
|
||||
1 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
|
||||
wrote 1536/1536 bytes at offset 131072
|
||||
1.500 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
|
||||
wrote 131072/131072 bytes at offset 1024
|
||||
128 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
|
||||
|
||||
== verifying patterns (1) ==
|
||||
read 512/512 bytes at offset 512
|
||||
512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
|
||||
read 131072/131072 bytes at offset 1024
|
||||
128 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
|
||||
read 512/512 bytes at offset 132096
|
||||
512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
|
||||
|
||||
== rewriting zeroes ==
|
||||
wrote 65536/65536 bytes at offset 65536
|
||||
64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
|
||||
wrote 65536/65536 bytes at offset 65536
|
||||
64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
|
||||
|
||||
== verifying patterns (2) ==
|
||||
read 131072/131072 bytes at offset 1024
|
||||
128 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
|
||||
|
||||
== rewriting unaligned zeroes ==
|
||||
wrote 4096/4096 bytes at offset 0
|
||||
4 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
|
||||
wrote 512/512 bytes at offset 512
|
||||
512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
|
||||
|
||||
== verifying patterns (3) ==
|
||||
read 512/512 bytes at offset 0
|
||||
512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
|
||||
read 512/512 bytes at offset 512
|
||||
512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
|
||||
read 3072/3072 bytes at offset 1024
|
||||
3 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
|
||||
|
||||
|
||||
== preparing image ==
|
||||
wrote 1024/1024 bytes at offset 512
|
||||
1 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
|
||||
|
||||
@@ -25,7 +25,6 @@ seq=`basename $0`
|
||||
echo "QA output created by $seq"
|
||||
|
||||
here=`pwd`
|
||||
tmp=/tmp/$$
|
||||
status=1 # failure is the default!
|
||||
|
||||
_cleanup()
|
||||
|
||||
@@ -26,7 +26,6 @@ seq=`basename $0`
|
||||
echo "QA output created by $seq"
|
||||
|
||||
here=`pwd`
|
||||
tmp=/tmp/$$
|
||||
status=1 # failure is the default!
|
||||
|
||||
_cleanup()
|
||||
|
||||
@@ -28,7 +28,6 @@ seq=`basename $0`
|
||||
echo "QA output created by $seq"
|
||||
|
||||
here=`pwd`
|
||||
tmp=/tmp/$$
|
||||
status=1 # failure is the default!
|
||||
|
||||
_cleanup()
|
||||
|
||||
@@ -25,7 +25,6 @@ seq=`basename $0`
|
||||
echo "QA output created by $seq"
|
||||
|
||||
here=`pwd`
|
||||
tmp=/tmp/$$
|
||||
status=1 # failure is the default!
|
||||
|
||||
_cleanup()
|
||||
|
||||
@@ -25,7 +25,6 @@ seq=`basename $0`
|
||||
echo "QA output created by $seq"
|
||||
|
||||
here=`pwd`
|
||||
tmp=/tmp/$$
|
||||
status=1 # failure is the default!
|
||||
|
||||
_cleanup()
|
||||
|
||||
@@ -28,7 +28,6 @@ seq=`basename $0`
|
||||
echo "QA output created by $seq"
|
||||
|
||||
here=`pwd`
|
||||
tmp=/tmp/$$
|
||||
status=1 # failure is the default!
|
||||
|
||||
_cleanup()
|
||||
|
||||
@@ -810,8 +810,7 @@ class TestRepairQuorum(iotests.QMPTestCase):
|
||||
self.assert_qmp(result, 'return', {})
|
||||
|
||||
self.complete_and_wait(drive="quorum0")
|
||||
result = self.vm.qmp('query-named-block-nodes')
|
||||
self.assert_qmp(result, 'return[0]/file', quorum_repair_img)
|
||||
self.assert_has_block_node("repair0", quorum_repair_img)
|
||||
# TODO: a better test requiring some QEMU infrastructure will be added
|
||||
# to check that this file is really driven by quorum
|
||||
self.vm.shutdown()
|
||||
@@ -833,8 +832,7 @@ class TestRepairQuorum(iotests.QMPTestCase):
|
||||
self.cancel_and_wait(drive="quorum0", force=True)
|
||||
# here we check that the last registered quorum file has not been
|
||||
# swapped out and unref
|
||||
result = self.vm.qmp('query-named-block-nodes')
|
||||
self.assert_qmp(result, 'return[1]/file', quorum_img3)
|
||||
self.assert_has_block_node(None, quorum_img3)
|
||||
self.vm.shutdown()
|
||||
|
||||
def test_cancel_after_ready(self):
|
||||
@@ -850,10 +848,9 @@ class TestRepairQuorum(iotests.QMPTestCase):
|
||||
self.assert_qmp(result, 'return', {})
|
||||
|
||||
self.wait_ready_and_cancel(drive="quorum0")
|
||||
result = self.vm.qmp('query-named-block-nodes')
|
||||
# here we check that the last registered quorum file has not been
|
||||
# swapped out and unref
|
||||
self.assert_qmp(result, 'return[1]/file', quorum_img3)
|
||||
self.assert_has_block_node(None, quorum_img3)
|
||||
self.vm.shutdown()
|
||||
self.assertTrue(iotests.compare_images(quorum_img2, quorum_repair_img),
|
||||
'target image does not match source after mirroring')
|
||||
@@ -974,8 +971,7 @@ class TestRepairQuorum(iotests.QMPTestCase):
|
||||
self.assert_qmp(result, 'return', {})
|
||||
|
||||
self.complete_and_wait(drive="quorum0")
|
||||
result = self.vm.qmp('query-named-block-nodes')
|
||||
self.assert_qmp(result, 'return[0]/file', quorum_repair_img)
|
||||
self.assert_has_block_node("repair0", quorum_repair_img)
|
||||
# TODO: a better test requiring some QEMU infrastructure will be added
|
||||
# to check that this file is really driven by quorum
|
||||
self.vm.shutdown()
|
||||
|
||||
@@ -25,7 +25,6 @@ seq=`basename $0`
|
||||
echo "QA output created by $seq"
|
||||
|
||||
here=`pwd`
|
||||
tmp=/tmp/$$
|
||||
status=1 # failure is the default!
|
||||
|
||||
_cleanup()
|
||||
|
||||
@@ -25,7 +25,6 @@ seq=`basename $0`
|
||||
echo "QA output created by $seq"
|
||||
|
||||
here=`pwd`
|
||||
tmp=/tmp/$$
|
||||
status=1 # failure is the default!
|
||||
|
||||
_cleanup()
|
||||
|
||||
@@ -25,7 +25,6 @@ seq=`basename $0`
|
||||
echo "QA output created by $seq"
|
||||
|
||||
here=`pwd`
|
||||
tmp=/tmp/$$
|
||||
status=1 # failure is the default!
|
||||
|
||||
_cleanup()
|
||||
|
||||
@@ -26,7 +26,6 @@ seq=`basename $0`
|
||||
echo "QA output created by $seq"
|
||||
|
||||
here=`pwd`
|
||||
tmp=/tmp/$$
|
||||
status=1 # failure is the default!
|
||||
|
||||
_cleanup()
|
||||
|
||||
@@ -25,7 +25,6 @@ seq=`basename $0`
|
||||
echo "QA output created by $seq"
|
||||
|
||||
here=`pwd`
|
||||
tmp=/tmp/$$
|
||||
status=1 # failure is the default!
|
||||
|
||||
_cleanup()
|
||||
|
||||
@@ -25,7 +25,6 @@ seq=`basename $0`
|
||||
echo "QA output created by $seq"
|
||||
|
||||
here=`pwd`
|
||||
tmp=/tmp/$$
|
||||
status=1 # failure is the default!
|
||||
|
||||
_cleanup()
|
||||
|
||||
@@ -25,7 +25,6 @@ seq=`basename $0`
|
||||
echo "QA output created by $seq"
|
||||
|
||||
here=`pwd`
|
||||
tmp=/tmp/$$
|
||||
status=1 # failure is the default!
|
||||
|
||||
_cleanup()
|
||||
|
||||
@@ -25,7 +25,6 @@ seq=`basename $0`
|
||||
echo "QA output created by $seq"
|
||||
|
||||
here=`pwd`
|
||||
tmp=/tmp/$$
|
||||
status=1 # failure is the default!
|
||||
|
||||
_cleanup()
|
||||
|
||||
@@ -25,7 +25,6 @@ seq=`basename $0`
|
||||
echo "QA output created by $seq"
|
||||
|
||||
here=`pwd`
|
||||
tmp=/tmp/$$
|
||||
status=1 # failure is the default!
|
||||
|
||||
_cleanup()
|
||||
|
||||
@@ -25,7 +25,6 @@ seq=`basename $0`
|
||||
echo "QA output created by $seq"
|
||||
|
||||
here=`pwd`
|
||||
tmp=/tmp/$$
|
||||
status=1 # failure is the default!
|
||||
|
||||
_cleanup()
|
||||
|
||||
@@ -27,7 +27,6 @@ seq=`basename $0`
|
||||
echo "QA output created by $seq"
|
||||
|
||||
here=`pwd`
|
||||
tmp=/tmp/$$
|
||||
status=1 # failure is the default!
|
||||
|
||||
nbd_unix_socket=$TEST_DIR/test_qemu_nbd_socket
|
||||
|
||||
@@ -25,7 +25,6 @@ seq=`basename $0`
|
||||
echo "QA output created by $seq"
|
||||
|
||||
here=`pwd`
|
||||
tmp=/tmp/$$
|
||||
status=1 # failure is the default!
|
||||
|
||||
_cleanup()
|
||||
|
||||
@@ -25,7 +25,6 @@ seq="$(basename $0)"
|
||||
echo "QA output created by $seq"
|
||||
|
||||
here="$PWD"
|
||||
tmp=/tmp/$$
|
||||
status=1 # failure is the default!
|
||||
|
||||
_cleanup()
|
||||
|
||||
@@ -25,7 +25,6 @@ seq=`basename $0`
|
||||
echo "QA output created by $seq"
|
||||
|
||||
here=`pwd`
|
||||
tmp=/tmp/$$
|
||||
status=1 # failure is the default!
|
||||
|
||||
_cleanup()
|
||||
|
||||
@@ -26,7 +26,6 @@ seq=`basename $0`
|
||||
echo "QA output created by $seq"
|
||||
|
||||
here=`pwd`
|
||||
tmp=/tmp/$$
|
||||
status=1 # failure is the default!
|
||||
|
||||
_cleanup()
|
||||
|
||||
@@ -26,7 +26,6 @@ seq=`basename $0`
|
||||
echo "QA output created by $seq"
|
||||
|
||||
here=`pwd`
|
||||
tmp=/tmp/$$
|
||||
status=1 # failure is the default!
|
||||
|
||||
_cleanup()
|
||||
|
||||
@@ -25,7 +25,6 @@ seq=`basename $0`
|
||||
echo "QA output created by $seq"
|
||||
|
||||
here=`pwd`
|
||||
tmp=/tmp/$$
|
||||
status=1 # failure is the default!
|
||||
|
||||
_cleanup()
|
||||
|
||||
@@ -25,7 +25,6 @@ seq="$(basename $0)"
|
||||
echo "QA output created by $seq"
|
||||
|
||||
here="$PWD"
|
||||
tmp=/tmp/$$
|
||||
status=1 # failure is the default!
|
||||
|
||||
_cleanup()
|
||||
|
||||
@@ -25,7 +25,6 @@ seq=`basename $0`
|
||||
echo "QA output created by $seq"
|
||||
|
||||
here=`pwd`
|
||||
tmp=/tmp/$$
|
||||
status=1 # failure is the default!
|
||||
|
||||
# get standard environment, filters and checks
|
||||
|
||||
@@ -25,7 +25,6 @@ seq="$(basename $0)"
|
||||
echo "QA output created by $seq"
|
||||
|
||||
here="$PWD"
|
||||
tmp=/tmp/$$
|
||||
status=1 # failure is the default!
|
||||
|
||||
_cleanup()
|
||||
|
||||
@@ -25,7 +25,6 @@ seq="$(basename $0)"
|
||||
echo "QA output created by $seq"
|
||||
|
||||
here="$PWD"
|
||||
tmp=/tmp/$$
|
||||
status=1 # failure is the default!
|
||||
|
||||
_cleanup()
|
||||
|
||||
@@ -26,7 +26,6 @@ seq=`basename $0`
|
||||
echo "QA output created by $seq"
|
||||
|
||||
here=`pwd`
|
||||
tmp=/tmp/$$
|
||||
status=1 # failure is the default!
|
||||
|
||||
_cleanup()
|
||||
|
||||
@@ -25,7 +25,6 @@ seq="$(basename $0)"
|
||||
echo "QA output created by $seq"
|
||||
|
||||
here="$PWD"
|
||||
tmp=/tmp/$$
|
||||
status=1 # failure is the default!
|
||||
|
||||
_cleanup()
|
||||
|
||||
@@ -25,7 +25,6 @@ seq="$(basename $0)"
|
||||
echo "QA output created by $seq"
|
||||
|
||||
here="$PWD"
|
||||
tmp=/tmp/$$
|
||||
status=1 # failure is the default!
|
||||
|
||||
_cleanup()
|
||||
|
||||
@@ -25,7 +25,6 @@ seq=`basename $0`
|
||||
echo "QA output created by $seq"
|
||||
|
||||
here=`pwd`
|
||||
tmp=/tmp/$$
|
||||
status=1 # failure is the default!
|
||||
|
||||
_cleanup()
|
||||
|
||||
@@ -25,7 +25,6 @@ seq=`basename $0`
|
||||
echo "QA output created by $seq"
|
||||
|
||||
here=`pwd`
|
||||
tmp=/tmp/$$
|
||||
status=1 # failure is the default!
|
||||
|
||||
_cleanup()
|
||||
|
||||
@@ -25,7 +25,6 @@ seq=`basename $0`
|
||||
echo "QA output created by $seq"
|
||||
|
||||
here=`pwd`
|
||||
tmp=/tmp/$$
|
||||
status=1 # failure is the default!
|
||||
|
||||
_cleanup()
|
||||
|
||||
@@ -25,7 +25,6 @@ seq=`basename $0`
|
||||
echo "QA output created by $seq"
|
||||
|
||||
here=`pwd`
|
||||
tmp=/tmp/$$
|
||||
status=1 # failure is the default!
|
||||
|
||||
_cleanup()
|
||||
|
||||
@@ -25,7 +25,6 @@ seq=`basename $0`
|
||||
echo "QA output created by $seq"
|
||||
|
||||
here=`pwd`
|
||||
tmp=/tmp/$$
|
||||
status=1 # failure is the default!
|
||||
|
||||
_cleanup()
|
||||
|
||||
@@ -25,7 +25,6 @@ seq=`basename $0`
|
||||
echo "QA output created by $seq"
|
||||
|
||||
here=`pwd`
|
||||
tmp=/tmp/$$
|
||||
status=1 # failure is the default!
|
||||
|
||||
_cleanup()
|
||||
|
||||
@@ -25,7 +25,6 @@ seq=`basename $0`
|
||||
echo "QA output created by $seq"
|
||||
|
||||
here=`pwd`
|
||||
tmp=/tmp/$$
|
||||
status=1 # failure is the default!
|
||||
|
||||
_cleanup()
|
||||
|
||||
@@ -25,7 +25,6 @@ seq=`basename $0`
|
||||
echo "QA output created by $seq"
|
||||
|
||||
here=`pwd`
|
||||
tmp=/tmp/$$
|
||||
status=1 # failure is the default!
|
||||
|
||||
_cleanup()
|
||||
|
||||
@@ -25,7 +25,6 @@ seq=`basename $0`
|
||||
echo "QA output created by $seq"
|
||||
|
||||
here=`pwd`
|
||||
tmp=/tmp/$$
|
||||
status=1 # failure is the default!
|
||||
|
||||
_cleanup()
|
||||
|
||||
@@ -25,7 +25,6 @@ seq=`basename $0`
|
||||
echo "QA output created by $seq"
|
||||
|
||||
here=`pwd`
|
||||
tmp=/tmp/$$
|
||||
status=1 # failure is the default!
|
||||
|
||||
# get standard environment, filters and checks
|
||||
|
||||
@@ -26,7 +26,6 @@ seq=`basename $0`
|
||||
echo "QA output created by $seq"
|
||||
|
||||
here=`pwd`
|
||||
tmp=/tmp/$$
|
||||
status=1 # failure is the default!
|
||||
|
||||
_cleanup()
|
||||
|
||||
@@ -25,7 +25,6 @@ seq=`basename $0`
|
||||
echo "QA output created by $seq"
|
||||
|
||||
here=`pwd`
|
||||
tmp=/tmp/$$
|
||||
status=1 # failure is the default!
|
||||
|
||||
_cleanup()
|
||||
|
||||
@@ -25,7 +25,6 @@ seq=`basename $0`
|
||||
echo "QA output created by $seq"
|
||||
|
||||
here=`pwd`
|
||||
tmp=/tmp/$$
|
||||
status=1 # failure is the default!
|
||||
|
||||
# get standard environment, filters and checks
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user