Beispiel #1
0
static void quorum_callback(quorum_handle_t h, uint32_t quorate,
			    uint64_t ring_seq, uint32_t node_list_entries,
			    uint32_t *node_list)
{
	corosync_cfg_node_address_t addrs[MAX_NODE_ADDRESSES];
	corosync_cfg_node_address_t *addrptr = addrs;
	cs_error_t err;
	int i, j, num_addrs;

	cluster_quorate = quorate;

	old_node_count = quorum_node_count;
	memcpy(&old_nodes, &quorum_nodes, sizeof(old_nodes));

	quorum_node_count = 0;
	memset(&quorum_nodes, 0, sizeof(quorum_nodes));

	for (i = 0; i < node_list_entries; i++)
		quorum_nodes[quorum_node_count++] = node_list[i];

	for (i = 0; i < old_node_count; i++) {
		if (!is_cluster_member(old_nodes[i])) {
			log_debug("cluster node %u removed", old_nodes[i]);
			node_history_cluster_remove(old_nodes[i]);
			del_configfs_node(old_nodes[i]);
		}
	}

	for (i = 0; i < quorum_node_count; i++) {
		if (!is_old_member(quorum_nodes[i])) {
			log_debug("cluster node %u added", quorum_nodes[i]);
			node_history_cluster_add(quorum_nodes[i]);

			err = corosync_cfg_get_node_addrs(ch, quorum_nodes[i],
							  MAX_NODE_ADDRESSES,
							  &num_addrs, addrs);
			if (err != CS_OK) {
				log_error("corosync_cfg_get_node_addrs failed "
					  "nodeid %u", quorum_nodes[i]);
				continue;
			}

			for (j = 0; j < num_addrs; j++) {
				add_configfs_node(quorum_nodes[i],
						  addrptr[j].address,
						  addrptr[j].address_length,
						  (quorum_nodes[i] ==
						   our_nodeid));
			}
		}
	}
}
Beispiel #2
0
int set_configfs_members(char *name, int new_count, int *new_members,
			 int renew_count, int *renew_members)
{
	char path[PATH_MAX];
	char buf[32];
	int i, w, fd, rv, id, old_count, *old_members;
	int do_renew;

	/*
	 * create lockspace dir if it doesn't exist yet
	 */

	memset(path, 0, PATH_MAX);
	snprintf(path, PATH_MAX, "%s/%s", SPACES_DIR, name);

	if (!path_exists(path)) {
		if (create_path(path))
			return -1;
	}

	/*
	 * remove/add lockspace members
	 */

	rv = update_dir_members(name);
	if (rv)
		return rv;

	old_members = dir_members;
	old_count = dir_members_count;

	for (i = 0; i < old_count; i++) {
		id = old_members[i];
		if (id_exists(id, new_count, new_members))
			continue;

		memset(path, 0, PATH_MAX);
		snprintf(path, PATH_MAX, "%s/%s/nodes/%d",
			 SPACES_DIR, name, id);

		log_debug("set_members rmdir \"%s\"", path);

		rv = rmdir(path);
		if (rv) {
			log_error("%s: rmdir failed: %d", path, errno);
			goto out;
		}
	}

	/*
	 * remove lockspace dir after we've removed all the nodes
	 * (when we're shutting down and adding no new nodes)
	 */

	if (!new_count) {
		memset(path, 0, PATH_MAX);
		snprintf(path, PATH_MAX, "%s/%s", SPACES_DIR, name);

		log_debug("set_members lockspace rmdir \"%s\"", path);

		rv = rmdir(path);
		if (rv)
			log_error("%s: rmdir failed: %d", path, errno);
	}

	for (i = 0; i < new_count; i++) {
		id = new_members[i];

		do_renew = 0;

		if (id_exists(id, renew_count, renew_members))
			do_renew = 1;
		else if (id_exists(id, old_count, old_members))
			continue;

		if (!is_cluster_member(id))
			update_cluster();
		/*
		 * create node's dir
		 */

		memset(path, 0, PATH_MAX);
		snprintf(path, PATH_MAX, "%s/%s/nodes/%d",
			 SPACES_DIR, name, id);

		if (do_renew) {
			log_debug("set_members renew rmdir \"%s\"", path);
			rv = rmdir(path);
			if (rv) {
				log_error("%s: renew rmdir failed: %d",
					  path, errno);

				/* don't quit here, there's a case where
				 * this can happen, where a node identified
				 * for renewal was not really added
				 * previously */
			}
		}

		log_debug("set_members mkdir \"%s\"", path);

		rv = create_path(path);
		if (rv)
			goto out;

		/*
		 * set node's nodeid
		 */

		memset(path, 0, PATH_MAX);
		snprintf(path, PATH_MAX, "%s/%s/nodes/%d/nodeid",
			 SPACES_DIR, name, id);

		rv = fd = open(path, O_WRONLY);
		if (rv < 0) {
			log_error("%s: open failed: %d", path, errno);
			goto out;
		}

		memset(buf, 0, 32);
		snprintf(buf, 32, "%d", id);

		rv = do_write(fd, buf, strlen(buf));
		if (rv < 0) {
			log_error("%s: write failed: %d, %s", path, errno, buf);
			close(fd);
			goto out;
		}
		close(fd);

		/*
		 * set node's weight
		 */

		w = get_weight(id, name);

		memset(path, 0, PATH_MAX);
		snprintf(path, PATH_MAX, "%s/%s/nodes/%d/weight",
			 SPACES_DIR, name, id);

		rv = fd = open(path, O_WRONLY);
		if (rv < 0) {
			log_error("%s: open failed: %d", path, errno);
			goto out;
		}

		memset(buf, 0, 32);
		snprintf(buf, 32, "%d", w);

		rv = do_write(fd, buf, strlen(buf));
		if (rv < 0) {
			log_error("%s: write failed: %d, %s", path, errno, buf);
			close(fd);
			goto out;
		}
		close(fd);
	}

	rv = 0;
 out:
	return rv;
}
Beispiel #3
0
static void statechange(void)
{
	cman_cluster_t info;
	cman_node_t *old;
	int i, j, rv;
	struct cman_node_address addrs[MAX_NODE_ADDRESSES];
	int num_addrs;
	struct cman_node_address *addrptr = addrs;

	rv = cman_get_cluster(ch, &info);
	if (rv < 0) {
		log_error("cman_get_cluster error %d %d", rv, errno);
		/* keep going, this is just informational */
		memset(&info, 0, sizeof(info));
	}
	cluster_ringid_seq = info.ci_generation;

	cluster_quorate = cman_is_quorate(ch);

	old_node_count = cman_node_count;
	memcpy(&old_nodes, &cman_nodes, sizeof(old_nodes));

	cman_node_count = 0;
	memset(&cman_nodes, 0, sizeof(cman_nodes));
	rv = cman_get_nodes(ch, MAX_NODES, &cman_node_count, cman_nodes);
	if (rv < 0) {
		log_debug("cman_get_nodes error %d %d", rv, errno);
		return;
	}

	/* Never allow node ID 0 to be considered a member #315711 */
	for (i = 0; i < cman_node_count; i++) {
		if (cman_nodes[i].cn_nodeid == 0) {
			cman_nodes[i].cn_member = 0;
			break;
		}
	}

	for (i = 0; i < old_node_count; i++) {
		if (old_nodes[i].cn_member &&
		    !is_cluster_member(old_nodes[i].cn_nodeid)) {

			log_debug("cluster node %d removed seq %u",
				  old_nodes[i].cn_nodeid, cluster_ringid_seq);

			node_history_cluster_remove(old_nodes[i].cn_nodeid);

			del_configfs_node(old_nodes[i].cn_nodeid);
		}
	}

	for (i = 0; i < cman_node_count; i++) {
		if (cman_nodes[i].cn_member &&
		    !is_old_member(cman_nodes[i].cn_nodeid)) {

			log_debug("cluster node %d added seq %u",
				  cman_nodes[i].cn_nodeid, cluster_ringid_seq);

			rv = cman_get_node_addrs(ch, cman_nodes[i].cn_nodeid,
						 MAX_NODE_ADDRESSES,
						 &num_addrs, addrs);
			if (rv < 0) {
				log_debug("cman_get_node_addrs failed, falling back to single-homed. ");
				num_addrs = 1;
				addrptr = &cman_nodes[i].cn_address;
			}

			node_history_cluster_add(cman_nodes[i].cn_nodeid);

			for (j = 0; j < num_addrs; j++) {
				add_configfs_node(cman_nodes[i].cn_nodeid,
						  addrptr[j].cna_address,
						  addrptr[j].cna_addrlen,
						  (cman_nodes[i].cn_nodeid ==
						   our_nodeid));
			}
		} else {
			/* look for any nodes that were members of both
			 * old and new but have a new incarnation number
			 * from old to new, indicating they left and rejoined
			 * in between */

			old = get_node(old_nodes, old_node_count, cman_nodes[i].cn_nodeid);

			if (!old)
				continue;
			if (cman_nodes[i].cn_incarnation == old->cn_incarnation)
				continue;

			log_debug("cluster node %d removed and added seq %u "
				  "old %u new %u",
				  cman_nodes[i].cn_nodeid, cluster_ringid_seq,
				  old->cn_incarnation,
				  cman_nodes[i].cn_incarnation);

			/*
			 * remove (copied from above)
			 */

			node_history_cluster_remove(old_nodes[i].cn_nodeid);

			del_configfs_node(old_nodes[i].cn_nodeid);

			/*
			 * add (copied from above)
			 */

			rv = cman_get_node_addrs(ch, cman_nodes[i].cn_nodeid,
						 MAX_NODE_ADDRESSES,
						 &num_addrs, addrs);
			if (rv < 0) {
				log_debug("cman_get_node_addrs failed, falling back to single-homed. ");
				num_addrs = 1;
				addrptr = &cman_nodes[i].cn_address;
			}

			node_history_cluster_add(cman_nodes[i].cn_nodeid);

			for (j = 0; j < num_addrs; j++) {
				add_configfs_node(cman_nodes[i].cn_nodeid,
						  addrptr[j].cna_address,
						  addrptr[j].cna_addrlen,
						  (cman_nodes[i].cn_nodeid ==
						   our_nodeid));
			}
		}
	}
}