/*
 * Copyright (C) 2002-2004 Sistina Software, Inc. All rights reserved.
 * Copyright (C) 2004-2006 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 "locking_types.h"
#include "defaults.h"
#include "sharedlib.h"
#include "toolcontext.h"
#include "activate.h"

static void *_locking_lib = NULL;
static void (*_reset_fn) (void) = NULL;
static void (*_end_fn) (void) = NULL;
static int (*_lock_fn) (struct cmd_context * cmd, const char *resource,
			uint32_t flags) = NULL;
static int (*_init_fn) (int type, struct dm_config_tree * cft,
			uint32_t *flags) = NULL;
static int (*_lock_query_fn) (const char *resource, int *mode) = NULL;

static int _lock_resource(struct cmd_context *cmd, const char *resource,
			  uint32_t flags, const struct logical_volume *lv __attribute__((unused)))
{
	if (!_lock_fn)
		return 0;

	if (!strcmp(resource, VG_SYNC_NAMES)) {
		/* Hide this lock request from external locking */
		fs_unlock();
		return 1;
	}

	return _lock_fn(cmd, resource, flags);
}

static void _fin_external_locking(void)
{
	if (_end_fn)
		_end_fn();

	dlclose(_locking_lib);

	_locking_lib = NULL;
	_init_fn = NULL;
	_end_fn = NULL;
	_lock_fn = NULL;
	_reset_fn = NULL;
}

static void _reset_external_locking(void)
{
	if (_reset_fn)
		_reset_fn();
}

int init_external_locking(struct locking_type *locking, struct cmd_context *cmd,
			  int suppress_messages)
{
	const char *libname;

	if (_locking_lib) {
		log_error_suppress(suppress_messages, "External locking already initialised");
		return 1;
	}

	locking->lock_resource = _lock_resource;
	locking->fin_locking = _fin_external_locking;
	locking->reset_locking = _reset_external_locking;
	locking->flags = 0;

	if (!(libname = find_config_tree_str(cmd, global_locking_library_CFG, NULL)))
		return_0;

	if (!(_locking_lib = load_shared_library(cmd, libname, "locking", 1)))
		return_0;

	/* Get the functions we need */
	if (!(_init_fn = dlsym(_locking_lib, "locking_init")) ||
	    !(_lock_fn = dlsym(_locking_lib, "lock_resource")) ||
	    !(_reset_fn = dlsym(_locking_lib, "reset_locking")) ||
	    !(_end_fn = dlsym(_locking_lib, "locking_end"))) {
		log_error_suppress(suppress_messages, "Shared library %s does "
				   "not contain locking functions", libname);
		dlclose(_locking_lib);
		_locking_lib = NULL;
		return 0;
	}

	if (!(_lock_query_fn = dlsym(_locking_lib, "query_resource")))
		log_warn_suppress(suppress_messages, "WARNING: %s: _query_resource() "
				  "missing: Using inferior activation method.", libname);

	log_verbose("Loaded external locking library %s", libname);
	return _init_fn(2, cmd->cft, &locking->flags);
}
