Commit 6850dd945ea7eb0beedb25435bf2bc16741aec38
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 | ... | ... |