提交的变更: 修改: code/sys_nicmonitor/README 修改: code/sys_nicmonitor/mnic.c 修改: code/sys_nicmonitor/version.h Signed-off-by: Wei, Jing <jwei@linx-info.com>
1837 lines
46 KiB
C
1837 lines
46 KiB
C
#include "mnic.h"
|
||
#include "dotconf.h"
|
||
#include <unistd.h>
|
||
#include <arpa/inet.h>
|
||
#include <sys/stat.h>
|
||
#include <sys/ipc.h>
|
||
#include <sys/shm.h>
|
||
#include <pthread.h>
|
||
#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; k<conf.pingnum; ++k){
|
||
for(j=0; j<conf.nic[i].gw_num; ++j){
|
||
snprintf(buf,sizeof(buf),"ping -c 1 -w %d %s|grep received|awk -F, '{print $2}'|awk '{print $1}'", conf.pinglap,conf.nic[i].ping_ip[j]);
|
||
if((fp = popen(buf,"r")) == NULL)
|
||
{
|
||
//perror("popen");
|
||
//return 0;
|
||
continue;
|
||
}else{
|
||
fgets(getbuf,sizeof(getbuf),fp);
|
||
if(strncmp(getbuf,"0",1) != 0)
|
||
{
|
||
pclose(fp);
|
||
return 0;
|
||
}else{
|
||
pclose(fp);
|
||
//return -1;
|
||
continue;
|
||
}
|
||
}
|
||
pclose(fp);
|
||
return 0;
|
||
|
||
}
|
||
}
|
||
|
||
return -1;
|
||
}
|
||
|
||
static void *check_inc_switch(void *ptr)
|
||
{
|
||
THENV *arg = (THENV *)ptr;
|
||
FILE *fp = NULL;
|
||
char name[NIC_NAME_LEN];
|
||
struct timespec s_time, os_time;
|
||
int count = 0;
|
||
char linebuf[LINE_SIZE];
|
||
char error_str[200];
|
||
char *str = NULL;
|
||
char *retp = NULL;
|
||
|
||
if((fp = fopen(arg->bond_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; i<nicnum; ++i)
|
||
if(!strcmp(dev_name, conf.nic[i].dev_name))
|
||
index = i;
|
||
|
||
return index;
|
||
}
|
||
|
||
/*get_ping_server*/
|
||
DOTCONF_CB(cb_str)
|
||
{
|
||
int i, index, card_info_index;
|
||
char wrong_ip[125] = {0};
|
||
|
||
//"ping"选项的处理
|
||
if((strcmp(cmd ->name, 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;
|
||
}
|