2

I have an hard disk image of an openSUSE installation from a x86-64 machine which I no longer have access to. I'm trying to boot from this raw disk using quemu. If I start the virtual machine with for example qemu-system-x86_64 -m 4096 -curses -hda srv.sda -enable-kvm or qemu-system-x86_64 -m 4096 -curses -drive id=disk,file=srv.sda,if=none,format=raw -device ahci,id=ahci -device ide-drive,drive=disk,bus=ahci.0 -enable-kvm, then I end up in the GRUB 2.02 shell, where I can specify the Linux kernel and initial ramdisk with commands below:

grub> linux (hd0,msdos1)/boot/vmlinuz
grub> initrd (hd0,msdos1)/boot/initrd
grub> boot

This starts the boot process which always ends here:

              [    0.234732] NET: Registered protocol family 10
              [    0.235188] lo: Disabled Privacy Extensions
              [    0.235592] lib80211: common routines for IEEE802.11 drivers
              [    0.236014] registered taskstats version 1
              [    0.236439]   Magic number: 1:617:774
              [    0.236774] mem zero: hash matches
              [    0.237151] rtc_cmos 00:01: setting system clock to 2021-04-22 07:46:24 UTC (
              1619077584)
              [    0.237802] Freeing unused kernel memory: 896k freed
              [    0.238330] Write protecting the kernel read-only data: 10240k
              [    0.238762] Freeing unused kernel memory: 1616k freed
              [    0.239578] Freeing unused kernel memory: 748k freed
              doing fast boot
              Creating device nodes with udev
              [    0.255337] udev: starting version 157
              mount: devpts already mounted or /dev/pts busy
              mount: according to mtab, devpts is already mounted on /dev/pts
              Boot logging started on /dev/char/../tty1(/dev/console) at Thu Apr 22 10:46:24 2
              021
              resume device  not found (ignoring)
              Waiting for device /dev/sda1 to appear: [    1.072809] input: ImExPS/2 Generic E
              xplorer Mouse as /devices/platform/i8042/serio1/input/input1
              ..............................Could not find /dev/sda1.
              Want me to fall back to /dev/sda1? (Y/n)

Can I modify the disk settings of the qemu in some way that the first and only partition of the disk becomes available for Linux? For example, looks like GRUB is able to access it as it successfully reads the /boot/vmlinuz and /boot/initrd.

EDIT 1: After recreating the initial ramdisk and including the ata_piix kernel module the qemu-system-x86_64 boot process is following:

              [    0.244118] rtc_cmos 00:01: setting system clock to 2021-04-27 15:31:52 UTC (
              1619537512)
              [    0.244762] Freeing unused kernel memory: 896k freed
              [    0.245284] Write protecting the kernel read-only data: 10240k
              [    0.245716] Freeing unused kernel memory: 1616k freed
              [    0.246529] Freeing unused kernel memory: 748k freed
              doing fast boot
              [    0.266568] SCSI subsystem initialized
              [    0.267653] megasas: 00.00.04.17.1-rc1 Thu. Oct. 29, 11:41:51 PST 2009
              [    0.278467] scsi0 : ata_piix
              [    0.278833] scsi1 : ata_piix
              [    0.279164] ata1: PATA max MWDMA2 cmd 0x1f0 ctl 0x3f6 bmdma 0xc060 irq 14
              [    0.279562] ata2: PATA max MWDMA2 cmd 0x170 ctl 0x376 bmdma 0xc068 irq 15
              Creating device nodes with udev
              [    0.444780] udev: starting version 157
              mount: devpts already mounted or /dev/pts busy
              mount: according to mtab, devpts is already mounted on /dev/pts
              Boot logging started on /dev/char/../tty1(/dev/console) at Tue Apr 27 18:31:52 2
              021
              resume device  not found (ignoring)
              Waiting for device /dev/sda1 to appear: [    1.080811] input: ImExPS/2 Generic E
              xplorer Mouse as /devices/platform/i8042/serio1/input/input1
              ..............................Could not find /dev/sda1.
              Want me to fall back to sda1? (Y/n)

As seen above, the ata_piix module seems to be loaded, but /dev/sda1 is still not found.

EDIT 2: I modified the /etc/fstab in chroot environment in a way that /dev/sda1 / reiserfs acl,user_xattr 1 1 was replaced with UUID=dafc3c3a-1469-44b1-b85c-deb904aac291 / reiserfs acl,user_xattr 1 1, regenerated the initial ramdisk and tried to boot this system by specifying the Linux kernel and initial ramdisk in the GRUB shell:

grub> linux (hd0,msdos1)/boot/vmlinuz root=UUID=dafc3c3a-1469-44b1-b85c-deb904aac291
grub> initrd (hd0,msdos1)/boot/initrd
grub> boot

Unfortunately, the system did not boot. I'll also add the mkinitrd output:

# mkinitrd -v -k vmlinuz-2.6.34.10-0.6-default -i initrd-2.6.34.10-0.6-default -d /

Kernel image:   /boot/vmlinuz-2.6.34.10-0.6-default
Initrd image:   /boot/initrd-2.6.34.10-0.6-default
[MODULES]       02-start.sh: reiserfs thermal megaraid_sas ata_piix ata_generic processor fan
[MODULES]       02-start.sh:
[MODULES]       03-rtc.sh: rtc_cmos
[MODULES]       03-storage.sh: reiserfs
[MODULES]       11-usb.sh: usbcore
[MODULES]       11-usb.sh: ohci_hcd
[MODULES]       11-usb.sh: uhci-hcd
[MODULES]       11-usb.sh: ehci_hcd
[MODULES]       11-usb.sh: usbhid
[MODULES]       'modinfo -k "2.6.34.10-0.6-default" -F supported'  returned with an error.
Kernel Modules: reiserfs thermal_sys thermal scsi_mod megaraid_sas libata ata_piix ata_generic processor fan usbcore pcmcia_core pcmcia mmc_core ssb ohci-hcd ehci-
hcd uhci-hcd usbhid
[MOUNT] Root:   /
Features:       usb resume.userspace resume.kernel
Bootsplash:     openSUSE (640x480)
Shared libs:    /lib/udev/collect_lvm is a script
/lib/udev/findkeyboards is a script
/lib/udev/idedma.sh is a script
/lib/udev/iwlwifi-led.sh is a script
/lib/udev/keyboard-force-release.sh is a script
/lib/udev/kpartx_id is a script
/lib/udev/udev-add-printer is a script
/lib/udev/write_cd_rules is a script
/lib/udev/write_net_rules is a script
/lib/mkinitrd/bin/ipconfig.sh is a script
/sbin/ifup is a script
/lib/mkinitrd/bin/ipconfig.sh is a script
/lib/mkinitrd/bin/linuxrc is a script
/usr/bin/on_ac_power is a script
lib64/ld-2.11.2.so lib64/libacl.so.1.1.0 lib64/libattr.so.1.1.0 lib64/libblkid.so.1.1.0 lib64/libcap.so.2.16 lib64/libcom_err.so.2.1 lib64/libcrypto.so.1.0.0 lib64
/libc-2.11.2.so lib64/libdevmapper.so.1.02 lib64/libdl-2.11.2.so lib64/libgcrypt.so.11.5.2 lib64/libgpg-error.so.0.5.0 lib64/libkeyutils-1.3.so lib64/liblzo2.so.2.
0.0 lib64/libm-2.11.2.so lib64/libncurses.so.5.7 lib64/libpcre.so.0.0.1 lib64/libpthread-2.11.2.so lib64/libreadline.so.6.1 lib64/libresolv-2.11.2.so lib64/librt-2
.11.2.so lib64/libselinux.so.1 lib64/libsepol.so.1 lib64/libssl.so.1.0.0 lib64/libudev.so.0.8.2 lib64/libutil-2.11.2.so lib64/libuuid.so.1.3.0 lib64/libz.so.1.2.3
usr/lib64/libatasmart.so.4.0.3 usr/lib64/libcups.so.2 usr/lib64/libdal-0.3.so.0.0.0 usr/lib64/libdirect-1.2.so.9.0.0 usr/lib64/libdirectfb-1.2.so.9.0.0 usr/lib64/l
ibfusion-1.2.so.9.0.0 usr/lib64/libglib-2.0.so.0.2400.1 usr/lib64/libgssapi_krb5.so.2.2 usr/lib64/libk5crypto.so.3.1 usr/lib64/libkrb5.so.3.3 usr/lib64/libkrb5supp
ort.so.0.1 usr/lib64/libparted.so.0.0.1 usr/lib64/libreiserfs-0.3.so.0.0.0 usr/lib64/libsplashycnf.so.1.0.0 usr/lib64/libsplashy.so.1.0.0 usr/lib64/libusb-0.1.so.4
.4.4 usr/lib64/libusb-1.0.so.0.0.0 lib64/libnss_dns-2.11.2.so lib64/libnss_dns.so.2 lib64/libnss_files-2.11.2.so lib64/libnss_files.so.2 lib64/libgcc_s.so.1
37516 blocks
Perl-Bootloader: 2021-05-03 18:57:38 ERROR: UDEVMAPPING: dmdev /dev/dm-0 doesn't have defined DM_NAME in udev
#

There is an error about the DM_NAME variable in udev, but on the other hand, new initial ramdisk file is created and for example, adding the ata_piix clearly worked. I have also tried with different root devices(-d option) for mkinitrd like sda1.

5
  • 1
    Was the original machine possibly fitted with a SCSI device instead of a SATA?
    – LL3
    Apr 27, 2021 at 0:06
  • @LL3 Turned out, that this x86-64 machine was a xen virtual machine.
    – Martin
    Apr 27, 2021 at 15:54
  • Are you really sure that the disk is being mounted at /dev/sda Perhaps consider replacing /dev/sda1 with UUID=<the uuid of the device> you'd get the UUID by mounting it and then running blkid As you've stated qemu you can probably mount the disk on the hypervisor
    – Timothy c
    Apr 28, 2021 at 21:18
  • @Martin What qemu command did you use after you added ata_piix to the initial ramdisk? I would expect that driver to detect your qemu ... -hda ... command, but not the qemu ... -device ahci ... one because the latter requires yet a different driver in the Linux guest
    – LL3
    Apr 29, 2021 at 9:37
  • @Timothyc Where would you like me to replace /dev/sda1 with the UUID? @LL3 I used the qemu ... -hda ... command.
    – Martin
    Apr 29, 2021 at 12:39

3 Answers 3

4
+200

My first guess would be that the storage controller in the original system differs from the one provided by qemu, and so the initrd file does not contain the right module to run the virtual storage controller.

The default storage controller of qemu-system-x86_64 does not seem to be AHCI, but a classic Intel PIIX3 IDE controller. It requires the ata_piix kernel module, which is unnecessary in the initrd of any reasonably modern physical system that uses AHCI as a minimum baseline.

As a result, the kernel never gets to see the disk at all, and the boot process never gets to transition off the initrd to the real root filesystem.

GRUB sees the disk just fine, because it uses the BIOS routines to access the disk... and since the BIOS is provided by qemu, the BIOS obviously has exactly the right routines for the job.

If you can access the command prompt of the virtual machine, try this command:

dmesg | grep -e piix -e ahci -e " sd"

It should display any messages related to the detection of the disk: if nothing is displayed, then your (virtual) storage controller is not being detected, which makes detecting the virtual disk impossible.


To fix it, you might have to access the disk image in your regular system: (if /dev/loop0 is already in use in your system, use a free loop device instead)

losetup -P /dev/loop0 srv.sda

Then mount /dev/loop0p1 to a suitable temporary location in your regular system:

mkdir /mnt/opensuse
mount /dev/loop0p1 /mnt/opensuse

Add the necessary virtual filesystems and chroot into the filesystem of the disk image, similar to what you might do when booting a physical system off a live Linux media:

mount --rbind /dev /mnt/opensuse/dev
mount --bind /proc /mnt/opensuse/proc
mount --bind /sys /mnt/opensuse/sys
chroot /mnt/opensuse

Now you should be able to recreate the initrd/initramfs file within the disk image. You did not specify the version of the OpenSUSE system on the image, but the classic mkinitrd command might be the tool to use - or it might actually be a compatibility alias for whatever newer tool (dracut perhaps?) may be used by the newer versions.

Whichever tool is used to create the initrd file in that version of OpenSUSE, that tool will most likely have an option to force a particular kernel module to be included in initrd. Read the man page of the tool to find out the option, and use it to create a new initrd with the ata_piix module included. (Move the original initrd file aside first, just to be safe.)

Once you've successfully created a new initrd file in the proper location in the /boot of the image, exit out of the chroot environment, umount all the mounts you did earlier, and detach the loop device with losetup -d /dev/loop0. Now you can try booting the image again, hopefully with success.

1
  • Thank you for such an exhaustive reply! I added the ata_piix kernel module to the initial ramdisk and according to openSUSE boot log the virtual storage controller is now detected, but the /dev/sda1 is still not found. In addition, I made sure that the reiserfs kernel module is included to the initial ramdisk as the first partition on this raw disk has ReiserFS. I updated my initial question with openSUSE boot messages.
    – Martin
    Apr 27, 2021 at 16:00
1
+500

Recreating the initrd file through mkinitrd is a correct thing to do, only it should be done from a system which is as close as possible to the one that will be used by the final target OS. This is because mkinitrd performs a lot of auto-detection on the kernel&system it is run from, especially with regard to the kernel modules that are to be made available to the initrd file. You've recreated the initrd file from your host OS, which is clearly very different from that old machine of yours, so mkinitrd built an incomplete/inconsistent initrd.

The best approach in these situations is usually to boot the about-to-be target machine from the original distribution's installation CD/DVD/ISO, as these typically have a "rescue mode" that come in handy for these cases, to recreate the initrd file from there. In your case it appears the target OS is an openSuSE 11.3, so you could grab its ISO, boot it with whatever qemu virtual system you want the target OS to be adjusted to (-hda or -device ahci or even some SCSI/SAS if you feel so inclined), select the "Rescue System" option which is available from the very first boot-menu of that ISO, login as root and from there run:

~# mount /dev/sda1 /mnt
~# cd /mnt
/mnt# mount --rbind /dev dev && mount --make-rslave dev
/mnt# mount -t proc proc proc
/mnt# mount -t sysfs sysfs sys
/mnt# chroot .
<chrooted># mkinitrd
...
<chrooted># exit
/mnt# umount dev/pts dev/shm dev proc sys
/mnt# cd ..
/# umount mnt

to recreate the initrd file.

Having booted with the real original kernel (the one from openSuSE 11.3) running on the real target qemu system, a simple mkinitrd with no options should work just fine.

Of course after the above operation you would poweroff to rerun a qemu with same virtual system but no ISO image.


It is perfectly possible to recreate an initrd file from a completely different OS like you have attempted, but then one would need to know precisely all the required drivers in order to override the (unavoidably) incomplete/inconsistent auto-detection performed by mkinitrd.

In your case I see your recreated initrd file lacks the sd_mod driver which is in fact required to provide /dev/sd* disk devices. It wasn't copied probably because your host OS (on which you operated to recreate the initrd file) does not have that driver as an sd_mod.ko loadable module, but rather has it compiled into the kernel image itself. That is well possible because that module has become quite the default nowadays while it wasn't at all 10 years ago, as much as its IDE counterpart (ide-disk.ko) was quite the default (i.e. compiled-in) until some ~15 years ago while nowadays it is often left off completely.

So you might possibly just repeat the same operations you've done on your host OS while also specifying sd_mod as well as ata_piix, and you might be all set. However, in such cases, that is if for instance an original installation CD/DVD/ISO is not available, a safer alternative is to rather run mkinitrd -A from inside the chrooted environment on the host OS, because that argument instructs mkinitrd to simply include all possible drivers. Naturally that requires much more disk space off the filesystem the initrd file is locate in, but once booted into the target OS's disk you can finally re-re-create the initrd with a simple mkinitrd (i.e. no arguments) which rebuilds a lean initrd file made for the new hardware system.

1
  • Adding the sd_mod driver did the trick. Thanks!
    – Martin
    May 4, 2021 at 10:25
1

Following the UUID comment I made.

Assuming you have access to the disk (disk/image) you can mount it on the host machine per the instructions that @telcoM gives above. From there you can run blkid to get the UUID

You can then update /etc/fstab on the disk image. I assume it has a line that looks something like

/dev/sda1 / ext4 defaults 1 1

comment that line out and replace the /dev/sda1 with UUID=### eg

UUID=aaaaaaa-aaaa-aaaa-aaaa-aaaaaaaaaaaa / ext4 defaults 1 1

If possibly do similar on the grub linux line

grub> linux (hd0,msdos1)/boot/vmlinuz root=UUID=###
3
  • Thanks! I modified the /etc/fstab in chroot environment and rebuild the initial ramdisk, but unfortunately this did not help. I updated my initial question. At least for me it still looks like the whole virtual disk is not found. For example, when I drop to BusyBox shell after unsuccessfully mounting the root filesystem and list the files under /dev, then there are no /dev/sda, /dev/hda, etc devices.
    – Martin
    May 3, 2021 at 16:34
  • 1
    @Martin run blkid in the busybox shell to see if the kernel can see any of the disks. It's starting to sound like it's a kernel driver (module) issue. I personally set all the disks as virtio in KVM unless I'm doing device passthrough
    – Timothy c
    May 4, 2021 at 9:40
  • Kernel does not see the disks. There are no sd*, hd*, etc files under /dev/.
    – Martin
    May 4, 2021 at 10:24

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.