Merge ~mwhudson/curtin:lp-1868177 into curtin:master

Proposed by Michael Hudson-Doyle
Status: Merged
Approved by: Michael Hudson-Doyle
Approved revision: c3800f7bccc9e892224c0dfcfd750adaba7e5eb9
Merge reported by: Server Team CI bot
Merged at revision: not available
Proposed branch: ~mwhudson/curtin:lp-1868177
Merge into: curtin:master
Diff against target: 216 lines (+25/-24)
5 files modified
curtin/block/__init__.py (+6/-7)
curtin/block/clear_holders.py (+2/-3)
examples/tests/uefi_basic.yaml (+4/-0)
tests/unittests/test_block.py (+2/-2)
tests/unittests/test_clear_holders.py (+11/-12)
Reviewer Review Type Date Requested Status
Server Team CI bot continuous-integration Approve
curtin developers Pending
Review via email: mp+399893@code.launchpad.net

Commit message

remove 'strict' arguments to block.wipe_volume and block.quick_zero

It was only passed by clear_holders._wipe_superblock and clear_holders
is all best effort anyway.

in particular, this should fix failures seen in subiquity error reports
when wiping very small (<1M) partitions.

LP: #1868177

Description of the change

i haven't tested this beyond running the unittests yet. I guess I should add some more of those too.

To post a comment you must log in.
Revision history for this message
Ryan Harper (raharper) wrote :

Definitely should add a less than 1MB partition in one of the vmtests
Comment below, I suggest that we drop the strict=true in clear_holders.py:_wipe_superblock() instead.

~mwhudson/curtin:lp-1868177 updated
bb8b718... by Michael Hudson-Doyle

remove strict argument to block.wipe_volume

It was only passed by clear_holders._wipe_superblock and clear_holders
is all best effort anyway.

in particular, this should fix failures seen in subiquity error reports
when wiping very small (<1M) partitions.

LP: #1868177

Revision history for this message
Michael Hudson-Doyle (mwhudson) wrote :

Yes, that seems completely fair. Take another look?

~mwhudson/curtin:lp-1868177 updated
62bf639... by Michael Hudson-Doyle

remove strict argument from quick_zero too

c3800f7... by Michael Hudson-Doyle

add a tiny partition to a randomly selected vmtest

Revision history for this message
Michael Hudson-Doyle (mwhudson) wrote :

Confirmed that the vmtest change makes a vmtest fail without the fix that passes with it

Revision history for this message
Server Team CI bot (server-team-bot) wrote :
review: Needs Fixing (continuous-integration)
Revision history for this message
Server Team CI bot (server-team-bot) wrote :
review: Needs Fixing (continuous-integration)
Revision history for this message
Michael Hudson-Doyle (mwhudson) wrote :

arm64 failure is that odd pylint race

Revision history for this message
Ryan Harper (raharper) wrote :

I think this is fine. I _was_ thinking to only remove the strict=True default in _wipe_superblock in clear-holders. However no where else is code calling with strict=true; if *something* external were using wipe_superblock and strict=true, so this is the minimal change I think:

(here's me wanting github style markdown in comments)
```
(crispyboi) curtin % git diff
diff --git a/curtin/block/clear_holders.py b/curtin/block/clear_holders.py
index c182d91a..ba026574 100644
--- a/curtin/block/clear_holders.py
+++ b/curtin/block/clear_holders.py
@@ -332,7 +332,7 @@ def wipe_superblock(device):
             time.sleep(wait)

-def _wipe_superblock(blockdev, exclusive=True, strict=True):
+def _wipe_superblock(blockdev, exclusive=True):
     """ No checks, just call wipe_volume """

     retries = [1, 3, 5, 7]
@@ -341,8 +341,7 @@ def _wipe_superblock(blockdev, exclusive=True, strict=True):
         LOG.debug('wiping %s attempt %s/%s',
                   blockdev, attempt + 1, len(retries))
         try:
- block.wipe_volume(blockdev, mode='superblock',
- exclusive=exclusive, strict=strict)
+ block.wipe_volume(blockdev, mode='superblock', exclusive=exclusive)
             LOG.debug('successfully wiped device %s on attempt %s/%s',
                       blockdev, attempt + 1, len(retries))
             return
```

So, I'll approve and leave it up to you if you want to do the minimal or the full removal that you have.

Revision history for this message
Michael Hudson-Doyle (mwhudson) wrote :

Are there any users of curtin-as-a-library beyond maas and subiquity? I'm not aware of any and if this change shakes any out of the tree I'd be interested to talk to them :)

Revision history for this message
Server Team CI bot (server-team-bot) :
review: Approve (continuous-integration)

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
diff --git a/curtin/block/__init__.py b/curtin/block/__init__.py
index 1b33002..2580a0d 100644
--- a/curtin/block/__init__.py
+++ b/curtin/block/__init__.py
@@ -1203,7 +1203,7 @@ def wipe_file(path, reader=None, buflen=4 * 1024 * 1024, exclusive=True):
1203 fp.write(pbuf)1203 fp.write(pbuf)
12041204
12051205
1206def quick_zero(path, partitions=True, exclusive=True, strict=False):1206def quick_zero(path, partitions=True, exclusive=True):
1207 """1207 """
1208 zero 1M at front, 1M at end, and 1M at front1208 zero 1M at front, 1M at end, and 1M at front
1209 if this is a block device and partitions is true, then1209 if this is a block device and partitions is true, then
@@ -1227,11 +1227,11 @@ def quick_zero(path, partitions=True, exclusive=True, strict=False):
1227 for (pt, kname, ptnum) in pt_names:1227 for (pt, kname, ptnum) in pt_names:
1228 LOG.debug('Wiping path: dev:%s kname:%s partnum:%s',1228 LOG.debug('Wiping path: dev:%s kname:%s partnum:%s',
1229 pt, kname, ptnum)1229 pt, kname, ptnum)
1230 quick_zero(pt, partitions=False, strict=strict)1230 quick_zero(pt, partitions=False)
12311231
1232 LOG.debug("wiping 1M on %s at offsets %s", path, offsets)1232 LOG.debug("wiping 1M on %s at offsets %s", path, offsets)
1233 return zero_file_at_offsets(path, offsets, buflen=buflen, count=count,1233 return zero_file_at_offsets(path, offsets, buflen=buflen, count=count,
1234 exclusive=exclusive, strict=strict)1234 exclusive=exclusive)
12351235
12361236
1237def zero_file_at_offsets(path, offsets, buflen=1024, count=1024, strict=False,1237def zero_file_at_offsets(path, offsets, buflen=1024, count=1024, strict=False,
@@ -1286,7 +1286,7 @@ def zero_file_at_offsets(path, offsets, buflen=1024, count=1024, strict=False,
1286 fp.write(buf)1286 fp.write(buf)
12871287
12881288
1289def wipe_volume(path, mode="superblock", exclusive=True, strict=False):1289def wipe_volume(path, mode="superblock", exclusive=True):
1290 """wipe a volume/block device1290 """wipe a volume/block device
12911291
1292 :param path: a path to a block device1292 :param path: a path to a block device
@@ -1299,7 +1299,6 @@ def wipe_volume(path, mode="superblock", exclusive=True, strict=False):
1299 volume and beginning and end of any partitions that are1299 volume and beginning and end of any partitions that are
1300 known to be on this device.1300 known to be on this device.
1301 :param exclusive: boolean to control how path is opened1301 :param exclusive: boolean to control how path is opened
1302 :param strict: boolean to control when to raise errors on write failures
1303 """1302 """
1304 if mode == "pvremove":1303 if mode == "pvremove":
1305 # We need to use --force --force in case it's already in a volgroup and1304 # We need to use --force --force in case it's already in a volgroup and
@@ -1317,9 +1316,9 @@ def wipe_volume(path, mode="superblock", exclusive=True, strict=False):
1317 with open("/dev/urandom", "rb") as reader:1316 with open("/dev/urandom", "rb") as reader:
1318 wipe_file(path, reader=reader.read, exclusive=exclusive)1317 wipe_file(path, reader=reader.read, exclusive=exclusive)
1319 elif mode == "superblock":1318 elif mode == "superblock":
1320 quick_zero(path, partitions=False, exclusive=exclusive, strict=strict)1319 quick_zero(path, partitions=False, exclusive=exclusive)
1321 elif mode == "superblock-recursive":1320 elif mode == "superblock-recursive":
1322 quick_zero(path, partitions=True, exclusive=exclusive, strict=strict)1321 quick_zero(path, partitions=True, exclusive=exclusive)
1323 else:1322 else:
1324 raise ValueError("wipe mode %s not supported" % mode)1323 raise ValueError("wipe mode %s not supported" % mode)
13251324
diff --git a/curtin/block/clear_holders.py b/curtin/block/clear_holders.py
index c182d91..ba02657 100644
--- a/curtin/block/clear_holders.py
+++ b/curtin/block/clear_holders.py
@@ -332,7 +332,7 @@ def wipe_superblock(device):
332 time.sleep(wait)332 time.sleep(wait)
333333
334334
335def _wipe_superblock(blockdev, exclusive=True, strict=True):335def _wipe_superblock(blockdev, exclusive=True):
336 """ No checks, just call wipe_volume """336 """ No checks, just call wipe_volume """
337337
338 retries = [1, 3, 5, 7]338 retries = [1, 3, 5, 7]
@@ -341,8 +341,7 @@ def _wipe_superblock(blockdev, exclusive=True, strict=True):
341 LOG.debug('wiping %s attempt %s/%s',341 LOG.debug('wiping %s attempt %s/%s',
342 blockdev, attempt + 1, len(retries))342 blockdev, attempt + 1, len(retries))
343 try:343 try:
344 block.wipe_volume(blockdev, mode='superblock',344 block.wipe_volume(blockdev, mode='superblock', exclusive=exclusive)
345 exclusive=exclusive, strict=strict)
346 LOG.debug('successfully wiped device %s on attempt %s/%s',345 LOG.debug('successfully wiped device %s on attempt %s/%s',
347 blockdev, attempt + 1, len(retries))346 blockdev, attempt + 1, len(retries))
348 return347 return
diff --git a/examples/tests/uefi_basic.yaml b/examples/tests/uefi_basic.yaml
index 1f49fa9..91a72ae 100644
--- a/examples/tests/uefi_basic.yaml
+++ b/examples/tests/uefi_basic.yaml
@@ -1,6 +1,10 @@
1showtrace: true1showtrace: true
22
3early_commands:3early_commands:
4 # Create a small (512KiB) partition to test the fix for LP: #1868177.
5 tinypartition: [
6 "parted", /dev/disk/by-id/virtio-disk-a, "--script", "mklabel", "gpt",
7 "mkpart", "primary", "4096s", "4096s", "5120s"]
4 # Recreate and test LP:17223228 # Recreate and test LP:1722322
5 # Make one disk dirty with an MBR and a storage configuration9 # Make one disk dirty with an MBR and a storage configuration
6 # GPT and don't supply wipe: superblock. This will exercise10 # GPT and don't supply wipe: superblock. This will exercise
diff --git a/tests/unittests/test_block.py b/tests/unittests/test_block.py
index d96a4a8..519628a 100644
--- a/tests/unittests/test_block.py
+++ b/tests/unittests/test_block.py
@@ -409,11 +409,11 @@ class TestWipeVolume(CiTestCase):
409 def test_wipe_superblock(self, mock_quick_zero):409 def test_wipe_superblock(self, mock_quick_zero):
410 block.wipe_volume(self.dev, mode='superblock')410 block.wipe_volume(self.dev, mode='superblock')
411 mock_quick_zero.assert_called_with(self.dev, exclusive=True,411 mock_quick_zero.assert_called_with(self.dev, exclusive=True,
412 partitions=False, strict=False)412 partitions=False)
413 block.wipe_volume(self.dev, exclusive=True,413 block.wipe_volume(self.dev, exclusive=True,
414 mode='superblock-recursive')414 mode='superblock-recursive')
415 mock_quick_zero.assert_called_with(self.dev, exclusive=True,415 mock_quick_zero.assert_called_with(self.dev, exclusive=True,
416 partitions=True, strict=False)416 partitions=True)
417417
418 @mock.patch('curtin.block.wipe_file')418 @mock.patch('curtin.block.wipe_file')
419 def test_wipe_zero(self, mock_wipe_file):419 def test_wipe_zero(self, mock_wipe_file):
diff --git a/tests/unittests/test_clear_holders.py b/tests/unittests/test_clear_holders.py
index d1c2590..48697b5 100644
--- a/tests/unittests/test_clear_holders.py
+++ b/tests/unittests/test_clear_holders.py
@@ -142,8 +142,7 @@ class TestClearHolders(CiTestCase):
142 # 1. wipe the bcache device contents142 # 1. wipe the bcache device contents
143 m_block.wipe_volume.assert_called_with(self.test_blockdev,143 m_block.wipe_volume.assert_called_with(self.test_blockdev,
144 mode='superblock',144 mode='superblock',
145 exclusive=False,145 exclusive=False)
146 strict=True)
147 # 2. extract the backing device146 # 2. extract the backing device
148 m_bcache.get_backing_device.assert_called_with(self.test_blockdev)147 m_bcache.get_backing_device.assert_called_with(self.test_blockdev)
149 m_bcache.sysfs_path.assert_has_calls([148 m_bcache.sysfs_path.assert_has_calls([
@@ -243,7 +242,7 @@ class TestClearHolders(CiTestCase):
243 clear_holders.shutdown_mdadm(self.test_syspath)242 clear_holders.shutdown_mdadm(self.test_syspath)
244243
245 mock_wipe.assert_called_with(self.test_blockdev, exclusive=False,244 mock_wipe.assert_called_with(self.test_blockdev, exclusive=False,
246 mode='superblock', strict=True)245 mode='superblock')
247 mock_mdadm.set_sync_action.assert_has_calls([246 mock_mdadm.set_sync_action.assert_has_calls([
248 mock.call(self.test_blockdev, action="idle"),247 mock.call(self.test_blockdev, action="idle"),
249 mock.call(self.test_blockdev, action="frozen")])248 mock.call(self.test_blockdev, action="frozen")])
@@ -281,7 +280,7 @@ class TestClearHolders(CiTestCase):
281 clear_holders.shutdown_mdadm(self.test_syspath)280 clear_holders.shutdown_mdadm(self.test_syspath)
282281
283 mock_wipe.assert_called_with(self.test_blockdev, exclusive=False,282 mock_wipe.assert_called_with(self.test_blockdev, exclusive=False,
284 mode='superblock', strict=True)283 mode='superblock')
285 mock_mdadm.set_sync_action.assert_has_calls([284 mock_mdadm.set_sync_action.assert_has_calls([
286 mock.call(self.test_blockdev, action="idle"),285 mock.call(self.test_blockdev, action="idle"),
287 mock.call(self.test_blockdev, action="frozen")])286 mock.call(self.test_blockdev, action="frozen")])
@@ -363,7 +362,7 @@ class TestClearHolders(CiTestCase):
363 clear_holders.wipe_superblock(self.test_syspath)362 clear_holders.wipe_superblock(self.test_syspath)
364 mock_block.sysfs_to_devpath.assert_called_with(self.test_syspath)363 mock_block.sysfs_to_devpath.assert_called_with(self.test_syspath)
365 mock_block.wipe_volume.assert_called_with(364 mock_block.wipe_volume.assert_called_with(
366 self.test_blockdev, exclusive=True, mode='superblock', strict=True)365 self.test_blockdev, exclusive=True, mode='superblock')
367366
368 @mock.patch('curtin.block.clear_holders.multipath')367 @mock.patch('curtin.block.clear_holders.multipath')
369 @mock.patch('curtin.block.clear_holders.is_swap_device')368 @mock.patch('curtin.block.clear_holders.is_swap_device')
@@ -391,7 +390,7 @@ class TestClearHolders(CiTestCase):
391 mock_block.sysfs_to_devpath.assert_called_with(self.test_syspath)390 mock_block.sysfs_to_devpath.assert_called_with(self.test_syspath)
392 mock_zfs.zpool_export.assert_called_with('fake_pool')391 mock_zfs.zpool_export.assert_called_with('fake_pool')
393 mock_block.wipe_volume.assert_called_with(392 mock_block.wipe_volume.assert_called_with(
394 self.test_blockdev, exclusive=True, mode='superblock', strict=True)393 self.test_blockdev, exclusive=True, mode='superblock')
395394
396 @mock.patch('curtin.block.clear_holders.multipath')395 @mock.patch('curtin.block.clear_holders.multipath')
397 @mock.patch('curtin.block.clear_holders.is_swap_device')396 @mock.patch('curtin.block.clear_holders.is_swap_device')
@@ -420,7 +419,7 @@ class TestClearHolders(CiTestCase):
420 self.assertEqual(0, mock_zfs.device_to_poolname.call_count)419 self.assertEqual(0, mock_zfs.device_to_poolname.call_count)
421 self.assertEqual(0, mock_zfs.zpool_list.call_count)420 self.assertEqual(0, mock_zfs.zpool_list.call_count)
422 mock_block.wipe_volume.assert_called_with(421 mock_block.wipe_volume.assert_called_with(
423 self.test_blockdev, exclusive=True, mode='superblock', strict=True)422 self.test_blockdev, exclusive=True, mode='superblock')
424423
425 @mock.patch('curtin.block.clear_holders.udev')424 @mock.patch('curtin.block.clear_holders.udev')
426 @mock.patch('curtin.block.clear_holders.multipath')425 @mock.patch('curtin.block.clear_holders.multipath')
@@ -454,7 +453,7 @@ class TestClearHolders(CiTestCase):
454 clear_holders.wipe_superblock(self.test_syspath)453 clear_holders.wipe_superblock(self.test_syspath)
455 mock_block.sysfs_to_devpath.assert_called_with(self.test_syspath)454 mock_block.sysfs_to_devpath.assert_called_with(self.test_syspath)
456 mock_block.wipe_volume.assert_called_with(455 mock_block.wipe_volume.assert_called_with(
457 self.test_blockdev, exclusive=True, mode='superblock', strict=True)456 self.test_blockdev, exclusive=True, mode='superblock')
458457
459 @mock.patch('curtin.block.clear_holders.multipath')458 @mock.patch('curtin.block.clear_holders.multipath')
460 @mock.patch('curtin.block.clear_holders.is_swap_device')459 @mock.patch('curtin.block.clear_holders.is_swap_device')
@@ -482,7 +481,7 @@ class TestClearHolders(CiTestCase):
482 clear_holders.wipe_superblock(self.test_syspath)481 clear_holders.wipe_superblock(self.test_syspath)
483 mock_block.sysfs_to_devpath.assert_called_with(self.test_syspath)482 mock_block.sysfs_to_devpath.assert_called_with(self.test_syspath)
484 mock_block.wipe_volume.assert_called_with(483 mock_block.wipe_volume.assert_called_with(
485 self.test_blockdev, exclusive=True, mode='superblock', strict=True)484 self.test_blockdev, exclusive=True, mode='superblock')
486 mock_block.get_sysfs_partitions.assert_has_calls(485 mock_block.get_sysfs_partitions.assert_has_calls(
487 [mock.call(self.test_syspath)] * 3)486 [mock.call(self.test_syspath)] * 3)
488 mock_block.rescan_block_devices.assert_has_calls(487 mock_block.rescan_block_devices.assert_has_calls(
@@ -515,7 +514,7 @@ class TestClearHolders(CiTestCase):
515 clear_holders.wipe_superblock(self.test_syspath)514 clear_holders.wipe_superblock(self.test_syspath)
516 mock_block.sysfs_to_devpath.assert_called_with(self.test_syspath)515 mock_block.sysfs_to_devpath.assert_called_with(self.test_syspath)
517 mock_block.wipe_volume.assert_called_with(516 mock_block.wipe_volume.assert_called_with(
518 self.test_blockdev, exclusive=True, mode='superblock', strict=True)517 self.test_blockdev, exclusive=True, mode='superblock')
519 mock_block.get_sysfs_partitions.assert_has_calls(518 mock_block.get_sysfs_partitions.assert_has_calls(
520 [mock.call(self.test_syspath)] * 3)519 [mock.call(self.test_syspath)] * 3)
521 mock_block.rescan_block_devices.assert_has_calls(520 mock_block.rescan_block_devices.assert_has_calls(
@@ -577,7 +576,7 @@ class TestClearHolders(CiTestCase):
577 clear_holders.wipe_superblock(self.test_syspath)576 clear_holders.wipe_superblock(self.test_syspath)
578 mock_block.sysfs_to_devpath.assert_called_with(self.test_syspath)577 mock_block.sysfs_to_devpath.assert_called_with(self.test_syspath)
579 mock_block.wipe_volume.assert_called_with(578 mock_block.wipe_volume.assert_called_with(
580 self.test_blockdev, exclusive=True, mode='superblock', strict=True)579 self.test_blockdev, exclusive=True, mode='superblock')
581580
582 @mock.patch('curtin.block.clear_holders.zfs')581 @mock.patch('curtin.block.clear_holders.zfs')
583 @mock.patch('curtin.block.clear_holders.get_holders')582 @mock.patch('curtin.block.clear_holders.get_holders')
@@ -614,7 +613,7 @@ class TestClearHolders(CiTestCase):
614 mock_block.sysfs_to_devpath.assert_called_with(self.test_syspath)613 mock_block.sysfs_to_devpath.assert_called_with(self.test_syspath)
615 mock_mpath.remove_partition.assert_called_with('mpatha-part1')614 mock_mpath.remove_partition.assert_called_with('mpatha-part1')
616 mock_block.wipe_volume.assert_called_with(615 mock_block.wipe_volume.assert_called_with(
617 self.test_blockdev, exclusive=True, mode='superblock', strict=True)616 self.test_blockdev, exclusive=True, mode='superblock')
618617
619 @mock.patch('curtin.block.clear_holders.LOG')618 @mock.patch('curtin.block.clear_holders.LOG')
620 @mock.patch('curtin.block.clear_holders.block')619 @mock.patch('curtin.block.clear_holders.block')

Subscribers

People subscribed via source and target branches