/* Open connection to the Cluster Manager daemon */
static int _open_local_sock(int suppress_messages)
{
	int local_socket;
	struct sockaddr_un sockaddr;

	/* Open local socket */
	if ((local_socket = socket(PF_UNIX, SOCK_STREAM, 0)) < 0) {
		log_error_suppress(suppress_messages, "Local socket "
				   "creation failed: %s", strerror(errno));
		return -1;
	}

	memset(&sockaddr, 0, sizeof(sockaddr));
	memcpy(sockaddr.sun_path, CLVMD_SOCKNAME, sizeof(CLVMD_SOCKNAME));

	sockaddr.sun_family = AF_UNIX;

	if (connect(local_socket,(struct sockaddr *) &sockaddr,
		    sizeof(sockaddr))) {
		int saved_errno = errno;

		log_error_suppress(suppress_messages, "connect() failed "
				   "on local socket: %s", strerror(errno));
		if (close(local_socket))
			stack;

		errno = saved_errno;
		return -1;
	}

	return local_socket;
}
Example #2
0
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;

	libname = find_config_tree_str(cmd, "global/locking_library",
				       DEFAULT_LOCKING_LIB);

	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);
}
Example #3
0
/*
 * Select a locking type
 * type: locking type; if < 0, then read config tree value
 */
int init_locking(int type, struct cmd_context *cmd, int suppress_messages)
{
	if (getenv("LVM_SUPPRESS_LOCKING_FAILURE_MESSAGES"))
		suppress_messages = 1;

	if (type < 0)
		type = find_config_tree_int(cmd, global_locking_type_CFG, NULL);

	_blocking_supported = find_config_tree_bool(cmd, global_wait_for_locks_CFG, NULL);

	switch (type) {
	case 0:
		init_no_locking(&_locking, cmd, suppress_messages);
		log_warn("WARNING: Locking disabled. Be careful! "
			  "This could corrupt your metadata.");
		return 1;

	case 1:
		log_very_verbose("%sFile-based locking selected.",
				 _blocking_supported ? "" : "Non-blocking ");

		if (!init_file_locking(&_locking, cmd, suppress_messages)) {
			log_error_suppress(suppress_messages,
					   "File-based locking initialisation failed.");
			break;
		}
		return 1;

#ifdef HAVE_LIBDL
	case 2:
		if (!is_static()) {
			log_very_verbose("External locking selected.");
			if (init_external_locking(&_locking, cmd, suppress_messages))
				return 1;
		}
		if (!find_config_tree_bool(cmd, global_fallback_to_clustered_locking_CFG, NULL)) {
			log_error_suppress(suppress_messages, "External locking initialisation failed.");
			break;
		}
#endif

#ifdef CLUSTER_LOCKING_INTERNAL
		log_very_verbose("Falling back to internal clustered locking.");
		/* Fall through */

	case 3:
		log_very_verbose("Cluster locking selected.");
		if (!init_cluster_locking(&_locking, cmd, suppress_messages)) {
			log_error_suppress(suppress_messages,
					   "Internal cluster locking initialisation failed.");
			break;
		}
		return 1;
#endif

	case 4:
		log_verbose("Read-only locking selected. "
			    "Only read operations permitted.");
		if (!init_readonly_locking(&_locking, cmd, suppress_messages))
			break;
		return 1;

	default:
		log_error("Unknown locking type requested.");
		return 0;
	}

	if ((type == 2 || type == 3) &&
	    find_config_tree_bool(cmd, global_fallback_to_local_locking_CFG, NULL)) {
		log_warn_suppress(suppress_messages, "WARNING: Falling back to local file-based locking.");
		log_warn_suppress(suppress_messages,
				  "Volume Groups with the clustered attribute will "
				  "be inaccessible.");
		if (init_file_locking(&_locking, cmd, suppress_messages))
			return 1;
		else
			log_error_suppress(suppress_messages,
					   "File-based locking initialisation failed.");
	}

	if (!ignorelockingfailure())
		return 0;

	log_verbose("Locking disabled - only read operations permitted.");
	init_readonly_locking(&_locking, cmd, suppress_messages);

	return 1;
}
Example #4
0
int config_def_check(struct cmd_context *cmd, struct cft_check_handle *handle)
{
	cfg_def_item_t *def;
	struct dm_config_node *cn;
	char *vp = _cfg_path, rp[CFG_PATH_MAX_LEN];
	size_t rplen;
	int id, r = 1;

	/*
	 * vp = virtual path, it might contain substitutes for variable parts
	 * 	of the path, used while working with the hash
	 * rp = real path, the real path of the config element as found in the
	 *      configuration, used for message output
	 */

	/*
	 * If the check has already been done and 'skip_if_checked' is set,
	 * skip the actual check and use last result if available.
	 * If not available, we must do the check. The global status
	 * is stored in root node.
	 */
	if (handle->skip_if_checked && (handle->status[root_CFG_SECTION] & CFG_USED))
		return handle->status[root_CFG_SECTION] & CFG_VALID;

	/* Nothing to do if checks are disabled and also not forced. */
	if (!handle->force_check && !find_config_tree_bool(cmd, config_checks_CFG, NULL))
		return 1;

	/* Clear 'used' and 'valid' status flags. */
	for (id = 0; id < CFG_COUNT; id++)
		handle->status[id] &= ~(CFG_USED | CFG_VALID);

	/*
	 * Create a hash of all possible configuration
	 * sections and settings with full path as a key.
	 * If section name is variable, use '#' as a substitute.
	 */
	if (!cmd->cft_def_hash) {
		if (!(cmd->cft_def_hash = dm_hash_create(64))) {
			log_error("Failed to create configuration definition hash.");
			r = 0; goto out;
		}
		for (id = 1; id < CFG_COUNT; id++) {
			def = cfg_def_get_item_p(id);
			if (!cfg_def_get_path(def)) {
				dm_hash_destroy(cmd->cft_def_hash);
				cmd->cft_def_hash = NULL;
				r = 0; goto out;
			}
			if (!dm_hash_insert(cmd->cft_def_hash, vp, def)) {
				log_error("Failed to insert configuration to hash.");
				r = 0;
				goto out;
			}
		}
	}

	/*
	 * Mark this handle as used so next time we know that the check
	 * has already been done and so we can just reuse the previous
	 * status instead of running this whole check again.
	 */
	handle->status[root_CFG_SECTION] |= CFG_USED;

	/*
	 * Allow only sections as top-level elements.
	 * Iterate top-level sections and dive deeper.
	 * If any of subsequent checks fails, the whole check fails.
	 */
	for (cn = handle->cft->root; cn; cn = cn->sib) {
		if (!cn->v) {
			/* top level node: vp=vp, rp=rp */
			if (!_config_def_check_node(handle, vp, vp, rp, rp,
						    CFG_PATH_MAX_LEN,
						    cn, cmd->cft_def_hash)) {
				r = 0; continue;
			}
			rplen = strlen(rp);
			if (!_config_def_check_tree(handle,
						    vp, vp + strlen(vp),
						    rp, rp + rplen,
						    CFG_PATH_MAX_LEN - rplen,
						    cn, cmd->cft_def_hash))
				r = 0;
		} else {
			log_error_suppress(handle->suppress_messages,
				"Configuration setting \"%s\" invalid. "
				"It's not part of any section.", cn->key);
			r = 0;
		}
	}
out:
	if (r)
		handle->status[root_CFG_SECTION] |= CFG_VALID;
	else
		handle->status[root_CFG_SECTION] &= ~CFG_VALID;

	return r;
}