Merge ~paelzer/qa-regression-testing:fix-libvirt-artful-locking into qa-regression-testing:master

Proposed by Christian Ehrhardt 
Status: Merged
Merged at revision: 1b1d098bc5973e2fa6f7d348dd43b5c4d272182c
Proposed branch: ~paelzer/qa-regression-testing:fix-libvirt-artful-locking
Merge into: qa-regression-testing:master
Diff against target: 139 lines (+40/-5)
1 file modified
scripts/test-libvirt.py (+40/-5)
Reviewer Review Type Date Requested Status
Jamie Strandboge (community) Approve
Review via email: mp+332639@code.launchpad.net

Description of the change

Hi,
qemu 2.10 does the right thing to prevent data and metadata clobbering.
It locks image files, and without extra opt-in via special flags does not allow to open image files multiple times.

Some tests we have are currently affected as they attach a disk device.
Then skip to detach it but then attach it again.

Further the disk file gets re-written to be attached again.
All that is no more valid - but OTOH the reasons to skip the detach are gone as well.

So we can properly test the detach again and thereby automatically fix the attach without Failures.

To post a comment you must log in.
Revision history for this message
Christian Ehrhardt  (paelzer) wrote :
Download full text (5.1 KiB)

Without these fixes the libvirt tests on Artful run into the following issues:

FAIL: test_guest_aa_attach_detach_physical (main.LibvirtTestVirshSystemRoot)

Test attach/detach physical
Traceback (most recent call last):
File "./test-libvirt.py", line 2304, in test_guest_aa_attach_detach_physical
self._virsh_cmd_and_check("attach-disk %s %s sdc --driver=%s" % (self.vm_name, device_disk, driver), check_aa_files=True, tail=True, fn=device
_disk)
File "./test-libvirt.py", line 1831, in _virsh_cmd_and_check
self._run_virsh_cmd(self.qemu_uri, args, None)
File "./test-libvirt.py", line 1740, in _run_virsh_cmd
self.assertEquals(expected, rc, result + str(report))
AssertionError: Got exit code 1, expected 0
error: Failed to attach disk
error: internal error: unable to execute QEMU command 'device_add': Failed to get "write" lock

======================================================================
FAIL: test_guest_aa_attach_detach_physical (main.LibvirtTestVirshSystemRootAppArmor)

Test attach/detach physical
Traceback (most recent call last):
File "./test-libvirt.py", line 2291, in test_guest_aa_attach_detach_physical
self._virsh_cmd_and_check("attach-device %s %s" % (self.vm_name, device_xml), check_aa_files=True, tail=True, fn=device_disk)
File "./test-libvirt.py", line 1831, in _virsh_cmd_and_check
self._run_virsh_cmd(self.qemu_uri, args, None)
File "./test-libvirt.py", line 1740, in _run_virsh_cmd
self.assertEquals(expected, rc, result + str(report))
AssertionError: Got exit code 1, expected 0
error: Failed to attach device from /tmp/tmpipVhxT/device.xml
error: internal error: unable to execute QEMU command 'device_add': Property 'scsi-hd.drive' can't find value 'drive-scsi0-0-0-1'

======================================================================
FAIL: test_guest_cb_attach_detach_virtio (main.LibvirtTestVirshSystemRootAppArmor)

Test attach/detach virtio
Traceback (most recent call last):
File "./test-libvirt.py", line 2346, in test_guest_cb_attach_detach_virtio
self._virsh_cmd_and_check("attach-device %s %s" % (self.vm_name, device_xml), check_aa_files=True, tail=True, fn=device_disk)
File "./test-libvirt.py", line 1831, in _virsh_cmd_and_check
self._run_virsh_cmd(self.qemu_uri, args, None)
File "./test-libvirt.py", line 1740, in _run_virsh_cmd
self.assertEquals(expected, rc, result + str(report))
AssertionError: Got exit code 1, expected 0
error: Failed to attach device from /tmp/tmpIdjdPR/device.xml
error: internal error: unable to execute QEMU command 'device_add': Property 'virtio-blk-device.drive' can't find value 'drive-virtio-disk1'

======================================================================
FAIL: test_guest_aa_attach_detach_physical (main.LibvirtTestVirshSystemNonRootAppArmor)

Test attach/detach physical
Traceback (most recent call last):
File "./test-libvirt.py", line 2291, in test_guest_aa_attach_detach_physical
self._virsh_cmd_and_check("attach-device %s %s" % (self.vm_name, device_xml), check_aa_files=True, tail=True, fn=device_disk)
File "./test-libvirt.py", line 1831, in _virsh_cmd_and_check
self._run_virsh_cmd(self.qemu_uri, args, None)
File "./test-libvirt.py", line 1740, in _run_virsh_cmd
self.assertEquals(...

Read more...

Revision history for this message
Christian Ehrhardt  (paelzer) wrote :

Full run on Artful now completed, no side effects found.
But there seem to be more issues when running the full test, will take a look and merge here as needed.

Oh I see, it now works for the class derived from LibvirtTestVirshSystemRoot but on the apparmor cases like LibvirtTestVirshSystemRootAppArmor the issue you faced in the past with the detach comes up.

Marking this WIP for now until the full set runs.

Revision history for this message
Christian Ehrhardt  (paelzer) wrote :

error: internal error: unable to execute QEMU command 'device_add': Property 'scsi-hd.drive' can't find value 'drive-scsi0-0-0-1'

Actually is:
su -c sudo -H -u tkfvcmMz virsh -c qemu:///system attach-device qatest-i386 /tmp/tmp6CrF_y/device.xml

Causing:
apparmor="DENIED" operation="file_lock" profile="libvirt-7d781722-69b7-8801-fe96-caf37b7a8969" name="/tmp/tmp6CrF_y/device_disk.img" pid=1673 comm="qemu" requested_mask="k" denied_mask="k" fsuid=0 ouid=0

We add k in libvirt-aa-helper for image files.
I can see that even in the profile used this is true:
  "/home/ubuntu/qa-regression-testing/scripts/libvirt/qatest/qatest.img" rwk,

Next: libvirt might be missing to add the k perm on the use-case that the test is using to attach the disk?

Revision history for this message
Christian Ehrhardt  (paelzer) wrote :

As usual these rules are generated on the hot-add.
So we can't check the rules before.
Instead we need to "intercept" what gets added in the short time the disk gets added.

This shows on:
su -c sudo -H -u tBmzjHwq virsh -c qemu:///system attach-device qatest-i386 /tmp/tmpFLjlVS/device.xml

The rule rendered is:
"/tmp/tmpFLjlVS/device_disk.img" rw,

This is really missing the k flag.
The XML defining the hot-add is:
<disk type='block'>
  <driver name='qemu'/>
  <source dev='/tmp/tmpAoRaMw/device_disk.img'/>
  <target dev='sdb'/>
</disk>

Well this is odd, qemu locks on files.
But this is a file, yet defined as type='block'

So it should actually be like:
<disk type='file'>
  <driver name='qemu'/>
  <source file='/tmp/tmpAoRaMw/device_disk.img'/>
  <target dev='sdb'/>
</disk>

But even with that it is failing, maybe that is a real bug in the addition of the lock perm to aa-helper not considering the attache-device files the same way.
Analysis ongoing ...

Revision history for this message
Christian Ehrhardt  (paelzer) wrote :

When I add the same snippet to the main guest definition it gets the rule:
  "/tmp/tmpAoRaMw/device_disk.img" rwk,
Which would be correct, but as we see in the test above it is not generated the same way on attach-device.
The same is true for the type=block device.

That said it is now an issue isolated to libvirt and not this MP/the-tests.
I'll fork a libvirt bug and track it there.
Coming back to the MP once that is unblocked by a fix to libvirt.

Revision history for this message
Christian Ehrhardt  (paelzer) wrote :

Since I needed it for the debugging I had some debug helpers that I'll include.
It seems I need that more often than not so it might be wise to add this for everyone.

OTOH with a ppa for bug 1726804 and this fix I'm now able to run all tests correctly again.
Too bad the locking issues I fix int his MP had hidden these real issues for me earlier in this cycle.

Changes pushed - branch now has the fixes plus the enhanced debugging, ready for review again - setting status.

Revision history for this message
Jamie Strandboge (jdstrand) wrote :

These debugging options look really nice and I can imagine how they have come in handy. This and the fixes for 17.10 LGTM.

review: Approve

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1diff --git a/scripts/test-libvirt.py b/scripts/test-libvirt.py
2index 58d80ce..f82590d 100755
3--- a/scripts/test-libvirt.py
4+++ b/scripts/test-libvirt.py
5@@ -63,6 +63,14 @@
6 If you interrupt the test halfway, you might need to clean up and reset
7 the test environment. One way to do this is to run "./test-libvirt reset"
8
9+ For extra debugging (way above verbose) you can add environment variables
10+ like:
11+ $ DEBUG_AA=True sudo ./test-libvirt.py -v
12+ The list of such debug variables is:
13+ - DEBUG_AA: report apparmor rules
14+ - DEBUG_XML: xml snippets that are used
15+ - DEBUG_VIRSH: virsh commands that are issues
16+
17 TODO for migration away from libvirt-aa-secdriver.sh:
18 - USB tests (eg analog for libvirt-apparmor.sh foo usb:2,3)
19 - remote tests (eg analog for libvirt-apparmor.sh foo remote:192.168.122.203
20@@ -92,6 +100,10 @@ copy_image = False
21 qemu_user = None
22 qemu_savetmpdir = None
23
24+DEBUG_VIRSH = os.environ.get('DEBUG_VIRSH', "False")
25+DEBUG_AA = os.environ.get('DEBUG_AA', "False")
26+DEBUG_XML = os.environ.get('DEBUG_XML', "False")
27+
28 def checksecmodel(txt):
29 dom = xml.dom.minidom.parseString(txt)
30 for n in dom.getElementsByTagName('secmodel'):
31@@ -1726,13 +1738,12 @@ class LibvirtTestVirshCommon(LibvirtTestCommonWithAbort):
32
33 def _run_virsh_cmd(self, connect_uri, args, search, invert=False, user=None, expected=0):
34 '''Run virsh command and search for string'''
35- debug = False
36
37 if not user:
38 global qemu_user
39 user = qemu_user
40
41- if debug:
42+ if DEBUG_VIRSH != "False":
43 print "%s" % (" ".join(['su', '-c', 'sudo -H -u %s virsh -c %s %s' % (user.login, connect_uri, args)]))
44
45 rc, report = testlib.cmd(['su', '-c', 'sudo -H -u %s virsh -c %s %s' % (user.login, connect_uri, args)])
46@@ -1752,7 +1763,7 @@ class LibvirtTestVirshCommon(LibvirtTestCommonWithAbort):
47 result = "Could not find '%s'\n" % search
48 self.assertTrue(re.search(r'%s' % search, report) != None, result + str(report))
49
50- if debug:
51+ if DEBUG_VIRSH != "False":
52 print report,
53
54 return report
55@@ -1865,6 +1876,9 @@ class LibvirtTestVirshCommon(LibvirtTestCommonWithAbort):
56 global qemu_user
57 self._adjust_perms("%s:%s" % (self.kvm_user, self.kvm_group), self.qemu_tmpdir)
58
59+ if DEBUG_XML != "False":
60+ with open(self.qemu_xml, 'r') as xml:
61+ print xml.read()
62 rc, report = testlib.cmd(['su', '-c', 'sudo -H -u %s virsh -c %s define %s' % (qemu_user.login, self.qemu_uri, self.qemu_xml)])
63 expected = 0
64 result = 'Got exit code %d, expected %d\n' % (rc, expected)
65@@ -1891,6 +1905,13 @@ class LibvirtTestVirshCommon(LibvirtTestCommonWithAbort):
66 if self.lsb_release['Release'] < 10.04:
67 self.vm_uuid = report.splitlines()[1].strip()
68
69+ if DEBUG_AA != "False":
70+ aa_file = "/etc/apparmor.d/libvirt/libvirt-%s.files" % (self.vm_uuid)
71+ if os.path.exists(aa_file):
72+ print "Apparmor File: %s" % aa_file
73+ with open(aa_file, 'r') as profile:
74+ print profile.read()
75+
76 def test_aa_initialize(self):
77 '''Test initialization'''
78 global abort_tests
79@@ -1932,6 +1953,9 @@ class LibvirtTestVirshCommon(LibvirtTestCommonWithAbort):
80 # Need this for skip_apparmor changes
81 self._restart_daemon()
82
83+ if DEBUG_XML != "False":
84+ with open(self.qemu_xml, 'r') as xml:
85+ print xml.read()
86 rc, report = testlib.cmd(['su', '-c', 'sudo -H -u %s virsh -c %s define %s' % (qemu_user.login, self.qemu_uri, self.qemu_xml)])
87 expected = 0
88 result = 'Got exit code %d, expected %d\n' % (rc, expected)
89@@ -2287,12 +2311,16 @@ class LibvirtTestVirshGuest(LibvirtTestVirshCommon):
90 print " detach-interface"
91 self._run_virsh_cmd(self.qemu_uri, "detach-interface %s network --mac %s" % (self.vm_name, new_mac), None)
92
93+ if DEBUG_XML != "False":
94+ with open(device_xml, 'r') as xml:
95+ print xml.read()
96 print " attach-device (physical)"
97 self._virsh_cmd_and_check("attach-device %s %s" % (self.vm_name, device_xml), check_aa_files=True, tail=True, fn=device_disk)
98- if self.lsb_release['Release'] >= 10.10:
99+ if self.lsb_release['Release'] >= 10.10 and self.lsb_release['Release'] < 17.10:
100 # cannot hot unplug physical block device with qemu in 0.7.7 and higher
101 print " detach-device (physical): (skipped on 10.10 and higher)"
102 else:
103+ # working again in later releases, >= qemu 2.10 (17.10) required as images are locked and can only be used once
104 print " detach-device (physical)"
105 self._virsh_cmd_and_check("detach-device %s %s" % (self.vm_name, device_xml), check_aa_files=True, invert=True, fn=device_disk)
106
107@@ -2302,10 +2330,11 @@ class LibvirtTestVirshGuest(LibvirtTestVirshCommon):
108 # libvirt 0.9 requires this
109 driver = 'qemu'
110 self._virsh_cmd_and_check("attach-disk %s %s sdc --driver=%s" % (self.vm_name, device_disk, driver), check_aa_files=True, tail=True, fn=device_disk)
111- if self.lsb_release['Release'] >= 10.10:
112+ if self.lsb_release['Release'] >= 10.10 and self.lsb_release['Release'] < 17.10:
113 # cannot hot unplug scsi device with qemu in 0.7.7 and higher
114 print " detach-disk (physical): (skipped on 10.10 and higher)"
115 else:
116+ # working again in later releases, >= qemu 2.10 (17.10) required as images are locked and can only be used once
117 print " detach-disk (physical)"
118 self._virsh_cmd_and_check("detach-disk %s sdc" % (self.vm_name), check_aa_files=True, invert=True, fn=device_disk)
119
120@@ -2343,6 +2372,9 @@ class LibvirtTestVirshGuest(LibvirtTestVirshCommon):
121 max_tries = 4
122 for i in range(1, max_tries+1):
123 print " attach-device (virtio #%d)" % i
124+ if DEBUG_XML != "False":
125+ with open(device_xml, 'r') as xml:
126+ print xml.read()
127 self._virsh_cmd_and_check("attach-device %s %s" % (self.vm_name, device_xml), check_aa_files=True, tail=True, fn=device_disk)
128 print " detach-device (virtio #%d)" % i
129
130@@ -2394,6 +2426,9 @@ class LibvirtTestVirshGuest(LibvirtTestVirshCommon):
131 self._define_and_start_guest()
132
133 print " attach-device (AoE)"
134+ if DEBUG_XML != "False":
135+ with open(device_xml, 'r') as xml:
136+ print xml.read()
137 self._virsh_cmd_and_check("attach-device %s %s" % (self.vm_name, device_xml), check_aa_files=True, tail=True, fn=device_aoe)
138 print " detach-device (AoE)"
139 # if fail here, might have hit https://launchpad.net/bugs/455832

Subscribers

People subscribed via source and target branches