14

I have a VM which I can start with virsh. According to virsh dumpxml VM1, this is the allocated pty:

<serial type='pty'>
  <source path='/dev/pts/6'/>
  <target port='0'/>
  <alias name='serial0'/>
</serial>
<console type='pty' tty='/dev/pts/6'>
  <source path='/dev/pts/6'/>
  <target type='serial' port='0'/>
  <alias name='serial0'/>
</console>

The VM is running:

# virsh list
 Id Name                 State
----------------------------------
  7 VM1                  running

Inside the VM, this is the grub configuration:

kernel          /boot/vmlinuz-2.6.24-28-virtual root=UUID=7a1685b9-ecc8-4b70-932c-459a6faac07d ro quiet splash console=tty0 console=ttyS0,9600n8

And this is the command line launched by virsh to start the VM:

/usr/bin/kvm -S -M pc-0.12 -enable-kvm -m 256 -smp 1,sockets=1,cores=1,threads=1 -name VM1 -uuid 47ff6ec2-a748-4738-16b9-2ffe5780e456 -nodefaults -chardev socket,id=monitor,path=/var/lib/libvirt/qemu/VM1.monitor,server,nowait -mon chardev=monitor,mode=readline -rtc base=utc -boot c -drive file=/var/VMs/VM1.qcow2,if=none,id=drive-ide0-0-0,boot=on,format=raw -device ide-drive,bus=ide.0,unit=0,drive=drive-ide0-0-0,id=ide0-0-0 -device virtio-net-pci,vlan=0,id=net0,mac=52:54:00:12:34:50,bus=pci.0,addr=0x3 -net tap,fd=64,vlan=0,name=hostnet0 -chardev pty,id=serial0 -device isa-serial,chardev=serial0 -usb -vnc 127.0.0.1:0 -k de -vga cirrus -device virtio-balloon-pci,id=balloon0,bus=pci.0,addr=0x4

But if I connect with virsh console VM1, or I do cat /dev/pts/6, nothing is shown in the VM console.

Is there something else that I must consider?

UPDATE

I have two VMs, one started directly with kvm, the other via virsh. The one started directly has a working console. I have verified the open files in both cases:

root@host1:~# lsof | grep 25093 | grep dev
kvm       25093         root  DEL       REG                0,4                3758780 /dev/zero
kvm       25093         root  DEL       REG                0,4                3758779 /dev/zero
kvm       25093         root  DEL       REG                0,4                3758777 /dev/zero
kvm       25093         root    0u      CHR              136,3         0t0          6 /dev/pts/3
kvm       25093         root    1u      CHR              136,3         0t0          6 /dev/pts/3
kvm       25093         root    2u      CHR              136,3         0t0          6 /dev/pts/3
kvm       25093         root    3u      CHR             10,232         0t0       8025 /dev/kvm
kvm       25093         root    7u      CHR             10,200         0t0       4983 /dev/net/tun
root@host1:~# lsof | grep 8341 | grep dev
kvm        8341 libvirt-qemu  DEL       REG                0,4                9743486 /dev/zero
kvm        8341 libvirt-qemu  DEL       REG                0,4                9743485 /dev/zero
kvm        8341 libvirt-qemu  DEL       REG                0,4                9743483 /dev/zero
kvm        8341 libvirt-qemu    0r      CHR                1,3         0t0       4640 /dev/null
kvm        8341 libvirt-qemu    4u      CHR                5,2         0t0       4897 /dev/ptmx
kvm        8341 libvirt-qemu    5u      CHR             10,232         0t0       8025 /dev/kvm
kvm        8341 libvirt-qemu   64u      CHR             10,200         0t0       4983 /dev/net/tun

As you can see, in one of the VMs (the wrong one), there are no file descriptors 1 & 2, and file descriptor 0 is redirected to /dev/null. That is the problem I guess.

The question is, how do I tell virsh not to do that?

2
  • Have you tried to hit "enter" a couple of times, to get the login prompt?
    – dyasny
    Feb 29, 2012 at 18:03
  • yes, i have, but there is no reaction. Even during the startup phase (I connect to the pty immediately after starting up the VM) I see no grub startup, and no linux boot messages. I think the VM is running fine, but I can not access it from the outside. I need to debug it (the network is not yet working), that is why I need console access.
    – blueFast
    Feb 29, 2012 at 18:46

5 Answers 5

15
<serial type='pty'>
  <target port='0'/>
</serial>
<console type='pty'>
  <target type='serial' port='0'/>
</console>

This is what I normally add to the VMs definition, using virsh edit Then console=ttyS0 appended in the VM's kernel line in grub.conf

Never failed me so far

9
  • 1
    What is the command that you use to create the vm? I use the following: virt-install --connect qemu:///system -n VM1 -r 256 --vcpus=1 --vnc --noautoconsole --os-type linux --accelerate --network=bridge:eth0,model=virtio -m 52:54:00:12:34:50 -k de --import --nographics --disk /var/VMs/VM1.qcow2
    – blueFast
    Feb 29, 2012 at 21:22
  • 3
    The problem was somewhere else, but thanks to your hints, I found it. Using virt-manager allowed me to open a VNC connection and I saw that it is not booting at all, because I did not specify in the --disk parameter that this is a qcow2 disk image. Aparently this can not be automatically inferred - even though the extension should be a good hint?. The command must be extended with --disk path=$vm_drive,format=qcow2
    – blueFast
    Feb 29, 2012 at 23:54
  • 2
    In Linux extensions are meaningless, just a part of the filename
    – dyasny
    Apr 8, 2015 at 13:17
  • 1
    Sure, but it would be very strange to suffix a python script with .sh or a bash script with .py (and would probably not work in some cases: you can not import a python module which does not end in .py for example)
    – blueFast
    Apr 8, 2015 at 14:12
  • 2
    that's just done for convenience, nothing to prevent a .sh file to be executed as a python script, if the hashbang is correct
    – dyasny
    Apr 8, 2015 at 14:44
17

Working example of using Debian jessie as host and guest operating system.

  1. create a VM using virt-install or virt-manager In any case you will get serial console statements added to VM.xml file

  2. in guest VM run the following

     systemctl enable serial-[email protected]
     systemctl start [email protected]
    
  3. in guest VM in /etc/default/grub replace

     GRUB_CMDLINE_LINUX_DEFAULT="quiet"
     #GRUB_TERMINAL=console
    

by

    GRUB_CMDLINE_LINUX_DEFAULT="console=tty0 console=ttyS0"
    GRUB_TERMINAL="serial console"
  1. in guest VM run the following

     guest# update-grub
    
  2. the VM console for running VM can be get by

     host# virsh console VM
    

or start the VM with console attached

    host# virsh start VM --console

Sources:

4
  • Still working 100% on Stretch Apr 26, 2019 at 3:45
  • What is the purpose of tty0 and serial? It works with just GRUB_CMDLINE_LINUX_DEFAULT="console=ttyS0" and GRUB_TERMINAL="console" in my case. I couldn't find explanation in the sources.
    – Lacek
    Jul 10, 2019 at 3:28
  • Just step 1 and 2 are sufficient. No need to update your grub configuration. I just tested this on both Debian buster and bullseye.
    – Serrano
    Nov 3, 2021 at 23:22
  • this worked for me like a charm ! I'm using CentOS Linux release 7.9.2009 (Core) for the host and Ubuntu 18.04.5 LTS for the guest VM
    – rh4games
    Dec 29, 2021 at 18:31
6

I've found the most applicable answer here:

Suppose your virtual domain is myGuest, your preferred editor is vi, and your guest is installed with grub2 and uses systemd. If the last assumption is not true, you might have a look at Working with the Serial Console.

First, install libguestfs-tools on the host: sudo apt install libguestfs-tools. You will need this when working with headless guests.

Second, shut down your guest: virsh shutdown myGuest.

Next, mount the virtual disk: guestmount -d myGuest -i /mnt (or use any other existing directory as mountpoint). Now in /mnt you should be able to see the filesystem of the guest.

With grub2 and systemd, you only have to modify the grub configuration: vi /mnt/etc/default/grub, and modify like

GRUB_CMDLINE_LINUX='console=tty0 console=ttyS0,19200n8'
GRUB_TERMINAL=serial
GRUB_SERIAL_COMMAND="serial --speed=19200 --unit=0 --word=8 --parity=no --stop=1"

As you will have to run update-grub on the guest, for the first start you have to also modify /mnt/boot/grub/grub.cfg. Find the default boot menu item and append the console information to the linux entry to look similar to

linux   /boot/vmlinuz-4.4.0-75-generic root=UUID=76f3e237-d791-4e9d-8ad7-fe5c9165ae55 ro console=ttyS0,19200 earlyprint=serial,ttyS0,19200

Maybe you need root privileges to mount and edit the files.

Now restart the guest and start the virtual console:

virsh start myGuest && virsh console myGuest

You should see the kernel log and then a login prompt. After logging in, don't forget to run sudo update-grub.

4
systemctl enable serial[email protected]
systemctl start [email protected]

has been sufficient for an Ubuntu guest (20.04), VM been initialized with virt-manager.

No need to change GRUB configuration entries, nor adding serial/console to the virsh XML file.

2
  • This also works on Debian (buster, bullseye).
    – Serrano
    Nov 3, 2021 at 23:25
  • Also works on an Ubuntu 22.04 guest. No other changes needed on host or guest.
    – zwets
    Nov 15, 2022 at 9:26
0
systemctl enable serial[email protected]
systemctl start [email protected]

is good but i think You have to add sth to grub configuration to make console work before service serial-getty starts

You must log in to answer this question.

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