/*######################### check_dir_status() ##########################*/ void check_dir_status(Widget w) { signed char flush; int i, x, y, pos, prev_no_of_dirs = no_of_dirs, location_where_changed, new_bar_length, old_bar_length, redo_warn_time_bar, redraw_everything = NO; u_off_t bytes_received; unsigned int files_received, prev_dir_flag; time_t delta_time, end_time; /* Initialise variables. */ location_where_changed = no_of_dirs + 10; flush = NO; now = time(NULL); /* * See if a directory has been added or removed from the FRA. * If it changed resize the window. */ if (check_fra(NO) == YES) { unsigned int new_bar_length; size_t new_size = no_of_dirs * sizeof(struct dir_line); struct dir_line *new_connect_data, *tmp_connect_data; if ((new_connect_data = calloc(no_of_dirs, sizeof(struct dir_line))) == NULL) { (void)xrec(FATAL_DIALOG, "calloc() error : %s (%s %d)", strerror(errno), __FILE__, __LINE__); return; } /* * First try to copy the connect data from the old structure * so long as the directories are the same. */ for (i = 0, location_where_changed = 0; i < prev_no_of_dirs; i++, location_where_changed++) { if (strcmp(connect_data[i].dir_alias, fra[i].dir_alias) == 0) { (void)memcpy(&new_connect_data[i], &connect_data[i], sizeof(struct dir_line)); } else { break; } } for (i = location_where_changed; i < no_of_dirs; i++) { if ((pos = check_disp_data(fra[i].dir_alias, prev_no_of_dirs)) != INCORRECT) { (void)memcpy(&new_connect_data[i], &connect_data[pos], sizeof(struct dir_line)); } else /* A directory host has been added. */ { /* Initialise values for new host. */ (void)strcpy(new_connect_data[i].dir_alias, fra[i].dir_alias); (void)sprintf(new_connect_data[i].dir_display_str, "%-*s", MAX_DIR_ALIAS_LENGTH, new_connect_data[i].dir_alias); new_connect_data[i].dir_status = fra[i].dir_status; new_connect_data[i].bytes_received = fra[i].bytes_received; new_connect_data[i].files_received = fra[i].files_received; new_connect_data[i].dir_flag = fra[i].dir_flag; new_connect_data[i].files_in_dir = fra[i].files_in_dir; new_connect_data[i].files_queued = fra[i].files_queued; new_connect_data[i].bytes_in_dir = fra[i].bytes_in_dir; new_connect_data[i].bytes_in_queue = fra[i].bytes_in_queue; new_connect_data[i].max_process = fra[i].max_process; new_connect_data[i].no_of_process = fra[i].no_of_process; new_connect_data[i].max_errors = fra[i].max_errors; new_connect_data[i].error_counter = fra[i].error_counter; CREATE_FC_STRING(new_connect_data[i].str_files_in_dir, new_connect_data[i].files_in_dir); CREATE_FS_STRING(new_connect_data[i].str_bytes_in_dir, new_connect_data[i].bytes_in_dir); CREATE_FC_STRING(new_connect_data[i].str_files_queued, new_connect_data[i].files_queued); CREATE_FS_STRING(new_connect_data[i].str_bytes_queued, new_connect_data[i].bytes_in_queue); CREATE_EC_STRING(new_connect_data[i].str_np, new_connect_data[i].no_of_process); CREATE_EC_STRING(new_connect_data[i].str_ec, new_connect_data[i].error_counter); new_connect_data[i].last_retrieval = fra[i].last_retrieval; new_connect_data[i].start_event_handle = fra[i].start_event_handle; new_connect_data[i].end_event_handle = fra[i].end_event_handle; if (*(unsigned char *)((char *)fra - AFD_FEATURE_FLAG_OFFSET_END) & DISABLE_DIR_WARN_TIME) { new_connect_data[i].warn_time = 0; } else { new_connect_data[i].warn_time = fra[i].warn_time; } new_connect_data[i].bytes_per_sec = 0; new_connect_data[i].prev_bytes_per_sec = 0; new_connect_data[i].str_tr[0] = new_connect_data[i].str_tr[1] = ' '; new_connect_data[i].str_tr[2] = '0'; new_connect_data[i].str_tr[3] = 'B'; new_connect_data[i].str_tr[4] = '\0'; new_connect_data[i].average_tr = 0.0; new_connect_data[i].max_average_tr = 0.0; new_connect_data[i].files_per_sec = 0; new_connect_data[i].prev_files_per_sec = 0; new_connect_data[i].str_fr[0] = ' '; new_connect_data[i].str_fr[1] = '0'; new_connect_data[i].str_fr[2] = '.'; new_connect_data[i].str_fr[3] = '0'; new_connect_data[i].str_fr[4] = '\0'; new_connect_data[i].average_fr = 0.0; new_connect_data[i].max_average_fr = 0.0; new_connect_data[i].bar_length[BYTE_RATE_BAR_NO] = 0; if (new_connect_data[i].warn_time < 1) { new_connect_data[i].scale = 0.0; new_connect_data[i].bar_length[TIME_UP_BAR_NO] = 0; } else { new_connect_data[i].scale = max_bar_length / new_connect_data[i].warn_time; new_bar_length = (now - new_connect_data[i].last_retrieval) * new_connect_data[i].scale; if (new_bar_length > 0) { if (new_bar_length >= max_bar_length) { new_connect_data[i].bar_length[TIME_UP_BAR_NO] = max_bar_length; } else { new_connect_data[i].bar_length[TIME_UP_BAR_NO] = new_bar_length; } } else { new_connect_data[i].bar_length[TIME_UP_BAR_NO] = 0; } } new_connect_data[i].bar_length[FILE_RATE_BAR_NO] = 0; new_connect_data[i].start_time = times(&tmsdummy); new_connect_data[i].inverse = OFF; new_connect_data[i].expose_flag = NO; /* * If this line has been selected in the old * connect_data structure, we have to make sure * that this host has not been deleted. If it * is deleted reduce the select counter! */ if ((i < prev_no_of_dirs) && (connect_data[i].inverse == ON)) { if ((pos = check_fra_data(connect_data[i].dir_alias)) == INCORRECT) { /* Host has been deleted. */ no_selected--; } } } } /* for (i = location_where_changed; i < no_of_dirs; i++) */ /* * Ensure that we really have checked all directories in old * structure. */ if (prev_no_of_dirs > no_of_dirs) { while (i < prev_no_of_dirs) { if (connect_data[i].inverse == ON) { if ((pos = check_fra_data(connect_data[i].dir_alias)) == INCORRECT) { /* Host has been deleted. */ no_selected--; } } i++; } } if ((tmp_connect_data = realloc(connect_data, new_size)) == NULL) { int tmp_errno = errno; free(connect_data); (void)xrec(FATAL_DIALOG, "realloc() error : %s (%s %d)", strerror(tmp_errno), __FILE__, __LINE__); return; } connect_data = tmp_connect_data; /* Activate the new connect_data structure. */ (void)memcpy(&connect_data[0], &new_connect_data[0], no_of_dirs * sizeof(struct dir_line)); free(new_connect_data); /* Resize window if necessary. */ if ((redraw_everything = resize_dir_window()) == YES) { if (no_of_columns != 0) { location_where_changed = 0; } } /* When no. of directories have been reduced, then delete */ /* removed directories from end of list. */ for (i = prev_no_of_dirs; i > no_of_dirs; i--) { draw_dir_blank_line(i - 1); } /* Make sure changes are drawn!!! */ flush = YES; } /* if (check_fra(NO) == YES) */ /* Change information for each directory if necessary. */ for (i = 0; i < no_of_dirs; i++) { x = y = -1; redo_warn_time_bar = NO; if (connect_data[i].dir_status != fra[i].dir_status) { connect_data[i].dir_status = fra[i].dir_status; locate_xy(i, &x, &y); draw_dir_identifier(i, x, y); flush = YES; } if (connect_data[i].max_process != fra[i].max_process) { connect_data[i].max_process = fra[i].max_process; } if (connect_data[i].dir_flag != fra[i].dir_flag) { prev_dir_flag = connect_data[i].dir_flag; connect_data[i].dir_flag = fra[i].dir_flag; if (x == -1) { locate_xy(i, &x, &y); } if (((prev_dir_flag & MAX_COPIED) == 0) && (connect_data[i].dir_flag & MAX_COPIED)) { draw_dir_full_marker(i, x, y, YES); } else if ((prev_dir_flag & MAX_COPIED) && ((connect_data[i].dir_flag & MAX_COPIED) == 0)) { draw_dir_full_marker(i, x, y, NO); } flush = YES; } if (connect_data[i].max_errors != fra[i].max_errors) { connect_data[i].max_errors = fra[i].max_errors; } if (*(unsigned char *)((char *)fra - AFD_FEATURE_FLAG_OFFSET_END) & DISABLE_DIR_WARN_TIME) { if (connect_data[i].warn_time != 0) { connect_data[i].scale = 0.0; connect_data[i].warn_time = 0; redo_warn_time_bar = YES; } } else { if (connect_data[i].warn_time != fra[i].warn_time) { connect_data[i].warn_time = fra[i].warn_time; if (connect_data[i].warn_time < 1) { connect_data[i].scale = 0.0; } else { connect_data[i].scale = max_bar_length / connect_data[i].warn_time; } redo_warn_time_bar = YES; } } end_time = times(&tmsdummy); if ((delta_time = (end_time - connect_data[i].start_time)) == 0) { delta_time = 1; } connect_data[i].start_time = end_time; /* * Byte Rate Bar */ bytes_received = 0; if (connect_data[i].bytes_received != fra[i].bytes_received) { if (fra[i].bytes_received < connect_data[i].bytes_received) { bytes_received = fra[i].bytes_received; } else { bytes_received = fra[i].bytes_received - connect_data[i].bytes_received; } connect_data[i].bytes_received = fra[i].bytes_received; } if (bytes_received > 0) { connect_data[i].bytes_per_sec = (float)(bytes_received) / delta_time * clktck; if (line_style != CHARACTERS_ONLY) { /* Arithmetischer Mittelwert. */ connect_data[i].average_tr = (connect_data[i].average_tr + connect_data[i].bytes_per_sec) / 2.0; if (connect_data[i].average_tr > connect_data[i].max_average_tr) { connect_data[i].max_average_tr = connect_data[i].average_tr; } } } else { connect_data[i].bytes_per_sec = 0; if ((line_style != CHARACTERS_ONLY) && (connect_data[i].average_tr > 0.0)) { /* Arithmetischer Mittelwert. */ connect_data[i].average_tr = (connect_data[i].average_tr + connect_data[i].bytes_per_sec) / 2.0; if (connect_data[i].average_tr > connect_data[i].max_average_tr) { connect_data[i].max_average_tr = connect_data[i].average_tr; } } } files_received = 0; if (connect_data[i].files_received != fra[i].files_received) { if (fra[i].files_received < connect_data[i].files_received) { files_received = fra[i].files_received; } else { files_received = fra[i].files_received - connect_data[i].files_received; } connect_data[i].files_received = fra[i].files_received; } if (files_received > 0) { connect_data[i].files_per_sec = (float)(files_received) / delta_time * clktck; if (line_style != CHARACTERS_ONLY) { /* Arithmetischer Mittelwert. */ connect_data[i].average_fr = (connect_data[i].average_fr + connect_data[i].files_per_sec) / 2.0; if (connect_data[i].average_fr > connect_data[i].max_average_fr) { connect_data[i].max_average_fr = connect_data[i].average_fr; } } } else { connect_data[i].files_per_sec = 0; if ((line_style != CHARACTERS_ONLY) && (connect_data[i].average_fr > 0.0)) { /* Arithmetischer Mittelwert. */ connect_data[i].average_fr = (connect_data[i].average_fr + connect_data[i].files_per_sec) / 2.0; if (connect_data[i].average_fr > connect_data[i].max_average_fr) { connect_data[i].max_average_fr = connect_data[i].average_fr; } } } /* * CHARACTER INFORMATION * ===================== * * If in character mode see if any change took place, * if so, redraw only those characters. */ if (line_style != BARS_ONLY) { /* * Number of files in directory. */ if (connect_data[i].files_in_dir != fra[i].files_in_dir) { connect_data[i].files_in_dir = fra[i].files_in_dir; if (x == -1) { locate_xy(i, &x, &y); } CREATE_FC_STRING(connect_data[i].str_files_in_dir, connect_data[i].files_in_dir); if (i < location_where_changed) { draw_dir_chars(i, FILES_IN_DIR, x, y); flush = YES; } } /* * Number of bytes in directory. */ if (connect_data[i].bytes_in_dir != fra[i].bytes_in_dir) { connect_data[i].bytes_in_dir = fra[i].bytes_in_dir; if (x == -1) { locate_xy(i, &x, &y); } CREATE_FS_STRING(connect_data[i].str_bytes_in_dir, connect_data[i].bytes_in_dir); if (i < location_where_changed) { draw_dir_chars(i, BYTES_IN_DIR, x, y); flush = YES; } } /* * Number of files queued. */ if (connect_data[i].files_queued != fra[i].files_queued) { connect_data[i].files_queued = fra[i].files_queued; if (x == -1) { locate_xy(i, &x, &y); } CREATE_FC_STRING(connect_data[i].str_files_queued, connect_data[i].files_queued); if (i < location_where_changed) { draw_dir_chars(i, FILES_QUEUED, x, y); flush = YES; } } /* * Number of bytes queued. */ if (connect_data[i].bytes_in_queue != fra[i].bytes_in_queue) { connect_data[i].bytes_in_queue = fra[i].bytes_in_queue; if (x == -1) { locate_xy(i, &x, &y); } CREATE_FS_STRING(connect_data[i].str_bytes_queued, connect_data[i].bytes_in_queue); if (i < location_where_changed) { draw_dir_chars(i, BYTES_QUEUED, x, y); flush = YES; } } /* * Number of process for this directory. */ if (connect_data[i].no_of_process != fra[i].no_of_process) { connect_data[i].no_of_process = fra[i].no_of_process; if (x == -1) { locate_xy(i, &x, &y); } CREATE_EC_STRING(connect_data[i].str_np, connect_data[i].no_of_process); if (i < location_where_changed) { draw_dir_chars(i, NO_OF_DIR_PROCESS, x, y); flush = YES; } } /* * Byte rate. */ if (connect_data[i].bytes_per_sec != connect_data[i].prev_bytes_per_sec) { connect_data[i].prev_bytes_per_sec = connect_data[i].bytes_per_sec; if (x == -1) { locate_xy(i, &x, &y); } CREATE_FS_STRING(connect_data[i].str_tr, connect_data[i].bytes_per_sec); if (i < location_where_changed) { draw_dir_chars(i, BYTE_RATE, x, y); flush = YES; } } /* * File rate. */ if (connect_data[i].files_per_sec != connect_data[i].prev_files_per_sec) { connect_data[i].prev_files_per_sec = connect_data[i].files_per_sec; if (x == -1) { locate_xy(i, &x, &y); } CREATE_FR_STRING(connect_data[i].str_fr, connect_data[i].files_per_sec); if (i < location_where_changed) { draw_dir_chars(i, FILE_RATE, x, y); flush = YES; } } /* * Error Counter. */ if (connect_data[i].error_counter != fra[i].error_counter) { connect_data[i].error_counter = fra[i].error_counter; if (x == -1) { locate_xy(i, &x, &y); } CREATE_EC_STRING(connect_data[i].str_ec, connect_data[i].error_counter); if (i < location_where_changed) { draw_dir_chars(i, DIR_ERRORS, x, y); flush = YES; } } } /* if (line_style != BARS_ONLY) */ /* * BAR INFORMATION * =============== */ if (line_style != CHARACTERS_ONLY) { if (connect_data[i].last_retrieval != fra[i].last_retrieval) { connect_data[i].last_retrieval = fra[i].last_retrieval; } if (connect_data[i].average_tr > 1.0) { if (connect_data[i].max_average_tr < 2.0) { new_bar_length = (log10(connect_data[i].average_tr) * max_bar_length / log10((double) 2.0)); } else { new_bar_length = (log10(connect_data[i].average_tr) * max_bar_length / log10(connect_data[i].max_average_tr)); } } else { new_bar_length = 0; } if ((connect_data[i].bar_length[BYTE_RATE_BAR_NO] != new_bar_length) && (new_bar_length < max_bar_length)) { old_bar_length = connect_data[i].bar_length[BYTE_RATE_BAR_NO]; connect_data[i].bar_length[BYTE_RATE_BAR_NO] = new_bar_length; if (i < location_where_changed) { if (x == -1) { locate_xy(i, &x, &y); } if (old_bar_length < new_bar_length) { draw_dir_bar(i, 1, BYTE_RATE_BAR_NO, x, y); } else { draw_dir_bar(i, -1, BYTE_RATE_BAR_NO, x, y); } if (flush != YES) { flush = YUP; } } } else if ((new_bar_length >= max_bar_length) && (connect_data[i].bar_length[BYTE_RATE_BAR_NO] < max_bar_length)) { connect_data[i].bar_length[BYTE_RATE_BAR_NO] = max_bar_length; if (i < location_where_changed) { if (x == -1) { locate_xy(i, &x, &y); } draw_dir_bar(i, 1, BYTE_RATE_BAR_NO, x, y); if (flush != YES) { flush = YUP; } } } if (((connect_data[i].warn_time > 0) && (connect_data[i].scale > 0.0)) || (redo_warn_time_bar == YES)) { new_bar_length = (now - connect_data[i].last_retrieval) * connect_data[i].scale; if (new_bar_length > 0) { if (new_bar_length >= max_bar_length) { new_bar_length = max_bar_length; } } else { new_bar_length = 0; } if (new_bar_length != connect_data[i].bar_length[TIME_UP_BAR_NO]) { old_bar_length = connect_data[i].bar_length[TIME_UP_BAR_NO]; connect_data[i].bar_length[TIME_UP_BAR_NO] = new_bar_length; if (i < location_where_changed) { if (x == -1) { locate_xy(i, &x, &y); } if (old_bar_length < new_bar_length) { draw_dir_bar(i, 1, TIME_UP_BAR_NO, x, y + bar_thickness_3); } else { draw_dir_bar(i, -1, TIME_UP_BAR_NO, x, y + bar_thickness_3); } if (flush != YES) { flush = YUP; } } } } /* * File Rate Bar */ if (connect_data[i].average_fr > 1.0) { if (connect_data[i].max_average_fr < 2.0) { new_bar_length = (log10(connect_data[i].average_fr) * max_bar_length / log10((double) 2.0)); } else { new_bar_length = (log10(connect_data[i].average_fr) * max_bar_length / log10(connect_data[i].max_average_fr)); } } else { new_bar_length = 0; } if ((connect_data[i].bar_length[FILE_RATE_BAR_NO] != new_bar_length) && (new_bar_length < max_bar_length)) { old_bar_length = connect_data[i].bar_length[FILE_RATE_BAR_NO]; connect_data[i].bar_length[FILE_RATE_BAR_NO] = new_bar_length; if (i < location_where_changed) { if (x == -1) { locate_xy(i, &x, &y); } if (old_bar_length < new_bar_length) { draw_dir_bar(i, 1, FILE_RATE_BAR_NO, x, y + bar_thickness_3 + bar_thickness_3); } else { draw_dir_bar(i, -1, FILE_RATE_BAR_NO, x, y + bar_thickness_3 + bar_thickness_3); } if (flush != YES) { flush = YUP; } } } else if ((new_bar_length >= max_bar_length) && (connect_data[i].bar_length[FILE_RATE_BAR_NO] < max_bar_length)) { connect_data[i].bar_length[FILE_RATE_BAR_NO] = max_bar_length; if (i < location_where_changed) { if (x == -1) { locate_xy(i, &x, &y); } draw_dir_bar(i, 1, FILE_RATE_BAR_NO, x, y + bar_thickness_3 + bar_thickness_3); if (flush != YES) { flush = YUP; } } } } /* Redraw the line. */ if (i >= location_where_changed) { #ifdef _DEBUG (void)fprintf(stderr, "count_channels: i = %d\n", i); #endif flush = YES; draw_dir_line_status(i, 1); } } if (redraw_everything == YES) { redraw_all(); flush = YES; } /* Make sure all changes are shown. */ if ((flush == YES) || (flush == YUP)) { XFlush(display); if (flush != YUP) { redraw_time_line = MIN_DIR_REDRAW_TIME; } } else { if (redraw_time_line < MAX_DIR_REDRAW_TIME) { redraw_time_line += DIR_REDRAW_STEP_TIME; } #ifdef _DEBUG (void)fprintf(stderr, "count_channels: Redraw time = %d\n", redraw_time_line); #endif } /* Redraw every redraw_time_line ms. */ (void)XtAppAddTimeOut(app, redraw_time_line, (XtTimerCallbackProc)check_dir_status, w); return; }
/*############################ check_changes() ##########################*/ void check_changes(FILE *p_data) { static int old_amg_status = PROC_INIT_VALUE, old_archive_watch_status = PROC_INIT_VALUE, old_fd_status = PROC_INIT_VALUE, old_max_connections; static unsigned int old_sys_log_ec; static time_t next_stat_time, old_st_mtime; static char old_receive_log_history[MAX_LOG_HISTORY], old_sys_log_history[MAX_LOG_HISTORY], old_trans_log_history[MAX_LOG_HISTORY]; register int i; time_t now; if (check_fsa(YES, AFDD) == YES) { int loop_counter = 0, status; retry_check: if (old_error_history != NULL) { FREE_RT_ARRAY(old_error_history); old_error_history = NULL; } if (check_fsa(YES, AFDD) == YES) { loop_counter++; if (loop_counter < 10) { system_log(DEBUG_SIGN, __FILE__, __LINE__, _("Hmm, FSA has changed again!")); my_usleep(500000L); goto retry_check; } } status = 0; while (p_afd_status->amg_jobs & WRITTING_JID_STRUCT) { (void)my_usleep(100000L); status++; if ((status > 1) && ((status % 100) == 0)) { system_log(INFO_SIGN, __FILE__, __LINE__, _("AFDD: Timeout arrived for waiting for AMG to finish writting to JID structure.")); } } RT_ARRAY(old_error_history, no_of_hosts, ERROR_HISTORY_LENGTH, unsigned char); for (i = 0; i < no_of_hosts; i++) { if (fsa[i].real_hostname[0][0] == GROUP_IDENTIFIER) { (void)memset(old_error_history[i], 0, ERROR_HISTORY_LENGTH); } else { (void)memcpy(old_error_history[i], fsa[i].error_history, ERROR_HISTORY_LENGTH); } } host_config_counter = (int)*(unsigned char *)((char *)fsa - AFD_WORD_OFFSET + SIZEOF_INT); show_host_list(p_data); show_job_list(p_data); } else { if (host_config_counter != (int)*(unsigned char *)((char *)fsa - AFD_WORD_OFFSET + SIZEOF_INT)) { FREE_RT_ARRAY(old_error_history); RT_ARRAY(old_error_history, no_of_hosts, ERROR_HISTORY_LENGTH, unsigned char); for (i = 0; i < no_of_hosts; i++) { if (fsa[i].real_hostname[0][0] == GROUP_IDENTIFIER) { (void)memset(old_error_history[i], 0, ERROR_HISTORY_LENGTH); } else { (void)memcpy(old_error_history[i], fsa[i].error_history, ERROR_HISTORY_LENGTH); } } host_config_counter = (int)*(unsigned char *)((char *)fsa - AFD_WORD_OFFSET + SIZEOF_INT); show_host_list(p_data); } } if (check_fra(YES) == YES) { show_dir_list(p_data); } /* * It costs too much system performance to constantly stat() * the AFD_CONFIG file to see if the modification time has * changed. For this reason lets only stat() this file at a * reasonable interval of say STAT_INTERVAL seconds. */ now = time(NULL); if (next_stat_time < now) { struct stat stat_buf; next_stat_time = now + STAT_INTERVAL; if (stat(afd_config_file, &stat_buf) == 0) { if (stat_buf.st_mtime != old_st_mtime) { char *buffer; old_st_mtime = stat_buf.st_mtime; if ((eaccess(afd_config_file, F_OK) == 0) && (read_file_no_cr(afd_config_file, &buffer, YES, __FILE__, __LINE__) != INCORRECT)) { int max_connections = 0; char value[MAX_INT_LENGTH]; if (get_definition(buffer, MAX_CONNECTIONS_DEF, value, MAX_INT_LENGTH) != NULL) { max_connections = atoi(value); } if ((max_connections < 1) || (max_connections > MAX_CONFIGURABLE_CONNECTIONS)) { max_connections = MAX_DEFAULT_CONNECTIONS; } if (max_connections != old_max_connections) { old_max_connections = max_connections; (void)fprintf(p_data, "MC %d\r\n", old_max_connections); } free(buffer); } } } else { if (errno != ENOENT) { system_log(DEBUG_SIGN, __FILE__, __LINE__, _("Failed to stat() `%s' : %s"), afd_config_file, strerror(errno)); } } } if (old_sys_log_ec != p_afd_status->sys_log_ec) { char buf[LOG_FIFO_SIZE + 1]; old_sys_log_ec = p_afd_status->sys_log_ec; for (i = 0; i < LOG_FIFO_SIZE; i++) { buf[i] = p_afd_status->sys_log_fifo[i] + ' '; } buf[i] = '\0'; (void)fprintf(p_data, "SR %u %s\r\n", old_sys_log_ec, buf); } if (memcmp(old_receive_log_history, p_afd_status->receive_log_history, MAX_LOG_HISTORY) != 0) { char buf[MAX_LOG_HISTORY + 1]; (void)memcpy(old_receive_log_history, p_afd_status->receive_log_history, MAX_LOG_HISTORY); for (i = 0; i < MAX_LOG_HISTORY; i++) { buf[i] = p_afd_status->receive_log_history[i] + ' '; } buf[i] = '\0'; (void)fprintf(p_data, "RH %s\r\n", buf); } if (memcmp(old_sys_log_history, p_afd_status->sys_log_history, MAX_LOG_HISTORY) != 0) { char buf[MAX_LOG_HISTORY + 1]; (void)memcpy(old_sys_log_history, p_afd_status->sys_log_history, MAX_LOG_HISTORY); for (i = 0; i < MAX_LOG_HISTORY; i++) { buf[i] = p_afd_status->sys_log_history[i] + ' '; } buf[i] = '\0'; (void)fprintf(p_data, "SH %s\r\n", buf); } if (memcmp(old_trans_log_history, p_afd_status->trans_log_history, MAX_LOG_HISTORY) != 0) { char buf[MAX_LOG_HISTORY + 1]; (void)memcpy(old_trans_log_history, p_afd_status->trans_log_history, MAX_LOG_HISTORY); for (i = 0; i < MAX_LOG_HISTORY; i++) { buf[i] = p_afd_status->trans_log_history[i] + ' '; } buf[i] = '\0'; (void)fprintf(p_data, "TH %s\r\n", buf); } for (i = 0; i < no_of_hosts; i++) { if (fsa[i].real_hostname[0][0] != GROUP_IDENTIFIER) { if (memcmp(old_error_history[i], fsa[i].error_history, ERROR_HISTORY_LENGTH) != 0) { int k; (void)memcpy(old_error_history[i], fsa[i].error_history, ERROR_HISTORY_LENGTH); (void)fprintf(p_data, "EL %d %d", i, old_error_history[i][0]); for (k = 1; k < ERROR_HISTORY_LENGTH; k++) { (void)fprintf(p_data, " %d", old_error_history[i][k]); } (void)fprintf(p_data, "\r\n"); } } } /* * Check if status of any of the main process (AMG, FD and * archive_watch) have changed. */ if (old_amg_status != p_afd_status->amg) { old_amg_status = p_afd_status->amg; (void)fprintf(p_data, "AM %d\r\n", old_amg_status); } if (old_fd_status != p_afd_status->fd) { old_fd_status = p_afd_status->fd; (void)fprintf(p_data, "FD %d\r\n", old_fd_status); } if (old_archive_watch_status != p_afd_status->archive_watch) { old_archive_watch_status = p_afd_status->archive_watch; (void)fprintf(p_data, "AW %d\r\n", old_archive_watch_status); } (void)fflush(p_data); return; }
/*$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$ main() $$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$*/ int main(int argc, char *argv[]) { register int i, j; int current_year, hour, new_year, status, test_sec_counter, test_hour_counter; unsigned int ui_value; /* Temporary storage for uns. ints */ time_t next_rescan_time = 0L, now; long int sleep_time; double d_value[MAX_NO_PARALLEL_JOBS]; /* Temporary storage */ /* for doubles. */ char work_dir[MAX_PATH_LENGTH], istatistic_file_name[MAX_FILENAME_LENGTH], statistic_file_name[MAX_FILENAME_LENGTH]; struct timeval timeout; struct stat stat_buf; struct tm *p_ts; CHECK_FOR_VERSION(argc, argv); /* Evaluate arguments */ statistic_file_name[0] = istatistic_file_name[0] = '\0'; if (get_afd_path(&argc, argv, work_dir) < 0) { exit(INCORRECT); } eval_input_as(argc, argv, work_dir, statistic_file_name, istatistic_file_name); #ifdef HAVE_SETPRIORITY get_afd_config_value(); #endif /* Initialize variables */ now = time(NULL); p_ts = gmtime(&now); /* * NOTE: We must put the hour into a temporary storage since * function system_log() uses the function localtime which seems * to overwrite our p_ts->tm_hour with local time!? */ hour = p_ts->tm_hour; current_year = p_ts->tm_year + 1900; p_work_dir = work_dir; if (statistic_file_name[0] == '\0') { char str_year[6]; (void)sprintf(str_year, ".%d", current_year); (void)strcpy(statistic_file, work_dir); (void)strcat(statistic_file, LOG_DIR); (void)strcpy(new_statistic_file, statistic_file); (void)strcat(new_statistic_file, NEW_STATISTIC_FILE); (void)strcat(new_statistic_file, str_year); (void)strcpy(new_istatistic_file, statistic_file); (void)strcat(new_istatistic_file, NEW_ISTATISTIC_FILE); (void)strcat(new_istatistic_file, str_year); (void)strcpy(istatistic_file, statistic_file); (void)strcat(istatistic_file, ISTATISTIC_FILE); (void)strcat(istatistic_file, str_year); (void)strcat(statistic_file, STATISTIC_FILE); (void)strcat(statistic_file, str_year); } else { (void)strcpy(statistic_file, statistic_file_name); (void)strcpy(new_statistic_file, statistic_file); (void)strcat(new_statistic_file, ".NEW"); (void)strcpy(istatistic_file, istatistic_file_name); (void)strcpy(new_istatistic_file, istatistic_file); (void)strcat(new_istatistic_file, ".NEW"); } if (other_file == NO) { char sys_log_fifo[MAX_PATH_LENGTH]; (void)strcpy(sys_log_fifo, work_dir); (void)strcat(sys_log_fifo, FIFO_DIR); (void)strcat(sys_log_fifo, SYSTEM_LOG_FIFO); /* If the process AFD has not yet created the */ /* system log fifo create it now. */ if ((stat(sys_log_fifo, &stat_buf) < 0) || (!S_ISFIFO(stat_buf.st_mode))) { if (make_fifo(sys_log_fifo) < 0) { (void)fprintf(stderr, "ERROR : Could not create fifo %s. (%s %d)\n", sys_log_fifo, __FILE__, __LINE__); exit(INCORRECT); } } /* Open system log fifo */ #ifdef WITHOUT_FIFO_RW_SUPPORT if (open_fifo_rw(sys_log_fifo, &sys_log_readfd, &sys_log_fd) == -1) #else if ((sys_log_fd = open(sys_log_fifo, O_RDWR)) == -1) #endif { (void)fprintf(stderr, "ERROR : Could not open fifo %s : %s (%s %d)\n", sys_log_fifo, strerror(errno), __FILE__, __LINE__); exit(INCORRECT); } } /* Attach to FSA (output) and FRA (input) so we can */ /* accumulate the statistics for both. */ if (fsa_attach(AFD_STAT) < 0) { system_log(FATAL_SIGN, __FILE__, __LINE__, "Failed to attach to FSA."); exit(INCORRECT); } if (fra_attach() < 0) { system_log(FATAL_SIGN, __FILE__, __LINE__, "Failed to attach to FRA."); exit(INCORRECT); } /* * Read old AFD statistics database file if it is there. If not creat it! */ read_afd_stat_db(no_of_hosts); read_afd_istat_db(no_of_dirs); /* Tell user we are starting the AFD_STAT */ if (other_file == NO) { system_log(INFO_SIGN, NULL, 0, "Starting %s (%s)", AFD_STAT, PACKAGE_VERSION); } /* Do some cleanups when we exit */ if (atexit(stat_exit) != 0) { system_log(FATAL_SIGN, __FILE__, __LINE__, "Could not register exit handler : %s", strerror(errno)); exit(INCORRECT); } /* Ignore any SIGHUP signal. */ if ((signal(SIGINT, sig_exit) == SIG_ERR) || (signal(SIGQUIT, sig_exit) == SIG_ERR) || (signal(SIGTERM, sig_exit) == SIG_ERR) || (signal(SIGSEGV, sig_segv) == SIG_ERR) || (signal(SIGBUS, sig_bus) == SIG_ERR) || (signal(SIGHUP, SIG_IGN) == SIG_ERR)) { system_log(DEBUG_SIGN, __FILE__, __LINE__, "signal() error : %s", strerror(errno)); } next_rescan_time = (now / STAT_RESCAN_TIME) * STAT_RESCAN_TIME + STAT_RESCAN_TIME; /* Initialize sec_counter, hour_counter and day_counter. */ test_sec_counter = (((p_ts->tm_min * 60) + p_ts->tm_sec) / STAT_RESCAN_TIME) + 1; for (i = 0; i < no_of_hosts; i++) { stat_db[i].sec_counter = test_sec_counter; stat_db[i].hour_counter = hour; stat_db[i].day_counter = p_ts->tm_yday; } for (i = 0; i < no_of_dirs; i++) { istat_db[i].sec_counter = test_sec_counter; istat_db[i].hour_counter = hour; istat_db[i].day_counter = p_ts->tm_yday; } for (;;) { if ((sleep_time = (next_rescan_time - time(NULL))) < 0) { sleep_time = 0L; } timeout.tv_usec = 0; timeout.tv_sec = sleep_time; status = select(0, NULL, NULL, NULL, &timeout); /* Did we get a timeout? */ if (status == 0) { now = time(NULL); if (now != next_rescan_time) { now = (now + (STAT_RESCAN_TIME / 2)) / STAT_RESCAN_TIME * STAT_RESCAN_TIME; } next_rescan_time = (now / STAT_RESCAN_TIME) * STAT_RESCAN_TIME + STAT_RESCAN_TIME; p_ts = gmtime(&now); test_sec_counter = ((p_ts->tm_min * 60) + p_ts->tm_sec) / STAT_RESCAN_TIME; test_hour_counter = p_ts->tm_hour; if (test_sec_counter != stat_db[0].sec_counter) { if ((((stat_db[0].sec_counter - test_sec_counter) == 1) && (test_hour_counter == stat_db[0].hour_counter)) || ((stat_db[0].sec_counter == 0) && (test_sec_counter == 719))) { (void)sleep(STAT_RESCAN_TIME); } else { system_log(DEBUG_SIGN, __FILE__, __LINE__, "Hmmm..., second counter wrong [%d -> %d]. Correcting.", stat_db[0].sec_counter, test_sec_counter); for (i = 0; i < no_of_hosts; i++) { stat_db[i].sec_counter = test_sec_counter; } for (i = 0; i < no_of_dirs; i++) { istat_db[i].sec_counter = test_sec_counter; } } } if (test_hour_counter != stat_db[0].hour_counter) { if ((((test_hour_counter + 1) == stat_db[0].hour_counter) || ((stat_db[0].hour_counter == 0) && (test_hour_counter == 23))) && (p_ts->tm_min == 59) && (p_ts->tm_sec > 54)) { /* Sometimes it happens that current time is just one */ /* second behind and when this is just before the hour */ /* value changes we think we are an hour behind. */; } else { system_log(DEBUG_SIGN, __FILE__, __LINE__, "Hmmm..., hour counter wrong [%d -> %d]. Correcting.", stat_db[0].hour_counter, test_hour_counter); for (i = 0; i < no_of_hosts; i++) { stat_db[i].hour_counter = test_hour_counter; stat_db[i].day[stat_db[i].hour_counter].nfs = 0; stat_db[i].day[stat_db[i].hour_counter].nbs = 0.0; stat_db[i].day[stat_db[i].hour_counter].ne = 0; stat_db[i].day[stat_db[i].hour_counter].nc = 0; } for (i = 0; i < no_of_dirs; i++) { istat_db[i].hour_counter = test_hour_counter; istat_db[i].day[istat_db[i].hour_counter].nfr = 0; istat_db[i].day[istat_db[i].hour_counter].nbr = 0.0; } } } /* * If the FSA or FRA canges we have to reread everything. This * is easier then trying to find out where the change took * place and change only that part. This is not very effective. * But since changes in the FSA or FRA are very seldom and the * size of the status is relative small, it seems to be * the best solution at this point. */ if (check_fsa(NO, AFD_STAT) == YES) { read_afd_stat_db(no_of_hosts); } if (check_fra(NO) == YES) { read_afd_istat_db(no_of_dirs); } /* * Now lets update the statistics. There are two methods that * can be used to update the data. The first one is to have * a pointer telling which is the newest data. In the second * method we always move everything in the array one position * backwards. The advantage of the first method is that we * don't have to move around any data. However it is more * difficult to evaluate the data when we want to display * the information graphicaly. This can be done better with the * second method. * Lets try the first method first and see how it works. */ for (i = 0; i < no_of_hosts; i++) { /***********************************/ /* Handle structure entry for day. */ /***********************************/ /* Store number of files send. */ ui_value = fsa[i].file_counter_done; if (ui_value >= stat_db[i].prev_nfs) { stat_db[i].hour[stat_db[i].sec_counter].nfs = ui_value - stat_db[i].prev_nfs; } else { /* Check if an overflow has occured */ if ((UINT_MAX - stat_db[i].prev_nfs) <= MAX_FILES_PER_SCAN) { stat_db[i].hour[stat_db[i].sec_counter].nfs = ui_value + UINT_MAX - stat_db[i].prev_nfs; } else /* To large. Lets assume it was a reset of the AFD. */ { stat_db[i].hour[stat_db[i].sec_counter].nfs = ui_value; } } stat_db[i].day[stat_db[i].hour_counter].nfs += stat_db[i].hour[stat_db[i].sec_counter].nfs; stat_db[i].prev_nfs = ui_value; /* Store number of bytes send. */ stat_db[i].hour[stat_db[i].sec_counter].nbs = 0.0; for (j = 0; j < MAX_NO_PARALLEL_JOBS; j++) { d_value[j] = (double)fsa[i].job_status[j].bytes_send; if (d_value[j] >= stat_db[i].prev_nbs[j]) { stat_db[i].hour[stat_db[i].sec_counter].nbs += d_value[j] - stat_db[i].prev_nbs[j]; } else { stat_db[i].hour[stat_db[i].sec_counter].nbs += d_value[j]; } stat_db[i].prev_nbs[j] = d_value[j]; } if (stat_db[i].hour[stat_db[i].sec_counter].nbs < 0.0) { stat_db[i].hour[stat_db[i].sec_counter].nbs = 0.0; system_log(DEBUG_SIGN, __FILE__, __LINE__, "Hmm.... Byte counter less then zero?!? [%d]", i); } stat_db[i].day[stat_db[i].hour_counter].nbs += stat_db[i].hour[stat_db[i].sec_counter].nbs; /* Store number of errors. */ ui_value = fsa[i].total_errors; if (ui_value >= stat_db[i].prev_ne) { stat_db[i].hour[stat_db[i].sec_counter].ne = ui_value - stat_db[i].prev_ne; } else { stat_db[i].hour[stat_db[i].sec_counter].ne = ui_value; } stat_db[i].day[stat_db[i].hour_counter].ne += stat_db[i].hour[stat_db[i].sec_counter].ne; stat_db[i].prev_ne = ui_value; /* Store number of connections. */ ui_value = fsa[i].connections; if (ui_value >= stat_db[i].prev_nc) { stat_db[i].hour[stat_db[i].sec_counter].nc = ui_value - stat_db[i].prev_nc; } else { stat_db[i].hour[stat_db[i].sec_counter].nc = ui_value; } stat_db[i].day[stat_db[i].hour_counter].nc += stat_db[i].hour[stat_db[i].sec_counter].nc; stat_db[i].prev_nc = ui_value; stat_db[i].sec_counter++; } /* for (i = 0; i < no_of_hosts; i++) */ /* Now do the same thing for the input. */ for (i = 0; i < no_of_dirs; i++) { /***********************************/ /* Handle structure entry for day. */ /***********************************/ /* Store number of files received. */ ui_value = fra[i].files_received; if (ui_value >= istat_db[i].prev_nfr) { istat_db[i].hour[istat_db[i].sec_counter].nfr = ui_value - istat_db[i].prev_nfr; } else { /* Check if an overflow has occured */ if ((UINT_MAX - istat_db[i].prev_nfr) <= MAX_FILES_PER_SCAN) { istat_db[i].hour[istat_db[i].sec_counter].nfr = ui_value + UINT_MAX - istat_db[i].prev_nfr; } else /* To large. Lets assume it was a reset of the AFD. */ { istat_db[i].hour[istat_db[i].sec_counter].nfr = ui_value; } } istat_db[i].day[istat_db[i].hour_counter].nfr += istat_db[i].hour[istat_db[i].sec_counter].nfr; istat_db[i].prev_nfr = ui_value; /* Store number of bytes received. */ d_value[0] = (double)fra[i].bytes_received; if (d_value[0] >= istat_db[i].prev_nbr) { istat_db[i].hour[istat_db[i].sec_counter].nbr = d_value[0] - istat_db[i].prev_nbr; } else { istat_db[i].hour[istat_db[i].sec_counter].nbr = d_value[0]; } if (istat_db[i].hour[istat_db[i].sec_counter].nbr < 0.0) { istat_db[i].hour[istat_db[i].sec_counter].nbr = 0.0; system_log(DEBUG_SIGN, __FILE__, __LINE__, "Hmm.... Byte counter less then zero?!? [%d: %f %f]", i, d_value[0], istat_db[i].prev_nbr); } istat_db[i].day[istat_db[i].hour_counter].nbr += istat_db[i].hour[istat_db[i].sec_counter].nbr; istat_db[i].prev_nbr = d_value[0]; istat_db[i].sec_counter++; } /* for (i = 0; i < no_of_dirs; i++) */ /* Did we reach another hour? */ if (stat_db[0].sec_counter >= SECS_PER_HOUR) { for (i = 0; i < no_of_hosts; i++) { /* Reset the counter for the day structure */ stat_db[i].sec_counter = 0; stat_db[i].hour_counter++; if (stat_db[i].hour_counter >= HOURS_PER_DAY) { stat_db[i].hour_counter = 0; stat_db[i].year[stat_db[i].day_counter].nfs = 0; stat_db[i].year[stat_db[i].day_counter].nbs = 0.0; stat_db[i].year[stat_db[i].day_counter].ne = 0; stat_db[i].year[stat_db[i].day_counter].nc = 0; for (j = 0; j < HOURS_PER_DAY; j++) { stat_db[i].year[stat_db[i].day_counter].nfs += stat_db[i].day[j].nfs; stat_db[i].year[stat_db[i].day_counter].nbs += stat_db[i].day[j].nbs; stat_db[i].year[stat_db[i].day_counter].ne += stat_db[i].day[j].ne; stat_db[i].year[stat_db[i].day_counter].nc += stat_db[i].day[j].nc; } stat_db[i].day_counter++; } stat_db[i].day[stat_db[i].hour_counter].nfs = 0; stat_db[i].day[stat_db[i].hour_counter].nbs = 0.0; stat_db[i].day[stat_db[i].hour_counter].ne = 0; stat_db[i].day[stat_db[i].hour_counter].nc = 0; } for (i = 0; i < no_of_dirs; i++) { /* Reset the counter for the day structure */ istat_db[i].sec_counter = 0; istat_db[i].hour_counter++; if (istat_db[i].hour_counter >= HOURS_PER_DAY) { istat_db[i].hour_counter = 0; istat_db[i].year[istat_db[i].day_counter].nfr = 0; istat_db[i].year[istat_db[i].day_counter].nbr = 0.0; for (j = 0; j < HOURS_PER_DAY; j++) { istat_db[i].year[istat_db[i].day_counter].nfr += istat_db[i].day[j].nfr; istat_db[i].year[istat_db[i].day_counter].nbr += istat_db[i].day[j].nbr; } istat_db[i].day_counter++; } istat_db[i].day[istat_db[i].hour_counter].nfr = 0; istat_db[i].day[istat_db[i].hour_counter].nbr = 0.0; } } /* if (stat_db[i].sec_counter >= SECS_PER_HOUR) */ /* Did we reach another year? */ new_year = p_ts->tm_year + 1900; if (current_year != new_year) { if (other_file == NO) { save_old_input_year(new_year); save_old_output_year(new_year); } current_year = new_year; /* * Reset all values in current memory mapped file. Watch out * for leap seconds and NTP! */ if ((test_hour_counter == 23) && (p_ts->tm_min == 59) && (p_ts->tm_yday >= 363)) { test_sec_counter = 0; test_hour_counter = 0; j = 0; } else { test_sec_counter = ((p_ts->tm_min * 60) + p_ts->tm_sec) / STAT_RESCAN_TIME; j = p_ts->tm_yday; } for (i = 0; i < no_of_hosts; i++) { stat_db[i].sec_counter = test_sec_counter; stat_db[i].hour_counter = test_hour_counter; stat_db[i].day_counter = j; (void)memset(&stat_db[i].year, 0, (DAYS_PER_YEAR * sizeof(struct statistics))); (void)memset(&stat_db[i].day, 0, (HOURS_PER_DAY * sizeof(struct statistics))); (void)memset(&stat_db[i].hour, 0, (SECS_PER_HOUR * sizeof(struct statistics))); } for (i = 0; i < no_of_dirs; i++) { istat_db[i].sec_counter = test_sec_counter; istat_db[i].hour_counter = test_hour_counter; istat_db[i].day_counter = j; (void)memset(&istat_db[i].year, 0, (DAYS_PER_YEAR * sizeof(struct istatistics))); (void)memset(&istat_db[i].day, 0, (HOURS_PER_DAY * sizeof(struct istatistics))); (void)memset(&istat_db[i].hour, 0, (SECS_PER_HOUR * sizeof(struct istatistics))); } } if (stat_db[0].day_counter >= DAYS_PER_YEAR) { system_log(DEBUG_SIGN, __FILE__, __LINE__, "Hmmm..., day counter wrong [%d -> 0]. Correcting.", stat_db[0].day_counter); for (i = 0; i < no_of_hosts; i++) { stat_db[i].day_counter = p_ts->tm_yday; } for (i = 0; i < no_of_dirs; i++) { istat_db[i].day_counter = p_ts->tm_yday; } } } /* An error has occured */ else if (status < 0) { system_log(FATAL_SIGN, __FILE__, __LINE__, "select() error : %s", strerror(errno)); exit(INCORRECT); } else { system_log(FATAL_SIGN, __FILE__, __LINE__, "Unknown condition."); exit(INCORRECT); } } /* for (;;) */ exit(SUCCESS); }