On Aug 14, 2013 7:21 PM, "Mattias Andrée" <[email protected]> wrote: > > That is ridiculus that NFS does not implement flock, but > there is a solution documented in flock(2): > > flock() does not lock files over NFS. Use fcntl(2) > instead: that does work over NFS, given a sufficiently > recent version of Linux and a server which supports locking.
Keyword being Linux. We support BSD and OSX as well. fcntl semantics aren't portable. Again, you're not the first to go down this road. > > > On Wed, 14 Aug 2013 18:14:20 -0400 > Dave Reisner <[email protected]> wrote: > > > On Thu, Aug 15, 2013 at 12:03:33AM +0200, Mattias Andrée > > wrote: > > > This allows for further improvement of pacman where > > > shared locks could also be used, in cases there pacman > > > only reads the database and does not edit it. > > > > > > File locks also makes it easy to let pacman wait until > > > the block instance has finished, by just not using the > > > LOCK_NB flag. --- > > > > And the question that comes up every time this patch > > arises: what about NFS? > > > > No, we won't change this. > > > > > lib/libalpm/be_sync.c | 5 +---- > > > lib/libalpm/handle.c | 26 > > > ++++++++++++++------------ > > > lib/libalpm/handle.h | 2 +- > > > lib/libalpm/trans.c | 7 +------ > > > scripts/pacman-db-upgrade.sh.in | 9 +++++---- > > > scripts/pacman-optimize.sh.in | 9 +++++---- 6 files > > > changed, 27 insertions(+), 31 deletions(-) > > > > > > diff --git a/lib/libalpm/be_sync.c > > > b/lib/libalpm/be_sync.c index 0b99684..e7c8c4b 100644 > > > --- a/lib/libalpm/be_sync.c > > > +++ b/lib/libalpm/be_sync.c > > > @@ -284,10 +284,7 @@ int SYMEXPORT alpm_db_update(int > > > force, alpm_db_t *db) > > > cleanup: > > > > > > - if(_alpm_handle_unlock(handle)) { > > > - _alpm_log(handle, ALPM_LOG_WARNING, > > > _("could not remove lock file %s\n"), > > > - handle->lockfile); > > > - } > > > + _alpm_handle_unlock(handle); > > > free(syncpath); > > > umask(oldmask); > > > return ret; > > > diff --git a/lib/libalpm/handle.c b/lib/libalpm/handle.c > > > index 53c86c5..5d1cfb7 100644 > > > --- a/lib/libalpm/handle.c > > > +++ b/lib/libalpm/handle.c > > > @@ -27,6 +27,7 @@ > > > #include <sys/types.h> > > > #include <syslog.h> > > > #include <sys/stat.h> > > > +#include <sys/file.h> > > > #include <fcntl.h> > > > > > > /* libalpm */ > > > @@ -44,6 +45,7 @@ alpm_handle_t *_alpm_handle_new(void) > > > > > > CALLOC(handle, 1, sizeof(alpm_handle_t), > > > return NULL); handle->deltaratio = 0.0; > > > + handle->lckstream = -1; > > > > > > return handle; > > > } > > > @@ -95,7 +97,7 @@ int _alpm_handle_lock(alpm_handle_t > > > *handle) char *dir, *ptr; > > > > > > ASSERT(handle->lockfile != NULL, return -1); > > > - ASSERT(handle->lckstream == NULL, return 0); > > > + ASSERT(handle->lckstream < 0, return 0); > > > > > > /* create the dir of the lockfile first */ > > > dir = strdup(handle->lockfile); > > > @@ -110,14 +112,14 @@ int > > > _alpm_handle_lock(alpm_handle_t *handle) FREE(dir); > > > > > > do { > > > - fd = open(handle->lockfile, O_WRONLY | > > > O_CREAT | O_EXCL, 0000); > > > + fd = open(handle->lockfile, O_WRONLY | > > > O_CREAT); } while(fd == -1 && errno == EINTR); > > > if(fd >= 0) { > > > - FILE *f = fdopen(fd, "w"); > > > - fprintf(f, "%ld\n", (long)getpid()); > > > - fflush(f); > > > fsync(fd); > > > - handle->lckstream = f; > > > + if(flock(fd, LOCK_EX | LOCK_NB) < 0) { > > > + return -1; > > > + } > > > + handle->lckstream = fd; > > > return 0; > > > } > > > return -1; > > > @@ -127,14 +129,14 @@ int > > > _alpm_handle_lock(alpm_handle_t *handle) int > > > _alpm_handle_unlock(alpm_handle_t *handle) { > > > ASSERT(handle->lockfile != NULL, return -1); > > > - ASSERT(handle->lckstream != NULL, return 0); > > > - > > > - fclose(handle->lckstream); > > > - handle->lckstream = NULL; > > > + ASSERT(handle->lckstream >= 0, return 0); > > > > > > - if(unlink(handle->lockfile) && errno != > > > ENOENT) { > > > - return -1; > > > + flock(handle->lckstream, LOCK_UN); > > > + if(flock(handle->lckstream, LOCK_EX | LOCK_NB) > > > == 0) { > > > + unlink(handle->lockfile); > > > + flock(handle->lckstream, LOCK_UN); > > > } > > > + handle->lckstream = NULL; > > > return 0; > > > } > > > > > > diff --git a/lib/libalpm/handle.h b/lib/libalpm/handle.h > > > index 5e84d58..7ca90ff 100644 > > > --- a/lib/libalpm/handle.h > > > +++ b/lib/libalpm/handle.h > > > @@ -55,7 +55,7 @@ struct __alpm_handle_t { > > > alpm_db_t *db_local; /* local db pointer > > > */ alpm_list_t *dbs_sync; /* List of (alpm_db_t *) */ > > > FILE *logstream; /* log file stream > > > pointer */ > > > - FILE *lckstream; /* lock file stream > > > pointer if one exists */ > > > + int lckstream; /* lock file file > > > descriptor if one exists */ alpm_trans_t *trans; > > > > > > #ifdef HAVE_LIBCURL > > > diff --git a/lib/libalpm/trans.c b/lib/libalpm/trans.c > > > index 8d4e0e7..122f35b 100644 > > > --- a/lib/libalpm/trans.c > > > +++ b/lib/libalpm/trans.c > > > @@ -215,12 +215,7 @@ int SYMEXPORT > > > alpm_trans_release(alpm_handle_t *handle) > > > /* unlock db */ > > > if(!nolock_flag) { > > > - if(_alpm_handle_unlock(handle)) { > > > - _alpm_log(handle, > > > ALPM_LOG_WARNING, _("could not remove lock file %s\n"), > > > - > > > handle->lockfile); > > > - alpm_logaction(handle, > > > ALPM_CALLER_PREFIX, > > > - "warning: could not > > > remove lock file %s\n", handle->lockfile); > > > - } > > > + _alpm_handle_unlock(handle); > > > } > > > > > > return 0; > > > diff --git a/scripts/pacman-db-upgrade.sh.in > > > b/scripts/pacman-db-upgrade.sh.in index > > > a1630c5..20cf035 100644 --- > > > a/scripts/pacman-db-upgrade.sh.in +++ > > > b/scripts/pacman-db-upgrade.sh.in @@ -102,12 +102,12 @@ > > > dbroot="${dbroot%/}" # form the path to our lockfile > > > location lockfile="${dbroot}/db.lck" > > > > > > -# make sure pacman isn't running > > > -if [[ -f $lockfile ]]; then > > > +# make sure pacman isn't running and stop other > > > instances for starting +exec 100<>"$lockfile" > > > +if ! flock -x --nonblock 100; then > > > + flock --close 100 > > > die "$(gettext "Pacman lock file was found. > > > Cannot run while pacman is running.")" fi > > > -# do not let pacman run while we do this > > > -touch "$lockfile" > > > > > > # pacman-3.4 to 3.5 upgrade - merge depends into desc > > > if [[ $(find "$dbroot"/local -name depends) ]]; then > > > @@ -123,5 +123,6 @@ fi > > > > > > # remove the lock file > > > rm -f "$lockfile" > > > +flock --close 100 > > > > > > # vim: set ts=2 sw=2 noet: > > > diff --git a/scripts/pacman-optimize.sh.in > > > b/scripts/pacman-optimize.sh.in index 47fbb49..8c6e556 > > > 100644 --- a/scripts/pacman-optimize.sh.in > > > +++ b/scripts/pacman-optimize.sh.in > > > @@ -114,12 +114,12 @@ dbroot="${dbroot%/}" > > > lockfile="${dbroot}/db.lck" > > > localdb="${dbroot}/local" > > > > > > -# make sure pacman isn't running > > > -if [[ -f $lockfile ]]; then > > > +# make sure pacman isn't running and stop other > > > instances for starting +exec 100<>"$lockfile" > > > +if ! flock -x --nonblock 100; then > > > + flock --close 100 > > > die "$(gettext "Pacman lock file was found. > > > Cannot run while pacman is running.")" fi > > > -# do not let pacman run while we do this > > > -touch "$lockfile" > > > > > > workdir=$(mktemp -d > > > "${TMPDIR:-/tmp}/pacman-optimize.XXXXXXXXXX") || die_r > > > "$(gettext "Can not create temp directory for database > > > building.")\n" >&2 @@ -178,6 +178,7 @@ rm -rf > > > "$localdb.old" # remove the lock file and our working > > > directory with sums and tarfile rm -f "$lockfile" > > > +flock --close 100 > > > rm -rf "$workdir" > > > > > > echo > > > -- > > > 1.8.3.4 > > > > > > > > > >
