Пример #1
0
char *
get_local_node_name(void)
{
    char *name = NULL;
    struct utsname res;

    if (use_cman) {
#if SUPPORT_CMAN
        cman_node_t us;
        cman_handle_t cman;

        cman = cman_init(NULL);
        if (cman != NULL && cman_is_active(cman)) {
            us.cn_name[0] = 0;
            cman_get_node(cman, CMAN_NODEID_US, &us);
            name = crm_strdup(us.cn_name);
            crm_info("Using CMAN node name: %s", name);

        } else {
            crm_err("Couldn't determin node name from CMAN");
        }

        cman_finish(cman);
#endif

    } else if (uname(&res) < 0) {
        crm_perror(LOG_ERR, "Could not determin the current host");
        exit(100);

    } else {
        name = crm_strdup(res.nodename);
    }
    return name;
}
Пример #2
0
static void delay_members(void)
{
	int rv, tries = 0;
	int cd;

	cd = ccs_connect();
	if (cd < 0) {
		cman_finish(ch);
		die("lost cman/ccs connection");
	}

	read_ccs_nodeids(cd);

	while (1) {
		rv = all_nodeids_are_members();
		if (rv < 0) {
			ccs_disconnect(cd);
			cman_finish(ch);
			die("lost cman connection");
		}
		if (rv)
			break;

		tries++;

		if (opt_delay_members < 0)
			goto retry_members;

		if (!opt_delay_members || tries > opt_delay_members) {
			fprintf(stderr, "%s: continuing without all members\n", prog_name);
			break;
		}
 retry_members:
		if (!(tries % 10))
			fprintf(stderr, "%s: delaying for members\n", prog_name);

		sleep(1);
	}

	ccs_disconnect(cd);
	return;
}
Пример #3
0
int member_list_nodes(clv_clnode_head_t *cn_head)
{
    int             node_count, i;
    cman_handle_t   cman_handle;
    cman_node_t     *cman_nodes, local_node;
    
    if ((cman_handle = cman_init(0)) == 0) {
        return -1;
    }

    if ((node_count = cman_get_node_count(cman_handle)) < 0) {
        return -1;
    }
    
    cman_nodes = calloc((size_t) node_count, sizeof(cman_node_t));
    cman_get_nodes(cman_handle, node_count, &node_count, cman_nodes);
    
    local_node.cn_name[0] = '\0'; /* init cn_name for cman_get_node */

    if (cman_get_node(cman_handle, CMAN_NODEID_US, &local_node) != 0) {
        return -1;
    }
    
    for (i = 0; i < node_count; i++) {
        clv_clnode_t    *n;
        
        n = malloc(sizeof(clv_clnode_t));
        STAILQ_INSERT_TAIL(cn_head, n, next);

        n->id           = (uint32_t) cman_nodes[i].cn_nodeid;
        n->host         = strdup(cman_nodes[i].cn_name);
        n->status       = 0;
        
        if (cman_nodes[i].cn_member != 0) {
            n->status   |= CLUSTER_NODE_ONLINE;
        }
        
        if (cman_nodes[i].cn_nodeid == local_node.cn_nodeid) {
            n->status   |= CLUSTER_NODE_LOCAL;
        }
    }
    
    free(cman_nodes);

    cman_finish(cman_handle);
    return 0;
}
Пример #4
0
static int connect_cman(void)
{
	int rv, tries = 0;

	while (1) {
		ch = cman_init(NULL);
		if (ch)
			break;

		tries++;

		if (opt_retry_cman < 0)
			goto retry_init;

		if (!opt_retry_cman || tries >= opt_retry_cman)
			return -1;
 retry_init:
		if (!(tries % 10))
			fprintf(stderr, "%s: retrying cman connection\n", prog_name);
		sleep(1);
	}

	while (1) {
		rv = cman_is_active(ch);
		if (rv)
			break;

		tries++;

		if (opt_retry_cman < 0)
			goto retry_active;

		if (!opt_retry_cman || tries >= opt_retry_cman) {
			cman_finish(ch);
			return -1;
		}
 retry_active:
		if (!(tries % 10))
			fprintf(stderr, "%s: retrying cman active check\n", prog_name);
		sleep(1);
	}

	return 0;
}
Пример #5
0
static void do_join(int argc, char *argv[])
{
	int rv, tries = 0;

	rv = connect_cman();
	if (rv < 0)
		die("can't connect to cman");

	/* if delay_quorum() or delay_members() fail on any cman/ccs
	   connection or operation, they call cman_finish() and exit
	   with failure */

	if (opt_delay_quorum)
		delay_quorum();

	if (opt_delay_members)
		delay_members();

	cman_finish(ch);

	/* This loop deals with the case where fenced is slow enough starting
	   up that fenced_join fails.  Do we also want to add a delay here to
	   deal with the case where fenced is so slow starting up that it hasn't
	   locked its lockfile yet, causing check_fenced_running to fail? */

	while (1) {
		rv = fenced_join();
		if (!rv)
			break;

		check_fenced_running();

		tries++;
		if (!(tries % 10))
			fprintf(stderr, "%s: retrying join\n", prog_name);
		sleep(1);
	}

	if (opt_wait_joinleave)
		wait_domain(1);

	exit(EXIT_SUCCESS);
}
Пример #6
0
int join(commandline_t *comline, char *main_envp[])
{
	int i, err;
	int envptr = 0;
	int argvptr = 0;
	char scratch[1024];
	char config_modules[1024];
	cman_handle_t h = NULL;
	int status;
	hdb_handle_t object_handle;
	confdb_handle_t confdb_handle;
	int res;
	pid_t corosync_pid;
	int p[2];
	confdb_callbacks_t callbacks = {
		.confdb_key_change_notify_fn = NULL,
		.confdb_object_create_change_notify_fn = NULL,
		.confdb_object_delete_change_notify_fn = NULL
	};

        /*
	 * If we can talk to cman then we're already joined (or joining);
	 */
	h = cman_admin_init(NULL);
	if (h)
		die("Node is already active");

	/* Set up environment variables for override */
	if (comline->multicast_addr) {
		snprintf(scratch, sizeof(scratch), "CMAN_MCAST_ADDR=%s", comline->multicast_addr);
		envp[envptr++] = strdup(scratch);
	}
	if (comline->votes_opt) {
		snprintf(scratch, sizeof(scratch), "CMAN_VOTES=%d", comline->votes);
		envp[envptr++] = strdup(scratch);
	}
	if (comline->expected_votes_opt) {
		snprintf(scratch, sizeof(scratch), "CMAN_EXPECTEDVOTES=%d", comline->expected_votes);
		envp[envptr++] = strdup(scratch);
	}
	if (comline->port) {
		snprintf(scratch, sizeof(scratch), "CMAN_IP_PORT=%d", comline->port);
		envp[envptr++] = strdup(scratch);
	}
	if (comline->nodeid) {
		snprintf(scratch, sizeof(scratch), "CMAN_NODEID=%d", comline->nodeid);
		envp[envptr++] = strdup(scratch);
	}
	if (comline->clustername_opt) {
		snprintf(scratch, sizeof(scratch), "CMAN_CLUSTER_NAME=%s", comline->clustername);
		envp[envptr++] = strdup(scratch);
	}
	if (comline->nodenames[0]) {
		snprintf(scratch, sizeof(scratch), "CMAN_NODENAME=%s", comline->nodenames[0]);
		envp[envptr++] = strdup(scratch);
	}
	if (comline->key_filename) {
		snprintf(scratch, sizeof(scratch), "CMAN_KEYFILE=%s", comline->key_filename);
		envp[envptr++] = strdup(scratch);
	}
	if (comline->two_node) {
		snprintf(scratch, sizeof(scratch), "CMAN_2NODE=true");
		envp[envptr++] = strdup(scratch);
	}
	if (comline->verbose ^ DEBUG_STARTUP_ONLY) {
		snprintf(scratch, sizeof(scratch), "CMAN_DEBUG=%d", comline->verbose);
		envp[envptr++] = strdup(scratch);
	}
	if (comline->nostderr_debug) {
		snprintf(scratch, sizeof(scratch), "CMAN_NOSTDERR_DEBUG=true");
		envp[envptr++] = strdup(scratch);
	}
	if (comline->noconfig_opt) {
		envp[envptr++] = strdup("CMAN_NOCONFIG=true");
		snprintf(config_modules, sizeof(config_modules), "cmanpreconfig");
	}
	else {
		snprintf(config_modules, sizeof(config_modules), "%s:cmanpreconfig", comline->config_lcrso);
	}
	if (comline->noopenais_opt) {
		envp[envptr++] = strdup("CMAN_NOOPENAIS=true");
	}

	snprintf(scratch, sizeof(scratch), "COROSYNC_DEFAULT_CONFIG_IFACE=%s", config_modules);
	envp[envptr++] = strdup(scratch);

	/* Copy any COROSYNC_* env variables to the new daemon */
	i=0;
	while (i < MAX_ARGS && main_envp[i]) {
		if (strncmp(main_envp[i], "COROSYNC_", 9) == 0)
			envp[envptr++] = main_envp[i];
		i++;
	}


	/* Create a pipe to monitor cman startup progress */
	if (pipe(p) < 0)
		die("unable to create pipe: %s", strerror(errno));
	fcntl(p[1], F_SETFD, 0); /* Don't close on exec */
	snprintf(scratch, sizeof(scratch), "CMAN_PIPE=%d", p[1]);
	envp[envptr++] = strdup(scratch);
	envp[envptr++] = NULL;

	/* Always run corosync -f because we have already forked twice anyway, and
	   we want to return any exit code that might happen */
	/* also strdup strings because it's otherwise virtually impossible to fix
	 * build warnings due to the way argv C implementation is done */
	argv[0] = strdup("corosync");
	argv[++argvptr] = strdup("-f");
	if (comline->nosetpri_opt)
		argv[++argvptr] = strdup("-p");
	argv[++argvptr] = NULL;

	/* Fork/exec cman */
	switch ( (corosync_pid = fork()) )
	{
	case -1:
		die("fork of corosync daemon failed: %s", strerror(errno));

	case 0: /* child */
		close(p[0]);
		if (comline->verbose & DEBUG_STARTUP_ONLY) {
			fprintf(stderr, "Starting %s", COROSYNCBIN);
			for (i=0; i< argvptr; i++) {
				fprintf(stderr, " %s", argv[i]);
			}
			fprintf(stderr, "\n");
			for (i=0; i<envptr-1; i++) {
				fprintf(stderr, "%s\n", envp[i]);
			}
		}
		be_daemon();

		sprintf(scratch, "FORKED: %d\n", getpid());
		err = write(p[1], scratch, strlen(scratch));

		execve(COROSYNCBIN, argv, envp);

		/* exec failed - tell the parent process */
		sprintf(scratch, "execve of " COROSYNCBIN " failed: %s", strerror(errno));
		err = write(p[1], scratch, strlen(scratch));
		exit(1);
		break;

	default: /* parent */
		break;

	}

	/* Give the daemon a chance to start up, and monitor the pipe FD for messages */
	i = 0;
	close(p[1]);

	/* Wait for the process to start or die */
	sleep(1);
	do {
		fd_set fds;
		struct timeval tv={1, 0};
		char message[1024];
		char *messageptr = message;

		FD_ZERO(&fds);
		FD_SET(p[0], &fds);

		status = select(p[0]+1, &fds, NULL, NULL, &tv);

		/* Did we get a cman-reported error? */
		if (status == 1) {
			int len;
			if ((len = read(p[0], message, sizeof(message)) > 0)) {

				/* Forked OK - get the real corosync pid */
				if (sscanf(messageptr, "FORKED: %d", &corosync_pid) == 1) {
					if (comline->verbose & DEBUG_STARTUP_ONLY)
						fprintf(stderr, "forked process ID is %d\n", corosync_pid);
					status = 0;

					/* There might be a SUCCESS or error message in the pipe too. */
					messageptr = strchr(messageptr, '\n');
					if (messageptr && strlen(messageptr) > 1)
						messageptr++;
					else
						continue;
				}
				/* Success! get the new PID of double-forked corosync */
				if (sscanf(messageptr, "SUCCESS: %d", &corosync_pid) == 1) {
					if (comline->verbose & DEBUG_STARTUP_ONLY)
						fprintf(stderr, "corosync running, process ID is %d\n", corosync_pid);
					status = 0;
					break;
				}
				else if (messageptr) {
						fprintf(stderr, "%s\n", messageptr);
						status = 1;
						break;
					}
			}
			else if (len < 0 && errno == EINTR) {
				continue;
			}
			else { /* Error or EOF - check the child status */
				status = check_corosync_status(corosync_pid);
				if (status == 0)
					break;
			}
		}

	} while (status == 0);
	close(p[0]);

	/* If corosync has started, try to connect to cman ... if it's still there */
	if (status == 0) {
		do {
			if (status == 0) {
				if (kill(corosync_pid, 0) < 0) {
					status = check_corosync_status(corosync_pid);
					die("corosync died during startup\n");
				}

				h = cman_admin_init(NULL);
				if (!h && comline->verbose & DEBUG_STARTUP_ONLY)
				{
					fprintf(stderr, "waiting for cman to start\n");
					status = check_corosync_status(corosync_pid);
				}
			}
			sleep (1);
		} while (!h && ++i < 100);
	}

	if (!h)
		die("corosync daemon didn't start");

	if ((comline->verbose & DEBUG_STARTUP_ONLY) && !cman_is_active(h))
		fprintf(stderr, "corosync started, but not joined the cluster yet.\n");

	cman_finish(h);

	/* Copy all COROSYNC_* environment variables into objdb so they can be used to validate new configurations later */
	res = confdb_initialize (&confdb_handle, &callbacks);
	if (res != CS_OK)
		goto join_exit;

	res = confdb_object_create(confdb_handle, OBJECT_PARENT_HANDLE, "cman_private", strlen("cman_private"), &object_handle);
	if (res == CS_OK) {
		int envnum = 0;
		const char *envvar = main_envp[envnum];
		const char *equal;
		char envname[PATH_MAX];


		while (envvar) {
			if (strncmp("COROSYNC_", envvar, 9) == 0) {
				equal = strchr(envvar, '=');
				if (equal) {
				        strncpy(envname, envvar, PATH_MAX);
					if (equal-envvar < PATH_MAX) {
					    envname[equal-envvar] = '\0';

					    res = confdb_key_create_typed(confdb_handle, object_handle, envname,
									  equal+1, strlen(equal+1),CONFDB_VALUETYPE_STRING);
					}
				}
			}
			envvar = main_envp[++envnum];
		}
	}
	res = confdb_key_create_typed(confdb_handle, object_handle,
				      "COROSYNC_DEFAULT_CONFIG_IFACE",
				      config_modules, strlen(config_modules), CONFDB_VALUETYPE_STRING);
	confdb_finalize (confdb_handle);

join_exit:
	return 0;
}
Пример #7
0
Quorum::~Quorum() {
    if (dispatchHandle.get()) dispatchHandle->stopWatch();
    dispatchHandle.reset();
    if (cman) cman_finish(cman);
}
Пример #8
0
Quorum::~Quorum() {
    dispatchHandle.reset();
    if (cman) cman_finish(cman);
}