Bug 1226854 - automatically generated path for a unix channel contains "(null)"
Summary: automatically generated path for a unix channel contains "(null)"
Keywords:
Status: CLOSED ERRATA
Alias: None
Product: Red Hat Enterprise Linux 7
Classification: Red Hat
Component: libvirt
Version: 7.2
Hardware: x86_64
OS: Linux
medium
medium
Target Milestone: rc
: ---
Assignee: Jiri Denemark
QA Contact: Virtualization Bugs
URL:
Whiteboard:
Depends On:
Blocks:
TreeView+ depends on / blocked
 
Reported: 2015-06-01 09:58 UTC by Luyao Huang
Modified: 2015-11-19 06:39 UTC (History)
6 users (show)

Fixed In Version: libvirt-1.2.17-1.el7
Doc Type: Bug Fix
Doc Text:
Clone Of:
Environment:
Last Closed: 2015-11-19 06:39:35 UTC
Target Upstream Version:


Attachments (Terms of Use)


Links
System ID Private Priority Status Summary Last Updated
Red Hat Product Errata RHBA-2015:2202 0 normal SHIPPED_LIVE libvirt bug fix and enhancement update 2015-11-19 08:17:58 UTC

Description Luyao Huang 2015-06-01 09:58:38 UTC
description of problem:
 libvirt will use a wrong name for unix type channel device with no target name

Version-Release number of selected component (if applicable):
libvirt-1.2.15-2.el7.x86_64

How reproducible:
100%

Steps to Reproduce:
1. edit a guest xml like this:
# virsh edit rhel7.0

    <channel type='spicevmc'>
      <target type='virtio' name='com.redhat.spice.0'/>
      <address type='virtio-serial' controller='0' bus='0' port='1'/>
    </channel>
    <channel type='unix'>
      <source mode='bind' path='/var/lib/libvirt/qemu/r6.agent'/>
      <target type='virtio' name='org.qemu.guest_agent.0'/>
      <address type='virtio-serial' controller='0' bus='0' port='2'/>
    </channel>
    <channel type='unix'>            <----notice this
      <source mode='bind'/>
      <target type='virtio'/>
      <address type='virtio-serial' controller='0' bus='0' port='3'/>
    </channel>


2. recheck the xml:
# virsh dumpxml rhel7.0
    <channel type='spicevmc'>
      <target type='virtio' name='com.redhat.spice.0'/>
      <address type='virtio-serial' controller='0' bus='0' port='1'/>
    </channel>
    <channel type='unix'>
      <source mode='bind' path='/var/lib/libvirt/qemu/r6.agent'/>
      <target type='virtio' name='org.qemu.guest_agent.0'/>
      <address type='virtio-serial' controller='0' bus='0' port='2'/>
    </channel>
    <channel type='unix'>            <---notice this
      <source mode='bind' path='/var/lib/libvirt/qemu/channel/target/rhel7.0.(null)'/>
      <target type='virtio'/>
      <address type='virtio-serial' controller='0' bus='0' port='3'/>
    </channel>

3. try to start guest and will get error:

# virsh start rhel7.0
error: Failed to start domain rhel7.0
error: internal error: early end of file from monitor: possible problem:
2015-06-01T07:20:08.860661Z qemu-system-x86_64: -device virtserialport,bus=virtio-serial0.0,nr=3,chardev=charchannel2,id=channel2,name=com.redhat.spice.0: virtio-serial-bus: A port already exists by name com.redhat.spice.0
2015-06-01T07:20:08.860788Z qemu-system-x86_64: -device virtserialport,bus=virtio-serial0.0,nr=3,chardev=charchannel2,id=channel2,name=com.redhat.spice.0: Device 'virtserialport' could not be initialized

4. check qemu command line libvirt use:

...
-device virtserialport,bus=virtio-serial0.0,nr=1,chardev=charchannel0,id=channel0,name=com.redhat.spice.0 -chardev socket,id=charchannel1,path=/var/lib/libvirt/qemu/r6.agent,server,nowait -device virtserialport,bus=virtio-serial0.0,nr=2,chardev=charchannel1,id=channel1,name=org.qemu.guest_agent.0 -chardev socket,id=charchannel2,path=/var/lib/libvirt/qemu/channel/target/rhel7.0.(null),server,nowait -device virtserialport,bus=virtio-serial0.0,nr=3,chardev=charchannel2,id=channel2,name=com.redhat.spice.0

Actual results:
libvirt use "com.redhat.spice.0" as a default name for unix type channel device,
but qemu forbid use the same name for 2 virtserialport. Why a Unix type channel use a name like a spicevmc.

Expected results:
build a right name for unix type channel device, or do not build it when we do not specified.

Also i doubt if this path name is okay "/var/lib/libvirt/qemu/channel/target/rhel7.0.(null)", maybe use a random string will be better.

Additional info:

From the code in function qemuBuildVirtioSerialPortDevStr():

 6392     if (!(dev->deviceType == VIR_DOMAIN_CHR_DEVICE_TYPE_CHANNEL &&
 6393           dev->source.type == VIR_DOMAIN_CHR_TYPE_SPICEVMC &&
 6394           virQEMUCapsGet(qemuCaps, QEMU_CAPS_DEVICE_SPICEVMC))) {
 6395         virBufferAsprintf(&buf, ",chardev=char%s,id=%s",
 6396                           dev->info.alias, dev->info.alias);
 6397         if (dev->deviceType == VIR_DOMAIN_CHR_DEVICE_TYPE_CHANNEL) {
 6398             virBufferAsprintf(&buf, ",name=%s", dev->target.name
 6399                               ? dev->target.name : "com.redhat.spice.0");
 6400         }
 6401     } else {
 6402         virBufferAsprintf(&buf, ",id=%s", dev->info.alias);
 6403     }

Comment 1 Jiri Denemark 2015-06-30 09:21:10 UTC
(In reply to Luyao Huang from comment #0)
> # virsh start rhel7.0
> error: Failed to start domain rhel7.0
> error: internal error: early end of file from monitor: possible problem:
> 2015-06-01T07:20:08.860661Z qemu-system-x86_64: -device
> virtserialport,bus=virtio-serial0.0,nr=3,chardev=charchannel2,id=channel2,
> name=com.redhat.spice.0: virtio-serial-bus: A port already exists by name
> com.redhat.spice.0
> 2015-06-01T07:20:08.860788Z qemu-system-x86_64: -device
> virtserialport,bus=virtio-serial0.0,nr=3,chardev=charchannel2,id=channel2,
> name=com.redhat.spice.0: Device 'virtserialport' could not be initialized

The wrong usage of com.redhat.spice.0 for the second channel is covered by bug
1179680.

> Also i doubt if this path name is okay
> "/var/lib/libvirt/qemu/channel/target/rhel7.0.(null)", maybe use a random
> string will be better.

This is definitely not OK. Apparently we have a bug in the code which
autogenerates paths for UNIX sockets. Let's reword this BZ to only cover this
second issue.

Comment 2 Jiri Denemark 2015-06-30 11:50:05 UTC
Sent upstream for review: https://www.redhat.com/archives/libvir-list/2015-June/msg01642.html

Comment 3 Jiri Denemark 2015-07-01 08:34:21 UTC
Fixed upstream by v1.2.17-rc2-5-gffbafd4:

commit ffbafd4e883900722cbfc68cd9053d4b42eb38fa
Author: Jiri Denemark <jdenemar@redhat.com>
Date:   Tue Jun 30 13:34:20 2015 +0200

    qemu: Avoid using ".(null)" in UNIX socket path
    
    The code which generates paths for UNIX socket blindly used target name
    without checking if it was set. Thus for the following device XML
    
        <channel type='unix'>
          <source mode='bind'/>
          <target type='virtio'/>
        </channel>
    
    we would generate "/var/lib/libvirt/qemu/channel/target/NAME.(null)"
    path which works but is not really correct. Let's not use the
    ".target_name" suffix at all if target name is not set.
    
    https://bugzilla.redhat.com/show_bug.cgi?id=1226854
    
    Signed-off-by: Jiri Denemark <jdenemar@redhat.com>

Comment 5 Shanzhi Yu 2015-07-06 09:51:08 UTC
Verify this with libvirt-1.2.17-1.el7.x86_64

1. Prepare a xml file as below

# cat r7.xml |grep channel -A 4 
    <channel type='spicevmc'>
      <target type='virtio' name='com.redhat.spice.0'/>
      <address type='virtio-serial' controller='0' bus='0' port='1'/>
    </channel>
    <channel type='unix'>
      <source mode='bind'/>
      <target type='virtio' name='org.qemu.guest_agent.0'/>
      <address type='virtio-serial' controller='0' bus='0' port='2'/>
    </channel>
    <channel type='unix'>
      <source mode='bind'/>
      <target type='virtio'/>
      <address type='virtio-serial' controller='0' bus='0' port='3'/>
    </channel>

2. Create domain with the prepared xml 
# virsh create r7.xml 
Domain r7 created from r7.xml

3. Check live guest xml 
# virsh dumpxml r7|grep channel -A 4 
    <channel type='spicevmc'>
      <target type='virtio' name='com.redhat.spice.0' state='disconnected'/>
      <alias name='channel0'/>
      <address type='virtio-serial' controller='0' bus='0' port='1'/>
    </channel>
    <channel type='unix'>
      <source mode='bind' path='/var/lib/libvirt/qemu/channel/target/r7.org.qemu.guest_agent.0'/>
      <target type='virtio' name='org.qemu.guest_agent.0' state='disconnected'/>
      <alias name='channel1'/>
      <address type='virtio-serial' controller='0' bus='0' port='2'/>
    </channel>
    <channel type='unix'>
      <source mode='bind' path='/var/lib/libvirt/qemu/channel/target/r7'/>
      <target type='virtio' state='disconnected'/>
      <alias name='channel2'/>
      <address type='virtio-serial' controller='0' bus='0' port='3'/>
    </channel>

So the socket path is right now, without suffix ".(null)"
 

A little problem about this is, I can configure the unix path which with ".(null)". Like 

# virsh dumpxml r7|grep null
      <source mode='bind' path='/var/lib/libvirt/qemu/channel/target/r7.(null)'/>

# virsh start r7 
Domain r7 started

# ps aux|grep null

/usr/libexec/qemu-kvm -name r7 -S -machine 
....
 -device virtserialport,bus=virtio-serial0.0,nr=2,chardev=charchannel1,id=channel1,name=org.qemu.guest_agent.0 -chardev socket,id=charchannel2,path=/var/lib/libvirt/qemu/channel/target/r7.(null),

Given that, file with name "file.(null)" is can be created in linux/unix env, so above is acceptable, right?

Comment 6 Jiri Denemark 2015-07-07 05:30:20 UTC
Sure, if you explicitly request such path, there's no reason libvirt should forbid that.

Comment 7 Shanzhi Yu 2015-07-07 05:55:00 UTC
Jiri, 
Thanks. 
Verify this bug.

Comment 9 errata-xmlrpc 2015-11-19 06:39:35 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://rhn.redhat.com/errata/RHBA-2015-2202.html


Note You need to log in before you can comment on or make changes to this bug.