Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
22 changes: 18 additions & 4 deletions convert/convert.ml
Original file line number Diff line number Diff line change
Expand Up @@ -394,11 +394,25 @@ and get_target_firmware i_firmware guestcaps source output =

and get_target_boot_device g inspect =
with_return (fun {return} ->
(* We only do it for Linux, as most likely Windows never(?) boots
* from any drive other than C:. We can revisit this decision
* if someone reports a bug.
(* For non-Linux (eg. Windows) guests, use the root filesystem
* device to determine which disk is the boot device.
* This handles multi-OS guests where the selected OS may not
* be on the first disk.
*)
if inspect.i_type <> "linux" then return None;
if inspect.i_type <> "linux" then (
let boot_device =
try
let dev = g#part_to_dev inspect.i_root in
debug "get_target_boot_device: root %s is on device %s"
inspect.i_root dev;
Some (g#device_index dev)
with
| G.Error msg
when String.find msg "device name is not a partition" >= 0
|| String.find msg "device not found" >= 0 ->
None in
return boot_device
);

(* Look for "GRUB" signature in the boot sector of each disk.
* If we find it, choose that disk.
Expand Down
11 changes: 10 additions & 1 deletion test-data/phony-guests/Makefile.am
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ EXTRA_DIST = \
archlinux-package \
make-coreos-img.sh \
make-windows-img.sh \
make-windows-multi-disk-img.sh \
win10-software.reg \
win10-software.reg.bin \
win11-software.reg \
Expand Down Expand Up @@ -74,7 +75,9 @@ disk_images = \
win2k25.img \
win7-32.img \
winxp-32.img \
windows.img
windows.img \
windows-multi-disk-sda.img \
windows-multi-disk-sdb.img

# This is 'check_DATA' because we don't need it until 'make check'
# time and we need the tools we have built in order to make it.
Expand Down Expand Up @@ -163,6 +166,12 @@ win2k22-uefi.img: make-windows-img.sh \
windows-bcd.reg.bin
SRCDIR=$(srcdir) $(top_builddir)/run --test ./$< $@

# Make (dummy) multi-disk Windows images (for boot order testing).
windows-multi-disk-sda.img windows-multi-disk-sdb.img: make-windows-multi-disk-img.sh \
win2k22-software.reg.bin \
windows-system.reg.bin
SRCDIR=$(srcdir) $(top_builddir)/run --test ./$<

# This is the 'latest` windows image used by most test cases
windows.img: win2k22.img
ln -f $< $@
Expand Down
26 changes: 26 additions & 0 deletions test-data/phony-guests/guests.xml.in
Original file line number Diff line number Diff line change
Expand Up @@ -322,4 +322,30 @@
</devices>
</domain>

<!-- Multi-disk Windows guest: blank data disk on sda,
Windows OS on sdb. Used to test boot order detection. -->
<domain type='test'>
<name>windows-multi-disk</name>
<memory>1048576</memory>
<os>
<type>hvm</type>
<boot dev='hd'/>
</os>
<devices>
<disk type='file' device='disk'>
<driver name='qemu' type='raw'/>
<source file='@abs_builddir@/windows-multi-disk-sda.img'/>
<target dev='vda' bus='virtio'/>
</disk>
<disk type='file' device='disk'>
<driver name='qemu' type='raw'/>
<source file='@abs_builddir@/windows-multi-disk-sdb.img'/>
<target dev='vdb' bus='virtio'/>
</disk>
<video>
<model type='vga' vram='16384' heads='1'/>
</video>
</devices>
</domain>

</node>
88 changes: 88 additions & 0 deletions test-data/phony-guests/make-windows-multi-disk-img.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,88 @@
#!/bin/bash -
# libguestfs
# Copyright (C) 2010-2025 Red Hat Inc.
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.

# Make a multi-disk Windows image for testing boot order.
# Disk 1 (sda) is a blank data disk.
# Disk 2 (sdb) has the Windows OS on it.
# This tests that virt-v2v correctly identifies the boot disk
# when Windows is not on the first disk.

export LANG=C
set -e

SOFTWARE_REG="$SRCDIR/win2k22-software.reg.bin"
SYSTEM_REG="$SRCDIR/windows-system.reg.bin"
CMD_EXE="$SRCDIR/../binaries/bin-win64.exe"

# If libguestfs doesn't support ntfs-3g/ntfsprogs, just touch
# the output files and skip.
if ! guestfish -a /dev/null run : available "ntfs3g ntfsprogs"; then
touch windows-multi-disk-sda.img windows-multi-disk-sdb.img
exit 0
fi

# Create disk 1 (sda) - a blank data disk with a single NTFS partition.
guestfish <<EOF
sparse windows-multi-disk-sda.img-t 256M
run

part-init /dev/sda gpt
part-add /dev/sda p 64 -64

mkfs ntfs /dev/sda1

EOF

mv windows-multi-disk-sda.img-t windows-multi-disk-sda.img

# Create disk 2 (sdb) - the Windows OS disk.
guestfish <<EOF
sparse windows-multi-disk-sdb.img-t 512M
run

# Format the disk.
part-init /dev/sda gpt
part-add /dev/sda p 64 524287
part-add /dev/sda p 524288 -64

# Phony boot loader filesystem.
mkfs vfat /dev/sda1

# Mark this as a BIOS boot partition.
part_set_gpt_type /dev/sda 1 21686148-6449-6E6F-744E-656564454649

# Phony root filesystem.
mkfs ntfs /dev/sda2

# Enough to fool inspection API.
mount /dev/sda2 /
mkdir-p /Windows/System32/Config
mkdir-p /Windows/System32/Drivers
mkdir-p /Windows/TEMP

upload $SOFTWARE_REG /Windows/System32/Config/SOFTWARE
upload $SYSTEM_REG /Windows/System32/Config/SYSTEM

upload $CMD_EXE /Windows/System32/cmd.exe

mkdir "/Program Files"
touch /autoexec.bat

EOF

mv windows-multi-disk-sdb.img-t windows-multi-disk-sdb.img
2 changes: 2 additions & 0 deletions tests/Makefile.am
Original file line number Diff line number Diff line change
Expand Up @@ -119,6 +119,7 @@ TESTS = \
test-sound.sh \
test-virtio-win-iso.sh \
test-windows-conversion.sh \
test-windows-multi-disk-boot-order.sh \
test-windows-uefi-conversion.sh \
$(phony_windows_scripts) \
$(SLOW_TESTS) \
Expand Down Expand Up @@ -334,5 +335,6 @@ EXTRA_DIST += \
test-virtio-win-iso.sh \
test-windows-conversion.sh \
test-windows-conversion-ls.txt \
test-windows-multi-disk-boot-order.sh \
test-windows-uefi-conversion.sh \
test-windows-phony.sh
67 changes: 67 additions & 0 deletions tests/test-windows-multi-disk-boot-order.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
#!/bin/bash -
# libguestfs virt-v2v test script
# Copyright (C) 2014-2025 Red Hat Inc.
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.

# Test virt-v2v boot order for multi-disk Windows guests.
#
# Windows is installed on the second disk (sdb). After conversion,
# the second disk should get boot order 1 in the output XML.

source ./functions.sh
set -e
set -x

skip_if_skipped
requires test -s ../test-data/phony-guests/windows-multi-disk-sda.img
requires test -s ../test-data/phony-guests/windows-multi-disk-sdb.img

libvirt_uri="test://$abs_top_builddir/test-data/phony-guests/guests.xml"

export VIRT_TOOLS_DATA_DIR="$srcdir/../test-data/fake-virt-tools"
export VIRTIO_WIN="$srcdir/../test-data/fake-virtio-win/drivers"

d=test-windows-multi-disk-boot-order.d
rm -rf $d
cleanup_fn rm -r $d
mkdir $d

$VG virt-v2v --debug-gc \
-i libvirt -ic "$libvirt_uri" windows-multi-disk \
-o local -os $d \
--root /dev/sdb2

# Test the libvirt XML metadata and disks were created.
test -f $d/windows-multi-disk.xml
test -f $d/windows-multi-disk-sda
test -f $d/windows-multi-disk-sdb

# Check that the second disk (sdb, the boot disk) gets boot order 1
# and the first disk (sda, blank data) does not.

xml=$d/windows-multi-disk.xml

# The sda disk must NOT have boot order 1.
if grep -A5 'windows-multi-disk-sda' "$xml" | grep -q "boot order='1'"; then
echo "FAIL: disk 1 (sda) should not have boot order 1"
exit 1
fi

# The sdb disk (Windows root) must have boot order 1.
if ! grep -A5 'windows-multi-disk-sdb' "$xml" | grep -q "boot order='1'"; then
echo "FAIL: expected boot order 1 for disk 2 (sdb)"
exit 1
fi