Skip to content

Commit

Permalink
Open block devices in qubesd
Browse files Browse the repository at this point in the history
This makes race conditions (e.g. against udev) more obviously
impossible.  It also allows perfoming verification steps on the block
device if that becomes necessary in the future.
  • Loading branch information
DemiMarie committed Apr 1, 2022
1 parent 067b493 commit b04d611
Showing 1 changed file with 31 additions and 23 deletions.
54 changes: 31 additions & 23 deletions qubes/backup.py
Original file line number Diff line number Diff line change
Expand Up @@ -640,29 +640,37 @@ async def _wrap_and_send_files(self, files_to_backup, output_queue):
os.path.basename(path)
])
file_stat = os.stat(path)
if stat.S_ISBLK(file_stat.st_mode) or \
file_info.name != os.path.basename(path):
# tar doesn't handle content of block device, use our
# writer
# also use our tar writer when renaming file
assert not stat.S_ISDIR(file_stat.st_mode), \
"Renaming directories not supported"
tar_cmdline = ['python3', '-m', 'qubes.tarwriter',
'--override-name=%s' % (
os.path.join(file_info.subdir, os.path.basename(
file_info.name))),
path]
if self.compressed:
tar_cmdline.insert(-2,
"--use-compress-program=%s" % self.compression_filter)

self.log.debug(" ".join(tar_cmdline))

# Pipe: tar-sparse | scrypt | tar | backup_target
# TODO: log handle stderr
# pylint: disable=not-an-iterable
tar_sparse = await asyncio.create_subprocess_exec(
*tar_cmdline, stdout=subprocess.PIPE)
fd_to_close = None
subprocess_kwargs = {'stdout': subprocess.PIPE}
try:
if stat.S_ISBLK(file_stat.st_mode) or \
file_info.name != os.path.basename(path):
# tar doesn't handle content of block device, use our
# writer
# also use our tar writer when renaming file
assert not stat.S_ISDIR(file_stat.st_mode), \
"Renaming directories not supported"
# pylint: disable=line-too-long
fd_to_close = os.open(path, os.O_RDONLY | os.O_NOCTTY | os.O_CLOEXEC)
subprocess_kwargs['stdin'] = fd_to_close
tar_cmdline = ['python3', '-m', 'qubes.tarwriter',
'--override-name=%s' % (
os.path.join(subdir, os.path.basename(
file_info.name))),
'/proc/self/fd/0']
if self.compressed:
tar_cmdline.insert(-2,
"--use-compress-program=" + self.compression_filter)

# Pipe: tar-sparse | scrypt | tar | backup_target
# TODO: log handle stderr
# pylint: disable=not-an-iterable
tar_sparse = await asyncio.create_subprocess_exec(
*tar_cmdline, **subprocess_kwargs)
finally:
if fd_to_close is not None:
os.close(fd_to_close)
del fd_to_close, subprocess_kwargs

try:
await self._split_and_send(
Expand Down

0 comments on commit b04d611

Please sign in to comment.