Commit 6850dd945ea7eb0beedb25435bf2bc16741aec38

Authored by ths
1 parent b9209030

Support for Bochs "growing" images, by Volker Ruppert.


git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@2296 c046a42c-6fe2-441c-8c8c-71466251a162
Showing 1 changed file with 35 additions and 5 deletions
block-bochs.c
@@ -28,7 +28,8 @@ @@ -28,7 +28,8 @@
28 /**************************************************************/ 28 /**************************************************************/
29 29
30 #define HEADER_MAGIC "Bochs Virtual HD Image" 30 #define HEADER_MAGIC "Bochs Virtual HD Image"
31 -#define HEADER_VERSION 0x00010000 31 +#define HEADER_VERSION 0x00020000
  32 +#define HEADER_V1 0x00010000
32 #define HEADER_SIZE 512 33 #define HEADER_SIZE 512
33 34
34 #define REDOLOG_TYPE "Redolog" 35 #define REDOLOG_TYPE "Redolog"
@@ -37,7 +38,7 @@ @@ -37,7 +38,7 @@
37 // not allocated: 0xffffffff 38 // not allocated: 0xffffffff
38 39
39 // always little-endian 40 // always little-endian
40 -struct bochs_header { 41 +struct bochs_header_v1 {
41 char magic[32]; // "Bochs Virtual HD Image" 42 char magic[32]; // "Bochs Virtual HD Image"
42 char type[16]; // "Redolog" 43 char type[16]; // "Redolog"
43 char subtype[16]; // "Undoable" / "Volatile" / "Growing" 44 char subtype[16]; // "Undoable" / "Volatile" / "Growing"
@@ -56,6 +57,27 @@ struct bochs_header { @@ -56,6 +57,27 @@ struct bochs_header {
56 } extra; 57 } extra;
57 }; 58 };
58 59
  60 +// always little-endian
  61 +struct bochs_header {
  62 + char magic[32]; // "Bochs Virtual HD Image"
  63 + char type[16]; // "Redolog"
  64 + char subtype[16]; // "Undoable" / "Volatile" / "Growing"
  65 + uint32_t version;
  66 + uint32_t header; // size of header
  67 +
  68 + union {
  69 + struct {
  70 + uint32_t catalog; // num of entries
  71 + uint32_t bitmap; // bitmap size
  72 + uint32_t extent; // extent size
  73 + uint32_t reserved; // for ???
  74 + uint64_t disk; // disk size
  75 + char padding[HEADER_SIZE - 64 - 8 - 24];
  76 + } redolog;
  77 + char padding[HEADER_SIZE - 64 - 8];
  78 + } extra;
  79 +};
  80 +
59 typedef struct BDRVBochsState { 81 typedef struct BDRVBochsState {
60 int fd; 82 int fd;
61 83
@@ -79,7 +101,8 @@ static int bochs_probe(const uint8_t *buf, int buf_size, const char *filename) @@ -79,7 +101,8 @@ static int bochs_probe(const uint8_t *buf, int buf_size, const char *filename)
79 if (!strcmp(bochs->magic, HEADER_MAGIC) && 101 if (!strcmp(bochs->magic, HEADER_MAGIC) &&
80 !strcmp(bochs->type, REDOLOG_TYPE) && 102 !strcmp(bochs->type, REDOLOG_TYPE) &&
81 !strcmp(bochs->subtype, GROWING_TYPE) && 103 !strcmp(bochs->subtype, GROWING_TYPE) &&
82 - (le32_to_cpu(bochs->version) == HEADER_VERSION)) 104 + ((le32_to_cpu(bochs->version) == HEADER_VERSION) ||
  105 + (le32_to_cpu(bochs->version) == HEADER_V1)))
83 return 100; 106 return 100;
84 107
85 return 0; 108 return 0;
@@ -90,6 +113,7 @@ static int bochs_open(BlockDriverState *bs, const char *filename, int flags) @@ -90,6 +113,7 @@ static int bochs_open(BlockDriverState *bs, const char *filename, int flags)
90 BDRVBochsState *s = bs->opaque; 113 BDRVBochsState *s = bs->opaque;
91 int fd, i; 114 int fd, i;
92 struct bochs_header bochs; 115 struct bochs_header bochs;
  116 + struct bochs_header_v1 header_v1;
93 117
94 fd = open(filename, O_RDWR | O_BINARY); 118 fd = open(filename, O_RDWR | O_BINARY);
95 if (fd < 0) { 119 if (fd < 0) {
@@ -109,11 +133,17 @@ static int bochs_open(BlockDriverState *bs, const char *filename, int flags) @@ -109,11 +133,17 @@ static int bochs_open(BlockDriverState *bs, const char *filename, int flags)
109 if (strcmp(bochs.magic, HEADER_MAGIC) || 133 if (strcmp(bochs.magic, HEADER_MAGIC) ||
110 strcmp(bochs.type, REDOLOG_TYPE) || 134 strcmp(bochs.type, REDOLOG_TYPE) ||
111 strcmp(bochs.subtype, GROWING_TYPE) || 135 strcmp(bochs.subtype, GROWING_TYPE) ||
112 - (le32_to_cpu(bochs.version) != HEADER_VERSION)) { 136 + ((le32_to_cpu(bochs.version) != HEADER_VERSION) &&
  137 + (le32_to_cpu(bochs.version) != HEADER_V1))) {
113 goto fail; 138 goto fail;
114 } 139 }
115 140
116 - bs->total_sectors = le64_to_cpu(bochs.extra.redolog.disk) / 512; 141 + if (le32_to_cpu(bochs.version) == HEADER_V1) {
  142 + memcpy(&header_v1, &bochs, sizeof(bochs));
  143 + bs->total_sectors = le64_to_cpu(header_v1.extra.redolog.disk) / 512;
  144 + } else {
  145 + bs->total_sectors = le64_to_cpu(bochs.extra.redolog.disk) / 512;
  146 + }
117 147
118 lseek(s->fd, le32_to_cpu(bochs.header), SEEK_SET); 148 lseek(s->fd, le32_to_cpu(bochs.header), SEEK_SET);
119 149