Example #1
0
void
crm_enable_blackbox(int nsig)
{
    if (blackbox_file_prefix == NULL) {
        pid_t pid = getpid();

        blackbox_file_prefix = malloc(NAME_MAX);
        snprintf(blackbox_file_prefix, NAME_MAX, "%s/%s-%d", CRM_BLACKBOX_DIR, crm_system_name,
                 pid);
    }

    if (qb_log_ctl(QB_LOG_BLACKBOX, QB_LOG_CONF_STATE_GET, 0) != QB_LOG_STATE_ENABLED) {
        qb_log_ctl(QB_LOG_BLACKBOX, QB_LOG_CONF_SIZE, 5 * 1024 * 1024); /* Any size change drops existing entries */
        qb_log_ctl(QB_LOG_BLACKBOX, QB_LOG_CONF_ENABLED, QB_TRUE);      /* Setting the size seems to disable it */

        crm_notice("Initiated blackbox recorder: %s", blackbox_file_prefix);

        /* Save to disk on abnormal termination */
        crm_signal(SIGSEGV, crm_trigger_blackbox);
        crm_signal(SIGABRT, crm_trigger_blackbox);
        crm_signal(SIGILL,  crm_trigger_blackbox);
        crm_signal(SIGBUS,  crm_trigger_blackbox);

        crm_update_callsites();

        blackbox_trigger = qb_log_custom_open(blackbox_logger, NULL, NULL, NULL);
        qb_log_ctl(blackbox_trigger, QB_LOG_CONF_ENABLED, QB_TRUE);
        crm_trace("Trigger: %d is %d %d", blackbox_trigger,
                  qb_log_ctl(blackbox_trigger, QB_LOG_CONF_STATE_GET, 0), QB_LOG_STATE_ENABLED);

        crm_update_callsites();
    }
}
Example #2
0
void
alter_debug(int nsig) 
{
	crm_signal(DEBUG_INC, alter_debug);
	crm_signal(DEBUG_DEC, alter_debug);
	
	switch(nsig) {
		case DEBUG_INC:
			if (crm_log_level < 100) {
				crm_log_level++;
			}
			break;

		case DEBUG_DEC:
			if (crm_log_level > 0) {
				crm_log_level--;
			}
			break;	

		default:
			fprintf(stderr, "Unknown signal %d\n", nsig);
			cl_log(LOG_ERR, "Unknown signal %d", nsig);
			break;	
	}
}
Example #3
0
gboolean
crm_log_init(
    const char *entity, int level, gboolean coredir, gboolean to_stderr,
    int argc, char **argv)
{
	/* Redirect messages from glib functions to our handler */
/*  	cl_malloc_forced_for_glib(); */
#ifdef HAVE_G_LOG_SET_DEFAULT_HANDLER
	glib_log_default = g_log_set_default_handler(crm_glib_handler, NULL);
#endif
	
	/* and for good measure... - this enum is a bit field (!) */
	g_log_set_always_fatal((GLogLevelFlags)0); /*value out of range*/
	
	crm_system_name = entity;
	setenv("PCMK_service", crm_system_name, 1);
	cl_log_set_entity(entity);
	if(argc == 0) {
	    /* Nuke any syslog activity */
	    unsetenv("HA_logfacility");

	} else if(getenv("HA_logfacility") == NULL) {
	    /* Set a default */
	    cl_log_set_facility(HA_LOG_FACILITY);
	} /* else: picked up by crm_set_env_options() */
	
	if(coredir) {
	    int user = getuid();
	    struct passwd *pwent = NULL;
	    const char *base = HA_COREDIR;
	    
	    pwent = getpwuid(user);

	    if (chdir(base) < 0) {
		crm_perror(LOG_ERR, "Cannot change active directory to %s", base);

	    } else if (pwent == NULL) {
		crm_perror(LOG_ERR, "Cannot get name for uid: %d", user);

	    } else if (chdir(pwent->pw_name) < 0) {
		crm_perror(LOG_ERR, "Cannot change active directory to %s/%s", base, pwent->pw_name);

	    } else {
		crm_info("Changed active directory to %s/%s", base, pwent->pw_name);
	    }
	}
	
	set_crm_log_level(level);
	crm_set_env_options();

	cl_log_args(argc, argv);
	cl_log_enable_stderr(to_stderr);

	crm_signal(DEBUG_INC, alter_debug);
	crm_signal(DEBUG_DEC, alter_debug);

	return TRUE;
}
Example #4
0
void
crm_enable_blackbox(int nsig)
{
    if(blackbox_file_prefix == NULL) {
        pid_t pid = getpid();

        blackbox_file_prefix = malloc(NAME_MAX);
        snprintf(blackbox_file_prefix, NAME_MAX, "%s/blackbox-%s-%d", CRM_BLACKBOX_DIR, crm_system_name, pid);
    }

    if (qb_log_ctl(QB_LOG_BLACKBOX, QB_LOG_CONF_STATE_GET, 0) != QB_LOG_STATE_ENABLED) {
        qb_log_ctl(QB_LOG_BLACKBOX, QB_LOG_CONF_SIZE, 1024*1024); /* Any size change drops existing entries */
        qb_log_ctl(QB_LOG_BLACKBOX, QB_LOG_CONF_ENABLED, QB_TRUE); /* Setting the size seems to disable it */

        crm_notice("Initiated blackbox recorder: %s", blackbox_file_prefix);
        crm_signal(SIGSEGV, crm_write_blackbox);
        crm_update_callsites();

        /* Original meanings from signal(7) 
         *
         * Signal       Value     Action   Comment
         * SIGPROF     27,27,29    Term    Profiling timer expired
         * SIGTRAP        5        Core    Trace/breakpoint trap
         *
         * Our usage is as similar as possible
         */
        mainloop_add_signal(SIGPROF, crm_enable_blackbox_tracing);
        mainloop_add_signal(SIGTRAP, crm_write_blackbox);
    }
}
Example #5
0
gboolean
mainloop_add_signal(int sig, void (*dispatch) (int sig))
{
    GSource *source = NULL;
    int priority = G_PRIORITY_HIGH - 1;

    if (sig == SIGTERM) {
        /* TERM is higher priority than other signals,
         *   signals are higher priority than other ipc.
         * Yes, minus: smaller is "higher"
         */
        priority--;
    }

    if (sig >= NSIG || sig < 0) {
        crm_err("Signal %d is out of range", sig);
        return FALSE;

    } else if (crm_signals[sig] != NULL
               && crm_signals[sig]->handler == dispatch) {
        crm_trace("Signal handler for %d is already installed", sig);
        return TRUE;

    } else if (crm_signals[sig] != NULL) {
        crm_err("Different signal handler for %d is already installed", sig);
        return FALSE;
    }

    CRM_ASSERT(sizeof(crm_signal_t) > sizeof(GSource));
    source = g_source_new(&crm_signal_funcs, sizeof(crm_signal_t));

    crm_signals[sig] = (crm_signal_t *) mainloop_setup_trigger(source, priority, NULL, NULL);
    CRM_ASSERT(crm_signals[sig] != NULL);

    crm_signals[sig]->handler = dispatch;
    crm_signals[sig]->signal = sig;

    if (crm_signal(sig, mainloop_signal_handler) == FALSE) {
        crm_signal_t *tmp = crm_signals[sig];

        crm_signals[sig] = NULL;

        mainloop_destroy_trigger((crm_trigger_t *) tmp);
        return FALSE;
    }
#if 0
    /* If we want signals to interrupt mainloop's poll(), instead of waiting for
     * the timeout, then we should call siginterrupt() below
     *
     * For now, just enforce a low timeout
     */
    if (siginterrupt(sig, 1) < 0) {
        crm_perror(LOG_INFO, "Could not enable system call interruptions for signal %d", sig);
    }
#endif

    return TRUE;
}
Example #6
0
void
crm_write_blackbox(int nsig, struct qb_log_callsite *cs)
{
    static int counter = 1;
    static time_t last = 0;

    char buffer[NAME_MAX];
    time_t now = time(NULL);

    if (blackbox_file_prefix == NULL) {
        return;
    }

    switch (nsig) {
        case 0:
        case SIGABRT:
        case SIGTRAP:
            /* The graceful case - such as assertion failure or user request */

            if (nsig == 0 && now == last) {
                /* Prevent over-dumping */
                return;
            }

            snprintf(buffer, NAME_MAX, "%s.%d", blackbox_file_prefix, counter++);
            if (nsig == SIGTRAP) {
                crm_notice("Blackbox dump requested, please see %s for contents", buffer);

            } else if (cs) {
                syslog(LOG_NOTICE,
                       "Problem detected at %s:%d (%s), please see %s for additional details",
                       cs->function, cs->lineno, cs->filename, buffer);
            } else {
                crm_notice("Problem detected, please see %s for additional details", buffer);
            }

            last = now;
            qb_log_blackbox_write_to_file(buffer);

            /* Flush the existing contents
             * A size change would also work
             */
            qb_log_ctl(QB_LOG_BLACKBOX, QB_LOG_CONF_ENABLED, QB_FALSE);
            qb_log_ctl(QB_LOG_BLACKBOX, QB_LOG_CONF_ENABLED, QB_TRUE);
            break;

        default:
            /* Do as little as possible, just try to get what we have out
             * We logged the filename when the blackbox was enabled
             */
            crm_signal(nsig, SIG_DFL);
            qb_log_blackbox_write_to_file(blackbox_file_prefix);
            qb_log_ctl(QB_LOG_BLACKBOX, QB_LOG_CONF_ENABLED, QB_FALSE);
            raise(nsig);
            break;
    }
}
Example #7
0
gboolean
mainloop_destroy_signal(int sig)
{
    crm_signal_t *tmp = NULL;

    if (sig >= NSIG || sig < 0) {
        crm_err("Signal %d is out of range", sig);
        return FALSE;

    } else if (crm_signal(sig, NULL) == FALSE) {
        crm_perror(LOG_ERR, "Could not uninstall signal handler for signal %d", sig);
        return FALSE;

    } else if (crm_signals[sig] == NULL) {
        return TRUE;
    }

    tmp = crm_signals[sig];
    crm_signals[sig] = NULL;
    mainloop_destroy_trigger((crm_trigger_t *) tmp);
    return TRUE;
}
Example #8
0
int
main(int argc, char **argv)
{
    int argerr = 0;
    int flag;
    int attempts = 0;

#ifdef HAVE_GETOPT_H
    int option_index = 0;

    static struct option long_options[] = {
        /* Top-level Options */
        {"verbose", 0, 0, 'V'},
        {"help", 0, 0, '?'},
        {"log-diffs", 0, 0, 'd'},
        {"log-updates", 0, 0, 'u'},
        {"max-conn-fail", 1, 0, 'm'},
        {0, 0, 0, 0}
    };
#endif

    crm_log_cli_init("cibmon");

    crm_signal(SIGTERM, cibmon_shutdown);

    while (1) {
#ifdef HAVE_GETOPT_H
        flag = getopt_long(argc, argv, OPTARGS, long_options, &option_index);
#else
        flag = getopt(argc, argv, OPTARGS);
#endif
        if (flag == -1)
            break;

        switch (flag) {
            case 'V':
                crm_bump_log_level(argc, argv);
                break;
            case '?':
                usage(crm_system_name, EX_OK);
                break;
            case 'd':
                log_diffs = TRUE;
                break;
            case 'u':
                log_updates = TRUE;
                break;
            case 'm':
                max_failures = crm_parse_int(optarg, "30");
                break;
            default:
                printf("Argument code 0%o (%c)" " is not (?yet?) supported\n", flag, flag);
                ++argerr;
                break;
        }
    }

    if (optind < argc) {
        printf("non-option ARGV-elements: ");
        while (optind < argc)
            printf("%s ", argv[optind++]);
        printf("\n");
    }

    if (optind > argc) {
        ++argerr;
    }

    if (argerr) {
        usage(crm_system_name, EX_USAGE);
    }

    cib = cib_new();

    do {
        sleep(1);
        exit_code = cib->cmds->signon(cib, crm_system_name, cib_query);

    } while (exit_code == -ENOTCONN && attempts++ < max_failures);

    if (exit_code != pcmk_ok) {
        crm_err("Signon to CIB failed: %s", pcmk_strerror(exit_code));
    }

    if (exit_code == pcmk_ok) {
        crm_debug("Setting dnotify");
        exit_code = cib->cmds->set_connection_dnotify(cib, cib_connection_destroy);
    }

    crm_debug("Setting diff callback");
    exit_code = cib->cmds->add_notify_callback(cib, T_CIB_DIFF_NOTIFY, cibmon_diff);

    if (exit_code != pcmk_ok) {
        crm_err("Failed to set %s callback: %s", T_CIB_DIFF_NOTIFY, pcmk_strerror(exit_code));
    }

    if (exit_code != pcmk_ok) {
        crm_err("Setup failed, could not monitor CIB actions");
        return -exit_code;
    }

    mainloop = g_main_new(FALSE);
    crm_info("Starting mainloop");
    g_main_run(mainloop);
    crm_trace("%s exiting normally", crm_system_name);
    fflush(stderr);
    return -exit_code;
}