提交 7b2f89c4 编写于 作者: A Anthony Liguori

Merge remote-tracking branch 'kwolf/for-anthony' into staging

* kwolf/for-anthony:
  virtio-blk: hide VIRTIO_BLK_F_CONFIG_WCE from old machine types
  Documentation: Warn against qemu-img on active image
  vmdk: Read footer for streamOptimized images
  vmdk: Fix header structure

Conflicts:
	hw/virtio-blk.c
...@@ -35,6 +35,7 @@ ...@@ -35,6 +35,7 @@
#define VMDK4_FLAG_RGD (1 << 1) #define VMDK4_FLAG_RGD (1 << 1)
#define VMDK4_FLAG_COMPRESS (1 << 16) #define VMDK4_FLAG_COMPRESS (1 << 16)
#define VMDK4_FLAG_MARKER (1 << 17) #define VMDK4_FLAG_MARKER (1 << 17)
#define VMDK4_GD_AT_END 0xffffffffffffffffULL
typedef struct { typedef struct {
uint32_t version; uint32_t version;
...@@ -57,8 +58,8 @@ typedef struct { ...@@ -57,8 +58,8 @@ typedef struct {
int64_t desc_offset; int64_t desc_offset;
int64_t desc_size; int64_t desc_size;
int32_t num_gtes_per_gte; int32_t num_gtes_per_gte;
int64_t gd_offset;
int64_t rgd_offset; int64_t rgd_offset;
int64_t gd_offset;
int64_t grain_offset; int64_t grain_offset;
char filler[1]; char filler[1];
char check_bytes[4]; char check_bytes[4];
...@@ -115,6 +116,13 @@ typedef struct VmdkGrainMarker { ...@@ -115,6 +116,13 @@ typedef struct VmdkGrainMarker {
uint8_t data[0]; uint8_t data[0];
} VmdkGrainMarker; } VmdkGrainMarker;
enum {
MARKER_END_OF_STREAM = 0,
MARKER_GRAIN_TABLE = 1,
MARKER_GRAIN_DIRECTORY = 2,
MARKER_FOOTER = 3,
};
static int vmdk_probe(const uint8_t *buf, int buf_size, const char *filename) static int vmdk_probe(const uint8_t *buf, int buf_size, const char *filename)
{ {
uint32_t magic; uint32_t magic;
...@@ -451,6 +459,54 @@ static int vmdk_open_vmdk4(BlockDriverState *bs, ...@@ -451,6 +459,54 @@ static int vmdk_open_vmdk4(BlockDriverState *bs,
if (header.capacity == 0 && header.desc_offset) { if (header.capacity == 0 && header.desc_offset) {
return vmdk_open_desc_file(bs, flags, header.desc_offset << 9); return vmdk_open_desc_file(bs, flags, header.desc_offset << 9);
} }
if (le64_to_cpu(header.gd_offset) == VMDK4_GD_AT_END) {
/*
* The footer takes precedence over the header, so read it in. The
* footer starts at offset -1024 from the end: One sector for the
* footer, and another one for the end-of-stream marker.
*/
struct {
struct {
uint64_t val;
uint32_t size;
uint32_t type;
uint8_t pad[512 - 16];
} QEMU_PACKED footer_marker;
uint32_t magic;
VMDK4Header header;
uint8_t pad[512 - 4 - sizeof(VMDK4Header)];
struct {
uint64_t val;
uint32_t size;
uint32_t type;
uint8_t pad[512 - 16];
} QEMU_PACKED eos_marker;
} QEMU_PACKED footer;
ret = bdrv_pread(file,
bs->file->total_sectors * 512 - 1536,
&footer, sizeof(footer));
if (ret < 0) {
return ret;
}
/* Some sanity checks for the footer */
if (be32_to_cpu(footer.magic) != VMDK4_MAGIC ||
le32_to_cpu(footer.footer_marker.size) != 0 ||
le32_to_cpu(footer.footer_marker.type) != MARKER_FOOTER ||
le64_to_cpu(footer.eos_marker.val) != 0 ||
le32_to_cpu(footer.eos_marker.size) != 0 ||
le32_to_cpu(footer.eos_marker.type) != MARKER_END_OF_STREAM)
{
return -EINVAL;
}
header = footer.header;
}
l1_entry_sectors = le32_to_cpu(header.num_gtes_per_gte) l1_entry_sectors = le32_to_cpu(header.num_gtes_per_gte)
* le64_to_cpu(header.granularity); * le64_to_cpu(header.granularity);
if (l1_entry_sectors == 0) { if (l1_entry_sectors == 0) {
......
...@@ -104,6 +104,7 @@ struct VirtIOBlkConf ...@@ -104,6 +104,7 @@ struct VirtIOBlkConf
BlockConf conf; BlockConf conf;
char *serial; char *serial;
uint32_t scsi; uint32_t scsi;
uint32_t config_wce;
}; };
#define DEFINE_VIRTIO_BLK_FEATURES(_state, _field) \ #define DEFINE_VIRTIO_BLK_FEATURES(_state, _field) \
......
...@@ -886,6 +886,7 @@ static Property virtio_blk_properties[] = { ...@@ -886,6 +886,7 @@ static Property virtio_blk_properties[] = {
#ifdef __linux__ #ifdef __linux__
DEFINE_PROP_BIT("scsi", VirtIOPCIProxy, blk.scsi, 0, true), DEFINE_PROP_BIT("scsi", VirtIOPCIProxy, blk.scsi, 0, true),
#endif #endif
DEFINE_PROP_BIT("config-wce", VirtIOPCIProxy, blk.config_wce, 0, true),
DEFINE_PROP_BIT("ioeventfd", VirtIOPCIProxy, flags, VIRTIO_PCI_FLAG_USE_IOEVENTFD_BIT, true), DEFINE_PROP_BIT("ioeventfd", VirtIOPCIProxy, flags, VIRTIO_PCI_FLAG_USE_IOEVENTFD_BIT, true),
DEFINE_PROP_UINT32("vectors", VirtIOPCIProxy, nvectors, 2), DEFINE_PROP_UINT32("vectors", VirtIOPCIProxy, nvectors, 2),
DEFINE_VIRTIO_BLK_FEATURES(VirtIOPCIProxy, host_features), DEFINE_VIRTIO_BLK_FEATURES(VirtIOPCIProxy, host_features),
......
...@@ -4,6 +4,16 @@ usage: qemu-img command [command options] ...@@ -4,6 +4,16 @@ usage: qemu-img command [command options]
@c man end @c man end
@end example @end example
@c man begin DESCRIPTION
qemu-img allows you to create, convert and modify images offline. It can handle
all image formats supported by QEMU.
@b{Warning:} Never use qemu-img to modify images in use by a running virtual
machine or any other process; this may destroy the image. Also, be aware that
querying an image that is being modified by another process may encounter
inconsistent state.
@c man end
@c man begin OPTIONS @c man begin OPTIONS
The following commands are supported: The following commands are supported:
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册