1
1
#include < cstring>
2
+ #include < algorithm>
2
3
3
4
#include < logger.h>
4
5
5
6
#include " teamdctl_mgr.h"
6
7
8
+ // /
9
+ // / Custom function for libteamdctl logger. IT is empty to prevent libteamdctl to spam us with the error messages
10
+ // / @param tdc teamdctl descriptor
11
+ // / @param priority priority of the message
12
+ // / @param file file where error was raised
13
+ // / @param line line in the file where error was raised
14
+ // / @param fn function where the error was raised
15
+ // / @param format format of the error message
16
+ // / @param args arguments of the error message
17
+ void teamdctl_log_function (struct teamdctl *tdc, int priority,
18
+ const char *file, int line,
19
+ const char *fn, const char *format,
20
+ va_list args)
21
+ {
22
+
23
+ }
24
+
25
+
7
26
// /
8
27
// / The destructor clean up handlers to teamds
9
28
// /
@@ -31,10 +50,11 @@ bool TeamdCtlMgr::has_key(const std::string & lag_name) const
31
50
}
32
51
33
52
// /
34
- // / Adds a LAG interface with lag_name to the manager
35
- // / This method allocates structures to connect to teamd
53
+ // / Public method to add a LAG interface with lag_name to the manager
54
+ // / This method tries to add. If the method can't add the LAG interface,
55
+ // / this action will be postponed.
36
56
// / @param lag_name a name for LAG interface
37
- // / @return true if the lag was added successfully, false otherwise
57
+ // / @return true if the lag was added or postponed successfully, false otherwise
38
58
// /
39
59
bool TeamdCtlMgr::add_lag (const std::string & lag_name)
40
60
{
@@ -43,26 +63,51 @@ bool TeamdCtlMgr::add_lag(const std::string & lag_name)
43
63
SWSS_LOG_DEBUG (" The LAG '%s' was already added. Skip adding it." , lag_name.c_str ());
44
64
return true ;
45
65
}
46
- else
66
+ return try_add_lag (lag_name);
67
+ }
68
+
69
+ // /
70
+ // / Try to adds a LAG interface with lag_name to the manager
71
+ // / This method allocates structures to connect to teamd
72
+ // / if the method can't add, it will retry to add next time
73
+ // / @param lag_name a name for LAG interface
74
+ // / @return true if the lag was added successfully, false otherwise
75
+ // /
76
+ bool TeamdCtlMgr::try_add_lag (const std::string & lag_name)
77
+ {
78
+ if (m_lags_to_add.find (lag_name) == m_lags_to_add.end ())
47
79
{
48
- auto tdc = teamdctl_alloc ();
49
- if (!tdc)
50
- {
51
- SWSS_LOG_ERROR (" Can't allocate memory for teamdctl handler. LAG='%s'" , lag_name.c_str ());
52
- return false ;
53
- }
80
+ m_lags_to_add[lag_name] = 0 ;
81
+ }
54
82
55
- int err = teamdctl_connect (tdc, lag_name.c_str (), nullptr , nullptr );
56
- if (err)
83
+ int attempt = m_lags_to_add[lag_name];
84
+
85
+ auto tdc = teamdctl_alloc ();
86
+ if (!tdc)
87
+ {
88
+ SWSS_LOG_ERROR (" Can't allocate memory for teamdctl handler. LAG='%s'. attempt=%d" , lag_name.c_str (), attempt);
89
+ m_lags_to_add[lag_name]++;
90
+ return false ;
91
+ }
92
+
93
+ teamdctl_set_log_fn (tdc, &teamdctl_log_function);
94
+
95
+ int err = teamdctl_connect (tdc, lag_name.c_str (), nullptr , nullptr );
96
+ if (err)
97
+ {
98
+ if (attempt != 0 )
57
99
{
58
- SWSS_LOG_ERROR (" Can't connect to teamd LAG='%s', error='%s'" , lag_name.c_str (), strerror (-err));
59
- teamdctl_free (tdc);
60
- return false ;
100
+ SWSS_LOG_WARN (" Can't connect to teamd LAG='%s', error='%s'. attempt=%d" , lag_name.c_str (), strerror (-err), attempt);
61
101
}
62
- m_handlers.emplace (lag_name, tdc);
63
- SWSS_LOG_NOTICE (" The LAG '%s' has been added." , lag_name.c_str ());
102
+ teamdctl_free (tdc);
103
+ m_lags_to_add[lag_name]++;
104
+ return false ;
64
105
}
65
106
107
+ m_handlers.emplace (lag_name, tdc);
108
+ m_lags_to_add.erase (lag_name);
109
+ SWSS_LOG_NOTICE (" The LAG '%s' has been added." , lag_name.c_str ());
110
+
66
111
return true ;
67
112
}
68
113
@@ -82,13 +127,39 @@ bool TeamdCtlMgr::remove_lag(const std::string & lag_name)
82
127
m_handlers.erase (lag_name);
83
128
SWSS_LOG_NOTICE (" The LAG '%s' has been removed." , lag_name.c_str ());
84
129
}
130
+ else if (m_lags_to_add.find (lag_name) != m_lags_to_add.end ())
131
+ {
132
+ m_lags_to_add.erase (lag_name);
133
+ SWSS_LOG_DEBUG (" The LAG '%s' has been removed from adding queue." , lag_name.c_str ());
134
+ }
85
135
else
86
136
{
87
137
SWSS_LOG_WARN (" The LAG '%s' hasn't been added. Can't remove it" , lag_name.c_str ());
88
138
}
89
139
return true ;
90
140
}
91
141
142
+ // /
143
+ // / Process the queue with postponed add operations for LAG.
144
+ // /
145
+ void TeamdCtlMgr::process_add_queue ()
146
+ {
147
+ std::vector<std::string> lag_names_to_add;
148
+ std::transform (m_lags_to_add.begin (), m_lags_to_add.end (), lag_names_to_add.begin (), [](auto pair) { return pair.first ; });
149
+ for (const auto lag_name: lag_names_to_add)
150
+ {
151
+ bool result = try_add_lag (lag_name);
152
+ if (!result)
153
+ {
154
+ if (m_lags_to_add[lag_name] == TeamdCtlMgr::max_attempts_to_add)
155
+ {
156
+ SWSS_LOG_ERROR (" Can't connect to teamd after %d attempts. LAG '%s'" , TeamdCtlMgr::max_attempts_to_add, lag_name.c_str ());
157
+ m_lags_to_add.erase (lag_name);
158
+ }
159
+ }
160
+ }
161
+ }
162
+
92
163
// /
93
164
// / Get json dump from teamd for LAG interface with name lag_name
94
165
// / @param lag_name a name for LAG interface
0 commit comments