/*############################ check_fra() ##############################*/ int check_fra(int passive) { if (fra != NULL) { char *ptr; ptr = (char *)fra; ptr -= AFD_WORD_OFFSET; if (*(int *)ptr == STALE) { #ifdef HAVE_MMAP if (munmap(ptr, fra_size) == -1) { system_log(ERROR_SIGN, __FILE__, __LINE__, _("Failed to munmap() from FRA [fra_id = %d fra_size = %d] : %s"), fra_id, fra_size, strerror(errno)); } #else if (munmap_emu(ptr) == -1) { system_log(ERROR_SIGN, __FILE__, __LINE__, _("Failed to munmap_emu() from FRA (%d) : %s"), fra_id, strerror(errno)); } #endif if (passive == YES) { if (fra_attach_passive() != SUCCESS) { system_log(ERROR_SIGN, __FILE__, __LINE__, _("Passive attach to FRA failed.")); exit(INCORRECT); } } else { if (fra_attach() != SUCCESS) { system_log(ERROR_SIGN, __FILE__, __LINE__, _("Failed to attach to FRA.")); exit(INCORRECT); } } return(YES); } } return(NO); }
/*$$$$$$$$$$$$$$$$$$$$$$$$$$$$ fra_edit() $$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$*/ int main(int argc, char *argv[]) { int position = -1, leave_flag = NO, ret; unsigned int value; char dir_alias[MAX_DIR_ALIAS_LENGTH + 1], work_dir[MAX_PATH_LENGTH]; CHECK_FOR_VERSION(argc, argv); if (get_afd_path(&argc, argv, work_dir) < 0) { exit(INCORRECT); } p_work_dir = work_dir; if (argc == 2) { if (isdigit((int)(argv[1][0])) != 0) { position = atoi(argv[1]); } else { (void)strcpy(dir_alias, argv[1]); } } else { usage(argv[0]); exit(INCORRECT); } if ((ret = fra_attach()) < 0) { if (ret == INCORRECT_VERSION) { (void)fprintf(stderr, _("ERROR : This program is not able to attach to the FRA due to incorrect version. (%s %d)\n"), __FILE__, __LINE__); } else { (void)fprintf(stderr, _("ERROR : Failed to attach to FRA. (%s %d)\n"), __FILE__, __LINE__); } exit(INCORRECT); } if (tcgetattr(STDIN_FILENO, &buf) < 0) { (void)fprintf(stderr, _("ERROR : tcgetattr() error : %s (%s %d)\n"), strerror(errno), __FILE__, __LINE__); exit(0); } if (position < 0) { if ((position = get_dir_position(fra, dir_alias, no_of_dirs)) < 0) { (void)fprintf(stderr, _("ERROR : Could not find directory %s in FRA. (%s %d)\n"), dir_alias, __FILE__, __LINE__); exit(INCORRECT); } } for (;;) { menu(position); switch (get_key()) { case 0 : break; case '1' : (void)fprintf(stderr, _("\n\n Enter value [1] : ")); if (scanf("%11u", &value) == EOF) { (void)fprintf(stderr, _("ERROR : scanf() error, failed to read input : %s (%s %d)\n"), strerror(errno), __FILE__, __LINE__); exit(INCORRECT); } fra[position].files_in_dir = (int)value; break; case '2' : (void)fprintf(stderr, _("\n\n Enter value [2] : ")); if (scanf("%11u", &value) == EOF) { (void)fprintf(stderr, _("ERROR : scanf() error, failed to read input : %s (%s %d)\n"), strerror(errno), __FILE__, __LINE__); exit(INCORRECT); } fra[position].bytes_in_dir = value; break; case '3' : (void)fprintf(stderr, _("\n\n Enter value [3] : ")); if (scanf("%11u", &value) == EOF) { (void)fprintf(stderr, _("ERROR : scanf() error, failed to read input : %s (%s %d)\n"), strerror(errno), __FILE__, __LINE__); exit(INCORRECT); } fra[position].files_queued = value; break; case '4' : (void)fprintf(stderr, _("\n\n Enter value [4] : ")); if (scanf("%11u", &value) == EOF) { (void)fprintf(stderr, _("ERROR : scanf() error, failed to read input : %s (%s %d)\n"), strerror(errno), __FILE__, __LINE__); exit(INCORRECT); } fra[position].bytes_in_queue = value; break; case '5' : (void)fprintf(stderr, _("\n\n Enter value [5] : ")); if (scanf("%11u", &value) == EOF) { (void)fprintf(stderr, _("ERROR : scanf() error, failed to read input : %s (%s %d)\n"), strerror(errno), __FILE__, __LINE__); exit(INCORRECT); } fra[position].error_counter = value; break; case '6' : (void)fprintf(stdout, "\033[2J\033[3;1H"); (void)fprintf(stdout, "\n\n\n"); (void)fprintf(stdout, " Reset to zero.................(0)\n"); (void)fprintf(stdout, " MAX_COPIED [%d]...............(1)\n", (fra[position].dir_flag & MAX_COPIED) ? 1 : 0); (void)fprintf(stdout, " FILES_IN_QUEUE [%d]...........(2)\n", (fra[position].dir_flag & FILES_IN_QUEUE) ? 1 : 0); (void)fprintf(stdout, " ADD_TIME_ENTRY [%d]...........(3)\n", (fra[position].dir_flag & ADD_TIME_ENTRY) ? 1 : 0); (void)fprintf(stdout, " LINK_NO_EXEC [%d].............(4)\n", (fra[position].dir_flag & LINK_NO_EXEC) ? 1 : 0); (void)fprintf(stdout, " DIR_DISABLED [%d].............(5)\n", (fra[position].dir_flag & DIR_DISABLED) ? 1 : 0); (void)fprintf(stdout, " ACCEPT_DOT_FILES [%d].........(6)\n", (fra[position].dir_flag & ACCEPT_DOT_FILES) ? 1 : 0); (void)fprintf(stdout, " DONT_GET_DIR_LIST [%d]........(7)\n", (fra[position].dir_flag & DONT_GET_DIR_LIST) ? 1 : 0); (void)fprintf(stdout, " DIR_ERROR_SET [%d]............(8)\n", (fra[position].dir_flag & DIR_ERROR_SET) ? 1 : 0); (void)fprintf(stdout, " WARN_TIME_REACHED [%d]........(9)\n", (fra[position].dir_flag & WARN_TIME_REACHED) ? 1 : 0); (void)fprintf(stdout, " DIR_ERROR_ACKN [%d]...........(a)\n", (fra[position].dir_flag & DIR_ERROR_ACKN) ? 1 : 0); (void)fprintf(stdout, " DIR_ERROR_OFFLINE [%d]........(b)\n", (fra[position].dir_flag & DIR_ERROR_OFFLINE) ? 1 : 0); (void)fprintf(stdout, " DIR_ERROR_ACKN_T [%d].........(c)\n", (fra[position].dir_flag & DIR_ERROR_ACKN_T) ? 1 : 0); (void)fprintf(stdout, " DIR_ERROR_OFFL_T [%d].........(d)\n", (fra[position].dir_flag & DIR_ERROR_OFFL_T) ? 1 : 0); (void)fprintf(stdout, " DIR_STOPPED [%d]..............(e)\n", (fra[position].dir_flag & DIR_ERROR_OFFL_T) ? 1 : 0); #ifdef WITH_INOTIFY (void)fprintf(stdout, " INOTIFY_RENAME [%d]...........(f)\n", (fra[position].dir_flag & INOTIFY_RENAME) ? 1 : 0); (void)fprintf(stdout, " INOTIFY_CLOSE [%d]............(g)\n", (fra[position].dir_flag & INOTIFY_CLOSE) ? 1 : 0); (void)fprintf(stdout, " INOTIFY_CREATE [%d]...........(h)\n", (fra[position].dir_flag & INOTIFY_CREATE) ? 1 : 0); #endif (void)fprintf(stdout, " ALL_DISABLED [%d].............(i)\n", (fra[position].dir_flag & ALL_DISABLED) ? 1 : 0); (void)fprintf(stdout, " CREATE_R_SRC_DIR [%d].........(j)\n", (fra[position].dir_flag & CREATE_R_SRC_DIR) ? 1 : 0); (void)fprintf(stderr, " None..........................(Z) "); switch (get_key()) { case '0' : fra[position].dir_flag = 0; break; case '1' : fra[position].dir_flag ^= MAX_COPIED; break; case '2' : fra[position].dir_flag ^= FILES_IN_QUEUE; break; case '3' : fra[position].dir_flag ^= ADD_TIME_ENTRY; break; case '4' : fra[position].dir_flag ^= LINK_NO_EXEC; break; case '5' : fra[position].dir_flag ^= DIR_DISABLED; break; case '6' : fra[position].dir_flag ^= ACCEPT_DOT_FILES; break; case '7' : fra[position].dir_flag ^= DONT_GET_DIR_LIST; break; case '8' : fra[position].dir_flag ^= DIR_ERROR_SET; break; case '9' : fra[position].dir_flag ^= WARN_TIME_REACHED; break; case 'a' : fra[position].dir_flag ^= DIR_ERROR_ACKN; break; case 'b' : fra[position].dir_flag ^= DIR_ERROR_OFFLINE; break; case 'c' : fra[position].dir_flag ^= DIR_ERROR_ACKN_T; break; case 'd' : fra[position].dir_flag ^= DIR_ERROR_OFFL_T; break; case 'e' : fra[position].dir_flag ^= DIR_STOPPED; break; #ifdef WITH_INOTIFY case 'f' : fra[position].dir_flag ^= INOTIFY_RENAME; break; case 'g' : fra[position].dir_flag ^= INOTIFY_CLOSE; break; case 'h' : fra[position].dir_flag ^= INOTIFY_CREATE; break; #endif case 'i' : fra[position].dir_flag ^= ALL_DISABLED; break; case 'j' : fra[position].dir_flag ^= CREATE_R_SRC_DIR; break; case 'Z' : break; default : (void)printf(_("Wrong choice!\n")); (void)sleep(1); break; } break; case '7' : (void)fprintf(stderr, _("\n\n Enter value [7] : ")); if (scanf("%11u", &value) == EOF) { (void)fprintf(stderr, _("ERROR : scanf() error, failed to read input : %s (%s %d)\n"), strerror(errno), __FILE__, __LINE__); exit(INCORRECT); } fra[position].queued = (char)value; break; case 'x' : case 'Q' : case 'q' : leave_flag = YES; break; default : (void)printf(_("Wrong choice!\n")); (void)sleep(1); break; } if (leave_flag == YES) { (void)fprintf(stdout, "\n\n"); break; } else { (void)my_usleep(100000L); } } /* for (;;) */ exit(SUCCESS); }
/*######################### change_alias_order() ########################*/ void change_alias_order(char **p_host_names, int new_no_of_hosts) { int i, ignore_first_errors, fd, position, pagesize, old_no_of_hosts = no_of_hosts, loop_no_of_hosts, current_fsa_id, new_fsa_fd; off_t new_fsa_size; char *ptr, fsa_id_file[MAX_PATH_LENGTH], new_fsa_stat[MAX_PATH_LENGTH]; struct flock wlock; struct filetransfer_status *new_fsa; if (new_no_of_hosts != -1) { if (no_of_hosts > new_no_of_hosts) { loop_no_of_hosts = no_of_hosts; } else { loop_no_of_hosts = new_no_of_hosts; } no_of_hosts = new_no_of_hosts; } else { loop_no_of_hosts = no_of_hosts; } (void)strcpy(fsa_id_file, p_work_dir); (void)strcat(fsa_id_file, FIFO_DIR); (void)strcat(fsa_id_file, FSA_ID_FILE); wlock.l_type = F_WRLCK; wlock.l_whence = SEEK_SET; wlock.l_start = 0; #ifdef HAVE_MMAP wlock.l_len = fsa_size; #else wlock.l_len = AFD_WORD_OFFSET + (no_of_hosts * sizeof(struct filetransfer_status)); #endif /* HAVE_MMAP */ if (fcntl(fsa_fd, F_SETLKW, &wlock) < 0) { /* Is lock already set or are we setting it again? */ if ((errno != EACCES) && (errno != EAGAIN) && (errno != EBUSY)) { system_log(ERROR_SIGN, __FILE__, __LINE__, _("Could not set write lock for FSA_STAT_FILE : %s"), strerror(errno)); } else { system_log(DEBUG_SIGN, __FILE__, __LINE__, _("Could not set write lock for FSA_STAT_FILE : %s"), strerror(errno)); } } /* * When changing the order of the hosts, lock the FSA_ID_FILE so no * one gets the idea to do the same thing or change the DIR_CONFIG * file. */ if ((fd = lock_file(fsa_id_file, ON)) < 0) { system_log(ERROR_SIGN, __FILE__, __LINE__, _("Failed to lock `%s' [%d]"), fsa_id_file, fd); exit(INCORRECT); } /* Read the fsa_id. */ if (read(fd, ¤t_fsa_id, sizeof(int)) < 0) { system_log(ERROR_SIGN, __FILE__, __LINE__, _("Could not read the value of the fsa_id : %s"), strerror(errno)); (void)close(fd); exit(INCORRECT); } if (current_fsa_id != fsa_id) { system_log(DEBUG_SIGN, __FILE__, __LINE__, _("AAAaaaarrrrghhhh!!! DON'T CHANGE THE DIR_CONFIG FILE WHILE USING edit_hc!!!!")); (void)close(fd); exit(INCORRECT); } current_fsa_id++; /* Mark old FSA as stale. */ *(int *)((char *)fsa - AFD_WORD_OFFSET) = STALE; pagesize = *(int *)((char *)fsa - AFD_WORD_OFFSET + SIZEOF_INT + 4); ignore_first_errors = *(unsigned char *)((char *)fsa - AFD_WORD_OFFSET + SIZEOF_INT + 1 + 1); /* * Create a new FSA with the new ordering of the host aliases. */ (void)snprintf(new_fsa_stat, MAX_PATH_LENGTH, "%s%s%s.%d", p_work_dir, FIFO_DIR, FSA_STAT_FILE, current_fsa_id); /* Now map the new FSA region to a file. */ if ((new_fsa_fd = coe_open(new_fsa_stat, (O_RDWR | O_CREAT | O_TRUNC), FILE_MODE)) < 0) { system_log(FATAL_SIGN, __FILE__, __LINE__, _("Failed to open() `%s' : %s"), new_fsa_stat, strerror(errno)); exit(INCORRECT); } new_fsa_size = AFD_WORD_OFFSET + (no_of_hosts * sizeof(struct filetransfer_status)); if (lseek(new_fsa_fd, new_fsa_size - 1, SEEK_SET) == -1) { system_log(FATAL_SIGN, __FILE__, __LINE__, _("Failed to lseek() in `%s' : %s"), new_fsa_stat, strerror(errno)); exit(INCORRECT); } if (write(new_fsa_fd, "", 1) != 1) { system_log(FATAL_SIGN, __FILE__, __LINE__, _("write() error : %s"), strerror(errno)); exit(INCORRECT); } #ifdef HAVE_MMAP if ((ptr = mmap(NULL, new_fsa_size, (PROT_READ | PROT_WRITE), MAP_SHARED, new_fsa_fd, 0)) == (caddr_t) -1) #else if ((ptr = mmap_emu(NULL, new_fsa_size, (PROT_READ | PROT_WRITE), MAP_SHARED, new_fsa_stat, 0)) == (caddr_t) -1) #endif { system_log(FATAL_SIGN, __FILE__, __LINE__, _("mmap() error : %s"), strerror(errno)); exit(INCORRECT); } /* Write number of hosts to new mmap region. */ *(int *)ptr = no_of_hosts; *(ptr + SIZEOF_INT + 1 + 1) = ignore_first_errors; *(ptr + SIZEOF_INT + 1 + 1 + 1) = CURRENT_FSA_VERSION; /* FSA version number. */ *(int *)(ptr + SIZEOF_INT + 4) = pagesize; *(ptr + SIZEOF_INT + 4 + SIZEOF_INT) = 0; /* Not used. */ *(ptr + SIZEOF_INT + 4 + SIZEOF_INT + 1) = 0; /* Not used. */ *(ptr + SIZEOF_INT + 4 + SIZEOF_INT + 2) = 0; /* Not used. */ *(ptr + SIZEOF_INT + 4 + SIZEOF_INT + 3) = 0; /* Not used. */ /* Copy configuration information from the old FSA. */ ptr += AFD_WORD_OFFSET; *((char *)ptr - AFD_FEATURE_FLAG_OFFSET_END) = *((char *)fsa - AFD_FEATURE_FLAG_OFFSET_END); /* Reposition fsa pointer after no_of_host. */ new_fsa = (struct filetransfer_status *)ptr; if (fra_attach() != SUCCESS) { system_log(FATAL_SIGN, __FILE__, __LINE__, _("Failed to attach to FRA.")); exit(INCORRECT); } /* * Now copy each entry from the old FSA to the new FSA in * the order they are found in the host_list_w. */ for (i = 0; i < loop_no_of_hosts; i++) { if (p_host_names[i][0] != '\0') { if ((position = get_host_position(fsa, p_host_names[i], old_no_of_hosts)) < 0) { if (hl != NULL) { int k; /* * Hmmm. This host is not in the FSA. So lets assume this * is a new host. */ (void)memset(&new_fsa[i], 0, sizeof(struct filetransfer_status)); (void)memcpy(new_fsa[i].host_alias, hl[i].host_alias, MAX_HOSTNAME_LENGTH + 1); new_fsa[i].host_id = get_str_checksum(new_fsa[i].host_alias); (void)snprintf(new_fsa[i].host_dsp_name, MAX_HOSTNAME_LENGTH + 2, "%-*s", MAX_HOSTNAME_LENGTH, hl[i].host_alias); new_fsa[i].toggle_pos = strlen(new_fsa[i].host_alias); (void)memcpy(new_fsa[i].real_hostname[0], hl[i].real_hostname[0], MAX_REAL_HOSTNAME_LENGTH); (void)memcpy(new_fsa[i].real_hostname[1], hl[i].real_hostname[1], MAX_REAL_HOSTNAME_LENGTH); new_fsa[i].host_toggle = HOST_ONE; if (hl[i].host_toggle_str[0] != '\0') { (void)memcpy(new_fsa[i].host_toggle_str, hl[i].host_toggle_str, MAX_TOGGLE_STR_LENGTH); if (hl[i].host_toggle_str[0] == AUTO_TOGGLE_OPEN) { new_fsa[i].auto_toggle = ON; } else { new_fsa[i].auto_toggle = OFF; } new_fsa[i].original_toggle_pos = DEFAULT_TOGGLE_HOST; new_fsa[i].host_dsp_name[(int)new_fsa[i].toggle_pos] = hl[i].host_toggle_str[(int)new_fsa[i].original_toggle_pos]; } else { new_fsa[i].host_toggle_str[0] = '\0'; new_fsa[i].original_toggle_pos = NONE; new_fsa[i].auto_toggle = OFF; } (void)memcpy(new_fsa[i].proxy_name, hl[i].proxy_name, MAX_PROXY_NAME_LENGTH + 1); new_fsa[i].transfer_rate_limit = hl[i].transfer_rate_limit; new_fsa[i].allowed_transfers = hl[i].allowed_transfers; for (k = 0; k < new_fsa[i].allowed_transfers; k++) { new_fsa[i].job_status[k].connect_status = DISCONNECT; new_fsa[i].job_status[k].proc_id = -1; #ifdef _WITH_BURST_2 new_fsa[i].job_status[k].job_id = NO_ID; #endif } for (k = new_fsa[i].allowed_transfers; k < MAX_NO_PARALLEL_JOBS; k++) { new_fsa[i].job_status[k].no_of_files = -1; new_fsa[i].job_status[k].proc_id = -1; } new_fsa[i].max_errors = hl[i].max_errors; new_fsa[i].retry_interval = hl[i].retry_interval; new_fsa[i].block_size = hl[i].transfer_blksize; new_fsa[i].max_successful_retries = hl[i].successful_retries; new_fsa[i].file_size_offset = hl[i].file_size_offset; new_fsa[i].transfer_timeout = hl[i].transfer_timeout; new_fsa[i].protocol = hl[i].protocol; new_fsa[i].protocol_options = hl[i].protocol_options; new_fsa[i].ttl = hl[i].ttl; new_fsa[i].special_flag = 0; if (hl[i].host_status & HOST_CONFIG_HOST_DISABLED) { new_fsa[i].special_flag |= HOST_DISABLED; } new_fsa[i].host_status = 0; if (hl[i].host_status & STOP_TRANSFER_STAT) { new_fsa[i].host_status |= STOP_TRANSFER_STAT; } if (hl[i].host_status & PAUSE_QUEUE_STAT) { new_fsa[i].host_status |= PAUSE_QUEUE_STAT; } } else { system_log(DEBUG_SIGN, __FILE__, __LINE__, _("AAAaaaarrrrghhhh!!! Could not find hostname `%s'"), p_host_names[i]); (void)close(fd); exit(INCORRECT); } } else { if ((position != INCORRECT) && (position != i)) { int k; for (k = 0; k < no_of_dirs; k++) { if ((fra[k].host_alias[0] != '\0') && (CHECK_STRCMP(fra[k].host_alias, fsa[position].host_alias) == 0)) { fra[k].fsa_pos = i; } } } (void)memcpy(&new_fsa[i], &fsa[position], sizeof(struct filetransfer_status)); } } } #ifdef HAVE_MMAP if (msync(ptr - AFD_WORD_OFFSET, new_fsa_size, MS_SYNC) == -1) { system_log(WARN_SIGN, __FILE__, __LINE__, "msync() error : %s", strerror(errno)); } #endif if (fra_detach() < 0) { system_log(WARN_SIGN, __FILE__, __LINE__, _("Failed to detach from FRA.")); } if (fsa_detach(NO) < 0) { system_log(WARN_SIGN, __FILE__, __LINE__, _("Failed to detach from old FSA.")); } /* Now "attach" to the new FSA. */ fsa = new_fsa; fsa_fd = new_fsa_fd; fsa_id = current_fsa_id; #ifdef HAVE_MMAP fsa_size = new_fsa_size; #endif /* Go to beginning in file. */ if (lseek(fd, 0, SEEK_SET) < 0) { system_log(ERROR_SIGN, __FILE__, __LINE__, _("Could not seek() to beginning of `%s' : %s"), fsa_id_file, strerror(errno)); } /* Write new value into FSA_ID_FILE file. */ if (write(fd, &fsa_id, sizeof(int)) != sizeof(int)) { system_log(FATAL_SIGN, __FILE__, __LINE__, _("Could not write value to FSA ID file : %s"), strerror(errno)); exit(INCORRECT); } /* Release the lock. */ if (close(fd) == -1) { system_log(DEBUG_SIGN, __FILE__, __LINE__, _("close() error : %s"), strerror(errno)); } /* Remove the old FSA file. */ (void)snprintf(new_fsa_stat, MAX_PATH_LENGTH, "%s%s%s.%d", p_work_dir, FIFO_DIR, FSA_STAT_FILE, current_fsa_id - 1); if (unlink(new_fsa_stat) < 0) { system_log(WARN_SIGN, __FILE__, __LINE__, _("unlink() error : %s"), strerror(errno)); } 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); }
/*$$$$$$$$$$$$$$$$$$$$$$$$$$$ fra_version() $$$$$$$$$$$$$$$$$$$$$$$$$$$$$*/ int main(int argc, char *argv[]) { int ret, set_version; char *ptr, work_dir[MAX_PATH_LENGTH]; CHECK_FOR_VERSION(argc, argv); if (get_afd_path(&argc, argv, work_dir) < 0) { exit(INCORRECT); } p_work_dir = work_dir; if (argc == 2) { if (isdigit((int)(argv[1][0])) != 0) { set_version = atoi(argv[1]); } else { usage(); exit(INCORRECT); } } else { set_version = -1; } if ((ret = fra_attach()) != SUCCESS) { if (ret == INCORRECT_VERSION) { (void)fprintf(stderr, _("ERROR : This program is not able to attach to the FRA due to incorrect version. (%s %d)\n"), __FILE__, __LINE__); } else { if (ret < 0) { (void)fprintf(stderr, _("ERROR : Failed to attach to FRA. (%s %d)\n"), __FILE__, __LINE__); } else { (void)fprintf(stderr, _("ERROR : Failed to attach to FRA : %s (%s %d)\n"), strerror(ret), __FILE__, __LINE__); } } exit(INCORRECT); } ptr = (char *)fra; ptr -= AFD_WORD_OFFSET; if (set_version > -1) { int current_version = (int)(*(ptr + SIZEOF_INT + 1 + 1 + 1)); *(ptr + SIZEOF_INT + 1 + 1 + 1) = set_version; (void)fprintf(stdout, _("Changed FRA version number from %d to %d\n"), current_version, set_version); } else { (void)fprintf(stdout, _("Current FRA version: %d\n"), (int)(*(ptr + SIZEOF_INT + 1 + 1 + 1))); } (void)fra_detach(); exit(SUCCESS); }