Coverage Report

Created: 2024-09-19 09:45

/proc/self/cwd/envoy/server/hot_restart.h
Line
Count
Source (jump to first uncovered line)
1
#pragma once
2
3
#include <cstdint>
4
#include <string>
5
6
#include "envoy/common/pure.h"
7
#include "envoy/event/dispatcher.h"
8
#include "envoy/stats/allocator.h"
9
#include "envoy/stats/store.h"
10
#include "envoy/thread/thread.h"
11
12
namespace Envoy {
13
namespace Server {
14
15
class Instance;
16
17
/**
18
 * Abstracts functionality required to "hot" (live) restart the server including code and
19
 * configuration. Right now this interface assumes a UNIX like socket interface for fd passing
20
 * but it could be relatively easily swapped with something else if necessary.
21
 */
22
class HotRestart {
23
public:
24
  struct ServerStatsFromParent {
25
    uint64_t parent_memory_allocated_ = 0;
26
    uint64_t parent_connections_ = 0;
27
  };
28
29
  struct AdminShutdownResponse {
30
    time_t original_start_time_;
31
    bool enable_reuse_port_default_;
32
  };
33
34
10.5k
  virtual ~HotRestart() = default;
35
36
  /**
37
   * Shutdown listeners in the parent process if applicable. Listeners will begin draining to
38
   * clear out old connections.
39
   */
40
  virtual void drainParentListeners() PURE;
41
42
  /**
43
   * Retrieve a listening socket on the specified address from the parent process. The socket will
44
   * be duplicated across process boundaries.
45
   * @param address supplies the address of the socket to duplicate, e.g. tcp://127.0.0.1:5000.
46
   * @param worker_index supplies the socket/worker index to fetch. When using reuse_port sockets
47
   *        each socket is fetched individually to ensure no connection loss.
48
   * @return int the fd or -1 if there is no bound listen port in the parent.
49
   */
50
  virtual int duplicateParentListenSocket(const std::string& address, uint32_t worker_index) PURE;
51
52
  /**
53
   * Registers a UdpListenerConfig as a possible receiver of udp packets forwarded from the
54
   * parent process to the child process. This is used to forward QUIC packets that are not for
55
   * connections belonging to the parent process during draining (in the absence of BPF delivery to
56
   * the correct process), via its listenerWorkerRouter.
57
   * The HotRestart instance is responsible for recognizing "any" addresses (e.g. "0.0.0.0").
58
   * @param address supplies the address and port of the listening socket.
59
   * @param listener_config is the UdpListenerConfig to receive packets forwarded for the given
60
   * address.
61
   */
62
  virtual void
63
  registerUdpForwardingListener(Network::Address::InstanceConstSharedPtr address,
64
                                std::shared_ptr<Network::UdpListenerConfig> listener_config) PURE;
65
66
  /**
67
   * @return An interface on which registerParentDrainedCallback can be called during
68
   *         creation of a listener, or nullopt if there is no parent instance.
69
   *
70
   *         If this is set, any UDP listener should start paused and only begin listening
71
   *         when the parent instance is drained; this allows draining QUIC listeners to
72
   *         catch their own packets and forward unrecognized packets to the child instance.
73
   */
74
  virtual OptRef<Network::ParentDrainedCallbackRegistrar> parentDrainedCallbackRegistrar() PURE;
75
76
  /**
77
   * Initialize the parent logic of our restarter. Meant to be called after initialization of a
78
   * new child has begun. The hot restart implementation needs to be created early to deal with
79
   * shared memory, logging, etc. so late initialization of needed interfaces is done here.
80
   */
81
  virtual void initialize(Event::Dispatcher& dispatcher, Server::Instance& server) PURE;
82
83
  /**
84
   * Shutdown admin processing in the parent process if applicable. This allows admin processing
85
   * to start up in the new process.
86
   * @return response if the parent is alive.
87
   */
88
  virtual absl::optional<AdminShutdownResponse> sendParentAdminShutdownRequest() PURE;
89
90
  /**
91
   * Tell our parent process to gracefully terminate itself.
92
   */
93
  virtual void sendParentTerminateRequest() PURE;
94
95
  /**
96
   * Retrieve stats from our parent process and merges them into stats_store, taking into account
97
   * the stats values we've already seen transferred.
98
   * Skips all of the above and returns 0s if there is not currently a parent.
99
   * @param stats_store the store whose stats will be updated.
100
   * @param stats_proto the stats values we are updating with.
101
   * @return special values relating to the "server" stats scope, whose
102
   *         merging has to be handled by Server::InstanceImpl.
103
   */
104
  virtual ServerStatsFromParent mergeParentStatsIfAny(Stats::StoreRoot& stats_store) PURE;
105
106
  /**
107
   * Shutdown the half of our hot restarter that acts as a parent.
108
   */
109
  virtual void shutdown() PURE;
110
111
  /**
112
   * Return the base id used to generate a domain socket name.
113
   */
114
  virtual uint32_t baseId() PURE;
115
116
  /**
117
   * Return the hot restart compatibility version so that operations code can decide whether to
118
   * perform a full or hot restart.
119
   */
120
  virtual std::string version() PURE;
121
122
  /**
123
   * @return Thread::BasicLockable& a lock for logging.
124
   */
125
  virtual Thread::BasicLockable& logLock() PURE;
126
127
  /**
128
   * @return Thread::BasicLockable& a lock for access logs.
129
   */
130
  virtual Thread::BasicLockable& accessLogLock() PURE;
131
};
132
133
/**
134
 * HotRestartDomainSocketInUseException is thrown during HotRestart construction only when the
135
 * underlying domain socket is in use.
136
 */
137
class HotRestartDomainSocketInUseException : public EnvoyException {
138
public:
139
0
  HotRestartDomainSocketInUseException(const std::string& what) : EnvoyException(what) {}
140
};
141
142
} // namespace Server
143
} // namespace Envoy