Bug 1377602

Summary: hotplug of UDP chardev backends does not work properly
Product: Red Hat Enterprise Linux 7 Reporter: Yanqiu Zhang <yanqzhan>
Component: libvirtAssignee: Peter Krempa <pkrempa>
Status: CLOSED ERRATA QA Contact: Fangge Jin <fjin>
Severity: medium Docs Contact:
Priority: medium    
Version: 7.3CC: berrange, dyuan, fjin, jdenemar, mzhan, rbalakri, xuzhang, yafu, yanqzhan, zpeng
Target Milestone: rc   
Target Release: ---   
Hardware: x86_64   
OS: Linux   
Whiteboard:
Fixed In Version: libvirt-2.5.0-1.el7 Doc Type: If docs needed, set a value
Doc Text:
Story Points: ---
Clone Of: Environment:
Last Closed: 2017-08-01 17:16:43 UTC Type: Bug
Regression: --- Mount Type: ---
Documentation: --- CRM:
Verified Versions: Category: ---
oVirt Team: --- RHEL 7.3 requirements from Atomic Host:
Cloudforms Team: --- Target Upstream Version:
Embargoed:

Description Yanqiu Zhang 2016-09-20 08:12:05 UTC
Description of problem:
Guest with udp backend rng device should fail to start when no random data resource or when to connect a unknown host ip

Version-Release number of selected component (if applicable):
libvirt-2.0.0-9.el7.x86_64
Qemu-kvm-rhev-2.6.0-25.el7.x86_64

How reproducible:
100%

Steps to Reproduce:
1. Prepare a guest has following rng device in xml:
    <rng model='virtio'>
     <backend model='egd' type='udp'>
       <source mode='connect' host='localhost' service='1234'/>
     </backend>
    </rng>

2. Do not give any random data resource for it, and try to start the guest
The guest is started unexpectedly.

3. Destroy the guest, edit the guest's xml with following rng device, ip=1.2.3.4 is a non-exist host:
     <rng model='virtio'>
     <backend model='egd' type='udp'>
       <source mode='connect' host='1.2.3.4' service='1234'/>
     </backend>
    </rng>

4. Try to start the guest again
The guest is started unexpectedly, too.

5. Start a normal guest without rng device, and try to attach the rng device by xml as step 1 descripted.
Device attached successfully.

6. Start a normal guest without rng device, and try to attach the rng device by xml as step 3 descripted.
Failed to attach the rng device, but error is not correct:
error: internal error: unable to execute QEMU command 'chardev-add': Failed to bind socket: Cannot assign requested address

Actual results:
As above.
1.In step 2&4, guest with udp backend rng device can be started when no random data resource is given or when to connect a unknown host ip(1.2.3.4).
2.In step 5, a udp rng device can be attached even no random data resource is given.
3.In step 6, a udp rng device with a non-exist host ip failed to be attached with a uncorrect error, seems like a syntax error, because I used 'connect' source mode but not a 'bind' source mode.

Expected results:
1.In step 2, should fail to start with "connection refused" error;
  In step 4, should fail to start with "time out" error.
2.In step 5, a udp rng device should fail to be attached with "connection refused" error.
3.In step 6, failed error should be correct such as "time out" error.

Additional info:
1.The result tested by tcp backend are as follows, more reasonable.
    <rng model='virtio'>
     <backend model='egd' type='tcp'>
       <source mode='connect' host='1.2.3.4'(or localhost) service='1024'/>
       <protocol type='raw'/>
     </backend>
    </rng>
(1)Start guest without random data resource(host=localhost):
error: internal error: qemu unexpectedly closed the monitor: 2016-09-19T11:33:56.330256Z qemu-kvm: -chardev socket,id=charrng0,host=localhost,port=1024: Failed to connect socket: Connection refused
(2)Start guest with non-exit host ip(host='1.2.3.4'):
error: internal error: qemu unexpectedly closed the monitor: 2016-09-19T11:09:45.723691Z qemu-kvm: -chardev socket,id=charrng0,host=1.2.3.4,port=1024: Failed to connect socket: Connection timed out
(3)Hotplug the tcp backend rng device without random data resource(host=localhost):
error: internal error: unable to execute QEMU command 'chardev-add': Failed to connect socket: Connection refused
(4)Hotplug the tcp backend rng device with non-exit host ip(host='1.2.3.4'):
error: internal error: unable to execute QEMU command 'chardev-add': Failed to connect socket: Connection timed out

Comment 2 Daniel Berrangé 2016-09-20 11:49:05 UTC
The code for hotplug of UDP chardevs just seems broken to me.

In the method qemuMonitorJSONAttachCharDevCommand it is just doing:

        addr = qemuMonitorJSONBuildInetSocketAddress(chr->data.udp.connectHost,
                                                     chr->data.udp.connectService);
        if (!addr ||
            virJSONValueObjectAppend(data, "addr", addr) < 0)
            goto error;
 
which is ignoring the bindHost, bindService parameters, and also not actually requesting UDP in any way - the JSON generated is identical to that used for TCP chardevs, so I don't see how QEMU is actually going to use UDP at all.

Comment 3 Daniel Berrangé 2016-09-20 12:05:03 UTC
The QAPI schema for UDP chardevs confirms the libvirt code is just plain wrong - it needs to use 'local' and 'remote' instead of 'addr', and 'udp' instead of 'socket' for the type

{ 'struct': 'ChardevUdp', 'data': { 'remote' : 'SocketAddress',
                                  '*local' : 'SocketAddress' },
  'base': 'ChardevCommon' }

Comment 4 Peter Krempa 2016-10-06 08:44:45 UTC
Note that as UDP does not really establish a connection. Steps 2 and 4 of the reproducer steps are not unexpected. Qemu is able to start but no data will flow to the RNG backend as there is no source.

The hotplug case where libvirt would plug in a TCP backend rather than UDP is fixed by:

commit 9bc4179dd4ac19c93f6efd73e1f50fc6dad7cbc2
Author: Peter Krempa <pkrempa>
Date:   Tue Sep 27 16:01:55 2016 +0200

    qemu: monitor: Properly configure backend for UDP chardevs
    
    Since introduction of chardev hotplug the code was wrong for the UDP
    case and basically created a TCP socket instead. Use proper objects and
    type for UDP.

Comment 6 Fangge Jin 2017-03-15 03:28:02 UTC
Reproduce on build libvirt-2.0.0-10.el7.x86_64

Verify PASS on build libvirt-3.1.0-2.el7.x86_64

Steps are same as desciption. The test results are:
In step 2 and 4, guest starts successfully.
In step 5 and 6, rng device is attached successfully.

Comment 7 errata-xmlrpc 2017-08-01 17:16:43 UTC
Since the problem described in this bug report should be
resolved in a recent advisory, it has been closed with a
resolution of ERRATA.

For information on the advisory, and where to find the updated
files, follow the link below.

If the solution does not work for you, open a new bug report.

https://access.redhat.com/errata/RHEA-2017:1846

Comment 8 errata-xmlrpc 2017-08-01 23:57:38 UTC
Since the problem described in this bug report should be
resolved in a recent advisory, it has been closed with a
resolution of ERRATA.

For information on the advisory, and where to find the updated
files, follow the link below.

If the solution does not work for you, open a new bug report.

https://access.redhat.com/errata/RHEA-2017:1846