Subject: bug#14579: locking breaks across filesystems

From: Amitai Schlair <[email-masked]>
Date: Sat, 8 Jun 2013 14:06:57 -0400

What I tried:

On Mac OS X 10.6.8 (Darwin 10.8.0) with Xcode 3.2.5, fetch and extract
pkgsrc into a dedicated disk partition. Using pkgsrc, build and
install libtool 2.4.2 to the root partition. Using pkgsrc, try
building and installing software that uses libtool.

What I expected to happen:

Succeed at building and installing software that uses libtool.

What actually happened:

Fail, like so (in this example, pkg-config):

[...]
  CC       gprintf.lo
  CC       glib-unix.lo
  CC       gthread-posix.lo
  CC       giounix.lo
  CC       gspawn.lo
  CCLD     libglib-2.0.la
libtool: link: Waiting for
/Volumes/pkgsrc/current/devel/pkg-config/work.ap-juicer/pkg-config-0.28/glib/glib/libcharset/.libs/libcharset.a.lock
to be removed
libtool: link: Waiting for
/Volumes/pkgsrc/current/devel/pkg-config/work.ap-juicer/pkg-config-0.28/glib/glib/libcharset/.libs/libcharset.a.lock
to be removed
libtool: link: Waiting for
/Volumes/pkgsrc/current/devel/pkg-config/work.ap-juicer/pkg-config-0.28/glib/glib/libcharset/.libs/libcharset.a.lock
to be removed
[repeats forever]

What I've figured out so far:

* The error message comes from func_extract_an_archive() (and not the
other occurrence of "to be removed").

* It's conditionalized on lock_old_archive_extraction being "yes",
which is true only on Darwin.

* It attempts to create a lockfile as a hardlink to libtool itself,
which fails when the installed libtool is not on the same filesystem
as the source being built.

* It assumes the only reason the hardlink could fail is the target
already existing.

* When it fails for any other reason, a wrong conclusion goes to
stderr, the real error goes to /dev/null, and we're stuck in an
infinite loop.

* If I set lock_old_archive_extraction=no, everything works as
expected in my limited testing.

What I haven't figured out, and am asking you to:

* What Darwin-specific problem is lock_old_archive_extraction trying
to prevent? I see that the variable was introduced 2009-06-10,
accompanied by an automated test to verify that convenience archive
extraction works concurrently. I couldn't figure out at a glance how
to run that test, so I'm not sure whether a working
lock_old_archive_extraction would have done me any good. What have I
broken on my Darwin system by setting it to "no"? In what context is
it still needed? (I'm guessing there is one, but if it turns out there
isn't, removing lock_old_archive_extraction and related codepaths
would solve my problem.)

* Can the locking code (if it needs to live) print the actual error
when there is one, so that future problems are less confusing?

* Can the locking code (if it needs to live) either work entirely
within the build area or not rely on hardlinks, so that it works in a
filesystem configuration like mine?

Thank you for libtool and for reading this bug report!