From: Damien Robert Date: Tue, 20 Nov 2012 20:52:45 +0000 (+0100) Subject: save-cmd.py: don't crash when a path disappears between index and save. X-Git-Tag: bup-0.25-rc2~27 X-Git-Url: https://arthur.barton.de/gitweb/?a=commitdiff_plain;h=16f9f9829038f25aec80ebfae3c882a66281e145;p=bup.git save-cmd.py: don't crash when a path disappears between index and save. Protect calls to metadata.from_path() with a try/catch and defer errors via add_error() instead of just crashing. Signed-off-by: Damien Robert [git@tim-riemenschneider.de: rebase to current tmp/pending/meta: since metadata is (now) stored in the index, only 1 of 2 hunks still applies (race condition between reading the file for its content and stat-ing it for metadata).] [rlb@defaultvalue.org: edit commit message; squash file and dir removal fixes into this commit; limit the scope of the try/catch to the from_path() call, and put the remaining code in an else clause.] Signed-off-by: Rob Browning --- diff --git a/cmd/save-cmd.py b/cmd/save-cmd.py index 3f1649a..66d56e2 100755 --- a/cmd/save-cmd.py +++ b/cmd/save-cmd.py @@ -296,8 +296,13 @@ for (transname,ent) in r.filter(extra, wantrecurse=wantrecurse_during): dir_name, fs_path = dirp[0] first_root = dirp[0] # Not indexed, so just grab the FS metadata or use empty metadata. - meta = metadata.from_path(fs_path) if fs_path else metadata.Metadata() - _push(dir_name, meta) + try: + meta = metadata.from_path(fs_path) if fs_path else metadata.Metadata() + except (OSError, IOError), e: + add_error(e) + lastskip_name = dir_name + else: + _push(dir_name, meta) elif first_root != dirp[0]: root_collision = True @@ -309,8 +314,13 @@ for (transname,ent) in r.filter(extra, wantrecurse=wantrecurse_during): for path_component in dirp[len(parts):]: dir_name, fs_path = path_component # Not indexed, so just grab the FS metadata or use empty metadata. - meta = metadata.from_path(fs_path) if fs_path else metadata.Metadata() - _push(dir_name, meta) + try: + meta = metadata.from_path(fs_path) if fs_path else metadata.Metadata() + except (OSError, IOError), e: + add_error(e) + lastskip_name = dir_name + else: + _push(dir_name, meta) if not file: if len(parts) == 1: @@ -381,9 +391,14 @@ for (transname,ent) in r.filter(extra, wantrecurse=wantrecurse_during): shalists[-1].append(git_info) sort_key = git.shalist_item_sort_key((ent.mode, file, id)) hlink = find_hardlink_target(hlink_db, ent) - metalists[-1].append((sort_key, - metadata.from_path(ent.name, - hardlink_target=hlink))) + try: + meta = metadata.from_path(ent.name, hardlink_target=hlink) + except (OSError, IOError), e: + add_error(e) + lastskip_name = ent.name + else: + metalists[-1].append((sort_key, meta)) + if exists and wasmissing: count += oldsize subcount = 0