...
...
13
we can see that Azure uses a different 'Creator application' --
13
we can see that Azure uses a different 'Creator application' --
14
'wa\0\0' (offset 0x1c, likely reads as 'Windows Azure') and QEMU uses this
14
'wa\0\0' (offset 0x1c, likely reads as 'Windows Azure') and QEMU uses this
15
field to determine how it can get image size. Apparently, Azure uses 'new'
15
field to determine how it can get image size. Apparently, Azure uses 'new'
16
method, just like Hyper-V.
16
method, just like Hyper-V.
17
17
18
Overall, it seems that only VPC and old QEMUs need to be ignored as all new
19
creator apps seem to have reliable current_size. Invert the logic and make
20
'current_size' method the default to avoid adding every new creator app to
21
the list.
22
18
Signed-off-by: Vitaly Kuznetsov <vkuznets@redhat.com>
23
Signed-off-by: Vitaly Kuznetsov <vkuznets@redhat.com>
19
---
24
---
20
Alternatively, we can probably make 'current_size' the default and only use
25
Changes since v1/v2: invert the logic and make 'vpc' and 'qemu' use CHS
21
CHS for 'vpc '/'qemu'.
26
while defaulting to current_size.
22
---
27
---
23
block/vpc.c | 2 ++
28
block/vpc.c | 65 ++++++++++++++++++++++++++++-------------------------
24
1 file changed, 2 insertions(+)
29
1 file changed, 35 insertions(+), 30 deletions(-)
25
30
26
diff --git a/block/vpc.c b/block/vpc.c
31
diff --git a/block/vpc.c b/block/vpc.c
27
index XXXXXXX..XXXXXXX 100644
32
index XXXXXXX..XXXXXXX 100644
28
--- a/block/vpc.c
33
--- a/block/vpc.c
29
+++ b/block/vpc.c
34
+++ b/block/vpc.c
35
@@ -XXX,XX +XXX,XX @@ static void vpc_parse_options(BlockDriverState *bs, QemuOpts *opts,
36
}
37
}
38
39
+/*
40
+ * Microsoft Virtual PC and Microsoft Hyper-V produce and read
41
+ * VHD image sizes differently. VPC will rely on CHS geometry,
42
+ * while Hyper-V and disk2vhd use the size specified in the footer.
43
+ *
44
+ * We use a couple of approaches to try and determine the correct method:
45
+ * look at the Creator App field, and look for images that have CHS
46
+ * geometry that is the maximum value.
47
+ *
48
+ * If the CHS geometry is the maximum CHS geometry, then we assume that
49
+ * the size is the footer->current_size to avoid truncation. Otherwise,
50
+ * we follow the table based on footer->creator_app:
51
+ *
52
+ * Currently known creator apps:
53
+ * 'vpc ' : CHS Virtual PC (uses disk geometry)
54
+ * 'qemu' : CHS QEMU (uses disk geometry)
55
+ * 'qem2' : current_size QEMU (uses current_size)
56
+ * 'win ' : current_size Hyper-V
57
+ * 'd2v ' : current_size Disk2vhd
58
+ * 'tap\0' : current_size XenServer
59
+ * 'CTXS' : current_size XenConverter
60
+ * 'wa\0\0': current_size Azure
61
+ *
62
+ * The user can override the table values via drive options, however
63
+ * even with an override we will still use current_size for images
64
+ * that have CHS geometry of the maximum size.
65
+ */
66
+static bool vpc_ignore_current_size(VHDFooter *footer)
67
+{
68
+ return !strncmp(footer->creator_app, "vpc ", 4) ||
69
+ !strncmp(footer->creator_app, "qemu", 4);
70
+}
71
+
72
static int vpc_open(BlockDriverState *bs, QDict *options, int flags,
73
Error **errp)
74
{
30
@@ -XXX,XX +XXX,XX @@ static int vpc_open(BlockDriverState *bs, QDict *options, int flags,
75
@@ -XXX,XX +XXX,XX @@ static int vpc_open(BlockDriverState *bs, QDict *options, int flags,
31
* 'qemu' : CHS QEMU (uses disk geometry)
76
bs->total_sectors = (int64_t)
32
* 'qem2' : current_size QEMU (uses current_size)
77
be16_to_cpu(footer->cyls) * footer->heads * footer->secs_per_cyl;
33
* 'win ' : current_size Hyper-V
78
34
+ * 'wa\0\0': current_size Azure
79
- /* Microsoft Virtual PC and Microsoft Hyper-V produce and read
35
* 'd2v ' : current_size Disk2vhd
80
- * VHD image sizes differently. VPC will rely on CHS geometry,
36
* 'tap\0' : current_size XenServer
81
- * while Hyper-V and disk2vhd use the size specified in the footer.
37
* 'CTXS' : current_size XenConverter
82
- *
38
@@ -XXX,XX +XXX,XX @@ static int vpc_open(BlockDriverState *bs, QDict *options, int flags,
83
- * We use a couple of approaches to try and determine the correct method:
39
* that have CHS geometry of the maximum size.
84
- * look at the Creator App field, and look for images that have CHS
40
*/
85
- * geometry that is the maximum value.
41
use_chs = (!!strncmp(footer->creator_app, "win ", 4) &&
86
- *
42
+ !!memcmp(footer->creator_app, "wa\0", 4) &&
87
- * If the CHS geometry is the maximum CHS geometry, then we assume that
43
!!strncmp(footer->creator_app, "qem2", 4) &&
88
- * the size is the footer->current_size to avoid truncation. Otherwise,
44
!!strncmp(footer->creator_app, "d2v ", 4) &&
89
- * we follow the table based on footer->creator_app:
45
!!strncmp(footer->creator_app, "CTXS", 4) &&
90
- *
91
- * Known creator apps:
92
- * 'vpc ' : CHS Virtual PC (uses disk geometry)
93
- * 'qemu' : CHS QEMU (uses disk geometry)
94
- * 'qem2' : current_size QEMU (uses current_size)
95
- * 'win ' : current_size Hyper-V
96
- * 'd2v ' : current_size Disk2vhd
97
- * 'tap\0' : current_size XenServer
98
- * 'CTXS' : current_size XenConverter
99
- *
100
- * The user can override the table values via drive options, however
101
- * even with an override we will still use current_size for images
102
- * that have CHS geometry of the maximum size.
103
- */
104
- use_chs = (!!strncmp(footer->creator_app, "win ", 4) &&
105
- !!strncmp(footer->creator_app, "qem2", 4) &&
106
- !!strncmp(footer->creator_app, "d2v ", 4) &&
107
- !!strncmp(footer->creator_app, "CTXS", 4) &&
108
- !!memcmp(footer->creator_app, "tap", 4)) || s->force_use_chs;
109
+ /* Use CHS or current_size to determine the image size */
110
+ use_chs = vpc_ignore_current_size(footer) || s->force_use_chs;
111
112
if (!use_chs || bs->total_sectors == VHD_MAX_GEOMETRY || s->force_use_sz) {
113
bs->total_sectors = be64_to_cpu(footer->current_size) /
46
--
114
--
47
2.47.0
115
2.47.0
diff view generated by jsdifflib