NixOS / nixpkgs

Nix Packages collection & NixOS
MIT License
17.29k stars 13.54k forks source link

Virt-Manager: Can't use UEFI in QEMU #115996

Open davidak opened 3 years ago

davidak commented 3 years ago

Describe the bug I want to try out mobile-nixos. So i build the Generic UEFI build (x86_64) und imported the mobile-nixos.img into QEMU using Virt-Manager.

When choosing "Customize configuration before install", there is an option to select UEFI instead of BIOS as Firmware, but UEFI is not available.

Screenshot from 2021-03-11 22-38-29

To Reproduce Steps to reproduce the behavior: virt-manger > File > New Virtual Machine > Select Network Install > URL: https://boot.netboot.xyz/ipxe/netboot.xyz-efi.iso OS: Generic, Forward > Forward > Deselect "Enable storage" > Forward > Click "Customize configuration before install" > Finish

Observe in the "Overview" Tab, that Firmware is "BIOS" and you can't move the selection to "UEFI". (Click "Cancel Installation")

Expected behavior UEFI should be selectable.

Additional context This issue was reported (https://github.com/NixOS/nixpkgs/issues/25209) and fixed (https://github.com/NixOS/nixpkgs/pull/25397) before.

This is just an issue of Virt-Manager, it works from CLI:

#!/nix/store/f7jzmxq9bpbxsg69cszx56mw14n115n5-bash-4.4-p23/bin/bash
ARGS=(
  -enable-kvm
  -bios   "/nix/store/079cwcpiwmyxqilblvsfxr0g8xp725f3-OVMF-202011-fd/FV/OVMF.fd"
  -m      "2048M"
  -serial "mon:stdio"
  -drive  "file=/nix/store/1az9bsfbn9m88nhj1bk9wra74yv6f721-disk-image-mobile-nixos/mobile-nixos.img,format=raw,snapshot=on"

  -device "VGA,edid=on,xres=720,yres=1280"
  -device "usb-ehci"
  -device "usb-kbd"
  -device "usb-tablet"

  -device "e1000,netdev=net0"
  -netdev "user,id=net0,hostfwd=tcp::2222-:22,hostfwd=tcp::2323-:23,net=172.16.42.0/24,dhcpstart=172.16.42.1"

  -device "e1000,netdev=user.0"
  -netdev "user,id=user.0"
)

/nix/store/i7sizpm5yicbyhvzv291k2xpbfkac93c-qemu-5.2.0/bin/qemu-system-x86_64 "${ARGS[@]}" "${@}"

Notify maintainers @eelco cc @clefru @bjornfor @peterhoeg

Metadata

Maintainer information:

# a list of nixpkgs attributes affected by the problem
attribute:
# a list of nixos modules affected by the problem
module:
samueldr commented 3 years ago

Tangentially (since it was your initial goal), for uefi-x86_64 you can build the build.vm attribute which builds a convenient wrapper around QEMU to launch the VM.

TredwellGit commented 3 years ago

Works for me:

virtualisation.libvirtd = {
  allowedBridges = [
    "nm-bridge"
    "virbr0"
  ];
  enable = true;
  qemuRunAsRoot = false;
};

~/.config/libvirt/qemu.conf: nvram = ["/run/libvirt/nix-ovmf/OVMF_CODE.fd:/run/libvirt/nix-ovmf/OVMF_VARS.fd"]

TredwellGit commented 3 years ago

QEMU/KVM works without ~/.config/libvirt/qemu.conf but QEMU/KVM User session requires it.

davidak commented 3 years ago

@TredwellGit i created ~/.config/libvirt/qemu.conf with that content, but still have the issue.

My config.: https://codeberg.org/davidak/nixos-config/src/commit/7b61845b50c2136a8deb1e765fbeae6a64e04f16/profiles/personal.nix#L18-L21

It does not make a difference to add qemuRunAsRoot = false;.

The files /run/libvirt/nix-ovmf/OVMF_CODE.fd:/run/libvirt/nix-ovmf/OVMF_VARS.fd does exist.

I run it as strace -ff virt-manager and find no occurance of OVMF. Also nothing relevant in the journal.

So it's still a mystery what the issue here is.

TredwellGit commented 3 years ago

virtualisation.libvirtd.enable = true; needs to be set to link /run/libvirt/nix-ovmf/OVMF_CODE.fd:/run/libvirt/nix-ovmf/OVMF_VARS.fd even if you only want to use a user session.

davidak commented 3 years ago

It is. What do you mean?

TredwellGit commented 3 years ago

https://github.com/NixOS/nixpkgs/blob/22b61e52634160847a19e63b65265219f9a806d6/nixos/modules/virtualisation/libvirtd.nix#L200-L201 It is an issue that for /run/libvirt/nix-ovmf/OVMF_CODE.fd:/run/libvirt/nix-ovmf/OVMF_VARS.fd to be linked Nixpkgs requires the system daemon to be enabled if only the user daemon is going to be used. It is also an issue that ~/.config/libvirt/qemu.conf must be configured for user sessions, but not system sessions, to use UEFI.

If you have done both of these, then there is another different issue.

stale[bot] commented 2 years ago

I marked this as stale due to inactivity. → More info

stale[bot] commented 2 years ago

I marked this as stale due to inactivity. → More info

spikespaz commented 1 year ago

This is still an issue

Vskilet commented 1 year ago

Hi, I still have the same issue, I can't find any OVMF file where it should be :

$ ls -ahl /run/libvirt/nix-ovmf/OVMF_CODE.fd
lrwxrwxrwx 1 root root 69 27 sept. 22:12 /run/libvirt/nix-ovmf/OVMF_CODE.fd -> /nix/store/nq45p2h6w5kmg4jvzs4ky7g1lgpgydkl-qemu-ovmf/FV/OVMF_CODE.fd
$ ls -ahl /nix/store/nq45p2h6w5kmg4jvzs4ky7g1lgpgydkl-qemu-ovmf/FV/
total 28M
dr-xr-xr-x   3 root root 4,0K  1 janv.  1970 .
dr-xr-xr-x   4 root root 4,0K  1 janv.  1970 ..
-r--r--r--   1 root root   20  1 janv.  1970 DXEFV.ext
-r--r--r--   1 root root  12M  1 janv.  1970 DXEFV.Fv
-r--r--r--   1 root root   88  1 janv.  1970 DXEFV.Fv.map
-r--r--r--   1 root root 5,3K  1 janv.  1970 DXEFV.Fv.txt
-r--r--r--   1 root root  18K  1 janv.  1970 DXEFV.inf
dr-xr-xr-x 129 root root  16K  1 janv.  1970 Ffs
-r--r--r--   1 root root   20  1 janv.  1970 FVMAIN_COMPACT.ext
-r--r--r--   1 root root 1,7M  1 janv.  1970 FVMAIN_COMPACT.Fv
-r--r--r--   1 root root   87  1 janv.  1970 FVMAIN_COMPACT.Fv.map
-r--r--r--   1 root root  106  1 janv.  1970 FVMAIN_COMPACT.Fv.txt
-r--r--r--   1 root root  802  1 janv.  1970 FVMAIN_COMPACT.inf
-r--r--r--   1 root root  464  1 janv.  1970 GuidedSectionTools.txt
-r--r--r--   1 root root  31K  1 janv.  1970 Guid.xref
-r--r--r--   1 root root  13M  1 janv.  1970 MEMFD.fd
-r--r--r--   1 root root   20  1 janv.  1970 PEIFV.ext
-r--r--r--   1 root root 896K  1 janv.  1970 PEIFV.Fv
-r--r--r--   1 root root 3,0K  1 janv.  1970 PEIFV.Fv.map
-r--r--r--   1 root root  728  1 janv.  1970 PEIFV.Fv.txt
-r--r--r--   1 root root 2,8K  1 janv.  1970 PEIFV.inf
-r--r--r--   1 root root   20  1 janv.  1970 SECFV.ext
-r--r--r--   1 root root 208K  1 janv.  1970 SECFV.Fv
-r--r--r--   1 root root  310  1 janv.  1970 SECFV.Fv.map
-r--r--r--   1 root root  151  1 janv.  1970 SECFV.Fv.txt
-r--r--r--   1 root root  938  1 janv.  1970 SECFV.inf
n8henrie commented 1 year ago

homebrew-installed libvirt seems to work fine for VMs on an M1 Mac (https://n8henrie.com/2022/09/linux-vms-on-my-m1-mac/), but with nix-installed libvirt and qemu I'm getting error: operation failed: Unable to find any firmware to satisfy 'efi'; based on this thread it looks like unavailability of OVMF may be the culprit?

$ nix search nixpkgs#OVMF
* legacyPackages.aarch64-darwin.OVMF (202205)
  Sample UEFI firmware for QEMU and KVM
$ nix shell nixpkgs/nixpkgs-unstable#OVMF
error: Package ‘OVMF-202205’ in /nix/store/5y5ndnbgvv6mfknnxv48v1swznc5g6wx-source/pkgs/applications/virtualization/OVMF/default.nix:84 is not supported on ‘aarch64-darwin’, refusing to evaluate.

EDIT: Created a separate issue and a PR that gets EFI VM images working on my M1 Mac.

Jayman2000 commented 1 year ago

I found a work around for this bug. Here’s the relevant part of my configuration:

{
  virtualisation.libvirtd.enable = true;
  programs.dconf.enable = true;
  home-manager.users.jayman = { pkgs, ... }: {
    home.packages = [ pkgs.virt-manager ];
  };
}

If I try to create a VM using a “QEMU/KVM User Session” connection, then virt-manager won’t be able to find the UEFI firmware image. If I try to create a VM using a “QEMU/KVM” connection, then virt-manager will find the UEFI firmware image.

edanaher commented 1 year ago

For me, virtualisation.libvirtd.enable = true; wasn't enough; after poking at the relevant source, I found that running systemctl restart libvirtd-config actually generated the symlink. I suspect there's supposed to be a cleaner way to do this, but that works for me for now.

Vskilet commented 1 year ago

It seems that something change on nixos-unstable and now files are present so default options work correctly on my side.

blitz commented 1 year ago

This is still an issue. I can't create UEFI VMs in the "Qemu/KVM User Session". It does work in the system-wide session, though.

enderger commented 1 year ago

For me, even the "Qemu/KVM" session is not working.

ErrorNoInternet commented 1 year ago

Same here, the QEMU/KVM session doesn't provide a UEFI option.

virtualization is enabled in configuration.nix, virt-manager is installed via home-manager. All of my VMs in virt-manager are under "QEMU/KVM", and the files /run/libvirt/nix-ovmf/OVMF_CODE.fd and /run/libvirt/nix-ovmf/OVMF_VARS.fd do exist.

aviallon commented 10 months ago

I have the same issues. Tried all of the workarounds in this thread.

adamdicarlo commented 8 months ago

I solved this by adding OVMF explicitly to my environment.systemPackages.

blitz commented 8 months ago

I solved this by adding OVMF explicitly to my environment.systemPackages.

That's good to know, but this should really not be necessary.

bbqsrc commented 6 months ago

To make Windows 11 play nice:

  virtualisation = {
    libvirtd = {
      enable = true;
      qemu = {
        package = pkgs.qemu_kvm;
        runAsRoot = true;
        swtpm.enable = true;
        ovmf = {
          enable = true;
          packages = [(nixosUnstable.OVMF.override {
            secureBoot = true;
            tpmSupport = true;
          }).fd];
        };
      };
    };
  };

Pay attention to the .fd on the OVMF package. The actual files are not in the out. This is likely where the issue comes from.

onny commented 6 months ago

@bbqsrc Could you try if it works on Gnome-Boxes for you too? Are you using Virt-Manager?

bbqsrc commented 6 months ago

I am using virt-manager via X11 over SSH.

TotalTaxAmount commented 5 months ago

This is still an issue for me, even with the fd appended on. It appears the symlinks to:

TotalTaxAmount commented 5 months ago

Appears to be moving those files to a different location in /nix/store:

 nix log /nix/store/gcm2yhiiz932f3qhr1z0fcd1whwybvdb-OVMF-202402/ | grep OVMF_VARS
Fd File Name:OVMF_VARS (/build/edk2-unvendored-src/Build/OvmfX64/RELEASE_GCC5/FV/OVMF_VARS.fd)
copied 'Build/OvmfX64/RELEASE_GCC5/FV/OVMF_VARS.fd' -> '/nix/store/gcm2yhiiz932f3qhr1z0fcd1whwybvdb-OVMF-202402/FV/OVMF_VARS.fd'
copied 'Build/OvmfX64/RELEASE_GCC5/FV/OVMF_VARS.ms.fd' -> '/nix/store/gcm2yhiiz932f3qhr1z0fcd1whwybvdb-OVMF-202402/FV/OVMF_VARS.ms.fd'
removed 'Build/OvmfX64/RELEASE_GCC5/FV/OVMF_VARS.fd'
removed 'Build/OvmfX64/RELEASE_GCC5/FV/OVMF_VARS.ms.fd'
renamed '/nix/store/gcm2yhiiz932f3qhr1z0fcd1whwybvdb-OVMF-202402/FV/OVMF_VARS.fd' -> '/nix/store/vv8f4d580lb8iri6b2xym46hqrdcyz1z-OVMF-202402-fd/FV/OVMF_VARS.fd'
renamed '/nix/store/gcm2yhiiz932f3qhr1z0fcd1whwybvdb-OVMF-202402/FV/OVMF_VARS.ms.fd' -> '/nix/store/vv8f4d580lb8iri6b2xym46hqrdcyz1z-OVMF-202402-fd/FV/OVMF_VARS.ms.fd'

However /nix/store/gcm2yhiiz932f3qhr1z0fcd1whwybvdb-OVMF-202402/FV is still the directory that is symlinked to the directory (/nix/store/rqf3xmixdjznl7qxyxy4h5ciqg77pi7i-qemu-ovmf/FV) that is symlinked to /run/libvirt/nix-ovmf

lasandell commented 1 month ago

tl;dr Adding qemu to my environment.systemPackages and the following snippet to my nixos config makes everything work - libvirt / virt-manger for both system and user sessions and GNOME Boxes (which itself uses a libvirt user session):

systemd.tmpfiles.rules =
  let
    firmware =
      pkgs.runCommandLocal "qemu-firmware" { } ''
        mkdir $out
        cp ${pkgs.qemu}/share/qemu/firmware/*.json $out
        substituteInPlace $out/*.json --replace ${pkgs.qemu} /run/current-system/sw
      '';
  in
  [ "L+ /var/lib/qemu/firmware - - - - ${firmware}" ];

I don't think the separate OVMF package is necessary anymore, nor manually selecting the firmware file - QEMU includes its own UEFI firmwares with JSON descriptor files that libvirt uses to automatically select a compatible firmware. This comment suggests that the NixOS way of specifying firmware files with an nvram setting in qemu.conf is outdated. I think using QEMU's built in firmware / descriptors may be the way forward as GNOME Boxes only supports that mechanism.

The issue is that libvirt doesn't know where to look to find QEMU's firmware descriptor files, so the above configuration expression places them in /var/lib/qemu/firmware (after some /run/current-system substitutions to avoid locking a vm to a /nix/store path). This works because the libvirt package overrides its sysconfdir for QEMU to be /var/lib/qemu instead of /etc/qemu. I based it on this code in the libvirtd module that's doing something similar for vhost-users.

Something like this could be incorporated into the libvirtd module, thought it's still a bit funky the way it depends on /run/current-system. The OVMF options get around this by creating /run/libvirt/nix-ovmf/ in libvirtd-config.service, though this all requires the system libvirtd service to be enabled, which may not be the case if only the user session (or GNOME boxes) is used.