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

Reply via email to