Kea  1.9.9-git
library_manager_collection.cc
Go to the documentation of this file.
1 // Copyright (C) 2013-2020 Internet Systems Consortium, Inc. ("ISC")
2 //
3 // This Source Code Form is subject to the terms of the Mozilla Public
4 // License, v. 2.0. If a copy of the MPL was not distributed with this
5 // file, You can obtain one at http://mozilla.org/MPL/2.0/.
6 
7 #include <config.h>
8 
10 #include <hooks/hooks_manager.h>
11 #include <hooks/library_manager.h>
13 
14 namespace isc {
15 namespace hooks {
16 
17 // Return callout manager for the loaded libraries. This call is only valid
18 // after one has been created for the loaded libraries (which includes the
19 // case of no loaded libraries).
20 //
21 // Note that there is no real connection between the callout manager and the
22 // libraries, other than it knows the number of libraries so can do sanity
23 // checks on values passed to it. However, this may change in the future,
24 // so the hooks framework is written such that a callout manager is used only
25 // with the LibraryManagerCollection that created it. It is also the reason
26 // why each LibraryManager contains a pointer to this CalloutManager.
27 
28 boost::shared_ptr<CalloutManager>
30 
31  // Only return a pointer if we have a CalloutManager created.
32  if (!callout_manager_) {
33  isc_throw(LoadLibrariesNotCalled, "must load hooks libraries before "
34  "attempting to retrieve a CalloutManager for them");
35  }
36 
37  return (callout_manager_);
38 }
39 
41  : library_info_(libraries) {
42 
43  // We need to split hook libs into library names and library parameters.
44  for (HookLibsCollection::const_iterator it = libraries.begin();
45  it != libraries.end(); ++it) {
46  library_names_.push_back(it->first);
47  }
48 }
49 
50 // Load a set of libraries
51 
52 bool
54 
55  // There must be no libraries still in memory.
56  if (!lib_managers_.empty()) {
57  isc_throw(LibrariesStillOpened, "some libraries are still opened");
58  }
59 
60  // Access the callout manager, (re)creating it if required.
61  //
62  // A pointer to the callout manager is maintained by each as well as by
63  // the HooksManager itself. Note that the callout manager does not hold any
64  // memory allocated by a library: although a library registers a callout
65  // (and so causes the creation of an entry in the CalloutManager's callout
66  // list), that creation is done by the CalloutManager itself. The
67  // CalloutManager is created within the server. The upshot of this is that
68  // it is therefore safe for the CalloutManager to be deleted after all
69  // associated libraries are deleted, hence this link (LibraryManager ->
70  // CalloutManager) is safe.
71  //
72  // The call of this function will result in re-creating the callout manager.
73  // This deletes all callouts (including the pre-library and post-
74  // library) ones. It is up to the libraries to re-register their callouts.
75  // The pre-library and post-library callouts will also need to be
76  // re-registered.
77  callout_manager_.reset(new CalloutManager(library_names_.size()));
78 
79  // Now iterate through the libraries are load them one by one. We'll
80  for (size_t i = 0; i < library_names_.size(); ++i) {
81  // Create a pointer to the new library manager. The index of this
82  // library is determined by the number of library managers currently
83  // loaded: note that the library indexes run from 1 to (number of loaded
84  // libraries).
85  boost::shared_ptr<LibraryManager> manager(
86  new LibraryManager(library_names_[i], lib_managers_.size() + 1,
87  callout_manager_));
88 
89  // Load the library. On success, add it to the list of loaded
90  // libraries. On failure, unload all currently loaded libraries,
91  // leaving the object in the state it was in before loadLibraries was
92  // called.
93  if (manager->loadLibrary()) {
94  lib_managers_.push_back(manager);
95  } else {
96  static_cast<void>(unloadLibraries());
97  return (false);
98  }
99  }
100 
101  return (true);
102 }
103 
104 // Unload the libraries.
105 
106 void
108 
109  // Delete the library managers in the reverse order to which they were
110  // created, then clear the library manager vector.
111  while (!lib_managers_.empty()) {
112  lib_managers_.pop_back();
113  }
114 
115  // Get rid of the callout manager. (The other member, the list of library
116  // names, was cleared when the libraries were loaded.)
117  callout_manager_.reset();
118 }
119 
120 // Prepare the unloading of libraries.
121 bool
123  bool result = true;
124  // Iterate on library managers in reverse order.
125  for (auto lm = lib_managers_.rbegin(); lm != lib_managers_.rend(); ++lm) {
126  result = (*lm)->prepareUnloadLibrary() && result;
127  }
128  return (result);
129 }
130 
131 // Return number of loaded libraries.
132 int
134  return (lib_managers_.size());
135 }
136 
137 // Validate the libraries.
138 std::vector<std::string>
140  const std::vector<std::string>& libraries) {
141 
142  std::vector<std::string> failures;
143  for (size_t i = 0; i < libraries.size(); ++i) {
144  if (!LibraryManager::validateLibrary(libraries[i])) {
145  failures.push_back(libraries[i]);
146  }
147  }
148 
149  return (failures);
150 }
151 
152 } // namespace hooks
153 } // namespace isc
bool prepareUnloadLibraries()
Prepare libaries unloading.
static std::vector< std::string > validateLibraries(const std::vector< std::string > &libraries)
Validate libraries.
Libraries still opened.
Definition: hooks_manager.h:28
boost::shared_ptr< CalloutManager > getCalloutManager() const
Get callout manager.
static bool validateLibrary(const std::string &name)
Validate library.
int getLoadedLibraryCount() const
Get number of loaded libraries.
std::vector< HookLibInfo > HookLibsCollection
A storage for information about hook libraries.
Definition: libinfo.h:31
#define isc_throw(type, stream)
A shortcut macro to insert known values into exception arguments.
Defines the logger used by the top-level component of kea-dhcp-ddns.
LibraryManagerCollection(const HookLibsCollection &libraries)
Constructor.