The current wipe_chunk_size computation is doing min(int_value,
float_value). For small disks, the actual formula will result into the
float value being chosen. This results into very interesting
behaviour:
Wiping disk 0, offset 102.4, chunk 102.4
Wiping disk 0, offset 204.8, chunk 102.4
…
Wiping disk 0, offset 921.6, chunk 102.4
Wiping disk 0, offset 1024.0, chunk 1.13686837722e-13
Since these are passed to dd via %d, this will result into the call to
dd specifying offset 1024 and count 0, which will fail.
We just need to enforce conversion to int, in order to not get bitten
by floating point rounding errors.
The patch also reorders some logging messages in order to log the
chunk size.
---
lib/cmdlib.py | 13 +++++++++----
1 files changed, 9 insertions(+), 4 deletions(-)
diff --git a/lib/cmdlib.py b/lib/cmdlib.py
index 9db959e..644fa4c 100644
--- a/lib/cmdlib.py
+++ b/lib/cmdlib.py
@@ -6656,14 +6656,17 @@ def _WipeDisks(lu, instance):
try:
for idx, device in enumerate(instance.disks):
- lu.LogInfo("* Wiping disk %d", idx)
- logging.info("Wiping disk %d for instance %s, node %s",
- idx, instance.name, node)
-
# The wipe size is MIN_WIPE_CHUNK_PERCENT % of the instance disk but
# MAX_WIPE_CHUNK at max
wipe_chunk_size = min(constants.MAX_WIPE_CHUNK, device.size / 100.0 *
constants.MIN_WIPE_CHUNK_PERCENT)
+ # we _must_ make this an int, otherwise rounding errors will
+ # occur
+ wipe_chunk_size = int(wipe_chunk_size)
+
+ lu.LogInfo("* Wiping disk %d", idx)
+ logging.info("Wiping disk %d for instance %s, node %s using"
+ " chunk size %s", idx, instance.name, node, wipe_chunk_size)
offset = 0
size = device.size
@@ -6672,6 +6675,8 @@ def _WipeDisks(lu, instance):
while offset < size:
wipe_size = min(wipe_chunk_size, size - offset)
+ logging.debug("Wiping disk %d, offset %s, chunk %s",
+ idx, offset, wipe_size)
result = lu.rpc.call_blockdev_wipe(node, device, offset, wipe_size)
result.Raise("Could not wipe disk %d at offset %d for size %d" %
(idx, offset, wipe_size))
--
1.7.3.1