#include "mnic.h" #include "dotconf.h" #include #include #include #include #include #include #include "proc_inv.h" #include "version.h" #define THRNR 10 #define DAYS 25 #define LINE_SIZE 2048 #define HOST_NAME_SIZE 40 #define BOND_PATH "/proc/net/bonding/*" #define LOG_PATH "/var/log/netcard/" #define SHM_PATH "/share/sys_netcard_shm_path" #define SEM_PATH "/share/sys_netcard_sem_path" #define MAX_GW 32 #define DEV_MAXLEN 32 #define IPLEN 16 #define CONF_FILE "/conf/nic/sys_netcard_conf.txt" //#define MNIC_VERSION "1.9" #define NIC_UNKNOWN 0 #define NIC_DOWN 1 #define NIC_UNRUNNING 2 #define NIC_UNLINKABLE 3 #define NIC_NORMAL 4 //网卡设备描述结构 typedef struct __nic_dev{ char dev_name[DEV_MAXLEN]; //网卡名称 char ping_ip[MAX_GW][IPLEN]; //ping地址列表,最多32个 int gw_num; //地址列表的长度 }NIC_DEV; typedef struct __config_file_st{ unsigned char domain; short serv; short event; int udpport; int monitor_interval; int write_interval; int flow_interval; int flow_limit; int flow_peak; char udp[NIC_NAME_LEN]; NIC_DEV nic[MAXNICNUM]; //被监视网卡的列表 char ip[IPSIZE]; int pingnum; //OPTIONAL!! How many times for once ping check? Default is 2. int pinglap; //OPTIONAL!! How many seconds does ping wait for reply package? Default is 1. int crazyping; }CONFIG_FILE_ST; typedef struct inc_name_node{ char name[NIC_NAME_LEN]; struct inc_name_node *next; }NET_NAME_ST; typedef struct inc_info_node{ NETCARD_INFO info; int status; struct inc_info_node *next; }NETCARD_INFO_ST; typedef struct net_info{ NETCARD_INFO info[MAXNICNUM]; }SHM; typedef struct __thread_env_st{ D5000_NIC_ALARM Malarm; char bond_file_path[64]; char host_name[HOST_NAME_SIZE]; int host_name_size; CONFIG_FILE_ST *conf; }THENV; typedef struct __thread_mem_st{ int semid; SHM *shm_ptr; NETCARD_INFO_ST *listp; CONFIG_FILE_ST *conf; }THMEM; typedef struct __thread_flow_st{ THENV env; THMEM mem; }THFLOW; int find_nic_config(char *); static pthread_mutex_t mut = PTHREAD_MUTEX_INITIALIZER; static short seqno = 1; static char log_flag = 1; static int sem_id = 0; static char process_name[64]; char log_path[1024]; char shm_path[1024]; char sem_path[1024]; char conf_path[1024]; int host_name_size = 0; char host_name[HOST_NAME_SIZE]; int semid = -1; SHM *shm_ptr; //20100510 int total_ping_time, elapsed_ping_time; int get_netcard_status(NETCARD_INFO_ST *); /****dotconf****/ static DOTCONF_CB(cb_str); static DOTCONF_CB(cb_int); int nicnum = 0; CONFIG_FILE_ST conf; char myconf[][64] = { "domain", // 0 "serv", // 1 "event", // 2 "udpport", // 3 "sys_netcard_shm_path", // 4 "sys_netcard_sem_path", // 5 "monitor_interval", // 6 "write_interval", // 7 "flow_interval", // 8 "flow_limit", // 9 "flow_peak", // 10 "udp", // 11 "nic", // 12 "ping", // 13 "pingnum", // 14 "pinglap", // 15 "crazyping", // 16 "" }; static const configoption_t options[] = { {myconf[0], ARG_INT, cb_int, NULL, CTX_ALL}, {myconf[1], ARG_INT, cb_int, NULL, CTX_ALL}, {myconf[2], ARG_INT, cb_int, NULL, CTX_ALL}, {myconf[3], ARG_INT, cb_int, NULL, CTX_ALL}, {myconf[4], ARG_STR, cb_str, NULL, CTX_ALL}, {myconf[5], ARG_STR, cb_str, NULL, CTX_ALL}, {myconf[6], ARG_INT, cb_int, NULL, CTX_ALL}, {myconf[7], ARG_INT, cb_int, NULL, CTX_ALL}, {myconf[8], ARG_INT, cb_int, NULL, CTX_ALL}, {myconf[9], ARG_INT, cb_int, NULL, CTX_ALL}, {myconf[10], ARG_INT, cb_int, NULL, CTX_ALL}, {myconf[11], ARG_STR, cb_str, NULL, CTX_ALL}, {myconf[12], ARG_STR, cb_str, NULL, CTX_ALL}, {myconf[13], ARG_STR, cb_str, NULL, CTX_ALL}, {myconf[14], ARG_INT, cb_int, NULL, CTX_ALL}, {myconf[15], ARG_INT, cb_int, NULL, CTX_ALL}, {myconf[16], ARG_INT, cb_int, NULL, CTX_ALL}, LAST_OPTION }; /* 1 for output more debug information, from getenv(SYS_NIC_DEBUG) */ static int sys_nic_debug = 0; /****dotconf****/ void create_dir(char *create_path); #if 0 ///////////////// no use static pthread_mutex_t lock_record_log = PTHREAD_MUTEX_INITIALIZER; #define LOG_LOCK pthread_mutex_lock(&lock_record_log) #define LOG_UNLOCK pthread_mutex_unlock(&lock_record_log) #define MAX_LOG_COUNT 5000 static char **log_prepare = NULL; static char **log_writing = NULL; static int log_thread_exit = 1; static int log_idx = 0; static void *record_log_thread( void *arg ) { char *log_str; FILE *log_fp = NULL; char **tmp = NULL; inti i = 0; create_dir( log_path ); log_thread_exit = 0; log_fp = fopen(log_path, "a"); while( !log_thread_exit ) { if( !log_fp ) { log_fp = fopen(log_path, "a"); } //prepare log strings LOG_LOCK; tmp = log_writing; log_writing = log_prepare; log_prepare = log_writing; log_idx=0; LOG_UNLOCK; while( i < MAX_LOG_COUNT ) { log_str = log_writing[i]; if( log_str == NULL ) { break; } if( log_fp ) { fwrite( log_str, 1, strlen(log_str), log_fp ); //write to file } free( log_str ); //free log_writing[i] = NULL; //clear //next i++; } usleep(100); } //while if( log_fp ) { fclose(log_fp); } if( log_prepare ) free( log_prepare ); if( log_writing ) free( log_writing ); log_prepare = NULL; log_writing = NULL; return NULL; } /* write error in logfile */ void record_log(char *str) { #if 0 time_t tamp; char str_tm[4]; char log_str[512]; FILE *log_fp = NULL; struct tm tmptr; struct timeval tv; struct timezone tz; if((log_fp = fopen(log_path, "a")) != NULL){ tamp = time(NULL); memset(str_tm, 0, sizeof(str_tm)); memset(log_str, 0, sizeof(log_str)); localtime_r(&tamp, &tmptr); gettimeofday(&tv, &tz); snprintf(str_tm, sizeof(str_tm), "%d", (int)tv.tv_usec/1000); if(str_tm[1] == '\0')str_tm[1] = '0'; if(str_tm[2] == '\0')str_tm[2] = '0'; strftime(log_str, sizeof(log_str), "%F %T.", &tmptr); strcat(log_str, str_tm); strcat(log_str, " "); strcat(log_str, process_name); strcat(log_str, " "); strcat(log_str, str); if(fwrite(log_str, 1, strlen(log_str), log_fp) < 1){ } fclose(log_fp); } #else static int log_thread_started = 0; time_t tamp; char str_tm[4]; char log_str[512]; struct tm tmptr; struct timeval tv; struct timezone tz; pthread_t pid; char *keepstr = strdup( log_str ); tamp = time(NULL); memset(str_tm, 0, sizeof(str_tm)); memset(log_str, 0, sizeof(log_str)); localtime_r(&tamp, &tmptr); gettimeofday(&tv, &tz); snprintf(str_tm, sizeof(str_tm), "%d", (int)tv.tv_usec/1000); if(str_tm[1] == '\0')str_tm[1] = '0'; if(str_tm[2] == '\0')str_tm[2] = '0'; strftime(log_str, sizeof(log_str), "%F %T. %s %s %s", &tmptr, str_tm, process_name, str ); //check log thread if( log_thread_started == 0 ) { log_thread_started = 1; log_prepare = (char **)malloc( sizeof(char *)*MAX_LOG_COUNT ); log_writing = (char **)malloc( sizeof(char *)*MAX_LOG_COUNT ); memset( log_prepare, 0, sizeof(char *) *MAX_LOG_COUNT ); memset( log_writing, 0, sizeof(char *) *MAX_LOG_COUNT ); log_idx = 0; pthread_create( &pid, NULL, record_log_thread, (void *)NULL ); } LOG_LOCK; if( log_prepare ) { log_prepare[log_idx] = keepstr; log_idx++; } LOG_UNLOCK; #endif } #else #include "common.c" #endif static void init_sem(int *semid, CONFIG_FILE_ST *ptr) { key_t key; char error_str[200]; /* write error in logfile */ memset(error_str, 0, sizeof(error_str)); #if 0 if ((key = ftok(sem_path, SEM_PROJ_ID)) == -1) { snprintf(error_str, sizeof(error_str), "EMERG: ftok():%s\n", strerror(errno)); record_log(error_str); return; } #else key = 0x1d5200; #endif if((*semid = semget(key, 1, IPC_CREAT|0666)) == -1){ snprintf(error_str, sizeof(error_str), "EMERG: semget():%s\n", strerror(errno)); record_log(error_str); return; } if(semctl(*semid, 0, SETVAL, 1) == -1){ snprintf(error_str, sizeof(error_str), "EMERG: semctl: %s !\n", strerror(errno)); record_log(error_str); semctl(*semid, 0, IPC_RMID); return; } } static int global_share_id = -1; static int dir_share_id = -1; static void *global_shmptr = NULL; static void init_shm(SHM **ptr, CONFIG_FILE_ST *p) { #ifdef USE_OLD_MMSHARE int fd = -1; char error_str[200]; mode_t mask_tmp; mask_tmp = umask(0000); if((fd = open(shm_path, O_RDWR|O_CREAT|O_TRUNC, 0666)) == -1){ printf("could not create %s\n", shm_path); return; } umask(mask_tmp); lseek(fd, sizeof(SHM), SEEK_SET); write(fd, "\0", 1); *ptr = (SHM *)mmap(NULL, sizeof(SHM), PROT_READ|PROT_WRITE, MAP_SHARED, fd, 0); if(*ptr == MAP_FAILED){ snprintf(error_str, sizeof(error_str), "EMERG: mmap():%s\n", strerror(errno)); record_log(error_str); return; } close(fd); #else void* shmptr = NULL; int size = 0; key_t share_key; char *path = shm_path; char error_str[200]; size = sizeof(SHM); size = size + 16; share_key = 0x1d5010; #if 0 snprintf( error_str, sizeof( error_str ), "MSG: sys_nic, shm, size:%d, key:0x%x(%d)\n", size, share_key, share_key); record_log(error_str); #endif global_share_id = shmget( share_key, size, IPC_CREAT|0666 ); if( global_share_id == -1 ) { snprintf( error_str, sizeof( error_str ), "EMERG: fail shmget, %s, 0x%x\n", strerror(errno), share_key); record_log(error_str); return; } shmptr = shmat( global_share_id, NULL, 0 ); if( shmptr == (void *)-1 ) { snprintf( error_str, sizeof( error_str ), "EMERG: fail shmat, %s, %s\n", strerror(errno), path); record_log(error_str); return; } //flag_str = (char *)shmptr+size-16; // if( strcmp( flag_str, "D5001" ) != 0 ) { //first, do init. memset( shmptr, 0, size ); // strcpy( flag_str, "D5001" ); // } global_shmptr = shmptr; // ref_count = (char *)shmptr+size-1; // (*ref_count)++; *ptr = (SHM *)shmptr; #endif } static void get_sem(int semid) { struct sembuf lock[2]; char error_str[200]; lock[0].sem_num = 0; lock[0].sem_op = -1; lock[0].sem_flg = SEM_UNDO; /*lock[1].sem_num = 0; lock[1].sem_op = 1; lock[1].sem_flg = SEM_UNDO;*/ while(semop(semid, lock, 1)){ if(errno == EINTR)continue; snprintf(error_str, sizeof(error_str), "EMERG: get_sem semop():%s\n", strerror(errno)); record_log(error_str); return; } } static void release_sem(int semid) { int ret; char error_str[200]; struct sembuf unlock; unlock.sem_num = 0; unlock.sem_op = 1; unlock.sem_flg = SEM_UNDO; if((ret = semop(semid, &unlock, 1)) == -1){ snprintf(error_str, sizeof(error_str), "EMERG: rel_sem semop():%s\n", strerror(errno)); record_log(error_str); return; } } static void proc_get_name(NET_NAME_ST *nodep) { char linebuf[LINE_SIZE]; char error_str[200]; char *retp = NULL; int err_val=0; NET_NAME_ST *node = NULL; FILE *dev_fp; if((dev_fp = fopen("/proc/net/dev", "rb")) == NULL){ snprintf(error_str, sizeof(error_str), "EMERG: Can't open dev file:%s\n", strerror(errno)); record_log(error_str); return; } memset(linebuf, 0, sizeof(linebuf)); fgets(linebuf, sizeof(linebuf), dev_fp); fgets(linebuf, sizeof(linebuf), dev_fp); while((retp = fgets(linebuf, sizeof(linebuf), dev_fp)) != NULL){ if((node = (NET_NAME_ST *)malloc(sizeof(NET_NAME_ST))) == NULL){ err_val = 1; break; } memset(node->name, 0, NIC_NAME_LEN); get_name(node->name, retp); node->next = nodep->next; nodep->next = node; } if(err_val){ NET_NAME_ST *curr = nodep->next; while(curr != NULL){ node = curr->next; free(curr); curr = node; } } fclose(dev_fp); } static void ioctl_get_name(NET_NAME_ST *nodep) { int count = 0; int inuse = 0; int err_val = 0; NETCARD_INFO net_name[MAXNICNUM]; NET_NAME_ST *node = NULL, *curr = NULL; memset(net_name, 0, sizeof(net_name)); if((count = ioc_get_name(net_name)) == 0)return; if(nodep->next == NULL) inuse = 1; while(count > 0){ curr = nodep->next; while(curr != NULL){ if(!strncmp(net_name[count - 1].charname, curr->name, NIC_NAME_LEN)){ inuse = 0; break; } inuse = 1; curr = curr->next; } if(inuse){ if((node = (NET_NAME_ST *)malloc(sizeof(NET_NAME_ST))) == NULL){ err_val = 1; break; } memset(node->name, 0, NIC_NAME_LEN); strncpy(node->name, net_name[count - 1].charname, NIC_NAME_LEN); node->next = nodep->next; nodep->next = node; } count--; } if(err_val){ curr = nodep->next; while(curr != NULL){ node = curr->next; free(curr); curr = node; } } } static void get_all_name(NET_NAME_ST *nodep) { proc_get_name(nodep); ioctl_get_name(nodep); } static void create_monit_list(NET_NAME_ST *nodep, NETCARD_INFO_ST *info_list, char *bond) { int err_val = 0; NETCARD_INFO_ST *info_node = NULL; NET_NAME_ST *curr, *node; curr = nodep->next; while(curr != NULL){ if((info_node = (NETCARD_INFO_ST *)malloc(sizeof(NETCARD_INFO_ST))) == NULL){ err_val = 1; break; } memset(info_node, 0, sizeof(NETCARD_INFO_ST)); strncpy(info_node->info.charname, curr->name, NIC_NAME_LEN); strncpy(info_node->info.descr, bond, strlen(bond)); info_node->next = info_list->next; info_list->next = info_node; curr = curr->next; } if(err_val){ NETCARD_INFO_ST *info_curr = info_list->next; while(info_curr != NULL){ info_node = info_curr->next; free(info_curr); info_curr = info_node; } curr = nodep->next; while(curr != NULL){ node = curr->next; free(curr); curr = node; } } } static int get_inc_info(NETCARD_INFO *net) { return if_fetch(net); } static void get_inc_stats(NETCARD_INFO *net) { char linebuf[LINE_SIZE]; char *retp = NULL; char *str = NULL; FILE *dev_fp; if((dev_fp = fopen("/proc/net/dev", "r")) == NULL)return; memset(linebuf, 0, sizeof(linebuf)); while((retp = fgets(linebuf, sizeof(linebuf), dev_fp)) != NULL){ if((str = strstr(linebuf, net->charname)) != NULL){ str=strstr(str,":"); str+=1; get_dev_fields(str, net); break; } } fclose(dev_fp); } static void send_inc_info_one(NETCARD_INFO *net, int semid, SHM *ptr) { int i; for(i = 0; ptr->info[i].charname[0] != 0; i++){ if(!strncmp(ptr->info[i].charname, net->charname, NIC_NAME_LEN)){ get_sem(semid); memcpy(&ptr->info[i], net, sizeof(NETCARD_INFO)); release_sem(semid); } } } static void *send_inc_info(void *p) { int i = 0; int flags = 1; char error_str[200]; unsigned long long bytes[MAXNICNUM]; THMEM *ptr = (THMEM *)p; NETCARD_INFO_ST *curr; struct timespec s_time, os_time; if((curr = ptr->listp->next) == NULL){ pthread_mutex_lock(&mut); snprintf(error_str, sizeof(error_str), "EMERG: Empty Netcard list!\n"); record_log(error_str); pthread_mutex_unlock(&mut); return NULL; } s_time.tv_sec = ptr->conf->write_interval; s_time.tv_nsec = 0; /* copy all net_info*/ while(1){ i = 0; get_sem(ptr->semid); //memset(ptr->shm_ptr, 0, sizeof(SHM)); curr = ptr->listp->next; while(curr != NULL){ get_inc_info(&curr->info); if(curr->status == NIC_UNLINKABLE){ curr->info.flags &= (~IFF_UP); curr->info.flags &= (~IFF_RUNNING); } get_inc_stats(&curr->info); if(flags){ bytes[i] = curr->info.rx_bytes + curr->info.tx_bytes; } curr->info.average_flow =(unsigned long long)((curr->info.rx_bytes + curr->info.tx_bytes - bytes[i])/(ptr->conf->write_interval)); memcpy(&ptr->shm_ptr->info[i], &curr->info, sizeof(NETCARD_INFO)); bytes[i] = curr->info.rx_bytes + curr->info.tx_bytes; i++; curr = curr->next; } release_sem(ptr->semid); flags = 0; nanosleep(&s_time, &os_time); } } static int get_netcard_count(char *name) { int count = 0; FILE *fp = NULL; char path[64] = "/proc/net/bonding/"; char buf[LINE_SIZE]; char *retp = NULL; char *str = NULL; strncat(path, name, strlen(name)); if((fp = fopen(path, "r")) == NULL)return 1; memset(buf, 0, sizeof(buf)); fseek(fp, 65, SEEK_SET); while((retp = fgets(buf, sizeof(buf), fp)) != NULL){ if((str = strstr(buf, "active-backup")) != NULL){ fclose(fp); return 1; } if(!strncmp(buf, "Slave Interface:", 16))count++; } fclose(fp); return count; } static void *cacu_flow(void *p) { int i = 0, count_t = 1; int summit = 0; int flags = 1; int count_ok[MAXNICNUM]; int count_no[MAXNICNUM]; unsigned long long rx_flow = 0; unsigned long long tx_flow = 0; char error_str[2048]; // tx_bytes tx_bytes unsigned long long rx_bytes[MAXNICNUM]; unsigned long long tx_bytes[MAXNICNUM]; THFLOW *ptr = (THFLOW *)p; NETCARD_INFO_ST *curr; struct timespec s_time, os_time; if((curr = ptr->mem.listp->next) == NULL){ pthread_mutex_lock(&mut); snprintf(error_str, sizeof(error_str), "EMERG: Empty Netcard list!\n"); record_log(error_str); pthread_mutex_unlock(&mut); return NULL; } s_time.tv_sec = ptr->mem.conf->flow_interval; s_time.tv_nsec = 0; for(i = 0; i < MAXNICNUM ; i++){ count_ok[i] = 0; count_no[i] = 0; } while(1){ i = 0; curr = ptr->mem.listp->next; while(curr != NULL){ get_inc_info(&curr->info); get_inc_stats(&curr->info); if(flags){ rx_bytes[i] = curr->info.rx_bytes; tx_bytes[i] = curr->info.tx_bytes; } //tx_flow,rx_flow, rx_flow=(curr->info.rx_bytes -rx_bytes[i])/ptr->mem.conf->flow_interval; tx_flow=(curr->info.tx_bytes -tx_bytes[i])/ptr->mem.conf->flow_interval; if(!strncmp(curr->info.charname, "bond", 4)){ count_t = get_netcard_count(curr->info.charname); }else { count_t = 1; } summit = (tx_flow > rx_flow ? tx_flow :rx_flow)*8*100/1024/1024/(ptr->mem.conf->flow_peak)/count_t; if( sys_nic_debug ) { #if 1 printf("%s:\tcount=%d\tsummit=%d\tflow_limit:%d\taverage_flow:%lld\trx_flow:%lld\ttx_flow:%lld\n", curr->info.charname, count_t, summit, conf.flow_limit, curr->info.average_flow,rx_flow,tx_flow); #endif snprintf(error_str, sizeof(error_str), "%s:\tcount=%d\tsummit=%d\tflow_limit:%d\tcurr->info.rx_bytes:%lld\tcurr->info.tx_bytes:%lld\tflow_interval:%d\n", curr->info.charname, count_t, summit, conf.flow_limit,curr->info.rx_bytes,curr->info.tx_bytes,ptr->mem.conf->flow_interval); record_log(error_str); } if(summit >= ptr->mem.conf->flow_limit){ memset(ptr->env.Malarm.tSysNetcardAlarm.fault_devname, 0, NIC_NAME_LEN); strncpy(ptr->env.Malarm.tSysNetcardAlarm.fault_devname, ptr->env.host_name, ptr->env.host_name_size); strncat(ptr->env.Malarm.tSysNetcardAlarm.fault_devname, "-", 1); strncat(ptr->env.Malarm.tSysNetcardAlarm.fault_devname, curr->info.charname, (NIC_NAME_LEN - ptr->env.host_name_size - 1)); ptr->env.Malarm.tSysNetcardAlarm.flags = NETCARD_ALARM_ABNORMAL; ptr->env.Malarm.tSysNetcardAlarm.retrytimes = 0; ptr->env.Malarm.tMsgFrame.len = sizeof(ptr->env.Malarm); ptr->env.Malarm.tMsgFrame.seqno = seqno; pthread_mutex_lock(&mut); while(count_no[i] > 0){ send_alarm(&ptr->env.Malarm, ptr->mem.conf->udpport, ptr->mem.conf->ip); seqno++; ptr->env.Malarm.tMsgFrame.seqno = seqno; ptr->env.Malarm.tSysNetcardAlarm.retrytimes++; count_no[i]--; if(count_no[i] == 0){ send_inc_info_one(&curr->info, ptr->mem.semid, ptr->mem.shm_ptr); if( sys_nic_debug ) { snprintf(error_str, sizeof(error_str), "NOTICE: %s flow is abnormal, summit is %d, average flow is %lld , rx_flow is %lld , tx_flow is %lld !\n", curr->info.charname, summit, curr->info.average_flow,rx_flow,tx_flow); } else { snprintf(error_str, sizeof(error_str), "NOTICE: %s flow is abnormal !\n", curr->info.charname); } record_log(error_str); } } pthread_mutex_unlock(&mut); count_ok[i] = 3; }else{ memset(ptr->env.Malarm.tSysNetcardAlarm.fault_devname, 0, NIC_NAME_LEN); strncpy(ptr->env.Malarm.tSysNetcardAlarm.fault_devname, ptr->env.host_name, ptr->env.host_name_size); strncat(ptr->env.Malarm.tSysNetcardAlarm.fault_devname, "-", 1); strncat(ptr->env.Malarm.tSysNetcardAlarm.fault_devname, curr->info.charname, (NIC_NAME_LEN - ptr->env.host_name_size - 1)); ptr->env.Malarm.tSysNetcardAlarm.flags = NETCARD_ALARM_NORMAL; ptr->env.Malarm.tSysNetcardAlarm.retrytimes = 0; ptr->env.Malarm.tMsgFrame.len = sizeof(ptr->env.Malarm); ptr->env.Malarm.tMsgFrame.seqno = seqno; pthread_mutex_lock(&mut); while(count_ok[i] > 0){ send_alarm(&ptr->env.Malarm, ptr->mem.conf->udpport, ptr->mem.conf->ip); seqno++; ptr->env.Malarm.tMsgFrame.seqno = seqno; ptr->env.Malarm.tSysNetcardAlarm.retrytimes++; count_ok[i]--; if(count_ok[i] == 0){ send_inc_info_one(&curr->info, ptr->mem.semid, ptr->mem.shm_ptr); snprintf(error_str, sizeof(error_str), "NOTICE: %s flow is normal now !\n", curr->info.charname); record_log(error_str); } } pthread_mutex_unlock(&mut); count_no[i] = 3; }/* end if(summit... */ rx_bytes[i] = curr->info.rx_bytes; tx_bytes[i] = curr->info.tx_bytes; i++; curr = curr->next; }/* end while(curr...) */ flags = 0; nanosleep(&s_time, &os_time); }/* end while(1) */ } static char *parse_str(char **s) { char *retp = NULL; char *p = *s; while(isspace(*p))p++; retp = p; while(!isspace(*p))p++; *p = '\0'; return retp; } int ping_gw(char *devname) { FILE *fp; int i, j, k; char buf[128]; char getbuf[64]; i = find_nic_config(devname); if( i == -1 ) return 0; if(conf.nic[i].gw_num == 0) return 0; for(k=0; kbond_file_path, "r")) == NULL){ snprintf(error_str, sizeof(error_str), "EMERG: fopen():%s\n", strerror(errno)); record_log(error_str); free(ptr); return NULL; } fseek(fp, 65, SEEK_SET); memset(name, 0, sizeof(name)); memset(linebuf, 0, sizeof(linebuf)); if((retp = fgets(linebuf, sizeof(linebuf), fp)) != NULL){ if((retp = strstr(linebuf, "active-backup")) == NULL){ free(ptr); fclose(fp); return NULL; } } s_time.tv_sec = 0; s_time.tv_nsec = 100000000; while(1){ while((str = fgets(linebuf, sizeof(linebuf), fp)) != NULL){ if(!strncmp(linebuf, "Currently Active Slave:", 23)){ str += 23; retp = parse_str(&str); break; } } if(name[0] == 0){ strncpy(name, retp, strlen(retp)); }else if(strncmp(name, retp, strlen(retp)) != 0){ memset(arg->Malarm.tSysNetcardAlarm.switch_devname, 0, NIC_NAME_LEN); strncpy(arg->Malarm.tSysNetcardAlarm.switch_devname, arg->host_name, arg->host_name_size); strncat(arg->Malarm.tSysNetcardAlarm.switch_devname, "-", 1); strncat(arg->Malarm.tSysNetcardAlarm.switch_devname, retp, (NIC_NAME_LEN - arg->host_name_size - 1)); arg->Malarm.tSysNetcardAlarm.flags = NETCARD_ALARM_SWITCH; arg->Malarm.tSysNetcardAlarm.retrytimes = 0; arg->Malarm.tMsgFrame.len = sizeof(arg->Malarm); arg->Malarm.tMsgFrame.seqno = seqno; count = 3; pthread_mutex_lock(&mut); snprintf(error_str, sizeof(error_str), "NOTICE: Net card checking to %s!\n", retp); record_log(error_str); while(count > 0){ send_alarm(&arg->Malarm, arg->conf->udpport, arg->conf->ip); seqno++; arg->Malarm.tMsgFrame.seqno = seqno; arg->Malarm.tSysNetcardAlarm.retrytimes++; count--; } pthread_mutex_unlock(&mut); memset(name, 0, NIC_NAME_LEN); strncpy(name, retp, strlen(retp)); } fclose(fp); nanosleep(&s_time, &os_time); if((fp = fopen(arg->bond_file_path, "r")) == NULL){ free(ptr); return NULL; } fseek(fp, 65, SEEK_SET); } free(ptr); fclose(fp); return NULL; } static void *create_logfile(void *ptr) { char buf[128]; char del_file[DAYS][1024]; char *s; int head, tail, fd; int flag = 0, del_flag = 0; int old_mon = 0; int old_day = 0; time_t tamp; struct tm tmptr; struct timespec s_time, os_time; s_time.tv_sec = 1; s_time.tv_nsec = 0; head = tail = 0; while(1){ tamp = time(NULL); localtime_r(&tamp, &tmptr); if(old_mon != (tmptr.tm_mon + 1))flag = 1; else if(old_day != tmptr.tm_mday)flag = 1; else flag = 0; if(flag){ LOGPATH_LOCK; s = strrchr(log_path, '/'); s++; *s = '\0'; memset(buf, 0, sizeof(buf)); strftime(buf, sizeof(buf), "%Y%m%d_", &tmptr); strcat(buf, process_name); strcat(buf, ".log"); strcat(log_path, buf); mode_t mask_tmp; mask_tmp = umask(0000); if((fd = open(log_path, O_RDWR|O_CREAT, 0666)) != -1){ log_flag = 0; close(fd); } umask(mask_tmp); strcpy(del_file[head++], log_path); LOGPATH_UNLOCK; old_mon = tmptr.tm_mon+1; old_day = tmptr.tm_mday; // strcpy(del_file[head++], log_path); if(head == DAYS){ head = 0; del_flag = 1; } if(del_flag){ unlink(del_file[tail]); tail++; if(tail == DAYS)tail = 0; } } nanosleep(&s_time, &os_time); } } void write_time(int semid, SHM *ptr) { int i = 0; int flag_time_stamp; flag_time_stamp = time(NULL); while(ptr->info[i].charname[0] != 0){ ptr->info[i].time_stamp = flag_time_stamp; i++; } } #if 0 char *parse(char *line) { char *begin = NULL; char *end = NULL; if((begin = strchr(line, '/')) != NULL){ if((end = strstr(line, "bin")) != NULL){ *end='\0'; return begin; } } return NULL; } #endif void release_name_list(NET_NAME_ST *head) { NET_NAME_ST *curr, *save; curr = head->next; while(curr != NULL){ save = curr->next; free(curr); curr = save; } } int get_netcard(char *line, char *nic) { char *begin, *retp; while(isspace(*line))line++; begin = line; while(!isspace(*line))line++; *line++ = '\0'; if(!strncmp(begin, "nic", 4)){ if((retp = parse_str(&line)) != NULL){ strncpy(nic, retp, MAXNICNUM); return 1; } } return 0; } void sig_handler(int sig) { // char err_str[200]; #if 0 if(unlink(SHM_PATH) == -1){ snprintf(err_str, sizeof(err_str), "NOTICE: error delete %s\n", strerror(errno)); record_log(err_str); } if(unlink(SEM_PATH) == -1){ snprintf(err_str, sizeof(err_str), "NOTICE: error delete %s\n", strerror(errno)); record_log(err_str); } #endif // semctl(sem_id, 0, IPC_RMID); // snprintf(err_str, sizeof(err_str), "NOTICE: process exit by signal %d\n", sig); // record_log(err_str); semctl(semid,0,IPC_RMID,0); shmctl(global_share_id,IPC_RMID,NULL); shmctl(dir_share_id,IPC_RMID,NULL); exit(0); } /* * 查看数据结构中是否有给定的网卡 * 输入:网卡名称 * 返回值:-1 表示没有 * 非0值表示设备列表中的索引 * */ int find_nic_config(char *dev_name){ int i, index=-1; for(i=0; iname, myconf[13]) == 0) && (nicnum <= MAXNICNUM)){ i = 1; if(cmd->data.list[0] && cmd->data.list[1]){ //查找设备列表中是否已有该网卡 //如果没有则创建一项 //如果已有则只要增加ping的地址和地址数量 //一般都能找到,因为配置文件中一般总是先定义"nic",后定义"ping" //如果没找到,则表明先定义了"ping",未定义"nic"或后定义"nic",而未定义"nic"应该是错误的 index = find_nic_config(cmd->data.list[0]); if(index == -1){ strncpy(conf.nic[nicnum].dev_name, cmd->data.list[0], strlen(cmd->data.list[0]) >= IPLEN ? IPLEN-1 : strlen(cmd->data.list[0])); card_info_index = nicnum; nicnum++; } else card_info_index = index; while(cmd->data.list[i]){ if((int)(inet_addr(cmd->data.list[i])) == -1){ sprintf(wrong_ip,"The wrong IP address:'%s'",cmd->data.list[i]); strcat(wrong_ip,"\n"); record_log(wrong_ip); } else{ strncpy(conf.nic[card_info_index].ping_ip[conf.nic[card_info_index].gw_num++], cmd->data.list[i], strlen(cmd->data.list[i]) >= IPLEN ? IPLEN-1 : strlen(cmd->data.list[i])); } i++; } } } //"nic"选项的处理 if((strcmp(cmd ->name, myconf[12]) == 0) && (nicnum <= MAXNICNUM)){ //设备列表中没有给定的网卡设备,则添加一项 //否则不必添加 //对应配置文件中先指定"ping"后指定"nic"的情况 index = find_nic_config(cmd->data.str); if(index == -1){ strncpy(conf.nic[nicnum].dev_name, cmd->data.str, strlen(cmd->data.str) >= NIC_NAME_LEN ? NIC_NAME_LEN-1 : strlen(cmd->data.str)); nicnum++; } } if((strcmp(cmd ->name, myconf[11]) == 0)){ strncpy(conf.udp, cmd->data.str, strlen(cmd->data.str)); } return NULL; } DOTCONF_CB(cb_int) { if(strcmp(cmd ->name, myconf[0]) == 0){ conf.domain = cmd->data.value; } if(strcmp(cmd ->name, myconf[1]) == 0){ conf.serv = cmd->data.value; } if(strcmp(cmd ->name, myconf[2]) == 0){ conf.event = cmd->data.value; } if(strcmp(cmd ->name, myconf[3]) == 0){ conf.udpport = cmd->data.value; } if(strcmp(cmd ->name, myconf[6]) == 0){ conf.monitor_interval = cmd->data.value; } if(strcmp(cmd ->name, myconf[7]) == 0){ conf.write_interval = cmd->data.value; } if(strcmp(cmd ->name, myconf[8]) == 0){ conf.flow_interval = cmd->data.value; } if(strcmp(cmd ->name, myconf[9]) == 0){ conf.flow_limit = cmd->data.value; } if(strcmp(cmd ->name, myconf[10]) == 0){ conf.flow_peak = cmd->data.value; } if(strcmp(cmd ->name, myconf[14]) == 0){ conf.pingnum = cmd->data.value; } if(strcmp(cmd ->name, myconf[15]) == 0){ conf.pinglap = cmd->data.value; } if(strcmp(cmd ->name, myconf[16]) == 0){ conf.crazyping = cmd->data.value; } return NULL; } DOTCONF_CB(cb_list) { return NULL; } int get_conf() { // int uid; // char buf[1024]; // int i; // struct passwd *user; configfile_t *configfile; char tmp_str[256]; // memset(buf, 0, sizeof(buf)); // uid=getuid(); // user = getpwnam("d5000"); // user = getpwuid(uid); // sprintf(buf,"%s", user->pw_dir); // strcat(buf,conf_path); configfile = dotconf_create(conf_path, options, NULL, CASE_INSENSITIVE); if (!configfile) { sprintf(tmp_str,"%s","Warning can't reading config file\n"); record_log(tmp_str); return -1; } if (dotconf_command_loop(configfile) == 0){ sprintf(tmp_str,"%s","Warning can't reading config file\n"); record_log(tmp_str); return -1; } dotconf_cleanup(configfile); if(conf.domain == 0) conf.domain = 10; if(conf.serv == 0) conf.serv = 1; if(conf.event == 0) conf.event = 2; if(conf.udpport == 0) conf.udpport = 15000; if(conf.monitor_interval == 0) conf.monitor_interval = 100; if(conf.monitor_interval >= 1000){ sprintf(tmp_str,"%s","Error monitor_interval must less than 1000\n"); record_log(tmp_str); return -2; } if(conf.write_interval == 0) conf.write_interval = 300; if(conf.flow_interval == 0) conf.flow_interval = 60; if(conf.flow_limit == 0) conf.flow_limit = 30; if(conf.flow_peak == 0) conf.flow_peak = 1000; if(conf.udp[0] == 0) strcpy(conf.udp, "bond0"); if(conf.nic[0].dev_name[0] == 0) strcpy(conf.nic[0].dev_name, "bond0"); if(conf.pingnum == 0) conf.pingnum = 2; if(conf.pinglap == 0) conf.pinglap = 1; return 0; } int isrun(char *p) { char buf[16]; char cmdbuf[1024]; FILE *fp; memset(buf, 0, sizeof(buf)); memset(cmdbuf, 0, sizeof(cmdbuf)); snprintf(cmdbuf, sizeof(cmdbuf), "pidof %s", p); fp=popen(cmdbuf, "r"); fread(buf, sizeof(char), sizeof(buf), fp); pclose(fp); if(strchr(buf, ' ') != NULL) return 1; else return 0; } int get_broad_ip(void) { char ip_p[4][4]; char error_str[200]; int skfd; struct ifreq ifr; memset(&ifr, 0, sizeof(ifr)); memset(ip_p, 0, sizeof(ip_p)); if((skfd = socket(PF_INET, SOCK_DGRAM, 0)) == -1)return -1; strcpy(ifr.ifr_name, conf.udp); if (!ioctl(skfd, SIOCGIFBRDADDR, &ifr)){ sprintf(ip_p[0], "%d", (unsigned char)ifr.ifr_broadaddr.sa_data[2]); sprintf(ip_p[1], "%d", (unsigned char)ifr.ifr_broadaddr.sa_data[3]); sprintf(ip_p[2], "%d", (unsigned char)ifr.ifr_broadaddr.sa_data[4]); sprintf(ip_p[3], "%d", (unsigned char)ifr.ifr_broadaddr.sa_data[5]); }else{ snprintf(error_str, sizeof(error_str), "EMERG: Invalid broadcast device -- %s\n", conf.udp); record_log(error_str); close(skfd); return -1; } close(skfd); strcat(conf.ip, ip_p[0]); strcat(conf.ip, "."); strcat(conf.ip, ip_p[1]); strcat(conf.ip, "."); strcat(conf.ip, ip_p[2]); strcat(conf.ip, "."); strcat(conf.ip, ip_p[3]); return 0; } void create_semdir() { #if 0 int ret = 0; mode_t mask_tmp; mask_tmp = umask(0000); create_dir(sem_path); if((ret = open(sem_path, O_RDWR | O_CREAT, 0666)) != -1){ close(ret); } umask(mask_tmp); #endif } void create_shmdir() { #if 0 int ret = 0; mode_t mask_tmp; mask_tmp = umask(0000); create_dir(shm_path); if((ret = open(shm_path, O_RDWR | O_CREAT, 0666)) != -1){ close(ret); } umask(mask_tmp); #endif } void create_confdir() { int ret = 0; mode_t mask_tmp; mask_tmp = umask(0000); create_dir(conf_path); if((ret = open(conf_path, O_RDWR | O_CREAT, 0666)) != -1){ close(ret); } umask(mask_tmp); } void create_logdir() { int len = 0; mode_t mask_tmp; mask_tmp = umask(0000); len = strlen(log_path); if(log_path[len-1]!='/') strcat(log_path, "/"); create_dir(log_path); umask(mask_tmp); } /* create netcard name list */ int create_name_list(NET_NAME_ST *all_name_list, NET_NAME_ST *opt_name_list) { int i, count_t, err_val = 0; NET_NAME_ST *curr, *node; char error_str[200]; for(i = 0, count_t = 0; conf.nic[i].dev_name[0] != 0 && (i < MAXNICNUM); i++){ curr = all_name_list->next; while(curr != NULL){ if(!strncmp(curr->name, conf.nic[i].dev_name, NIC_NAME_LEN)){ if((node = (NET_NAME_ST *)malloc(sizeof(NET_NAME_ST))) == NULL){ err_val = 1; break; } memset(node->name, 0, NIC_NAME_LEN); strncpy(node->name, conf.nic[i].dev_name, NIC_NAME_LEN); node->next = opt_name_list->next; opt_name_list->next = node; count_t ++; break; } curr = curr->next; } if(err_val)break; } if(count_t != i || err_val){ for(curr = opt_name_list->next; curr != NULL; curr = curr->next)free(curr); snprintf(error_str, sizeof(error_str), "EMERG: Invalid netcard name --\n"); record_log(error_str); return -1; } err_val = 0; return 0; } int get_netcard_status(NETCARD_INFO_ST *listp) { if((listp->info.flags & IFF_UP) != IFF_UP) return NIC_DOWN; if((listp->info.flags & IFF_RUNNING) != IFF_RUNNING) return NIC_UNRUNNING; //20100510 if(conf.crazyping || (elapsed_ping_time == total_ping_time)){ if(ping_gw(listp->info.charname) != 0) return NIC_UNLINKABLE; } else{ if(listp->status == NIC_UNLINKABLE) return NIC_UNLINKABLE; } return NIC_NORMAL; } int do_alarm(NETCARD_INFO_ST *listp, int nic_status, D5000_NIC_ALARM *Malarm) { int i; char error_str[200]; memset(Malarm->tSysNetcardAlarm.fault_devname, 0, NIC_NAME_LEN); strncpy(Malarm->tSysNetcardAlarm.fault_devname, host_name, host_name_size); strncat(Malarm->tSysNetcardAlarm.fault_devname, "-", 1); strncat(Malarm->tSysNetcardAlarm.fault_devname, listp->info.charname, NIC_NAME_LEN - host_name_size - 1); Malarm->tSysNetcardAlarm.retrytimes = 0; Malarm->tMsgFrame.len = sizeof(Malarm); Malarm->tMsgFrame.seqno = seqno; switch(nic_status){ case NIC_DOWN: Malarm->tSysNetcardAlarm.flags = NETCARD_ALARM_FAULT; snprintf(error_str, sizeof(error_str), "NOTICE: %s is DOWN!\n", listp->info.charname); break; case NIC_UNRUNNING: Malarm->tSysNetcardAlarm.flags = NETCARD_ALARM_FAULT; snprintf(error_str, sizeof(error_str), "NOTICE: %s is UP but UNRUNNING!\n", listp->info.charname); break; case NIC_UNLINKABLE: Malarm->tSysNetcardAlarm.flags = NETCARD_ALARM_FAULT; listp->info.flags &= (~IFF_UP); listp->info.flags &= (~IFF_RUNNING); snprintf(error_str, sizeof(error_str), "NOTICE: %s is RUNNING but UNLINKABLE!\n", listp->info.charname); break; case NIC_NORMAL: Malarm->tSysNetcardAlarm.flags = NETCARD_ALARM_RESUME; snprintf(error_str, sizeof(error_str), "NOTICE: %s is NORMAL!\n", listp->info.charname); break; } pthread_mutex_lock(&mut); for(i = 0; i < 3; i++){ send_alarm(Malarm, conf.udpport, conf.ip); seqno++; Malarm->tMsgFrame.seqno = seqno; Malarm->tSysNetcardAlarm.retrytimes++; } send_inc_info_one(&listp->info, semid, shm_ptr); pthread_mutex_unlock(&mut); record_log(error_str); return 0; } int main(int argc, char ** argv) { int id = -1; if((id = semget(0x1d5200, 1, 0666)) != -1) semctl(id,0,IPC_RMID,0); id = -1; if((id = shmget(0x1d5010,sizeof(SHM) + 16 , 0666)) != -1) shmctl(id,IPC_RMID,0); id = -1; if((id = shmget(0x1d6010, 128, 0666)) != -1) shmctl(id,IPC_RMID,0); int ret = 0, proc_stat = 0; unsigned int i = 0; int nic_status; int sys_time_stamp = 0; char *retp = NULL; char *str = NULL; char bond[128]; char error_str[200]; char linebuf[LINE_SIZE]; THENV *arg; glob_t res; FILE *bond_fp = NULL; pthread_t tid[THRNR]; pthread_t tid_mem; pthread_t tid_flow; pthread_t tid_time; THMEM mem; THFLOW flow; struct timespec s_time, os_time, log_time; NET_NAME_ST all_name_list, opt_name_list; NETCARD_INFO_ST inc_info_list, *listp = NULL; D5000_NIC_ALARM Malarm; struct sigaction sig; struct passwd *user; //#define TESTINTERVAL #ifndef TESTINTERVAL proc_invocation prcm; #endif char log_record[125]={0}; char *dir_memory; int shm_key =0x1d6010; if( getenv("SYS_NIC_DEBUG") ) { sys_nic_debug = 1; } //process register #ifndef TESTINTERVAL if((proc_stat=prcm.proc_init("sys","base_srv","sys_nicmonitor"))==-1){ perror("proc_init()"); exit(-1); } #endif memset(&conf, 0, sizeof(CONFIG_FILE_ST)); if(isrun(argv[0]) == 1){ printf("the program is already started!\n"); exit(0); } sig.sa_handler = sig_handler; sigemptyset(&sig.sa_mask); sigaddset(&sig.sa_mask, SIGINT); sigaddset(&sig.sa_mask, SIGTERM); sig.sa_flags = 0; sigaction(SIGTERM, &sig, NULL); sigaction(SIGINT, &sig, NULL); sigaction(SIGSEGV, &sig, NULL); /* create dir file path */ if((user = getpwnam("d5000")) != NULL){ sprintf(log_path,"%s",user->pw_dir); sprintf(shm_path,"%s",user->pw_dir); sprintf(sem_path,"%s",user->pw_dir); sprintf(conf_path,"%s",user->pw_dir); } dir_share_id = shmget(shm_key,128,IPC_CREAT|0666); if(dir_share_id == -1) return -1; dir_memory = (char *) shmat(dir_share_id,NULL,0); if(dir_memory == (void *) -1) return -1; strcpy(dir_memory,user->pw_dir); strcat(log_path,LOG_PATH); strcat(shm_path,SHM_PATH); strcat(sem_path,SEM_PATH); strcat(conf_path,CONF_FILE); create_semdir(); create_shmdir(); create_logdir(); create_confdir(); /* get process name */ memset(process_name, 0, sizeof(process_name)); if((retp = strrchr(argv[0], '/')) != NULL){ retp++; strcpy(process_name, retp); }else{ strcpy(process_name, argv[0]); } /*create logfile thread */ pthread_create(&tid_time, NULL, create_logfile, NULL); /* initialize some....*/ memset(&all_name_list, 0, sizeof(NET_NAME_ST)); all_name_list.next = NULL; memset(&opt_name_list, 0, sizeof(NET_NAME_ST)); opt_name_list.next = NULL; memset(&inc_info_list, 0, sizeof(NETCARD_INFO_ST)); inc_info_list.next = NULL; /* get all netcard by proc/net/dev and ioctl */ get_all_name(&all_name_list); /* wait for create log thread */ log_time.tv_sec = 0; log_time.tv_nsec = 1000000; while(log_flag)nanosleep(&log_time, NULL); if(get_conf()==-2){ printf("Error monitor_interval must less than 1000\n"); return -1; } else{ snprintf(error_str, sizeof(error_str), "NOTICE: %s V%s is started !\n", process_name, MNIC_VERSION); record_log(error_str); } /* sure the process is started */ if(shm_path){ printf("shm_path:%s\n",shm_path); sprintf(log_record,"shm_path:%s\n",shm_path); record_log(log_record); } if(log_path){ printf("log_path:%s\n",log_path); sprintf(log_record,"log_path:%s\n",log_path); record_log(log_record); } if(conf.udp){ printf("udp %s\n",conf.udp); sprintf(log_record,"udp %s\n",conf.udp); record_log(log_record); } for(i=0;conf.nic[i].dev_name[0]!=0;i++){ printf("nic %s\n",conf.nic[i].dev_name); sprintf(log_record,"nic %s\n",conf.nic[i].dev_name); record_log(log_record); } /* get broadcast address*/ if((ret = get_broad_ip()) != 0) return -1; if((ret = create_name_list(&all_name_list, &opt_name_list)) != 0) return -1; /* get hostname */ if((ret = gethostname(host_name, sizeof(host_name))) != -1){ host_name_size = strlen(host_name); }else host_name_size = HOST_NAME_SIZE; /* initialize Malarm */ Malarm.tMsgFrame.serv = conf.serv; Malarm.tMsgFrame.event = conf.event; Malarm.tMsgFrame.domain = conf.domain; /* get bonding file */ memset(bond, 0, sizeof(bond)); memset(linebuf, 0, sizeof(linebuf)); if((ret = glob(BOND_PATH, 0, NULL, &res)) != 0){ snprintf(error_str, sizeof(error_str), "NOTICE: No bonding netcard !\n"); record_log(error_str); strcpy(bond, "No bonding netcard!"); } for (i = 0; i < res.gl_pathc; ++i) { if((arg = (THENV *)malloc(sizeof(THENV))) != NULL){ memset(arg, 0, sizeof(THENV)); strncpy(arg->bond_file_path, res.gl_pathv[i], strlen(res.gl_pathv[i])); arg->Malarm = Malarm; strncpy(arg->host_name, host_name, host_name_size); arg->host_name_size = host_name_size; arg->conf = &conf; if(pthread_create(tid+i, NULL, check_inc_switch, (void*)arg)){ snprintf(error_str, sizeof(error_str), "EMERG: pthread_create(): %s\n", strerror(errno)); record_log(error_str); } } } for(i = 0; i < res.gl_pathc; ++i){ if((bond_fp = fopen(res.gl_pathv[i], "r")) == NULL){ snprintf(error_str, sizeof(error_str), "EMERG: fopen(): %s\n", strerror(errno)); record_log(error_str); }else{ retp = strrchr(res.gl_pathv[i], '/'); retp++; strcat(bond, retp); strcat(bond, ":"); while((str = fgets(linebuf, sizeof(linebuf), bond_fp)) != NULL){ if(!strncmp(linebuf, "Slave Interface:", 16)){ str += 16; retp = parse_str(&str); strcat(bond, retp); strcat(bond, " "); } } fclose(bond_fp); } } /* initialize time*/ s_time.tv_sec = 0; s_time.tv_nsec = conf.monitor_interval*1000*1000; /* initialize sem*/ init_sem(&semid, &conf); init_shm(&shm_ptr, &conf); /* for IPC_RMID */ sem_id = semid; /* create monitor netcard list */ create_monit_list(&opt_name_list, &inc_info_list, bond); release_name_list(&all_name_list); release_name_list(&opt_name_list); mem.semid = semid; mem.shm_ptr = shm_ptr; mem.listp = &inc_info_list; mem.conf = &conf; if(pthread_create(&tid_mem, NULL, send_inc_info, (void *)&mem)){ snprintf(error_str, sizeof(error_str), "EMERG: pthread_create(): %s\n", strerror(errno)); record_log(error_str); } /* create caculate flow thread*/ flow.env.Malarm = Malarm; strncpy(flow.env.host_name, host_name, host_name_size); flow.env.host_name_size = host_name_size; flow.mem.semid = semid; flow.mem.shm_ptr = shm_ptr; flow.mem.listp = &inc_info_list; flow.mem.conf = &conf; if(pthread_create(&tid_flow, NULL, cacu_flow, (void *)&flow)){ snprintf(error_str, sizeof(error_str), "EMERG: pthread_create(): %s\n", strerror(errno)); record_log(error_str); } total_ping_time = 1000 / conf.monitor_interval; if(total_ping_time == 0) total_ping_time = 1; //elapsed_ping_time = 1; elapsed_ping_time = total_ping_time; while(1){ i = 0; listp = inc_info_list.next; for(i = 0; listp != NULL; i++){ get_inc_info(&listp->info); get_inc_stats(&listp->info); nic_status = get_netcard_status(listp); if(nic_status != listp->status){ do_alarm(listp, nic_status, &Malarm); listp->status = nic_status; } listp = listp->next; } if(seqno > 32765)seqno = 0; nanosleep(&s_time, &os_time); //20100510 ++elapsed_ping_time; if(elapsed_ping_time > total_ping_time) elapsed_ping_time = 1; sys_time_stamp += conf.monitor_interval; if(sys_time_stamp >= 1000){ sys_time_stamp = 0; write_time(semid, shm_ptr); } } for (i = 0; i < res.gl_pathc; i++) { pthread_join(tid[i], NULL); } pthread_join(tid_mem, NULL); pthread_join(tid_flow, NULL); pthread_join(tid_time, NULL); pthread_mutex_destroy(&mut); globfree(&res); #ifdef USE_OLD_MMSHARE munmap(shm_ptr, sizeof(SHM)); #else { void *shmptr = shm_ptr; #if 0 snprintf(error_str, sizeof(error_str), "NOTICE: free shm %p, glo:%p\n", shmptr, global_shmptr); record_log(error_str); #endif if( shmptr == global_shmptr ) { char *ref_count = NULL; int is_last = 0; int size = sizeof(SHM); ref_count = (char *)shmptr + size + 16 - 1; is_last = *ref_count == 1?1:0; #if 0 snprintf(error_str, sizeof(error_str), "NOTICE: sys_nic, size:%d, ref_count: %d, last:%d\n", size, *ref_count, is_last); record_log(error_str); #endif // if( is_last ) { memset( shmptr, 0, size + 16 ); // } shmdt( shmptr ); // shmctl( global_share_id, IPC_RMID, NULL ); // if( is_last ) { // global_shmptr = NULL; // global_share_id = -1; // } } } #endif return 0; }