/* get a job */ void *get_job( gearman_job_st *job, void *context, size_t *result_size, gearman_return_t *ret_ptr ) { sigset_t block_mask; int wsize, valid_lines; char workload[GM_BUFFERSIZE]; char * decrypted_data; char * decrypted_data_c; char * decrypted_orig; char *ptr; /* reset timeout for now, will be set befor execution again */ alarm(0); signal(SIGALRM, SIG_IGN); jobs_done++; /* send start signal to parent */ set_state(GM_JOB_START); gm_log( GM_LOG_TRACE, "get_job()\n" ); /* contect is unused */ context = context; /* set size of result */ *result_size = 0; /* reset sleep time */ sleep_time_after_error = 1; /* ignore sigterms while running job */ sigemptyset(&block_mask); sigaddset(&block_mask, SIGTERM); sigprocmask(SIG_BLOCK, &block_mask, NULL); /* get the data */ current_gearman_job = job; wsize = gearman_job_workload_size(job); strncpy(workload, (const char*)gearman_job_workload(job), wsize); workload[wsize] = '\0'; gm_log( GM_LOG_TRACE, "got new job %s\n", gearman_job_handle( job ) ); gm_log( GM_LOG_TRACE, "%d +++>\n%s\n<+++\n", strlen(workload), workload ); /* decrypt data */ decrypted_data = malloc(GM_BUFFERSIZE); decrypted_data_c = decrypted_data; mod_gm_decrypt(&decrypted_data, workload, mod_gm_opt->transportmode); decrypted_orig = strdup(decrypted_data); if(decrypted_data == NULL) { *ret_ptr = GEARMAN_WORK_FAIL; free(decrypted_orig); return NULL; } gm_log( GM_LOG_TRACE, "%d --->\n%s\n<---\n", strlen(decrypted_data), decrypted_data ); /* set result pointer to success */ *ret_ptr= GEARMAN_SUCCESS; exec_job = ( gm_job_t * )malloc( sizeof *exec_job ); set_default_job(exec_job, mod_gm_opt); valid_lines = 0; while ( (ptr = strsep(&decrypted_data, "\n" )) != NULL ) { char *key = strsep( &ptr, "=" ); char *value = strsep( &ptr, "\x0" ); if ( key == NULL ) continue; if ( value == NULL || !strcmp( value, "") ) break; if ( !strcmp( key, "host_name" ) ) { exec_job->host_name = strdup(value); valid_lines++; } else if ( !strcmp( key, "service_description" ) ) { exec_job->service_description = strdup(value); valid_lines++; } else if ( !strcmp( key, "type" ) ) { exec_job->type = strdup(value); valid_lines++; } else if ( !strcmp( key, "result_queue" ) ) { exec_job->result_queue = strdup(value); valid_lines++; } else if ( !strcmp( key, "check_options" ) ) { exec_job->check_options = atoi(value); valid_lines++; } else if ( !strcmp( key, "scheduled_check" ) ) { exec_job->scheduled_check = atoi(value); valid_lines++; } else if ( !strcmp( key, "reschedule_check" ) ) { exec_job->reschedule_check = atoi(value); valid_lines++; } else if ( !strcmp( key, "latency" ) ) { exec_job->latency = atof(value); valid_lines++; } else if ( !strcmp( key, "next_check" ) ) { string2timeval(value, &exec_job->next_check); valid_lines++; } else if ( !strcmp( key, "start_time" ) ) { /* for compatibility reasons... (used by older mod-gearman neb modules) */ string2timeval(value, &exec_job->next_check); string2timeval(value, &exec_job->core_time); valid_lines++; } else if ( !strcmp( key, "core_time" ) ) { string2timeval(value, &exec_job->core_time); valid_lines++; } else if ( !strcmp( key, "timeout" ) ) { exec_job->timeout = atoi(value); valid_lines++; } else if ( !strcmp( key, "command_line" ) ) { exec_job->command_line = strdup(value); valid_lines++; } } #ifdef GM_DEBUG if(exec_job->next_check.tv_sec < 10000) write_debug_file(&decrypted_orig); #endif if(valid_lines == 0) { gm_log( GM_LOG_ERROR, "discarded invalid job (%s), check your encryption settings\n", gearman_job_handle( job ) ); } else { do_exec_job(); } current_gearman_job = NULL; /* start listening to SIGTERMs */ sigprocmask(SIG_UNBLOCK, &block_mask, NULL); free(decrypted_orig); free(decrypted_data_c); free_job(exec_job); /* send finish signal to parent */ set_state(GM_JOB_END); if(mod_gm_opt->max_jobs > 0 && jobs_done >= mod_gm_opt->max_jobs) { gm_log( GM_LOG_TRACE, "jobs done: %i -> exiting...\n", jobs_done ); clean_worker_exit(0); _exit( EXIT_SUCCESS ); } return NULL; }
/* put back the result into the core */ void *get_results( gearman_job_st *job, void *context, size_t *result_size, gearman_return_t *ret_ptr ) { int wsize; char workload[GM_BUFFERSIZE]; char *decrypted_data; char *decrypted_data_c; #ifdef GM_DEBUG char *decrypted_orig; #endif struct timeval now, core_start_time; check_result * chk_result; int active_check = TRUE; char *ptr; double now_f, core_starttime_f, starttime_f, finishtime_f, exec_time, latency; /* for calculating real latency */ gettimeofday(&now,NULL); /* contect is unused */ context = context; /* set size of result */ *result_size = 0; /* set result pointer to success */ *ret_ptr = GEARMAN_SUCCESS; /* get the data */ wsize = gearman_job_workload_size(job); strncpy(workload, (const char*)gearman_job_workload(job), wsize); workload[wsize] = '\x0'; gm_log( GM_LOG_TRACE, "got result %s\n", gearman_job_handle( job )); gm_log( GM_LOG_TRACE, "%d +++>\n%s\n<+++\n", strlen(workload), workload ); /* decrypt data */ decrypted_data = malloc(GM_BUFFERSIZE); decrypted_data_c = decrypted_data; mod_gm_decrypt(&decrypted_data, workload, mod_gm_opt->transportmode); if(decrypted_data == NULL) { *ret_ptr = GEARMAN_WORK_FAIL; return NULL; } gm_log( GM_LOG_TRACE, "%d --->\n%s\n<---\n", strlen(decrypted_data), decrypted_data ); #ifdef GM_DEBUG decrypted_orig = strdup(decrypted_data); #endif /* * save this result to a file, so when nagios crashes, * we have at least the crashed package */ if(mod_gm_opt->debug_result == GM_ENABLED) { FILE * fd; fd = fopen( "/tmp/last_result_received.txt", "w+" ); if(fd == NULL) perror("fopen"); fputs( decrypted_data, fd ); fclose( fd ); } /* nagios will free it after processing */ if ( ( chk_result = ( check_result * )malloc( sizeof *chk_result ) ) == 0 ) { *ret_ptr = GEARMAN_WORK_FAIL; return NULL; } init_check_result(chk_result); chk_result->scheduled_check = TRUE; chk_result->reschedule_check = TRUE; chk_result->output_file = 0; chk_result->output_file_fd = -1; core_start_time.tv_sec = 0; core_start_time.tv_usec = 0; while ( (ptr = strsep(&decrypted_data, "\n" )) != NULL ) { char *key = strsep( &ptr, "=" ); char *value = strsep( &ptr, "\x0" ); if ( key == NULL ) continue; if ( !strcmp( key, "output" ) ) { if ( value == NULL ) { chk_result->output = strdup("(null)"); } else { chk_result->output = strdup( value ); } } if ( value == NULL || !strcmp( value, "") ) break; if ( !strcmp( key, "host_name" ) ) { chk_result->host_name = strdup( value ); } else if ( !strcmp( key, "service_description" ) ) { chk_result->service_description = strdup( value ); } else if ( !strcmp( key, "check_options" ) ) { chk_result->check_options = atoi( value ); } else if ( !strcmp( key, "scheduled_check" ) ) { chk_result->scheduled_check = atoi( value ); } else if ( !strcmp( key, "type" ) && !strcmp( value, "passive" ) ) { active_check=FALSE; } else if ( !strcmp( key, "reschedule_check" ) ) { chk_result->reschedule_check = atoi( value ); } else if ( !strcmp( key, "exited_ok" ) ) { chk_result->exited_ok = atoi( value ); } else if ( !strcmp( key, "early_timeout" ) ) { chk_result->early_timeout = atoi( value ); } else if ( !strcmp( key, "return_code" ) ) { chk_result->return_code = atoi( value ); } else if ( !strcmp( key, "core_start_time" ) ) { string2timeval(value, &core_start_time); } else if ( !strcmp( key, "start_time" ) ) { string2timeval(value, &chk_result->start_time); } else if ( !strcmp( key, "finish_time" ) ) { string2timeval(value, &chk_result->finish_time); } else if ( !strcmp( key, "latency" ) ) { chk_result->latency = atof( value ); } } if ( chk_result->host_name == NULL || chk_result->output == NULL ) { *ret_ptr= GEARMAN_WORK_FAIL; gm_log( GM_LOG_ERROR, "discarded invalid result\n" ); return NULL; } if ( chk_result->service_description != NULL ) { chk_result->object_check_type = SERVICE_CHECK; chk_result->check_type = SERVICE_CHECK_ACTIVE; if(active_check == FALSE ) chk_result->check_type = SERVICE_CHECK_PASSIVE; } else { chk_result->object_check_type = HOST_CHECK; chk_result->check_type = HOST_CHECK_ACTIVE; if(active_check == FALSE ) chk_result->check_type = HOST_CHECK_PASSIVE; } /* fill some maybe missing options */ if(chk_result->start_time.tv_sec == 0) { chk_result->start_time.tv_sec = (unsigned long)time(NULL); } if(chk_result->finish_time.tv_sec == 0) { chk_result->finish_time.tv_sec = (unsigned long)time(NULL); } if(core_start_time.tv_sec == 0) { core_start_time.tv_sec = (unsigned long)time(NULL); } /* calculate real latency */ now_f = (double)now.tv_sec + (double)now.tv_usec / 1000000; core_starttime_f = (double)core_start_time.tv_sec + (double)core_start_time.tv_usec / 1000000; starttime_f = (double)chk_result->start_time.tv_sec + (double)chk_result->start_time.tv_usec / 1000000; finishtime_f = (double)chk_result->finish_time.tv_sec + (double)chk_result->finish_time.tv_usec / 1000000; exec_time = finishtime_f - starttime_f; latency = now_f - exec_time - core_starttime_f; if(latency < 0) latency = 0; if(chk_result->latency < 0) chk_result->latency = 0; chk_result->latency += latency; #ifdef GM_DEBUG if(chk_result->latency > 1000) write_debug_file(&decrypted_orig); #endif /* this check is not a freshnes check */ chk_result->check_options = chk_result->check_options & ! CHECK_OPTION_FRESHNESS_CHECK; if ( chk_result->service_description != NULL ) { #ifdef GM_DEBUG /* does this services exist */ service * svc = find_service( chk_result->host_name, chk_result->service_description ); if(svc == NULL) { write_debug_file(&decrypted_orig); gm_log( GM_LOG_ERROR, "service '%s' on host '%s' could not be found\n", chk_result->service_description, chk_result->host_name ); return NULL; } #endif gm_log( GM_LOG_DEBUG, "service job completed: %s %s: %d\n", chk_result->host_name, chk_result->service_description, chk_result->return_code ); } else { #ifdef GM_DEBUG /* does this host exist */ host * hst = find_host( chk_result->host_name ); if(hst == NULL) { write_debug_file(&decrypted_orig); gm_log( GM_LOG_ERROR, "host '%s' could not be found\n", chk_result->host_name ); return NULL; } #endif gm_log( GM_LOG_DEBUG, "host job completed: %s: %d\n", chk_result->host_name, chk_result->return_code ); } /* add result to result list */ mod_gm_add_result_to_list( chk_result ); /* reset pointer */ chk_result = NULL; free(decrypted_data_c); #ifdef GM_DEBUG free(decrypted_orig); #endif return NULL; }