Example #1
0
void *start_gearmand(void*data) {
    int sid;
    data = data; // warning: unused parameter 'data'
    pid_t pid = fork();
    if(pid == 0) {
        sid = setsid();
        char port[30];
        snprintf(port, 30, "--port=%d", GEARMAND_TEST_PORT);
        /* for newer gearman versions */
        if(atof(gearman_version()) >= 0.27) {
            execlp("gearmand", "gearmand", "--listen=127.0.0.1", "--threads=10", "--job-retries=0", port, "--verbose=DEBUG", "--log-file=/tmp/gearmand.log" , (char *)NULL);
        } else if(atof(gearman_version()) > 0.14) {
            execlp("gearmand", "gearmand", "--listen=127.0.0.1", "--threads=10", "--job-retries=0", port, "--verbose=999", "--log-file=/tmp/gearmand.log" , (char *)NULL);
        } else {
            /* for gearman 0.14 */
            execlp("gearmand", "gearmand", "-t 10", "-j 0", port, (char *)NULL);
        }
        perror("gearmand");
        exit(1);
    }
    else {
        gearmand_pid = pid;
    }
    return NULL;
}
Example #2
0
/* print version */
void print_version() {
    printf("send_gearman: version %s running on libgearman %s\n", GM_VERSION, gearman_version());
    printf("\n");
    exit( STATE_UNKNOWN );
}
Example #3
0
/* create a task and send it */
int add_job_to_queue( gearman_client_st *client, char ** server_list, char * queue, char * uniq, char * data, int priority, int retries, int transport_mode, int send_now ) {
    gearman_task_st *task = NULL;
    gearman_return_t ret1, ret2;
    char * crypted_data;
    int size, free_uniq;
    struct timeval now;

    /* check too long queue names */
    if(strlen(queue) > 63) {
        gm_log( GM_LOG_ERROR, "queue name too long: '%s'\n", queue );
        return GM_ERROR;
    }

    /* cut off to long uniq ids */
    free_uniq = 0;
    if(uniq != NULL && strlen(uniq) > 63) {
        uniq = strndup(uniq, 63);
        free_uniq = 1;
    }

    signal(SIGPIPE, SIG_IGN);

    gm_log( GM_LOG_TRACE, "add_job_to_queue(%s, %s, %d, %d, %d, %d)\n", queue, uniq, priority, retries, transport_mode, send_now );
    gm_log( GM_LOG_TRACE, "%d --->%s<---\n", strlen(data), data );

    crypted_data = malloc(GM_BUFFERSIZE);
    size = mod_gm_encrypt(&crypted_data, data, transport_mode);
    gm_log( GM_LOG_TRACE, "%d +++>\n%s\n<+++\n", size, crypted_data );

#ifdef GM_DEBUG
    /* verify decrypted string is equal to the original */
    char * test;
    test = malloc(GM_BUFFERSIZE);
    mod_gm_decrypt(&test, crypted_data, transport_mode);
    gm_log( GM_LOG_TRACE, "%d ===>\n%s\n<===\n", size, test );
    if(strcmp(test, data)) {
        gm_log( GM_LOG_ERROR, "%d --->%s<---\n", strlen(data), data );
        gm_log( GM_LOG_ERROR, "%d ===>\n%s\n<===\n", size, test );
        fprintf(stderr, "encrypted string does not match\n");
        exit(EXIT_FAILURE);
    }
#endif

    if( priority == GM_JOB_PRIO_LOW ) {
        task = gearman_client_add_task_low_background( client, NULL, NULL, queue, uniq, ( void * )crypted_data, ( size_t )size, &ret1 );
        gearman_task_give_workload(task,crypted_data,size);
    }
    else if( priority == GM_JOB_PRIO_NORMAL ) {
        task = gearman_client_add_task_background( client, NULL, NULL, queue, uniq, ( void * )crypted_data, ( size_t )size, &ret1 );
        gearman_task_give_workload(task,crypted_data,size);
    }
    else if( priority == GM_JOB_PRIO_HIGH ) {
        task = gearman_client_add_task_high_background( client, NULL, NULL, queue, uniq, ( void * )crypted_data, ( size_t )size, &ret1 );
        gearman_task_give_workload(task,crypted_data,size);
    }
    else {
        gm_log( GM_LOG_ERROR, "add_job_to_queue() wrong priority: %d\n", priority );
    }

    if(send_now != TRUE)
        return GM_OK;

    ret2 = gearman_client_run_tasks( client );
    gearman_client_task_free_all( client );
    if(   ret1 != GEARMAN_SUCCESS
       || ret2 != GEARMAN_SUCCESS
       || task == NULL
       || ( gearman_client_error(client) != NULL && atof(gearman_version()) == 0.14 )
      ) {

        /* log the error */
        if(retries == 0) {
            gettimeofday(&now,NULL);
            /* only log the first error, otherwise we would fill the log very quickly */
            if( mod_gm_con_errors == 0 ) {
                gettimeofday(&mod_gm_error_time,NULL);
                gm_log( GM_LOG_ERROR, "sending job to gearmand failed: %s\n", gearman_client_error(client) );
            }
            /* or every minute to give an update */
            else if( now.tv_sec >= mod_gm_error_time.tv_sec + 60) {
                gettimeofday(&mod_gm_error_time,NULL);
                gm_log( GM_LOG_ERROR, "sending job to gearmand failed: %s (%i lost jobs so far)\n", gearman_client_error(client), mod_gm_con_errors );
            }
            mod_gm_con_errors++;
        }

        /* recreate client, otherwise gearman sigsegvs */
        gearman_client_free( client );
        create_client( server_list, client );

        /* retry as long as we have retries */
        if(retries > 0) {
            retries--;
            gm_log( GM_LOG_TRACE, "add_job_to_queue() retrying... %d\n", retries );
            return(add_job_to_queue( client, server_list, queue, uniq, data, priority, retries, transport_mode, send_now ));
        }
        /* no more retries... */
        else {
            gm_log( GM_LOG_TRACE, "add_job_to_queue() finished with errors: %d %d\n", ret1, ret2 );
            return GM_ERROR;
        }
    }

    /* reset error counter */
    mod_gm_con_errors = 0;

    if(free_uniq)
        free(uniq);

    gm_log( GM_LOG_TRACE, "add_job_to_queue() finished sucessfully: %d %d\n", ret1, ret2 );
    return GM_OK;
}
Example #4
0
int nebmodule_init( int flags, char *args, nebmodule *handle ) {
    int i;
    int broker_option_errors = 0;
    send_now                 = FALSE;
    result_threads_running   = 0;

    /* save our handle */
    gearman_module_handle=handle;

    /* set some module info */
    neb_set_module_info( gearman_module_handle, NEBMODULE_MODINFO_TITLE,   "Mod-Gearman" );
    neb_set_module_info( gearman_module_handle, NEBMODULE_MODINFO_AUTHOR,  "Sven Nierlein" );
    neb_set_module_info( gearman_module_handle, NEBMODULE_MODINFO_TITLE,   "Copyright (c) 2010-2011 Sven Nierlein" );
    neb_set_module_info( gearman_module_handle, NEBMODULE_MODINFO_VERSION, GM_VERSION );
    neb_set_module_info( gearman_module_handle, NEBMODULE_MODINFO_LICENSE, "GPL v3" );
    neb_set_module_info( gearman_module_handle, NEBMODULE_MODINFO_DESC,    "distribute host/service checks and eventhandler via gearman" );

    mod_gm_opt = malloc(sizeof(mod_gm_opt_t));
    set_default_options(mod_gm_opt);

    /* parse arguments */
    gm_log( GM_LOG_DEBUG, "Version %s\n", GM_VERSION );
    gm_log( GM_LOG_DEBUG, "args: %s\n", args );
    gm_log( GM_LOG_TRACE, "nebmodule_init(%i, %i)\n", flags );
    gm_log( GM_LOG_DEBUG, "running on libgearman %s\n", gearman_version() );

    if( read_arguments( args ) == GM_ERROR )
        return NEB_ERROR;

    /* check for minimum eventbroker options */
    if(!(event_broker_options & BROKER_PROGRAM_STATE)) {
        gm_log( GM_LOG_ERROR, "mod_gearman needs BROKER_PROGRAM_STATE (%i) event_broker_options enabled to work\n", BROKER_PROGRAM_STATE );
        broker_option_errors++;
    }
    if(!(event_broker_options & BROKER_TIMED_EVENTS)) {
        gm_log( GM_LOG_ERROR, "mod_gearman needs BROKER_TIMED_EVENTS (%i) event_broker_options enabled to work\n", BROKER_TIMED_EVENTS );
        broker_option_errors++;
    }
    if(    (    mod_gm_opt->perfdata == GM_ENABLED
             || mod_gm_opt->hostgroups_num > 0
             || mod_gm_opt->hosts == GM_ENABLED
           )
        && !(event_broker_options & BROKER_HOST_CHECKS)) {
        gm_log( GM_LOG_ERROR, "mod_gearman needs BROKER_HOST_CHECKS (%i) event_broker_options enabled to work\n", BROKER_HOST_CHECKS );
        broker_option_errors++;
    }
    if(    (    mod_gm_opt->perfdata == GM_ENABLED
             || mod_gm_opt->servicegroups_num > 0
             || mod_gm_opt->services == GM_ENABLED
           )
        && !(event_broker_options & BROKER_SERVICE_CHECKS)) {
        gm_log( GM_LOG_ERROR, "mod_gearman needs BROKER_SERVICE_CHECKS (%i) event_broker_options enabled to work\n", BROKER_SERVICE_CHECKS );
        broker_option_errors++;
    }
    if(mod_gm_opt->events == GM_ENABLED && !(event_broker_options & BROKER_EVENT_HANDLERS)) {
        gm_log( GM_LOG_ERROR, "mod_gearman needs BROKER_EVENT_HANDLERS (%i) event_broker option enabled to work\n", BROKER_EVENT_HANDLERS );
        broker_option_errors++;
    }
    if(broker_option_errors > 0)
        return NEB_ERROR;

    /* check the minimal gearman version */
    if((float)atof(gearman_version()) < (float)GM_MIN_LIB_GEARMAN_VERSION) {
        gm_log( GM_LOG_ERROR, "minimum version of libgearman is %.2f, yours is %.2f\n", (float)GM_MIN_LIB_GEARMAN_VERSION, (float)atof(gearman_version()) );
        return NEB_ERROR;
    }

    /* init crypto functions */
    if(mod_gm_opt->encryption == GM_ENABLED) {
        if(mod_gm_opt->crypt_key == NULL) {
            gm_log( GM_LOG_ERROR, "no encryption key provided, please use --key=... or keyfile=...\n");
            return NEB_ERROR;
        }
        mod_gm_crypt_init(mod_gm_opt->crypt_key);
    } else {
        mod_gm_opt->transportmode = GM_ENCODE_ONLY;
    }

    /* create client */
    if ( create_client( mod_gm_opt->server_list, &client ) != GM_OK ) {
        gm_log( GM_LOG_ERROR, "cannot start client\n" );
        return NEB_ERROR;
    }

    /* register callback for process event where everything else starts */
    neb_register_callback( NEBCALLBACK_PROCESS_DATA, gearman_module_handle, 0, handle_process_events );
    neb_register_callback( NEBCALLBACK_TIMED_EVENT_DATA, gearman_module_handle, 0, handle_timed_events );

    /* register export callbacks */
    for(i=0;i<GM_NEBTYPESSIZE;i++) {
        if(mod_gm_opt->exports[i]->elem_number > 0)
            neb_register_callback( i, gearman_module_handle, 0, handle_export );
    }

    /* log at least one line into the core logfile */
    if ( mod_gm_opt->logmode != GM_LOG_MODE_CORE ) {
        int logmode_saved = mod_gm_opt->logmode;
        mod_gm_opt->logmode = GM_LOG_MODE_CORE;
        gm_log( GM_LOG_INFO,  "initialized version %s (libgearman %s)\n", GM_VERSION, gearman_version() );
        mod_gm_opt->logmode = logmode_saved;
    }

    gm_log( GM_LOG_DEBUG, "finished initializing\n" );

    return NEB_OK;
}
Example #5
0
int main (int argc, char **argv, char **env) {
    struct stat stat_buf;
#else
int main (int argc, char **argv) {
#endif
    int sid, x;
#ifdef EMBEDDEDPERL
    start_env=env;
#endif

    last_time_increased = 0;

    /* store the original command line for later reloads */
    store_original_comandline(argc, argv);

    /*
     * allocate options structure
     * and parse command line
     */
    mod_gm_opt = gm_malloc(sizeof(mod_gm_opt_t));
    set_default_options(mod_gm_opt);
    if(parse_arguments(argc, argv) != GM_OK) {
        exit( EXIT_FAILURE );
    }

#ifdef EMBEDDEDPERL
    /* make sure the P1 file exists... */
    if(p1_file==NULL){
        gm_log(GM_LOG_ERROR,"Error: p1.pl file required for embedded Perl interpreter is not set!\n");
        exit( EXIT_FAILURE );
    }
    if(stat(p1_file,&stat_buf)!=0){
        gm_log(GM_LOG_ERROR,"Error: p1.pl file required for embedded Perl interpreter is missing!\n");
        perror("stat");
        exit( EXIT_FAILURE );
    }
#endif

    /* fork into daemon mode? */
    if(mod_gm_opt->daemon_mode == GM_ENABLED) {
        pid_t pid = fork();
        /* an error occurred while trying to fork */
        if(pid == -1) {
            perror("fork");
            exit( EXIT_FAILURE );
        }
        /* we are the child process */
        else if(pid == 0) {
            gm_log( GM_LOG_INFO, "mod_gearman worker daemon started with pid %d\n", getpid());

            /* Create a new SID for the child process */
            sid = setsid();
            if ( sid < 0 ) {
                mod_gm_free_opt(mod_gm_opt);
                exit( EXIT_FAILURE );
            }

            /* Close out the standard file descriptors */
            if(mod_gm_opt->debug_level <= 1) {
                close(STDIN_FILENO);
                close(STDOUT_FILENO);
                close(STDERR_FILENO);
            }
        }
        /* we are the parent. So forking into daemon mode worked */
        else {
            mod_gm_free_opt(mod_gm_opt);
            exit( EXIT_SUCCESS );
        }
    } else {
        gm_log( GM_LOG_INFO, "mod_gearman worker started with pid %d\n", getpid());
    }

    /* print some version information */
    gm_log( GM_LOG_DEBUG, "Version %s\n", GM_VERSION );
    gm_log( GM_LOG_DEBUG, "running on libgearman %s\n", gearman_version() );


    /* set signal handlers for a clean exit */
    signal(SIGINT, clean_exit);
    signal(SIGTERM,clean_exit);
    signal(SIGHUP, reload_config);
    signal(SIGPIPE, SIG_IGN);


    /* check and write pid file */
    if(write_pid_file() != GM_OK) {
        exit(EXIT_FAILURE);
    }

    /* init crypto functions */
    if(mod_gm_opt->encryption == GM_ENABLED) {
        mod_gm_crypt_init(mod_gm_opt->crypt_key);
    } else {
        mod_gm_opt->transportmode = GM_ENCODE_ONLY;
    }

    gm_log( GM_LOG_DEBUG, "main process started\n");

    /* start a single non forked standalone worker */
    if(mod_gm_opt->debug_level >= 10) {
        gm_log( GM_LOG_TRACE, "starting standalone worker\n");
#ifdef EMBEDDEDPERL
        worker_client(GM_WORKER_STANDALONE, 1, shmid, start_env);
#else
        worker_client(GM_WORKER_STANDALONE, 1, shmid);
#endif
        exit(EXIT_SUCCESS);
    }

    /* setup shared memory */
    setup_child_communicator();

    /* start status worker */
    make_new_child(GM_WORKER_STATUS);

    /* setup children */
    for(x=0; x < mod_gm_opt->min_worker; x++) {
        make_new_child(GM_WORKER_MULTI);
    }

    /* maintain worker population */
    monitor_loop();

    gm_log( GM_LOG_ERROR, "worker exited from main loop\n");
    clean_exit(15);
    exit( EXIT_SUCCESS );
}
Example #6
0
int main (int argc, char **argv, char **env) {
    argc = argc; argv = argv; env  = env;
    int rc, rrc;
    char *result, *error;
    char cmd[120];
    char hostname[GM_BUFFERSIZE];

    plan(56);

    /* set hostname */
    gethostname(hostname, GM_BUFFERSIZE-1);

    /* create options structure and set debug level */
    mod_gm_opt = malloc(sizeof(mod_gm_opt_t));
    set_default_options(mod_gm_opt);
    mod_gm_opt->debug_level = 0;

#ifdef EMBEDDEDPERL
    char p1[150];
    snprintf(p1, 150, "--p1_file=worker/mod_gearman_p1.pl");
    parse_args_line(mod_gm_opt, p1, 0);
    init_embedded_perl(env);
#endif

    /*****************************************
     * arg parsing test 1
     */
    char *args[MAX_CMD_ARGS];
    strcpy(cmd, "/bin/hostname");
    parse_command_line(cmd, args);
    like(args[0], cmd, "parsing args cmd 1");

    /*****************************************
     * arg parsing test 2
     */
    strcpy(cmd, "/bin/cmd blah blub   foo");
    parse_command_line(cmd,args);
    like(args[0], "/bin/cmd", "parsing args cmd 2");
    like(args[1], "blah", "parsing args cmd 2");
    like(args[2], "blub", "parsing args cmd 2");
    like(args[3], "foo", "parsing args cmd 2");

    /*****************************************
     * send_gearman
     */
    strcpy(cmd, "./send_gearman --server=blah --key=testtest --host=test --service=test --message=test --returncode=0");
    rrc = real_exit_code(run_check(cmd, &result, &error));
    //diag(result);
    cmp_ok(rrc, "==", 3, "cmd '%s' returned rc %d", cmd, rrc);
    if(atof(gearman_version()) >= 0.31) {
        like(result, "send_gearman UNKNOWN:", "result");
    } else {
        like(result, "sending job to gearmand failed:", "result");
    }
    free(result);
    free(error);

    /*****************************************
     * send_gearman
     */
    //mod_gm_opt->debug_level = 4;
    strcpy(cmd, "./send_multi --server=blah --host=blah < t/data/send_multi.txt");
    rrc = real_exit_code(run_check(cmd, &result, &error));
    //diag(result);
    cmp_ok(rrc, "==", 3, "cmd '%s' returned rc %d", cmd, rrc);
    if(atof(gearman_version()) >= 0.31) {
        like(result, "send_multi UNKNOWN:", "result");
    } else {
        like(result, "sending job to gearmand failed:", "result");
    }
    free(result);
    free(error);

    /*****************************************
     * simple test command 1
     */
    strcpy(cmd, "/bin/hostname");
    rc = run_check(cmd, &result, &error);
    cmp_ok(rc, "==", 0, "pclose for cmd '%s' returned rc %d", cmd, rc);
    rrc = real_exit_code(rc);
    cmp_ok(rrc, "==", 0, "cmd '%s' returned rc %d", cmd, rrc);
    free(result);
    free(error);

    /*****************************************
     * simple test command 2
     */
    strcpy(cmd, "/bin/hostname 2>&1");
    rc = run_check(cmd, &result, &error);
    cmp_ok(rc, "==", 0, "pclose for cmd '%s' returned rc %d", cmd, rc);
    rrc = real_exit_code(rc);
    cmp_ok(rrc, "==", 0, "cmd '%s' returned rc %d", cmd, rrc);
    free(result);
    free(error);

    /*****************************************
     * simple test command 3
     */
    strcpy(cmd, "/usr/lib/nagios/plugins/check_icmp -H 127.0.0.1");
    rc = run_check(cmd, &result, &error);
    cmp_ok(rc, "==", 0, "pclose for cmd '%s' returned rc %d", cmd, rc);
    rrc = real_exit_code(rc);
    cmp_ok(rrc, "==", 0, "cmd '%s' returned rc %d", cmd, rrc);
    free(result);
    free(error);

    /*****************************************
     * simple test command 4
     */
    strcpy(cmd, "echo -n 'test'; exit 2");
    rc  = run_check(cmd, &result, &error);
    rrc = real_exit_code(rc);
    cmp_ok(rrc, "==", 2, "cmd '%s' returned rc %d", cmd, rrc);
    like(result, "test", "returned result string");
    free(result);
    free(error);

    gm_job_t * exec_job;
    exec_job = ( gm_job_t * )malloc( sizeof *exec_job );
    set_default_job(exec_job, mod_gm_opt);



    /*****************************************
     * non existing command 1
     */
    exec_job->command_line = strdup("/bin/doesntexist");
    exec_job->type         = strdup("service");
    exec_job->timeout      = 10;
    int fork_on_exec       = 0;

    execute_safe_command(exec_job, fork_on_exec, hostname);
    cmp_ok(exec_job->return_code, "==", 2, "cmd '%s' returns rc 2", exec_job->command_line);
    like(exec_job->output, "CRITICAL: Return code of 127 is out of bounds. Make sure the plugin you're trying to run actually exists. \\(worker:", "returned result string");
    free(exec_job->output);
    free(exec_job->error);

    fork_on_exec = 1;
    lives_ok({execute_safe_command(exec_job, fork_on_exec, hostname);}, "executing command using fork on exec");