New patch
1
Changes since v3:
2
- Split the change into two patches [Philippe Mathieu-Daude].
1
3
4
It was found that 'qemu-nbd' is not able to work with some disk images
5
exported from Azure as it uses a currently unknown 'wa\0\0' 'creator app'
6
signature. QEMU currently supports two methods for determining the image
7
size: CHS and 'current_size' and the list of known 'creator app's is used
8
to decide between the two. Invert the logic in QEMU and make 'current_size'
9
the default as it seems that VPC and old QEMU are the only two legacy apps
10
where preferring CHS makes sense.
11
12
Vitaly Kuznetsov (2):
13
vpc: Split off vpc_ignore_current_size() helper
14
vpc: Read images exported from Azure correctly
15
16
block/vpc.c | 65 ++++++++++++++++++++++++++++-------------------------
17
1 file changed, 35 insertions(+), 30 deletions(-)
18
19
--
20
2.47.0
diff view generated by jsdifflib
New patch
1
In preparation to making changes to the logic deciding whether CHS or
2
'current_size' need to be used in determining the image size, split off
3
vpc_ignore_current_size() helper.
1
4
5
No functional change intended.
6
7
Signed-off-by: Vitaly Kuznetsov <vkuznets@redhat.com>
8
---
9
block/vpc.c | 67 +++++++++++++++++++++++++++++------------------------
10
1 file changed, 37 insertions(+), 30 deletions(-)
11
12
diff --git a/block/vpc.c b/block/vpc.c
13
index XXXXXXX..XXXXXXX 100644
14
--- a/block/vpc.c
15
+++ b/block/vpc.c
16
@@ -XXX,XX +XXX,XX @@ static void vpc_parse_options(BlockDriverState *bs, QemuOpts *opts,
17
}
18
}
19
20
+/*
21
+ * Microsoft Virtual PC and Microsoft Hyper-V produce and read
22
+ * VHD image sizes differently. VPC will rely on CHS geometry,
23
+ * while Hyper-V and disk2vhd use the size specified in the footer.
24
+ *
25
+ * We use a couple of approaches to try and determine the correct method:
26
+ * look at the Creator App field, and look for images that have CHS
27
+ * geometry that is the maximum value.
28
+ *
29
+ * If the CHS geometry is the maximum CHS geometry, then we assume that
30
+ * the size is the footer->current_size to avoid truncation. Otherwise,
31
+ * we follow the table based on footer->creator_app:
32
+ *
33
+ * Known creator apps:
34
+ * 'vpc ' : CHS Virtual PC (uses disk geometry)
35
+ * 'qemu' : CHS QEMU (uses disk geometry)
36
+ * 'qem2' : current_size QEMU (uses current_size)
37
+ * 'win ' : current_size Hyper-V
38
+ * 'd2v ' : current_size Disk2vhd
39
+ * 'tap\0' : current_size XenServer
40
+ * 'CTXS' : current_size XenConverter
41
+ *
42
+ * The user can override the table values via drive options, however
43
+ * even with an override we will still use current_size for images
44
+ * that have CHS geometry of the maximum size.
45
+ */
46
+static bool vpc_ignore_current_size(VHDFooter *footer)
47
+{
48
+ return !!strncmp(footer->creator_app, "win ", 4) &&
49
+ !!strncmp(footer->creator_app, "qem2", 4) &&
50
+ !!strncmp(footer->creator_app, "d2v ", 4) &&
51
+ !!strncmp(footer->creator_app, "CTXS", 4) &&
52
+ !!memcmp(footer->creator_app, "tap", 4));
53
+}
54
+
55
static int vpc_open(BlockDriverState *bs, QDict *options, int flags,
56
Error **errp)
57
{
58
@@ -XXX,XX +XXX,XX @@ static int vpc_open(BlockDriverState *bs, QDict *options, int flags,
59
bs->total_sectors = (int64_t)
60
be16_to_cpu(footer->cyls) * footer->heads * footer->secs_per_cyl;
61
62
- /* Microsoft Virtual PC and Microsoft Hyper-V produce and read
63
- * VHD image sizes differently. VPC will rely on CHS geometry,
64
- * while Hyper-V and disk2vhd use the size specified in the footer.
65
- *
66
- * We use a couple of approaches to try and determine the correct method:
67
- * look at the Creator App field, and look for images that have CHS
68
- * geometry that is the maximum value.
69
- *
70
- * If the CHS geometry is the maximum CHS geometry, then we assume that
71
- * the size is the footer->current_size to avoid truncation. Otherwise,
72
- * we follow the table based on footer->creator_app:
73
- *
74
- * Known creator apps:
75
- * 'vpc ' : CHS Virtual PC (uses disk geometry)
76
- * 'qemu' : CHS QEMU (uses disk geometry)
77
- * 'qem2' : current_size QEMU (uses current_size)
78
- * 'win ' : current_size Hyper-V
79
- * 'd2v ' : current_size Disk2vhd
80
- * 'tap\0' : current_size XenServer
81
- * 'CTXS' : current_size XenConverter
82
- *
83
- * The user can override the table values via drive options, however
84
- * even with an override we will still use current_size for images
85
- * that have CHS geometry of the maximum size.
86
- */
87
- use_chs = (!!strncmp(footer->creator_app, "win ", 4) &&
88
- !!strncmp(footer->creator_app, "qem2", 4) &&
89
- !!strncmp(footer->creator_app, "d2v ", 4) &&
90
- !!strncmp(footer->creator_app, "CTXS", 4) &&
91
- !!memcmp(footer->creator_app, "tap", 4)) || s->force_use_chs;
92
+ /* Use CHS or current_size to determine the image size. */
93
+ use_chs = vpc_ignore_current_size(footer) || s->force_use_chs;
94
95
if (!use_chs || bs->total_sectors == VHD_MAX_GEOMETRY || s->force_use_sz) {
96
bs->total_sectors = be64_to_cpu(footer->current_size) /
97
--
98
2.47.0
diff view generated by jsdifflib
...
...
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
block/vpc.c | 8 +++-----
21
CHS for 'vpc '/'qemu'.
26
1 file changed, 3 insertions(+), 5 deletions(-)
22
---
23
block/vpc.c | 2 ++
24
1 file changed, 2 insertions(+)
25
27
26
diff --git a/block/vpc.c b/block/vpc.c
28
diff --git a/block/vpc.c b/block/vpc.c
27
index XXXXXXX..XXXXXXX 100644
29
index XXXXXXX..XXXXXXX 100644
28
--- a/block/vpc.c
30
--- a/block/vpc.c
29
+++ b/block/vpc.c
31
+++ b/block/vpc.c
30
@@ -XXX,XX +XXX,XX @@ static int vpc_open(BlockDriverState *bs, QDict *options, int flags,
32
@@ -XXX,XX +XXX,XX @@ static void vpc_parse_options(BlockDriverState *bs, QemuOpts *opts,
31
* 'qemu' : CHS QEMU (uses disk geometry)
33
* 'd2v ' : current_size Disk2vhd
32
* 'qem2' : current_size QEMU (uses current_size)
34
* 'tap\0' : current_size XenServer
33
* 'win ' : current_size Hyper-V
35
* 'CTXS' : current_size XenConverter
34
+ * 'wa\0\0': current_size Azure
36
+ * 'wa\0\0': current_size Azure
35
* 'd2v ' : current_size Disk2vhd
37
*
36
* 'tap\0' : current_size XenServer
38
* The user can override the table values via drive options, however
37
* 'CTXS' : current_size XenConverter
39
* even with an override we will still use current_size for images
38
@@ -XXX,XX +XXX,XX @@ static int vpc_open(BlockDriverState *bs, QDict *options, int flags,
40
@@ -XXX,XX +XXX,XX @@ static void vpc_parse_options(BlockDriverState *bs, QemuOpts *opts,
39
* that have CHS geometry of the maximum size.
41
*/
40
*/
42
static bool vpc_ignore_current_size(VHDFooter *footer)
41
use_chs = (!!strncmp(footer->creator_app, "win ", 4) &&
43
{
42
+ !!memcmp(footer->creator_app, "wa\0", 4) &&
44
- return !!strncmp(footer->creator_app, "win ", 4) &&
43
!!strncmp(footer->creator_app, "qem2", 4) &&
45
- !!strncmp(footer->creator_app, "qem2", 4) &&
44
!!strncmp(footer->creator_app, "d2v ", 4) &&
46
- !!strncmp(footer->creator_app, "d2v ", 4) &&
45
!!strncmp(footer->creator_app, "CTXS", 4) &&
47
- !!strncmp(footer->creator_app, "CTXS", 4) &&
48
- !!memcmp(footer->creator_app, "tap", 4));
49
+ return !strncmp(footer->creator_app, "vpc ", 4) ||
50
+ !strncmp(footer->creator_app, "qemu", 4);
51
}
52
53
static int vpc_open(BlockDriverState *bs, QDict *options, int flags,
46
--
54
--
47
2.47.0
55
2.47.0
diff view generated by jsdifflib