105 Commits

Author SHA1 Message Date
Richard W.M. Jones
4b39b7bd0f convert: Display osinfo in "Converting ..." message
eg:

[ 9.3] Converting Windows Server 2022 Phony Edition (win2k22) to run on KVM

Reported-by: Ming Xie
Fixes: https://issues.redhat.com/browse/RHEL-56784
Signed-off-by: Richard W.M. Jones <rjones@redhat.com>
2024-08-31 09:40:21 +01:00
Richard W.M. Jones
cb56f6f94d convert: windows: Online all virtio disks at first boot
Windows 2022 (and possibly earlier versions back to around 2019) will
force offline any non-boot disks which change bus, apparently as a
security mitigation.  The effect of this is that although the system
drive (C:) is present after conversion, other drives may seem to
disappear.

Running a Powershell script to bring all disks online seems risky.
The compromise is to bring online only virtio disks at first boot.

To further reduce risk, we only do this if there are non-system disks
(ie. > 1 disks in total), and only if we installed virtio drivers.

Fixes: https://issues.redhat.com/browse/RHEL-55763
Fixes: https://issues.redhat.com/browse/RHEL-55837
Related: https://issues.redhat.com/browse/MTV-1299
Related: https://bugzilla.redhat.com/show_bug.cgi?id=1662286
Signed-off-by: Richard W.M. Jones <rjones@redhat.com>
Thanks: Martin Necas
Acked-by: Martin Necas
2024-08-27 13:19:36 +01:00
Richard W.M. Jones
ade62ebdb5 v2v: Add support for virt-customize options
For higher level tools making further arbitrary changes to the guest
post-conversion, especially adding more firstboot scripts, it's useful
if we have various features from virt-customize.  Particularly the
ability to upload and run scripts.  Since we have the virt-customize
code in the common/ submodule, the easiest thing to do is to add the
virt-customize options, the same way it is done in virt-builder and
virt-sysprep.

Also updates the common submodule to get:

Richard W.M. Jones (1):
      mlcustomize: Move virt-customize modules to mlcustomize/
2024-08-20 11:46:31 +01:00
Richard W.M. Jones
373ee61ab5 convert: Move SELinux relabelling step to common conversion code
Simple code motion.  SELinux relabelling is a no-op for
non-Linux/non-SELinux guests.
2024-08-20 10:14:06 +01:00
Richard W.M. Jones
0e3fb1ba37 convert: windows: Allow increasing verboseness of driver installation
To try to chase an issue with installing drivers on 32 bit Windows 10,
let's increase the LogLevel to maximum to get maximum logging.  As I
understand it we shouldn't leave this on all the time, so it is
commented out by default.

This setting is explained further here:
https://learn.microsoft.com/en-us/windows-hardware/drivers/install/setting-setupapi-logging-levels

Thanks: Vadim Rozenfeld
Related: https://issues.redhat.com/browse/RHEL-53990
2024-08-14 16:30:25 +01:00
Richard W.M. Jones
bc845c124c convert: windows: Don't wait indefinitely for netkvm.sys
In the network configuration script, don't wait indefinitely for the
netkvm.sys (virtio-net) adapter to become available.  It might not
have been installed correctly or there could be some other reason why
it doesn't work.  This of course indicates a bug in the guest, but
it's still better than looping forever.

Reported-by: Ming Xie
Related: https://stackoverflow.com/a/40841942
Related: https://issues.redhat.com/browse/RHEL-50731
2024-08-13 10:47:51 +01:00
Richard W.M. Jones
c57ec4fd5d convert: More robust qemu-ga installation, change paths
Add a commit from the common submodule to attempt to make qemu-ga
installation more robust on Windows.

Rename network configuration Powershell script from "v2vnetcf" to
"network-configuration".  I also dropped the ".ps1" extension as the
modified Firstboot.add_firstboot_powershell function now adds this.

Update the common submodule to get these changes:

Richard W.M. Jones (3):
      mlcustomize: Use Start-Process -Wait to run qemu-ga installer
      mlcustomize: Add Firstboot.firstboot_dir function
      mlcustomize: Place powershell scripts into <firstboot_dir>\Temp
2024-08-01 10:12:28 +01:00
Richard W.M. Jones
d33fa8822b convert: Collect drive mappings in 'inspect' object
Currently we only print it in debugging output, but we might use it in
future.  It costs nothing to get it as it is already collected for
Windows guests (and is empty for other guests).
2024-07-30 16:33:20 +01:00
Richard W.M. Jones
652766b412 convert: Dump more information about the guest during conversion
As with the previous commit, this will match searches for ^info:
2024-07-30 16:07:34 +01:00
Richard W.M. Jones
0950ae3d75 convert: Tag some important information in debug output with ^info:
When we get large virt-v2v logs back from customers it is often
difficult to find relevant information about the guest.  Try to fix
this by tagging some important information so that it will match this
regular expression in searches:

  ^info:

Note I'm not including information about input and output drivers
here.  If we suspect a problem there, then more detailed review of the
log is always needed, plus that information is usually much easier to
find (eg. finding the kubevirt yaml or libvirt XML is obvious even in
large log files).

The main complexity here was to ensure that all of the nbdinfo
information appears together.  We need to run the command and collect
the output, otherwise it gets mixed in with debugging from nbdkit
which resulted from running nbdinfo.

Also update the common submodule to include:

  Richard W.M. Jones (1):
      mldrivers/linux_kernels.ml: Prefix general information with ^info:
2024-07-30 16:07:34 +01:00
Richard W.M. Jones
70eec57765 convert: windows: Install blnsvr from virtio-win
Also update the common module to get these two commits for the
implementation:

Richard W.M. Jones (2):
      mlcustomize: Add virt-customize --inject-blnsvr generated files
      mlcustomize: Add Inject_virtio_win.inject_blnsvr implementation

Fixes: https://issues.redhat.com/browse/RHEL-36591
2024-05-16 13:29:40 +01:00
Bella Zhang
bfb8ca212e convert_linux: add CircleLinux to supported distros 2024-01-28 18:43:42 +08:00
Richard W.M. Jones
5f58def90a convert: Find out if Windows guest is expecting RTC set to UTC
Read HKLM\SYSTEM\CurrentControlSet\Control\TimeZoneInformation key
"RealTimeIsUniversal" to see if the Windows guest is expecting RTC
set to localtime (not present) or UTC (present and set to 1).

See: https://wiki.archlinux.org/title/System_time#UTC_in_Microsoft_Windows
See: https://listman.redhat.com/archives/libguestfs/2023-September/thread.html#32556
Reported-by: Lee Garrett
Reviewed-by: Laszlo Ersek <lersek@redhat.com>
2023-09-25 17:21:00 +01:00
Richard W.M. Jones
69d73c251a types: Add gcaps_rtc_utc to record if the RTC is set to UTC or localtime
Almost every Linux guest expects the motherboard Real Time Clock (RTC)
to be set to UTC and they adjust the time displayed based on their
timezone (which may be different for each user).

Most Windows guests expect the RTC to be set to the local time.
Windows can be configured to use a UTC clock.  We can detect this by
looking at the Windows registry.

To cope with this difference we need to add a guestcaps flag based on
what we think the guest is expecting.  (We might also use the source
hypervisor RTC setting, but it is not thought to be as reliable as
inspecting the guest.)

This change simply adds the flag to guestcaps, and sets it to always
true, so there is no change to the output.

Reviewed-by: Laszlo Ersek <lersek@redhat.com>
2023-09-25 17:21:00 +01:00
Andrey Drobyshev
b42e44da83 convert_windows: configure_wait_pnp: do not create a separate log file
Right now wait-pnp is the only firstboot script which does its logging
into a separate log file.  Let's align its behaviour with that of the the
other scripts so that logs go to the common log file, i.e.
"C:\Program Files\Guestfs\Firstboot\log.txt".

Signed-off-by: Andrey Drobyshev <andrey.drobyshev@virtuozzo.com>
Message-Id: <20230316173438.100162-3-andrey.drobyshev@virtuozzo.com>
Acked-by: Laszlo Ersek <lersek@redhat.com>
2023-03-20 06:08:24 +01:00
Andrey Drobyshev
f1fb82964e convert_windows: add firstboot script to install drivers with pnputil
During conversion we copy the necessary drivers to the directory
"%systemroot%\Drivers\Virtio", adding it to the DevicePath registry
value.  As documented in [1], this should be enough for Windows to find
device drivers and successfully install them.

However, it doesn't always happen.  Commit 73e009c04 ("v2v: windows:
Document use of pnputil to install drivers.") describes such issues with
Win2k12R2.  I'm seeing the same problem with Win2k16 and netkvm.sys
driver not being installed.

That same commit 73e009c04 suggests adding a firstboot script invoking
pnputil at an early stage to install all the drivers we put into the
drivers store.  So let's add such a script to make sure all the
necessary drivers are installed.

[1] https://learn.microsoft.com/en-us/windows-hardware/drivers/install/how-windows-selects-a-driver-for-a-device

Signed-off-by: Andrey Drobyshev <andrey.drobyshev@virtuozzo.com>
Acked-by: Laszlo Ersek <lersek@redhat.com>
Message-Id: <20230316173438.100162-2-andrey.drobyshev@virtuozzo.com>
2023-03-20 06:05:28 +01:00
Richard W.M. Jones
74dd9faa1a convert_windows: set block driver priority according to block_driver option
If "block_driver" option is set to Virtio_SCSI, prepend the block drivers
priority list with "vioscsi" so that we first search for "vioscsi.sys" during
the drivers injection phase.

Originally-by: Richard W.M. Jones <rjones@redhat.com>
Signed-off-by: Andrey Drobyshev <andrey.drobyshev@virtuozzo.com>
Message-Id: <20230310175433.781335-5-andrey.drobyshev@virtuozzo.com>
Reviewed-by: Richard W.M. Jones <rjones@redhat.com>
Acked-by: Laszlo Ersek <lersek@redhat.com>
2023-03-14 13:02:27 +01:00
Richard W.M. Jones
2b849d002d convert: introduce "block_driver" convert option
When injecting a block VirtIO driver during conversion, we rely on the
predefined list of names of such drivers.  Order in this list denotes the
priority (see common/mlcustomize/inject_virtio_win.ml).

This commit introduces the "block_driver" convert option, setting its
value to the default Virtio_blk and making sure it's being properly passed
to the conversion functions. Along with the means of altering the drivers
list (introduced in a separate commit in the common submodule), this option
will be brought to command line, giving us the opportunity to choose the
block driver to be used on conversion.

Originally-by: Richard W.M. Jones <rjones@redhat.com>
Signed-off-by: Andrey Drobyshev <andrey.drobyshev@virtuozzo.com>
Message-Id: <20230310175433.781335-4-andrey.drobyshev@virtuozzo.com>
Reviewed-by: Richard W.M. Jones <rjones@redhat.com>
Acked-by: Laszlo Ersek <lersek@redhat.com>
2023-03-14 13:02:20 +01:00
Andrey Drobyshev
8f0761008d convert_windows: add Inject_virtio_win.Virtio_SCSI as a possible block type
It is needed to pass the proper guest capability in case we have
virtio-scsi driver installed during conversion.

Signed-off-by: Andrey Drobyshev <andrey.drobyshev@virtuozzo.com>
Message-Id: <20230310175433.781335-3-andrey.drobyshev@virtuozzo.com>
Reviewed-by: Richard W.M. Jones <rjones@redhat.com>
Acked-by: Laszlo Ersek <lersek@redhat.com>
2023-03-14 13:02:14 +01:00
Andrey Drobyshev
ebb0b7b239 Revert "Remove guestcaps_block_type Virtio_SCSI"
This code is needed to check whether virtio-scsi driver was installed.

This reverts commit f0afc439524853508938b2bfc758896f053462e3.
Message-Id: <20230310175433.781335-2-andrey.drobyshev@virtuozzo.com>
Reviewed-by: Richard W.M. Jones <rjones@redhat.com>
Acked-by: Laszlo Ersek <lersek@redhat.com>
2023-03-14 13:02:04 +01:00
Richard W.M. Jones
2cf337c26e v2v: Rename gcaps_default_cpu to gcaps_arch_min_version
Some guests require not just a specific architecture, but cannot run
on qemu's default CPU model, eg. requiring x86_64-v2.  Since we
anticipate future guests requiring higher versions, let's encode the
minimum architecture version instead of a simple boolean.

This patch essentially just remaps:

  gcaps_default_cpu = true  => gcaps_arch_min_version = 0
  gcaps_default_cpu = false => gcaps_arch_min_version = 2

I removed a long comment about how this capability is used because we
intend to completely remove use of the capability in a coming commit.

Updates: commit a50b975024ac5e46e107882e27fea498bf425685
Reviewed-by: Laszlo Ersek <lersek@redhat.com>
2023-02-20 11:08:39 +00:00
Richard W.M. Jones
9f12b95bbe convert: linux: Require host cpu for all RHEL-alike >= 9
RHEL >= 9 and compatible distros like Rocky >= 9 will not boot using
the default qemu CPU.  You will see an error at boot:

  Fatal glibc error: CPU does not support x86-64-v2

Instead you need to use -cpu host.

In commit f28757c6d1 ("convert_linux: set "gcaps_default_cpu = false"
for x86_64 RHEL-9.0+ guests") we fixed this specifically for RHEL >= 9.

This commit extends the same fix to all RHEL family distros.

Updates: commit f28757c6d100060c65212ea55cfa59d308dcb850
Fixes: https://bugzilla.redhat.com/show_bug.cgi?id=2166619
Reported-by: Ming Xie
Thanks: Laszlo Ersek
2023-02-06 12:17:17 +00:00
Richard W.M. Jones
d2b01e487f Split long lines in messages
This commit splits up any long lines found in errors, warnings or
other messages.  OCaml ignores whitespace following "\<CR>" within a
string, eg:

  "long string \
   more stuff"

is parsed as:

  "long string more stuff"

Thanks: Laszlo Ersek, for working out the OCaml syntax for this
2023-01-20 10:29:24 +00:00
Richard W.M. Jones
4b9c8e1560 convert: Move Linux driver detection code to common/
Update common to get this commit:

    mldrivers: New directory containing driver detection code

    Move the existing code from virt-v2v for handling driver detection.
    This is just code motion from virt-v2v, so that we can create a new
    tool (in guestfs-tools) called 'virt-drivers'.

    This so far only handles Linux (because virt-v2v doesn't do Windows
    driver detection), but we will add Windows support in future.

This is just code motion.
2023-01-19 10:49:27 +00:00
Richard W.M. Jones
22bcfbb4aa convert: Remove dependency of Linux_bootloaders and Linux_kernels on Types
As with other modules, we want to move these to common/ (so it can be
used in guestfs-tools), so remove the minimal dependencies that remain
on the Types module.
2023-01-19 10:14:15 +00:00
Richard W.M. Jones
4ab3126aa1 convert: Move firmware inspection to a new Firmware module
The existing function Inspect_source.get_firmware_bootable_device
detected if the guest could boot using UEFI through inspection (rather
than whatever the hypervisor told us).

Move this function to a new module, renaming it as
Firmware.detect_firmware.

Since we intend to move this into common/ (so it can be used in
guestfs-tools), remove the i_firmware field from the inspect struct
and pass it around as a separate argument.
2023-01-19 10:13:52 +00:00
Richard W.M. Jones
6837b6f811 convert: Remove dependency of Linux module on Types
As this module is generally useful we would like to use the same code
in guestfs-tools (ie. move it into common/).  In preparation for doing
that, remove dependencies on the virt-v2v specific Types module.

This change is mostly routine avoidance of the inspect struct, but I
changed the way that we determine which version of RPM is installed.
Instead of consulting inspect.i_apps, actually run 'rpm --version'
(inside the guest) and parse the output.  Note the only place we do
this, we're going to run 'rpm' soon anyway, so we know this is OK.
2023-01-19 10:13:36 +00:00
Richard W.M. Jones
1ea99fb2a7 Remove support for RHEL 3
This was the only guest type which did not support ACPI.  It also only
supported direct to libvirt output.  It hasn't been tested for a long
time, and hasn't been supported by Red Hat for very much longer.
Removing this means we no longer have to think about non-ACPI guests.
2023-01-17 14:23:08 +00:00
Richard W.M. Jones
7250e3bc74 convert: windows: Move code for injecting virtio-win to common/mlcustomize
So that we can reuse this useful code in virt-customize, move it to
the common module.

This is mostly code motion, but note:

(a) the module name changes from Windows_virtio to Inject_virtio_win

(b) as there were still some dependencies on types in the virt-v2v
Types module (eg. block driver type) I had to duplicate those.

See also:
https://listman.redhat.com/archives/libguestfs/2022-December/030389.html
2023-01-16 17:34:24 +00:00
Richard W.M. Jones
9ca0774109 convert: Move OCaml bindings of libosinfo to common/mltools
This library is needed by Windows_virtio.  Since I intend to move that
functionality into common/mlcustomize, I must also move this library
into common/.
2023-01-16 17:13:15 +00:00
Richard W.M. Jones
1794e6bc7a convert: Add a handle type to Windows_virtio
To further encapsulate the Windows_virtio module, add a handle.
Initially there is just one way to set up the handle, through
Windows_virtio.from_environment which reads the $VIRTIO_WIN
environment variable.

In future, when we move this module into common/mlcustomize, we will
add other ways to create this handle from a path.  (Using environment
variables with virt-customize is undesirable.)

I made further notes in comments about aspects of this that I think
are a real hack, but that can be addressed in future now that the
module is completely self-contained.

This is just refactoring and shouldn't change functionality at all.
2023-01-16 16:55:00 +00:00
Richard W.M. Jones
b506aeb6c2 v2v: Remove unit test for virtio-win path mapping
This large unit test hadn't been updated for quite a while and it
complicates moving this code into common/.  Remove it for now, but
consider revisiting it later, especially if we can make it smaller and
more useful.
2023-01-16 16:50:44 +00:00
Richard W.M. Jones
3a62efb709 convert: windows: Return the machine and virtio-1.0 status in Windows_virtio
There was a rather inelegant hack in Convert_windows used to try to
determine the machine type and virtio-1.0 status on x86 by predicting
the behaviour of Windows_virtio.

Refactor so this code is inside Windows_virtio.  This also allows us
to completely remove virtio_win_from_env (another inelegant hack).

I did the minimal safe change here rather than rethinking the code too
much.  By encapsulating it this way we make future changes
considerably easier.
2023-01-16 15:20:05 +00:00
Richard W.M. Jones
26b9cd1f87 convert: windows: Remove unused 'open Utils'
No function from Utils was being used by Windows_virtio, so remove the
unnecessary line.
2023-01-16 15:12:16 +00:00
Richard W.M. Jones
aa05060fa6 convert: windows: Refactor qemu-ga injection code
The existing Windows_virtio module is able to completely inject
virtio-win drivers (including modifying the registry).  However the
Windows_virtio.copy_qemu_ga function only copies the installer files
but didn't complete the injection by adding a firstboot script.
Instead there's more code in Convert_windows which completes the
injection.

Rename copy_qemu_ga -> inject_qemu_ga and copy the rest of the
injection code from Convert_windows to Windows_virtio, so that the
function is now completely self-contained and does a complete
injection of qemu-ga (when possible).

This is just refactoring and doesn't change functionality at all.
2023-01-16 15:05:36 +00:00
Richard W.M. Jones
015b5b7cdb convert: windows: Move function for installing Powershell to Firstboot module
We have a function Windows.install_firstboot_powershell which installs
a Powershell script and is a wrapper around a Firstboot function.

Move this to a more logical place, the Firstboot module inside
common/mlcustomize.  The new function is renamed
[Firstboot.add_firstboot_powershell] for consistency.
2023-01-16 14:51:16 +00:00
Richard W.M. Jones
7499ab10ea convert: windows: Document what copy_qemu_ga function returns
Just updates the comment.
2023-01-16 14:31:32 +00:00
Richard W.M. Jones
121da14e14 convert: windows: Rename function for injecting virtio-win drivers
Simple renaming of this function to reflect what it actually does.
2023-01-16 14:31:32 +00:00
Richard W.M. Jones
61df1975d0 convert: windows: Introduce a struct for what virtio-win installed
Having a large tuple isn't particularly safe, for example adjacent
boolean fields might be swapped accidentally.  Introduce a struct
describing what drivers were installed by the virtio-win code.

This is a simple refactoring and introduces no functional change.
2023-01-16 14:31:32 +00:00
Richard W.M. Jones
e7a243bb4e convert: windows: Remove extraneous blank lines in source 2023-01-16 14:31:32 +00:00
Laszlo Ersek
0596edf29a windows_virtio: favor "fwcfg" over "qemufwcfg"
Virtio-win may provide the "qemufwcfg" stub driver and/or the "fwcfg"
actual driver.  If both are provided, we must not install both, as they
conflict with each other. Pick "fwcfg" in this case.

Because the drivers can originate from two sources (libosinfo vs.
virtio-win), *and* because "copy_from_virtio_win" is reused for the QEMU
guest agent (i.e., not just for the drivers), do not sink the above
filtering into "copy_drivers" (or even more deeply).  Instead, let copying
complete, and then clean up "driverdir" -- remove "qemufwcfg" if "fwcfg"
is present.  (We'd have to consult the full list of drivers anyway, to see
if "fwcfg" indicates we should exclude "qemufwcfg".)

A note on annotating the "install_drivers" parameter list (OCaml obscurity
level one million):

> -let rec install_drivers ((g, _) as reg) inspect =
> +let rec install_drivers ((g, _) as reg : Registry.t) inspect =

Turns out that in this module, OCaml doesn't really have an idea that all
the "g#method" calls are made for an object of type "Guestfs.guestfs".
Instead, the compiler infers an interface from the methods we call, and
then tries to shoehorn that "collected interface" into "Guestfs.guestfs"
when it reaches:

>   reg_import reg (regedits @ common_regedits)

This used to work fine until now; however, once we call

> g#glob_expand (driverdir // "qemufwcfg.*")

in this patch, the "reg_import" call fails like this:

> File "windows_virtio.ml", line 152, characters 13-16:
> 152 |   reg_import reg (regedits @ common_regedits)
>                    ^^^
> Error: This expression has type
>          (< [snip]
>             glob_expand : string -> 'weak1 array;
>             [snip] >
>           as 'a) *
>          'weak2
>        but an expression was expected of type
>          Registry.t = Guestfs.guestfs * Registry.node
>        Type
>          < [snip]
>            glob_expand : string -> 'weak1 array;
>            [snip] >
>          as 'a
>        is not compatible with type
>          Guestfs.guestfs =
>            < [snip]
>              glob_expand : ?directoryslash:bool -> string -> string array;
>              [snip] >
>        Types for method glob_expand are incompatible

The problem is that in our "g#glob_expand" call, we silently omit the
optional parameter "directoryslash", so at that point the compiler
"infers" a parameter list

> glob_expand : string -> 'weak1 array;

for the "interface" we require.  And then that blows up because the actual
object provides only

> glob_expand : ?directoryslash:bool -> string -> string array;

The solution is to enlighten the compiler in "install_drivers" about the
actual type of "g", so that it need not infer or "collect" an interface
when we call "g#glob_expand" with "directoryslash" elided.

Now, "install_drivers" is called (as a callback!) ultimately from
"Registry.with_hive_write", and so its "reg" parameter has type
"Registry.t":

> type t = Guestfs.guestfs * node

(This is in fact reported by the compiler too, in the above-quoted error
message.  Except said error message is like ten pages long -- see those
[snip] markers? --, so you will only ever find the relevant bit in the
error report if you already know what to look for.  Helpful, that!)

Therefore, annotating the "reg" parameter like this:

> -let rec install_drivers ((g, _) as reg) inspect =
> +let rec install_drivers ((g, _) as reg : Registry.t) inspect =

forces "g" to have type "Guestfs.guestfs".

This is of course super obscure.  The hint was that both
"linux_bootloaders.ml" and "convert_linux.ml" already used "g#glob_expand"
without the optional parameter -- and the important difference was that
these files had been type-annotated previously.

In *retrospect* -- that is, rather uselessly... --, the language
documentation does highlight this
<https://v2.ocaml.org/manual/lablexamples.html#s:label-inference>:

> We will not try here to explain in detail how type inference works. One
> must just understand that there is not enough information in the above
> program to deduce the correct type of g or bump. That is, there is no
> way to know whether an argument is optional or not, or which is the
> correct order, by looking only at how a function is applied. The
> strategy used by the compiler is to assume that there are no optional
> arguments, and that applications are done in the right order.
>
> [...]
>
> In practice, such problems appear mostly when using objects whose
> methods have optional arguments, so that writing the type of object
> arguments is often a good idea.

Bugzilla: https://bugzilla.redhat.com/show_bug.cgi?id=2151752
Signed-off-by: Laszlo Ersek <lersek@redhat.com>
Message-Id: <20221215111544.18511-1-lersek@redhat.com>
2022-12-22 08:14:54 +01:00
Andrey Drobyshev
22ec2d24f5 inspect: check presence of BIOS boot partition to handle BIOS+GPT setup
If the guest uses BIOS firmware but GPT partitioned disk, v2v inspection
might fail to correctly detect the firmware being used by the source machine.
Namely, consider the following GPT partition table:

Number  Start (sector)    End (sector)  Size       Code  Name
   1            2048            4095   1024.0 KiB  EF02
   2            4096          528383   256.0 MiB   EF00
   3          528384       125827071   59.7 GiB    8300
   4       125827072       134215679   4.0 GiB     8200

where partition 1 is a BIOS boot partition (code 0xEF02, GPT partition
entry with GUID 21686148-6449-6E6F-744E-656564454649), and partition 2
is an EFI System partition (code 0xEF00, GPT partition entry with GUID
C12A7328-F81F-11D2-BA4B-00A0C93EC93B).  The former is commonly used to
store the bootloader in BIOS+GPT machines.  The latter is used by UEFI
powered machines.

Normally an OS installer wouldn't put those two together: if the disk is
being partitioned in GPT, there's either BIOS boot partition (if BIOS
firmware is used) or EFI System partition (if UEFI firmware is used).
However, GRUB2 will deal with such "busted" layout just fine, so this
configuration may exist. If it is the case, v2v inspection will detect the
presence of an EFI system partition and mistakenly mark the system as UEFI.

So let's prioritize Bios boot partition over ESP.  As discussed in [1],
this solution is not entirely bulletproof.  It will work in case a GPT
disk was first used in a UEFI machine, and then put into a BIOS machine
with an ESP partition remaining on it.  It won't work in the opposite case,
i.e. when a GPT disk is moved from BIOS machine to UEFI machine with
BIOS boot partition remaining on it. However, it's better to prioritize
something, and the latter case is less probable than the former.

[1] https://listman.redhat.com/archives/libguestfs/2022-December/030401.html

Co-authored-by: Laszlo Ersek <lersek@redhat.com>
Signed-off-by: Andrey Drobyshev <andrey.drobyshev@virtuozzo.com>
Message-Id: <20221221163831.423551-3-andrey.drobyshev@virtuozzo.com>
[lersek@redhat.com: fix typos in the commit message]
2022-12-22 07:37:41 +01:00
Andrey Drobyshev
d04b9a05b2 inspect: use Array.fold_left to iterate over partitions
This patch is merely a refactoring and does not introduce any changes in
behaviour.  It's used as a prelude for the next patch which prioritizes
BIOS boot partition when searching for the right firmware.

Co-authored-by: Laszlo Ersek <lersek@redhat.com>
Signed-off-by: Andrey Drobyshev <andrey.drobyshev@virtuozzo.com>
Message-Id: <20221221163831.423551-2-andrey.drobyshev@virtuozzo.com>
[lersek@redhat.com: s/List.fold_left/Array.fold_left/ in subject]
2022-12-22 07:33:29 +01:00
Andrey Drobyshev
db831c167b convert_linux: add Rocky Linux to supported distros
Libguestfs commit 631962c0e88 ("Add detection support for Rocky Linux
(CentOS/RHEL-like)") introduced Rocky support, so now inspector returns
"rocky" in its i_distro field instead of just "redhat-based".  virt-v2v
knows nothing about it, so when converting a Rocky guest we get en
error:

    virt-v2v-in-place: error: virt-v2v is unable to convert this guest type
    (linux/rocky)

Let's fix that by adding "rocky" as an acceptable value.

Signed-off-by: Andrey Drobyshev <andrey.drobyshev@virtuozzo.com>
2022-12-09 22:00:23 +00:00
Laszlo Ersek
9d4b58dcec convert_windows: fix up the UEFI fallback boot loader if broken
The "fallback" (or "default") boot behavior is described at great length
here:

https://blog.uncooperative.org/uefi/linux/shim/efi%20system%20partition/2014/02/06/the-efi-system-partition.html

The gist of it applies to all UEFI OSes, including Windows. For the
fallback boot behavior to work, the \EFI\BOOT\BOOTX64.efi boot loader on
the EFI system partition must match the installed operating system. We've
encountered a physical machine, during a virt-p2v conversion, where (a)
\EFI\BOOT\BOOTX64.efi belongs to a previously installed, but now wiped,
RHEL (hence shim+grub) deployment, and (b) the currently installed
operating system is Windows.

Virt-v2v never transfers the UEFI variables (including the UEFI boot
options) of the source, therefore the converted VM always relies on the
default boot behavior when it is first started up. In the above scenario,
where \EFI\BOOT\BOOTX64.efi is actually "shim", the mismatch is triggered
at first boot after conversion, and a broken grub shell is reached instead
of the Windows boot loader.

Detect this situation by investigating \EFI\BOOT\BOOTX64.efi on the EFI
system partition of a Windows disk image. If the file is missing, or is
not -- as expected -- a duplicate of \EFI\Microsoft\Boot\bootmgfw.efi,
then copy the latter to the former.

Bugzilla: https://bugzilla.redhat.com/show_bug.cgi?id=2149629
Signed-off-by: Laszlo Ersek <lersek@redhat.com>
Message-Id: <20221202124409.11741-3-lersek@redhat.com>
Reviewed-by: Richard W.M. Jones <rjones@redhat.com>
2022-12-02 14:30:01 +01:00
Laszlo Ersek
b13813b527 convert_linux.get_uefi_arch_suffix: move to Utils
So that Windows conversion can use the same function.

Bugzilla: https://bugzilla.redhat.com/show_bug.cgi?id=2149629
Signed-off-by: Laszlo Ersek <lersek@redhat.com>
Message-Id: <20221202124409.11741-2-lersek@redhat.com>
Reviewed-by: Richard W.M. Jones <rjones@redhat.com>
2022-12-02 14:29:54 +01:00
Richard W.M. Jones
7b49177e2b convert: windows: Copy drivers for Windows 11, Windows 2019 & Windows 2022
If the virtio-win ISO contains drivers for Windows 11, Windows 2019 or
Windows 2022, and the guest matches these, then copy in the right
drivers.  For this to work you will need libguestfs >= 1.49.8 which
allows osinfo to be used to detect Windows versions >= 10.

Side note: virtio-win uses a mix of different path element styles.

In the exploded tree of drivers installed by the RPM:

  /usr/share/virtio-win/drivers/amd64$ ls -l
  total 0
  drwxr-xr-x. 2 root root 174 Nov 30 13:28 Win10
  drwxr-xr-x. 2 root root 174 Nov 30 13:28 Win11
  drwxr-xr-x. 2 root root 236 Nov 30 13:28 Win2008R2
  drwxr-xr-x. 2 root root 174 Nov 30 13:28 Win2012
  drwxr-xr-x. 2 root root 174 Nov 30 13:28 Win2012R2
  drwxr-xr-x. 2 root root 174 Nov 30 13:28 Win2016
  drwxr-xr-x. 2 root root 174 Nov 30 13:28 Win2019
  drwxr-xr-x. 2 root root 174 Nov 30 13:28 Win2022
  drwxr-xr-x. 2 root root 236 Nov 30 13:28 Win7
  drwxr-xr-x. 2 root root 174 Nov 30 13:28 Win8
  drwxr-xr-x. 2 root root 174 Nov 30 13:28 Win8.1

Inside the ISO:

  ><fs> ll /viostor/
  total 28
  dr-xr-xr-x 1 root root 2048 Jun 14  2020 2k12
  dr-xr-xr-x 1 root root 2048 Jun 14  2020 2k12R2
  dr-xr-xr-x 1 root root 2048 Jun 14  2020 2k16
  dr-xr-xr-x 1 root root 2048 Jun 14  2020 2k19
  dr-xr-xr-x 1 root root 2048 Dec 11  2021 2k22
  dr-xr-xr-x 1 root root 2048 Jun 14  2020 2k8R2
  dr-xr-xr-x 1 root root 2048 Jun 14  2020 w10
  dr-xr-xr-x 1 root root 2048 Dec 11  2021 w11
  dr-xr-xr-x 1 root root 2048 Jun 14  2020 w7
  dr-xr-xr-x 1 root root 2048 Jun 14  2020 w8
  dr-xr-xr-x 1 root root 2048 Jun 14  2020 w8.1

So I have matched both path elements.

Reported-by: Tingting Zheng
Fixes: https://bugzilla.redhat.com/show_bug.cgi?id=2149811
Reviewed-by: Laszlo Ersek <lersek@redhat.com>
2022-12-02 10:20:31 +00:00
Richard W.M. Jones
7866fecbe5 convert: windows: Introduce osinfo matching
This neutral refactoring allows us to match drivers with virtio-win
guests using the inspect osinfo field.  This change adds an
"any_osinfo" predicate which matches any osinfo field.  The following
commit will add more cases for Windows >= 10 and use the osinfo field
to distinguish them.
2022-12-02 10:20:31 +00:00
Laszlo Ersek
aa69d64cd4 convert_linux: include the BOCHS DRM driver in the initial ram disk
UEFI RHEL-7 guests cannot be successfully converted from VMWare without
including the BOCHS DRM driver -- Plymouth ("rhgb") crashes during early
boot in the converted domain.

Bugzilla: https://bugzilla.redhat.com/show_bug.cgi?id=2131123
Signed-off-by: Laszlo Ersek <lersek@redhat.com>
Message-Id: <20220930120444.11883-1-lersek@redhat.com>
Reviewed-by: Richard W.M. Jones <rjones@redhat.com>
2022-10-04 12:22:50 +02:00
Laszlo Ersek
ad2b4f2e50 convert_linux: start the QEMU guest agent in a distro-specific way
The current command "service <package-name> start" does not apply to
RHEL-6; the service name ("qemu-ga") differs from the package name
("qemu-guest-agent") there.

Overhaul the logic -- detach the command from the package name; cover the
RHEL, ALT, SUSE and Debian families separately. Remove the "chkconfig"
command, as in all tested / investigated cases, it is unnecessary.

Bugzilla: https://bugzilla.redhat.com/show_bug.cgi?id=2028764
Signed-off-by: Laszlo Ersek <lersek@redhat.com>
Message-Id: <20220817144736.18850-1-lersek@redhat.com>
Acked-by: Richard W.M. Jones <rjones@redhat.com>
2022-08-18 10:31:39 +02:00