On Tue, 2011-10-11 at 08:34:48 +0200, Raphael Hertzog wrote:
> On Mon, 10 Oct 2011, Guillem Jover wrote:
> > The correct solution would be to lock a file we know must be there, so
> > that there's no race condition and no possible cruft leftover. For
> > example debian/control or debian/changelog (or the file arguments
> > specified on the command line).
> 
> What do you mean with "file arguments"? if you mean "debian/files" then
> it won't work as that file is replaced with rename() so we're back to the
> initial situation where you can have a lock on the now deleted/replaced
> file.

I meant the arguments to options -c or -l.

> Using debian/control would work but it doesn't seem very clean.

Well it seems to be in theory the most correct, simple and clean
solution to me (except for perl making things difficult in general).
A file known to exist is just being used for locking, nothing more.
All other solutions just seem inferior in one way or another.

> > Also we should be using fcntl(2) instead of flock(2) to get NFS support,
> > but this seems tricky on perl?
> 
> Not really, it's a built-in function on systems that support it. The
> question is whether we have to care about systems that do not support it.

I'm assuming you mean it's not tricky. But to lock using fcntl(2) the
function needs a struct flock which would need to be packed from the
perl code, but the order of its members is not standardized anywhere,
and sizeof(off_t) might vary, that's what seems tricky to me. About the
system supporting fcntl(2), well it must, otherwise dpkg itself will
not work.

The easy solution to this would seem to be to package something like
the perl File::FcntlLock module:

  <http://search.cpan.org/~jtt/File-FcntlLock-0.12/>

I also considered as a possibility rewritting dpkg-distaddfile in C
or creating a trival C helper to update debian/files, which I started
locally but discared as it seems File::FcntlLock is a way way better
solution, better even than reinventing ourselves such XS perl module,
and avoids needing to create a new arch:any package to put any of
those in.

> Perl's flock() is the recommended interface because it will use whatever
> is supported among flock(), fnctl() and lockf() so it's more
> portable.

Availability of the interface here is not an issue as mentioned before
dpkg just needs fcntl(2), but portability is, given that we cannot
just hardcode struct flock layout in the perl code. Also using perl's
flock makes it an unreliable interface as it depends on what perl is
going to use internally, and it might end up using the wrong underlying
interface.

> I have another idea to propose. Create "debian/files.new" with
> O_CREAT|O_EXCL and if it fails with EEXIST, sleep for Xms and try again.
> It's not optimal in the sense that we're not going to sleep
> exactly the required amount of time, but at least it doesn't involve
> messing with unrelated files.

Besides the loop being somewhat suboptimal, usage of “O_CREAT | O_EXCL”
on NFS might be unreliable.

> A third solution would be to use semaphores...

A semaphore is inherently not going to work on NFS, being it a local
resource. In addition even if we ignore the NFS issue it would need to
be unique per source directory, which means we'd need to encode that
somehow reliably for SysV semaphores. And POSIX semaphores which allow
path-style names (although the name might have a lower limit than
NAME_MAX or PATH_MAX) do not seem to be supported by perl, which would
make this solution undesirable.

regards,
guillem



--
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