char* gm_strdup(const char* str) { size_t l = strlen(str); char* res = static_cast<char*>(gm_malloc(l+1)); memcpy(res, str, l+1); return res; }
/* handle host check events */ static int handle_host_check( int event_type, void *data ) { nebstruct_host_check_data * hostdata; char *raw_command=NULL; char *processed_command=NULL; host * hst; check_result * chk_result; int check_options; struct timeval core_time; struct tm next_check; char buffer1[GM_BUFFERSIZE]; gettimeofday(&core_time,NULL); gm_log( GM_LOG_TRACE, "handle_host_check(%i)\n", event_type ); if ( mod_gm_opt->do_hostchecks != GM_ENABLED ) return NEB_OK; hostdata = ( nebstruct_host_check_data * )data; gm_log( GM_LOG_TRACE, "---------------\nhost Job -> %i, %i\n", event_type, hostdata->type ); if ( event_type != NEBCALLBACK_HOST_CHECK_DATA ) return NEB_OK; /* ignore non-initiate host checks */ if ( hostdata->type != NEBTYPE_HOSTCHECK_ASYNC_PRECHECK && hostdata->type != NEBTYPE_HOSTCHECK_SYNC_PRECHECK) return NEB_OK; /* get objects and set target function */ if((hst=hostdata->object_ptr)==NULL) { gm_log( GM_LOG_ERROR, "Host handler received NULL host object pointer.\n" ); return NEBERROR_CALLBACKCANCEL; } set_target_queue( hst, NULL ); /* local check? */ if(!strcmp( target_queue, "" )) { gm_log( GM_LOG_DEBUG, "passing by local hostcheck: %s\n", hostdata->host_name ); return NEB_OK; } gm_log( GM_LOG_DEBUG, "received job for queue %s: %s\n", target_queue, hostdata->host_name ); /* as we have to intercept host checks so early * (we cannot cancel checks otherwise) * we have to do some host check logic here * taken from checks.c: */ /* clear check options - we don't want old check options retained */ check_options = hst->check_options; hst->check_options = CHECK_OPTION_NONE; /* unset the freshening flag, otherwise only the first freshness check would be run */ hst->is_being_freshened=FALSE; /* adjust host check attempt */ adjust_host_check_attempt(hst,TRUE); temp_buffer[0]='\x0'; /* grab the host macro variables */ clear_volatile_macros(); grab_host_macros(hst); /* get the raw command line */ get_raw_command_line(hst->check_command_ptr,hst->check_command,&raw_command,0); if(raw_command==NULL){ gm_log( GM_LOG_ERROR, "Raw check command for host '%s' was NULL - aborting.\n",hst->name ); return NEBERROR_CALLBACKCANCEL; } /* process any macros contained in the argument */ process_macros(raw_command,&processed_command,0); if(processed_command==NULL){ gm_log( GM_LOG_ERROR, "Processed check command for host '%s' was NULL - aborting.\n",hst->name); return NEBERROR_CALLBACKCANCEL; } /* log latency */ if(mod_gm_opt->debug_level >= GM_LOG_DEBUG) { localtime_r(&hst->next_check, &next_check); strftime(buffer1, sizeof(buffer1), "%Y-%m-%d %H:%M:%S", &next_check ); gm_log( GM_LOG_DEBUG, "host: '%s', next_check is at %s, latency so far: %i\n", hst->name, buffer1, ((int)core_time.tv_sec - (int)hst->next_check)); } /* increment number of host checks that are currently running */ currently_running_host_checks++; /* set the execution flag */ hst->is_executing=TRUE; gm_log( GM_LOG_TRACE, "cmd_line: %s\n", processed_command ); snprintf( temp_buffer,GM_BUFFERSIZE-1,"type=host\nresult_queue=%s\nhost_name=%s\nstart_time=%i.0\nnext_check=%i.0\ntimeout=%d\ncore_time=%i.%i\ncommand_line=%s\n\n\n", mod_gm_opt->result_queue, hst->name, (int)hst->next_check, (int)hst->next_check, host_check_timeout, (int)core_time.tv_sec, (int)core_time.tv_usec, processed_command ); if(add_job_to_queue( &client, mod_gm_opt->server_list, target_queue, (mod_gm_opt->use_uniq_jobs == GM_ENABLED ? hst->name : NULL), temp_buffer, GM_JOB_PRIO_NORMAL, GM_DEFAULT_JOB_RETRIES, mod_gm_opt->transportmode, TRUE ) == GM_OK) { } else { my_free(raw_command); my_free(processed_command); /* unset the execution flag */ hst->is_executing=FALSE; /* decrement number of host checks that are currently running */ currently_running_host_checks--; gm_log( GM_LOG_TRACE, "handle_host_check() finished unsuccessfully -> %d\n", NEBERROR_CALLBACKCANCEL ); return NEBERROR_CALLBACKCANCEL; } /* clean up */ my_free(raw_command); my_free(processed_command); /* orphaned check - submit fake result to mark host as orphaned */ if(mod_gm_opt->orphan_host_checks == GM_ENABLED && check_options & CHECK_OPTION_ORPHAN_CHECK) { gm_log( GM_LOG_DEBUG, "host check for %s orphaned\n", hst->name ); if ( ( chk_result = ( check_result * )gm_malloc( sizeof *chk_result ) ) == 0 ) return NEBERROR_CALLBACKCANCEL; snprintf( temp_buffer,GM_BUFFERSIZE-1,"(host check orphaned, is the mod-gearman worker on queue '%s' running?)\n", target_queue); init_check_result(chk_result); chk_result->host_name = gm_strdup( hst->name ); chk_result->scheduled_check = TRUE; chk_result->reschedule_check = TRUE; chk_result->output_file = 0; chk_result->output_file_fp = NULL; chk_result->output = gm_strdup(temp_buffer); chk_result->return_code = mod_gm_opt->orphan_return; chk_result->check_options = CHECK_OPTION_NONE; chk_result->object_check_type = HOST_CHECK; chk_result->check_type = HOST_CHECK_ACTIVE; chk_result->start_time.tv_sec = (unsigned long)time(NULL); chk_result->finish_time.tv_sec = (unsigned long)time(NULL); chk_result->latency = 0; mod_gm_add_result_to_list( chk_result ); chk_result = NULL; } /* tell naemon to not execute */ gm_log( GM_LOG_TRACE, "handle_host_check() finished successfully -> %d\n", NEBERROR_CALLBACKOVERRIDE ); return NEBERROR_CALLBACKOVERRIDE; }
/* get worker/jobs data from gearman server */ int get_gearman_server_data(mod_gm_server_status_t *stats, char ** message, char ** version, char * hostnam, int port) { int rc; char *total, *running, *worker, *output, *output_c, *line, *name; mod_gm_status_function_t *func; *version = gm_malloc(GM_BUFFERSIZE); snprintf(*version, GM_BUFFERSIZE, "%s", "" ); rc = send2gearmandadmin("status\nversion\n", hostnam, port, &output, message); if(rc != STATE_OK) { if(output != NULL) free(output); return rc; } output_c = output; while ( (line = strsep( &output, "\n" )) != NULL ) { gm_log( GM_LOG_TRACE, "%s\n", line ); if(!strcmp( line, ".")) { if((line = strsep( &output, "\n" )) != NULL) { gm_log( GM_LOG_TRACE, "%s\n", line ); if(line[0] == 'O') { strncpy(*version, line+3, 10); } else { snprintf(*version, GM_BUFFERSIZE, "%s", line); } gm_log( GM_LOG_TRACE, "extracted version: '%s'\n", *version ); } /* sort our array by queue name */ qsort(stats->function, stats->function_num, sizeof(mod_gm_status_function_t*), struct_cmp_by_queue); free(output_c); return( STATE_OK ); } name = strsep(&line, "\t"); if(name == NULL) break; total = strsep(&line, "\t"); if(total == NULL) break; running = strsep(&line, "\t"); if(running == NULL) break; worker = strsep(&line, "\x0"); if(worker == NULL) break; func = gm_malloc(sizeof(mod_gm_status_function_t)); func->queue = gm_strdup(name); func->running = atoi(running); func->total = atoi(total); func->worker = atoi(worker); func->waiting = func->total - func->running; /* skip the dummy queue if its empty */ if(!strcmp( name, "dummy") && func->total == 0) { free(func->queue); free(func); continue; } stats->function[stats->function_num++] = func; gm_log( GM_LOG_DEBUG, "%i: name:%-20s worker:%-5i waiting:%-5i running:%-5i\n", stats->function_num, func->queue, func->worker, func->waiting, func->running ); } snprintf(*message, GM_BUFFERSIZE, "got no valid data from %s:%i\n", hostnam, (int)port); free(output_c); return(rc); }