debian使用initramfs脚本:自动检测物理机,虚拟机运行并挂载对应的UUID

  1. debian使用initramfs脚本:自动检测物理机/虚拟机运行并挂载对应的UUID
  2. 修改 /etc/fstab
  3. 总结

debian使用initramfs脚本:自动检测物理机/虚拟机运行并挂载对应的UUID

  1. 创建或编辑 initramfs 脚本文件

    创建或编辑 /etc/initramfs-tools/scripts/init-top/detect_vm_and_mount_root

    sudo nano /etc/initramfs-tools/scripts/init-top/detect_vm_and_mount_root
    
  2. 编写脚本内容

    在脚本文件中添加以下内容:

    #!/bin/sh
    
    PREREQ=""
    
    prereqs() {
        echo "$PREREQ"
    }
    
    case $1 in
        prereqs)
            prereqs
            exit 0
            ;;
    esac
    
    . /scripts/functions
    
    # 检测是否在虚拟机中
    if [ -f /sys/class/dmi/id/product_name ]; then
        VM_PRODUCT_NAME=$(cat /sys/class/dmi/id/product_name)
        if [ "$VM_PRODUCT_NAME" = "VMware7,1" ] || [ "$VM_PRODUCT_NAME" = "VirtualBox" ]; then
            IS_VM=true
        else
            IS_VM=false
        fi
    else
        IS_VM=false
    fi
    
    # 根据检测结果选择挂载配置
    if [ "$IS_VM" = true ]; then
        log_success_msg "Detected virtual machine, using VM configuration"
        ROOT_UUID="xxxxxx-xxxx-xxxx-xxxx-xxxxxx"  # 替换为虚拟机的根目录 UUID
        ROOT_DEVICE="/dev/nvme0np5"
        EFI_DEVICE="/dev/sda1"
        CDROM_DEVICE="/dev/nvme0n12"
    else
        log_success_msg "Detected physical machine, using physical configuration"
        ROOT_UUID="a39cb932-ad9f-4b9a-ae69-c14ca43a5313"  # 物理机的根目录 UUID
        ROOT_DEVICE="/dev/nvme0n1p2"
        EFI_UUID="F440-36ED"
        CDROM_DEVICE="/dev/nvme0n12"
    fi
    
     # 尝试挂载根目录
     if mount -o rw -U $ROOT_UUID /; then
         log_success_msg "Successfully mounted UUID $ROOT_UUID to / in read-write mode"
     else
         log_failure_msg "Failed to mount UUID $ROOT_UUID, trying device $ROOT_DEVICE"
         if mount -o rw $ROOT_DEVICE /; then
             log_success_msg "Successfully mounted device $ROOT_DEVICE to / in read-write mode"
         else
             log_failure_msg "Failed to mount both UUID and device for root"
             exit 1
         fi
     fi
    
    # 挂载 /boot/efi
    if [ "$IS_VM" = true ]; then
        if mount $EFI_DEVICE /root/boot/efi; then
            log_success_msg "Successfully mounted device $EFI_DEVICE to /root/boot/efi"
        else
            log_failure_msg "Failed to mount device $EFI_DEVICE to /root/boot/efi"
            exit 1
        fi
    else
        if mount -U $EFI_UUID /root/boot/efi; then
            log_success_msg "Successfully mounted UUID $EFI_UUID to /root/boot/efi"
        else
            log_failure_msg "Failed to mount UUID $EFI_UUID to /root/boot/efi"
            exit 1
        fi
    fi
    
    # 挂载 /media/cdrom0
    if mount $CDROM_DEVICE /root/media/cdrom0; then
        log_success_msg "Successfully mounted device $CDROM_DEVICE to /root/media/cdrom0"
    else
        log_failure_msg "Failed to mount device $CDROM_DEVICE to /root/media/cdrom0"
        exit 1
    fi
    

    若挂载脚本出问题,/变成只读,可以强制用rw重新挂载

    sudo mount -o remount,rw /
    
  3. 赋予脚本执行权限

    保存并退出编辑器后,赋予脚本执行权限:

    sudo chmod +x /etc/initramfs-tools/scripts/init-top/detect_vm_and_mount_root
    
  4. 更新 initramfs

    更新 initramfs 以包含新脚本:

    sudo update-initramfs -u
    

    强制更新 initramfs:

    sudo update-initramfs -u -k all
    

修改 /etc/fstab

/etc/fstab 文件中,移除或注释掉根目录、/boot/efi/media/cdrom0 的挂载条目。例如:

# /etc/fstab: static file system information.
#
# Use 'blkid' to print the universally unique identifier for a
# device; this may be used with UUID= as a more robust way to name devices
# that works even if disks are added and removed. See fstab(5).
#
# <file system> <mount point>   <type>  <options>       <dump>  <pass>

# 注释掉根目录的挂载条目
# UUID=a39cb932-ad9f-4b9a-ae69-c14ca43a5313 /               ext4    errors=remount-ro 0       1

# 注释掉 /boot/efi 的挂载条目
# UUID=F440-36ED  /boot/efi       vfat    umask=0077      0       1

# 注释掉 /media/cdrom0 的挂载条目
# /dev/nvme0n12   /media/cdrom0   udf,iso9660 user,noauto     0       0

总结

通过创建或编辑 initramfs 脚本,你可以在系统启动的早期阶段检测当前环境(物理机或虚拟机),并根据检测结果选择正确的配置来挂载根目录、/boot/efi/media/cdrom0。确保在脚本中正确填写物理机和虚拟机的 UUID 和设备名称,并备份配置文件以防万一。


欢迎指出任何有错误或不够清晰的表达,可以在下面评论区评论。

×

喜欢就点赞,疼爱就打赏

//