If you’re trying to debug that problem you’re having in your Linux distribution, but can’t figure out if the problem is in the application or in your own distribution, the solution is to try to simulate the same behavior in a virtual machine. Or if you develop for different Linux distributions and want to test your packages, you can create virtual machines of different distributions to test your applications.

An easy way to do this is using libvirt, an open-source tool used for managing machine virtualization. It provides the server and libraries on the host to interact with hypervisors and guest systems.

Installing libvirt on Fedora

If you have Fedora installed on your host computer, you can follow the steps below to install libvirt:

sudo dnf install @virtualization

This will install the following packages:

Group: Virtualization
Description: These packages provide a graphical virtualization environment.
Mandatory Packages:
 virt-install
Default Packages:
 libvirt-daemon-config-network
 libvirt-daemon-kvm
 qemu-kvm
 virt-manager
 virt-viewer
Optional Packages:
 libguestfs-tools
 python3-libguestfs
 virt-top

After installation, start the libvirt service:

sudo systemctl start libvirtd

To enable the service at boot, run:

sudo systemctl enable libvirtd

And finally, verify that the kernel modules were properly loaded:

[root@localhost ~]# lsmod | grep kvm
kvm_amd               114688  0
kvm                   831488  1 kvm_amd

For more details on installing libvirt on Fedora, visit Getting started with virtualization. For a guide on how to install on Ubuntu, visit UbuntuKVMWalkthrough.

Creating the Dynamically Allocated Disk

Let’s start by creating a dynamically allocated disk for our guest operating system, i.e., our virtual machine. To do this, run the command below:

sudo truncate --size=20480M /var/lib/libvirt/images/fedora36.img

The command above will create a 20GB disk that will be used by our virtual machine in the specified path.

Downloading Fedora 36 Server

You can download the Fedora Server ISO here. If you want to use the same version as this article, the direct link to the ISO, click here. With the ISO downloaded, let’s now run the command that will create our guest:

sudo virt-install \
--name fedora36 \
--ram 4096 \
--vcpus 2 \
--disk path=/var/lib/libvirt/images/fedora36.img,size=20 \
--os-variant fedora36 \
--network bridge=virbr0 \
--graphics none \
--console pty,target_type=serial \
--location /tmp/Fedora-Server-dvd-x86_64-36-1.5.iso \
--extra-args 'console=ttyS0,115200n8'

If you receive a permission error like this: 'WARNING /path/to/fedora.iso may not be accessible by the hypervisor. You will need to grant the 'qemu' user search permissions for the following directories:', place the Fedora ISO in a location that qemu has read permission for, in this case we're placing the ISO in the /tmp folder.

Continuing the Installation

After running the command above, the following text will be displayed in your terminal:

Text mode provides a limited set of installation options. It does not offer
custom partitioning for full control over the disk layout. Would you like to use
VNC mode instead?
 
1) Start VNC
2) Use text mode

Here it’s up to you if you prefer to continue with the graphical or text installation. If you want to continue with the installation in text mode, answer with option 2 and press Enter.

If you chose text mode, proceed with the setup the way you think is best to configure your new Fedora installation, such as configuring the timezone, root password, creating a user during installation, and others. The text mode installation is quite intuitive and easy to understand.

After finishing your configuration in text mode, press b to start the installation and wait.

If at any point during installation you lose connection to the VM console, it's possible to reconnect to the virtual machine by typing virsh console fedora36:

[root@localhost ~]# virsh console fedora36
Connected to domain fedora36
Escape character is ^]  # Enter key

The installation will be complete when the following message is displayed:

Installation complete. Press ENTER to quit:

Press Enter and the VM will restart.

If the VM didn't restart and just shut down, you can start it again by typing sudo virsh start fedora36:

[root@localhost ~]# sudo virsh start fedora36
Domain 'fedora36' started

After Installation

To connect to the guest again after reboot, run:

[root@localhost ~]# sudo virsh console fedora36
Connected to domain 'fedora36'
Escape character is ^] (Ctrl + ])

Press Enter and the guest will request a login. Enter the username you configured for use during the installation process or log in as root and enter the password. From there you’ll have your Fedora virtual machine running and available to perform some tests, install packages, and more!

Useful Commands

List all guests:

[root@localhost ~]# sudo virsh list --all
Id   Name       State
-----------------------------
7    fedora36   running
-    win11      shut off

Shut down a guest:

[root@localhost ~]# sudo virsh shutdown fedora36
Domain 'fedora36' is being shutdown

Reboot a guest:

[root@localhost ~]# sudo virsh reboot fedora36
Domain 'fedora36' is being rebooted

Display information about a guest:

[root@localhost ~]# sudo virsh dominfo fedora36
Id:             8
Name:           fedora36
OS Type:        hvm
State:          running
CPU(s):         2
CPU time:       27.5s
Max memory:     4194304 KiB
Used memory:    4194304 KiB
Persistent:     yes
Autostart:      disable
Managed save:   no
Security model: none
Security DOI:   0

For the complete list of commands, access the virsh command help:

[root@localhost ~]# sudo virsh --help
virsh [options]... [<command_string>]
virsh [options]... <command> [args...]
 
options:
  -c | --connect=URI      hypervisor connection URI
  -d | --debug=NUM        debug level [0-4]
  -e | --escape <char>    set escape sequence for console
  -h | --help             this help
  -k | --keepalive-interval=NUM
                          keepalive interval in seconds, 0 for disable
  -K | --keepalive-count=NUM
                          number of possible missed keepalive messages
  -l | --log=FILE         output logging to file
  -q | --quiet            quiet mode
  -r | --readonly         connect readonly
  -t | --timing           print timing information
  -v                      short version
  -V                      long version
       --version[=TYPE]   version, TYPE is short or long (default short)
commands (non interactive mode):
...
...
...
...

References: