コード例 #1
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;
}
コード例 #2
0
ファイル: utils.c プロジェクト: aspiers/pacemaker
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;
}