Kea 1.5.0
library_manager_collection.cc
Go to the documentation of this file.
1// Copyright (C) 2013-2017 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>
13
14namespace isc {
15namespace 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
28boost::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
52bool
54
55 // Unload libraries if any are loaded.
56 static_cast<void>(unloadLibraries());
57
58 // Access the callout manager, (re)creating it if required.
59 //
60 // A pointer to the callout manager is maintained by each as well as by
61 // the HooksManager itself. Note that the callout manager does not hold any
62 // memory allocated by a library: although a library registers a callout
63 // (and so causes the creation of an entry in the CalloutManager's callout
64 // list), that creation is done by the CalloutManager itself. The
65 // CalloutManager is created within the server. The upshot of this is that
66 // it is therefore safe for the CalloutManager to be deleted after all
67 // associated libraries are deleted, hence this link (LibraryManager ->
68 // CalloutManager) is safe.
69 //
70 // If the list of libraries is not empty, re-create the callout manager.
71 // This deletes all callouts (including the pre-library and post-
72 // library) ones. It is up to the libraries to re-register their callouts.
73 // The pre-library and post-library callouts will also need to be
74 // re-registered.
75 //
76 // If the list of libraries stays empty (as in the case of a reconfiguration
77 // where the hooks-libraries clause was empty and is not changed), try
78 // to re-use the existing callout manager (so retaining registered pre-
79 // and post-library callouts).
80 if (library_names_.empty()) {
81 callout_manager_ = HooksManager::getSharedCalloutManager();
82 }
83 if (!library_names_.empty() || !callout_manager_) {
84 callout_manager_.reset(new CalloutManager(library_names_.size()));
85 }
86
87 // Now iterate through the libraries are load them one by one. We'll
88 for (size_t i = 0; i < library_names_.size(); ++i) {
89 // Create a pointer to the new library manager. The index of this
90 // library is determined by the number of library managers currently
91 // loaded: note that the library indexes run from 1 to (number of loaded
92 // libraries).
93 boost::shared_ptr<LibraryManager> manager(
94 new LibraryManager(library_names_[i], lib_managers_.size() + 1,
95 callout_manager_));
96
97 // Load the library. On success, add it to the list of loaded
98 // libraries. On failure, unload all currently loaded libraries,
99 // leaving the object in the state it was in before loadLibraries was
100 // called.
101 if (manager->loadLibrary()) {
102 lib_managers_.push_back(manager);
103 } else {
104 static_cast<void>(unloadLibraries());
105 return (false);
106 }
107 }
108
109 return (true);
110}
111
112// Unload the libraries.
113
114void
116
117 // Delete the library managers in the reverse order to which they were
118 // created, then clear the library manager vector.
119 for (int i = lib_managers_.size() - 1; i >= 0; --i) {
120 lib_managers_[i].reset();
121 }
122 lib_managers_.clear();
123
124 // Get rid of the callout manager. (The other member, the list of library
125 // names, was cleared when the libraries were loaded.)
126 callout_manager_.reset();
127}
128
129// Return number of loaded libraries.
130int
132 return (lib_managers_.size());
133}
134
135// Validate the libraries.
136std::vector<std::string>
138 const std::vector<std::string>& libraries) {
139
140 std::vector<std::string> failures;
141 for (size_t i = 0; i < libraries.size(); ++i) {
142 if (!LibraryManager::validateLibrary(libraries[i])) {
143 failures.push_back(libraries[i]);
144 }
145 }
146
147 return (failures);
148}
149
150} // namespace hooks
151} // namespace isc
static boost::shared_ptr< CalloutManager > & getSharedCalloutManager()
Return the shared callout manager.
static std::vector< std::string > validateLibraries(const std::vector< std::string > &libraries)
Validate libraries.
LibraryManagerCollection(const HookLibsCollection &libraries)
Constructor.
boost::shared_ptr< CalloutManager > getCalloutManager() const
Get callout manager.
int getLoadedLibraryCount() const
Get number of loaded libraries.
static bool validateLibrary(const std::string &name)
Validate library.
#define isc_throw(type, stream)
A shortcut macro to insert known values into exception arguments.
std::vector< HookLibInfo > HookLibsCollection
A storage for information about hook libraries.
Definition: libinfo.h:31
Defines the logger used by the top-level component of kea-dhcp-ddns.