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 |
1 | It was found that 'qemu-nbd' is not able to work with some disk images | 1 | In preparation to making changes to the logic deciding whether CHS or |
---|---|---|---|
2 | exported from Azure. Looking at the 512b footer (which contains VPC | 2 | 'current_size' need to be used in determining the image size, split off |
3 | metadata): | 3 | vpc_ignore_current_size() helper. |
4 | 4 | ||
5 | 00000000 63 6f 6e 65 63 74 69 78 00 00 00 02 00 01 00 00 |conectix........| | 5 | No functional change intended. |
6 | 00000010 ff ff ff ff ff ff ff ff 2e c7 9b 96 77 61 00 00 |............wa..| | ||
7 | 00000020 00 07 00 00 57 69 32 6b 00 00 00 01 40 00 00 00 |....Wi2k....@...| | ||
8 | 00000030 00 00 00 01 40 00 00 00 28 a2 10 3f 00 00 00 02 |....@...(..?....| | ||
9 | 00000040 ff ff e7 47 8c 54 df 94 bd 35 71 4c 94 5f e5 44 |...G.T...5qL._.D| | ||
10 | 00000050 44 53 92 1a 00 00 00 00 00 00 00 00 00 00 00 00 |DS..............| | ||
11 | 00000060 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................| | ||
12 | |||
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 | ||
15 | field to determine how it can get image size. Apparently, Azure uses 'new' | ||
16 | method, just like Hyper-V. | ||
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 | 6 | ||
23 | Signed-off-by: Vitaly Kuznetsov <vkuznets@redhat.com> | 7 | Signed-off-by: Vitaly Kuznetsov <vkuznets@redhat.com> |
24 | --- | 8 | --- |
25 | Changes since v1/v2: invert the logic and make 'vpc' and 'qemu' use CHS | 9 | block/vpc.c | 67 +++++++++++++++++++++++++++++------------------------ |
26 | while defaulting to current_size. | 10 | 1 file changed, 37 insertions(+), 30 deletions(-) |
27 | --- | ||
28 | block/vpc.c | 65 ++++++++++++++++++++++++++++------------------------- | ||
29 | 1 file changed, 35 insertions(+), 30 deletions(-) | ||
30 | 11 | ||
31 | diff --git a/block/vpc.c b/block/vpc.c | 12 | diff --git a/block/vpc.c b/block/vpc.c |
32 | index XXXXXXX..XXXXXXX 100644 | 13 | index XXXXXXX..XXXXXXX 100644 |
33 | --- a/block/vpc.c | 14 | --- a/block/vpc.c |
34 | +++ b/block/vpc.c | 15 | +++ b/block/vpc.c |
... | ... | ||
47 | + * | 28 | + * |
48 | + * If the CHS geometry is the maximum CHS geometry, then we assume that | 29 | + * 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, | 30 | + * the size is the footer->current_size to avoid truncation. Otherwise, |
50 | + * we follow the table based on footer->creator_app: | 31 | + * we follow the table based on footer->creator_app: |
51 | + * | 32 | + * |
52 | + * Currently known creator apps: | 33 | + * Known creator apps: |
53 | + * 'vpc ' : CHS Virtual PC (uses disk geometry) | 34 | + * 'vpc ' : CHS Virtual PC (uses disk geometry) |
54 | + * 'qemu' : CHS QEMU (uses disk geometry) | 35 | + * 'qemu' : CHS QEMU (uses disk geometry) |
55 | + * 'qem2' : current_size QEMU (uses current_size) | 36 | + * 'qem2' : current_size QEMU (uses current_size) |
56 | + * 'win ' : current_size Hyper-V | 37 | + * 'win ' : current_size Hyper-V |
57 | + * 'd2v ' : current_size Disk2vhd | 38 | + * 'd2v ' : current_size Disk2vhd |
58 | + * 'tap\0' : current_size XenServer | 39 | + * 'tap\0' : current_size XenServer |
59 | + * 'CTXS' : current_size XenConverter | 40 | + * 'CTXS' : current_size XenConverter |
60 | + * 'wa\0\0': current_size Azure | ||
61 | + * | 41 | + * |
62 | + * The user can override the table values via drive options, however | 42 | + * The user can override the table values via drive options, however |
63 | + * even with an override we will still use current_size for images | 43 | + * even with an override we will still use current_size for images |
64 | + * that have CHS geometry of the maximum size. | 44 | + * that have CHS geometry of the maximum size. |
65 | + */ | 45 | + */ |
66 | +static bool vpc_ignore_current_size(VHDFooter *footer) | 46 | +static bool vpc_ignore_current_size(VHDFooter *footer) |
67 | +{ | 47 | +{ |
68 | + return !strncmp(footer->creator_app, "vpc ", 4) || | 48 | + return !!strncmp(footer->creator_app, "win ", 4) && |
69 | + !strncmp(footer->creator_app, "qemu", 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)); | ||
70 | +} | 53 | +} |
71 | + | 54 | + |
72 | static int vpc_open(BlockDriverState *bs, QDict *options, int flags, | 55 | static int vpc_open(BlockDriverState *bs, QDict *options, int flags, |
73 | Error **errp) | 56 | Error **errp) |
74 | { | 57 | { |
... | ... | ||
104 | - use_chs = (!!strncmp(footer->creator_app, "win ", 4) && | 87 | - use_chs = (!!strncmp(footer->creator_app, "win ", 4) && |
105 | - !!strncmp(footer->creator_app, "qem2", 4) && | 88 | - !!strncmp(footer->creator_app, "qem2", 4) && |
106 | - !!strncmp(footer->creator_app, "d2v ", 4) && | 89 | - !!strncmp(footer->creator_app, "d2v ", 4) && |
107 | - !!strncmp(footer->creator_app, "CTXS", 4) && | 90 | - !!strncmp(footer->creator_app, "CTXS", 4) && |
108 | - !!memcmp(footer->creator_app, "tap", 4)) || s->force_use_chs; | 91 | - !!memcmp(footer->creator_app, "tap", 4)) || s->force_use_chs; |
109 | + /* Use CHS or current_size to determine the image size */ | 92 | + /* Use CHS or current_size to determine the image size. */ |
110 | + use_chs = vpc_ignore_current_size(footer) || s->force_use_chs; | 93 | + use_chs = vpc_ignore_current_size(footer) || s->force_use_chs; |
111 | 94 | ||
112 | if (!use_chs || bs->total_sectors == VHD_MAX_GEOMETRY || s->force_use_sz) { | 95 | if (!use_chs || bs->total_sectors == VHD_MAX_GEOMETRY || s->force_use_sz) { |
113 | bs->total_sectors = be64_to_cpu(footer->current_size) / | 96 | bs->total_sectors = be64_to_cpu(footer->current_size) / |
114 | -- | 97 | -- |
115 | 2.47.0 | 98 | 2.47.0 | diff view generated by jsdifflib |
New patch | |||
---|---|---|---|
1 | It was found that 'qemu-nbd' is not able to work with some disk images | ||
2 | exported from Azure. Looking at the 512b footer (which contains VPC | ||
3 | metadata): | ||
1 | 4 | ||
5 | 00000000 63 6f 6e 65 63 74 69 78 00 00 00 02 00 01 00 00 |conectix........| | ||
6 | 00000010 ff ff ff ff ff ff ff ff 2e c7 9b 96 77 61 00 00 |............wa..| | ||
7 | 00000020 00 07 00 00 57 69 32 6b 00 00 00 01 40 00 00 00 |....Wi2k....@...| | ||
8 | 00000030 00 00 00 01 40 00 00 00 28 a2 10 3f 00 00 00 02 |....@...(..?....| | ||
9 | 00000040 ff ff e7 47 8c 54 df 94 bd 35 71 4c 94 5f e5 44 |...G.T...5qL._.D| | ||
10 | 00000050 44 53 92 1a 00 00 00 00 00 00 00 00 00 00 00 00 |DS..............| | ||
11 | 00000060 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................| | ||
12 | |||
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 | ||
15 | field to determine how it can get image size. Apparently, Azure uses 'new' | ||
16 | method, just like Hyper-V. | ||
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 | |||
23 | Signed-off-by: Vitaly Kuznetsov <vkuznets@redhat.com> | ||
24 | --- | ||
25 | block/vpc.c | 8 +++----- | ||
26 | 1 file changed, 3 insertions(+), 5 deletions(-) | ||
27 | |||
28 | diff --git a/block/vpc.c b/block/vpc.c | ||
29 | index XXXXXXX..XXXXXXX 100644 | ||
30 | --- a/block/vpc.c | ||
31 | +++ b/block/vpc.c | ||
32 | @@ -XXX,XX +XXX,XX @@ static void vpc_parse_options(BlockDriverState *bs, QemuOpts *opts, | ||
33 | * 'd2v ' : current_size Disk2vhd | ||
34 | * 'tap\0' : current_size XenServer | ||
35 | * 'CTXS' : current_size XenConverter | ||
36 | + * 'wa\0\0': current_size Azure | ||
37 | * | ||
38 | * The user can override the table values via drive options, however | ||
39 | * even with an override we will still use current_size for images | ||
40 | @@ -XXX,XX +XXX,XX @@ static void vpc_parse_options(BlockDriverState *bs, QemuOpts *opts, | ||
41 | */ | ||
42 | static bool vpc_ignore_current_size(VHDFooter *footer) | ||
43 | { | ||
44 | - return !!strncmp(footer->creator_app, "win ", 4) && | ||
45 | - !!strncmp(footer->creator_app, "qem2", 4) && | ||
46 | - !!strncmp(footer->creator_app, "d2v ", 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, | ||
54 | -- | ||
55 | 2.47.0 | diff view generated by jsdifflib |