Home | History | Annotate | only in /onnv/onnv-gate/usr/src/lib/libdhcpsvc/private
Up to higher level directory
NameDateSize
confopt.c08-Dec-20089.4K
dsvcd_synch.c08-Dec-20088.6K
errmsgs.c08-Dec-20082.8K
i386/08-Dec-2008
inc.flg08-Dec-2008996
llib-ldhcpsvc08-Dec-20081.1K
Makefile08-Dec-20081.1K
Makefile.com08-Dec-20081.4K
mapfile-vers10-Feb-20091.7K
private.c08-Dec-200821.9K
public.c08-Dec-20084.1K
README.synch08-Dec-20088.1K
sparc/08-Dec-2008

README.synch

      1 #
      2 # CDDL HEADER START
      3 #
      4 # The contents of this file are subject to the terms of the
      5 # Common Development and Distribution License, Version 1.0 only
      6 # (the "License").  You may not use this file except in compliance
      7 # with the License.
      8 #
      9 # You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
     10 # or http://www.opensolaris.org/os/licensing.
     11 # See the License for the specific language governing permissions
     12 # and limitations under the License.
     13 #
     14 # When distributing Covered Code, include this CDDL HEADER in each
     15 # file and include the License file at usr/src/OPENSOLARIS.LICENSE.
     16 # If applicable, add the following below this CDDL HEADER, with the
     17 # fields enclosed by brackets "[]" replaced with your own identifying
     18 # information: Portions Copyright [yyyy] [name of copyright owner]
     19 #
     20 # CDDL HEADER END
     21 #
     22 DHCP Service Library Synchronization
     23 Peter Memishian, Solaris Software, meem@east.sun.com
     24 
     25 #ident	"%Z%%M%	%I%	%E% SMI"
     26 
     27 Introduction
     28 ============
     29 
     30 When writing DHCP service libraries (i.e., public modules) that provide
     31 access to locally-backed datastores (i.e., have their backing datastore on
     32 the same machine that the module is running on), it can be difficult for
     33 the module author to synchronize access to the underlying datastore between
     34 multiple processes, multiple threads within a single process, multiple
     35 threads within multiple processes, and multiple threads within multiple
     36 processes on multiple machines.
     37 
     38 The goal of DHCP Service Library Synchronization is to simplify the design
     39 of modules using locally-backed datastores by pushing these issues up into
     40 the DHCP service library framework: by designing your module to use this
     41 framework, your code becomes simpler and your design cleaner.
     42 
     43 What does DHCP Service Library Synchronization do for me?
     44 =========================================================
     45 
     46 It synchronizes access to several of the DHCP Service Library public-layer
     47 functions; the particular synchronization guarantees vary depending on the
     48 underlying function being called:
     49 
     50 	add_d?()	per-container exclusive-perimeter
     51 	delete_d?()	per-container exclusive-perimeter
     52 	modify_d?()	per-container exclusive-perimeter
     53 	lookup_d?()	per-container shared-perimeter
     54 	all others	no synchronization provided
     55 
     56 The term `per-container exclusive perimeter' access means that only one
     57 thread may be inside the per-container "perimeter" at a time; that means
     58 that if one thread is inside add_dn() for a given container, no other thread
     59 may be inside add_dn() (or delete_dn(), modify_dn(), and lookup_dn() for
     60 that same container).  However, other threads may be within routines that
     61 provide no synchronization guarantees such as close_dn().
     62 
     63 The term `per-container shared perimeter' access means that multiple threads
     64 may be inside the perimeter, as long as they are all in routines which have
     65 either no synchronization guarantees or also have `per-container shared
     66 perimeter' access.  For instance, multiple threads may be within lookup_dt()
     67 concurrently, but another thread may not be in add_dt() at the same time.
     68 
     69 Note that the preceding discussion assumes that all the threads being
     70 serialized are all running on the same machine.  However, there's also an
     71 optional facility which provides synchronization across multiple threads on
     72 multiple machines as well; see the discussion on cross-host synchronization
     73 below.
     74 
     75 How do I write my module to use DHCP Service Library Synchronization?
     76 =====================================================================
     77 
     78 Write your module just as you normally would.  Of course, when writing your
     79 code, you get to take advantage of the synchronization guarantees this
     80 architecture makes for you.
     81 
     82 When you're done writing your module, then add the following to one of your
     83 C source files:
     84 
     85   /*
     86    * This symbol and its value tell the private layer that it must provide
     87    * synchronization guarantees via dsvclockd(1M) before calling our *_dn()
     88    * and *_dt() methods.  Please see $SRC/lib/libdhcpsvc/private/README.synch
     89    */
     90   int dsvc_synchtype = DSVC_SYNCH_DSVCD;
     91 
     92 Next, note that if you want to use cross-host synchronization, you'll need
     93 to bitwise-or in the DSVC_SYNCH_CROSSHOST flag as well -- however, please
     94 read the discussion below regarding cross-host synchronization first!
     95 
     96 The private layer synchronizes access to similarly named containers; that
     97 is, all requests for a given (location, container_name, container_version,
     98 datastore) tuple are synchronized with respect to one another.  One
     99 implication of this approach is that there must not be two tuples which
    100 identify the same container -- for instance, (/var/dhcp, dhcptab, 1,
    101 SUNWfiles) and (/var/dhcp/, dhcptab, 1, SUNWfiles) name the same container
    102 but are distinct tuples and thus would not be synchronized with respect to
    103 one another!
    104 
    105 To address this issue, the `location' field given in the above tuple is
    106 required to have the property that no two location names map to the same
    107 location.  Public modules whose `location' field does not meet this
    108 constraint must implement a mkloctoken() method, prototyped below, which
    109 maps a location into a token which does meet the constraints.  In the above
    110 scenario, mkloctoken() would use realpath(3C) to perform the mapping.
    111 
    112 	int mkloctoken(const char *location, char *token, size_t tokensize);
    113 
    114 The location to map is passed in as `location', which must be mapped into an
    115 ASCII `token' of `tokensize' bytes or less.  The function should return
    116 DSVC_SUCCESS or a DSVC_* error code describing the problem on failure.  Note
    117 that modules which do not use synchronization or already have location names
    118 which meet the constraints need not provide mkloctoken().
    119 
    120 Cross-host Synchronization
    121 ==========================
    122 
    123 Datastores wishing to make use of cross-host synchronization have an
    124 additional constraint: the `location' must be the name of a directory which
    125 is shared and accessible by all hosts which are accessing the datastore.
    126 This constraint is because the code is uses NFS-based file locking to
    127 perform the synchronization.  While this is a severe limitation, only
    128 SUNWfiles currently uses this feature, and even that is only for backward
    129 compatibility.  We discourage use of this feature in future datastore
    130 implementations.
    131 
    132 How does it work?
    133 =================
    134 
    135 It is helpful but not necessary to understand how this architecture works.
    136 Furthermore, the internal details are still evolving; if you rely on any
    137 details here, the only guarantee is that your code will break someday.
    138 
    139 The easiest way to explain the architecture is by example; thus, assume you
    140 have a module `mymod' that you want to use with DHCP Service Library
    141 Synchronization.  Then, for each method specified in the DHCP Server
    142 Performance Project specification, the following happens:
    143 
    144 	1. The private layer is called with the specified method
    145 	   (as specified in the DHCP Server Performance Project spec)
    146 
    147 	2. The private layer locates the underlying public module
    148 	   to invoke, given the settings in /etc/inet/dhcpsvc.conf.
    149 	   (as specified in the DHCP Server Performance Project spec)
    150 
    151 	3. The private layer detects that this module is one that
    152 	   requires use of DHCP Service Library Synchronization (by
    153 	   checking the value of the module's dsvc_synchtype symbol).
    154 
    155 	4. If this method is one for which synchronization guarantees
    156 	   are provided, the private layer sends a "lock" request
    157 	   across a door to the DHCP service door server daemon (also
    158 	   known as the lock manager), dsvclockd.
    159 
    160 	5. The dsvclockd daemon receives the lock request and attempts
    161 	   to lock a given container for either exclusive or shared
    162 	   access (depending on the request).  If the lock request was
    163 	   "nonblocking" and the lock cannot be immediately acquired,
    164 	   a DSVC_BUSY error is returned.  Otherwise, the daemon waits
    165 	   until it acquires the lock and sends a DSVC_SUCCESS reply
    166 	   back.
    167 
    168 	6. Assuming the lock could be obtained (if it was necessary;
    169 	   see step 4), the private layer locates the appropriate
    170 	   method in `ds_mymod.so' module, and calls it.
    171 
    172 	7. Once the method has completed (successfully or otherwise),
    173 	   if this was a method which required a "lock" request, the
    174 	   private layer sends an "unlock" request to the dsvclockd.
    175 
    176         8. The private layer returns the reply to the caller.
    177