BIND 10 #2980: Implement Hooks Framework (part 2) - library loading and unloading

BIND 10 Development do-not-reply at isc.org
Wed Jul 3 15:18:06 UTC 2013


#2980: Implement Hooks Framework (part 2) - library loading and unloading
-------------------------------------+-------------------------------------
            Reporter:  stephen       |                        Owner:
                Type:  enhancement   |  stephen
            Priority:  medium        |                       Status:
           Component:  Unclassified  |  reviewing
            Keywords:                |                    Milestone:
           Sensitive:  0             |  Sprint-DHCP-20130703
         Sub-Project:  DHCP          |                   Resolution:
Estimated Difficulty:  0             |                 CVSS Scoring:
         Total Hours:  0             |              Defect Severity:  N/A
                                     |  Feature Depending on Ticket:
                                     |          Add Hours to Ticket:  0
                                     |                    Internal?:  0
-------------------------------------+-------------------------------------
Changes (by tomek):

 * owner:  tomek => stephen
 * milestone:  Sprint-DHCP-20130717 => Sprint-DHCP-20130703


Comment:

 Replying to [comment:2 stephen]:
 > * Look at library_manager.*, library_manager_collection.* and
 hooks_manager.* in that order. The first handles the loading and unloading
 of a user library, the second handles the fact that there can be multiple
 libraries, and the last collects all the disparate hooks framework objects
 in one place and provides an easy interface for BIND 10 component
 developers.
 '''library_manager.h'''
 LibraryManager class comment: "On unload, it calls the "unload" method if
 present, clears the callouts
  all hooks and closes the library.". There seems to be something missing
 between "callouts" and "all hooks".

 "Should this happens" => "Should this happen'

 I would use stronger language in checkVersion() and point out that the
 version() method is really mandatory.

 I would like to see registerStandardCallouts() returing bool if any
 callouts were registered. Right now it is possible to make an empty
 library that has version() function and nothing else in it. We should at
 least print out a warning about that (or more likely an error). That's the
 only way we can catch spelling errors in user library function names, so
 it is rather important.

 '''library_manager.cc'''
 I would like to see LOAD_FUNCTION_NAME, UNLOAD_FUNCTION_NAME and
 VERSION_FUNCTION_NAME moved to a header. A header is a natural place as it
 will be used by a user library developer.

 checkVersion() method: It would be good to check that version_function_ptr
 and void* are of the same size. I think this particular check should be
 done in the production code, not in tests (not everyone runs tests). You
 may also consider wrapping call to user libraries() with try ... catch.
 Libraries still could fail arbitrarily bad, up to and including segfault,
 so it won't be bullet-proof, just a bit resistant against more benign
 failures.

 I think HOOKS_REGISTER_STD_CALLOUT should print out function pointer. It
 doesn't give much, but that will at least give some pointers if we get
 bizarre segfaults.

 Question about checkVersion(), runLoad() and runUnload(). How did you
 solve the problem of dlsym() returning a pointer to a function not from
 the library? E.g. you load library1 then when you call dlsym("version")
 for library2 you can get version() from library1 (which is already
 loaded). I don't see any code for that. I admit that I don't have any
 experience with dynamically loaded libraries.

 Return codes for load() and unload() should be defined in a header
 somewhere. It may be just one constant for 0 with the explanation that
 non-zero status codes are errors and are library dependent.

 The code for union of pointers and dlsym() calls are repeated in 4 places.
 Would it be possible to refactor them into a separate method? It's an
 honest question. It's a tricky part of code and there will be much
 debugging conducted in that area in years to come (most 3rd party library
 debugging will probably start here), so perhaps keeping the code simple as
 it is may be the right way to go.

 loadLibrary(): This is a bit confusing. If version check fails, you run
 closeLibrary(). If runLoad() fails, you don't. I think in the first "else"
 there should be unloadLibrary() and closeLibrary().

 unloadLibrary(): I think there's a bug in the code. closeLibrary() will be
 called only if runUnload() succeeded. Is that what you wanted? I think
 that we should call closeLibrary() every time, so it should be:

 {{{
 result = closeLibrary() && result;
 }}}

 '''tests/test_libraries.h.in'''
 "Take carse of" => "Take care of"

 '''tests/Makefile.am'''
 There are unnecessary spaces in lines 32 and 37.

 '''tests/test_libraries.h'''
 Good work with the test_libraries.h.in and the libraries it points to.
 Very thorough.

 '''tests/library_manager_unittest.cc'''
 What are the r and d parameters of executeCallCallouts() mean? I presume
 it is a short for data and result, right?

 This is used in several tests. I understand that the callouts perform
 simple mathematical operations, but a bit of explanation would be handy.
 Also, that's a tricky approach as with all results can be achieved with
 different combinations of addition and multiplication.

 > * The changes to library_handle.* are minor and are related to providing
 a way for the server to register its own callouts (as desribed in the dox
 file).
 '''library_handle.h'''
 The comment about manager parameter passed to constructor being a raw
 pointer being safe. Although this may be true, there's not guarantee that
 LibraryHandle will not be created somewhere else. You would get that
 guarantee if constructor was protected and CalloutManager was defined a
 friend. This may possibly complicate some tests (which violate that
 guarantee).

 > * hooks_log.*/hooks_messages.mes are standard logging and message files.
 '''hooks/'hook_messages.mes'''
 The different between HOOKS_CALLOUT_REMOVED and HOOKS_DEREGISTER_CALLOUT
 are not clear (I understand the difference, but it not clearly explained).
 Two comments about log message naming. Firstly, some hooks have noun_verb
 names, which others have verb_nound. Secondly, some are in present and
 some in past tense. I don't have any preference, but I think it should be
 consistent.

 > In the test directories:
 >
 > * The *library.cc files are each compiled into a separate shared
 library.  These contain relatively simple code and are loaded and unloaded
 during the unit tests.
 '''tests/basic_callout_library.cc'''
 Please update the naming to reflect what the callouts are for. lm_one is a
 wrong name. It is not library manager, it is a callout. Also, it would be
 great if the name reflected what the callout actually does, so callout_add
 seems like a good name.

 It seems that the same applies to other test libraries as well. I did not
 go through them all.

 Finally, I think we should consider adding a separate version function for
 libraries. Right now the version() returns BIND10 Hooks API version. We
 should have another one for versioning library itself. This would be
 called upon load and returned string would be logged. We should do this as
 a separate ticket. Please do not complicate this ticket any further.

 > * common_test_class.h provides common test functionality for a number of
 test files.
 >
 > The remaining files should be reasonably well documented.

 Phew! That's the end of it. I must admit that the size of the code to
 cover made my review not as thorough as I'd like it to be. It was very
 difficult to stay focused when looking at fifth library that is only a bit
 different that previous four. Anyway, this code looks good. I hope the
 things I have missed in review are minor or will come up in testing.

 I'd like to repeat what I said when I began this review - this ticket is
 too large. The next time I receive such a large ticket, I will simply
 refuse to review it.

 The ticket is back with you, Stephen.

-- 
Ticket URL: <https://bind10.isc.org/ticket/2980#comment:6>
BIND 10 Development <http://bind10.isc.org>
BIND 10 Development


More information about the bind10-tickets mailing list