/* 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; }
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); }
/* * 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; }
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; }