[sheepdog] [RESEND PATCH v2 1/2] cluster/local: support lock/unlock

Liu Yuan namei.unix at gmail.com
Wed Dec 18 13:53:58 CET 2013


On Wed, Dec 18, 2013 at 08:48:34PM +0800, Liu Yuan wrote:
> Signed-off-by: Liu Yuan <namei.unix at gmail.com>
> ---
>  sheep/cluster/local.c |   61 +++++++++++++++++++++++++++++++++++++++++++++++--
>  1 file changed, 59 insertions(+), 2 deletions(-)
> 
> diff --git a/sheep/cluster/local.c b/sheep/cluster/local.c
> index 6d0af68..5c27908 100644
> --- a/sheep/cluster/local.c
> +++ b/sheep/cluster/local.c
> @@ -16,6 +16,7 @@
>  #include <sys/file.h>
>  #include <signal.h>
>  #include <fcntl.h>
> +#include <limits.h>
>  
>  #include "cluster.h"
>  #include "event.h"
> @@ -27,6 +28,10 @@
>  #define LOCAL_MAX_NODES 1024
>  
>  static const char *shmfile = "/tmp/sheepdog_shm";
> +static const char *lockdir = "/tmp/sheepdog_locks/";
> +/* we have to use sd_lock because flock isn't thread exclusive */
> +static struct sd_lock lock = SD_LOCK_INITIALIZER;
> +
>  static int shmfd;
>  static int sigfd;
>  static int block_event_pos;
> @@ -99,14 +104,25 @@ static inline void node_insert(struct sd_node *new, struct rb_root *root)
>  		panic("insert duplicate %s", node_to_str(new));
>  }
>  
> +static int xflock(int fd, int operation)
> +{
> +	int ret;
> +
> +	do {
> +		ret = flock(fd, operation);
> +	} while (ret < 0 && (errno == EAGAIN || errno == EINTR));
> +
> +	return ret;
> +}
> +
>  static void shm_queue_lock(void)
>  {
> -	flock(shmfd, LOCK_EX);
> +	xflock(shmfd, LOCK_EX);
>  }
>  
>  static void shm_queue_unlock(void)
>  {
> -	flock(shmfd, LOCK_UN);
> +	xflock(shmfd, LOCK_UN);
>  }
>  
>  static size_t get_nodes(struct local_node *n)
> @@ -544,15 +560,56 @@ static int local_init(const char *option)
>  		return -1;
>  	}
>  
> +	ret = xmkdir(lockdir, sd_def_dmode);
> +	if (ret < 0) {
> +		sd_err("failed to create lockdir %s, %m", lockdir);
> +		return -1;
> +	}
> +
> +	ret = purge_directory(lockdir);
> +	if (ret < 0) {
> +		sd_err("failed to purge lockdir %s, %m", lockdir);
> +		return -1;
> +	}
> +
>  	return 0;
>  }
>  
>  static void local_lock(uint64_t lock_id)
>  {
> +	char path[PATH_MAX];
> +	int fd;
> +
> +	sd_write_lock(&lock);
> +	snprintf(path, sizeof(path), "%s%016"PRIx64, lockdir, lock_id);
> +	fd = open(path, O_RDONLY | O_CREAT | O_EXCL, sd_def_fmode);
> +	if (fd < 0) {
> +		if (unlikely(errno != EEXIST))
> +			panic("failed to open %s, %m", path);
> +		fd = open(path, O_RDONLY, sd_def_fmode);
> +		if (fd < 0)
> +			panic("failed to open %s, %m", path);
> +	}

Please ignore this v2. Looks that O_CREAT can make sure only one thread/process
will actually create the file.

Thanks
Yuan



More information about the sheepdog mailing list