[PATCH] fsmonitor: be robust in the face of bad state

Mateusz Kwapich mitrandir at fb.com
Fri Nov 25 10:59:43 EST 2016


The logic looks correct. It definitely makes the fsmonitor more robust.

Excerpts from Simon Farnsworth's message of 2016-11-25 07:30:53 -0800:
> # HG changeset patch
> # User Simon Farnsworth <simonfar at fb.com>
> # Date 1480087846 28800
> #      Fri Nov 25 07:30:46 2016 -0800
> # Node ID 0ca34f1b83da754246ee33e01c4f7d6652061f5d
> # Parent  a3163433647108b7bec8fc45896db1c20b18ab21
> fsmonitor: be robust in the face of bad state
> 
> fsmonitor could write out bad state if interrupted part way through, and
> would then crash when it tried to read it back in.
> 
> Make both sides of the operation more robust - reading state should fail
> cleanly, and we can use atomictemp to write out cleanly as the file is
> small. Between the two, we shouldn't crash with an IndexError any more.
> 
> diff --git a/hgext/fsmonitor/state.py b/hgext/fsmonitor/state.py
> --- a/hgext/fsmonitor/state.py
> +++ b/hgext/fsmonitor/state.py
> @@ -59,6 +59,12 @@
>              state = file.read().split('\0')
>              # state = hostname\0clock\0ignorehash\0 + list of files, each
>              # followed by a \0
> +            if len(state) < 3:
> +                self._ui.log(
> +                    'fsmonitor', 'fsmonitor: state file truncated (expected '
> +                    '3 chunks, found %d), nuking state\n' % len(state))
> +                self.invalidate()
> +                return None, None, None
>              diskhostname = state[0]
>              hostname = socket.gethostname()
>              if diskhostname != hostname:
> @@ -85,12 +91,12 @@
>              return
>  
>          try:
> -            file = self._opener('fsmonitor.state', 'wb')
> +            file = self._opener('fsmonitor.state', 'wb', atomictemp=True)
>          except (IOError, OSError):
>              self._ui.warn(_("warning: unable to write out fsmonitor state\n"))
>              return
>  
> -        try:
> +        with file:
>              file.write(struct.pack(_versionformat, _version))
>              file.write(socket.gethostname() + '\0')
>              file.write(clock + '\0')
> @@ -98,8 +104,6 @@
>              if notefiles:
>                  file.write('\0'.join(notefiles))
>                  file.write('\0')
> -        finally:
> -            file.close()
>  
>      def invalidate(self):
>          try:

-- 


More information about the Mercurial-devel mailing list