Ejemplo n.º 1
0
gboolean
stop_child(crm_child_t *child, int signal)
{
    if(signal == 0) {
	signal = SIGTERM;
    }

    if(child->command == NULL) {
	ais_info("Nothing to do for child \"%s\"", child->name);
	return TRUE;
    }
    
    ais_debug("Stopping CRM child \"%s\"", child->name);
    
    if (child->pid <= 0) {
	ais_debug_2("Client %s not running", child->name);
	return TRUE;
    }
    
    errno = 0;
    if(kill(child->pid, signal) == 0) {
	ais_notice("Sent -%d to %s: [%d]", signal, child->name, child->pid);
	
    } else {
	ais_perror("Sent -%d to %s: [%d]", signal, child->name, child->pid);
    }
    
    return TRUE;
}
Ejemplo n.º 2
0
void destroy_ais_node(gpointer data) 
{
    crm_node_t *node = data;
    ais_info("Destroying entry for node %u", node->id);

    ais_free(node->addr);
    ais_free(node->uname);
    ais_free(node->state);
    ais_free(node);
}
Ejemplo n.º 3
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;
}
Ejemplo n.º 4
0
static void
pcmk_setscheduler(crm_child_t * child)
{
#if defined(HAVE_SCHED_SETSCHEDULER)
    int policy = sched_getscheduler(0);

    if (policy == -1) {
        ais_perror("Could not get scheduling policy for %s", child->name);

    } else {
        int priority = -10;

        if (policy != SCHED_OTHER) {
            struct sched_param sp;

            policy = SCHED_OTHER;
#  if defined(SCHED_RESET_ON_FORK)
            policy |= SCHED_RESET_ON_FORK;
#  endif
            memset(&sp, 0, sizeof(sp));
            sp.sched_priority = 0;

            if (sched_setscheduler(0, policy, &sp) == -1) {
                ais_perror("Could not reset scheduling policy to SCHED_OTHER for %s", child->name);
                return;
            }
        }

        if (setpriority(PRIO_PROCESS, 0, priority) == -1) {
            ais_perror("Could not reset process priority to %d for %s", priority, child->name);
        }
    }
#else
    ais_info("The platform is missing process priority setting features. Leaving at default.");
#endif
}
Ejemplo n.º 5
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;
}
Ejemplo n.º 6
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;
}
Ejemplo n.º 7
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;
}