diff --git a/diskimage_builder/block_device/level1/mbr.py b/diskimage_builder/block_device/level1/mbr.py index 8fab1e832..6b3f87f66 100644 --- a/diskimage_builder/block_device/level1/mbr.py +++ b/diskimage_builder/block_device/level1/mbr.py @@ -11,9 +11,10 @@ # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the # License for the specific language governing permissions and limitations # under the License. -import logging -import random +import logging +import os +import random from struct import pack @@ -173,6 +174,8 @@ class MBR(object): return self def __exit__(self, exc_type, exc_value, traceback): + self.image_fd.flush() + os.fsync(self.image_fd.fileno()) self.image_fd.close() def lba2chs(self, lba): diff --git a/diskimage_builder/block_device/level1/partitioning.py b/diskimage_builder/block_device/level1/partitioning.py index 926207e68..e8a559867 100644 --- a/diskimage_builder/block_device/level1/partitioning.py +++ b/diskimage_builder/block_device/level1/partitioning.py @@ -143,16 +143,13 @@ class Partitioning(PluginBase): self.state['blockdev'][part_name] \ = {'device': partition_device_name} + # "saftey sync" to make sure the partitions are written + exec_sudo(["sync"]) + # now all the partitions are created, get device-mapper to # mount them if not os.path.exists("/.dockerenv"): exec_sudo(["kpartx", "-avs", device_path]) - # We need to make sure udev finishes creating the device - # before continuting, so "udevadm settle". Otherwise later - # commands can fail with "file does not exist". - # XXX: "-s" (synchronous) to kpartx should avoid this, - # but experience shows it does not. - exec_sudo(["udevadm", "settle"]) else: # If running inside Docker, make our nodes manually, # because udev will not be working. kpartx cannot run in diff --git a/diskimage_builder/block_device/tests/test_mbr.py b/diskimage_builder/block_device/tests/test_mbr.py index 953dc1799..606b943ed 100644 --- a/diskimage_builder/block_device/tests/test_mbr.py +++ b/diskimage_builder/block_device/tests/test_mbr.py @@ -12,6 +12,7 @@ import fixtures import logging +import mock import os import subprocess @@ -62,11 +63,17 @@ class TestMBR(tb.TestBase): logger.info("Running command: %s", self.partx_args) return subprocess.check_output(self.partx_args).decode("ascii") - def test_one_ext_partition(self): + @mock.patch('os.fsync', wraps=os.fsync) + def test_one_ext_partition(self, mock_os_fsync): """Creates one partition and check correctness with partx.""" with MBR(self.image_path, TestMBR.disk_size_1G, 1024 * 1024) as mbr: mbr.add_partition(False, False, TestMBR.disk_size_10M, 0x83) + + # the exit handler of MBR should have synced the raw device + # before exit + mock_os_fsync.assert_called() + output = self._run_partx(self.image_path) self.assertEqual( "1 2048 2097151 0xf 0x0 dos\n"