Bug 1446980

Summary: Regression: path='…' for channel type='unix' ignored
Product: Red Hat Enterprise Linux 7 Reporter: Robert Scheck <redhat-bugzilla>
Component: libvirtAssignee: Pavel Hrdina <phrdina>
Status: CLOSED ERRATA QA Contact: Jing Qi <jinqi>
Severity: medium Docs Contact:
Priority: unspecified    
Version: 7.3CC: berrange, phrdina, pkrempa, rbalakri, xuzhang, yalzhang
Target Milestone: rcKeywords: Reopened
Target Release: ---   
Hardware: Unspecified   
OS: Linux   
Whiteboard:
Fixed In Version: libvirt-3.2.0-6.el7 Doc Type: If docs needed, set a value
Doc Text:
Story Points: ---
Clone Of: Environment:
Last Closed: 2017-08-02 00:08:25 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 Robert Scheck 2017-05-01 03:21:55 UTC
Description of problem:
It seems like libvirt >= 2.0 (RHEL 7.3) meanwhile ignores path='…' for
channel type='unix', which I would simply call regression.

Example: Add the following snippet to /etc/libvirt/qemu/tux.xml:

--- snipp ---
    <channel type='unix'>
      <source mode='bind' path='/var/lib/libvirt/qemu/channel/target/tux/org.qemu.guest_agent.0'/>
      <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' path='/var/lib/libvirt/qemu/channel/target/tux/com.redhat.rhevm.vdsm'/>
      <target type='virtio' name='com.redhat.rhevm.vdsm'/>
      <address type='virtio-serial' controller='0' bus='0' port='3'/>
    </channel>
--- snapp ---

Version-Release number of selected component (if applicable):
libvirt-2.0.0-10.el7_3.5.x86_64

How reproducible:
Everytime, see above and below.

Actual results:
/var/lib/libvirt/qemu/channel/target/domain-2-tux/org.qemu.guest_agent.0
/var/lib/libvirt/qemu/channel/target/domain-2-tux/com.redhat.rhevm.vdsm

Expected results:
/var/lib/libvirt/qemu/channel/target/tux/org.qemu.guest_agent.0
/var/lib/libvirt/qemu/channel/target/tux/com.redhat.rhevm.vdsm

Comment 2 Peter Krempa 2017-05-02 06:54:14 UTC
The problem is that you are attempting to create the sockets in the directory which libvirt uses to create the sockets. The naming convention of a new VM thus follows the path which libvirt would use.

If you attempt to create the sockets in path other than /var/lib/libvirt/qemu/channel/target it should work as expected.

Since the path is indented to use by libvirt's internal files, user specified paths should not lead here.

Technical note:

The following function clears the path if it's in the libvirt's channel directory:

/*
 * Clear auto generated unix socket path, i.e., the one which starts with our
 * channel directory.
 */
static void
qemuDomainChrDefDropDefaultPath(virDomainChrDefPtr chr,
                                virQEMUDriverPtr driver)
{
    virQEMUDriverConfigPtr cfg = virQEMUDriverGetConfig(driver);

    if (chr->deviceType == VIR_DOMAIN_CHR_DEVICE_TYPE_CHANNEL &&
        chr->targetType == VIR_DOMAIN_CHR_CHANNEL_TARGET_TYPE_VIRTIO &&
        chr->source->type == VIR_DOMAIN_CHR_TYPE_UNIX &&
        chr->source->data.nix.path &&
        STRPREFIX(chr->source->data.nix.path, cfg->channelTargetDir)) {
        VIR_FREE(chr->source->data.nix.path);
    }

    virObjectUnref(cfg);
}

Comment 3 Robert Scheck 2017-05-02 08:09:48 UTC
Peter, may I ask whether and where this behaviour is documented (aside from
the code itself)?

Comment 4 Peter Krempa 2017-05-02 10:40:38 UTC
Hmm, this aspect is not documented in the libvirt docs. On the other hand, according to the linux filesystem hierarchy standard ([1], man 7 hier) there's a reasonable expectation that the data in /var/lib belongs to the application and thus users should not touch it.

[1] https://en.wikipedia.org/wiki/Filesystem_Hierarchy_Standard :

/var/lib - State information. Persistent data modified by programs as they run, e.g., databases, packaging system metadata, etc. [1]

Comment 5 Daniel Berrangé 2017-05-02 10:50:37 UTC
Regardless of what the FHS says, we've been recommending that people use /var/lib/libvirt/qemu for VM channel sockets whenever anyone has asked, since that's the directory which works reliably out of the box wrt SELinux labelling. So blowing away the user's data in this way is not desirable.

Comment 6 Peter Krempa 2017-05-02 11:05:56 UTC
That way it's hard to guarantee that the user does not mess up their configuration by using a path that would be generated automatically by libvirtd for new VMs, where the new VM would fail to start.

Comment 7 Daniel Berrangé 2017-05-02 12:23:32 UTC
The key issue is that this was a valid XML configuration the user had, and we're silently changing their data which is liable to break their app usage. The reason libvirt changed its own autogenerated paths was sensible, to fix problem with SELinux labelling in some particular scenarios, but that's not enough justification to break user specified paths which were previously working fine.

Comment 8 Pavel Hrdina 2017-05-10 14:54:12 UTC
The only thing we can do is to improve the pattern that is used to detect whether the path was auto-generated or not.

These are the patterns that we've ever used:

  $CHANNEL_TARGET_DIR/$DOM_NAME.$TARGET_NAME                      (1.2.18 and older)
  $CHANNEL_TARGET_DIR/domain-$DOM_NAME/$TARGET_NAME               (1.2.19 - 1.3.2)
  $CHANNEL_TARGET_DIR/domain-%ID-%DOM_NAME_SHORT/$TARGET_NAME     (1.3.3 and newer)

where $CHANNEL_TARGET_DIR on most systems is:

  /var/lib/libvirt/qemu/channel/target         (for system libvirtd)
  /home/$USER/.config/qemu/channel/target      (for session libvirtd)

For automatically generated paths Libvirt creates required directories in order to create the UNIX socket and that changed in past.  Historically we've stored the automatically generated paths in the config XML, but since 1.3.1 Libvirt we generate the paths while starting domain and store the path only in the active XML.

For config XML created by Libvirt older than 1.3.1 there is no way how to determine whether the path was auto-generated or not if it matches the pattern that we used.

Improving the pattern would fix this bug because the path doesn't match any of our automatically generated path, however if user would specify path, that matches one of the mentioned patterns we still remove that path from config XML and generate a new one while starting a domain.

Comment 9 Pavel Hrdina 2017-05-16 09:44:30 UTC
Upstream commit:

commit ed996604464ab1652ad8d2de3ac446f460dd2ab1
Author: Pavel Hrdina <phrdina>
Date:   Thu May 11 14:09:35 2017 +0200

    qemu: improve detection of UNIX path generated by libvirt

Comment 11 Robert Scheck 2017-05-16 17:42:50 UTC
Cool, thank you! :) Could you add the patterns in comment #8 to the libvirt
documentation as well? That also would make clear which paths should be not
used to avoid clashes with generated ones.

Comment 13 Jing Qi 2017-06-08 08:59:50 UTC
Verified with libvirt-3.2.0-7.el7.x86_64 & libvirt-3.2.0-7.virtcov.el7.x86_64. 
1. Created /var/lib/libvirt/qemu/channel/target/tux directory and chown qemu:qemu  tux. 
2. Use below configuration which described in bug:

    <channel type='unix'>
      <source mode='bind' path='/var/lib/libvirt/qemu/channel/target/tux/org.qemu.guest_agent.0'/>
      <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' path='/var/lib/libvirt/qemu/channel/target/tux/com.redhat.rhevm.vdsm'/>
      <target type='virtio' name='com.redhat.rhevm.vdsm'/>
      <address type='virtio-serial' controller='0' bus='0' port='3'/>
    </channel>

Start the VM.

3.The /var/lib/libvirt/qemu/channel/target/tux/org.qemu.guest_agent.0
and /var/lib/libvirt/qemu/channel/target/tux/com.redhat.rhevm.vdsm were created as expected.

Comment 14 errata-xmlrpc 2017-08-02 00:08:25 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 15 errata-xmlrpc 2017-08-02 01:32: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://access.redhat.com/errata/RHEA-2017:1846