Note: This bug is displayed in read-only format because the product is no longer active in Red Hat Bugzilla.
RHEL Engineering is moving the tracking of its product development work on RHEL 6 through RHEL 9 to Red Hat Jira (issues.redhat.com). If you're a Red Hat customer, please continue to file support cases via the Red Hat customer portal. If you're not, please head to the "RHEL project" in Red Hat Jira and file new tickets here. Individual Bugzilla bugs in the statuses "NEW", "ASSIGNED", and "POST" are being migrated throughout September 2023. Bugs of Red Hat partners with an assigned Engineering Partner Manager (EPM) are migrated in late September as per pre-agreed dates. Bugs against components "kernel", "kernel-rt", and "kpatch" are only migrated if still in "NEW" or "ASSIGNED". If you cannot log in to RH Jira, please consult article #7032570. That failing, please send an e-mail to the RH Jira admins at rh-issues@redhat.com to troubleshoot your issue as a user management inquiry. The email creates a ServiceNow ticket with Red Hat. Individual Bugzilla bugs that are migrated will be moved to status "CLOSED", resolution "MIGRATED", and set with "MigratedToJIRA" in "Keywords". The link to the successor Jira issue will be found under "Links", have a little "two-footprint" icon next to it, and direct you to the "RHEL project" in Red Hat Jira (issue links are of type "https://issues.redhat.com/browse/RHEL-XXXX", where "X" is a digit). This same link will be available in a blue banner at the top of the page informing you that that bug has been migrated.

Bug 924153

Summary: block copy fail if original disk image located on NFS storage
Product: Red Hat Enterprise Linux 7 Reporter: yanbing du <ydu>
Component: libvirtAssignee: Eric Blake <eblake>
Status: CLOSED CURRENTRELEASE QA Contact: Virtualization Bugs <virt-bugs>
Severity: medium Docs Contact:
Priority: medium    
Version: 7.0CC: acathrow, cwei, dallan, dyuan, eblake, hliu, lsu, mzhan, ydu, zpeng
Target Milestone: rc   
Target Release: ---   
Hardware: Unspecified   
OS: Unspecified   
Whiteboard:
Fixed In Version: libvirt-1.1.1-4.el7 Doc Type: Bug Fix
Doc Text:
Story Points: ---
Clone Of: 924151 Environment:
Last Closed: 2014-06-13 10:30:22 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:
Bug Depends On: 924151    
Bug Blocks:    

Description yanbing du 2013-03-21 10:01:12 UTC
+++ This bug was initially created as a clone of Bug #924151 +++

Also reproduce this bug on rhel7, the error is:
error : qemuMonitorJSONCheckError:351 : internal error unable to execute QEMU command 'drive-mirror': Could not open '/tmp/vm1.img'



Description of problem:
Create a domain with the disk image located on NFS storage, then do blcok copy for this domain, and make sure the destination copy image not locate on the NFS storage, it will fail with permission denied. 

Version-Release number of selected component (if applicable):
libvirt-0.10.2-18.el6_4.2.x86_64 

How reproducible:
100% 

Steps to Reproduce:
1. Mount the NFS storage
# getenforce
Enforcing
# getsebool virt_use_nfs
virt_use_nfs --> on

# mount $nfs /mnt

2. Create a domain:
# virsh create test.xml
Domain vm1 created from test.xml

# virsh dumpxml vm1
<domain type='kvm' id='12'>
  <name>vm1</name>
  <uuid>de6e3e23-44db-2235-f779-b72dc0fc6da0</uuid>
  <memory unit='KiB'>131072</memory>
  <currentMemory unit='KiB'>131072</currentMemory>
  <vcpu placement='static'>1</vcpu>
  <os>
    <type arch='x86_64' machine='rhel6.4.0'>hvm</type>
    <boot dev='hd'/>
  </os>
  <clock offset='utc'/>
  <on_poweroff>destroy</on_poweroff>
  <on_reboot>restart</on_reboot>
  <on_crash>destroy</on_crash>
  <devices>
    <emulator>/usr/libexec/qemu-kvm</emulator>
    <disk type='file' device='disk'>
      <driver name='qemu' type='raw'/>
      <source file='/mnt/vm30.img'>
        <seclabel model='selinux' relabel='no'/>
      </source>
      <target dev='vda' bus='virtio'/>
      <alias name='virtio-disk0'/>
      <address type='pci' domain='0x0000' bus='0x00' slot='0x03' function='0x0'/>
    </disk>
    <controller type='usb' index='0'>
      <alias name='usb0'/>
      <address type='pci' domain='0x0000' bus='0x00' slot='0x01' function='0x2'/>
    </controller>
    <memballoon model='virtio'>
      <alias name='balloon0'/>
      <address type='pci' domain='0x0000' bus='0x00' slot='0x04' function='0x0'/>
    </memballoon>
  </devices>
  <seclabel type='dynamic' model='selinux' relabel='yes'>
    <label>system_u:system_r:svirt_t:s0:c288,c802</label>
    <imagelabel>system_u:object_r:svirt_image_t:s0:c288,c802</imagelabel>
  </seclabel>
</domain>


2. Do block copy for vda
# virsh blockcopy vm1 vda /tmp/vm1.img --wait --verbose
error: internal error unable to execute QEMU command '__com.redhat_drive-mirror': Could not open '/tmp/vm1.img': Permission denied

if change the destination path to nfs storage, it will pass
# virsh blockcopy vm1 vda /mnt/vm1.img --wait --verbose
Block Copy: [100 %]
Now in mirroring phase

# ll /mnt/vm1.img
-rw-------. 1 qemu qemu 5368709120 Mar 21  2013 /mnt/vm1.img
# virsh dumpxml vm1 |grep '<disk' -A 6
    <disk type='file' device='disk'>
      <driver name='qemu' type='raw'/>
      <source file='/mnt/vm30.img'>
        <seclabel model='selinux' relabel='no'/>
      </source>
      <mirror file='/mnt/vm1.img' format='raw' ready='yes'/>
      <target dev='vda' bus='virtio'/> 

  
Actual results:
Step2,  if the destination copy image not locate on the NFS storage, it will fail with permission denied. 

Expected results:
Blockcopy can successful 

Additional info:
/var/log/libvirt/libvirtd.log
.......
2013-03-21 08:44:48.328+0000: 3191: error : qemuMonitorJSONCheckError:355 : internal error unable to execute QEMU command '__com.redhat_drive-mirror': Could not open '/tmp/vm1.img': Permission denied

Comment 2 Eric Blake 2013-06-06 02:56:24 UTC
I have not tried to reproduce this yet, but it looks like a fairly reproducible setup, and therefore one that should still be solved for RHEL 7.

Comment 3 Eric Blake 2013-07-10 20:53:05 UTC
Could this be an artifact of using /tmp, where using a different directory doesn't have problems?

Comment 4 Dave Allan 2013-07-19 14:51:03 UTC
(In reply to Eric Blake from comment #3)
> Could this be an artifact of using /tmp, where using a different directory
> doesn't have problems?

Can you retest with a non /tmp directory and let us know the result?

Comment 5 yanbing du 2013-07-22 03:40:33 UTC
(In reply to Dave Allan from comment #4)
> (In reply to Eric Blake from comment #3)
> > Could this be an artifact of using /tmp, where using a different directory
> > doesn't have problems?
> 
> Can you retest with a non /tmp directory and let us know the result?

Use the other dir, still get the same result

# virsh blockcopy virt-tests-vm1 vda /home/vm1.img --wait --verbose
error: internal error unable to execute QEMU command 'drive-mirror': /home/vm1.img: error while creating raw: Permission denied

# virsh blockcopy virt-tests-vm1 vda /var/lib/libvirt/images/virt-test-vim1.bk --wait --verbose
error: internal error unable to execute QEMU command 'drive-mirror': /var/lib/libvirt/images/virt-test-vim1.bk: error while creating raw: Permission denied

Comment 6 Eric Blake 2013-08-07 21:16:32 UTC
I reproduced the setup today using libvirt-0.10.2-21.el6.x86_64; there is definitely a SELinux labeling issue as I got an AVC; and retrying under permissive mode succeeds.  I'm stepping through gdb now, and should have a fix soon.

Comment 7 Eric Blake 2013-08-09 19:09:56 UTC
Root cause - we associate a single virSecurityDeviceLabelDefPtr to an entire disk image backing chain.  When initially assigning SELinux context to an image chain, if one of the images lives on NFS (and can't be labeled), we set 'norelabel = true' for the disk label struct.  Later, when trying to create a copy to a local disk, we short-circuit any attempts to label because of the existing file being unlabeled.  But the local copy MUST be labeled, or SELinux prevents qemu from using it.

I suspect a similar confusion might occur when trying to copy a local file to NFS; there, because norelabel=false, but the relabel attempt fails on the copy, it may confuse libvirt into not doing the copy; or maybe the copy will happen but then libvirt will fail to clean up the label on the source because it sees that there is no cleanup needed on the destination.  The ultimate solution is that we must track the label success or failure per element in the disk chain, rather than having a top-level view of the chain as a whole.

I'm trying to figure out how best to patch that...

Comment 8 Eric Blake 2013-08-09 21:30:23 UTC
Commit 904e05 (v0.9.9) introduced the use of norelabel=true in order to try and minimize the impact of shutdown delays on a system where NFS disappeared.  Bug 770985 describes what we did: if the disk couldn't be labeled, we alter the XML, so that on shutdown, we don't try to unlabel it (the unlabel is at best a no-op on NFS, but if the NFS server hangs, then we got stuck on the unlabel attempt).  Unfortunately, the way I solved that bug, I can't tell the difference between a disk where we added the annotation internally, and a disk where the user specified no labeling from the get-go.  And that labeling is currently per-disk, instead of per chain element

Comment 9 Eric Blake 2013-08-13 04:21:11 UTC
Upstream patch proposed:
https://www.redhat.com/archives/libvir-list/2013-August/msg00562.html

Comment 11 Hao Liu 2013-09-12 09:09:56 UTC
Verifying steps on this patch.

1. Check SElinux status
# getenforce
Enforcing
# getsebool virt_use_nfs
virt_use_nfs --> on

2. Mount the NFS storage on /var/lib/libvirt/images/nfs/.

3. Prepare the domain XML.
# cat > test.xml << EOF
<domain type='kvm'>
  <name>vm1</name>
  <memory unit='KiB'>131072</memory>
  <currentMemory unit='KiB'>131072</currentMemory>
  <vcpu placement='static'>1</vcpu>
  <os>
    <type arch='x86_64' machine='pc'>hvm</type>
    <boot dev='hd'/>
  </os>
  <clock offset='utc'/>
  <on_poweroff>destroy</on_poweroff>
  <on_reboot>restart</on_reboot>
  <on_crash>destroy</on_crash>
  <devices>
    <emulator>/usr/libexec/qemu-kvm</emulator>
    <disk type='file' device='disk'>
      <driver name='qemu' type='raw'/>
      <source file='/var/lib/libvirt/images/nfs/test.img'/>
      <target dev='vda' bus='virtio'/>
      <address type='pci' domain='0x0000' bus='0x00' slot='0x03' function='0x0'/>
    </disk>
  </devices>
  <seclabel type='dynamic' model='selinux' relabel='yes'>
    <label>system_u:system_r:svirt_t:s0:c288,c802</label>
    <imagelabel>system_u:object_r:svirt_image_t:s0:c288,c802</imagelabel>
  </seclabel>
</domain>
EOF

4. Create the domain.
# virsh create test.xml
Domain vm1 created from test.xml

5. Check Disk Security label and try to blockcopy image to local disk.
1) For with package libvirt-1.1.1-3.el7.x86_64

# virsh dumpxml vm1 | grep seclabel | head -n1                                   
        <seclabel model='selinux' relabel='no'/>

# virsh blockcopy vm1 vda /tmp/vm1.img --verbose --wait                                 
error: internal error: unable to execute QEMU command 'drive-mirror': /tmp/vm1.img: error while creating raw: Permission denied

2) For with package libvirt-1.1.1-4.el7.x86_64

# virsh dumpxml vm1 | grep seclabel | head -n1                                   
        <seclabel model='selinux' labelskip='yes'/>

# virsh blockcopy vm1 vda /tmp/vm1.img --verbose --wait                                 
Block Copy: [100 %]
Now in mirroring phase

For a image on NFS, property labelskip of seclabel is enabled and the image
can be copied to local disk.
So this patch is considered VERIFIED.

Comment 12 Ludek Smid 2014-06-13 10:30:22 UTC
This request was resolved in Red Hat Enterprise Linux 7.0.

Contact your manager or support representative in case you have further questions about the request.