Skip to content

Commit

Permalink
vmdk: allow specification of tools version
Browse files Browse the repository at this point in the history
VMDK files support an attribute that represents the version of the guest
tools that are installed on the disk.
This attribute is used by vSphere before a machine has been started to
determine if the VM has the guest tools installed.
This is important when configuring "Operating system customizations" in
vSphere, as it checks for the presence of the guest tools before
allowing those customizations.
Thus when the VM has not yet booted normally it would be impossible to
customize it, therefore preventing a customized first-boot.

The attribute should not hurt on disks that do not have the guest tools
installed and indeed the VMware tools also unconditionally add this
attribute.
(Defaulting to the value "2147483647", as is done in this patch)

Signed-off-by: Thomas Weißschuh <[email protected]>
Message-Id: <[email protected]>
[hreitz: Added missing '#' in block-core.json]
Signed-off-by: Hanna Reitz <[email protected]>
  • Loading branch information
Thomas Weißschuh authored and XanClic committed Nov 2, 2021
1 parent 87e4d4a commit f3d43df
Show file tree
Hide file tree
Showing 2 changed files with 23 additions and 4 deletions.
24 changes: 20 additions & 4 deletions block/vmdk.c
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,7 @@
#define VMDK_ZEROED (-3)

#define BLOCK_OPT_ZEROED_GRAIN "zeroed_grain"
#define BLOCK_OPT_TOOLSVERSION "toolsversion"

typedef struct {
uint32_t version;
Expand Down Expand Up @@ -2344,6 +2345,7 @@ static int coroutine_fn vmdk_co_do_create(int64_t size,
BlockdevVmdkAdapterType adapter_type,
const char *backing_file,
const char *hw_version,
const char *toolsversion,
bool compat6,
bool zeroed_grain,
vmdk_create_extent_fn extent_fn,
Expand Down Expand Up @@ -2384,7 +2386,8 @@ static int coroutine_fn vmdk_co_do_create(int64_t size,
"ddb.geometry.cylinders = \"%" PRId64 "\"\n"
"ddb.geometry.heads = \"%" PRIu32 "\"\n"
"ddb.geometry.sectors = \"63\"\n"
"ddb.adapterType = \"%s\"\n";
"ddb.adapterType = \"%s\"\n"
"ddb.toolsVersion = \"%s\"\n";

ext_desc_lines = g_string_new(NULL);

Expand All @@ -2401,6 +2404,9 @@ static int coroutine_fn vmdk_co_do_create(int64_t size,
if (!hw_version) {
hw_version = "4";
}
if (!toolsversion) {
toolsversion = "2147483647";
}

if (adapter_type != BLOCKDEV_VMDK_ADAPTER_TYPE_IDE) {
/* that's the number of heads with which vmware operates when
Expand Down Expand Up @@ -2525,7 +2531,8 @@ static int coroutine_fn vmdk_co_do_create(int64_t size,
size /
(int64_t)(63 * number_heads * BDRV_SECTOR_SIZE),
number_heads,
BlockdevVmdkAdapterType_str(adapter_type));
BlockdevVmdkAdapterType_str(adapter_type),
toolsversion);
desc_len = strlen(desc);
/* the descriptor offset = 0x200 */
if (!split && !flat) {
Expand Down Expand Up @@ -2617,6 +2624,7 @@ static int coroutine_fn vmdk_co_create_opts(BlockDriver *drv,
BlockdevVmdkAdapterType adapter_type_enum;
char *backing_file = NULL;
char *hw_version = NULL;
char *toolsversion = NULL;
char *fmt = NULL;
BlockdevVmdkSubformat subformat;
int ret = 0;
Expand Down Expand Up @@ -2649,6 +2657,7 @@ static int coroutine_fn vmdk_co_create_opts(BlockDriver *drv,
adapter_type = qemu_opt_get_del(opts, BLOCK_OPT_ADAPTER_TYPE);
backing_file = qemu_opt_get_del(opts, BLOCK_OPT_BACKING_FILE);
hw_version = qemu_opt_get_del(opts, BLOCK_OPT_HWVERSION);
toolsversion = qemu_opt_get_del(opts, BLOCK_OPT_TOOLSVERSION);
compat6 = qemu_opt_get_bool_del(opts, BLOCK_OPT_COMPAT6, false);
if (strcmp(hw_version, "undefined") == 0) {
g_free(hw_version);
Expand Down Expand Up @@ -2692,14 +2701,15 @@ static int coroutine_fn vmdk_co_create_opts(BlockDriver *drv,
.opts = opts,
};
ret = vmdk_co_do_create(total_size, subformat, adapter_type_enum,
backing_file, hw_version, compat6, zeroed_grain,
vmdk_co_create_opts_cb, &data, errp);
backing_file, hw_version, toolsversion, compat6,
zeroed_grain, vmdk_co_create_opts_cb, &data, errp);

exit:
g_free(backing_fmt);
g_free(adapter_type);
g_free(backing_file);
g_free(hw_version);
g_free(toolsversion);
g_free(fmt);
g_free(desc);
g_free(path);
Expand Down Expand Up @@ -2782,6 +2792,7 @@ static int coroutine_fn vmdk_co_create(BlockdevCreateOptions *create_options,
opts->adapter_type,
opts->backing_file,
opts->hwversion,
opts->toolsversion,
false,
opts->zeroed_grain,
vmdk_co_create_cb,
Expand Down Expand Up @@ -3031,6 +3042,11 @@ static QemuOptsList vmdk_create_opts = {
.help = "VMDK hardware version",
.def_value_str = "undefined"
},
{
.name = BLOCK_OPT_TOOLSVERSION,
.type = QEMU_OPT_STRING,
.help = "VMware guest tools version",
},
{
.name = BLOCK_OPT_SUBFMT,
.type = QEMU_OPT_STRING,
Expand Down
3 changes: 3 additions & 0 deletions qapi/block-core.json
Original file line number Diff line number Diff line change
Expand Up @@ -4691,6 +4691,8 @@
# @adapter-type: The adapter type used to fill in the descriptor. Default: ide.
# @hwversion: Hardware version. The meaningful options are "4" or "6".
# Default: "4".
# @toolsversion: VMware guest tools version.
# Default: "2147483647" (Since 6.2)
# @zeroed-grain: Whether to enable zeroed-grain feature for sparse subformats.
# Default: false.
#
Expand All @@ -4704,6 +4706,7 @@
'*backing-file': 'str',
'*adapter-type': 'BlockdevVmdkAdapterType',
'*hwversion': 'str',
'*toolsversion': 'str',
'*zeroed-grain': 'bool' } }


Expand Down

0 comments on commit f3d43df

Please sign in to comment.