/*
 * Copyright (C) 2001-2004 Sistina Software, Inc. All rights reserved.
 * Copyright (C) 2004-2014 Red Hat, Inc. All rights reserved.
 *
 * This file is part of LVM2.
 *
 * This copyrighted material is made available to anyone wishing to use,
 * modify, copy, or redistribute it subject to the terms and conditions
 * of the GNU Lesser General Public License v.2.1.
 *
 * You should have received a copy of the GNU Lesser General Public License
 * along with this program; if not, write to the Free Software Foundation,
 * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
 */

#include "lib.h"
#include "config.h"
#include "lvm-file.h"
#include "lvm-flock.h"
#include "lvm-signal.h"
#include "locking.h"

#include <sys/file.h>
#include <fcntl.h>

struct lock_list {
	struct dm_list list;
	int lf;
	char *res;
};

static struct dm_list _lock_list;
static int _prioritise_write_locks;

/* Drop lock known to be shared with another file descriptor. */
static void _drop_shared_flock(const char *file, int fd)
{
	log_debug_locking("_drop_shared_flock %s.", file);

	if (close(fd) < 0)
		log_sys_debug("close", file);
}

static void _undo_flock(const char *file, int fd)
{
	struct stat buf1, buf2;

	log_debug_locking("_undo_flock %s", file);
	if (!flock(fd, LOCK_NB | LOCK_EX) &&
	    !stat(file, &buf1) &&
	    !fstat(fd, &buf2) &&
	    is_same_inode(buf1, buf2))
		if (unlink(file))
			log_sys_debug("unlink", file);

	if (close(fd) < 0)
		log_sys_debug("close", file);
}

static int _release_lock(const char *file, int unlock)
{
	struct lock_list *ll;
	struct dm_list *llh, *llt;

	dm_list_iterate_safe(llh, llt, &_lock_list) {
		ll = dm_list_item(llh, struct lock_list);

		if (!file || !strcmp(ll->res, file)) {
			dm_list_del(llh);
			if (unlock) {
				log_very_verbose("Unlocking %s", ll->res);
				if (flock(ll->lf, LOCK_NB | LOCK_UN))
					log_sys_debug("flock", ll->res);
				_undo_flock(ll->res, ll->lf);
			} else
				_drop_shared_flock(ll->res, ll->lf);

			dm_free(ll->res);
			dm_free(llh);

			if (file)
				return 1;
		}
	}

	return 0;
}

void release_flocks(int unlock)
{
	_release_lock(NULL, unlock);
}

static int _do_flock(const char *file, int *fd, int operation, uint32_t nonblock)
{
	int r;
	int old_errno;
	struct stat buf1, buf2;

	log_debug_locking("_do_flock %s %c%c", file,
			  operation == LOCK_EX ? 'W' : 'R', nonblock ? ' ' : 'B');
	do {
		if ((*fd > -1) && close(*fd))
			log_sys_debug("close", file);

		if ((*fd = open(file, O_CREAT | O_APPEND | O_RDWR, 0777)) < 0) {
			log_sys_error("open", file);
			return 0;
		}

		if (nonblock)
			operation |= LOCK_NB;
		else
			sigint_allow();

		r = flock(*fd, operation);
		old_errno = errno;
		if (!nonblock) {
			sigint_restore();
			if (sigint_caught())
				log_error("Giving up waiting for lock.");
		}

		if (r) {
			errno = old_errno;
			log_sys_error("flock", file);
			if (close(*fd))
				log_sys_debug("close", file);
			*fd = -1;
			return 0;
		}

		if (!stat(file, &buf1) && !fstat(*fd, &buf2) &&
		    is_same_inode(buf1, buf2))
			return 1;
	} while (!nonblock);

	return_0;
}

#define AUX_LOCK_SUFFIX ":aux"

static int _do_write_priority_flock(const char *file, int *fd, int operation, uint32_t nonblock)
{
	int r, fd_aux = -1;
	char *file_aux = alloca(strlen(file) + sizeof(AUX_LOCK_SUFFIX));

	strcpy(file_aux, file);
	strcat(file_aux, AUX_LOCK_SUFFIX);

	if ((r = _do_flock(file_aux, &fd_aux, LOCK_EX, 0))) {
		if (operation == LOCK_EX) {
			r = _do_flock(file, fd, operation, nonblock);
			_undo_flock(file_aux, fd_aux);
		} else {
			_undo_flock(file_aux, fd_aux);
			r = _do_flock(file, fd, operation, nonblock);
		}
	}

	return r;
}

int lock_file(const char *file, uint32_t flags)
{
	int operation;
	uint32_t nonblock = flags & LCK_NONBLOCK;
	int r;

	struct lock_list *ll;
	char state;

	switch (flags & LCK_TYPE_MASK) {
	case LCK_READ:
		operation = LOCK_SH;
		state = 'R';
		break;
	case LCK_WRITE:
		operation = LOCK_EX;
		state = 'W';
		break;
	case LCK_UNLOCK:
		return _release_lock(file, 1);
	default:
		log_error("Unrecognised lock type: %d", flags & LCK_TYPE_MASK);
		return 0;
	}

	if (!(ll = dm_malloc(sizeof(struct lock_list))))
		return_0;

	if (!(ll->res = dm_strdup(file))) {
		dm_free(ll);
		return_0;
	}

	ll->lf = -1;

	log_very_verbose("Locking %s %c%c", ll->res, state,
			 nonblock ? ' ' : 'B');

	(void) dm_prepare_selinux_context(file, S_IFREG);
	if (_prioritise_write_locks)
		r = _do_write_priority_flock(file, &ll->lf, operation, nonblock);
	else 
		r = _do_flock(file, &ll->lf, operation, nonblock);
	(void) dm_prepare_selinux_context(NULL, 0);

	if (r)
		dm_list_add(&_lock_list, &ll->list);
	else {
		dm_free(ll->res);
		dm_free(ll);
		stack;
	}

	return r;
}

void init_flock(struct cmd_context *cmd)
{
	dm_list_init(&_lock_list);

	_prioritise_write_locks =
	    find_config_tree_bool(cmd, global_prioritise_write_locks_CFG, NULL);
}
