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
|
return out
|
||||||
except exception.ProcessExecutionError:
|
except exception.ProcessExecutionError:
|
||||||
raise exception.FileNotFound(file_path=file_path)
|
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"),
|
"virtual_size=%(virtual_size)d block_size=%(block_size)d"),
|
||||||
locals())
|
locals())
|
||||||
|
|
||||||
with open(src_path, "r") as src:
|
# NOTE(sirp): we need read/write access to the devices; since we don't have
|
||||||
with open(dst_path, "w") as dst:
|
# the luxury of shelling out to a sudo'd command, we temporarily take
|
||||||
data = src.read(min(block_size, left))
|
# ownership of the devices.
|
||||||
while data:
|
with utils.temporary_chown(src_path):
|
||||||
if data == EMPTY_BLOCK:
|
with utils.temporary_chown(dst_path):
|
||||||
dst.seek(block_size, os.SEEK_CUR)
|
with open(src_path, "r") as src:
|
||||||
left -= block_size
|
with open(dst_path, "w") as dst:
|
||||||
bytes_read += block_size
|
data = src.read(min(block_size, left))
|
||||||
skipped_bytes += block_size
|
while data:
|
||||||
else:
|
if data == EMPTY_BLOCK:
|
||||||
dst.write(data)
|
dst.seek(block_size, os.SEEK_CUR)
|
||||||
data_len = len(data)
|
left -= block_size
|
||||||
left -= data_len
|
bytes_read += block_size
|
||||||
bytes_read += data_len
|
skipped_bytes += block_size
|
||||||
|
else:
|
||||||
|
dst.write(data)
|
||||||
|
data_len = len(data)
|
||||||
|
left -= data_len
|
||||||
|
bytes_read += data_len
|
||||||
|
|
||||||
if left <= 0:
|
if left <= 0:
|
||||||
break
|
break
|
||||||
|
|
||||||
data = src.read(min(block_size, left))
|
data = src.read(min(block_size, left))
|
||||||
|
|
||||||
duration = time.time() - start_time
|
duration = time.time() - start_time
|
||||||
compression_pct = float(skipped_bytes) / bytes_read * 100
|
compression_pct = float(skipped_bytes) / bytes_read * 100
|
||||||
|
Reference in New Issue
Block a user