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