qemu-devel
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: [Qemu-devel] qemu-ga virtio-serial socket clarification


From: Stefan Hajnoczi
Subject: Re: [Qemu-devel] qemu-ga virtio-serial socket clarification
Date: Fri, 4 Nov 2016 12:44:12 +0000
User-agent: Mutt/1.7.1 (2016-10-04)

On Tue, Oct 25, 2016 at 02:14:24PM -0400, Matt Broadstone wrote:
> Hi,
> 
> I've been attempting an experimental qemu agent using a node.js daemon on
> the host side, and have run into an issue I was hoping someone here might
> be able to help with:
> 
> Using libvirt I've set up a 'unix' channel for a domain using virtio-serial
> (the same way you would for the existing qemu agent) with the name
> 'test.agent', in order to bypass libvirt taking ownership of the domain
> socket. This works as expected, and so does the following test:
> 
>  - [host] $ echo "testing" | nc -U
> /var/lib/libvirt/qemu/channel/target/domain-T40001/test.agent
>  - [guest] $ cat -v < /dev/virtio-ports/test.agent
> 
> Then I tried the same test, converting the host->guest communication to
> node.js:
> 
> 'use strict';
> const net = require('net');
> const socketPath =
> '/var/lib/libvirt/qemu/channel/target/domain-T40001/test.agent';
> let socket = net.createConnection(socketPath);
> socket.write('testing');
> 
> In this case the data makes it across to the guest, however until I
> explicitly close the socket on the sender side (`socket.write('testing', ()
> => socket.end())`) both sides block indefinitely. I understand closing the
> socket brings the node example to parity with the netcat one, however after
> perusing the qemu-ga and libvirt repositories it looks like glib's io
> channels are being used on a single socket, and effectively handling
> bidirectional data.
> 
> Is this the expected behavior?

I have reproduced your test and it is expected behavior.

The virtio-serial port inside the guest has two states: connected and
disconnected.  When the port is disconnected read(2) returns 0 (EOF).
When the port is connect read(2) blocks or returns whatever data is
currently available.

Regarding node.js: node.js is an event loop so the process continues
running until your Javascript code terminates the event loop (your
script never does).  Since the virtio-serial port is kept open by the
node.js process on the host, the guest is in the connected state and
read(2) blocks inside the guest.

Here is a ping-pong test with node.js:

'use strict';
const net = require('net');
const socketPath = '/tmp/test.agent';
let socket = net.createConnection(socketPath);
socket.on('data', (data) => {
    let i = Number(data);
    socket.write(i + 1 + '\n');
});
socket.write('0\n');

Inside the guest I can alternate between "cat </dev/vport0p1" and "echo
1" and the node.js script is doing bi-directional communication.  You
could replace those two commands with a similar ping-pong program so it
doesn't require manual interaction.

Stefan

Attachment: signature.asc
Description: PGP signature


reply via email to

[Prev in Thread] Current Thread [Next in Thread]