Monitor the datanetwork for non-OpenStack work node

Update the lmon to support datanetwork interface monitoring
and use collectd to control the alarm information. Now lmon
will obtain the list of interfaces from /etc/lmon/lmon.conf
which can be generated by puppet.

Change-Id: Ice72eda03d1bbdee6c644b1ed7ab878c942eb85c
Story: #2002948
Task: #37326
Signed-off-by: marvin <weifei.yu@intel.com>
This commit is contained in:
marvin 2019-11-19 15:26:03 +08:00 committed by marvin Yu
parent cdabacd300
commit 6ccd0f4a43
3 changed files with 246 additions and 198 deletions

View File

@ -25,8 +25,9 @@ using namespace std;
#define INTERFACES_DIR ((const char *)"/sys/class/net/")
#define PLATFORM_DIR ((const char *)"/etc/platform/platform.conf")
#define LMON_DIR ((const char *)"/etc/lmon/lmon.conf")
#define INTERFACES_MAX (3) /* maximum number of interfaces to monitor */
#define INTERFACES_MAX (4) /* maximum number of interfaces to monitor */
enum interface_type { ethernet = 0, vlan = 1, bond = 2 };
string iface_type ( interface_type type_enum );
@ -56,11 +57,13 @@ typedef struct
#define MGMT_INTERFACE_NAME ((const char *)"mgmt")
#define CLUSTER_HOST_INTERFACE_NAME ((const char *)"cluster-host")
#define OAM_INTERFACE_NAME ((const char *)"oam")
#define DATA_NETWORK_INTERFACE_NAME ((const char *)"data-network")
/* name labels used in platform.conf */
#define MGMT_INTERFACE_FULLNAME ((const char *)"management_interface")
#define CLUSTER_HOST_INTERFACE_FULLNAME ((const char *)"cluster_host_interface")
#define OAM_INTERFACE_FULLNAME ((const char *)"oam_interface")
#define DATA_NETWORK_INTERFACE_FULLNAME ((const char *)"data_network_interface")
/* true if the interface is configured.
* i.e. the name label shown above is found in platform.conf */
@ -95,7 +98,13 @@ void lmon_learn_interfaces ( int ioctl_sock );
/* lmonUtils.cpp */
FMTimeT lmon_fm_timestamp ( void );
int lmon_interfaces_init ( interface_ctrl_type * ptr );
int lmon_interfaces_init ( interface_ctrl_type * ptr,
string physical_iface_name );
int lmon_get_link_state ( int ioctl_socket,
char iface[IF_NAMESIZE],
bool & link_up );
string get_interface_fullname( const char * iface_name );
int read_the_lmon_config ( string iface_fullname,
string& physical_interface );
void set_the_link_state ( int ioctl_socket,
interface_ctrl_type * ptr );

View File

@ -13,17 +13,19 @@
#include "lmon.h"
#include <linux/rtnetlink.h> /* for ... RTMGRP_LINK */
#include "nodeMacro.h" /* for ... CREATE_REUSABLE_INET_UDP_TX_SOCKET */
#include <vector>
#define HTTP_SERVER_NAME ((const char *)"link status query")
static lmon_ctrl_type lmon_ctrl ;
static interface_ctrl_type interfaces[INTERFACES_MAX];
static vector<interface_ctrl_type> interfaces;
static const char * iface_list[INTERFACES_MAX] = { MGMT_INTERFACE_NAME,
CLUSTER_HOST_INTERFACE_NAME,
OAM_INTERFACE_NAME };
OAM_INTERFACE_NAME,
DATA_NETWORK_INTERFACE_NAME };
/* httpUtil needs a mtclog socket pointer */
msgSock_type * get_mtclogd_sockPtr ( void )
@ -168,7 +170,7 @@ void lmonHdlr_http_handler (struct evhttp_request *req, void *arg)
/* loop over the interfaces and build a response string for each
* of those that are used */
for ( int i = 0 ; i < INTERFACES_MAX ; i++ )
for ( unsigned int i = 0 ; i < interfaces.size() ; i++ )
{
if ((interfaces[i].used == true) && (interfaces[i].name[0] != '\0'))
{
@ -347,51 +349,37 @@ void lmon_learn_interfaces ( int ioctl_socket )
/* initialize interface monitoring */
for ( int iface = 0 ; iface < INTERFACES_MAX ; iface++ )
{
interfaces[iface].name = iface_list[iface];
lmon_interfaces_init ( &interfaces[iface] );
string physical_interface = "";
string iface_fullname = get_interface_fullname(iface_list[iface]);
if ( interfaces[iface].used == false )
continue ;
if ( iface_fullname.empty() )
continue;
/* set the link state for all the primary physical interfaces */
if ( lmon_get_link_state ( ioctl_socket,
interfaces[iface].interface_one,
interfaces[iface].interface_one_link_up ) )
int rc = read_the_lmon_config(iface_fullname, physical_interface);
if( rc != PASS)
continue;
char * physical_iface_name = strtok(const_cast<char*>(physical_interface.c_str()), ",");
while (physical_iface_name != NULL)
{
interfaces[iface].interface_one_event_time = lmon_fm_timestamp();
interfaces[iface].interface_one_link_up = false ;
wlog ("%s interface state query failed ; defaulting to Down\n",
interfaces[iface].interface_one) ;
}
else
{
interfaces[iface].interface_one_event_time = lmon_fm_timestamp();
ilog ("%s is %s\n",
interfaces[iface].interface_one,
interfaces[iface].interface_one_link_up ?
"Up" : "Down" );
interface_ctrl_type iface_item;
memset (&iface_item, 0, sizeof(iface_item));
if ( interfaces[iface].lagged == true )
iface_item.name = iface_list[iface];
// Map an interface name to a physical port.
// interface type: ethernet, bonded or vlan
lmon_interfaces_init ( &iface_item, physical_iface_name );
if ( iface_item.used == true )
{
/* set the link state for all the lagged physical interfaces */
if ( lmon_get_link_state ( ioctl_socket,
interfaces[iface].interface_two,
interfaces[iface].interface_two_link_up ) )
{
interfaces[iface].interface_two_event_time = lmon_fm_timestamp();
interfaces[iface].interface_two_link_up = false ;
wlog ("%s lag interface state query failed ; defaulting to Down\n",
interfaces[iface].interface_two) ;
}
else
{
interfaces[iface].interface_two_event_time = lmon_fm_timestamp();
ilog ("%s is %s (lag)\n",
interfaces[iface].interface_two,
interfaces[iface].interface_two_link_up ?
"Up" : "Down" );
}
// initial up/down state
set_the_link_state(ioctl_socket, &iface_item);
interfaces.push_back(iface_item);
}
physical_iface_name = strtok(NULL, ",");
}
}
}
@ -423,7 +411,7 @@ int service_interface_events ( void )
return RETRY ;
}
for ( int i = 0 ; i < INTERFACES_MAX ; i++ )
for ( unsigned int i = 0 ; i < interfaces.size() ; i++ )
{
if ( interfaces[i].used == true )
{
@ -622,7 +610,7 @@ void lmon_query_all_links( void )
{
dlog1 ("audit timer fired");
for ( int i = 0 ; i < INTERFACES_MAX ; i++ )
for ( unsigned int i = 0 ; i < interfaces.size() ; i++ )
{
if ( interfaces[i].used )
{
@ -703,7 +691,6 @@ void daemon_service_run ( void )
lmon_ctrl.ioctl_socket = 0 ;
lmon_ctrl.netlink_socket = 0 ;
memset (&lmon_ctrl.mtclogd, 0, sizeof(lmon_ctrl.mtclogd));
memset (&interfaces, 0, sizeof(interfaces));
get_hostname (&lmon_ctrl.my_hostname[0], MAX_HOST_NAME_SIZE );
mtcTimer_init ( lmon_ctrl.audit_timer, lmon_ctrl.my_hostname, "audit");

View File

@ -191,168 +191,126 @@ int lmon_get_link_state ( int ioctl_socket,
*
*****************************************************************************/
int lmon_interfaces_init ( interface_ctrl_type * ptr )
int lmon_interfaces_init ( interface_ctrl_type * ptr, string physical_interface )
{
FILE * file_ptr;
char line_buf[MAX_CHARS_ON_LINE];
string str;
string physical_interface = "";
/* iface enum to pltform.conf iface name */
if ( strcmp(ptr->name, MGMT_INTERFACE_NAME) == 0 )
str = MGMT_INTERFACE_FULLNAME;
else if ( strcmp(ptr->name, CLUSTER_HOST_INTERFACE_NAME) == 0 )
str = CLUSTER_HOST_INTERFACE_FULLNAME;
else if ( strcmp(ptr->name, OAM_INTERFACE_NAME) == 0 )
str = OAM_INTERFACE_FULLNAME;
/* determine the interface type */
string uevent_interface_file =
INTERFACES_DIR + physical_interface + "/uevent";
ifstream finUevent( uevent_interface_file.data() );
if (!finUevent)
{
elog ("Cannot find '%s' ; unable to monitor '%s' interface\n",
uevent_interface_file.c_str(), ptr->name );
ptr->used = false;
return FAIL_OPERATION ;
}
else
{
slog ("%s is an unsupported iface\n", ptr->name );
return (FAIL_BAD_PARM);
}
/* open platform.conf and find the line containing this interface name. */
file_ptr = fopen (PLATFORM_DIR , "r");
if (file_ptr)
{
ifstream fin( PLATFORM_DIR );
string line;
while ( getline( fin, line ))
ptr->type_enum = ethernet;
while( getline( finUevent, line ) )
{
/* does this line contain it ? */
if ( line.find(str) != string::npos )
if ( line.find ("DEVTYPE") == 0 )
{
stringstream ss( line );
getline( ss, physical_interface, '=' ); // string before
getline( ss, physical_interface, '=' ); // string after
plog ("%s is the %s primary network interface",
physical_interface.c_str(),
ptr->name);
/* determine the interface type */
string uevent_interface_file =
INTERFACES_DIR + physical_interface + "/uevent";
ifstream finUevent( uevent_interface_file.data() );
if (!finUevent)
{
elog ("Cannot find '%s' ; unable to monitor '%s' interface\n",
uevent_interface_file.c_str(), ptr->name );
ptr->used = false;
fclose(file_ptr);
return FAIL_OPERATION ;
}
else
{
string line;
ptr->type_enum = ethernet;
while( getline( finUevent, line ) )
{
if ( line.find ("DEVTYPE") == 0 )
{
if ( line.find ("=vlan") != string::npos )
ptr->type_enum = vlan;
else if ( line.find ("=bond") != string::npos )
ptr->type_enum = bond;
break;
}
}
}
switch (ptr->type_enum)
{
case ethernet:
{
memcpy(ptr->interface_one,
physical_interface.c_str(),
physical_interface.size());
ilog("%s is a %s ethernet interface\n",
ptr->interface_one, ptr->name );
break;
}
case bond:
{
memcpy(ptr->bond,
physical_interface.c_str(),
physical_interface.size());
ilog("%s is a bonded %s network interface\n",
ptr->bond, ptr->name);
break;
}
case vlan:
{
/****************************************************
*
* If it is a VLAN interface, we need to determine its
* parent interface, which may be a single ethernet
* link or a bonded interface.
*
****************************************************/
string parent = get_iflink_interface(physical_interface);
if (!parent.empty())
{
string physical_interface_save = physical_interface ;
physical_interface = parent;
string uevent_parent_file =
INTERFACES_DIR + parent + "/uevent";
ifstream finUevent2( uevent_parent_file.c_str() );
string line;
bool bond_configured = false;
while( getline( finUevent2, line ) )
{
// if this uevent does not have a DEVTYPE
// then its a ethernet interface. If this
// does have a DEVTYPE then check explicity
// for bond. Since we don't allow vlan over
// vlan, for all other DEVTYPEs, assume
// this is a ethernet interface.
if ( (line.find ("DEVTYPE") == 0) &&
(line.find ("=bond") != string::npos) ) {
ilog("%s is a vlan off the %s network whose parent is %s\n",
physical_interface_save.c_str(),
ptr->name,
parent.c_str());
bond_configured = true;
break;
}
}
if (!bond_configured)
{
ilog("%s is a vlan off the %s network whose parent is %s\n",
physical_interface.c_str(),
ptr->name,
parent.c_str());
memcpy(ptr->interface_one,
parent.c_str(),
parent.size());
}
}
else
{
ilog("%s is a vlan %s network\n",
physical_interface.c_str(), ptr->name);
}
break;
}
} // end of switch
if ( line.find ("=vlan") != string::npos )
ptr->type_enum = vlan;
else if ( line.find ("=bond") != string::npos )
ptr->type_enum = bond;
break;
}
}
fclose(file_ptr);
}
switch (ptr->type_enum)
{
case ethernet:
{
memcpy(ptr->interface_one,
physical_interface.c_str(),
physical_interface.size());
ilog("%s is a %s ethernet interface\n",
ptr->interface_one, ptr->name );
break;
}
case bond:
{
memcpy(ptr->bond,
physical_interface.c_str(),
physical_interface.size());
ilog("%s is a bonded %s network interface\n",
ptr->bond, ptr->name);
break;
}
case vlan:
{
/****************************************************
*
* If it is a VLAN interface, we need to determine its
* parent interface, which may be a single ethernet
* link or a bonded interface.
*
****************************************************/
string parent = get_iflink_interface(physical_interface);
if (!parent.empty())
{
string physical_interface_save = physical_interface ;
physical_interface = parent;
string uevent_parent_file =
INTERFACES_DIR + parent + "/uevent";
ifstream finUevent2( uevent_parent_file.c_str() );
string line;
bool bond_configured = false;
while( getline( finUevent2, line ) )
{
// if this uevent does not have a DEVTYPE
// then its a ethernet interface. If this
// does have a DEVTYPE then check explicity
// for bond. Since we don't allow vlan over
// vlan, for all other DEVTYPEs, assume
// this is a ethernet interface.
if ( (line.find ("DEVTYPE") == 0) &&
(line.find ("=bond") != string::npos) ) {
ilog("%s is a vlan off the %s network whose parent is %s\n",
physical_interface_save.c_str(),
ptr->name,
parent.c_str());
bond_configured = true;
break;
}
}
if (!bond_configured)
{
ilog("%s is a vlan off the %s network whose parent is %s\n",
physical_interface.c_str(),
ptr->name,
parent.c_str());
memcpy(ptr->interface_one,
parent.c_str(),
parent.size());
}
}
else
{
ilog("%s is a vlan %s network\n",
physical_interface.c_str(), ptr->name);
}
break;
}
}
/* Lagged interface */
@ -411,5 +369,99 @@ int lmon_interfaces_init ( interface_ctrl_type * ptr )
return (PASS);
}
void set_the_link_state( int ioctl_socket, interface_ctrl_type * ptr ){
/* set the link state for all the primary physical interfaces */
if ( lmon_get_link_state ( ioctl_socket,
ptr->interface_one,
ptr->interface_one_link_up ) )
{
ptr->interface_one_event_time = lmon_fm_timestamp();
ptr->interface_one_link_up = false ;
wlog ("%s interface state query failed ; defaulting to Down\n",
ptr->interface_one) ;
}
else
{
ptr->interface_one_event_time = lmon_fm_timestamp();
ilog ("%s is %s\n",
ptr->interface_one,
ptr->interface_one_link_up ?
"Up" : "Down" );
if ( ptr->lagged == true )
{
/* set the link state for all the lagged physical interfaces */
if ( lmon_get_link_state ( ioctl_socket,
ptr->interface_two,
ptr->interface_two_link_up ) )
{
ptr->interface_two_event_time = lmon_fm_timestamp();
ptr->interface_two_link_up = false ;
wlog ("%s lag interface state query failed ; defaulting to Down\n",
ptr->interface_two) ;
}
else
{
ptr->interface_two_event_time = lmon_fm_timestamp();
ilog ("%s is %s (lag)\n",
ptr->interface_two,
ptr->interface_two_link_up ?
"Up" : "Down" );
}
}
}
}
int read_the_lmon_config( string iface_fullname, string& physical_interface){
FILE * file_ptr;
file_ptr = fopen (LMON_DIR , "r");
if (file_ptr)
{
ifstream fin( LMON_DIR );
string line;
while ( getline( fin, line ))
{
/* does this line contain it ? */
if ( line.find(iface_fullname) != string::npos )
{
stringstream ss( line );
// Config file Format like
// ....
// management_interface=ens7
// cluster_host_interface=ens7
// ...
getline( ss, physical_interface, '=' ); // get string before "="
getline( ss, physical_interface, '=' ); // get string after "="
plog ("%s is the %s primary network interface",
physical_interface.c_str(),
iface_fullname.c_str());
fclose(file_ptr);
return (PASS);
}
}
fclose(file_ptr);
}
return (FAIL);
}
string get_interface_fullname(const char * iface_name){
string iface_fullname = "";
if ( strcmp(iface_name, MGMT_INTERFACE_NAME) == 0 )
iface_fullname = MGMT_INTERFACE_FULLNAME;
else if ( strcmp(iface_name, CLUSTER_HOST_INTERFACE_NAME) == 0 )
iface_fullname = CLUSTER_HOST_INTERFACE_FULLNAME;
else if ( strcmp(iface_name, OAM_INTERFACE_NAME) == 0 )
iface_fullname = OAM_INTERFACE_FULLNAME;
else if ( strcmp(iface_name, DATA_NETWORK_INTERFACE_NAME) == 0 )
iface_fullname = DATA_NETWORK_INTERFACE_FULLNAME;
return iface_fullname;
}