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 28 /**************************************************************/
29 29  
30 30 #define HEADER_MAGIC "Bochs Virtual HD Image"
31   -#define HEADER_VERSION 0x00010000
  31 +#define HEADER_VERSION 0x00020000
  32 +#define HEADER_V1 0x00010000
32 33 #define HEADER_SIZE 512
33 34  
34 35 #define REDOLOG_TYPE "Redolog"
... ... @@ -37,7 +38,7 @@
37 38 // not allocated: 0xffffffff
38 39  
39 40 // always little-endian
40   -struct bochs_header {
  41 +struct bochs_header_v1 {
41 42 char magic[32]; // "Bochs Virtual HD Image"
42 43 char type[16]; // "Redolog"
43 44 char subtype[16]; // "Undoable" / "Volatile" / "Growing"
... ... @@ -56,6 +57,27 @@ struct bochs_header {
56 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 81 typedef struct BDRVBochsState {
60 82 int fd;
61 83  
... ... @@ -79,7 +101,8 @@ static int bochs_probe(const uint8_t *buf, int buf_size, const char *filename)
79 101 if (!strcmp(bochs->magic, HEADER_MAGIC) &&
80 102 !strcmp(bochs->type, REDOLOG_TYPE) &&
81 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 106 return 100;
84 107  
85 108 return 0;
... ... @@ -90,6 +113,7 @@ static int bochs_open(BlockDriverState *bs, const char *filename, int flags)
90 113 BDRVBochsState *s = bs->opaque;
91 114 int fd, i;
92 115 struct bochs_header bochs;
  116 + struct bochs_header_v1 header_v1;
93 117  
94 118 fd = open(filename, O_RDWR | O_BINARY);
95 119 if (fd < 0) {
... ... @@ -109,11 +133,17 @@ static int bochs_open(BlockDriverState *bs, const char *filename, int flags)
109 133 if (strcmp(bochs.magic, HEADER_MAGIC) ||
110 134 strcmp(bochs.type, REDOLOG_TYPE) ||
111 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 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 148 lseek(s->fd, le32_to_cpu(bochs.header), SEEK_SET);
119 149  
... ...