Example #1
0
static char *
get_heartbeat_uuid(uint32_t unused, const char *uname)
{
    char *uuid_calc = NULL;

#if SUPPORT_HEARTBEAT
    cl_uuid_t uuid_raw;
    const char *unknown = "00000000-0000-0000-0000-000000000000";

    if (heartbeat_cluster == NULL) {
        crm_warn("No connection to heartbeat, using uuid=uname");
        return NULL;
    }

    if (heartbeat_cluster->llc_ops->get_uuid_by_name(heartbeat_cluster, uname, &uuid_raw) ==
        HA_FAIL) {
        crm_err("get_uuid_by_name() call failed for host %s", uname);
        free(uuid_calc);
        return NULL;
    }

    uuid_calc = calloc(1, 50);
    cl_uuid_unparse(&uuid_raw, uuid_calc);

    if (safe_str_eq(uuid_calc, unknown)) {
        crm_warn("Could not calculate UUID for %s", uname);
        free(uuid_calc);
        return NULL;
    }
#endif
    return uuid_calc;
}
Example #2
0
int
read_local_hb_uuid(void)
{
    int rc = 0;
    cl_uuid_t uuid;
    char *buffer = NULL;
    long start = 0, read_len = 0;

    FILE *input = fopen(UUID_FILE, "r");

    if (input == NULL) {
        cl_perror("Could not open UUID file %s\n", UUID_FILE);
        return 1;
    }

    /* see how big the file is */
    start = ftell(input);
    fseek(input, 0L, SEEK_END);
    if (UUID_LEN != ftell(input)) {
        fprintf(stderr, "%s must contain exactly %d bytes\n", UUID_FILE, UUID_LEN);
        abort();
    }

    fseek(input, 0L, start);

    if (start != ftell(input)) {
        fprintf(stderr, "fseek not behaving: %ld vs. %ld\n", start, ftell(input));
        rc = 2;
        goto bail;
    }

/* 	fprintf(stderr, "Reading %d bytes from: %s\n", UUID_LEN, UUID_FILE); */

    buffer = malloc(50);
    read_len = fread(uuid.uuid, 1, UUID_LEN, input);
    if (read_len != UUID_LEN) {
        fprintf(stderr, "Expected and read bytes differ: %d vs. %ld\n", UUID_LEN, read_len);
        rc = 3;
        goto bail;

    } else if (buffer != NULL) {
        cl_uuid_unparse(&uuid, buffer);
        fprintf(stdout, "%s\n", buffer);

    } else {
        fprintf(stderr, "No buffer to unparse\n");
        rc = 4;
    }

  bail:
    free(buffer);
    fclose(input);

    return rc;
}
Example #3
0
static gboolean read_local_hb_uuid(void) 
{
    cl_uuid_t uuid;
    char *buffer = NULL;
    long start = 0, read_len = 0;

    FILE *input = fopen(UUID_FILE, "r");
	
    if(input == NULL) {
	crm_info("Could not open UUID file %s\n", UUID_FILE);
	return FALSE;
    }
	
    /* see how big the file is */
    start  = ftell(input);
    fseek(input, 0L, SEEK_END);
    if(UUID_LEN != ftell(input)) {
	fprintf(stderr, "%s must contain exactly %d bytes\n", UUID_FILE, UUID_LEN);
	abort();
    }
	
    fseek(input, 0L, start);
    if(start != ftell(input)) {
	fprintf(stderr, "fseek not behaving: %ld vs. %ld\n", start, ftell(input));
	exit(2);
    }

    buffer = malloc(50);
    read_len = fread(uuid.uuid, 1, UUID_LEN, input);
    if(read_len != UUID_LEN) {
	fprintf(stderr, "Expected and read bytes differ: %d vs. %ld\n",
		UUID_LEN, read_len);
	exit(3);
		
    } else if(buffer != NULL) {
	cl_uuid_unparse(&uuid, buffer);
	fprintf(stdout, "%s\n", buffer);
	return TRUE;
	
    } else {
	fprintf(stderr, "No buffer to unparse\n");
	exit(4);
    }

    free(buffer);
    fclose(input);

    return FALSE;
}
Example #4
0
static gboolean
stonith_client_connect(IPC_Channel *channel, gpointer user_data)
{
    cl_uuid_t client_id;
    xmlNode *reg_msg = NULL;
    stonith_client_t *new_client = NULL;
    char uuid_str[UU_UNPARSE_SIZEOF];
    const char *channel_name = user_data;

    crm_trace("Connecting channel");
    CRM_CHECK(channel_name != NULL, return FALSE);
	
    if (channel == NULL) {
	crm_err("Channel was NULL");
	return FALSE;

    } else if (channel->ch_status != IPC_CONNECT) {
	crm_err("Channel was disconnected");
	return FALSE;
		
    } else if(stonith_shutdown_flag) {
	crm_info("Ignoring new client [%d] during shutdown",
		 channel->farside_pid);
	return FALSE;		
    }

    crm_malloc0(new_client, sizeof(stonith_client_t));
    new_client->channel = channel;
    new_client->channel_name = channel_name;
	
    crm_trace("Created channel %p for channel %s",
		new_client, new_client->channel_name);
	
    channel->ops->set_recv_qlen(channel, 1024);
    channel->ops->set_send_qlen(channel, 1024);
	
    new_client->source = G_main_add_IPC_Channel(
	G_PRIORITY_DEFAULT, channel, FALSE, stonith_client_callback,
	new_client, stonith_client_destroy);
	
    crm_trace("Channel %s connected for client %s",
		new_client->channel_name, new_client->id);
	
    cl_uuid_generate(&client_id);
    cl_uuid_unparse(&client_id, uuid_str);

    CRM_CHECK(new_client->id == NULL, crm_free(new_client->id));
    new_client->id = crm_strdup(uuid_str);
	
    /* make sure we can find ourselves later for sync calls
     * redirected to the master instance
     */
    g_hash_table_insert(client_list, new_client->id, new_client);
	
    reg_msg = create_xml_node(NULL, "callback");
    crm_xml_add(reg_msg, F_STONITH_OPERATION, CRM_OP_REGISTER);
    crm_xml_add(reg_msg, F_STONITH_CLIENTID,  new_client->id);
	
    send_ipc_message(channel, reg_msg);		
    free_xml(reg_msg);
	
    return TRUE;
}
Example #5
0
gboolean
cib_remote_msg(int csock, gpointer data)
{
    const char *value = NULL;
    xmlNode *command = NULL;
    cib_client_t *client = data;

    crm_trace("%s callback", client->encrypted ? "secure" : "clear-text");

    command = cib_recv_remote_msg(client->channel, client->encrypted);
    if (command == NULL) {
        return FALSE;
    }

    value = crm_element_name(command);
    if (safe_str_neq(value, "cib_command")) {
        crm_log_xml(LOG_MSG, "Bad command: ", command);
        goto bail;
    }

    if (client->name == NULL) {
        value = crm_element_value(command, F_CLIENTNAME);
        if (value == NULL) {
            client->name = crm_strdup(client->id);
        } else {
            client->name = crm_strdup(value);
        }
    }

    if (client->callback_id == NULL) {
        value = crm_element_value(command, F_CIB_CALLBACK_TOKEN);
        if (value != NULL) {
            client->callback_id = crm_strdup(value);
            crm_debug_2("Callback channel for %s is %s", client->id, client->callback_id);

        } else {
            client->callback_id = crm_strdup(client->id);
        }
    }

    /* unset dangerous options */
    xml_remove_prop(command, F_ORIG);
    xml_remove_prop(command, F_CIB_HOST);
    xml_remove_prop(command, F_CIB_GLOBAL_UPDATE);

    crm_xml_add(command, F_TYPE, T_CIB);
    crm_xml_add(command, F_CIB_CLIENTID, client->id);
    crm_xml_add(command, F_CIB_CLIENTNAME, client->name);
#if ENABLE_ACL
    crm_xml_add(command, F_CIB_USER, client->user);
#endif

    if (crm_element_value(command, F_CIB_CALLID) == NULL) {
        cl_uuid_t call_id;
        char call_uuid[UU_UNPARSE_SIZEOF];

        /* fix the command */
        cl_uuid_generate(&call_id);
        cl_uuid_unparse(&call_id, call_uuid);
        crm_xml_add(command, F_CIB_CALLID, call_uuid);
    }

    if (crm_element_value(command, F_CIB_CALLOPTS) == NULL) {
        crm_xml_add_int(command, F_CIB_CALLOPTS, 0);
    }

    crm_log_xml(LOG_MSG, "Remote command: ", command);
    cib_common_callback_worker(command, client, FALSE, TRUE);
  bail:
    free_xml(command);
    command = NULL;
    return TRUE;
}
Example #6
0
gboolean
cib_remote_listen(int ssock, gpointer data)
{
    int lpc = 0;
    int csock = 0;
    unsigned laddr;
    time_t now = 0;
    time_t start = time(NULL);
    struct sockaddr_in addr;

#ifdef HAVE_GNUTLS_GNUTLS_H
    gnutls_session *session = NULL;
#endif
    cib_client_t *new_client = NULL;

    xmlNode *login = NULL;
    const char *user = NULL;
    const char *pass = NULL;
    const char *tmp = NULL;

    cl_uuid_t client_id;
    char uuid_str[UU_UNPARSE_SIZEOF];

#ifdef HAVE_DECL_NANOSLEEP
    const struct timespec sleepfast = { 0, 10000000 };  /* 10 millisec */
#endif

    /* accept the connection */
    laddr = sizeof(addr);
    csock = accept(ssock, (struct sockaddr *)&addr, &laddr);
    crm_debug("New %s connection from %s",
              ssock == remote_tls_fd ? "secure" : "clear-text", inet_ntoa(addr.sin_addr));

    if (csock == -1) {
        crm_err("accept socket failed");
        return TRUE;
    }

    if (ssock == remote_tls_fd) {
#ifdef HAVE_GNUTLS_GNUTLS_H
        /* create gnutls session for the server socket */
        session = create_tls_session(csock, GNUTLS_SERVER);
        if (session == NULL) {
            crm_err("TLS session creation failed");
            close(csock);
            return TRUE;
        }
#endif
    }

    do {
        crm_trace("Iter: %d", lpc++);
        if (ssock == remote_tls_fd) {
#ifdef HAVE_GNUTLS_GNUTLS_H
            login = cib_recv_remote_msg(session, TRUE);
#endif
        } else {
            login = cib_recv_remote_msg(GINT_TO_POINTER(csock), FALSE);
        }
        if (login != NULL) {
            break;
        }
#ifdef HAVE_DECL_NANOSLEEP
        nanosleep(&sleepfast, NULL);
#else
        sleep(1);
#endif
        now = time(NULL);

        /* Peers have 3s to connect */
    } while (login == NULL && (start - now) < 4);

    crm_log_xml_info(login, "Login: "******"cib_command")) {
        crm_err("Wrong tag: %s", tmp);
        goto bail;
    }

    tmp = crm_element_value(login, "op");
    if (safe_str_neq(tmp, "authenticate")) {
        crm_err("Wrong operation: %s", tmp);
        goto bail;
    }

    user = crm_element_value(login, "user");
    pass = crm_element_value(login, "password");

    /* Non-root daemons can only validate the password of the
     * user they're running as
     */
    if (check_group_membership(user, CRM_DAEMON_GROUP) == FALSE) {
        crm_err("User is not a member of the required group");
        goto bail;

    } else if (authenticate_user(user, pass) == FALSE) {
        crm_err("PAM auth failed");
        goto bail;
    }

    /* send ACK */
    crm_malloc0(new_client, sizeof(cib_client_t));
    num_clients++;
    new_client->channel_name = "remote";
    new_client->name = crm_element_value_copy(login, "name");

    cl_uuid_generate(&client_id);
    cl_uuid_unparse(&client_id, uuid_str);

    CRM_CHECK(new_client->id == NULL, crm_free(new_client->id));
    new_client->id = crm_strdup(uuid_str);

#if ENABLE_ACL
    new_client->user = crm_strdup(user);
#endif

    new_client->callback_id = NULL;
    if (ssock == remote_tls_fd) {
#ifdef HAVE_GNUTLS_GNUTLS_H
        new_client->encrypted = TRUE;
        new_client->channel = (void *)session;
#endif
    } else {
        new_client->channel = GINT_TO_POINTER(csock);
    }

    free_xml(login);
    login = create_xml_node(NULL, "cib_result");
    crm_xml_add(login, F_CIB_OPERATION, CRM_OP_REGISTER);
    crm_xml_add(login, F_CIB_CLIENTID, new_client->id);
    cib_send_remote_msg(new_client->channel, login, new_client->encrypted);
    free_xml(login);

    new_client->source =
        (void *)G_main_add_fd(G_PRIORITY_DEFAULT, csock, FALSE, cib_remote_msg, new_client,
                              cib_remote_connection_destroy);

    g_hash_table_insert(client_list, new_client->id, new_client);

    return TRUE;

  bail:
    if (ssock == remote_tls_fd) {
#ifdef HAVE_GNUTLS_GNUTLS_H
        gnutls_bye(*session, GNUTLS_SHUT_RDWR);
        gnutls_deinit(*session);
        gnutls_free(session);
#endif
    }
    close(csock);
    free_xml(login);
    return TRUE;
}
Example #7
0
/*	 A_TE_START, A_TE_STOP, A_TE_RESTART	*/
void
do_te_control(long long action,
	      enum crmd_fsa_cause cause,
	      enum crmd_fsa_state cur_state,
	      enum crmd_fsa_input current_input,
	      fsa_data_t *msg_data)
{
    int dummy;
    gboolean init_ok = TRUE;
	
    cl_uuid_t new_uuid;
    char uuid_str[UU_UNPARSE_SIZEOF];
	
    if(action & A_TE_STOP) {
	if(transition_graph) {
	    destroy_graph(transition_graph);
	    transition_graph = NULL;
	}

	if(fsa_cib_conn && cib_ok != fsa_cib_conn->cmds->del_notify_callback(
	       fsa_cib_conn, T_CIB_DIFF_NOTIFY, te_update_diff)) {
	    crm_err("Could not unset CIB notification callback");
	}

	clear_bit_inplace(fsa_input_register, te_subsystem->flag_connected);
	crm_info("Transitioner is now inactive");
	
	if(stonith_src) {
	    GCHSource *source = stonith_src;
	    crm_info("Disconnecting STONITH...");
	    stonith_src = NULL; /* so that we don't try to reconnect */
	    G_main_del_IPC_Channel(source);
	    stonithd_signoff();	    
	}
    }

    if((action & A_TE_START) == 0) {
	return;

    } else if(is_set(fsa_input_register, te_subsystem->flag_connected)) {
	crm_debug("The transitioner is already active");
	return;

    } else if((action & A_TE_START) && cur_state == S_STOPPING) {
	crm_info("Ignoring request to start %s while shutting down",
		 te_subsystem->name);
	return;
    }	

    cl_uuid_generate(&new_uuid);
    cl_uuid_unparse(&new_uuid, uuid_str);
    te_uuid = crm_strdup(uuid_str);
    crm_info("Registering TE UUID: %s", te_uuid);
	
    if(transition_trigger == NULL) {
	transition_trigger = mainloop_add_trigger(
	    G_PRIORITY_LOW, te_graph_trigger, NULL);
    }

    if(stonith_reconnect == NULL) {
	stonith_reconnect = mainloop_add_trigger(
	    G_PRIORITY_LOW, te_connect_stonith, &dummy);
    }
		    
    if(cib_ok != fsa_cib_conn->cmds->add_notify_callback(
	   fsa_cib_conn, T_CIB_DIFF_NOTIFY, te_update_diff)) {
	crm_err("Could not set CIB notification callback");
	init_ok = FALSE;
    }

    if(cib_ok != fsa_cib_conn->cmds->set_op_callback(fsa_cib_conn, global_cib_callback)) {
	crm_err("Could not set CIB global callback");
	init_ok = FALSE;
    }
    
    if(init_ok) {
	mainloop_set_trigger(stonith_reconnect);

	set_graph_functions(&te_graph_fns);

	if(transition_graph) {
	    destroy_graph(transition_graph);			    
	}
			
	/* create a blank one */
	crm_debug("Transitioner is now active");
	transition_graph = create_blank_graph();
	set_bit_inplace(fsa_input_register, te_subsystem->flag_connected);
    }
}