1

There is a copy of the disk in IMG format:

root@linux /mnt # fdisk -l /mnt/output.img 
Disk /mnt/output.img: 3 GiB, 3221225472 bytes, 6291456 sectors
Units: sectors of 1 * 512 = 512 bytes
Sector size (logical/physical): 512 bytes / 512 bytes
I/O size (minimum/optimal): 512 bytes / 512 bytes
Disklabel type: gpt
Disk identifier: 3EEB19F8-AB57-47B4-A7E7-F2A0BDE6C2B1

Device           Start     End Sectors Size Type
/mnt/output.img1  2048    4095    2048   1M BIOS boot
/mnt/output.img2  4096 6289407 6285312   3G Linux LVM

lvdisplay provides the following information about the disk:

lvm> lvdisplay
  --- Logical volume ---
  LV Path                /dev/connect/root
  LV Name                root
  VG Name                connect
  LV UUID                KXxms1-2d0j-C8Ps-6azt-3U0z-PpOO-K9mS0B
  LV Write Access        read/write
  LV Creation host, time client-dev-building-02, 2024-07-25 13:36:12 +0300
  LV Status              NOT available
  LV Size                2,00 GiB
  Current LE             512
  Segments               1
  Allocation             inherit
  Read ahead sectors     auto
   
  --- Logical volume ---
  LV Path                /dev/connect/boot
  LV Name                boot
  VG Name                connect
  LV UUID                OKFDNN-IUDQ-a0Ol-6Dqg-lDKu-GIWK-4A8faP
  LV Write Access        read/write
  LV Creation host, time client-dev-building-02, 2024-07-25 13:36:14 +0300
  LV Status              NOT available
  LV Size                512,00 MiB
  Current LE             128
  Segments               1
  Allocation             inherit
  Read ahead sectors     auto
   
  --- Logical volume ---
  LV Path                /dev/connect/home
  LV Name                home
  VG Name                connect
  LV UUID                Uls6Oa-fQ64-Qrpd-mVXr-kYxo-PZmO-uxXx4Z
  LV Write Access        read/write
  LV Creation host, time client-dev-building-02, 2024-07-25 13:36:14 +0300
  LV Status              NOT available
  LV Size                508,00 MiB
  Current LE             127
  Segments               1
  Allocation             inherit
  Read ahead sectors     auto

I created a USB stick with GRUB download. I copied the file output.img there. My configuration looks like this:

menuentry "output" {
        insmod lvm
        set isofile="output.img"
        loopback loop (hd0,2)/${isofile}
        linux (lvm/connect-boot)/vmlinuz root=/dev/connect/root ro
        initrd (lvm/connect-boot)/initrd.img
}

The kernel is loaded, but when loading initramfs it is not possible to mount the root directory, it gives an error:

Begin: Loading essential drivers ... done.
Begin: Running /scripts/init-premount ... done.
Begin:  Mounting root file system ... Begin: Running /scripts/local-top ... Volume group "connect" not found
  Cannot process volume group connect
done.

I mean, initramfs lacks LVM boot support.

Is there any way to mount the root directory, or load to GRUB, which is available on output.img?

My attempts to boot directly from the LVM device gives the error unknown file system type LVM2_member

enter image description here

It is necessary to load it in this form, without writing IMG directly to USB. The output.img file is always different, so i need to make different boot options from different disks in this format.

UPD 1

  1. I have brought the GRUB configuration to this form
menuentry "img" {
        insmod lvm
        set imgfile="output.img"
        set device="(hd0,2)"
        probe --set uuid --fs-uuid ${device}
        loopback loop ${device}/${imgfile}
        linux (lvm/connect-boot)/vmlinuz root=UUID=${uuid} rw
        initrd (lvm/connect-boot)/initrd.img
}
  1. I have initramfs loaded and the partition on which my output.img image is located is automatically mounted.

  2. I'm manually mounting my IMG image

losetup --partscan /dev/loop0 /root/output.img
  1. Identify LVM sections
vgchange -ay
  1. Mount the root directory
mkdir -p /mnt/root
mount /dev/mapper/connect-root /mnt/root
  1. I'm trying to start a further load, but I get a kernel crash
exec switch_root /mnt/root /sbin/init

Something went wrong.

enter image description here

UPD 2

I try to transfer the download in this way, but a black screen appears with the inscription GRUB and that's it.

enter image description here enter image description here enter image description here

5
  • 1
    You're running a busybox shell, and switch_root is an internal command of busybox. Maybe it won't need the exec? Also, unmount as much as possible mounted on the old root before running switch_root. Have you checked that /mnt/root/sbin/init exists and is of appropriate type (64-bit vs. 32-bit, etc.)?
    – telcoM
    Commented Jul 31 at 22:25
  • @JayCravens I wrote above that I am interested in the specific download method described. Commented Aug 1 at 8:57
  • @telcoM I haven't tried with unmounting. Thanks for the tip. I'll try and update the question. And as for the existence of /mnt/root/sbin/init - it is present there, the x64 system. Loads on a virtual machine without problems. It also loads if I record an image via Etcher IMG. Commented Aug 1 at 8:59
  • @telcoM Unmounting does not help Commented Aug 1 at 10:38
  • Do you know anything about the original system? If this is the only disk and it is configured to boot in legacy mode (not UEFI) you could try to create a virtual machine with virt-manager to boot using the .img as disk.
    – nicovell3
    Commented Aug 1 at 17:04

1 Answer 1

1

I managed to solve the problem by creating my own boot script in initrd. At the same time, I pass the image argument as a kernel parameter, which passes the necessary information inside my script for further loading.

It is necessary to rebuild initrd with its own script, which must be placed in the /etc/initramfs-tools/scripts/init-premount directory:

#!/bin/sh
 
get_device() {
    blkid -l -t "UUID=$1" -o device 2>/dev/null
}
 
get_filesystem_type() {
    blkid -s TYPE -o value $1 2>/dev/null
}
 
mount_device() {
    mount -t $1 -o rw $2 $3 2>/dev/null
}
 
mount_image() {
    losetup -P /dev/loop0 $1
    vgchange -ay
}
 
main() {
    local mntdir="/img"
    mkdir -p ${mntdir}
 
    for x in $(cat /proc/cmdline); do
        case $x in
        image=*)
            local image=${x#image=}
            ;;
        esac
    done
 
    if [ -n "${image}" ]; then
        local uuid=$(echo $image | sed -E 's/.*UUID=([^,]*),?.*/\1/')
        local img=$(echo $image | sed -E 's/.*IMG=([^,]*),?.*/\1/')
 
        if [ -n "${uuid}" ]; then
            local dev="$(get_device $uuid)"
        else
            echo "The device was not recognized: ${uuid}"
            return
        fi
 
        if [ -n "${dev}" ]; then
            local fstype="$(get_filesystem_type $dev)"
        else
            echo "The file system type has not been determined: ${dev}"
            return
        fi
 
        if [ -n "${fstype}" ]; then
            mount_device ${fstype} ${dev} ${mntdir}
        else
            echo "The file system type is missing"
            return
        fi
 
        if [ -f "${mntdir}/${img}" ]; then
            mount_image "${mntdir}/${img}"
        else
            echo "Couldn't find an IMG image to mount: ${mntdir}/${img}"
            return
        fi
    fi
}
 
main

Rebuild the initrd:

update-initramfs -u -k $(uname -r)

GRUB looks like this:

menuentry "myimage" {
        set imgfile="myimage.img"
        regexp -s rootdevice '(.*),' $root
        set datadevice="(${rootdevice},2)"
        rmmod tpm
        probe --set uuid --fs-uuid ${datadevice}
        loopback loop ${datadevice}/${imgfile}
        linux (lvm/connect-boot)/vmlinuz image=UUID=${uuid},IMG=${imgfile} root=/dev/connect/root rw
        initrd (lvm/connect-boot)/initrd.img
}

Thus, as a customized image parameter, I pass the necessary data to a script that mounts the device, mounts the IMG image, recognizes LVM partitions and loads from the root directory of the IMG image.

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .