[Date Prev][Date Next] [Chronological] [Thread] [Top]

Re: automatic uidnumber overlay

joel reed wrote:
Howard Chu wrote:
Joel Reed wrote:
The attached uidnumber.c overlay intercepts ADD requests for entries
with a posixAccount objectclass that do not have a uidNumber. When such
ADD requests are found, the overlay searches the directory for the
largest uidNumber, then automatically adds a uidNumber attribute of
largest+1 to the entry being added.
Interesting. Perhaps instead, your overlay should just maintain a fixed
entry with a copy of the largest uidNumber in it, instead of searching
the entire tree all the time.

I did consider this, but didn't implement it because I was thinking about running in an N-Way Multi-Master configuration. On further reflection, this scheme would probably still not support such a configuration under load.

Obviously, the approach I took doesn't scale well as you point out. I
think I will punt on supporting N-Way Multi-Master configs and either
use the approach you note above or the sambaUnixIdPool approach noted
elsewhere in this thread.

It seems the sambaUnixIdPool approach is essentually the same thing, they just have a dedicated entry with uidNumber and gidNumber attributes, recording the next available values.

Thanks to everyone who provided feedback. Greatly appreciated.

In a multimaster scenario the only sane way to handle things is to partition the namespace such that each master is allocating numbers from a totally disjoint range. I would try an approach like this:

Each server allocates uids in blocks, say 1000 at a time. There is an attribute that records the last used (or next available) block. This attribute resides in a dedicated entry that is read and written by all the servers. Each server then records, in a server-specific entry, the last used (or next available) number within that block. You can use the slap_serverID variable to obtain the current server's ID.

so, with 3 masters:

dn: cn=idblock,dc=example,dc=com
objectclass: idblock
cn: idblock
uidNumber: 3000

dn: cn=server1,dc=example,dc=com
objectclass: idblock
cn: server1
uidNumber: 5

dn: cn=server2,dc=example,dc=com
objectclass: idblock
cn: server2
uidNumber: 1003

dn: cn=server3,dc=example,dc=com
objectclass: idblock
cn: server3
uidNumber: 2008

When a particular server allocates all 1000 of the IDs in its current block it will have to go back to the idblock entry and bump that up to the next range. At that point there's the potential for two servers to try to grab the same range, and the resulting conflict would create a big mess.

Another alternative, if you will never change the number of servers involved, is to do away with the central idblock entry and just allocate every-other-Nth ID. E.g., with 3 servers, server1 will allocate 0, 3, 6, 9 ...
server2 will allocate 1,4,7,10,... server3 will allocate 2,5,8,11...

That guarantees there will never be conflicts, unless you decide to change the number of masters.
-- Howard Chu
CTO, Symas Corp. http://www.symas.com
Director, Highland Sun http://highlandsun.com/hyc/
Chief Architect, OpenLDAP http://www.openldap.org/project/