Merge "Adds temporary chown to sparse_copy."
This commit is contained in:
@@ -1523,3 +1523,23 @@ def read_file_as_root(file_path):
|
||||
return out
|
||||
except exception.ProcessExecutionError:
|
||||
raise exception.FileNotFound(file_path=file_path)
|
||||
|
||||
|
||||
@contextlib.contextmanager
|
||||
def temporary_chown(path, owner_uid=None):
|
||||
"""Temporarily chown a path.
|
||||
|
||||
:params owner_uid: UID of temporary owner (defaults to current user)
|
||||
"""
|
||||
if owner_uid is None:
|
||||
owner_uid = os.getuid()
|
||||
|
||||
orig_uid = os.stat(path).st_uid
|
||||
|
||||
if orig_uid != owner_uid:
|
||||
execute('chown', owner_uid, path, run_as_root=True)
|
||||
try:
|
||||
yield
|
||||
finally:
|
||||
if orig_uid != owner_uid:
|
||||
execute('chown', orig_uid, path, run_as_root=True)
|
||||
|
@@ -1651,25 +1651,30 @@ def _sparse_copy(src_path, dst_path, virtual_size, block_size=4096):
|
||||
"virtual_size=%(virtual_size)d block_size=%(block_size)d"),
|
||||
locals())
|
||||
|
||||
with open(src_path, "r") as src:
|
||||
with open(dst_path, "w") as dst:
|
||||
data = src.read(min(block_size, left))
|
||||
while data:
|
||||
if data == EMPTY_BLOCK:
|
||||
dst.seek(block_size, os.SEEK_CUR)
|
||||
left -= block_size
|
||||
bytes_read += block_size
|
||||
skipped_bytes += block_size
|
||||
else:
|
||||
dst.write(data)
|
||||
data_len = len(data)
|
||||
left -= data_len
|
||||
bytes_read += data_len
|
||||
# NOTE(sirp): we need read/write access to the devices; since we don't have
|
||||
# the luxury of shelling out to a sudo'd command, we temporarily take
|
||||
# ownership of the devices.
|
||||
with utils.temporary_chown(src_path):
|
||||
with utils.temporary_chown(dst_path):
|
||||
with open(src_path, "r") as src:
|
||||
with open(dst_path, "w") as dst:
|
||||
data = src.read(min(block_size, left))
|
||||
while data:
|
||||
if data == EMPTY_BLOCK:
|
||||
dst.seek(block_size, os.SEEK_CUR)
|
||||
left -= block_size
|
||||
bytes_read += block_size
|
||||
skipped_bytes += block_size
|
||||
else:
|
||||
dst.write(data)
|
||||
data_len = len(data)
|
||||
left -= data_len
|
||||
bytes_read += data_len
|
||||
|
||||
if left <= 0:
|
||||
break
|
||||
if left <= 0:
|
||||
break
|
||||
|
||||
data = src.read(min(block_size, left))
|
||||
data = src.read(min(block_size, left))
|
||||
|
||||
duration = time.time() - start_time
|
||||
compression_pct = float(skipped_bytes) / bytes_read * 100
|
||||
|
Reference in New Issue
Block a user