From 96db6d647fcd71a00ac6a184d367d7c39baf2f10 Mon Sep 17 00:00:00 2001 From: jli Date: Tue, 13 Sep 2011 04:30:53 +0000 Subject: [PATCH] =?UTF-8?q?=E9=BE=99=E8=8A=AF?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit git-svn-id: http://172.17.0.253/svn/soft_pkgs/sys_nicmonitor@789 09c3743a-b0dd-45d3-b506-aa74c7a2a6ef --- branches/sys_nicmonitor-1.4-龙芯-32/Makefile | 28 + .../Makefile.config | 16 + branches/sys_nicmonitor-1.4-龙芯-32/const.h | 51 + branches/sys_nicmonitor-1.4-龙芯-32/dotconf.h | 264 +++ branches/sys_nicmonitor-1.4-龙芯-32/mnic.c | 1513 +++++++++++++++++ branches/sys_nicmonitor-1.4-龙芯-32/mnic.h | 44 + .../sys_nicmonitor-1.4-龙芯-32/nicinfo_shm.c | 209 +++ .../sys_nicmonitor-1.4-龙芯-32/nicinfo_shm.h | 52 + .../sys_nicmonitor-1.4-龙芯-32/proc_inv.h | 198 +++ .../sys_nicmonitor-1.4-龙芯-32/read_netcard.c | 133 ++ .../sys_nicmonitor-1.4-龙芯-32/send_alarm.c | 37 + .../sys_nicmonitor-1.4-龙芯-32/sys_netcard.h | 88 + .../sys_nicmonitor-1.4-龙芯-32/sys_nicmonitor | Bin 0 -> 47706 bytes 13 files changed, 2633 insertions(+) create mode 100644 branches/sys_nicmonitor-1.4-龙芯-32/Makefile create mode 100644 branches/sys_nicmonitor-1.4-龙芯-32/Makefile.config create mode 100644 branches/sys_nicmonitor-1.4-龙芯-32/const.h create mode 100644 branches/sys_nicmonitor-1.4-龙芯-32/dotconf.h create mode 100644 branches/sys_nicmonitor-1.4-龙芯-32/mnic.c create mode 100644 branches/sys_nicmonitor-1.4-龙芯-32/mnic.h create mode 100644 branches/sys_nicmonitor-1.4-龙芯-32/nicinfo_shm.c create mode 100644 branches/sys_nicmonitor-1.4-龙芯-32/nicinfo_shm.h create mode 100644 branches/sys_nicmonitor-1.4-龙芯-32/proc_inv.h create mode 100644 branches/sys_nicmonitor-1.4-龙芯-32/read_netcard.c create mode 100644 branches/sys_nicmonitor-1.4-龙芯-32/send_alarm.c create mode 100644 branches/sys_nicmonitor-1.4-龙芯-32/sys_netcard.h create mode 100644 branches/sys_nicmonitor-1.4-龙芯-32/sys_nicmonitor diff --git a/branches/sys_nicmonitor-1.4-龙芯-32/Makefile b/branches/sys_nicmonitor-1.4-龙芯-32/Makefile new file mode 100644 index 0000000..95ab1ad --- /dev/null +++ b/branches/sys_nicmonitor-1.4-龙芯-32/Makefile @@ -0,0 +1,28 @@ +#! /usr/bin/make -f + +DEFAULTS = Makefile.config + +include $(DEFAULTS) + +all:sys_nicmonitor libnic_shm.so + +CFLAGS += -Wall -Wformat=2 -Wno-format-extra-args -Wformat-security -Wformat-nonliteral #-g + +sys_nicmonitor:mnic.o read_netcard.o send_alarm.o + $(CC) -lman -ldotconf -lpthread -o $@ $^ +libnic_shm.so:nicinfo_shm.c + $(CC) -fpic -shared -o $@ $^ +clean: + $(RM) *.o + $(RM) libnic_shm.so sys_nicmonitor +install: + $(MKDIR) -p $(LIBDIR) + $(MKDIR) -p $(BINDIR) + $(MKDIR) -p $(INCDIR) + $(CP) libnic_shm.so $(LIBDIR) + $(CP) sys_nicmonitor $(BINDIR) + $(CP) nicinfo_shm.h $(INCDIR) +uninstall: + $(RM) -f $(LIBDIR)/libnic_shm.so + $(RM) -f $(BINDIR)/sys_nicmonitor + $(RM) -f $(INCDIR)/nicinfo_shm.h diff --git a/branches/sys_nicmonitor-1.4-龙芯-32/Makefile.config b/branches/sys_nicmonitor-1.4-龙芯-32/Makefile.config new file mode 100644 index 0000000..7a2d8e6 --- /dev/null +++ b/branches/sys_nicmonitor-1.4-龙芯-32/Makefile.config @@ -0,0 +1,16 @@ + +PREFIX = $(DESTDIR) + +BINDIR = $(PREFIX)/usr/bin + +LIBDIR = $(PREFIX)/usr/lib64 + +INCDIR = $(PREFIX)/usr/include + +INSTALL_SH = ./install.sh + +CP = cp +RM = rm +#CC = gcc +CC = g++ +MKDIR = mkdir diff --git a/branches/sys_nicmonitor-1.4-龙芯-32/const.h b/branches/sys_nicmonitor-1.4-龙芯-32/const.h new file mode 100644 index 0000000..e2ebfa5 --- /dev/null +++ b/branches/sys_nicmonitor-1.4-龙芯-32/const.h @@ -0,0 +1,51 @@ +#ifndef _RTE_CONST_H +#define _RTE_CONST_H + +#include + + +#define MAX_STRING_LEN 24 +#define MAX_EXECMD_LEN 200 +#define MAX_FILENAME_LEN 200 + +#define MAX_CONTEXT 8 +#define MAX_HOSTNAME_LEN 24 +#define MAX_LOCAL_MESPROC 512 +#define MAX_LOCAL_PROCESS MAX_LOCAL_MESPROC +#define MAX_LOCAL_APP 32 +#define MAX_LOCAL_NODE 256 + +#define MAX_SET 256 //max num of event set +#define MAX_EVENT 1300 +#define MAX_REG_PROC 20 + +#define LEN_SHMBLK_BIG 4096 +#define MAX_MSGBUF_LEN 32767 +#define FREE_PAGE_SIZE 65536 +#define MAX_PAGE_NUM 1024 + +#define MAX_QUE MAX_LOCAL_MESPROC +#define MAX_SEMPHORE_SET MAX_LOCAL_MESPROC*2 +#define RTE_HAN 0 // queue number for event handeler0(RTE) +#define EX_EVENT_HAN RTE_HAN // queue number for extrnal event handeler + +#define DOMAIN_I 1 +#define DOMAIN_II 2 +#define DOMAIN_III 3 + +//Add 20090225 +const int PROC_TYPE_RPT =1; +const int PROC_TYPE_UNRPT =0; +//add end + + +//status for proc and app +const int NON_ACTIVE = 0; +const int ACTIVE = 1; +const int HANGUP = 2; +const int FAILURE = 5; +const int START = 6; +const int STOP = 7; + +#endif + diff --git a/branches/sys_nicmonitor-1.4-龙芯-32/dotconf.h b/branches/sys_nicmonitor-1.4-龙芯-32/dotconf.h new file mode 100644 index 0000000..e802508 --- /dev/null +++ b/branches/sys_nicmonitor-1.4-龙芯-32/dotconf.h @@ -0,0 +1,264 @@ +#ifndef DOTCONF_H +#define DOTCONF_H + +#ifdef __cplusplus +extern "C" { +#endif + +/* stdio.h should be included by the application - as the manual page says */ +#ifndef _STDIO_H +#include /* needed for FILE* */ +#endif + +#ifdef WIN32 +# ifndef R_OK +#define R_OK 0 +# endif +#endif + +/* some buffersize definitions */ +#define CFG_BUFSIZE 4096 /* max length of one line */ +#define CFG_MAX_OPTION 32 /* max length of any option name */ +#define CFG_MAX_VALUE 4064 /* max length of any options value */ +#define CFG_MAX_FILENAME 256 /* max length of a filename */ +#define CFG_VALUES 16 /* max # of arguments an option takes */ + +#define CFG_INCLUDEPATH_ENV "DC_INCLUDEPATH" +#define WILDCARDS "*?" /* list of supported wild-card characters */ + +/* constants for type of option */ +#define ARG_TOGGLE 0 /* TOGGLE on,off; yes,no; 1, 0; */ +#define ARG_INT 1 /* callback wants an integer */ +#define ARG_STR 2 /* callback expects a \0 terminated str */ +#define ARG_LIST 3 /* wants list of strings */ +#define ARG_NAME 4 /* wants option name plus ARG_LIST stuff */ +#define ARG_RAW 5 /* wants raw argument data */ +#define ARG_NONE 6 /* does not expect ANY args */ + +#define CTX_ALL 0 /* context: option can be used anywhere */ + +/* for convenience of terminating the dotconf_options list */ +#define LAST_OPTION { "", 0, NULL, NULL } +#define LAST_CONTEXT_OPTION { "", 0, NULL, NULL, 0 } + +#define DOTCONF_CB(__name) const char *__name(command_t *cmd, \ + context_t *ctx) +#define FUNC_ERRORHANDLER(_name) int _name(configfile_t * configfile, \ + int type, long dc_errno, const char *msg) + + +/* some flags that change the runtime behaviour of dotconf */ +#define NONE 0 +#define CASE_INSENSITIVE 1<<0 /* match option names case insensitive */ +#define DONT_SUBSTITUTE 1<<1 /* do not call substitute_env after read_arg */ +#define NO_INLINE_COMMENTS 1<<2 /* do not allow inline comments */ +#define DUPLICATE_OPTION_NAMES 1<<3 /* allow for duplicate option names */ + +/* syslog style errors as suggested by Sander Steffann */ +#ifdef HAVE_SYSLOG +#include + +#define DCLOG_EMERG LOG_EMERG /* system is unusable */ +#define DCLOG_ALERT LOG_ALERT /* action must be taken immediately */ +#define DCLOG_CRIT LOG_CRIT /* critical conditions */ +#define DCLOG_ERR LOG_ERR /* error conditions */ +#define DCLOG_WARNING LOG_WARNING /* warning conditions */ +#define DCLOG_NOTICE LOG_NOTICE /* normal but significant condition */ +#define DCLOG_INFO LOG_INFO /* informational */ +#define DCLOG_DEBUG LOG_DEBUG /* debug-level messages */ + +#define DCLOG_LEVELMASK LOG_PRIMASK /* mask off the level value */ + +#else /* HAVE_SYSLOG */ + +#define DCLOG_EMERG 0 /* system is unusable */ +#define DCLOG_ALERT 1 /* action must be taken immediately */ +#define DCLOG_CRIT 2 /* critical conditions */ +#define DCLOG_ERR 3 /* error conditions */ +#define DCLOG_WARNING 4 /* warning conditions */ +#define DCLOG_NOTICE 5 /* normal but significant condition */ +#define DCLOG_INFO 6 /* informational */ +#define DCLOG_DEBUG 7 /* debug-level messages */ + +#define DCLOG_LEVELMASK 7 /* mask off the level value */ + +#endif /* HAVE_SYSLOG */ + +/* callback types for dotconf_callback */ + +/* error constants */ +#define ERR_NOERROR 0x0000 +#define ERR_PARSE_ERROR 0x0001 +#define ERR_UNKNOWN_OPTION 0x0002 +#define ERR_WRONG_ARG_COUNT 0x0003 +#define ERR_INCLUDE_ERROR 0x0004 +#define ERR_NOACCESS 0x0005 +#define ERR_USER 0x1000 /* base for userdefined errno's */ + +/* i needed this to check an ARG_LIST entry if it's toggled in one of my apps; maybe you do too */ +#define CFG_TOGGLED(_val) ( (_val[0] == 'Y' \ + || _val[0] == 'y') \ + || (_val[0] == '1') \ + || ((_val[0] == 'o' \ + || _val[0] == 'O') \ + && (_val[1] == 'n' \ + || _val[1] == 'N'))) + +enum callback_types +{ + ERROR_HANDLER = 1, + CONTEXT_CHECKER +}; + +typedef enum callback_types callback_types; +typedef struct configfile_t configfile_t; +typedef struct configoption_t configoption_t; +typedef struct configoption_t ConfigOption; +typedef struct command_t command_t; +typedef void context_t; +typedef void info_t; + +typedef const char *(*dotconf_callback_t)(command_t *, context_t *); +typedef int (*dotconf_errorhandler_t)(configfile_t *, int, unsigned long, const char *); +typedef const char *(*dotconf_contextchecker_t)(command_t *, unsigned long); + +struct configfile_t +{ + /* ------ the fields in configfile_t are provided to the app via command_t's ; READ ONLY! --- */ + + FILE *stream; + char eof; /* end of file reached ? */ + size_t size; /* file size; cached on-demand for here-documents */ + + context_t *context; + + configoption_t const **config_options; + int config_option_count; + + /* ------ misc read-only fields ------------------------------------------------------------- */ + char *filename; /* name of file this option was found in */ + unsigned long line; /* line number we're currently at */ + unsigned long flags; /* runtime flags given to dotconf_open */ + + char *includepath; + + /* ------ some callbacks for interactivity -------------------------------------------------- */ + dotconf_errorhandler_t errorhandler; + dotconf_contextchecker_t contextchecker; + + int (*cmp_func)(const char *, const char *, size_t); +}; + +struct configoption_t +{ + const char *name; /* name of configuration option */ + int type; /* for possible values, see above */ + dotconf_callback_t callback; /* callback function */ + info_t *info; /* additional info for multi-option callbacks */ + unsigned long context; /* context sensitivity flags */ +}; + +struct command_t +{ + const char *name; /* name of the command */ + configoption_t *option; /* the option as given in the app; READ ONLY */ + + /* ------ argument data filled in for each line / command ----------------------------------- */ + struct { + long value; /* ARG_INT, ARG_TOGGLE */ + char *str; /* ARG_STR */ + char **list; /* ARG_LIST */ + } data; + int arg_count; /* number of arguments (in data.list) */ + + /* ------ misc context information ---------------------------------------------------------- */ + configfile_t *configfile; + context_t *context; +}; + +/* ------ dotconf_create() - create the configfile_t needed for further dot.conf fun ------------ */ +configfile_t *dotconf_create(char *, const configoption_t *, context_t *, unsigned long); + +/* ------ dotconf_cleanup() - tidy up behind dotconf_create and the parser dust ----------------- */ +void dotconf_cleanup(configfile_t *configfile); + +/* ------ dotconf_command_loop() - iterate through each line of file and handle the commands ---- */ +int dotconf_command_loop(configfile_t *configfile); + +/* ------ dotconf_command_loop_until_error() - like continue_line but return on the first error - */ +const char *dotconf_command_loop_until_error(configfile_t *configfile); + +/* ------ dotconf_continue_line() - check if line continuation is to be handled ----------------- */ +int dotconf_continue_line(char *buffer, size_t length); + +/* ------ dotconf_get_next_line() - read in the next line of the configfile_t ------------------- */ +int dotconf_get_next_line(char *buffer, size_t bufsize, configfile_t *configfile); + +/* ------ dotconf_get_here_document() - read the here document until delimit is found ----------- */ +char *dotconf_get_here_document(configfile_t *configfile, const char *delimit); + +/* ------ dotconf_invoke_command() - call the callback for command_t ---------------------------- */ +const char *dotconf_invoke_command(configfile_t *configfile, command_t *cmd); + +/* ------ dotconf_find_command() - iterate through all registered options trying to match ------- */ +configoption_t *dotconf_find_command(configfile_t *configfile, const char *command); + +/* ------ dotconf_read_arg() - read one argument from the line handling quoting and escaping ---- */ +/* + side effects: the char* returned by dotconf_read_arg is malloc() before, hence that pointer + will have to be free()ed later. +*/ +char *dotconf_read_arg(configfile_t *configfile, signed char **line); + +/* ------ dotconf_handle_command() - parse, substitute, find, invoke the command found in buffer */ +const char *dotconf_handle_command(configfile_t *configfile, char *buffer); + +/* ------ dotconf_register_option() - add a new option table to the list of commands ------------ */ +void dotconf_register_options(configfile_t *configfile, const configoption_t *options); + +/* ------ dotconf_warning() - handle the dispatch of error messages of various levels ----------- */ +int dotconf_warning(configfile_t *configfile, int level, unsigned long errnum, const char *, ...); + +/* ------ dotconf_callback() - register a special callback -------------------------------------- */ +void dotconf_callback(configfile_t *configfile, callback_types type, dotconf_callback_t); + +/* ------ dotconf_substitute_env() - handle the substitution on environment variables ----------- */ +char *dotconf_substitute_env(configfile_t *, char *); + +/* ------ internal utility function that verifies if a character is in the WILDCARDS list -- */ +int dotconf_is_wild_card(char value); + +/* ------ internal utility function that calls the appropriate routine for the wildcard passed in -- */ +int dotconf_handle_wild_card(command_t* cmd, char wild_card, char* path, char* pre, char* ext); + +/* ------ internal utility function that frees allocated memory from dotcont_find_wild_card -- */ +void dotconf_wild_card_cleanup(char* path, char* pre); + +/* ------ internal utility function to check for wild cards in file path -- */ +/* ------ path and pre must be freed by the developer ( dotconf_wild_card_cleanup) -- */ +int dotconf_find_wild_card(char* filename, char* wildcard, char** path, char** pre, char** ext); + +/* ------ internal utility function that compares two stings from back to front -- */ +int dotconf_strcmp_from_back(const char* s1, const char* s2); + +/* ------ internal utility function that determins if a string matches the '?' criteria -- */ +int dotconf_question_mark_match(char* dir_name, char* pre, char* ext); + +/* ------ internal utility function that determins if a string matches the '*' criteria -- */ +int dotconf_star_match(char* dir_name, char* pre, char* ext); + +/* ------ internal utility function that determins matches for filenames with -- */ +/* ------ a '?' in name and calls the Internal Include function on that filename -- */ +int dotconf_handle_question_mark(command_t* cmd, char* path, char* pre, char* ext); + +/* ------ internal utility function that determins matches for filenames with -- */ +/* ------ a '*' in name and calls the Internal Include function on that filename -- */ +int dotconf_handle_star(command_t* cmd, char* path, char* pre, char* ext); + + + +#ifdef __cplusplus +} /* extern "C" */ +#endif + +#endif /* DOTCONF_H */ diff --git a/branches/sys_nicmonitor-1.4-龙芯-32/mnic.c b/branches/sys_nicmonitor-1.4-龙芯-32/mnic.c new file mode 100644 index 0000000..70021a7 --- /dev/null +++ b/branches/sys_nicmonitor-1.4-龙芯-32/mnic.c @@ -0,0 +1,1513 @@ +#include "mnic.h" +#include "dotconf.h" +#include +#include +#include "proc_inv.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 "/tmp/sys_netcard_shm_path" +#define SEM_PATH "/tmp/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.4" + +#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. +}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 + "" +}; + +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}, + LAST_OPTION +}; +/****dotconf****/ + +/* write error in logfile */ +void record_log(char *str) +{ + 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); + } +} + +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 ((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; + } + 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, 0) == -1){ + snprintf(error_str, sizeof(error_str), "EMERG: semctl: %s !\n", strerror(errno)); + record_log(error_str); + semctl(*semid, 0, IPC_RMID); + return; + } +} + +static void init_shm(SHM **ptr, CONFIG_FILE_ST *p) +{ + 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); + +} + +static void get_sem(int semid) +{ + struct sembuf lock[2]; + char error_str[200]; + + lock[0].sem_num = 0; + lock[0].sem_op = 0; + 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, 2)){ + 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 +=strlen(net->charname) + 2; + 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]; + char error_str[200]; + unsigned long long 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){ + 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->mem.conf->flow_interval); + if(!strncmp(curr->info.charname, "bond", 4)){ + count_t = get_netcard_count(curr->info.charname); + }else { + count_t = 1; + } + summit = (unsigned int)(curr->info.average_flow*8*100/1024/1024/ptr->mem.conf->flow_peak/count_t); +#if 0 + printf("%s:\tcount=%d\tsummit=%d\tflow_limit:%d\taverage_flow:%d\n", curr->info.charname, count_t, summit, conf.flow_limit, curr->info.average_flow); +#endif + 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); + //snprintf(error_str, sizeof(error_str), "NOTICE: %s flow is abnormal, summit is %d, average flow is %lld !\n", curr->info.charname, summit, curr->info.average_flow); + 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... */ + bytes[i] = curr->info.rx_bytes + 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) +{ + int i, ret = -1, j, k; + char buf[64]; + + i = find_nic_config(devname); + if( i == -1 ) + return 0; + + if(conf.nic[i].gw_num == 0) + return 0; + + for(k=0; k /dev/null 2>&1", conf.pinglap,conf.nic[i].ping_ip[j]); + ret=system(buf); +#if 0 + if (WIFSIGNALED(ret) && + (WTERMSIG(ret) == SIGINT || WTERMSIG(ret) == SIGQUIT)) + exit(0); +#endif + if(ret == 0) + 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){ + 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); + 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); + exit(0); +} + +/* + * 查看数据结构中是否有给定的网卡 + * 输入:网卡名称 + * 返回值:-1 表示没有 + * 非0值表示设备列表中的索引 + * + */ +int find_nic_config(char *dev_name){ + int i, index=-1; + + for(i=0; iname, myconf[13]) == 0) && (nicnum <= MAXNICNUM)){ + i = 1; + if(cmd->data.list[0] && cmd->data.list[1]){ + //查找设备列表中是否已有该网卡 + //如果没有则创建一项 + //如果已有则只要增加ping的地址和地址数量 + //一般都能找到,因为配置文件中一般总是先定义"nic",后定义"ping" + //如果没找到,则表明先定义了"ping",未定义"nic"或后定义"nic",而未定义"nic"应该是错误的 + index = find_nic_config(cmd->data.list[0]); + if(index == -1){ + strncpy(conf.nic[nicnum].dev_name, cmd->data.list[0], strlen(cmd->data.list[0]) >= IPLEN ? IPLEN-1 : strlen(cmd->data.list[0])); + card_info_index = nicnum; + nicnum++; + } + else + card_info_index = index; + + while(cmd->data.list[i]){ + if((int)(inet_addr(cmd->data.list[i])) == -1){ + sprintf(wrong_ip,"The wrong IP address:'%s'",cmd->data.list[i]); + strcat(wrong_ip,"\n"); + record_log(wrong_ip); + } else{ + strncpy(conf.nic[card_info_index].ping_ip[conf.nic[card_info_index].gw_num++], cmd->data.list[i], strlen(cmd->data.list[i]) >= IPLEN ? IPLEN-1 : strlen(cmd->data.list[i])); + } + i++; + } + } + } + + //"nic"选项的处理 + if((strcmp(cmd ->name, myconf[12]) == 0) && (nicnum <= MAXNICNUM)){ + //设备列表中没有给定的网卡设备,则添加一项 + //否则不必添加 + //对应配置文件中先指定"ping"后指定"nic"的情况 + index = find_nic_config(cmd->data.str); + if(index == -1){ + strncpy(conf.nic[nicnum].dev_name, cmd->data.str, strlen(cmd->data.str) >= NIC_NAME_LEN ? NIC_NAME_LEN-1 : strlen(cmd->data.str)); + nicnum++; + } + } + + if((strcmp(cmd ->name, myconf[11]) == 0)){ + strncpy(conf.udp, cmd->data.str, strlen(cmd->data.str)); + } + + return NULL; +} + +DOTCONF_CB(cb_int) +{ + if(strcmp(cmd ->name, myconf[0]) == 0){ + conf.domain = cmd->data.value; + } + if(strcmp(cmd ->name, myconf[1]) == 0){ + conf.serv = cmd->data.value; + } + if(strcmp(cmd ->name, myconf[2]) == 0){ + conf.event = cmd->data.value; + } + if(strcmp(cmd ->name, myconf[3]) == 0){ + conf.udpport = cmd->data.value; + } + if(strcmp(cmd ->name, myconf[6]) == 0){ + conf.monitor_interval = cmd->data.value; + } + if(strcmp(cmd ->name, myconf[7]) == 0){ + conf.write_interval = cmd->data.value; + } + if(strcmp(cmd ->name, myconf[8]) == 0){ + conf.flow_interval = cmd->data.value; + } + if(strcmp(cmd ->name, myconf[9]) == 0){ + conf.flow_limit = cmd->data.value; + } + if(strcmp(cmd ->name, myconf[10]) == 0){ + conf.flow_peak = cmd->data.value; + } + if(strcmp(cmd ->name, myconf[14]) == 0){ + conf.pingnum = cmd->data.value; + } + if(strcmp(cmd ->name, myconf[15]) == 0){ + conf.pinglap = cmd->data.value; + } + + return NULL; +} + +DOTCONF_CB(cb_list) +{ + return NULL; +} + +int get_conf() +{ +// int uid; +// char buf[1024]; +// int i; +// struct passwd *user; + configfile_t *configfile; + +// 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) + { + record_log("Warning can't reading config file\n"); + return -1; + } + + if (dotconf_command_loop(configfile) == 0){ + record_log("Warning can't reading config file\n"); + 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.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_dir(char *create_path) +{ + int i,len = strlen(create_path); + + len = strlen(create_path); + + for(i=1; inext; + 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(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 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; + proc_invocation prcm; + + memset(&conf, 0, sizeof(CONFIG_FILE_ST)); + if(isrun(argv[0]) == 1){ + printf("the program is already started!\n"); + exit(0); + } +//process register +#if 1 + if((proc_stat=prcm.proc_init("sys","base_srv","sys_nicmonitor"))==-1){ + perror("proc_init()"); + exit(-1); + } +#endif + + 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); + } + 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); + + /* sure the process is started */ + snprintf(error_str, sizeof(error_str), "NOTICE: %s V%s is started !\n", process_name, MNIC_VERSION); + record_log(error_str); + + get_conf(); + + /* 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; + + 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); + munmap(shm_ptr, sizeof(SHM)); + return 0; +} diff --git a/branches/sys_nicmonitor-1.4-龙芯-32/mnic.h b/branches/sys_nicmonitor-1.4-龙芯-32/mnic.h new file mode 100644 index 0000000..d7a6390 --- /dev/null +++ b/branches/sys_nicmonitor-1.4-龙芯-32/mnic.h @@ -0,0 +1,44 @@ +#ifndef __MNIC_H +#define __MNIC_H + +//#define _GNU_SOURCE +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "sys_netcard.h" +#include +#include +#define IPSIZE 16 + +char *get_name(char *, char *); +int if_fetch(NETCARD_INFO *); +int ioc_get_name(NETCARD_INFO *); +int get_dev_fields(char *p, NETCARD_INFO *); +int get_user_home(int , char *); +void send_alarm(D5000_NIC_ALARM *, int , char *); +void record_log(char *); + +#endif diff --git a/branches/sys_nicmonitor-1.4-龙芯-32/nicinfo_shm.c b/branches/sys_nicmonitor-1.4-龙芯-32/nicinfo_shm.c new file mode 100644 index 0000000..c8a8bf2 --- /dev/null +++ b/branches/sys_nicmonitor-1.4-龙芯-32/nicinfo_shm.c @@ -0,0 +1,209 @@ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "nicinfo_shm.h" + +#define SHM_PATH "/tmp/sys_netcard_shm_path" +#define SEM_PATH "/tmp/sys_netcard_sem_path" +#define LOG_PATH "/var/log/netcard/" + +typedef struct net_info{ + NETCARD_INFO info[MAXNICNUM]; +}SHM; + +static int semid = 0; +static char log_path[1024]; +static char shm_path[1024]; +static char sem_path[1024]; +SHM *ptr = NULL; + +/* write error in logfile */ +void record_log(char *str) +{ + 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, "get_nic_info"); + strcat(log_str, " "); + strcat(log_str, str); + if(fwrite(log_str, 1, strlen(log_str), log_fp) < 1){ + } + fclose(log_fp); + } +} + +void get_sem(int semid) +{ + char err_str[200]; + struct sembuf lock[2]; + + lock[0].sem_num = 0; + lock[0].sem_op = 0; + 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, 2)){ + if (errno == EINTR) { + continue; + } + snprintf(err_str, sizeof(err_str), "EMERG: semop():\n", strerror(errno)); + record_log(err_str); + return; + } +} + +void release_sem(int semid) +{ + int ret; + char err_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(err_str, sizeof(err_str), "EMERG: semop():\n", strerror(errno)); + record_log(err_str); + return; + } +} + + +int init_nic_info(void) +{ + int fd = -1; + int sem_val; + char err_str[200]; + key_t key; + + + if ((key=ftok(sem_path, SEM_PROJ_ID)) == -1) { + snprintf(err_str, sizeof(err_str), "EMERG: ftok():%s\n", strerror(errno)); + record_log(err_str); + return -1; + } + if((semid = semget(key, 1, IPC_CREAT|0666)) == -1){ + snprintf(err_str, sizeof(err_str), "EMERG: Create semaphore error: %s\n", strerror(errno)); + record_log(err_str); + return -1; + } + /* + if((sem_val = semctl(semid, 0, GETVAL, 0)) == -1){ + snprintf(err_str, sizeof(err_str), "EMERG: semctl: %s !\n", strerror(errno)); + record_log(err_str); + semctl(semid, 0, IPC_RMID); + return -1; + } + if(!sem_val){ + if(semctl(semid, 0, SETVAL, 1) == -1){ + snprintf(err_str, sizeof(err_str), "EMERG: semctl: %s !\n", strerror(errno)); + record_log(err_str); + semctl(semid, 0, IPC_RMID); + return -1; + } + } + */ + if((fd = open(shm_path, O_RDONLY)) == -1){ + snprintf(err_str, sizeof(err_str), "EMERG: Error open %s: %s!\n",shm_path, strerror(errno)); + record_log(err_str); + return -1; + } + ptr = (SHM*)mmap(NULL, sizeof(SHM), PROT_READ, MAP_SHARED, fd, 0); + if(ptr == MAP_FAILED){ + snprintf(err_str, sizeof(err_str), "EMERG: mmap():%s\n", strerror(errno)); + record_log(err_str); + return -1; + } + close(fd); + + return 0; +} +int get_nic_info(char *nic_name, NETCARD_INFO *net_info) +{ + int i,ret; + time_t tamp; + struct tm tmptr; + DIR *dir; + char *s; + char buf[128]; + char err_str[200]; + struct passwd *user; + + tamp = time(NULL); + localtime_r(&tamp, &tmptr); + + 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); + } + strcat(log_path,LOG_PATH); + strcat(shm_path,SHM_PATH); + strcat(sem_path,SEM_PATH); + + if((dir = opendir(log_path)) == NULL){ + if(errno == ENOENT){ + strcpy(log_path, "/tmp/"); + } + } + closedir(dir); + s = strrchr(log_path, '/'); + s++; + *s = '\0'; + memset(buf, 0, sizeof(buf)); + strftime(buf, sizeof(buf), "%Y%m%d_", &tmptr); + strcat(buf, "sys_nicmonitor"); + strcat(buf, ".log"); + strcat(log_path, buf); + if((ret = init_nic_info()) == -1){ + return -1; + } + get_sem(semid); + for(i = 0; ptr->info[i].charname[0] != 0; i++){ + if(!strcmp(ptr->info[i].charname, nic_name)){ + // get_sem(semid); + memcpy(net_info, &ptr->info[i], sizeof(NETCARD_INFO)); + release_sem(semid); + munmap(ptr, sizeof(SHM)); + return 0; + } + } + release_sem(semid); + snprintf(err_str, sizeof(err_str), "NOTICE: No information of %s !\n", nic_name); + record_log(err_str); + munmap(ptr, sizeof(SHM)); + return -1; +} diff --git a/branches/sys_nicmonitor-1.4-龙芯-32/nicinfo_shm.h b/branches/sys_nicmonitor-1.4-龙芯-32/nicinfo_shm.h new file mode 100644 index 0000000..cd74135 --- /dev/null +++ b/branches/sys_nicmonitor-1.4-龙芯-32/nicinfo_shm.h @@ -0,0 +1,52 @@ +#ifndef NIC_SHM_H +#define NIC_SHM_H + +#include + +#ifdef __cplusplus +extern "C" { +#endif + +#ifndef NIC_NAME_LEN +#define NIC_NAME_LEN 64 +#endif +#define SEM_PROJ_ID 's' +#define MAXNICNUM 32 + +typedef long KEYID; +typedef struct _net_info +{ + KEYID ID; + char charname[NIC_NAME_LEN]; + char descr[128]; + struct sockaddr addr; + struct sockaddr broadaddr; + struct sockaddr netmask; + struct sockaddr hwaddr; + int time_stamp; + short flags; + int mtu; + int tx_queue_len; + unsigned long long average_flow; + unsigned long long rx_packets; + unsigned long long tx_packets; + unsigned long long rx_bytes; + unsigned long long tx_bytes; + unsigned long rx_errors; + unsigned long tx_errors; + unsigned long rx_dropped; + unsigned long tx_dropped; + unsigned long rx_multicast; + unsigned long collisions; + unsigned long rx_fifo_errors; + unsigned long tx_carrier_errors; + unsigned long tx_fifo_errors; +}NETCARD_INFO; + +int get_nic_info(char *nic_name, NETCARD_INFO *net_info); + + +#ifdef __cplusplus +} +#endif +#endif diff --git a/branches/sys_nicmonitor-1.4-龙芯-32/proc_inv.h b/branches/sys_nicmonitor-1.4-龙芯-32/proc_inv.h new file mode 100644 index 0000000..945622c --- /dev/null +++ b/branches/sys_nicmonitor-1.4-龙芯-32/proc_inv.h @@ -0,0 +1,198 @@ +//////////////////////////////////////////////////////////////////////////////////// +// +// Copyright (c) Comets' Grp. of Kedong Corp 2008. All Rights Reserved. +// +// FileName : procconf.h +// +// Function : this class realize some basic functions for process managerment, +// such as initiate process, report status of process, check status of process, +// update status of process, get information of process +// +// Author : +// +// Date : +// +// Modify by : +// +// Mod Date : +// +//////////////////////////////////////////////////////////////////////////////////// + +#ifndef _PROCCONF_H +#define _PROCCONF_H + +#include +#include +#include +#include +#include +#include +#include +//#include +#include + +#include "const.h" + +//for alarm ................................ +typedef struct MESS_BH +{ + unsigned char mtype; + int length; +}; +typedef struct PROCESS_ALM +{ + char context_name[MAX_STRING_LEN]; + char app_name[MAX_STRING_LEN]; + char proc_name[MAX_STRING_LEN]; + unsigned char status; +}; +//for alarm end ............................. + +//for mmi.................................... +const int MAX_BUFFER_LEN = 500; +typedef struct MESS_BLOCK +{ + unsigned char num; + char buffer[MAX_BUFFER_LEN]; +}; +typedef struct MESS_PROC +{ + char context_name[MAX_STRING_LEN]; + char app_name[MAX_STRING_LEN]; + char proc_name[MAX_STRING_LEN]; + char status; +}; +//for mmi end ................................ + +const int DEFAULT_PERIOD = 3; +const int COUNT_LIMIT = 2; +const int START_DEFAULT_PERIOD = 60; +const int START_COUNT_LIMIT = 5; +const int APP_COUNT_LIMIT = 1; + +//process critical level +//const int WST_CRITICAL = 1; // Shutdown and reboot workstation when failed +//const int SYS_CRITICAL = 2; // Shutdown and reboot the system on the wst when failed +//const int USER_CRITICAL = 3; // Shutdown and reboot the subsystem when failed +//const int GENERAL = 4; // reboot the process +const int CRUCIAL = 1; // crucial process +const int GENERAL = 0; // general process + + +extern int srv_init(char *service,int port); +extern int Tcp_close(int sockfd); +extern int Tcp_read(int fd,char *ptr,int nbytes); +extern int Tcp_write(int fd,char *ptr,int nbytes); +extern int srv_accept(int fd,struct sockaddr *cli_addr,int *clilen); +extern int client_tcp_open(char *host,char *service,int port); + +typedef struct +{ + char context_name[MAX_STRING_LEN]; + char app_name[MAX_STRING_LEN]; + char proc_name[MAX_STRING_LEN]; + pid_t proc_pid; +}PROC_ADM_INFO; + +//*************************************************************** +// structure name : PROC_INFO +// function : store process informatin +// author : +// date : +// modify by : +// modification : +// mod date : +//*************************************************************** +typedef struct +{ + int position; + char node_name[MAX_STRING_LEN]; + char context_name[MAX_STRING_LEN]; + char app_name[MAX_STRING_LEN]; + char proc_name[MAX_STRING_LEN]; + + unsigned char active_flag; + unsigned char master_flag; + + time_t startup_time; + time_t refresh_time; + short refresh_peri; + unsigned char monitor_type; + + pid_t proc_pid; + unsigned char auto_start; + unsigned char act_timer; + unsigned char start_timer; + unsigned char critical_level; + + char exefile_path[MAX_EXECMD_LEN]; + +}PROC_INFO; + +//*************************************************************** +// structure name : APP_INFO +// function : store application informatin +// author : +// date : +// modify by : +// modification : +// mod date : +//*************************************************************** +typedef struct +{ + int position; + char context_name[MAX_STRING_LEN]; + int context_id; + char app_name[MAX_STRING_LEN]; + int app_id; + unsigned char act_timer; + unsigned char active_flag; +}APP_INFO; + + +typedef struct +{ + int no_proc; + int semdes_cfg; + PROC_INFO proc[MAX_LOCAL_PROCESS]; + APP_INFO app[MAX_LOCAL_APP]; +}PROCCFG; + +class proc_invocation +{ + public: + int m_init; + PROCCFG *proccfg_p; + + public: + proc_invocation(); + ~proc_invocation(); + + int conf_create(); + //int check_proc_status(); + //int update_rtdb(); + //int kill_proc(pid_t pid); + //int start_proc(char *cmdline); + //int send_alarm(char *context_name, char *app_name, char *proc_name, unsigned char status); + //int update_proc_status(char *context_name, char *app_name, char *proc_name, char status); + + //int proc_init(char *context_name, char *app_name, char *proc_name, int critical_level);//exefile_path,auto_start + int proc_init(char *context_name, char *app_name, char *proc_name); + int proc_report(int pos, char status, int intertime=3); + int proc_exit(int proc_pos); + + int get_pos(char *context_name, char *app_name, char *proc_name); + int is_proc_exist(char *context_name, char *app_name, char *proc_name); + int conf_map(); + + int get_procinfo(int position, PROC_ADM_INFO *p_info); + int get_active_pid(int &num, int *p_pidlist); + int is_proc_run(pid_t pid); + int is_proc_run(char *context_name, char *app_name, char *proc_name); + +}; + +#endif + + + diff --git a/branches/sys_nicmonitor-1.4-龙芯-32/read_netcard.c b/branches/sys_nicmonitor-1.4-龙芯-32/read_netcard.c new file mode 100644 index 0000000..c745f48 --- /dev/null +++ b/branches/sys_nicmonitor-1.4-龙芯-32/read_netcard.c @@ -0,0 +1,133 @@ +#include "mnic.h" + +static char *prase_digit(char **s) +{ + char *retp = NULL; + char *p = *s; + + if(!p)return NULL; + while(!isdigit(*p)){ + p++; + if(*p == '\0')return NULL; + } + retp = p; + while(isdigit(*p)){ + p++; + if(*p == '\0'){ + *s = NULL; + return retp; + } + } + *p = '\0'; + p++; + *s = p; + return retp; +} + + +char *get_name(char *name, char *p) +{ + while (isspace(*p)) + p++; + while (*p) { + if (isspace(*p)) + break; + if (*p == ':') { /* could be an alias */ + char *dot = p, *dotname = name; + *name++ = *p++; + while (isdigit(*p)) + *name++ = *p++; + if (*p != ':') { /* it wasn't, backup */ + p = dot; + name = dotname; + } + if (*p == '\0') + return NULL; + p++; + break; + } + *name++ = *p++; + } + *name++ = '\0'; + return p; +} + +int get_dev_fields(char *str, NETCARD_INFO *ife) +{ + int i = 0; + char *retp[16]; + + while((retp[i] = prase_digit(&str)) != NULL){i++;if(i > 15)break;} + ife->rx_bytes = atoll(retp[0]); + ife->rx_packets = atoll(retp[1]); + ife->rx_errors = atol(retp[2]); + ife->rx_dropped = atol(retp[3]); + ife->rx_fifo_errors = atol(retp[4]); + ife->rx_multicast = atol(retp[7]); + ife->tx_bytes = atoll(retp[8]); + ife->tx_packets = atoll(retp[9]); + ife->tx_errors = atol(retp[10]); + ife->tx_dropped = atol(retp[11]); + ife->tx_fifo_errors = atol(retp[12]); + ife->collisions = atol(retp[13]); + ife->tx_carrier_errors = atol(retp[14]); + return 0; +} + +int if_fetch(NETCARD_INFO *ife) +{ + int skfd; + struct ifreq ifr; + + if((skfd = socket(PF_INET, SOCK_DGRAM, 0)) == -1)return -1; + + strcpy(ifr.ifr_name, ife->charname); + if (!ioctl(skfd, SIOCGIFFLAGS, &ifr)) + ife->flags = ifr.ifr_flags; + + if (!ioctl(skfd, SIOCGIFHWADDR, &ifr)) + ife->hwaddr = ifr.ifr_hwaddr; + + if (!ioctl(skfd, SIOCGIFMTU, &ifr)) + ife->mtu = ifr.ifr_mtu; + + if (!ioctl(skfd, SIOCGIFTXQLEN, &ifr)) + ife->tx_queue_len = ifr.ifr_qlen; + + if (!ioctl(skfd, SIOCGIFADDR, &ifr)) + ife->addr = ifr.ifr_addr; + + if (!ioctl(skfd, SIOCGIFBRDADDR, &ifr)) + ife->broadaddr = ifr.ifr_broadaddr; + + if (!ioctl(skfd, SIOCGIFNETMASK, &ifr)) + ife->netmask = ifr.ifr_netmask; + + ife->time_stamp = time(NULL); + close(skfd); + return 0; +} + + +int ioc_get_name(NETCARD_INFO *name) +{ + int skfd; + int ifrnum; + int i = 0; + struct ifconf ifc; + struct ifreq buf[MAXNICNUM]; + + if((skfd = socket(PF_INET, SOCK_DGRAM, 0)) == -1)return -1; + memset(buf, 0, sizeof(buf)); + ifc.ifc_len = sizeof(buf); + ifc.ifc_buf = (caddr_t) buf; + ioctl(skfd, SIOCGIFCONF, &ifc); + ifrnum = ifc.ifc_len / sizeof(struct ifreq); + while(ifrnum-- > 0){ + strcpy(name[i].charname, buf[ifrnum].ifr_name); + i++; + } + close(skfd); + return i; +} + diff --git a/branches/sys_nicmonitor-1.4-龙芯-32/send_alarm.c b/branches/sys_nicmonitor-1.4-龙芯-32/send_alarm.c new file mode 100644 index 0000000..e88635f --- /dev/null +++ b/branches/sys_nicmonitor-1.4-龙芯-32/send_alarm.c @@ -0,0 +1,37 @@ +#include "mnic.h" + +void send_alarm(D5000_NIC_ALARM *mesg, int socket_port, char *ipv4) +{ + int bytes; + int sock_sd; + int val; + char error_str[200]; + struct sockaddr_in recever; + socklen_t sock_len; + + if((sock_sd = socket(PF_INET, SOCK_DGRAM, IPPROTO_UDP)) == -1){ + snprintf(error_str, sizeof(error_str), "EMERG: socket(): %s\n", strerror(errno)); + record_log(error_str); + return; + } + val=1; + if ((setsockopt(sock_sd, SOL_SOCKET, SO_BROADCAST, &val, sizeof(val))) == -1) { + snprintf(error_str, sizeof(error_str), "EMERG: setsockopt(): %s\n", strerror(errno)); + record_log(error_str); + return; + } + /* init socket*/ + recever.sin_family = AF_INET; + recever.sin_port = htons(socket_port); + inet_pton(AF_INET, ipv4, &recever.sin_addr); + sock_len = sizeof(recever); + /* send alarm*/ + if((bytes = sendto(sock_sd, mesg, sizeof(D5000_NIC_ALARM), 0, (const struct sockaddr *)&recever, sock_len)) < 1){ + snprintf(error_str, sizeof(error_str), "EMERG: sendto(): %s\n", strerror(errno)); + record_log(error_str); + return; + } + //snprintf(error_str, sizeof(error_str), "NOTICE: Alarm information has already send!\n"); + //record_log(error_str); + close(sock_sd); +} diff --git a/branches/sys_nicmonitor-1.4-龙芯-32/sys_netcard.h b/branches/sys_nicmonitor-1.4-龙芯-32/sys_netcard.h new file mode 100644 index 0000000..0d7746c --- /dev/null +++ b/branches/sys_nicmonitor-1.4-龙芯-32/sys_netcard.h @@ -0,0 +1,88 @@ +#ifndef _SYS_NETCARD_H +#define _SYS_NETCARD_H + +#include + +#ifndef NIC_NAME_LEN +#define NIC_NAME_LEN 64 +#endif + +#define SEM_PROJ_ID 's' +#define MAXNICNUM 32 + +#ifdef __cplusplus +extern "C"{ +#endif + +typedef long KEYID; + +typedef struct _msg_frame // message frame +{ + short len; // message length + short seqno; // send sequence + short serv; // services ID + short event; // event ID + unsigned char domain; // domain ID + unsigned char ctxt; // Context ID + short stid; // SOURCE task id + short dtid; // DESTINATION task ID + unsigned char ver_coding; // 版本号 + 编码 + unsigned char mes_type; // 帧类型 +}MSG_FRAME, *LPMSG_FRAME; + +typedef struct _net_info +{ + KEYID ID; + char charname[NIC_NAME_LEN]; + char descr[128]; + struct sockaddr addr; + struct sockaddr broadaddr; + struct sockaddr netmask; + struct sockaddr hwaddr; + int time_stamp; + short flags; + int mtu; + int tx_queue_len; + unsigned long long average_flow; + unsigned long long rx_packets; + unsigned long long tx_packets; + unsigned long long rx_bytes; + unsigned long long tx_bytes; + unsigned long rx_errors; + unsigned long tx_errors; + unsigned long rx_dropped; + unsigned long tx_dropped; + unsigned long rx_multicast; + unsigned long collisions; + unsigned long rx_fifo_errors; + unsigned long tx_carrier_errors; + unsigned long tx_fifo_errors; +}NETCARD_INFO, *LPNETCARD_INFO; + +#define NETCARD_ALARM_FAULT 1 +#define NETCARD_ALARM_RESUME 2 +#define NETCARD_ALARM_SWITCH 3 +#define NETCARD_ALARM_ABNORMAL 4 +#define NETCARD_ALARM_NORMAL 5 +typedef struct _sys_netcard_alarm +{ + char fault_devname[NIC_NAME_LEN]; /*故障设备名称 */ + char switch_devname[NIC_NAME_LEN]; /*切换设备名称 */ + short flags; /* 状态标记 : 1:网卡故障。2:网卡恢复。3:网卡切换。4:流量异常。*/ + short retrytimes; //0,1,2 重发次数 +}SYS_NETCARD_ALARM, *LPSYS_NETCARD_ALARM; + + +typedef struct _d5000_nic_alarm +{ + MSG_FRAME tMsgFrame ; + SYS_NETCARD_ALARM tSysNetcardAlarm ; +}D5000_NIC_ALARM, *LPD5000_NIC_ALARM; + + +#ifdef __cplusplus +} +#endif + +#endif + diff --git a/branches/sys_nicmonitor-1.4-龙芯-32/sys_nicmonitor b/branches/sys_nicmonitor-1.4-龙芯-32/sys_nicmonitor new file mode 100644 index 0000000000000000000000000000000000000000..3f094ea619a4be3eee1e5df89374dfc100d56dcb GIT binary patch literal 47706 zcmeIbe|(%pwLd;d8VI#C;g=MsuwV-1SDKarrTp6d2;D*{p|r?FWjEbyn$RR0vzyW) zfxsr%WeG+EEpWvGRrz?m*ozcPq)7^uR78xZ+=_@1>-AYuF(5ypR`Pkj&&=#T`y>Ir z`nsR*KTMlv=A1d_%$YMYXXcq_o@Z~WSawlZk{Sq ze)UP^QwIQ3h(EvNFxDv>_ZiVPE;4ilh$k_fZxH!@oiOoq4JjL24H>h%Z19_;j&F)- z(8dZnGLVnDsy1E_+Cmc9xbz?m27)@ad{mEoGut$Nrs1>kuu;s$wtlP||E8PzP0#lO zBJ5{mw93X}3*amN5U*zXJ8MbB*q;-(oAPXI`7Q^a)K92C_+s^(RbRLIthux5t52`5 zYiwD6`ucfioqpEbvRJfij_6+kQ7m%F@>L?#+QXK>c3h4>(y;uEeZD;3B>zFgRpM_2 z{R;~;OBYh zQwD#WhyHF>0O6}1e7#1iM-aQ^Uuo?9q=$Znp?}JQzt`YDhS+D)?&#_ImJd82Z;da>@*TkB9zy2LG^!{+C9d7d-Tn4ZY7}|8E%jTI9Ry zWyfxTN4~Y^0*@Sv|C)z>rYU!!2Y;_A_wSx^Up0f{yb1Jg^T=6X5;R@(4XwVA8hakO(5rT5B+RIzXP$mUTX|~l}FD94E{GBIbqN-+=@T9oaqM&S~(s$ zFKV=U!9#D`{t8<43f2=7tgmy1cZ;S?h8!{LjU25>9$z1%( z3Gj2lcBq=HLLc{Q0p`ki<4|?5a>BXzwZ;y$M{E53c430`MMG6178EKNT+oDsUR+K1;*-VJREJTIem6nIaeg*#5Kih zn#%NO(Ss$rtY-v)#tC!C{v#B{6hT7{)v5RI`tQ$Au979+a zuc!=PQ69v96{}lQ6&7W!nx^>iBrm4qSfsH!9;G#6@#^rYr_vZ_(Z1`~2b&_zv1nse zeO-J*aGhAJL1%+{O*kBk5t^-ns~WGXLzPxUVl533iVAD87>pB%t601_+_XVO)}tkA zLiZwOYHO6aHO|&V}$o$4|1MD7eZVuNrD-_!tZH8tI;ds5y1$$FVJf>jVy2iDt zVQqCC=qz_lybk5oHAdpWCdgN8v3lZy&8jXIYpM!I6s+E)YSu&`1ed1k8mk&;tw=*t zd_xRMHbfd2t*MW$W|8=>YNWks(&}pF)x@J~btynJlY`Z&3D-ws5ojA{b)!uXRaFlS zC(EVV*deJQ)sNOxS8Y&L@u*mVreV5X zRfWTm7_5i_wAr-5fAL+t7F8nkXe%OUS%7q_s;du|335k#- z*;dC$N?(c+AxRKFT~hi|k_btH_)kbmU#2BOk|5r$1&Ht^LW~sg$4N?GW+pC47MND{=KCMkXCN`xdq{OOX?mraR~B#7r4$%f5|kR*wpB`JM*I1!Qr@#T`zm#vAA zB#5_bb0W4ULX4zdb0noNeTk4HNPmW;^ksJa^cT& z;Y(b2dr!>lX)gQ)E_$B}f1wLM(}nlD@Z~Q26)yZd7k+^Y?|0!By6^!Pevu1b>B28| z;jePxD_r=H3xAOdU+cmzap9X>_<#$)-i2T4!ne8b7rXEqUHD5}_%0WInG3(kg}>B= z4HyQFr<(+RlQ3O*IwbIGgz3W5 zl>)y?n65kR7x*Q@blK^0fnOj@SDp3={48O*=yZv|PZ6eTPAh@C3DYH~hyO0^PuNd* zP~dM9rmIa42>c*ny4ZA|!1ofSYfWzz_)fxfsp-uE-$uBCaF@Wh5T*-Fw+Vbb;U$Ed z1a2lAARH3-TEcXd=}LiD6TXGKYE&ecU2&9{*jQx0^&!5@?%Duse#V(N5ej~H2L(87L5M>M^ATk ztpZIT**X$PwhV7)ZGjYAVqZzJb$>5W&hP&=I%=_%pxzDYzCd!-_Wp{ONf79-7?e0w zu{)6R`vb`eC;bF4z1-S!egSr%1_O!KK~;QLUwdDC3OJFa()Z&MNFguT-%a8k%5h%! zD>zauP9W6^uKuEKKe5lj#Gu^{%cFBqSeAW@$w7fyd#LKD;*RrBOrrH=6~7jApluVnWW~sk4~UU0Vh}}+ zIQOxlA`p3r))Ce6D}Wi341EHSEn*lPj#H;OhG{V=v*qO8ABzNq2esr|IVlVC5U*YIzA0xEdu!%<`?(7%@En9-i zRNWGR5nwuZFvB?!BR^TOH_^IRw_uh}DsPM+R{l?Et@baV zwB7(N&T49HO`>}o#O$L^L(Slaz5At4=}Ly*9UXl?jhc#RY~2Z$h{a8nD*aj*aI#K5T>SmQ1CgwO(=C3y z@Vx~%7Etjh+U$G#pWuQ>wExSutw|A&0E@2G!4k4H-3TaCQv#Wqir?NQ)Sa!Homp>z z4GC!+=K(_2N9qAx+~08*_{Gm~u0a!RW>Gm!l>7@YaJ1c2rUyzZ=N+JiR>Ewg?wQM0 z4{Nizd)*P_axO-9$QCoS%5ZgaN#C=OtPZ4MuuV!-?8O*d*4yjHOo%o zOySqVKC}e7&V^7Z)wIy&zjhWXKuI|nBRI?u~bR1D_zNWC9I z@mMPz)iTvAtk5`Y22SwtQ(*luyv|k>$3BQj=cpDKRoW@g*|HT4(&wy(!1OXy&#vOM zm#2TvtfdC+uxuU7j7fMOR9+l?hHg)WZjXl!orYQtMcDr~1qx)wIB!MT>J;*2bZe|0qJzPR&nNEIg#r_+=GCbmz=~|wAmnGqY)MYpi*(t& zp}W!BZewqBbsyk#_hJ3f6|jOa-KU6N`oKSH`J-=6EdTe&L*05qosfTuM?P>`{%?fJ zEB{-sYx!S)ANdI@|4WenEbeUG`U9usw~i}+iIIPyOFm{_%=esqaaR@SMBnd6KLMuS zk68#YW>@CWb%RiMkLUjcOsZ3}>|lQPR2r{Qn+OFi(c!KS2Qng*qi^t>v23rNdg$3_#sA*ghyYKPQBH+XNbzZm1uoS@y1D%8#+_F zORsjAhi|$iQL#TSRd_u_!*{ zGrT``<@rq>ETM*$r;a!l`xB|c!*M<5sg~n74tZDa+ymETXMp1&iaWnU$j1EG#{0p< zNP!d~cuZ<=U35z<~2IbFeB&?(FZV2j9;xU0srr z)Vt}Oe>)(#d*{e;$)BCPlkTSbf7oKwU$>Y7Z}H<5zr(6*(lZsmD@XcOoqn}E(0M6J z+d);j(`2JEPLD2n(BwGJOPdQ-&oHQ*9WI2dbH3w32*rIwq_&B*w0viy(CBL0DZYc7 zr=ljN{v8A|bEPcO>0EWWYRKYV*qjtKT!S-W;w^hi>LnxkyvJRKaR2ABi-y3lmr)<>Yz%=5|c>5NtmMMIp^x4+H;FK zCAX+sT}3^PIe+LTD{3BZBb8n>Fr|CgI!McuafS2W08t%ZZW$NkmT`isj1?#&Q-Zz^ z%?f9Kv2AkmzCmQ<+8lEkYHRLA_Mv((u33!1C&&U&YdI`=da)-vtVi{5b=Z3a6w?%q zdtuf`Py$!4571JrBSszU_BmgNd5NK|duqYuoKBjGkp*Iv18CZ&EPYpC-w+|FyXWd*k=6_Qwv}P!W6b-+|3qhntnj9n)cs z8o61;^-XL@U|LWmxV|H4+<_qdH&rsU*g1_Qqkl|_qrJ2ibr~(#qq}d&)ncvIf?3Xe z*u28v>TDTKNtxZSw{rdsV$6)y^7YJE8Ba6O5}LUrNH;zb5^_e!Sx!5Yf`xv92GSN1 z-M*Tu+fQE=3yE%{=oHp2iG6Y}mu%UK4f#E0g)y`m4hTN$nIbG@WKkm9s|C1~&TOxi zp|Y5!=cZcsI`_f_jG^RiMzTMUe6gF%&izo2v_-IvtQvS@xN1*Ey4_^xu$tYx&yUW6 z{_J2tXKrN0b($H#Y{_DDkVGZ`E}~Lx(@MQJgxf%)C8a^p?=^(h^#=FX;=1jKD zV>0h4E(nu%{cxBTnutbp3Z&XK)yeRZ-imeX77Gu^h!4EGO@kVnx?3O$Pj+dw^#V=r z(moISIto@rZ#k4TkhL3UeLM`{9;`H}(M{Ns1K88Z4{&Gd@DAFD$(@6RbQC*ZJ3L3b z=`{NXYsXEG4vY12UeAC#g!6)%u0!y33&rG{Wwv?f>T`-zx_g7 zP9D&uz>e55wnbcM^r-1?>jKdv;R0|c0IfS@-KC1Zf5e5C`*dcqGGBM@MNlvOD??^# zj!nVA#hTIDLO;fEF2w_I?BbcwNiYHN|CFaQ?IjEGfaVkfuEWf1Sl9mK!; zO?D6;f_txA;l*D(41-bEy&oOZ4oMDC&QIyrCT#BY6b#MYx4FZE6EydLySWMc)6HFJ z^f1j`IB|1VUY2bZUFDTf@549uH77}P9|SSFxkr~vbB`d>4f|o5o2Jb)Hv!usOuv6~ zufj|!J2I~39?5O)H-DXN?h~+alq=lb+C2KP?iQSGO*#A)t z?4bES?||i$V_4=DgA5P&r|+sDU{}!!Q?hediy*__UUCv`itZS7fU$3 zgpaT+o#WOweVHAv4{~7w!)0&E&mw5H0+LT9UVV=+JOsA}JXyUtSs4BGkY;B+K307H zS&#Odh=%t#n`G7_m7Vo6mgv|cjggu1G^nw7T5BcSDG&Zgj8Ivm<+>h8a~1TwUIlGJ zPfcC=q4ZARA-LAv+uy#47H45t^mXI$fVb;ChBDF@2u;Tz)Xc0iyYxNvCO&e(gEjr+ z1)Hh%vA#UI0jT?k*$2Z6GZ?tJ|1Jy^y-T|4S76V5mbSuCtk*neDf@z~(l@hL9#!La z-)vv92f27~hAijv*g(UaMi{Ky!|E-E&nCYePAfy^u;+b?(;-noN@bbf$} zrujB>E`OVwpTI=?r%GLl+j$fRA_h^P%G}k_(ids2ib3~uiQZ&aN8sqMbmr3DDLj)* zJOy^w>S(=N5ds-Sa#u%#V^>FVfTt2`u@Ps6(ZNiW1){2ZWi)74Ml%9Forx8U*-q4s z^90dQ_N}B}2Xgy$?3bv3>DLcoT{~1G)=0JSv1)c9H3)A`OiC6~gU%$M%&gyCVrSNG zAcck0{fH>QETjf=7E-{Nk9<{z5IX#g zOxW4&a*fS(4Cm1dxsKr|J8t@zmmMxc(>RFq_Q3*-4QKN&&=m{Br-~oQ_$)D@-bYGq zE0y7Y_cTVS4vEGr$Y1<9JW=7MD`7(}#&>9{{*s=ydqT?DEuBG2NIaFh7%zd?%(x+t zv5Bj@rH(isqTLJeZ8NEkti>~hIa{HHQPI`aL}m20A~y5)E7;5$g$|eMVC|9}Q*ce} z;59$~Ig_|)s!rs^OVbtTK^iJ3Zr=#oX<$-u``ZB0C$h^KsrptR4{)c}QP#`l5Z!%k zZV&#i7hwJ&@P7!_wp`YAWZgP0t8BI9PV<7w%=BJ@UKCGFGX!JwemJ-Azy1uP4XX)b zSh@AdAFsYY&E?w(K0R)hpkvxykI$yg+`W>GBJJ3{nGgGe(`ArOUTg=cLJF<-*F`z4 zXH;+xRnxM1wBj)dHZ}8a{8}J&#A1|@I`hg4r6g9@X~txz)tRSV3ERlI3Y&Y`fh zUkOZhx|H>2=0wKza8tPHci#_xYJdxD-fWLo%1E~#f}MqWbWs0*-r0r}+1b`83SH>u z0%+(+6ftb}r_KI;$64Ux60l_kk1V)L!_#-)y&;8TUz4%jeO&P!?_#Zi_1L);ds_~W zRbvQd(S>NU4DqDSu;XJby(M8!%se%4a=XthKLxdUYVas_hWb19qa22zLu`Wx3YEn} zU}k39P_}3~E4F$cV)y$?NREfv(@gA>c=3=1y_t{tmg^S6&K5Fv$$|%Gf&<5_^i)_>~5y z0}Rj_olTQ8W^yjU-=$fEphy#>fpJNADN8U#6YK^?8;iCcx&W;@2+KV|V|ACHXxFo% z+kYah&V1)d?0!<=O~7T1of5N~xeF(;^p-az_w?1G8gihcg<|abv*qKx^H7RY4|(W0 z>_X{EapAbt`8=wJ!6;+S&@Fb+&9rn6fewf2CSd~xtHA@GDf}yL)+b|+<}JiESZy9u z(_i>MNaw+G75>hJ{5jJ3c(nR6#GsqpU-&dqo93g}7Vga8zK2vbDv>JuuMF-Xq)vkZ zslo>`xGy7hp3r?MgG(TFtl)0W;9^KQST958CM2QrVf}@xky;&XtcI$eMY5c^cV=?i zv$;1(ZmO{GF01pqUuG?+%iBoldi)V7sE3D!ay~3ovCoXaD*`v~+f>X)0k;pcA-1(4 z>aTbVv>=v_-e2*ghITQ+YJRtgA2#tG6Awz7#?dDiz3ep3O=RxxD92WVf4UzdUXt9dcS>bYW#At18A0jHStKl?oQtJ5Z-)#j z6zJSWaotS!O8#w7BL^#@;$G~>z~Ed1Z12NV@-dd5Sr^KAtpI#2Zi1V9`a%1fl#s!6 zhLkgygZUCL&*xxxGU`cSdLBUuTF5_Ofu24ADdBa3F9}HY-x3@Vkh}u`oeOc(>b!&- zIp?of;5$u7_43Jgw;vVI4Y=_~)XX-ZoGo+~gBSJLjoqK!`T=YF2ploojl1=h-6Fs_ z9;yvtquMZ*YwX8Zh0fM4c_P+5y%epBf|T>UXNm9Vf@9%i8pxDBnWgu43?PGqpz)8P z`JdfF)0U;_8qsn#q5tawp3*eFzgamuSe7%J+tU3VA@m;+-``P-q<>+t8af0Wk$BC& z8a2jnEI3yND`&;f-$zFmY(ElC?Fq5iF-W;wWfcq5RL+-PK~b-vXy@-xELrhbqV+Lj zHq28uU}!L;8xE8nCl&0}`W^W0`_P{c`ktB4yH^(WvtUCl+nk1*yPf##U2zi%lF==P z5&*bY_sPOF7yHx@{NJY$Qz{(g<4D#dJAQ#N0O;EqdXdoMg_{6vl)+AEagPk170?;;B%_mah>R=2_RfR#oX^6@Io7E(7VKV@Yurg9Lz=*u3y)$n z=vT|5zSaHyNpPZdI2qTt#@E>IpAw0OtFW|au09^_P5fGVB|1hgx6_>s6vd}jiPiyg zR-kpjK=b?AduIO{p5k}7tZ&a%FTfp%)UzeEN3nS&U0GDHas}O&fa}(ZX?|ELmFN; z!gt|E5*1J8rB*$OAbPT31dg^UQ`!_~$y`fdbIu zZOO~%@r7JH-rbee<0R-IN6E%(sCn9XeLy>A{aI66!sR@pjmrH)@=I*P`wViGUS}xn^dSL=Ic9B>j)7YL) zH~DGNi~Z4=&pjy|d4Xfi87yZ}P~oNuJy@^|5Q6R5@$y31p?%OUTcOucJyhsy_D|Un9&Z$#^AtD_+@9PBdFNL2#eL`ybUZ0M#v$9fKS3DwCh_`S z@)i=2Jo{8;kX;kbb5OP1gE?aF8JIE7|Hn-?a>4ye0HDvj*U;u1Lz5IICZIB;Sh-Z8pQ(ynH@EKkBNxke9ECpAU$F~$(BjPZ7J={ll36}1 zrLn+D|D7Wu*%88^3Z%X!ky)6Q(#T1TO6_2d^8j1LWEUbEFBXvR=3QJFe>!`wI?S?? zJ8Ic`liRo;09O;D?pEaJnIX~#Y)Y06Jk#vkh+%e!?g|}~pm?e<3{?{&zTz*wjrAfn zR$09ahu_CZ1pTJ{zme-k^A#tP^`s{Y9cv+W3~?7F$KN}CIaXrk8M`0qW+r|DnQ4jJ zdWn(Z>n?DY>YmX!sxzzva#)ixz=u9&Mmkr>IfBYlg>?&kbV=^5knJ*nQg_oiIPCwa z!bPCM{d=l#J`#Aynk<}+MEW7v3HvL^NpmTekzMJ-8CFQm%)#@Vn_=(lA+w1oahyn+ zujgy<@KQ6UhRtWN->2W-mPI(f|zmb0eFm^HX_Qu4I>RrS4{l z%aYFol0S7?VW$K-^ZQi^-MV8j2WEDB41NLQVN{n21-MQoPO>^@R$l*(NTm_VvnTZSCr8iAW72a{- zgk78T&NaR4+O?pP9vvik)(V?xg`pl-SCdrkN;Y%9un){~Gki2A7X?W`4#w}Xc7zhWz5vdxq?ef3MReF>*L zF>=s#zaSap3=hrlaA6k_h4fP>%NyndG&I{tE$%S_*8PZ>XEJ5t$)pIB^D<-sIB08t z^KXTq#9J?z(99NfH|5I>yx#e%+d(JD^ZI6A0C!Y;U7jI5KwUaJ24z0PO$em158-~Z zn*s-k$mB!&PE2#HZ}l9S*%tgY=s4Yl2l_j9L&{H{d+xdZj^~g<;yJV$k%4z#wKgq$wP4W>{{Pn&>!$=<5;!)`1 zoY_q+_Txqj#CW3y*US!^AE%IadyTRZvU0XV@e&2*J6L41crvU`OW^zZ;7E3j(EM@;QeLmL#T=hu zyurnIFnPe6)CZnSAqz9KmE+PL&iWYIBQmt5E?T!jyR!=EuA%Fl-3A`oo~^f=aZi?U zkV#YGF_{t{oq*BFGIAx+i$CT3kj=v*hNvv>FS(6+IRu!cO{!v-Yp3pEN=WXYN5KMw z-q&pC4NXqqg?w!37vD4|_1S%x!ARrqJ0kS#;iq}%F+?^bak5d8W_8+v&tJ&yhI0@4 zmOg$=(P%W;oKMMu$GO3q>67lGpPgR@Bj<4Xb>@0%F~^%}wshN^Y2KVBVQbywyayBH z2n^|*&CXk1o_RXwVdo`p&P<)N)!FKm7SK8Po`pB(DxK5k+~Cb=(>c4H)!v+1oipGB zygBQUBaRr0Nj4r9ljeIA^JcHzvb~%ev9O%OOpe7 z2URwQYQ!A!%3AULeR%RW&xt`lnBz$(?=r_%a@FklUe+A1<9=ViGO!z1wuw9Z<>?xR zvf|^~p^;L{lGUYy%aZk_4nDc_)9Lu+PBLCPyexS`>B!RLJAve9N-^=(m+ry0eC91k zjxJ69(m6;9D|`^dOHbalbm#tpOFQ<)kDdLeK=SFXK;nma%aX4xOTM!>IXZe+An|n3 z(sTCV{C(;(rA2{MeQC+ERCVdJWk~s!rQ)SCm!)nfEys6(=4nMazOD##equ4Co9_pm zBgv7`_@Twe0XI~H?+B#|c~2L$~IoNE^_+ns_HG1C(c$?YDTr1aglGv$};6s&8x{+acRYhCG&m0MOBR_#eMuJu@6kX zn!5VP{28&yHlLplo_Vqxqrb;H28S;N&u8JsPgdb*OMSJkF&g*j?>GZJIa?yXX`IWA z&-(@;)h8eR&CP0#)K8RE!H*#OmUG9qx!PBc&uF7)8eGhxmS47V>7oizsir=9ov$wD zt6JR{ZN_(wspEM0CbtpPpfCoKuRR;37PT}tM;hbx8+;3-2l%Av=SzXMJSgN7jl#8& z@LD!bJPHFqprwG3pv>aSKDFGV2e7LueXCpIKHsY4D^@LEzI6E#lH|zO+$L9uS1n(* zbonI<7A~t8Q^@kmR$RJZnaD8JS=zV`pT*e3h7Y6H#qs^@)m5=bFxHGud~b-U%(ud4o~)|REH5utv({BL&%&_aP^6V-saf%c zrdc9HV}h~ThG0`wymp+Nh{>TrXYs@8vruvlGm&NS^>H=3Y_7Y(uGD5XTC;m(J%SzN zr(_uTXhM(tjGe(@ESvj{bM!2+r>D0GZoXOx<6YMrg_)OD`uP2Bd_jBuNi$+6;luPM z@U40V&R`5HPWDUez3|m~h7Y3S>-8Uoj<48%7`j12hdnI`ldkleRBq(EH6(}+q6-w9{A_A~TjGWeZ;i&S~X6r9UtI_J~2t)rt`kiHA?F2vtP%y+8}e{^(o5{$YM zaVg>xu)JD~_%_7Vh%d%EsU7iZ#9I(IWBIfT@f57>_abgW%#GY8+z*u^Ui<^_Bkn_7 zjo619x^~2Eh_@gfM7#^}H?cXf7qPz={F9Wr7jY@#&3)iUJP&U{RU>`@o1pE8n{kuA z1@WDTcOgCikBaspF2y6DNrhOFA}&RI-fr+Cei3ms;_u)LPdnlhaT0M0;+I|oKVs)s z;Aj4?!GC~KU%{iGQp9Dy1wZ1eUIRbk!~YCE#4jS=g?MBbe2DkF3BCiB+VU3o5bt^$ ze2A;x9UZ*^aUAhoh;c$tLf-Y2%T}no^(6-u)E@0u1qD+MEb4;&nO};()292?VTe&B zr4~#rxix>$!6-)Z7bE7mjUy0`mtPJ1mB_yq^2W<=M}FTY{K`K8{}$lYv3~XZ1pK>@ z{rqu$`P%My^7kVDET3QXAs#P(66C&vd>(WkFTWJ|Q;+wn;t9%M4E(Vt_|-iVkx_ScsEy%ygyVVvJs=2u^zKz=Fmk1h8r-vsg(BmV;A$0p#fM*gF-{pu4FilwUwejMwN8+~3;7Q6@0lQfFY@`M^OqQ~GiNNxA;jgL6ukIWt z|8No^# zfNw?>e+F~ZP3?yd9-%gVoO?YVg^w)okp(`oz(*GN$O0c(;3ErsWPy(?@R0>RvcUf< z3*bSk1Y4dLws_tuF?eJB^e2m7uE{cVpD_%UugwGB=7IU!j0{tBl==PHgAHtdclPb~ zMx#Xe^ZmH;7b0~CP4-Iyx9$?!^8FIq2L{|bV8E@fglQ(`UYt7^GBxv-kf7~7pU>RS z+51F$d&j*n27j?%Vv8>^aFJlMzx8&Ifo=JC9xnCinyUHH4gyaybl9d8c<;eF-=P1W zMKjw%U5oO zEXuvlh5qV&vhi!p@}s)%NAkXTu?QZ<{tF?p4o}Sg1^$-mrlx4~KQCe2N5lUg^vU6O zKS2JFGR%W*{5Ceuhv3=!hh)o;$uBJb)7&_Vgu@U20=wp~uWP{1VEM7M=9bMa zo8y~PUVirM*>mRlX0E{Rhi}l>)921P`6Jr0IsdD6ScZL;Mjx|s#q;^vXhURHRZ~-a9ezx{ zF4`EIg`cxuTeT(agAtZ;L@uI!3`N{Glj z9Y6U_K??oVx8MrjoU+;TR9>4_^iZf{{Ce}8~+y+%{xSu9I)zuf}&%JW)$(4 zW7Sy91Hk61Pctv??^6%PHILTEU*5k|C#8(_r7aK2x4o-ia^58^=g%s?Bp?1DPaTwR zyIH}syi4*6HO_Xmg3`SFNkDz!e^W_X-Y99i?9mzRY^NWiyU! z#p=vBu$9^u_FEA-u~(i|X1(FJs=PA+zbcDuXoy#>MjUU}aji|snxRRR;V5OKY{9~% zr^l<-sIoPUEoHS;v07DDy`d4zI*vE%oOO}r7)D$U5JVnMQdW_{q?+pEs;mxY?o?Sk zg7a==H2{zot*(k!sj^6Ium&ggBEi~f@LC8$!{K0LeK^t-4?@@ah$;)?)LslK=;+!o z$WcmF1E$@wHBku0rA$iGl2^w-9ga3Ma9LPZ9a-J7CRo*6)d=5U!Metps7+U`Ufqln zw}!C3t`S9QCc~4{82^QXQc+= z6DWJ}`r+BgdI$HmmfxT62S(w(ULyI#3{#fR-bd?P{hQ&um$&?F`F=o3wHd^qxe*sX z0=(s)CR9o-LR^49%WwA<1Cj?iUzxJ?1Qc_!9hK3}p1T_vd@fhQ-5%*6MG|vGG;N z=e@s$?frk(RL$6C_^Cf-Sp5xJadAex<+u9{CB>Se+z{IGEx)b*=REv&|H5zh?S2RO zX=gA0=YeCNu=_36e}p~`B!VqRL)mt;FmJBh{MK)*H~a%ual>H25(D4t;jc7)tdboY zVN*cI_GW8$1xv+egXV6k=5Vs zbImmT^2QAEIsOL5E*WMyWcp|@UOQW!w9f^ zHcor^H@Am`a&x<8X!mp&pGIe{e@2S3Z2kSokmQvnB~nFK>eya=Heuqo5L16|u>7}s zGCiRB2N=CL%G!FHme{4E%++hpDPSIt-=ESfD?FJVP)(bF|IXVre`%&%lD7TDuB1N>kM~h0W|UF``su>7r<+` z<@+V=z7$|ohbE7QKS0@eJeU4JW#{Kye37#AZZ7_y%=3U;{N&7Yja>Z4l%4-_@l%wY z*K+X(<9kVdH%ih43bU4-hg`V@s#w|i#f65|N|c>9a`A^?9`L(Sk}goVjcf~zgFj4J z|Lx8!P=_n)mviw)DC=)?@gIl(47pK~F2IRn>mS{j1z2TRzn6j0`-ZpNWmXF0sgo#c#elj>Wwjb*c@l$;W;1Y&-3;SwQ|M#hX&7c^bB_Ys>Dd6WW32yBT=Ko8dfz=eceMp6zC+F?gQmX1G_bct6D8d5)W*Rjx`U44&t=8Sas* zQr|Urp4(>N*=+{COHDiQH!&Dy%2lbS1V2rkVC(=;!fqpn=erqr#+%_~gXg(!2A=I^ z_zUoP@VETrE5pNv{_lc6N-0yWU54csX#3drz<9=*;V9t8>u)m+J^U8Hw>|ARoh|g!)S$WV@Ix-cJm7tj%DpU^0RL%^ ze0$%};K9Fc#IJJF$a_dE_iA1c{$lWazlwqTLktICAH;2kS3$>6=D}OLEdl-z*E-g8 zD|Mydk5c@)wgi(A^2k}Bb5*n8r^x$YME%0x`CbP73Ez`p;JY#mT^>2lYP5O~c-p7W z*oU8eX80EHCFA(3$2@Z0;f)f)fCq2eeXroB$a`<3tL6paJrBLP9aBf5!&860hsI$2 z$ti*tlw9onV+0q}?9PgOXt`y=2JoJZ1 zsqkaKm*764)aq~WKQ?msJ}Lw69~ge`kz=~E`kSHW`-2R8hmhew3{1D(j@M{)j0gX+ z!O!yG*BSgpz>A%~6w(-D&&xdYwjZtrp7jctb(9gK)(HI+dC!tK+yAfk$T`5wr+0Yp z-!y_A^5AW|Jnq3SGW0+8;O+LtUf@};?WRANYT+}}xpuSiM?Lu2M*g&q>2b~X*BIm- zHpDXpFDSXJG0F2i_y-LBawCWDaWYuHz1l+`HtoC4gP#t+!|)Xk{zZ*e-}c~b|LF#P zyneV7_(R|)``SYy!P=+a$l*)W4ELK1N9ZvgJ41rU;#k5PhF(KTwVA{u+)~mX^1VR@ zd3O-;F@hJATcKA^0isek4)PnR916@s54 z@0pX-Z|K*0=xu+#(Sx^Tbs0H)-;{yxoHE=k__6z7_j%+TtI3t(!`ia2M0{3@WVoun zKDY)4%!2Y=5=BfEMRK7ca_W@wsiVu6ljhS+nQP z!Iyg)n(8C*NHxK7@Kr~HYwDw`tLlUDfHzpxvR>&2!__Sf4I6AZ70VY(F&C{^aA`%* zLM+Cnvx4M-u?T9w*(~aM_3X3thk}A~ST4wK`Bct6qpmR=ZR=qi zELOgA^FEcBElRVsC#dB-b`E|hsj{we_F2IoKVwsea-k2Zjxr2EZ9`?{JX_=ODW#f_ zR7cHbRes7rY_D_ zm*T4GtC|~RWHdEL#9UR)%~c!B&G!4bBhSqM`Mv(RCP2?uAm+fXs~%0_F{PN@Re>V zpLF8KpEQk^`bT*X|Dpa^y2Z0A;BJ>*hAQJ*Wx*EoAxwDauJW}oe&{Y& zW17GekFrG{u^f5UVHS*ddcWyzuJN4vsjpn=P2-FomZ;Brvlr#M)3NngB=y1cVU)y& z&%{Qt@rF8vNOQQhIai0Oc(gtj12Xy0;2112Jh-|w{0ySkD}ZjyNW?NC77f;7#>0Uz zICD(dxw7iV4mY!8vCD^yH=|=!=s@gFoD4mJFxg6L!Y78CJVQ`E42NTKRMBe*{aLD9 zVQAs1>Rc2WXb!wocERCZKLla9#%K^@SjggGsBa$NKWC z&z1>b&2=1dP~Pi6i1Svqv8pi|tB*uHzJ^n&7>G^pX$3v+x%yK?_ote1dMb)+98)HQ zM?K}$#bP-5JEoPea%B$>dioSbKaa{+g~M1r<=PLniSUDu<5)+#GcNx)J7ne{v&O2A zMw?^>5Rc|cm)>&pH9MOR&gVRU=7wfwXS8C z3a)Crj?QyMB-SD$V$q`D8D&_$Up@OQ;~QihJ>I&S&JvAT!{+c*o!#;hC*UD;4TMM(#7<;ueRK+|d