mirror of
https://github.com/borgbackup/borg.git
synced 2026-06-09 00:32:37 -04:00
Merge pull request #8971 from ThomasWaldmann/files-changed-option-master
create --files-changed=MODE option
This commit is contained in:
commit
547f7ec338
2 changed files with 46 additions and 11 deletions
|
|
@ -1215,6 +1215,7 @@ class FilesystemObjectProcessors:
|
|||
log_json,
|
||||
iec,
|
||||
file_status_printer=None,
|
||||
files_changed="ctime",
|
||||
):
|
||||
self.metadata_collector = metadata_collector
|
||||
self.cache = cache
|
||||
|
|
@ -1223,6 +1224,7 @@ class FilesystemObjectProcessors:
|
|||
self.process_file_chunks = process_file_chunks
|
||||
self.show_progress = show_progress
|
||||
self.print_file_status = file_status_printer or (lambda *args: None)
|
||||
self.files_changed = files_changed
|
||||
|
||||
self.hlm = HardLinkManager(id_type=tuple, info_type=(list, type(None))) # (dev, ino) -> chunks or None
|
||||
self.stats = Statistics(output_json=log_json, iec=iec) # threading: done by cache (including progress)
|
||||
|
|
@ -1445,21 +1447,37 @@ class FilesystemObjectProcessors:
|
|||
if not is_win32: # TODO for win32
|
||||
with backup_io("fstat2"):
|
||||
st2 = os.fstat(fd)
|
||||
if is_special_file:
|
||||
if self.files_changed == "disabled" or is_special_file:
|
||||
# special files:
|
||||
# - fifos change naturally, because they are fed from the other side. no problem.
|
||||
# - blk/chr devices don't change ctime anyway.
|
||||
pass
|
||||
elif st.st_ctime_ns != st2.st_ctime_ns:
|
||||
# ctime was changed, this is either a metadata or a data change.
|
||||
changed_while_backup = True
|
||||
elif start_reading - TIME_DIFFERS1_NS < st2.st_ctime_ns < end_reading + TIME_DIFFERS1_NS:
|
||||
# this is to treat a very special race condition, see #3536.
|
||||
# - file was changed right before st.ctime was determined.
|
||||
# - then, shortly afterwards, but already while we read the file, the
|
||||
# file was changed again, but st2.ctime is the same due to ctime granularity.
|
||||
# when comparing file ctime to local clock, widen interval by TIME_DIFFERS1_NS.
|
||||
changed_while_backup = True
|
||||
elif self.files_changed == "ctime":
|
||||
if st.st_ctime_ns != st2.st_ctime_ns:
|
||||
# ctime was changed, this is either a metadata or a data change.
|
||||
changed_while_backup = True
|
||||
elif (
|
||||
start_reading - TIME_DIFFERS1_NS < st2.st_ctime_ns < end_reading + TIME_DIFFERS1_NS
|
||||
):
|
||||
# this is to treat a very special race condition, see #3536.
|
||||
# - file was changed right before st.ctime was determined.
|
||||
# - then, shortly afterwards, but already while we read the file, the
|
||||
# file was changed again, but st2.ctime is the same due to ctime granularity.
|
||||
# when comparing file ctime to local clock, widen interval by TIME_DIFFERS1_NS.
|
||||
changed_while_backup = True
|
||||
elif self.files_changed == "mtime":
|
||||
if st.st_mtime_ns != st2.st_mtime_ns:
|
||||
# mtime was changed, this is either a data change.
|
||||
changed_while_backup = True
|
||||
elif (
|
||||
start_reading - TIME_DIFFERS1_NS < st2.st_mtime_ns < end_reading + TIME_DIFFERS1_NS
|
||||
):
|
||||
# this is to treat a very special race condition, see #3536.
|
||||
# - file was changed right before st.mtime was determined.
|
||||
# - then, shortly afterwards, but already while we read the file, the
|
||||
# file was changed again, but st2.mtime is the same due to mtime granularity.
|
||||
# when comparing file mtime to local clock, widen interval by TIME_DIFFERS1_NS.
|
||||
changed_while_backup = True
|
||||
if changed_while_backup:
|
||||
# regular file changed while we backed it up, might be inconsistent/corrupt!
|
||||
if last_try:
|
||||
|
|
|
|||
|
|
@ -262,6 +262,7 @@ class CreateMixIn:
|
|||
log_json=args.log_json,
|
||||
iec=args.iec,
|
||||
file_status_printer=self.print_file_status,
|
||||
files_changed=args.files_changed,
|
||||
)
|
||||
create_inner(archive, cache, fso)
|
||||
else:
|
||||
|
|
@ -611,6 +612,13 @@ class CreateMixIn:
|
|||
it had before a content change happened. This can be used maliciously as well as
|
||||
well-meant, but in both cases mtime based cache modes can be problematic.
|
||||
|
||||
The ``--files-changed`` option controls how Borg detects if a file has changed during backup:
|
||||
- ctime (default): Use ctime to detect changes. This is the safest option.
|
||||
- mtime: Use mtime to detect changes.
|
||||
- disabled: Disable the "file has changed while we backed it up" detection completely.
|
||||
This is not recommended unless you know what you're doing, as it could lead to
|
||||
inconsistent backups if files change during the backup process.
|
||||
|
||||
The mount points of filesystems or filesystem snapshots should be the same for every
|
||||
creation of a new archive to ensure fast operation. This is because the file cache that
|
||||
is used to determine changed files quickly uses absolute filenames.
|
||||
|
|
@ -888,6 +896,15 @@ class CreateMixIn:
|
|||
default=FILES_CACHE_MODE_UI_DEFAULT,
|
||||
help="operate files cache in MODE. default: %s" % FILES_CACHE_MODE_UI_DEFAULT,
|
||||
)
|
||||
fs_group.add_argument(
|
||||
"--files-changed",
|
||||
metavar="MODE",
|
||||
dest="files_changed",
|
||||
action=Highlander,
|
||||
choices=["ctime", "mtime", "disabled"],
|
||||
default="ctime",
|
||||
help="specify how to detect if a file has changed during backup (ctime, mtime, disabled). default: ctime",
|
||||
)
|
||||
fs_group.add_argument(
|
||||
"--read-special",
|
||||
dest="read_special",
|
||||
|
|
|
|||
Loading…
Reference in a new issue