Example #1
0
static int _config_def_check_node(struct cft_check_handle *handle,
				  const char *vp, char *pvp, char *rp, char *prp,
				  size_t buf_size, struct dm_config_node *cn,
				  struct dm_hash_table *ht)
{
	cfg_def_item_t *def;
	int sep = vp != pvp; /* don't use '/' separator for top-level node */

	if (dm_snprintf(pvp, buf_size, "%s%s", sep ? "/" : "", cn->key) < 0 ||
	    dm_snprintf(prp, buf_size, "%s%s", sep ? "/" : "", cn->key) < 0) {
		log_error("Failed to construct path for configuration node %s.", cn->key);
		return 0;
	}


	if (!(def = (cfg_def_item_t *) dm_hash_lookup(ht, vp))) {
		/* If the node is not a section but a setting, fail now. */
		if (cn->v) {
			log_warn_suppress(handle->suppress_messages,
				"Configuration setting \"%s\" unknown.", rp);
			cn->id = -1;
			return 0;
		}

		/* If the node is a section, try if the section name is variable. */
		/* Modify virtual path vp in situ and replace the key name with a '#'. */
		/* The real path without '#' is still stored in rp variable. */
		pvp[sep] = '#', pvp[sep + 1] = '\0';
		if (!(def = (cfg_def_item_t *) dm_hash_lookup(ht, vp))) {
			log_warn_suppress(handle->suppress_messages,
				"Configuration section \"%s\" unknown.", rp);
			cn->id = -1;
			return 0;
		}
	}

	handle->status[def->id] |= CFG_USED;
	cn->id = def->id;

	if (!_config_def_check_node_value(handle, rp, cn->v, def))
		return 0;

	/*
	 * Also check whether this configuration item is allowed
	 * in certain types of configuration trees as in some
	 * the use of configuration is restricted, e.g. profiles...
	 */
	if (handle->source == CONFIG_PROFILE &&
	    !(def->flags & CFG_PROFILABLE)) {
		log_warn_suppress(handle->suppress_messages,
			"Configuration %s \"%s\" is not customizable by "
			"a profile.", cn->v ? "option" : "section", rp);
		return 0;
	}

	handle->status[def->id] |= CFG_VALID;
	return 1;
}
Example #2
0
static int _config_def_check_node_single_value(const char *rp, const struct dm_config_value *v,
					       const cfg_def_item_t *def, int suppress_messages)
{
	/* Check empty array first if present. */
	if (v->type == DM_CFG_EMPTY_ARRAY) {
		if (!(def->type & CFG_TYPE_ARRAY)) {
			_log_type_error(rp, CFG_TYPE_ARRAY, def->type, suppress_messages);
			return 0;
		}
		if (!(def->flags & CFG_ALLOW_EMPTY)) {
			log_warn_suppress(suppress_messages,
				"Configuration setting \"%s\" invalid. Empty value not allowed.", rp);
			return 0;
		}
		return 1;
	}

	switch (v->type) {
		case DM_CFG_INT:
			if (!(def->type & CFG_TYPE_INT) && !(def->type & CFG_TYPE_BOOL)) {
				_log_type_error(rp, CFG_TYPE_INT, def->type, suppress_messages);
				return 0;
			}
			break;
		case DM_CFG_FLOAT:
			if (!(def->type & CFG_TYPE_FLOAT)) {
				_log_type_error(rp, CFG_TYPE_FLOAT, def->type, suppress_messages);
				return 0;
			}
			break;
		case DM_CFG_STRING:
			if (def->type & CFG_TYPE_BOOL) {
				if (!dm_config_value_is_bool(v)) {
					log_warn_suppress(suppress_messages,
						"Configuration setting \"%s\" invalid. "
						"Found string value \"%s\", "
						"expected boolean value: 0/1, \"y/n\", "
						"\"yes/no\", \"on/off\", "
						"\"true/false\".", rp, v->v.str);
					return 0;
				}
			} else if  (!(def->type & CFG_TYPE_STRING)) {
				_log_type_error(rp, CFG_TYPE_STRING, def->type, suppress_messages);
				return 0;
			}
			break;
		default: ;
	}

	return 1;
}
Example #3
0
static void _log_type_error(const char *path, cfg_def_type_t actual,
			    cfg_def_type_t expected, int suppress_messages)
{
	static char actual_type_name[128];
	static char expected_type_name[128];

	_get_type_name(actual_type_name, sizeof(actual_type_name), actual);
	_get_type_name(expected_type_name, sizeof(expected_type_name), expected);

	log_warn_suppress(suppress_messages, "Configuration setting \"%s\" has invalid type. "
					     "Found%s, expected%s.", path,
					     actual_type_name, expected_type_name);
}
Example #4
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 #5
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;
}