|
15 | 15 | #include <utility> |
16 | 16 | #include <vector> |
17 | 17 |
|
| 18 | +#include "envoy/admin/v3/init_dump.pb.h" |
18 | 19 | #include "envoy/common/exception.h" |
19 | 20 | #include "envoy/common/matchers.h" |
20 | 21 | #include "envoy/common/optref.h" |
@@ -1876,11 +1877,13 @@ NetworkPolicyMapImpl::NetworkPolicyMapImpl(Server::Configuration::FactoryContext |
1876 | 1877 | std::make_shared<Server::Configuration::TransportSocketFactoryContextImpl>( |
1877 | 1878 | context_, *npds_stats_scope_, |
1878 | 1879 | context_.messageValidationContext().dynamicValidationVisitor())), |
| 1880 | + parked_init_manager_(std::make_unique<Init::ManagerImpl>("Cilium NetworkPolicyMap parked")), |
1879 | 1881 | npds_config_(npds_config), |
1880 | 1882 | stats_{ALL_CILIUM_POLICY_STATS(POOL_COUNTER(*policy_stats_scope_), |
1881 | 1883 | POOL_HISTOGRAM(*policy_stats_scope_))} { |
1882 | 1884 | // Use listener init manager for subscription initialization |
1883 | 1885 | context.initManager().add(init_target_); |
| 1886 | + transport_factory_context_->setInitManager(*parked_init_manager_); |
1884 | 1887 |
|
1885 | 1888 | // Allocate an initial policy map so that the map pointer is never a nullptr |
1886 | 1889 | store(new RawPolicyMap()); |
@@ -1921,15 +1924,42 @@ bool NetworkPolicyMapImpl::isNewStream() { |
1921 | 1924 |
|
1922 | 1925 | // removeInitManager must be called at the end of each policy update |
1923 | 1926 | void NetworkPolicyMapImpl::removeInitManager() { |
1924 | | - // Remove the local init manager from the transport factory context |
1925 | | -#ifdef __clang__ |
1926 | | -#pragma clang diagnostic push |
1927 | | -#pragma clang diagnostic ignored "-Wnull-dereference" |
1928 | | -#endif |
1929 | | - transport_factory_context_->setInitManager(*static_cast<Init::Manager*>(nullptr)); |
1930 | | -#ifdef __clang__ |
1931 | | -#pragma clang diagnostic pop |
1932 | | -#endif |
| 1927 | + RELEASE_ASSERT(parked_init_manager_ != nullptr, "parked init manager must exist"); |
| 1928 | + |
| 1929 | + const bool parked_wrong_state = |
| 1930 | + parked_init_manager_->state() != Init::Manager::State::Uninitialized; |
| 1931 | + if (parked_wrong_state) { |
| 1932 | + ENVOY_LOG(warn, |
| 1933 | + "Cilium NetworkPolicyMap parked init manager unexpectedly reached state {}; " |
| 1934 | + "replacing it before re-installing", |
| 1935 | + static_cast<int>(parked_init_manager_->state())); |
| 1936 | + } |
| 1937 | + |
| 1938 | + envoy::admin::v3::UnreadyTargetsDumps parked_dumps; |
| 1939 | + parked_init_manager_->dumpUnreadyTargets(parked_dumps); |
| 1940 | + bool parked_has_targets = false; |
| 1941 | + for (const auto& parked_dump : parked_dumps.unready_targets_dumps()) { |
| 1942 | + if (!parked_dump.target_names().empty()) { |
| 1943 | + parked_has_targets = true; |
| 1944 | + ENVOY_LOG( |
| 1945 | + warn, |
| 1946 | + "Cilium NetworkPolicyMap parked init manager unexpectedly accumulated targets [{}]{}; " |
| 1947 | + "replacing it before re-installing", |
| 1948 | + fmt::join(parked_dump.target_names(), ", "), |
| 1949 | + parked_wrong_state |
| 1950 | + ? fmt::format(" in state {}", static_cast<int>(parked_init_manager_->state())) |
| 1951 | + : ""); |
| 1952 | + } |
| 1953 | + } |
| 1954 | + |
| 1955 | + // replace parked init manager if it got to a bad state |
| 1956 | + if (parked_wrong_state || parked_has_targets) { |
| 1957 | + parked_init_manager_ = std::make_unique<Init::ManagerImpl>("Cilium NetworkPolicyMap parked"); |
| 1958 | + } |
| 1959 | + |
| 1960 | + // Restore the parked init manager after a policy-version-specific init manager has been |
| 1961 | + // installed for the duration of the update. |
| 1962 | + transport_factory_context_->setInitManager(*parked_init_manager_); |
1933 | 1963 | } |
1934 | 1964 |
|
1935 | 1965 | // onConfigUpdate parses the new network policy resources, allocates a new policy map and atomically |
|
0 commit comments