Files
Wei, Jing 01e8b507c6 [ issues #6 ] 华为5885V3型号服务器科东应用启动网卡监视程序失败问题
提交的变更:
	修改:     code/sys_nicmonitor/README
	修改:     code/sys_nicmonitor/mnic.c
	修改:     code/sys_nicmonitor/version.h

Signed-off-by: Wei, Jing <jwei@linx-info.com>
2021-12-13 11:23:52 +08:00

1837 lines
46 KiB
C
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
#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;
}