Laszlo Ersek
2022-Apr-20 16:23 UTC
[Libguestfs] [v2v PATCH 1/9] types: introduce the "gcaps_default_cpu" field
Conversion will set "gcaps_default_cpu" to true iff the guest OS is capable of running on QEMU's default VCPU model. This capability will only matter for the QEMU and libvirt output modules, where, in case the capability is false *and* the source hypervisor does not specify a VCPU model, we'll have to manually present the guest OS with a VCPU that looks as close as possible to a physical CPU. (In that case, we'll specify host-passthrough.) The management applications targeted by the RHV and OpenStack output modules have their own explicit VCPU defaults, overriding the QEMU default model even in case the source hypervisor does not specify a VCPU model; those modules will ignore this capability therefore. Bugzilla: https://bugzilla.redhat.com/show_bug.cgi?id=2076013 Signed-off-by: Laszlo Ersek <lersek at redhat.com> --- lib/types.mli | 14 ++++++++++++++ convert/convert_linux.ml | 1 + convert/convert_windows.ml | 1 + lib/types.ml | 3 +++ 4 files changed, 19 insertions(+) diff --git a/lib/types.mli b/lib/types.mli index 37238cd75519..87544a0c59eb 100644 --- a/lib/types.mli +++ b/lib/types.mli @@ -251,52 +251,66 @@ val string_of_target_firmware : target_firmware -> string (** {2 Target NICs} *) type target_nics = source_nic list (** {2 Guest capabilities} *) type guestcaps = { gcaps_block_bus : guestcaps_block_type; gcaps_net_bus : guestcaps_net_type; (** Best block device and network device guest can access. These are determined during conversion by inspecting the guest (and in some cases conversion can actually enhance these by installing drivers). Thus this is not known until after conversion. *) gcaps_virtio_rng : bool; (** Guest supports virtio-rng. *) gcaps_virtio_balloon : bool; (** Guest supports virtio balloon. *) gcaps_isa_pvpanic : bool; (** Guest supports ISA pvpanic device. *) gcaps_virtio_socket : bool; (** Guest supports virtio socket. *) gcaps_machine : guestcaps_machine; (** Machine model. *) gcaps_arch : string; (** Architecture that KVM must emulate. *) gcaps_acpi : bool; (** True if guest supports acpi. *) gcaps_virtio_1_0 : bool; (** The guest supports the virtio devices that it does at the virtio-1.0 protocol level. *) + + gcaps_default_cpu : bool; + (** True iff the guest OS is capable of running on QEMU's default VCPU model. + + This capability only matters for the QEMU and libvirt output modules, + where, in case the capability is false *and* the source hypervisor does + not specify a VCPU model, we must manually present the guest OS with a + VCPU that looks as close as possible to a physical CPU. (In that case, we + specify host-passthrough.) + + The management applications targeted by the RHV and OpenStack output + modules have their own explicit VCPU defaults, overriding the QEMU default + model even in case the source hypervisor does not specify a VCPU model; + those modules ignore this capability therefore. Refer to RHBZ#2076013. *) } (** Guest capabilities after conversion. eg. Was virtio found or installed? *) and guestcaps_block_type = Virtio_blk | IDE and guestcaps_net_type = Virtio_net | E1000 | RTL8139 and guestcaps_machine = I440FX | Q35 | Virt val string_of_guestcaps : guestcaps -> string (** {2 Guest buses} *) type target_buses = { target_virtio_blk_bus : target_bus_slot array; target_ide_bus : target_bus_slot array; target_scsi_bus : target_bus_slot array; target_floppy_bus : target_bus_slot array; } (** Mapping of fixed and removable disks to buses. As shown in the diagram below, there are (currently) four buses attached to the target VM. Each contains a chain of fixed or removable disks. Slots can also be empty. We try to assign disks to the same slot number as they would occupy on the source, although that is not always possible. diff --git a/convert/convert_linux.ml b/convert/convert_linux.ml index c2bbce03637f..93b3922cac60 100644 --- a/convert/convert_linux.ml +++ b/convert/convert_linux.ml @@ -151,52 +151,53 @@ let convert (g : G.guestfs) source inspect keep_serial_console _ if major <= 4 then I440FX else Q35 | ("sles"|"suse-based"|"opensuse"), major -> if major < 10 then I440FX else Q35 | ("debian"|"ubuntu"|"linuxmint"|"kalilinux"), major -> if major < 4 then I440FX else Q35 (* reasonable default for all modern Linux kernels *) | _, _ -> Q35 ), true ) | _ -> Virt, true in (* Return guest capabilities from the convert () function. *) let guestcaps = { gcaps_block_bus = block_type; gcaps_net_bus = net_type; gcaps_virtio_rng = kernel.ki_supports_virtio_rng; gcaps_virtio_balloon = kernel.ki_supports_virtio_balloon; gcaps_isa_pvpanic = kernel.ki_supports_isa_pvpanic; gcaps_virtio_socket = kernel.ki_supports_virtio_socket; gcaps_machine = machine; gcaps_arch = Utils.kvm_arch inspect.i_arch; gcaps_acpi = acpi; gcaps_virtio_1_0 = virtio_1_0; + gcaps_default_cpu = true; } in guestcaps and augeas_grub_configuration () if bootloader#set_augeas_configuration () then Linux.augeas_reload g and unconfigure_xen () (* Remove kmod-xenpv-* (RHEL 3). *) let xenmods List.filter_map ( fun { G.app2_name = name } -> if name = "kmod-xenpv" || String.is_prefix name "kmod-xenpv-" then Some name else None ) inspect.i_apps in Linux.remove g inspect xenmods; (* Undo related nastiness if kmod-xenpv was installed. *) if xenmods <> [] then ( (* kmod-xenpv modules may have been manually copied to other kernels. * Hunt them down and destroy them. *) let dirs = g#find "/lib/modules" in diff --git a/convert/convert_windows.ml b/convert/convert_windows.ml index b53312a9aba4..34a5044dd338 100644 --- a/convert/convert_windows.ml +++ b/convert/convert_windows.ml @@ -282,52 +282,53 @@ let convert (g : G.guestfs) _ inspect _ static_ips Libosinfo_utils.os_support_of_osinfo_device_list (devices @ best_drv_devs) in (if q35 then Q35 else I440FX), vio10 with | Not_found -> (* Pivot on the year 2007. Any Windows version from earlier than * 2007 should use i440fx, anything 2007 or newer should use q35. * Luckily this coincides almost exactly with the release of NT 6. *) (if inspect.i_major_version < 6 then I440FX else Q35), true ) | _ -> Virt, true in (* Return guest capabilities from the convert () function. *) let guestcaps = { gcaps_block_bus = block_driver; gcaps_net_bus = net_driver; gcaps_virtio_rng = virtio_rng_supported; gcaps_virtio_balloon = virtio_ballon_supported; gcaps_isa_pvpanic = isa_pvpanic_supported; gcaps_virtio_socket = virtio_socket_supported; gcaps_machine = machine; gcaps_arch = Utils.kvm_arch inspect.i_arch; gcaps_acpi = true; gcaps_virtio_1_0 = virtio_1_0; + gcaps_default_cpu = true; } in guestcaps and configure_firstboot () (* Note that pnp_wait.exe must be the first firstboot script as it * suppresses PnP for all following scripts. *) let tool_path = virt_tools_data_dir () // "pnp_wait.exe" in if Sys.file_exists tool_path then configure_wait_pnp tool_path else debug (f_"%s is missing. Firstboot scripts may conflict with PnP.") tool_path; (* Install VMDP unconditionally, if available, but don't * warn about it if not. *) let tool_path = virt_tools_data_dir () // "vmdp.exe" in if Sys.file_exists tool_path then configure_vmdp tool_path; (* Install QEMU Guest Agent unconditionally and warn if missing *) let qemu_ga_files = Windows_virtio.copy_qemu_ga g inspect in if qemu_ga_files <> [] then configure_qemu_ga qemu_ga_files diff --git a/lib/types.ml b/lib/types.ml index 92ed0e52513d..7ffb868b1fbf 100644 --- a/lib/types.ml +++ b/lib/types.ml @@ -383,92 +383,95 @@ let string_of_target t target format: %s " (match t.target_file with | TargetFile s -> "[file] " ^ s | TargetURI s -> "[qemu] " ^ s) t.target_format type target_firmware = TargetBIOS | TargetUEFI let string_of_target_firmware = function | TargetBIOS -> "bios" | TargetUEFI -> "uefi" type target_nics = source_nic list type guestcaps = { gcaps_block_bus : guestcaps_block_type; gcaps_net_bus : guestcaps_net_type; gcaps_virtio_rng : bool; gcaps_virtio_balloon : bool; gcaps_isa_pvpanic : bool; gcaps_virtio_socket : bool; gcaps_machine : guestcaps_machine; gcaps_arch : string; gcaps_acpi : bool; gcaps_virtio_1_0 : bool; + gcaps_default_cpu : bool; } and guestcaps_block_type = Virtio_blk | IDE and guestcaps_net_type = Virtio_net | E1000 | RTL8139 and guestcaps_machine = I440FX | Q35 | Virt let string_of_block_type = function | Virtio_blk -> "virtio-blk" | IDE -> "ide" let string_of_net_type = function | Virtio_net -> "virtio-net" | E1000 -> "e1000" | RTL8139 -> "rtl8139" let string_of_machine = function | I440FX -> "i440fx" | Q35 -> "q35" | Virt -> "virt" let string_of_guestcaps gcaps sprintf "\ gcaps_block_bus = %s\n\ gcaps_net_bus = %s\n\ gcaps_virtio_rng = %b\n\ gcaps_virtio_balloon = %b\n\ gcaps_isa_pvpanic = %b\n\ gcaps_virtio_socket = %b\n\ gcaps_machine = %s\n\ gcaps_arch = %s\n\ gcaps_acpi = %b\n\ gcaps_virtio_1_0 = %b\n\ + gcaps_default_cpu = %b\n\ " (string_of_block_type gcaps.gcaps_block_bus) (string_of_net_type gcaps.gcaps_net_bus) gcaps.gcaps_virtio_rng gcaps.gcaps_virtio_balloon gcaps.gcaps_isa_pvpanic gcaps.gcaps_virtio_socket (string_of_machine gcaps.gcaps_machine) gcaps.gcaps_arch gcaps.gcaps_acpi gcaps.gcaps_virtio_1_0 + gcaps.gcaps_default_cpu type target_buses = { target_virtio_blk_bus : target_bus_slot array; target_ide_bus : target_bus_slot array; target_scsi_bus : target_bus_slot array; target_floppy_bus : target_bus_slot array; } and target_bus_slot | BusSlotEmpty | BusSlotDisk of source_disk | BusSlotRemovable of source_removable let string_of_target_bus_slots bus_name slots let slots Array.mapi ( fun slot_nr slot -> sprintf "%s slot %d:\n" bus_name slot_nr ^ (match slot with | BusSlotEmpty -> "\t(slot empty)\n" | BusSlotDisk d -> string_of_source_disk d | BusSlotRemovable r -> string_of_source_removable r ^ "\n" ) ) slots in String.concat "" (Array.to_list slots) -- 2.19.1.3.g30247aa5d201
Richard W.M. Jones
2022-Apr-20 16:47 UTC
[Libguestfs] [v2v PATCH 1/9] types: introduce the "gcaps_default_cpu" field
On Wed, Apr 20, 2022 at 06:23:25PM +0200, Laszlo Ersek wrote:> + gcaps_default_cpu : bool; > + (** True iff the guest OS is capable of running on QEMU's default VCPU model.Can we say ?(eg. -cpu qemu64)? here? Might be easier than trying to parse what QEMU's default VCPU means. Rest looks fine, so: Reviewed-by: Richard W.M. Jones <rjones at redhat.com> Rich. -- Richard Jones, Virtualization Group, Red Hat http://people.redhat.com/~rjones Read my programming and virtualization blog: http://rwmj.wordpress.com libguestfs lets you edit virtual machines. Supports shell scripting, bindings from many languages. http://libguestfs.org