The architecture provides a facility that helps a files-based module avoid record update collisions. The Service Provider API facilitates the maintenance of data consistency through the use of a per-record update signature, an unsigned 64–bit integer. The update signature is the d?_sig element of the d?_rec_t container record data structure, defined in /usr/include/dhcp_svc_public.h. All layers of the architecture use d?_rec_t records, from the Application/Service Layer through the Framework Configuration Layer API and on through to the Service Provider Layer API. Above the Service Provider Layer, the update signature is an opaque object which is not manipulated by users of the Framework Configuration Layer API.
When a module receives a d?_rec_t record through a Service Provider Layer API function call, it should perform a lookup in the data service to find a record that matches the key fields of the d?_rec_t, and compare the signature of the internal record against the d?_rec_t passed by the call. If the signature of the internal record does not match that of the passed record, then the record has been changed since the consumer acquired it from the public module. In this case, the module should return DSVC_COLLISION, which informs the caller that the record has been changed since it was acquired. If the signatures match, the module should increment the update signature of the argument record before it stores the record.
When a module receives a new d?_rec_t record through the Service Provider Layer API, the module must assign a value to the update signature before it adds the record to the container. The simplest way is to set the value to 1.
However, in certain rare situations a collision might not be detected if the signature always has the same initial value. Consider the following scenario. Thread A adds a record with a signature of 1, and Thread B looks up that record. Thread A deletes the record and creates a new record with the same key fields and a signature of 1 since it has just been created. Thread B then modifies the record it looked up, but that has already been deleted. The module compares the key fields and signatures of the record looked up by Thread B and the record in the data store, finds them to be the same, and makes the modification. Such a modification attempt should have been a collision because the records are, in fact, not the same.
The ds_SUNWfiles.so and ds_SUNWbinfiles.so modules provided with Solaris DHCP address such a possibility. They divide the update signature into two fields to ensure the uniqueness of each record's signature. The first 16 bit field of the update signature is set to a randomly generated number. This field never changes in the record after it is set. The lower 48 bit field of the signature is set to 1 and then incremented each time the record is updated.
The modules provided with Solaris DHCP illustrate one approach you can use to avoid record update collisions. You can devise your own method or use a similar one.