From 79d1833a88814667799e2067f5153addc8ae5d78 Mon Sep 17 00:00:00 2001 From: Avinash Kumar Date: Wed, 14 Sep 2016 19:11:48 -0700 Subject: [PATCH] @3526390 backport MP changes --- Makefile.am | 2 +- PrintProfilesAndExit.cpp | 76 ++++++++++++++++++++ build.sh | 15 ++-- eos/inline/sdk.h | 149 ++++++++++++++------------------------- sdk.cpp | 11 +++ 5 files changed, 152 insertions(+), 101 deletions(-) create mode 100644 PrintProfilesAndExit.cpp diff --git a/Makefile.am b/Makefile.am index afb9dbda..e9a95c21 100644 --- a/Makefile.am +++ b/Makefile.am @@ -7,7 +7,7 @@ AM_LDFLAGS = -Wl,--no-undefined PUBLISHED_HEADER_FILES := $(wildcard eos/*.h) $(wildcard eos/inline/*.h) $(wildcard eos/types/*.h) $(wildcard eos/inline/types/*.h) nobase_include_HEADERS = $(PUBLISHED_HEADER_FILES) -EXTRA_DIST = $(wildcard examples/*) $(wildcard examples/test/*) +EXTRA_DIST = PrintProfilesAndExit.cpp $(wildcard examples/*) $(wildcard examples/test/*) libeos_la_SOURCES = libeos_la_SOURCES += agent.cpp diff --git a/PrintProfilesAndExit.cpp b/PrintProfilesAndExit.cpp new file mode 100644 index 00000000..4561fd47 --- /dev/null +++ b/PrintProfilesAndExit.cpp @@ -0,0 +1,76 @@ +// Copyright (c) 2014 Arista Networks, Inc. All rights reserved. +// Arista Networks, Inc. Confidential and Proprietary. + +// To facilitate the making of customized sysdb-mount-profiles (in place of the +// brute-force one "EosSdk", see /usr/lib/SysdbMountProfiles/EosSdkAll), an app can +// be started with the env var EOS_PRINT_PROFILES_AND_EXIT pointing to a filename +// where the profile should be written, then exit. +// We are not printing directly (prevents dups, agent name is only known late, some +// debug prints might interfere) so we first insert the profiles into a map. +// The collections of utilities we need for that purposes are defined here, under a +// static class in order not to overly pollute the eos space. They are declared in +// eos/inline/sdk.h. +// +// This code is included as a header file into both sdk.cpp and stubs/sdk.cpp + +// Initialize static class variables +FILE* print_profiles::print_profiles_fp = 0; // if and where to print +const char* print_profiles::eossdk_progname = 0; +std::map print_profiles::profiles_to_print; + +// Called in sdk ctor to figure out if recording of managers is needed, if so +// open the target file (its file-pointer will be used later to determine if we +// need to record). The sdk ctor has some complex logic to figure out the agent-name; +// we need that agent-name later when we print the profiles, so it is passed in here. +// (the agent-name is the basename of the executable, unless the AGENT_PROCESS_NAME +// env var is set, in which case it may actually be wrong -- we need basename(exe)). +void print_profiles::set_print_profiles(const char* name) { + if (getenv("EOS_PRINT_PROFILES_AND_EXIT")) { + print_profiles_fp = fopen(getenv("EOS_PRINT_PROFILES_AND_EXIT"), "w"); + if (!print_profiles_fp) { + const char* text = + "Error: EOS_PRINT_PROFILES_AND_EXIT must be a writtable file\n"; + fprintf(stderr, text); + exit(1); // r+2 because of warnings: discarded fprintf rcode + unused var + } + eossdk_progname = name; + } else { + print_profiles_fp = 0; + } +} + +// called from xxx_mgr_get() to record that this manager is used +void print_profiles::add_profile(const char * profile) { + if (print_profiles_fp) { + profiles_to_print[profile] = true; + } +} + +// called from main_loop() or get_event_loop(): at that point all managers must +// have been instantiated, so print the collected profiles and exit. +void print_profiles::write_profiles() { + if (print_profiles_fp) { + if (eossdk_progname) { + fprintf(print_profiles_fp, "agentName:%s\n", eossdk_progname); + } else { + // extern const char *__progname; would be to GNU specific... + char myExe[1000]; + if (readlink("/proc/self/exe", myExe, 1000) != -1) { + fprintf(print_profiles_fp, "agentName:%s\n", basename(myExe)); + } else { + const char* text = + "Warning: couldn't figure out agent name, edit 'TBD' in profile\n"; + fprintf(stderr, text); + fprintf(print_profiles_fp, "agentName:!!!TBD!!!\n"); + } + } + for (std::map::iterator it = profiles_to_print.begin(); + it != profiles_to_print.end(); it++) { + fprintf(print_profiles_fp, "Include: EosSdk_%s.include\n", + it->first.c_str()); + } + fclose(print_profiles_fp); + exit(0); + } +} + diff --git a/build.sh b/build.sh index 9197f8cd..fd4cef48 100755 --- a/build.sh +++ b/build.sh @@ -38,12 +38,19 @@ fi CXXFLAGS=$CFLAGS export CXXFLAGS +sysroot=$($(which gcc) --print-sysroot) || sysroot = "" +[ $sysroot -a ${sysroot%-glibc2.19} != $sysroot ] && { + LDFLAGS="-Wl,--dynamic-linker=$sysroot/lib/ld-linux.so.2 -Wl,-rpath,$sysroot/lib:/usr/lib:/lib" + export LDFLAGS +} + set -e test -f configure || ./bootstrap test -f Makefile || ./configure $configure_flags \ $configure_flags --program-prefix= \ - --prefix=/usr --exec-prefix=/usr --bindir=/usr/bin --sbindir=/usr/sbin \ - --sysconfdir=/etc --datadir=/usr/share --includedir=/usr/include \ - --libdir=/usr/lib --libexecdir=/usr/libexec --localstatedir=/var \ - --sharedstatedir=/var/lib --mandir=/usr/share/man --infodir=/usr/share/info + #--prefix=/usr --exec-prefix=/usr --bindir=/usr/bin --sbindir=/usr/sbin \ + #--sysconfdir=/etc --datadir=/usr/share --includedir=/usr/include \ + #--libdir=/usr/lib --libexecdir=/usr/libexec --localstatedir=/var \ + #--sharedstatedir=/var/lib --mandir=/usr/share/man --infodir=/usr/share/info + --prefix=$sysroot/usr exec make "$@" diff --git a/eos/inline/sdk.h b/eos/inline/sdk.h index 36cfd5ad..4b7c4a1b 100644 --- a/eos/inline/sdk.h +++ b/eos/inline/sdk.h @@ -7,83 +7,77 @@ #include #include +#define GET_MGR(__mgr__) \ + print_profiles::add_profile( #__mgr__ ); \ + if (! __mgr__ ## _mgr_) { \ + init_ ## __mgr__ ## _mgr(); \ + } \ + return __mgr__ ## _mgr_; \ + namespace eos { +// To facilitate the making of customized sysdb-mount-profiles (in place of the +// brute-force one "EosSdk", see /usr/lib/SysdbMountProfiles/EosSdkAll), an app can +// be started with the env var EOS_PRINT_PROFILES_AND_EXIT pointing to a filename +// where the profile should be written, then exit. +class EOS_SDK_PUBLIC print_profiles { + public: + static void set_print_profiles(const char* name); + static void add_profile(const char * profile); + static void write_profiles(); // will call exit() after printing + + private: + static FILE* print_profiles_fp; + static std::map profiles_to_print; + static const char* eossdk_progname; +}; + inline std::string sdk::name() { return name_; } inline acl_mgr * sdk::get_acl_mgr() { - if (!acl_mgr_) { - init_acl_mgr(); - } - return acl_mgr_; + GET_MGR(acl) } inline agent_mgr * sdk::get_agent_mgr() { - if (!agent_mgr_) { - init_agent_mgr(); - } - return agent_mgr_; + GET_MGR(agent) } inline aresolve_mgr * sdk::get_aresolve_mgr() { - if (!aresolve_mgr_) { - init_aresolve_mgr(); - } - return aresolve_mgr_; + GET_MGR(aresolve) } inline bfd_session_mgr * sdk::get_bfd_session_mgr() { - if (!bfd_session_mgr_) { - init_bfd_session_mgr(); - } - return bfd_session_mgr_; + GET_MGR(bfd_session) } inline class_map_mgr * sdk::get_class_map_mgr() { - if (!class_map_mgr_) { - init_class_map_mgr(); - } - return class_map_mgr_; + GET_MGR(class_map) } inline decap_group_mgr * sdk::get_decap_group_mgr() { - if (!decap_group_mgr_) { - init_decap_group_mgr(); - } - return decap_group_mgr_; + GET_MGR(decap_group) } inline directflow_mgr * sdk::get_directflow_mgr() { - if (!directflow_mgr_) { - init_directflow_mgr(); - } - return directflow_mgr_; + GET_MGR(directflow) } inline eth_intf_mgr * sdk::get_eth_intf_mgr() { - if (!eth_intf_mgr_) { - init_eth_intf_mgr(); - } - return eth_intf_mgr_; + GET_MGR(eth_intf) } inline eth_lag_intf_mgr * sdk::get_eth_lag_intf_mgr() { - if (!eth_lag_intf_mgr_) { - init_eth_lag_intf_mgr(); - } - return eth_lag_intf_mgr_; + GET_MGR(eth_lag_intf) } inline eth_phy_intf_mgr * sdk::get_eth_phy_intf_mgr() { - if (!eth_phy_intf_mgr_) { - init_eth_phy_intf_mgr(); - } - return eth_phy_intf_mgr_; + GET_MGR(eth_phy_intf) } inline eth_phy_intf_counter_mgr * sdk::get_eth_phy_intf_counter_mgr() { + print_profiles::add_profile("eth_phy_intf"); if (!eth_phy_intf_counter_mgr_) { init_eth_phy_intf_counter_mgr(); } @@ -91,6 +85,8 @@ inline eth_phy_intf_counter_mgr * sdk::get_eth_phy_intf_counter_mgr() { } inline event_loop * sdk::get_event_loop() { + // if setup (env) to display needed sysdb profiles, this will print them and exit + print_profiles::write_profiles(); if (!event_loop_) { init_event_loop(); } @@ -98,6 +94,7 @@ inline event_loop * sdk::get_event_loop() { } inline fib_mgr * sdk::get_fib_mgr(mgr_mode_type_t mode) { + print_profiles::add_profile("fib"); if (!fib_mgr_) { init_fib_mgr(mode); } @@ -106,20 +103,15 @@ inline fib_mgr * sdk::get_fib_mgr(mgr_mode_type_t mode) { inline hardware_table_mgr * sdk::get_hardware_table_mgr() { - if (!hardware_table_mgr_) { - init_hardware_table_mgr(); - } - return hardware_table_mgr_; + GET_MGR(hardware_table) } inline intf_mgr * sdk::get_intf_mgr() { - if (!intf_mgr_) { - init_intf_mgr(); - } - return intf_mgr_; + GET_MGR(intf) } inline intf_counter_mgr * sdk::get_intf_counter_mgr() { + print_profiles::add_profile("intf"); if (!intf_counter_mgr_) { init_intf_counter_mgr(); } @@ -127,20 +119,15 @@ inline intf_counter_mgr * sdk::get_intf_counter_mgr() { } inline ip_intf_mgr * sdk::get_ip_intf_mgr() { - if (!ip_intf_mgr_) { - init_ip_intf_mgr(); - } - return ip_intf_mgr_; + GET_MGR(ip_intf) } inline ip_route_mgr * sdk::get_ip_route_mgr() { - if (!ip_route_mgr_) { - init_ip_route_mgr(); - } - return ip_route_mgr_; + GET_MGR(ip_route) } inline intf_mgr_helper * sdk::get_intf_mgr_helper() { + print_profiles::add_profile("IntfMgrHelper"); if (!intf_mgr_helper_) { init_intf_mgr_helper(); } @@ -148,17 +135,11 @@ inline intf_mgr_helper * sdk::get_intf_mgr_helper() { } inline mac_table_mgr * sdk::get_mac_table_mgr() { - if (!mac_table_mgr_) { - init_mac_table_mgr(); - } - return mac_table_mgr_; + GET_MGR(mac_table) } inline mlag_mgr * sdk::get_mlag_mgr() { - if (!mlag_mgr_) { - init_mlag_mgr(); - } - return mlag_mgr_; + GET_MGR(mlag) } inline mount_mgr * sdk::get_mount_mgr() { @@ -169,45 +150,27 @@ inline mount_mgr * sdk::get_mount_mgr() { } inline mpls_route_mgr * sdk::get_mpls_route_mgr() { - if (!mpls_route_mgr_) { - init_mpls_route_mgr(); - } - return mpls_route_mgr_; + GET_MGR(mpls_route) } inline neighbor_table_mgr * sdk::get_neighbor_table_mgr() { - if (!neighbor_table_mgr_) { - init_neighbor_table_mgr(); - } - return neighbor_table_mgr_; + GET_MGR(neighbor_table) } inline nexthop_group_mgr * sdk::get_nexthop_group_mgr() { - if (!nexthop_group_mgr_) { - init_nexthop_group_mgr(); - } - return nexthop_group_mgr_; + GET_MGR(nexthop_group) } inline policy_map_mgr * sdk::get_policy_map_mgr() { - if (!policy_map_mgr_) { - init_policy_map_mgr(); - } - return policy_map_mgr_; + GET_MGR(policy_map) } inline subintf_mgr * sdk::get_subintf_mgr() { - if (!subintf_mgr_) { - init_subintf_mgr(); - } - return subintf_mgr_; + GET_MGR(subintf) } inline system_mgr * sdk::get_system_mgr() { - if (!system_mgr_) { - init_system_mgr(); - } - return system_mgr_; + GET_MGR(system) } inline timeout_mgr * sdk::get_timeout_mgr() { @@ -218,18 +181,12 @@ inline timeout_mgr * sdk::get_timeout_mgr() { } inline vrf_mgr * sdk::get_vrf_mgr() { - if (!vrf_mgr_) { - init_vrf_mgr(); - } - return vrf_mgr_; + GET_MGR(vrf) } inline lldp_mgr * sdk::get_lldp_mgr() { - if (!lldp_mgr_) { - init_lldp_mgr(); - } - return lldp_mgr_; + GET_MGR(lldp) } } diff --git a/sdk.cpp b/sdk.cpp index 9927174f..252eed76 100644 --- a/sdk.cpp +++ b/sdk.cpp @@ -3,6 +3,7 @@ #include #include +#include #include "eos/event_loop.h" #include "eos/sdk.h" @@ -66,6 +67,7 @@ sdk::sdk() name_ = agent_process_name; eossdk_context_ = NULL; impl.register_sdk(this); + print_profiles::set_print_profiles(name_.c_str()); } sdk::sdk(std::string const name, void *eossdk_context) @@ -102,12 +104,14 @@ sdk::sdk(std::string const name, void *eossdk_context) name_ = name; eossdk_context_ = eossdk_context; impl.register_sdk(this); + print_profiles::set_print_profiles(name_.c_str()); } void sdk::main_loop(int argc, char ** argv) { assert(!name_.empty() && "No agent name set"); impl.agent_name_is(name_.c_str()); + print_profiles::write_profiles(); impl.main_loop(); } @@ -174,4 +178,11 @@ void default_signal_handler(int signo) { void internal_connection_buffer_size_is(uint32_t bytes) { } +// Real functions to facilitate the making of customized sysdb-mount-profiles +// (to use in place of the brute-force one called "EosSdk", see +// /usr/lib/SysdbMountProfiles/EosSdkAll), an app can be started with the env var +// EOS_PRINT_PROFILES_AND_EXIT pointing to a filename where the profile should be +// written, then exit. +#include "PrintProfilesAndExit.cpp" + }