Mercurial > public > mercurial-scm > hg-stable
comparison mercurial/util.py @ 13204:5b83ab614dab stable
checknlink: use two testfiles (issue2543)
Preventing file loss repository corruption (e.g. vanished changelog.i) when
Mercurial pushes to repositories on Windows shares served by Samba.
This is a workaround for Samba bug 7863, which is present in current latest
stable Samba 3.5.6 and various prior versions down to 3.0.26a (the oldest one
I tested).
Of course this should be fixed in Samba, but there probably aren't that many
other applications who use hardlinks that extensively and keep files open like
Mercurial, so the pressure to fix this on Samba is probably not that high. And
even if the Samba project should be able to fix their bug within a month or
two, it will take quite some time until users upgrade their Samba installs.
author | Adrian Buehlmann <adrian@cadifra.com> |
---|---|
date | Mon, 13 Dec 2010 22:38:06 +0100 |
parents | 6c9345f9edca |
children | 18f0084a97c8 5d0a30fad7de |
comparison
equal
deleted
inserted
replaced
13203:aa72ff5abf5f | 13204:5b83ab614dab |
---|---|
715 except (OSError, AttributeError): | 715 except (OSError, AttributeError): |
716 return False | 716 return False |
717 | 717 |
718 def checknlink(testfile): | 718 def checknlink(testfile): |
719 '''check whether hardlink count reporting works properly''' | 719 '''check whether hardlink count reporting works properly''' |
720 f = testfile + ".hgtmp" | 720 |
721 | 721 # testfile may be open, so we need a separate file for checking to |
722 try: | 722 # work around issue2543 (or testfile may get lost on Samba shares) |
723 os_link(testfile, f) | 723 f1 = testfile + ".hgtmp1" |
724 except OSError: | 724 if os.path.lexists(f1): |
725 return False | 725 return False |
726 | 726 try: |
727 try: | 727 posixfile(f1, 'w').close() |
728 except IOError: | |
729 return False | |
730 | |
731 f2 = testfile + ".hgtmp2" | |
732 fd = None | |
733 try: | |
734 try: | |
735 os_link(f1, f2) | |
736 except OSError: | |
737 return False | |
738 | |
728 # nlinks() may behave differently for files on Windows shares if | 739 # nlinks() may behave differently for files on Windows shares if |
729 # the file is open. | 740 # the file is open. |
730 fd = open(f) | 741 fd = open(f2) |
731 return nlinks(f) > 1 | 742 return nlinks(f2) > 1 |
732 finally: | 743 finally: |
733 fd.close() | 744 if fd is not None: |
734 os.unlink(f) | 745 fd.close() |
746 for f in (f1, f2): | |
747 try: | |
748 os.unlink(f) | |
749 except OSError: | |
750 pass | |
735 | 751 |
736 return False | 752 return False |
737 | 753 |
738 def endswithsep(path): | 754 def endswithsep(path): |
739 '''Check path ends with os.sep or os.altsep.''' | 755 '''Check path ends with os.sep or os.altsep.''' |