Package: ifupdown
Version: 0.7.40

Every so often, parallel invocations of ifup (for example, by Upstart)
will clobber each other's tmpstatefile in update_state(), causing the
loser(s) to fail.

update_state() opens the statefile, gets a F_SETLKW lock on it, opens a
tmpfile, filters the contents of the statefile into the tmpfile, closes
the tmpfile, then renames the tmpfile over the statefile.

Once the rename() happens in one instance of ifup, any other blocked
instances are waiting around to lock a file that no longer exists in the
filesystem. Overlap enough instances of ifup just right and you have
them all locking different copies of statefile, which then doesn't
prevent any of them from rename()ing tmpstatefile out from underneath
the others, thus causing their own rename()s to fail with ENOENT.

Example:

Process A starts, opens statefile.
Process A locks statefile.
Process B starts, opens statefile.
Process B waits for lock on statefile.
Process A renames tmpstatefile to statefile and exits.
Process B acquires lock on *outdated* statefile FILE pointer.
Process C starts, opens current statefile (written by Process A).
Process C locks current statefile.
** Two ifups now have locks **
Process B renames tmpstatefile to statefile and exits.
Process C tries to rename tmpstatefile, fails because tmpstatefile has
already been renamed out from under it by Process B.

NOTE: Since Process B was operating on an outdated statefile, it has
also stomped over any changes made by Process A, so simply making the
tmpstatefile process-specific to avoid rename()ing out from under each
other won't help.

Suggested fix:  Lock a lockfile, not the statefile.


--
To UNSUBSCRIBE, email to debian-bugs-dist-requ...@lists.debian.org
with a subject of "unsubscribe". Trouble? Contact listmas...@lists.debian.org

Reply via email to