Merge lp:~raharper/curtin/new-bionic-upstream-snapshot-v1 into lp:~curtin-dev/curtin/bionic

Proposed by Ryan Harper
Status: Merged
Merged at revision: 83
Proposed branch: lp:~raharper/curtin/new-bionic-upstream-snapshot-v1
Merge into: lp:~curtin-dev/curtin/bionic
Diff against target: 1202 lines (+350/-270)
36 files modified
curtin/block/__init__.py (+11/-5)
curtin/block/clear_holders.py (+33/-4)
curtin/commands/block_meta.py (+23/-20)
curtin/commands/block_wipe.py (+4/-0)
curtin/commands/clear_holders.py (+1/-1)
debian/changelog (+17/-0)
examples/tests/bcache-wipe-xfs.yaml (+74/-0)
examples/tests/uefi_basic.yaml (+23/-0)
tests/unittests/test_clear_holders.py (+82/-0)
tests/unittests/test_commands_block_meta.py (+11/-15)
tests/vmtests/__init__.py (+14/-15)
tests/vmtests/releases.py (+0/-11)
tests/vmtests/test_basic.py (+0/-48)
tests/vmtests/test_bcache_basic.py (+0/-4)
tests/vmtests/test_bcache_bug1718699.py (+21/-0)
tests/vmtests/test_iscsi.py (+0/-4)
tests/vmtests/test_lvm.py (+0/-8)
tests/vmtests/test_lvm_iscsi.py (+0/-4)
tests/vmtests/test_mdadm_iscsi.py (+0/-4)
tests/vmtests/test_network.py (+0/-5)
tests/vmtests/test_network_alias.py (+0/-5)
tests/vmtests/test_network_bonding.py (+0/-8)
tests/vmtests/test_network_enisource.py (+0/-6)
tests/vmtests/test_network_ipv6.py (+0/-5)
tests/vmtests/test_network_ipv6_enisource.py (+0/-7)
tests/vmtests/test_network_ipv6_static.py (+0/-5)
tests/vmtests/test_network_ipv6_vlan.py (+0/-16)
tests/vmtests/test_network_mtu.py (+1/-6)
tests/vmtests/test_network_static.py (+0/-6)
tests/vmtests/test_network_static_routes.py (+0/-6)
tests/vmtests/test_network_vlan.py (+0/-16)
tests/vmtests/test_nvme.py (+0/-5)
tests/vmtests/test_raid5_bcache.py (+0/-5)
tests/vmtests/test_uefi_basic.py (+1/-15)
tools/launch (+10/-10)
tools/xkvm (+24/-1)
To merge this branch: bzr merge lp:~raharper/curtin/new-bionic-upstream-snapshot-v1
Reviewer Review Type Date Requested Status
curtin developers Pending
Review via email: mp+333332@code.launchpad.net

Description of the change

* New upstream snapshot.
  - Drop Precise from vmtest
  - clear_holders: bcache log IO/OS exceptions but do not raise
  - vmtest: Support newer qemu and multipath.
  - block: enable control over exclusive_open use when wiping volumes
  - block: handle wiping bcache parts (LP: #1718699)
  - vmtests: Defer ArtfulNetworkMtu SkipbyDate to 2018
  - bcache: accept sysfs write failure in shutdown handler if path missing
    (LP: #1700564)
  - vmtest: Rephrase a message about no disks to be less scary
  - block_meta: use block.wipe_volume(mode=superblock) to clear MBR/GPT tables
    (LP: #1722322)

To post a comment you must log in.

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'curtin/block/__init__.py'
2--- curtin/block/__init__.py 2017-08-03 19:48:07 +0000
3+++ curtin/block/__init__.py 2017-11-07 18:32:47 +0000
4@@ -776,17 +776,21 @@
5
6
7 @contextmanager
8-def exclusive_open(path):
9+def exclusive_open(path, exclusive=True):
10 """
11- Obtain an exclusive file-handle to the file/device specified
12+ Obtain an exclusive file-handle to the file/device specified unless
13+ caller specifics exclusive=False.
14 """
15 mode = 'rb+'
16 fd = None
17 if not os.path.exists(path):
18 raise ValueError("No such file at path: %s" % path)
19
20+ flags = os.O_RDWR
21+ if exclusive:
22+ flags += os.O_EXCL
23 try:
24- fd = os.open(path, os.O_RDWR | os.O_EXCL)
25+ fd = os.open(path, flags)
26 try:
27 fd_needs_closing = True
28 with os.fdopen(fd, mode) as fo:
29@@ -875,7 +879,8 @@
30 return zero_file_at_offsets(path, offsets, buflen=buflen, count=count)
31
32
33-def zero_file_at_offsets(path, offsets, buflen=1024, count=1024, strict=False):
34+def zero_file_at_offsets(path, offsets, buflen=1024, count=1024, strict=False,
35+ exclusive=True):
36 """
37 write zeros to file at specified offsets
38 """
39@@ -890,7 +895,8 @@
40 tot = buflen * count
41 msg_vals = {'path': path, 'tot': buflen * count}
42
43- with exclusive_open(path) as fp:
44+ # allow caller to control if we require exclusive open
45+ with exclusive_open(path, exclusive=exclusive) as fp:
46 # get the size by seeking to end.
47 fp.seek(0, 2)
48 size = fp.tell()
49
50=== modified file 'curtin/block/clear_holders.py'
51--- curtin/block/clear_holders.py 2017-06-12 19:43:55 +0000
52+++ curtin/block/clear_holders.py 2017-11-07 18:32:47 +0000
53@@ -93,6 +93,24 @@
54 return path
55
56
57+def maybe_stop_bcache_device(device):
58+ """Attempt to stop the provided device_path or raise unexpected errors."""
59+ bcache_stop = os.path.join(device, 'stop')
60+ try:
61+ util.write_file(bcache_stop, '1', mode=None)
62+ except (IOError, OSError) as e:
63+ # Note: if we get any exceptions in the above exception classes
64+ # it is a result of attempting to write "1" into the sysfs path
65+ # The range of errors changes depending on when we race with
66+ # the kernel asynchronously removing the sysfs path. Therefore
67+ # we log the exception errno we got, but do not re-raise as
68+ # the calling process is watching whether the same sysfs path
69+ # is being removed; if it fails to go away then we'll have
70+ # a log of the exceptions to debug.
71+ LOG.debug('Error writing to bcache stop file %s, device removed: %s',
72+ bcache_stop, e)
73+
74+
75 def shutdown_bcache(device):
76 """
77 Shut down bcache for specified bcache device
78@@ -132,8 +150,7 @@
79 os.path.basename(bcache_cache_sysfs))
80 else:
81 LOG.info('stopping bcache cacheset at: %s', bcache_cache_sysfs)
82- util.write_file(os.path.join(bcache_cache_sysfs, 'stop'),
83- '1', mode=None)
84+ maybe_stop_bcache_device(bcache_cache_sysfs)
85 try:
86 util.wait_for_removal(bcache_cache_sysfs, retries=removal_retries)
87 except OSError:
88@@ -162,8 +179,7 @@
89 return
90 else:
91 LOG.info('stopping bcache backing device at: %s', bcache_block_sysfs)
92- util.write_file(os.path.join(bcache_block_sysfs, 'stop'),
93- '1', mode=None)
94+ maybe_stop_bcache_device(bcache_block_sysfs)
95 try:
96 # wait for them all to go away
97 for dev in [device, bcache_block_sysfs] + slave_paths:
98@@ -244,6 +260,19 @@
99 LOG.info("extended partitions do not need wiping, so skipping: '%s'",
100 blockdev)
101 else:
102+ # some volumes will be claimed by the bcache layer but do not surface
103+ # an actual /dev/bcacheN device which owns the parts (backing, cache)
104+ # The result is that some volumes cannot be wiped while bcache claims
105+ # the device. Resolve this by stopping bcache layer on those volumes
106+ # if present.
107+ for bcache_path in ['bcache', 'bcache/set']:
108+ stop_path = os.path.join(device, bcache_path)
109+ if os.path.exists(stop_path):
110+ LOG.debug('Attempting to release bcache layer from device: %s',
111+ device)
112+ maybe_stop_bcache_device(stop_path)
113+ continue
114+
115 retries = [1, 3, 5, 7]
116 LOG.info('wiping superblock on %s', blockdev)
117 for attempt, wait in enumerate(retries):
118
119=== modified file 'curtin/commands/block_meta.py'
120--- curtin/commands/block_meta.py 2017-06-12 19:43:55 +0000
121+++ curtin/commands/block_meta.py 2017-11-07 18:32:47 +0000
122@@ -384,7 +384,11 @@
123 LOG.info("labeling device: '%s' with '%s' partition table", disk,
124 ptable)
125 if ptable == "gpt":
126- util.subp(["sgdisk", "--clear", disk])
127+ # Wipe both MBR and GPT that may be present on the disk.
128+ # N.B.: wipe_volume wipes 1M at front and end of the disk.
129+ # This could destroy disk data in filesystems that lived
130+ # there.
131+ block.wipe_volume(disk, mode='superblock')
132 elif ptable in _dos_names:
133 util.subp(["parted", disk, "--script", "mklabel", "msdos"])
134 else:
135@@ -544,6 +548,24 @@
136 info.get('id'), device, disk_ptable)
137 LOG.debug("partnum: %s offset_sectors: %s length_sectors: %s",
138 partnumber, offset_sectors, length_sectors)
139+
140+ # Wipe the partition if told to do so, do not wipe dos extended partitions
141+ # as this may damage the extended partition table
142+ if config.value_as_boolean(info.get('wipe')):
143+ LOG.info("Preparing partition location on disk %s", disk)
144+ if info.get('flag') == "extended":
145+ LOG.warn("extended partitions do not need wiping, so skipping: "
146+ "'%s'" % info.get('id'))
147+ else:
148+ # wipe the start of the new partition first by zeroing 1M at the
149+ # length of the previous partition
150+ wipe_offset = int(offset_sectors * logical_block_size_bytes)
151+ LOG.debug('Wiping 1M on %s at offset %s', disk, wipe_offset)
152+ # We don't require exclusive access as we're wiping data at an
153+ # offset and the current holder maybe part of the current storage
154+ # configuration.
155+ block.zero_file_at_offsets(disk, [wipe_offset], exclusive=False)
156+
157 if disk_ptable == "msdos":
158 if flag in ["extended", "logical", "primary"]:
159 partition_type = flag
160@@ -565,25 +587,6 @@
161 else:
162 raise ValueError("parent partition has invalid partition table")
163
164- # check if we've triggered hidden metadata like md, lvm or bcache
165- part_kname = get_path_to_storage_volume(info.get('id'), storage_config)
166- holders = clear_holders.get_holders(part_kname)
167- if len(holders) > 0:
168- LOG.debug('Detected block holders on partition %s: %s', part_kname,
169- holders)
170- clear_holders.clear_holders(part_kname)
171- clear_holders.assert_clear(part_kname)
172-
173- # Wipe the partition if told to do so, do not wipe dos extended partitions
174- # as this may damage the extended partition table
175- if config.value_as_boolean(info.get('wipe')):
176- if info.get('flag') == "extended":
177- LOG.warn("extended partitions do not need wiping, so skipping: "
178- "'%s'" % info.get('id'))
179- else:
180- block.wipe_volume(
181- get_path_to_storage_volume(info.get('id'), storage_config),
182- mode=info.get('wipe'))
183 # Make the name if needed
184 if storage_config.get(device).get('name') and partition_type != 'extended':
185 make_dname(info.get('id'), storage_config)
186
187=== modified file 'curtin/commands/block_wipe.py'
188--- curtin/commands/block_wipe.py 2016-09-29 18:31:02 +0000
189+++ curtin/commands/block_wipe.py 2017-11-07 18:32:47 +0000
190@@ -18,11 +18,15 @@
191 import sys
192 import curtin.block as block
193 from . import populate_one_subcmd
194+from .. import log
195+
196+LOG = log.LOG
197
198
199 def wipe_main(args):
200 for blockdev in args.devices:
201 try:
202+ LOG.debug('Wiping volume %s with mode=%s', blockdev, args.mode)
203 block.wipe_volume(blockdev, mode=args.mode)
204 except Exception as e:
205 sys.stderr.write(
206
207=== modified file 'curtin/commands/clear_holders.py'
208--- curtin/commands/clear_holders.py 2016-09-29 18:31:02 +0000
209+++ curtin/commands/clear_holders.py 2017-11-07 18:32:47 +0000
210@@ -28,7 +28,7 @@
211 raise ValueError('invalid devices specified')
212 block.clear_holders.start_clear_holders_deps()
213 block.clear_holders.clear_holders(args.devices, try_preserve=args.preserve)
214- if args.try_preserve:
215+ if args.preserve:
216 print('ran clear_holders attempting to preserve data. however, '
217 'hotplug support for some devices may cause holders to restart ')
218 block.clear_holders.assert_clear(args.devices)
219
220=== modified file 'debian/changelog'
221--- debian/changelog 2017-10-06 02:22:45 +0000
222+++ debian/changelog 2017-11-07 18:32:47 +0000
223@@ -1,3 +1,20 @@
224+curtin (0.1.0~bzr541-0ubuntu1) bionic; urgency=medium
225+
226+ * New upstream snapshot.
227+ - Drop Precise from vmtest
228+ - clear_holders: bcache log IO/OS exceptions but do not raise
229+ - vmtest: Support newer qemu and multipath.
230+ - block: enable control over exclusive_open use when wiping volumes
231+ - block: handle wiping bcache parts (LP: #1718699)
232+ - vmtests: Defer ArtfulNetworkMtu SkipbyDate to 2018
233+ - bcache: accept sysfs write failure in shutdown handler if path missing
234+ (LP: #1700564)
235+ - vmtest: Rephrase a message about no disks to be less scary
236+ - block_meta: use block.wipe_volume(mode=superblock) to clear MBR/GPT tables
237+ (LP: #1722322)
238+
239+ -- Ryan Harper <ryan.harper@canonical.com> Tue, 07 Nov 2017 11:13:00 -0600
240+
241 curtin (0.1.0~bzr532-0ubuntu1) artful; urgency=medium
242
243 * New upstream snapshot.
244
245=== added file 'examples/tests/bcache-wipe-xfs.yaml'
246--- examples/tests/bcache-wipe-xfs.yaml 1970-01-01 00:00:00 +0000
247+++ examples/tests/bcache-wipe-xfs.yaml 2017-11-07 18:32:47 +0000
248@@ -0,0 +1,74 @@
249+showtrace: true
250+
251+early_commands:
252+ # Create a partitioned disk with bcache metadata in one of the partitions.
253+ # Then, wipe the partition table. This leaves "buried" bcache data that
254+ # would be seen as soon as the disk was partitioned and cause problems
255+ # for curtin's use of the disk.
256+ # This config recreates issue LP: #1718699
257+ 00_blockmeta: [env, -u, OUTPUT_FSTAB, TARGET_MOUNT_POINT=/tmp/my.bdir/target,
258+ WORKING_DIR=/tmp/my.bdir/work.d, curtin, --showtrace, -v,
259+ block-meta, --umount, custom]
260+ 01_clear_holders: [curtin, clear-holders, --preserve, /dev/vdb]
261+ 02_quick_erase: [curtin, block-wipe, --mode, superblock, /dev/vdb]
262+
263+storage:
264+ config:
265+ - grub_device: true
266+ id: vdb
267+ name: vdb
268+ path: /dev/vdb
269+ ptable: msdos
270+ type: disk
271+ wipe: superblock
272+ - id: vdc
273+ name: vdc
274+ path: /dev/vdc
275+ type: disk
276+ wipe: superblock
277+ - device: vdb
278+ id: vdb-part1
279+ name: vdb-part1
280+ number: 1
281+ offset: 4194304B
282+ size: 3997171712B
283+ type: partition
284+ uuid: 1d112703-1ff7-49fb-9655-741016e216bf
285+ wipe: superblock
286+ - device: vdb
287+ id: vdb-part2
288+ name: vdb-part2
289+ number: 2
290+ size: 3997171712B
291+ type: partition
292+ uuid: ec219a2e-c4a5-4623-b66a-965da2c6c1f1
293+ wipe: superblock
294+ - backing_device: vdc
295+ cache_device: vdb-part2
296+ cache_mode: writeback
297+ id: bcache0
298+ name: bcache0
299+ type: bcache
300+ - fstype: ext4
301+ id: vdb-part1_format
302+ label: ''
303+ type: format
304+ uuid: 0687dc8f-c089-4f30-8603-0ddf646a5dd7
305+ volume: vdb-part1
306+ - fstype: xfs
307+ id: bcache0_format
308+ label: ''
309+ type: format
310+ uuid: c40a45b2-1f12-454e-a0ec-784eb4ded4e6
311+ volume: bcache0
312+ - device: vdb-part1_format
313+ id: vdb-part1_mount
314+ options: ''
315+ path: /
316+ type: mount
317+ - device: bcache0_format
318+ id: bcache0_mount
319+ options: ''
320+ path: /var/lib/ceph-bcache/test-disk
321+ type: mount
322+ version: 1
323
324=== modified file 'examples/tests/uefi_basic.yaml'
325--- examples/tests/uefi_basic.yaml 2016-08-05 20:47:14 +0000
326+++ examples/tests/uefi_basic.yaml 2017-11-07 18:32:47 +0000
327@@ -1,4 +1,12 @@
328 showtrace: true
329+
330+early_commands:
331+ # Recreate and test LP:1722322
332+ # Make one disk dirty with an MBR and a storage configuration
333+ # GPT and don't supply wipe: superblock. This will exercise
334+ # curtin use of sgdisk --zap-all instead of --clear (GPT only)
335+ blockmeta: ["parted", /dev/vdc, "--script", "mklabel", "msdos"]
336+
337 storage:
338 config:
339 - id: id_disk0
340@@ -55,4 +63,19 @@
341 id: id_efi_mount
342 path: /boot/efi
343 type: mount
344+ - id: pnum_disk
345+ type: disk
346+ path: /dev/vdc
347+ name: pnum_disk
348+ ptable: gpt
349+ - id: pnum_disk_p1
350+ type: partition
351+ number: 1
352+ size: 1GB
353+ device: pnum_disk
354+ - id: pnum_disk_p2
355+ type: partition
356+ number: 10
357+ size: 1GB
358+ device: pnum_disk
359 version: 1
360
361=== modified file 'tests/unittests/test_clear_holders.py'
362--- tests/unittests/test_clear_holders.py 2017-08-03 19:48:07 +0000
363+++ tests/unittests/test_clear_holders.py 2017-11-07 18:32:47 +0000
364@@ -1,3 +1,4 @@
365+import errno
366 import mock
367 import os
368 import textwrap
369@@ -329,6 +330,52 @@
370 mock.call(cset, retries=self.remove_retries)
371 ])
372
373+ # test bcache shutdown with 'stop' sysfs write failure
374+ @mock.patch('curtin.block.clear_holders.udev.udevadm_settle')
375+ @mock.patch('curtin.block.clear_holders.get_bcache_sys_path')
376+ @mock.patch('curtin.block.clear_holders.util')
377+ @mock.patch('curtin.block.clear_holders.os')
378+ @mock.patch('curtin.block.clear_holders.LOG')
379+ @mock.patch('curtin.block.clear_holders.get_bcache_using_dev')
380+ def test_shutdown_bcache_stop_sysfs_write_fails(self, mock_get_bcache,
381+ mock_log, mock_os,
382+ mock_util,
383+ mock_get_bcache_block,
384+ mock_udevadm_settle):
385+ """Test writes sysfs write failures pass if file not present"""
386+ device = "/sys/class/block/null"
387+ mock_os.path.exists.side_effect = iter([
388+ True, # backing device exists
389+ True, # cset device not present (already removed)
390+ False, # backing device is removed with cset
391+ False, # bcache/stop sysfs is missing (already removed)
392+ ])
393+ cset = '/sys/fs/bcache/fake'
394+ mock_get_bcache.return_value = cset
395+ mock_get_bcache_block.return_value = device + '/bcache'
396+ mock_os.path.join.side_effect = os.path.join
397+
398+ # make writes to sysfs fail
399+ mock_util.write_file.side_effect = IOError(errno.ENOENT,
400+ "File not found")
401+
402+ clear_holders.shutdown_bcache(device)
403+
404+ self.assertEqual(2, len(mock_log.info.call_args_list))
405+ self.assertEqual(3, len(mock_os.path.exists.call_args_list))
406+ self.assertEqual(1, len(mock_get_bcache.call_args_list))
407+ self.assertEqual(1, len(mock_get_bcache_block.call_args_list))
408+ self.assertEqual(1, len(mock_util.write_file.call_args_list))
409+ self.assertEqual(1, len(mock_util.wait_for_removal.call_args_list))
410+
411+ mock_get_bcache.assert_called_with(device, strict=False)
412+ mock_util.write_file.assert_has_calls([
413+ mock.call(cset + '/stop', '1', mode=None),
414+ ])
415+ mock_util.wait_for_removal.assert_has_calls([
416+ mock.call(cset, retries=self.remove_retries)
417+ ])
418+
419 @mock.patch('curtin.block.clear_holders.LOG')
420 @mock.patch('curtin.block.clear_holders.block.sys_block_path')
421 @mock.patch('curtin.block.clear_holders.lvm')
422@@ -531,6 +578,41 @@
423 for tree, result in test_trees_and_results:
424 self.assertEqual(clear_holders.format_holders_tree(tree), result)
425
426+ @mock.patch('curtin.block.clear_holders.util.write_file')
427+ def test_maybe_stop_bcache_device_raises_errors(self, m_write_file):
428+ """Non-IO/OS exceptions are raised by maybe_stop_bcache_device."""
429+ m_write_file.side_effect = ValueError('Crazy Value Error')
430+ with self.assertRaises(ValueError) as cm:
431+ clear_holders.maybe_stop_bcache_device('does/not/matter')
432+ self.assertEqual('Crazy Value Error', str(cm.exception))
433+ self.assertEqual(
434+ mock.call('does/not/matter/stop', '1', mode=None),
435+ m_write_file.call_args)
436+
437+ @mock.patch('curtin.block.clear_holders.LOG')
438+ @mock.patch('curtin.block.clear_holders.util.write_file')
439+ def test_maybe_stop_bcache_device_handles_oserror(self, m_write_file,
440+ m_log):
441+ """When OSError.NOENT is raised, log the condition and move on."""
442+ m_write_file.side_effect = OSError(errno.ENOENT, 'Expected oserror')
443+ clear_holders.maybe_stop_bcache_device('does/not/matter')
444+ self.assertEqual(
445+ 'Error writing to bcache stop file %s, device removed: %s',
446+ m_log.debug.call_args[0][0])
447+ self.assertEqual('does/not/matter/stop', m_log.debug.call_args[0][1])
448+
449+ @mock.patch('curtin.block.clear_holders.LOG')
450+ @mock.patch('curtin.block.clear_holders.util.write_file')
451+ def test_maybe_stop_bcache_device_handles_ioerror(self, m_write_file,
452+ m_log):
453+ """When IOError.NOENT is raised, log the condition and move on."""
454+ m_write_file.side_effect = IOError(errno.ENOENT, 'Expected ioerror')
455+ clear_holders.maybe_stop_bcache_device('does/not/matter')
456+ self.assertEqual(
457+ 'Error writing to bcache stop file %s, device removed: %s',
458+ m_log.debug.call_args[0][0])
459+ self.assertEqual('does/not/matter/stop', m_log.debug.call_args[0][1])
460+
461 def test_get_holder_types(self):
462 """test clear_holders.get_holder_types"""
463 test_trees_and_results = [
464
465=== modified file 'tests/unittests/test_commands_block_meta.py'
466--- tests/unittests/test_commands_block_meta.py 2017-08-03 19:48:07 +0000
467+++ tests/unittests/test_commands_block_meta.py 2017-11-07 18:32:47 +0000
468@@ -130,6 +130,8 @@
469 'mock_clear_holders')
470 self.add_patch('curtin.block.clear_holders.assert_clear',
471 'mock_assert_clear')
472+ self.add_patch('curtin.block.zero_file_at_offsets',
473+ 'mock_block_zero_file')
474
475 self.target = "my_target"
476 self.config = {
477@@ -177,32 +179,26 @@
478 self.mock_clear_holders.assert_called_with(disk)
479 self.mock_assert_clear.assert_called_with(disk)
480
481- def test_partition_handler_calls_clear_holder(self):
482+ def test_partition_handler_wipes_at_partition_offset(self):
483+ """ Test wiping partition at offset prior to creating partition"""
484 disk_info = self.storage_config.get('sda')
485 part_info = self.storage_config.get('sda-part1')
486 disk_kname = disk_info.get('path')
487 part_kname = disk_kname + '1'
488 self.mock_getpath.side_effect = iter([
489- disk_info.get('id'),
490- part_kname,
491- part_kname,
492+ disk_kname,
493 part_kname,
494 ])
495-
496 self.mock_block_get_part_table_type.return_value = 'dos'
497 kname = 'xxx'
498 self.mock_block_path_to_kname.return_value = kname
499 self.mock_block_sys_block_path.return_value = '/sys/class/block/xxx'
500- self.mock_subp.side_effect = iter([
501- ("", 0), # parted mkpart
502- ("", 0), # ??
503- ])
504- holders = ['md1']
505- self.mock_get_holders.return_value = holders
506
507 block_meta.partition_handler(part_info, self.storage_config)
508
509- print("clear_holders: %s" % self.mock_clear_holders.call_args_list)
510- print("assert_clear: %s" % self.mock_assert_clear.call_args_list)
511- self.mock_clear_holders.assert_called_with(part_kname)
512- self.mock_assert_clear.assert_called_with(part_kname)
513+ part_offset = 2048 * 512
514+ self.mock_block_zero_file.assert_called_with(disk_kname, [part_offset],
515+ exclusive=False)
516+ self.mock_subp.assert_called_with(['parted', disk_kname, '--script',
517+ 'mkpart', 'primary', '2048s',
518+ '1001471s'], capture=True)
519
520=== modified file 'tests/vmtests/__init__.py'
521--- tests/vmtests/__init__.py 2017-10-06 02:20:08 +0000
522+++ tests/vmtests/__init__.py 2017-11-07 18:32:47 +0000
523@@ -699,9 +699,6 @@
524 logger.info('Detected centos, adding default config %s',
525 centos_default)
526
527- if cls.multipath:
528- disks = disks * cls.multipath_num_paths
529-
530 # set reporting logger
531 cls.reporting_log = os.path.join(cls.td.logs, 'webhooks-events.json')
532 reporting_logger = CaptureReporting(cls.reporting_log)
533@@ -727,7 +724,7 @@
534 }))
535 configs.append(reporting_config)
536
537- cmd.extend(uefi_flags + netdevs + disks +
538+ cmd.extend(uefi_flags + netdevs + cls.mpath_diskargs(disks) +
539 [ftypes['vmtest.root-image'], "--kernel=%s" %
540 ftypes['boot-kernel'], "--initrd=%s" %
541 ftypes['boot-initrd'], "--", "curtin", "-vv", "install"] +
542@@ -825,11 +822,6 @@
543 # unlike NVMe disks, we do not want to configure the iSCSI disks
544 # via KVM, which would use qemu's iSCSI target layer.
545
546- if cls.multipath:
547- target_disks = target_disks * cls.multipath_num_paths
548- extra_disks = extra_disks * cls.multipath_num_paths
549- nvme_disks = nvme_disks * cls.multipath_num_paths
550-
551 # output disk is always virtio-blk, with serial of output_disk.img
552 output_disk = '--disk={},driver={},format={},{},{}'.format(
553 cls.td.output_disk, 'virtio-blk',
554@@ -840,11 +832,9 @@
555 # create xkvm cmd
556 cmd = (["tools/xkvm", "-v", dowait] +
557 uefi_flags + netdevs +
558- target_disks + extra_disks + nvme_disks +
559- ["--", "-drive",
560- "file=%s,if=virtio,media=cdrom" % cls.td.seed_disk,
561- "-smp", cls.get_config_smp(),
562- "-m", "1024"])
563+ cls.mpath_diskargs(target_disks + extra_disks + nvme_disks) +
564+ ["--disk=file=%s,if=virtio,media=cdrom" % cls.td.seed_disk] +
565+ ["--", "-smp", cls.get_config_smp(), "-m", "1024"])
566
567 if not cls.interactive:
568 if cls.arch == 's390x':
569@@ -1007,6 +997,15 @@
570 # prepending ./ makes '/root/file' or 'root/file' work as expected.
571 return os.path.normpath(os.path.join(cls.td.collect, "./" + path))
572
573+ @classmethod
574+ def mpath_diskargs(cls, disks):
575+ """make multipath versions of --disk args in disks."""
576+ if not cls.multipath:
577+ return disks
578+ opt = ",file.locking=off"
579+ return ([d if d == "--disk" else d + opt for d in disks] *
580+ cls.multipath_num_paths)
581+
582 # Misc functions that are useful for many tests
583 def output_files_exist(self, files):
584 logger.debug('checking files exist: %s', files)
585@@ -1459,7 +1458,7 @@
586 logger.info('Taring %s disks sparsely to %s', len(disks), outfile)
587 util.subp(cmd, capture=True)
588 else:
589- logger.error('Failed to find "disks" dir under tmpdir: %s', tmpdir)
590+ logger.debug('No "disks" dir found in tmpdir: %s', tmpdir)
591
592
593 def boot_log_wrap(name, func, cmd, console_log, timeout, purpose):
594
595=== modified file 'tests/vmtests/releases.py'
596--- tests/vmtests/releases.py 2017-08-03 19:48:07 +0000
597+++ tests/vmtests/releases.py 2017-11-07 18:32:47 +0000
598@@ -39,15 +39,6 @@
599 target_release = "centos66"
600
601
602-class _PreciseBase(_UbuntuBase):
603- release = "precise"
604-
605-
606-class _PreciseHWET(_UbuntuBase):
607- release = "precise"
608- krel = "trusty"
609-
610-
611 class _TrustyBase(_UbuntuBase):
612 release = "trusty"
613
614@@ -90,8 +81,6 @@
615
616
617 class _Releases(object):
618- precise = _PreciseBase
619- precise_hwe_t = _PreciseHWET
620 trusty = _TrustyBase
621 trusty_hwe_u = _TrustyHWEU
622 trusty_hwe_v = _TrustyHWEV
623
624=== modified file 'tests/vmtests/test_basic.py'
625--- tests/vmtests/test_basic.py 2017-08-03 19:48:07 +0000
626+++ tests/vmtests/test_basic.py 2017-11-07 18:32:47 +0000
627@@ -137,49 +137,6 @@
628 self.assertEqual(source_version, installed_version)
629
630
631-class PreciseTestBasic(relbase.precise, TestBasicAbs):
632- __test__ = True
633-
634- collect_scripts = [textwrap.dedent("""
635- cd OUTPUT_COLLECT_D
636- blkid -o export /dev/vda > blkid_output_vda
637- blkid -o export /dev/vda1 > blkid_output_vda1
638- blkid -o export /dev/vda2 > blkid_output_vda2
639- f="btrfs_uuid_vdd"
640- btrfs-show /dev/vdd | awk '/uuid/ {print $4}' > $f
641- cat /proc/partitions > proc_partitions
642- ls -al /dev/disk/by-uuid/ > ls_uuid
643- cat /etc/fstab > fstab
644- mkdir -p /dev/disk/by-dname
645- ls /dev/disk/by-dname/ > ls_dname
646- find /etc/network/interfaces.d > find_interfacesd
647-
648- v=""
649- out=$(apt-config shell v Acquire::HTTP::Proxy)
650- eval "$out"
651- echo "$v" > apt-proxy
652- """)]
653-
654- def test_whole_disk_format(self):
655- # confirm the whole disk format is the expected device
656- btrfs_uuid = self.load_collect_file("btrfs_uuid_vdd").strip()
657-
658- self.assertTrue(btrfs_uuid is not None)
659- self.assertEqual(len(btrfs_uuid), 36)
660-
661- # extract uuid from ls_uuid by kname
662- kname_uuid = self._kname_to_uuid('vdd')
663-
664- # compare them
665- self.assertEqual(kname_uuid, btrfs_uuid)
666-
667- def test_ptable(self):
668- print("test_ptable does not work for Precise")
669-
670- def test_dname(self):
671- print("test_dname does not work for Precise")
672-
673-
674 class TrustyTestBasic(relbase.trusty, TestBasicAbs):
675 __test__ = True
676
677@@ -193,11 +150,6 @@
678 print("test_ptable does not work for Trusty")
679
680
681-class PreciseHWETTestBasic(relbase.precise_hwe_t, PreciseTestBasic):
682- # FIXME: off due to test_whole_disk_format failing
683- __test__ = False
684-
685-
686 class TrustyHWEXTestBasic(relbase.trusty_hwe_x, TrustyTestBasic):
687 __test__ = True
688
689
690=== modified file 'tests/vmtests/test_bcache_basic.py'
691--- tests/vmtests/test_bcache_basic.py 2017-08-03 19:48:07 +0000
692+++ tests/vmtests/test_bcache_basic.py 2017-11-07 18:32:47 +0000
693@@ -43,10 +43,6 @@
694 self.check_file_regex("cmdline", r"root=UUID=")
695
696
697-class PreciseHWETBcacheBasic(relbase.precise_hwe_t, TestBcacheBasic):
698- __test__ = True
699-
700-
701 class TrustyBcacheBasic(relbase.trusty, TestBcacheBasic):
702 __test__ = False # covered by test_raid5_bcache
703
704
705=== added file 'tests/vmtests/test_bcache_bug1718699.py'
706--- tests/vmtests/test_bcache_bug1718699.py 1970-01-01 00:00:00 +0000
707+++ tests/vmtests/test_bcache_bug1718699.py 2017-11-07 18:32:47 +0000
708@@ -0,0 +1,21 @@
709+from .releases import base_vm_classes as relbase
710+from .test_bcache_basic import TestBcacheBasic
711+
712+
713+class TestBcacheBug1718699(TestBcacheBasic):
714+ conf_file = "examples/tests/bcache-wipe-xfs.yaml"
715+ dirty_disks = False
716+ nr_cpus = 2
717+ extra_disks = ['10G']
718+
719+
720+class XenialTestBcacheBug1718699(relbase.xenial, TestBcacheBug1718699):
721+ __test__ = True
722+
723+
724+class ZestyTestBcacheBug1718699(relbase.zesty, TestBcacheBug1718699):
725+ __test__ = True
726+
727+
728+class ArtfulTestBcacheBug1718699(relbase.artful, TestBcacheBug1718699):
729+ __test__ = True
730
731=== modified file 'tests/vmtests/test_iscsi.py'
732--- tests/vmtests/test_iscsi.py 2017-08-03 19:48:07 +0000
733+++ tests/vmtests/test_iscsi.py 2017-11-07 18:32:47 +0000
734@@ -47,10 +47,6 @@
735 (testfile, expected_content, content))
736
737
738-class PreciseTestIscsiBasic(relbase.precise, TestBasicIscsiAbs):
739- __test__ = True
740-
741-
742 class TrustyTestIscsiBasic(relbase.trusty, TestBasicIscsiAbs):
743 __test__ = True
744
745
746=== modified file 'tests/vmtests/test_lvm.py'
747--- tests/vmtests/test_lvm.py 2017-08-03 19:48:07 +0000
748+++ tests/vmtests/test_lvm.py 2017-11-07 18:32:47 +0000
749@@ -48,14 +48,6 @@
750 raise SkipTest("test_dname does not work for %s" % self.release)
751
752
753-class PreciseTestLvm(relbase.precise, TestLvmAbs):
754- __test__ = True
755-
756-
757-class PreciseHWETTestLvm(relbase.precise_hwe_t, PreciseTestLvm):
758- __test__ = True
759-
760-
761 class TrustyTestLvm(relbase.trusty, TestLvmAbs):
762 __test__ = True
763
764
765=== modified file 'tests/vmtests/test_lvm_iscsi.py'
766--- tests/vmtests/test_lvm_iscsi.py 2017-10-06 02:20:08 +0000
767+++ tests/vmtests/test_lvm_iscsi.py 2017-11-07 18:32:47 +0000
768@@ -47,10 +47,6 @@
769 self.check_file_strippedline("pvs", "vg2=/dev/sdb6")
770
771
772-class PreciseTestIscsiLvm(relbase.precise, TestLvmIscsiAbs):
773- __test__ = True
774-
775-
776 class TrustyTestIscsiLvm(relbase.trusty, TestLvmIscsiAbs):
777 __test__ = True
778
779
780=== modified file 'tests/vmtests/test_mdadm_iscsi.py'
781--- tests/vmtests/test_mdadm_iscsi.py 2017-10-06 02:20:08 +0000
782+++ tests/vmtests/test_mdadm_iscsi.py 2017-11-07 18:32:47 +0000
783@@ -22,10 +22,6 @@
784 """)]
785
786
787-class PreciseTestIscsiMdadm(relbase.precise, TestMdadmIscsiAbs):
788- __test__ = True
789-
790-
791 class TrustyTestIscsiMdadm(relbase.trusty, TestMdadmIscsiAbs):
792 __test__ = True
793
794
795=== modified file 'tests/vmtests/test_network.py'
796--- tests/vmtests/test_network.py 2017-10-06 02:20:08 +0000
797+++ tests/vmtests/test_network.py 2017-11-07 18:32:47 +0000
798@@ -449,11 +449,6 @@
799 pass
800
801
802-class PreciseHWETTestNetworkBasic(relbase.precise_hwe_t, TestNetworkBasicAbs):
803- # FIXME: off due to hang at test: Starting execute cloud user/final scripts
804- __test__ = False
805-
806-
807 class TrustyTestNetworkBasic(relbase.trusty, TestNetworkBasicAbs):
808 __test__ = True
809
810
811=== modified file 'tests/vmtests/test_network_alias.py'
812--- tests/vmtests/test_network_alias.py 2017-08-03 19:48:07 +0000
813+++ tests/vmtests/test_network_alias.py 2017-11-07 18:32:47 +0000
814@@ -41,11 +41,6 @@
815 __test__ = True
816
817
818-class PreciseHWETTestNetworkAlias(relbase.precise_hwe_t, TestNetworkAliasAbs):
819- # FIXME: off due to hang at test: Starting execute cloud user/final scripts
820- __test__ = True
821-
822-
823 class TrustyTestNetworkAlias(relbase.trusty, TestNetworkAliasAbs):
824 __test__ = True
825
826
827=== modified file 'tests/vmtests/test_network_bonding.py'
828--- tests/vmtests/test_network_bonding.py 2017-10-06 02:20:08 +0000
829+++ tests/vmtests/test_network_bonding.py 2017-11-07 18:32:47 +0000
830@@ -38,14 +38,6 @@
831 pass
832
833
834-class PreciseHWETTestBonding(relbase.precise_hwe_t, TestNetworkBondingAbs):
835- __test__ = True
836-
837- def test_ifenslave_installed(self):
838- self.assertIn("ifenslave-2.6", self.debian_packages,
839- "ifenslave deb not installed")
840-
841-
842 class TrustyTestBonding(relbase.trusty, TestNetworkBondingAbs):
843 __test__ = False
844
845
846=== modified file 'tests/vmtests/test_network_enisource.py'
847--- tests/vmtests/test_network_enisource.py 2017-10-06 02:20:08 +0000
848+++ tests/vmtests/test_network_enisource.py 2017-11-07 18:32:47 +0000
849@@ -79,12 +79,6 @@
850 self.assertEqual(_nocidr(expected_address), _nocidr(actual_address))
851
852
853-class PreciseTestNetworkENISource(relbase.precise, TestNetworkENISource):
854- __test__ = False
855- # not working, still debugging though; possible older ifupdown doesn't
856- # like the multiple iface method.
857-
858-
859 class TrustyTestNetworkENISource(relbase.trusty, TestNetworkENISource):
860 __test__ = True
861
862
863=== modified file 'tests/vmtests/test_network_ipv6.py'
864--- tests/vmtests/test_network_ipv6.py 2017-10-06 02:20:08 +0000
865+++ tests/vmtests/test_network_ipv6.py 2017-11-07 18:32:47 +0000
866@@ -40,11 +40,6 @@
867 pass
868
869
870-class PreciseHWETTestNetwork(relbase.precise_hwe_t, TestNetworkIPV6Abs):
871- # FIXME: off due to hang at test: Starting execute cloud user/final scripts
872- __test__ = False
873-
874-
875 class TrustyTestNetworkIPV6(relbase.trusty, TestNetworkIPV6Abs):
876 __test__ = True
877
878
879=== modified file 'tests/vmtests/test_network_ipv6_enisource.py'
880--- tests/vmtests/test_network_ipv6_enisource.py 2017-10-06 02:20:08 +0000
881+++ tests/vmtests/test_network_ipv6_enisource.py 2017-11-07 18:32:47 +0000
882@@ -12,13 +12,6 @@
883 pass
884
885
886-class PreciseTestNetworkIPV6ENISource(relbase.precise,
887- TestNetworkIPV6ENISource):
888- __test__ = False
889- # not working, still debugging though; possible older ifupdown doesn't
890- # like the multiple iface method.
891-
892-
893 class TrustyTestNetworkIPV6ENISource(relbase.trusty, TestNetworkIPV6ENISource):
894 __test__ = True
895
896
897=== modified file 'tests/vmtests/test_network_ipv6_static.py'
898--- tests/vmtests/test_network_ipv6_static.py 2017-08-03 19:48:07 +0000
899+++ tests/vmtests/test_network_ipv6_static.py 2017-11-07 18:32:47 +0000
900@@ -13,11 +13,6 @@
901 conf_file = "examples/tests/basic_network_static_ipv6.yaml"
902
903
904-class PreciseHWETTestNetworkIPV6Static(relbase.precise_hwe_t,
905- TestNetworkIPV6StaticAbs):
906- __test__ = True
907-
908-
909 class TrustyTestNetworkIPV6Static(relbase.trusty, TestNetworkIPV6StaticAbs):
910 __test__ = True
911
912
913=== modified file 'tests/vmtests/test_network_ipv6_vlan.py'
914--- tests/vmtests/test_network_ipv6_vlan.py 2017-10-06 02:20:08 +0000
915+++ tests/vmtests/test_network_ipv6_vlan.py 2017-11-07 18:32:47 +0000
916@@ -12,22 +12,6 @@
917 conf_file = "examples/tests/vlan_network_ipv6.yaml"
918
919
920-class PreciseTestNetworkIPV6Vlan(relbase.precise, TestNetworkIPV6VlanAbs):
921- __test__ = True
922-
923- # precise ip -d link show output is different (of course)
924- def test_vlan_enabled(self):
925-
926- # we must have at least one
927- self.assertGreaterEqual(len(self.get_vlans()), 1)
928-
929- # did they get configured?
930- for vlan in self.get_vlans():
931- link_file = "ip_link_show_" + vlan['name']
932- vlan_msg = "vlan id " + str(vlan['vlan_id'])
933- self.check_file_regex(link_file, vlan_msg)
934-
935-
936 class TrustyTestNetworkIPV6Vlan(relbase.trusty, TestNetworkIPV6VlanAbs):
937 __test__ = True
938
939
940=== modified file 'tests/vmtests/test_network_mtu.py'
941--- tests/vmtests/test_network_mtu.py 2017-10-06 02:20:08 +0000
942+++ tests/vmtests/test_network_mtu.py 2017-11-07 18:32:47 +0000
943@@ -155,11 +155,6 @@
944 pass
945
946
947-class PreciseHWETTestNetworkMtu(relbase.precise_hwe_t, TestNetworkMtuAbs):
948- # FIXME: Precise mtu / ipv6 is buggy
949- __test__ = False
950-
951-
952 class TrustyTestNetworkMtu(relbase.trusty, TestNetworkMtuAbs):
953 __test__ = True
954
955@@ -203,7 +198,7 @@
956 @classmethod
957 def setUpClass(cls):
958 cls.skip_by_date(cls.__name__, cls.release, "1671951",
959- fixby=(2017, 10, 20), removeby=(2018, 1, 23))
960+ fixby=(2018, 1, 20), removeby=(2018, 2, 23))
961 super().setUpClass()
962
963
964
965=== modified file 'tests/vmtests/test_network_static.py'
966--- tests/vmtests/test_network_static.py 2017-08-03 19:48:07 +0000
967+++ tests/vmtests/test_network_static.py 2017-11-07 18:32:47 +0000
968@@ -28,12 +28,6 @@
969 pass
970
971
972-class PreciseHWETTestNetworkStatic(relbase.precise_hwe_t,
973- TestNetworkStaticAbs):
974- # FIXME: off due to hang at test: Starting execute cloud user/final scripts
975- __test__ = False
976-
977-
978 class TrustyTestNetworkStatic(relbase.trusty, TestNetworkStaticAbs):
979 __test__ = True
980
981
982=== modified file 'tests/vmtests/test_network_static_routes.py'
983--- tests/vmtests/test_network_static_routes.py 2017-08-03 19:48:07 +0000
984+++ tests/vmtests/test_network_static_routes.py 2017-11-07 18:32:47 +0000
985@@ -16,12 +16,6 @@
986 conf_file = "examples/tests/network_static_routes.yaml"
987
988
989-class PreciseHWETTestNetworkStaticRoutes(relbase.precise_hwe_t,
990- TestNetworkStaticRoutesAbs):
991- # FIXME: off due to hang at test: Starting execute cloud user/final scripts
992- __test__ = False
993-
994-
995 class TrustyTestNetworkStaticRoutes(relbase.trusty,
996 TestNetworkStaticRoutesAbs):
997 __test__ = True
998
999=== modified file 'tests/vmtests/test_network_vlan.py'
1000--- tests/vmtests/test_network_vlan.py 2017-10-06 02:20:08 +0000
1001+++ tests/vmtests/test_network_vlan.py 2017-11-07 18:32:47 +0000
1002@@ -68,22 +68,6 @@
1003 pass
1004
1005
1006-class PreciseTestNetworkVlan(relbase.precise, TestNetworkVlanAbs):
1007- __test__ = True
1008-
1009- # precise ip -d link show output is different (of course)
1010- def test_vlan_enabled(self):
1011-
1012- # we must have at least one
1013- self.assertGreaterEqual(len(self.get_vlans()), 1)
1014-
1015- # did they get configured?
1016- for vlan in self.get_vlans():
1017- link_file = "ip_link_show_" + vlan['name']
1018- vlan_msg = "vlan id " + str(vlan['vlan_id'])
1019- self.check_file_regex(link_file, vlan_msg)
1020-
1021-
1022 class TrustyTestNetworkVlan(relbase.trusty, TestNetworkVlanAbs):
1023 __test__ = True
1024
1025
1026=== modified file 'tests/vmtests/test_nvme.py'
1027--- tests/vmtests/test_nvme.py 2017-08-03 19:48:07 +0000
1028+++ tests/vmtests/test_nvme.py 2017-11-07 18:32:47 +0000
1029@@ -53,11 +53,6 @@
1030 self.check_file_strippedline("ls_dev_nvme", "/dev/nvme1")
1031
1032
1033-class PreciseTestNvme(relbase.precise, TestNvmeAbs):
1034- __test__ = False
1035- # Precise kernel doesn't have NVME support, with TrustyHWE it would
1036-
1037-
1038 class TrustyTestNvme(relbase.trusty, TestNvmeAbs):
1039 __test__ = True
1040
1041
1042=== modified file 'tests/vmtests/test_raid5_bcache.py'
1043--- tests/vmtests/test_raid5_bcache.py 2017-08-03 19:48:07 +0000
1044+++ tests/vmtests/test_raid5_bcache.py 2017-11-07 18:32:47 +0000
1045@@ -65,11 +65,6 @@
1046 self.check_file_regex("bcache_cache_mode", r"\[writeback\]")
1047
1048
1049-class PreciseHWETTestRaid5Bcache(relbase.precise_hwe_t, TestMdadmBcacheAbs):
1050- # FIXME: off due to failing install: RUN_ARRAY failed: Invalid argument
1051- __test__ = False
1052-
1053-
1054 class TrustyTestRaid5Bcache(relbase.trusty, TestMdadmBcacheAbs):
1055 __test__ = True
1056 # FIXME(LP: #1523037): dname does not work on trusty, so we cannot expect
1057
1058=== modified file 'tests/vmtests/test_uefi_basic.py'
1059--- tests/vmtests/test_uefi_basic.py 2017-08-03 19:48:07 +0000
1060+++ tests/vmtests/test_uefi_basic.py 2017-11-07 18:32:47 +0000
1061@@ -9,7 +9,7 @@
1062 interactive = False
1063 arch_skip = ["s390x"]
1064 conf_file = "examples/tests/uefi_basic.yaml"
1065- extra_disks = []
1066+ extra_disks = ['4G']
1067 uefi = True
1068 disk_to_check = [('main_disk', 1), ('main_disk', 2), ('main_disk', 3)]
1069 collect_scripts = [textwrap.dedent("""
1070@@ -76,16 +76,6 @@
1071 self.assertEqual(self.disk_block_size, size)
1072
1073
1074-class PreciseUefiTestBasic(relbase.precise, TestBasicAbs):
1075- __test__ = True
1076-
1077- def test_ptable(self):
1078- print("test_ptable does not work for Precise")
1079-
1080- def test_dname(self):
1081- print("test_dname does not work for Precise")
1082-
1083-
1084 class TrustyUefiTestBasic(relbase.trusty, TestBasicAbs):
1085 __test__ = True
1086
1087@@ -115,10 +105,6 @@
1088 __test__ = True
1089
1090
1091-class PreciseUefiTestBasic4k(PreciseUefiTestBasic):
1092- disk_block_size = 4096
1093-
1094-
1095 class TrustyUefiTestBasic4k(TrustyUefiTestBasic):
1096 disk_block_size = 4096
1097
1098
1099=== modified file 'tools/launch'
1100--- tools/launch 2017-08-03 19:48:07 +0000
1101+++ tools/launch 2017-11-07 18:32:47 +0000
1102@@ -583,11 +583,10 @@
1103 bs_args="${bs_args},physical_block_size=$phybs"
1104 bs_args="${bs_args},min_io_size=$logbs"
1105
1106- disk_args=( "${disk_args[@]}" "-drive"
1107- "file=${src},if=none,cache=unsafe,format=$fmt,id=drv${id},index=$id" )
1108-
1109- disk_args=( "${disk_args[@]}" "-device"
1110- "${driver},drive=drv${id},${bs_args}${devopts}" )
1111+ t="file=${src},if=none,cache=unsafe,format=$fmt,"
1112+ t="${t}id=drv${id},index=$id,"
1113+ t="${t}driver=${driver},${bs_args}${devopts}"
1114+ disk_args[${#disk_args[@]}]="--disk=$t"
1115
1116 done
1117
1118@@ -754,7 +753,7 @@
1119 seed="${TEMP_D}/seed.img"
1120 cloud-localds "$seed" "$udata" "$mdata" ||
1121 { error "failed cloud-localds"; return 1; }
1122- seedargs=( "-drive" "file=${seed},if=virtio,media=cdrom" )
1123+ seedargs=( "--disk=file=${seed},if=virtio,media=cdrom" )
1124 fi
1125
1126 local netargs
1127@@ -779,13 +778,14 @@
1128 fi
1129 fi
1130 # -monitor stdio
1131+ local bootdisk="--disk=file=$bootimg,id=boot,index=1,cache=unsafe"
1132 cmd=(
1133- xkvm "${pt[@]}" "${netargs[@]}" --
1134+ xkvm "${pt[@]}" "${netargs[@]}"
1135+ "$bootdisk"
1136+ "${disk_args[@]}"
1137+ --
1138 -smp ${smp}
1139 -m ${mem} ${serial_args} ${video}
1140- -drive "file=$bootimg,if=none,cache=unsafe,format=qcow2,id=boot,index=0"
1141- -device "virtio-blk,drive=boot"
1142- "${disk_args[@]}"
1143 "${seedargs[@]}"
1144 )
1145
1146
1147=== modified file 'tools/xkvm'
1148--- tools/xkvm 2016-12-02 02:04:27 +0000
1149+++ tools/xkvm 2017-11-07 18:32:47 +0000
1150@@ -11,6 +11,8 @@
1151 # OVS_CLEANUP gets populated with bridge:devname pairs used with ovs
1152 OVS_CLEANUP=( )
1153 MAC_PREFIX="52:54:00:12:34"
1154+# allow this to be set externally.
1155+_QEMU_SUPPORTS_FILE_LOCKING="${_QEMU_SUPPORTS_FILE_LOCKING}"
1156 KVM="kvm"
1157 declare -A KVM_DEVOPTS
1158
1159@@ -119,6 +121,21 @@
1160 return 1
1161 }
1162
1163+qemu_supports_file_locking() {
1164+ # hackily check if qemu has file.locking in -drive params (LP: #1716028)
1165+ if [ -z "$_QEMU_SUPPORTS_FILE_LOCKING" ]; then
1166+ # The only way we could find to check presense of file.locking is
1167+ # qmp (query-qmp-schema). Simply checking if the virtio-blk driver
1168+ # supports 'share-rw' is expected to be equivalent and simpler.
1169+ isdevopt virtio-blk share-rw &&
1170+ _QEMU_SUPPORTS_FILE_LOCKING=true ||
1171+ _QEMU_SUPPORTS_FILE_LOCKING=false
1172+ debug 1 "qemu supports file locking = ${_QEMU_SUPPORTS_FILE_LOCKING}"
1173+ fi
1174+ [ "$_QEMU_SUPPORTS_FILE_LOCKING" = "true" ]
1175+ return
1176+}
1177+
1178 padmac() {
1179 # return a full mac, given a subset.
1180 # assume whatever is input is the last portion to be
1181@@ -443,7 +460,7 @@
1182 out=$(LANG=C qemu-img info "$file") &&
1183 fmt=$(echo "$out" | awk '$0 ~ /^file format:/ { print $3 }') ||
1184 { error "failed to determine format of $file"; return 1; }
1185- else
1186+ elif [ -z "$fmt" ]; then
1187 fmt=raw
1188 fi
1189 if [ -z "$driver" ]; then
1190@@ -470,6 +487,12 @@
1191 id=*|if=*|driver=*|$file|file=*) continue;;
1192 fmt=*|format=*) continue;;
1193 serial=*|bus=*|unit=*|index=*) continue;;
1194+ file.locking=*)
1195+ qemu_supports_file_locking || {
1196+ debug 2 "qemu has no file locking." \
1197+ "Dropping '$tok' from: $cur"
1198+ continue
1199+ };;
1200 esac
1201 isdevopt "$driver" "$tok" && devopts="${devopts},$tok" ||
1202 diskopts="${diskopts},${tok}"

Subscribers

People subscribed via source and target branches

to all changes: