Example #1
0
char *get_ais_data(const AIS_Message *msg)
{
    int rc = BZ_OK;
    char *uncompressed = NULL;
    unsigned int new_size = msg->size + 1;
    
    if(msg->is_compressed == FALSE) {
	uncompressed = strdup(msg->data);

    } else {
	ais_malloc0(uncompressed, new_size);
	
	rc = BZ2_bzBuffToBuffDecompress(
	    uncompressed, &new_size, (char*)msg->data, msg->compressed_size, 1, 0);
	if(rc != BZ_OK) {
	    ais_info("rc=%d, new=%u expected=%u", rc, new_size, msg->size);
	}
	AIS_ASSERT(rc == BZ_OK);
	AIS_ASSERT(new_size == msg->size);
    }
    
    return uncompressed;
}
Example #2
0
int
send_plugin_msg(enum crm_ais_msg_types type, const char *host, const char *data)
{
    int rc = 0;
    int data_len = 0;
    AIS_Message *ais_msg = NULL;
    int total_size = sizeof(AIS_Message);

    AIS_ASSERT(local_nodeid != 0);

    if (data != NULL) {
        data_len = 1 + strlen(data);
        total_size += data_len;
    }
    ais_malloc0(ais_msg, total_size);

    ais_msg->header.size = total_size;
    ais_msg->header.error = CS_OK;
    ais_msg->header.id = 0;

    ais_msg->size = data_len;
    ais_msg->sender.type = crm_msg_ais;
    if (data != NULL) {
        memcpy(ais_msg->data, data, data_len);
    }

    ais_msg->host.type = type;
    ais_msg->host.id = 0;
    if (host) {
        ais_msg->host.size = strlen(host);
        memset(ais_msg->host.uname, 0, MAX_NAME);
        memcpy(ais_msg->host.uname, host, ais_msg->host.size);
/* 	ais_msg->host.id = nodeid_lookup(host); */

    } else {
        ais_msg->host.type = type;
        ais_msg->host.size = 0;
        memset(ais_msg->host.uname, 0, MAX_NAME);
    }

    rc = send_plugin_msg_raw(ais_msg);
    ais_free(ais_msg);

    return rc;
}
Example #3
0
gboolean spawn_child(crm_child_t *child)
{
    int lpc = 0;
    uid_t uid = 0;
    struct rlimit oflimits;
    gboolean use_valgrind = FALSE;
    const char *devnull = "/dev/null";
    const char *env_valgrind = getenv("HA_VALGRIND_ENABLED");
    
    if(child->command == NULL) {
	ais_info("Nothing to do for child \"%s\"", child->name);
	return TRUE;
    }
    
    if(env_valgrind == NULL) {
	use_valgrind = FALSE;

    } else if(ais_string_to_boolean(env_valgrind)) {
	use_valgrind = TRUE;

    } else if(strstr(env_valgrind, child->name)) {
	use_valgrind = TRUE;
    }

    if(use_valgrind && strlen(VALGRIND_BIN) == 0) {
	ais_warn("Cannot enable valgrind for %s:"
		 " The location of the valgrind binary is unknown", child->name);
	use_valgrind = FALSE;
    }

    if(child->uid) {
	if(pcmk_user_lookup(child->uid, &uid, NULL) < 0) {
	    ais_err("Invalid uid (%s) specified for %s",
		    child->uid, child->name);
	    return FALSE;
	}
    }
	
    child->pid = fork();
    AIS_ASSERT(child->pid != -1);

    if(child->pid > 0) {
	/* parent */
	ais_info("Forked child %d for process %s%s", child->pid, child->name,
		 use_valgrind?" (valgrind enabled)":"");

    } else {
	/* Setup the two alternate arg arrarys */ 
	opts_vgrind[0] = ais_strdup(VALGRIND_BIN);
	opts_vgrind[1] = ais_strdup(child->command);
	opts_default[0] = opts_vgrind[1];
	
#if 0
	/* Dont set the group for now - it prevents connection to the cluster */
	if(gid && setgid(gid) < 0) {
	    ais_perror("Could not set group to %d", gid);
	}
#endif

	if(uid && setuid(uid) < 0) {
	    ais_perror("Could not set user to %d (%s)", uid, child->uid);
	}
	
	/* Close all open file descriptors */
	getrlimit(RLIMIT_NOFILE, &oflimits);
	for (; lpc < oflimits.rlim_cur; lpc++) {
	    close(lpc);
	}
	
	(void)open(devnull, O_RDONLY);	/* Stdin:  fd 0 */
	(void)open(devnull, O_WRONLY);	/* Stdout: fd 1 */
	(void)open(devnull, O_WRONLY);	/* Stderr: fd 2 */

	setenv("HA_COMPRESSION",	"bz2",             1);
	setenv("HA_cluster_type",	"openais",	   1);
	setenv("HA_debug",		pcmk_env.debug,    1);
	setenv("HA_logfacility",	pcmk_env.syslog,   1);
	setenv("HA_LOGFACILITY",	pcmk_env.syslog,   1);
	setenv("HA_use_logd",		pcmk_env.use_logd, 1);
	if(pcmk_env.logfile) {
	    setenv("HA_debugfile", pcmk_env.logfile, 1);
	}
	
	if(use_valgrind) {
	    (void)execvp(VALGRIND_BIN, opts_vgrind);
	} else {
	    (void)execvp(child->command, opts_default);
	}
	ais_perror("FATAL: Cannot exec %s", child->command);
	exit(100);
    }
    return TRUE;
}
Example #4
0
int update_member(unsigned int id, uint64_t born, uint64_t seq, int32_t votes,
		  uint32_t procs, const char *uname, const char *state, const char *version) 
{
    int changed = 0;
    crm_node_t *node = NULL;
    
    node = g_hash_table_lookup(membership_list, GUINT_TO_POINTER(id));	

    if(node == NULL) {	
	ais_malloc0(node, sizeof(crm_node_t));
	ais_info("Creating entry for node %u born on "U64T"", id, seq);
	node->id = id;
	node->addr = NULL;
	node->state = ais_strdup("unknown");
	
	g_hash_table_insert(membership_list, GUINT_TO_POINTER(id), node);
	node = g_hash_table_lookup(membership_list, GUINT_TO_POINTER(id));
    }

    if(seq != 0) {
	node->last_seen = seq;
    }

    if(born != 0 && node->born != born) {
	changed = TRUE;
	node->born = born;
	ais_info("%p Node %u (%s) born on: "U64T, node, id, node->uname, born);
    }

    if(version != NULL) {
	ais_free(node->version);
	node->version = ais_strdup(version);
    }
    
    if(uname != NULL) {
	if(node->uname == NULL || ais_str_eq(node->uname, uname) == FALSE) {
	    ais_info("%p Node %u now known as %s (was: %s)",
		     node, id, uname, node->uname);
	    ais_free(node->uname);
	    node->uname = ais_strdup(uname);
	    changed = TRUE;
	}
    }

    if(procs != 0 && procs != node->processes) {
	ais_info("Node %s now has process list: %.32x (%u)",
		 node->uname, procs, procs);
	node->processes = procs;
	changed = TRUE;
    }

    if(votes >= 0 && votes != node->votes) {
	ais_info("Node %s now has %d quorum votes (was %d)",
		 node->uname, votes, node->votes);
	node->votes = votes;
	changed = TRUE;
    }
    
    if(state != NULL) {
	if(node->state == NULL || ais_str_eq(node->state, state) == FALSE) {
	    ais_free(node->state);
	    node->state = ais_strdup(state);
	    ais_info("Node %u/%s is now: %s",
		     id, node->uname?node->uname:"unknown", state);
	    changed = TRUE;
	}
    }
    
    AIS_ASSERT(node != NULL);
    return changed;
}
Example #5
0
gboolean
spawn_child(crm_child_t * child)
{
    int lpc = 0;
    uid_t uid = 0;
    gid_t gid = 0;
    struct rlimit oflimits;
    gboolean use_valgrind = FALSE;
    gboolean use_callgrind = FALSE;
    const char *devnull = "/dev/null";
    const char *env_valgrind = getenv("PCMK_valgrind_enabled");
    const char *env_callgrind = getenv("PCMK_callgrind_enabled");

    if (child->command == NULL) {
        ais_info("Nothing to do for child \"%s\"", child->name);
        return TRUE;
    }

    if (ais_string_to_boolean(env_callgrind)) {
        use_callgrind = TRUE;
        use_valgrind = TRUE;

    } else if (env_callgrind != NULL && strstr(env_callgrind, child->name)) {
        use_callgrind = TRUE;
        use_valgrind = TRUE;

    } else if (ais_string_to_boolean(env_valgrind)) {
        use_valgrind = TRUE;

    } else if (env_valgrind != NULL && strstr(env_valgrind, child->name)) {
        use_valgrind = TRUE;
    }

    if (use_valgrind && strlen(VALGRIND_BIN) == 0) {
        ais_warn("Cannot enable valgrind for %s:"
                 " The location of the valgrind binary is unknown", child->name);
        use_valgrind = FALSE;
    }

    if (child->uid) {
        if (pcmk_user_lookup(child->uid, &uid, &gid) < 0) {
            ais_err("Invalid uid (%s) specified for %s", child->uid, child->name);
            return FALSE;
        }
        ais_info("Using uid=%u and group=%u for process %s", uid, gid, child->name);
    }

    child->pid = fork();
    AIS_ASSERT(child->pid != -1);

    if (child->pid > 0) {
        /* parent */
        ais_info("Forked child %d for process %s%s", child->pid, child->name,
                 use_valgrind ? " (valgrind enabled: " VALGRIND_BIN ")" : "");

    } else {
        pcmk_setscheduler(child);

        /* Setup the two alternate arg arrarys */
        opts_vgrind[0] = ais_strdup(VALGRIND_BIN);
        if (use_callgrind) {
            opts_vgrind[1] = ais_strdup("--tool=callgrind");
            opts_vgrind[2] = ais_strdup("--callgrind-out-file=" CRM_STATE_DIR "/callgrind.out.%p");
            opts_vgrind[3] = ais_strdup(child->command);
            opts_vgrind[4] = NULL;
        } else {
            opts_vgrind[1] = ais_strdup(child->command);
            opts_vgrind[2] = NULL;
            opts_vgrind[3] = NULL;
            opts_vgrind[4] = NULL;
        }
        opts_default[0] = ais_strdup(child->command);;

        if (uid && initgroups(child->uid, gid) < 0) {
            ais_perror("Cannot initialize groups for %s", child->uid);
        }

        if (uid && setuid(uid) < 0) {
            ais_perror("Could not set user to %d (%s)", uid, child->uid);
        }

        /* Close all open file descriptors */
        getrlimit(RLIMIT_NOFILE, &oflimits);
        for (; lpc < oflimits.rlim_cur; lpc++) {
            close(lpc);
        }

        (void)open(devnull, O_RDONLY);  /* Stdin:  fd 0 */
        (void)open(devnull, O_WRONLY);  /* Stdout: fd 1 */
        (void)open(devnull, O_WRONLY);  /* Stderr: fd 2 */

/* *INDENT-OFF* */
	setenv("HA_COMPRESSION",	"bz2",             1);
	setenv("HA_cluster_type",	"openais",	   1);
	setenv("HA_debug",		pcmk_env.debug,    1);
	setenv("HA_logfacility",	pcmk_env.syslog,   1);
	setenv("HA_LOGFACILITY",	pcmk_env.syslog,   1);
	setenv("HA_use_logd",		pcmk_env.use_logd, 1);
	setenv("HA_quorum_type",	pcmk_env.quorum,   1);
/* *INDENT-ON* */

        if (pcmk_env.logfile) {
            setenv("HA_logfile", pcmk_env.logfile, 1);
        }

        if (use_valgrind) {
            (void)execvp(VALGRIND_BIN, opts_vgrind);
        } else {
            (void)execvp(child->command, opts_default);
        }
        ais_perror("FATAL: Cannot exec %s", child->command);
        exit(100);
    }
    return TRUE;
}