Merge lp:~raharper/curtin/trunk.block-wipe-exclusive-optional into lp:~curtin-dev/curtin/trunk

Proposed by Ryan Harper
Status: Merged
Merged at revision: 538
Proposed branch: lp:~raharper/curtin/trunk.block-wipe-exclusive-optional
Merge into: lp:~curtin-dev/curtin/trunk
Diff against target: 88 lines (+18/-9)
3 files modified
curtin/block/__init__.py (+11/-5)
curtin/commands/block_meta.py (+4/-1)
tests/unittests/test_commands_block_meta.py (+3/-3)
To merge this branch: bzr merge lp:~raharper/curtin/trunk.block-wipe-exclusive-optional
Reviewer Review Type Date Requested Status
Server Team CI bot continuous-integration Approve
Scott Moser (community) Approve
Review via email: mp+332937@code.launchpad.net

Commit message

block: enable control over exclusive_open use when wiping volumes

The exclusive_open check on a device is very useful to determine if
curtin is removing all metadata from a device w.r.t storage
configuraiton. However, in some cases during creation of new storage
configations when curtin attempts to add additional partitions to a
device that has partitions already added to an raid device, the
exclusive open is blocked while we attempt to zero some data on the
underlying device. The Mirrorboot-UEFI vmtest exemplifies this
situation.

This patch exposes a flag to the zero_file_at_offset method to allow
callers (block_meta in this case) to disable the exclusive_open. This
lets curtin wipe data at specific offsets on a volume without
requiring exclusive ownership of the device.

To post a comment you must log in.
Revision history for this message
Server Team CI bot (server-team-bot) wrote :
review: Approve (continuous-integration)
Revision history for this message
Scott Moser (smoser) wrote :

One nit, but looks good.

review: Approve
540. By Ryan Harper

Update function docstring; accept boolean-ish values for exclusive parameter

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

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-06-19 19:22:42 +0000
3+++ curtin/block/__init__.py 2017-10-30 14:51:57 +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/commands/block_meta.py'
51--- curtin/commands/block_meta.py 2017-10-23 16:49:46 +0000
52+++ curtin/commands/block_meta.py 2017-10-30 14:51:57 +0000
53@@ -561,7 +561,10 @@
54 # length of the previous partition
55 wipe_offset = int(offset_sectors * logical_block_size_bytes)
56 LOG.debug('Wiping 1M on %s at offset %s', disk, wipe_offset)
57- block.zero_file_at_offsets(disk, [wipe_offset])
58+ # We don't require exclusive access as we're wiping data at an
59+ # offset and the current holder maybe part of the current storage
60+ # configuration.
61+ block.zero_file_at_offsets(disk, [wipe_offset], exclusive=False)
62
63 if disk_ptable == "msdos":
64 if flag in ["extended", "logical", "primary"]:
65
66=== modified file 'tests/unittests/test_commands_block_meta.py'
67--- tests/unittests/test_commands_block_meta.py 2017-10-23 16:49:46 +0000
68+++ tests/unittests/test_commands_block_meta.py 2017-10-30 14:51:57 +0000
69@@ -131,7 +131,7 @@
70 self.add_patch('curtin.block.clear_holders.assert_clear',
71 'mock_assert_clear')
72 self.add_patch('curtin.block.zero_file_at_offsets',
73- 'mock_block_zero_file_at_offsets')
74+ 'mock_block_zero_file')
75
76 self.target = "my_target"
77 self.config = {
78@@ -197,8 +197,8 @@
79 block_meta.partition_handler(part_info, self.storage_config)
80
81 part_offset = 2048 * 512
82- self.mock_block_zero_file_at_offsets.assert_called_with(disk_kname,
83- [part_offset])
84+ self.mock_block_zero_file.assert_called_with(disk_kname, [part_offset],
85+ exclusive=False)
86 self.mock_subp.assert_called_with(['parted', disk_kname, '--script',
87 'mkpart', 'primary', '2048s',
88 '1001471s'], capture=True)

Subscribers

People subscribed via source and target branches