Controlling Memory Allocation for Multiple eDirectory Instances

With the release of eDirectory 8.8 and higher we got a really cool feature, multi-instance support. This allows us to very easily bring up several eDirectory instances on one server. For development and testing, this is amazingly powerful.

There are also some downsides to doing this. For one thing, the binaries in use are shared across all instances. That means all instances will be at the same revision of Security Services, eDirectory, and Identity Manager.

If you want to update the versions for one instance, then all instances will start to use the new binaries. This is sort of obvious but worth mentioning.

From a management side, Novell has done a really nice job of enabling most of the tools to support the multiple instances. For examples, here is a SLES 10 server with six eDirectory instances running, using ndsmanage:

acmeedir02:/etc/init.d # ndsmanage
Instances management utility for Novell eDirectory 8.8 SP 1 v2

The following are the instances configured by root:

[1] /home/root/edir/nds.conf : .ACMEEDIR02.SERVICES.ACME.ACME-EDIR. : : ACTIVE

[2] /home/root/edir-qc/nds.conf : .ACMEEDIR02-QC.SERVICES.ACME.ACME-QC. : : INACTIVE

[3] /home/root/edir-dev/nds.conf : .ACMEEDIR02-DEV.SERVICES.ACME.ACME-DEV. : : ACTIVE

[4] /home/root/edir-dev-auth/nds.conf : .ACMEEDIR02-DEV-AUTH.SERVICES.ACME.COM.ACME-DEV-AUTH. : : ACTIVE

[5] /home/root/edir-qc-auth/nds.conf : .ACMEEDIR02-QC-AUTH.ACME.COM.ACME-QC-AUTH. : : INACTIVE

[6] /home/root/edir-auth/nds.conf : .ACMEEDIR02-AUTH.ACME.COM.ACME-AUTH. : : INACTIVE

Enter [r] to refresh list, [1 - 6] for more options, [c] for creating a new instance or [q] to quit:

You get to select the instance you want to work on and then go back and work on another instance.

NDSRepair, the next obvious tool of concern, does much the same. Here is a timecheck with ndsrepair -T. Note how it asks you to select an instance to work on:

acmeedir02:/etc/init.d # ndsrepair -T

[1] Instance at /home/root/edir/nds.conf: acmeedir02.OU=services.O=acme.ACME-EDIR

[2] Instance at /home/root/edir-qc/nds.conf: acmeedir02-qc.OU=services.O=acme.ACME-QC

[3] Instance at /home/root/edir-dev/nds.conf: acmeedir02-dev.OU=services.O=acme.ACME-DEV

[4] Instance at /home/root/edir-dev-auth/nds.conf: acmeedir02-dev-auth.OU=Services.O=acme.dc=com.ACME-DEV-AUTH

[5] Instance at /home/root/edir-qc-auth/nds.conf: acmeedir02-qc-auth.O=acme.dc=com.ACME-QC-AUTH

[6] Instance at /home/root/edir-auth/nds.conf: acmeedir02-auth.O=acme.dc=com.ACME-AUTH
Select the instance you want to operate on: [ 1 - 6 ] or 'q' to quit:

One important tip is to remember to set up a new IP address for each eDirectory instance and bind the instance to that IP only. This way, port 389 and 636 for LDAP, 8028 and 8030 for httpstk, and 524 for NCP are all available and separated by IP address.

One serious consequence of running multiple instances is changing things that are normally global. For example, the amount of Java memory heap for IDM is usually set globally as an environment variable, DHOST_JVM_MAX_HEAP with a value of -Xmx512M to set it to 512 Megabytes of cache. In a six-instance server as shown above, that is 3GB of space potentially gone. So setting it globally is probably not an option.

Generally this would be set in /etc/init.d/pre_ndsd_start to set DHOST_JVM_MAX_HEAP to some value globally for all instances. That would look something like this:


Nice and simple. With multiple instances where you want to maintain different values per instance, it will be more complex. You would probably want something that looks more like this:

vardir=`cat ${NDS_CONF} |grep "^n4u.*vardir" | sed 's/^.*=//' | sed 's/\/\//\//'`
if [ -z "$vardir" ]; then

if [ "$vardir" = "/home/root/edir/data" ]; then


if [ "$vardir" = "/home/root/edir-qc/data" ]; then
if [ "$vardir" = "/home/root/edir-dev/data" ]; then
if [ "$vardir" = "/home/root/edir-dev-auth/data" ]; then
if [ "$vardir" = "/home/root/edir-qc-auth/data" ]; then
if [ "$vardir" = "/home/root/edir-auth/data" ]; then

What this does is set a specific value each time you call ndsd. You need to reset it, specific to each eDirectory instance. Otherwise, the last one set will be used.

This line:

vardir=`cat ${NDS_CONF} |grep "^n4u.*vardir" | sed 's/^.*=//' | sed 's/\/\//\//'`

sets a variable vardir, by listing off the file specified by $NDS_CONF (this is set by the /etc/init.d/ndsd script, and exported). It uses grep to look through it for the variable that specifies the config directory.

Then it uses sed to replace (the s function via "^.*=" which is a regular expression) some or all the characters in that line. It starts at the beginning (the ^ or caret mark), continues (.* the period asterisk), and then stops after the equals sign (=), replacing it with null.

Finally, the syntax of the nds.conf sometimes has a single forward slash, and sometimes has a double forward slash for path (anyone know why? I am sure it is a Unix'ism of some kind). So, we need to use sed again to replace (s, aka the substitute function) to replace "//" with "/". However, the forward slash is a reserved character, so we need to replace that with an escaped version. So, forward slash (/) becomes "\/" - the second one is "\/", which explains the "\/\/" part. The substitute function (s) uses "///" to indicate the stuff to be replaced. The format is "/something/somethingElse/". The "\/\/" surrounded by forward slashes is "/\/\//". Then we replace it with "\/" (single forward slash escaped) and then the final closing forward slash for the sed command - "\//". We end up with this command:

sed 's/\/\//\//'

So a line that looks like this:


becomes this:


Using if-then statements, you can test and set a value based on the path that the eDirectory instance is running from. This does assume that the nds.conf sits in the directory one above the data directory for each eDirectory instance.

There is probably an easier way, but you can try the following command to see if that worked for you:

ps auxeww | less

This ps command shows all processes (aux), the environment variables (e), and wide-wide width (double-w wide! There is a joke in there somewhere ...).

There are probably better ways to handle this, but this one seems to work for me. One nice thing is that it can be extended to set any variable you need per eDirectory instance.

Let me know if you can think of improvements or find any mistakes!

Note, I caught a typo, I had missed three zeros at the end of the memory values. It is in bytes, not kilobytes, updated now. Sorry for the inconvenience.


How To-Best Practice
Comment List