Name
Date
Size
#Lines
LOC

..--

i386/H--332

sparc/H--332

MakefileH A D09-Aug-20061.1 KiB398

Makefile.comH A D09-Aug-20061.4 KiB4912

README.synchH A D14-Jun-20058.1 KiB177144

confopt.cH A D14-Jun-20059.4 KiB416273

dsvcd_synch.cH A D14-Jun-20058.6 KiB327184

errmsgs.cH A D14-Jun-20052.8 KiB8139

inc.flgH A D14-Jun-2005996 311

llib-ldhcpsvcH A D14-Jun-20051.1 KiB3531

mapfile-versH A D25-Jun-20101.8 KiB7773

private.cH A D14-Jun-200521.9 KiB872547

public.cH A D14-Jun-20054.1 KiB189106

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#
22DHCP Service Library Synchronization
23Peter Memishian, Solaris Software, meem@east.sun.com
24
25#ident	"%Z%%M%	%I%	%E% SMI"
26
27Introduction
28============
29
30When writing DHCP service libraries (i.e., public modules) that provide
31access to locally-backed datastores (i.e., have their backing datastore on
32the same machine that the module is running on), it can be difficult for
33the module author to synchronize access to the underlying datastore between
34multiple processes, multiple threads within a single process, multiple
35threads within multiple processes, and multiple threads within multiple
36processes on multiple machines.
37
38The goal of DHCP Service Library Synchronization is to simplify the design
39of modules using locally-backed datastores by pushing these issues up into
40the DHCP service library framework: by designing your module to use this
41framework, your code becomes simpler and your design cleaner.
42
43What does DHCP Service Library Synchronization do for me?
44=========================================================
45
46It synchronizes access to several of the DHCP Service Library public-layer
47functions; the particular synchronization guarantees vary depending on the
48underlying 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
56The term `per-container exclusive perimeter' access means that only one
57thread may be inside the per-container "perimeter" at a time; that means
58that if one thread is inside add_dn() for a given container, no other thread
59may be inside add_dn() (or delete_dn(), modify_dn(), and lookup_dn() for
60that same container).  However, other threads may be within routines that
61provide no synchronization guarantees such as close_dn().
62
63The term `per-container shared perimeter' access means that multiple threads
64may be inside the perimeter, as long as they are all in routines which have
65either no synchronization guarantees or also have `per-container shared
66perimeter' access.  For instance, multiple threads may be within lookup_dt()
67concurrently, but another thread may not be in add_dt() at the same time.
68
69Note that the preceding discussion assumes that all the threads being
70serialized are all running on the same machine.  However, there's also an
71optional facility which provides synchronization across multiple threads on
72multiple machines as well; see the discussion on cross-host synchronization
73below.
74
75How do I write my module to use DHCP Service Library Synchronization?
76=====================================================================
77
78Write your module just as you normally would.  Of course, when writing your
79code, you get to take advantage of the synchronization guarantees this
80architecture makes for you.
81
82When you're done writing your module, then add the following to one of your
83C 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
92Next, note that if you want to use cross-host synchronization, you'll need
93to bitwise-or in the DSVC_SYNCH_CROSSHOST flag as well -- however, please
94read the discussion below regarding cross-host synchronization first!
95
96The private layer synchronizes access to similarly named containers; that
97is, all requests for a given (location, container_name, container_version,
98datastore) tuple are synchronized with respect to one another.  One
99implication of this approach is that there must not be two tuples which
100identify the same container -- for instance, (/var/dhcp, dhcptab, 1,
101SUNWfiles) and (/var/dhcp/, dhcptab, 1, SUNWfiles) name the same container
102but are distinct tuples and thus would not be synchronized with respect to
103one another!
104
105To address this issue, the `location' field given in the above tuple is
106required to have the property that no two location names map to the same
107location.  Public modules whose `location' field does not meet this
108constraint must implement a mkloctoken() method, prototyped below, which
109maps a location into a token which does meet the constraints.  In the above
110scenario, mkloctoken() would use realpath(3C) to perform the mapping.
111
112	int mkloctoken(const char *location, char *token, size_t tokensize);
113
114The location to map is passed in as `location', which must be mapped into an
115ASCII `token' of `tokensize' bytes or less.  The function should return
116DSVC_SUCCESS or a DSVC_* error code describing the problem on failure.  Note
117that modules which do not use synchronization or already have location names
118which meet the constraints need not provide mkloctoken().
119
120Cross-host Synchronization
121==========================
122
123Datastores wishing to make use of cross-host synchronization have an
124additional constraint: the `location' must be the name of a directory which
125is shared and accessible by all hosts which are accessing the datastore.
126This constraint is because the code is uses NFS-based file locking to
127perform the synchronization.  While this is a severe limitation, only
128SUNWfiles currently uses this feature, and even that is only for backward
129compatibility.  We discourage use of this feature in future datastore
130implementations.
131
132How does it work?
133=================
134
135It is helpful but not necessary to understand how this architecture works.
136Furthermore, the internal details are still evolving; if you rely on any
137details here, the only guarantee is that your code will break someday.
138
139The easiest way to explain the architecture is by example; thus, assume you
140have a module `mymod' that you want to use with DHCP Service Library
141Synchronization.  Then, for each method specified in the DHCP Server
142Performance 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