mirror of
https://github.com/xcat2/confluent.git
synced 2026-08-03 16:07:00 +00:00
Release the crypt device if encrypt_image is interrupted
Nothing unwound the loop device and dm-crypt mapping when the copy loop raised, so interrupting a pack stranded both, still holding the profile's rootimg.sfs. Tear them down from a finally. The retry loop moves with them, so also honour its tries counter, as unpack_image already does; spinning forever inside a finally would hang the interrupt it is meant to clean up after. A bounded retry loop can also give up, and the detach that follows would then fail with EBUSY and, raising from a finally, replace the exception that brought us here. Warn and leave both in place instead.
This commit is contained in:
+30
-21
@@ -385,28 +385,37 @@ def encrypt_image(plainfile, cryptfile, keyfile):
|
||||
neededblocks += 1
|
||||
loopdev = subprocess.check_output(['losetup', '-f']).decode('utf8').strip()
|
||||
subprocess.check_call(['losetup', loopdev, cryptfile])
|
||||
subprocess.check_call(['dmsetup', 'create', dmname, '--table', '0 {} crypt aes-xts-plain64 {} 0 {} 8'.format(neededblocks, key, loopdev)])
|
||||
subprocess.check_call(['dmsetup', 'mknodes', dmname])
|
||||
with open('/dev/mapper/{}'.format(dmname), 'wb') as cryptout:
|
||||
with open(plainfile, 'rb+') as plainin:
|
||||
lastoffset = 0
|
||||
chunk = plainin.read(2097152)
|
||||
while chunk:
|
||||
fallocate(plainin.fileno(), FALLOC_FL_KEEP_SIZE|FALLOC_FL_PUNCH_HOLE, lastoffset, len(chunk))
|
||||
lastoffset = plainin.tell()
|
||||
cryptout.write(chunk)
|
||||
try:
|
||||
subprocess.check_call(['dmsetup', 'create', dmname, '--table', '0 {} crypt aes-xts-plain64 {} 0 {} 8'.format(neededblocks, key, loopdev)])
|
||||
subprocess.check_call(['dmsetup', 'mknodes', dmname])
|
||||
with open('/dev/mapper/{}'.format(dmname), 'wb') as cryptout:
|
||||
with open(plainfile, 'rb+') as plainin:
|
||||
lastoffset = 0
|
||||
chunk = plainin.read(2097152)
|
||||
mounted = True
|
||||
tries = 30
|
||||
time.sleep(0.1)
|
||||
while mounted:
|
||||
tries -= 1
|
||||
try:
|
||||
subprocess.check_call(['dmsetup', 'remove', dmname])
|
||||
mounted = False
|
||||
except subprocess.CalledProcessError:
|
||||
time.sleep(0.1)
|
||||
subprocess.check_call(['losetup', '-d', loopdev])
|
||||
while chunk:
|
||||
fallocate(plainin.fileno(), FALLOC_FL_KEEP_SIZE|FALLOC_FL_PUNCH_HOLE, lastoffset, len(chunk))
|
||||
lastoffset = plainin.tell()
|
||||
cryptout.write(chunk)
|
||||
chunk = plainin.read(2097152)
|
||||
finally:
|
||||
mounted = True
|
||||
tries = 30
|
||||
time.sleep(0.1)
|
||||
while mounted and tries:
|
||||
tries -= 1
|
||||
try:
|
||||
subprocess.check_call(['dmsetup', 'remove', dmname])
|
||||
mounted = False
|
||||
except subprocess.CalledProcessError:
|
||||
time.sleep(0.1)
|
||||
if mounted:
|
||||
sys.stderr.write(
|
||||
'Warning: unable to remove {0}, it and {1} are left behind\n'.format(dmname, loopdev))
|
||||
else:
|
||||
try:
|
||||
subprocess.check_call(['losetup', '-d', loopdev])
|
||||
except subprocess.CalledProcessError:
|
||||
sys.stderr.write('Warning: unable to detach {0}\n'.format(loopdev))
|
||||
oum = os.umask(0o077)
|
||||
with open(keyfile, 'w') as keyout:
|
||||
keyout.write('aes-xts-plain64\n{}\n'.format(key))
|
||||
|
||||
Reference in New Issue
Block a user