From 097a09578a8050cfe6ee7737e9b8e9c88e512945 Mon Sep 17 00:00:00 2001 From: Dan Helfman Date: Tue, 26 May 2020 09:20:14 -0700 Subject: [PATCH] Fix enabled database hooks to implicitly set one_file_system configuration option to true to prevent Borg hang. (#315). --- NEWS | 2 ++ borgmatic/borg/create.py | 6 +++++- borgmatic/config/schema.yaml | 17 +++++++++++++---- docs/how-to/backup-your-databases.md | 4 ++++ tests/unit/borg/test_create.py | 5 +++-- 5 files changed, 27 insertions(+), 7 deletions(-) diff --git a/NEWS b/NEWS index 8f61e42..a70f440 100644 --- a/NEWS +++ b/NEWS @@ -1,6 +1,8 @@ 1.5.5.dev0 * #314: Fix regression in support for PostgreSQL's "directory" dump format. Unlike other dump formats, the "directory" dump format does not stream directly to/from Borg. + * #315: Fix enabled database hooks to implicitly set one_file_system configuration option to true. + This prevents Borg from reading devices like /dev/zero and hanging. * #316: Fix hang when streaming a database dump to Borg with implicit duplicate source directories by deduplicating them first. * #319: Fix error message when there are no MySQL databases to dump for "all" databases. diff --git a/borgmatic/borg/create.py b/borgmatic/borg/create.py index 5cb720f..80e0d7d 100644 --- a/borgmatic/borg/create.py +++ b/borgmatic/borg/create.py @@ -207,7 +207,11 @@ def create_archive( + (('--chunker-params', chunker_params) if chunker_params else ()) + (('--compression', compression) if compression else ()) + (('--remote-ratelimit', str(remote_rate_limit)) if remote_rate_limit else ()) - + (('--one-file-system',) if location_config.get('one_file_system') else ()) + + ( + ('--one-file-system',) + if location_config.get('one_file_system') or stream_processes + else () + ) + (('--numeric-owner',) if location_config.get('numeric_owner') else ()) + (('--noatime',) if location_config.get('atime') is False else ()) + (('--noctime',) if location_config.get('ctime') is False else ()) diff --git a/borgmatic/config/schema.yaml b/borgmatic/config/schema.yaml index a228e7a..b8d5dea 100644 --- a/borgmatic/config/schema.yaml +++ b/borgmatic/config/schema.yaml @@ -30,7 +30,10 @@ map: - user@backupserver:sourcehostname.borg one_file_system: type: bool - desc: Stay in same file system (do not cross mount points). Defaults to false. + desc: | + Stay in same file system (do not cross mount points). Defaults to false. But when + a database hook is used, the setting here is ignored and one_file_system is + considered true. example: true numeric_owner: type: bool @@ -53,7 +56,9 @@ map: desc: | Use Borg's --read-special flag to allow backup of block and other special devices. Use with caution, as it will lead to problems if used when - backing up special devices such as /dev/zero. Defaults to false. + backing up special devices such as /dev/zero. Defaults to false. But when a + database hook is used, the setting here is ignored and read_special is + considered true. example: false bsd_flags: type: bool @@ -452,7 +457,9 @@ map: type: str desc: | Database name (required if using this hook). Or "all" to dump all - databases on the host. + databases on the host. Note that using this database hook implicitly + enables both read_special and one_file_system (see above) to support + dump and restore streaming. example: users hostname: type: str @@ -508,7 +515,9 @@ map: type: str desc: | Database name (required if using this hook). Or "all" to dump all - databases on the host. + databases on the host. Note that using this database hook implicitly + enables both read_special and one_file_system (see above) to support + dump and restore streaming. example: users hostname: type: str diff --git a/docs/how-to/backup-your-databases.md b/docs/how-to/backup-your-databases.md index 80769d4..0c66015 100644 --- a/docs/how-to/backup-your-databases.md +++ b/docs/how-to/backup-your-databases.md @@ -31,6 +31,10 @@ To support this, borgmatic creates temporary named pipes in `~/.borgmatic` by default. To customize this path, set the `borgmatic_source_directory` option in the `location` section of borgmatic's configuration. +Also note that using a database hook implicitly enables both the +`read_special` and `one_file_system` configuration settings (even if they're +disabled in your configuration) to support this dump and restore streaming. + Here's a more involved example that connects to remote databases: ```yaml diff --git a/tests/unit/borg/test_create.py b/tests/unit/borg/test_create.py index 0685953..731ad6e 100644 --- a/tests/unit/borg/test_create.py +++ b/tests/unit/borg/test_create.py @@ -1064,7 +1064,8 @@ def test_create_archive_with_progress_and_stream_processes_calls_borg_with_progr flexmock(module).should_receive('_make_pattern_flags').and_return(()) flexmock(module).should_receive('_make_exclude_flags').and_return(()) flexmock(module).should_receive('execute_command_with_processes').with_args( - ('borg', 'create', '--read-special', '--progress') + ARCHIVE_WITH_PATHS, + ('borg', 'create', '--one-file-system', '--read-special', '--progress') + + ARCHIVE_WITH_PATHS, processes=processes, output_log_level=logging.INFO, output_file=module.DO_NOT_CAPTURE, @@ -1320,7 +1321,7 @@ def test_create_archive_with_stream_processes_calls_borg_with_processes(): flexmock(module).should_receive('_make_pattern_flags').and_return(()) flexmock(module).should_receive('_make_exclude_flags').and_return(()) flexmock(module).should_receive('execute_command_with_processes').with_args( - ('borg', 'create', '--read-special') + ARCHIVE_WITH_PATHS, + ('borg', 'create', '--one-file-system', '--read-special') + ARCHIVE_WITH_PATHS, processes=processes, output_log_level=logging.INFO, output_file=None,