Hello all,

I attached WIP patch to solve https://fedorahosted.org/freeipa/ticket/4949

I received several suggestions:

1) (implemented in patch) is to add the option --db-locks to installer (maybe as hidden option)

2) Configure the nsslapd-db-locks to higher value as default (what is the right value?)

3) Combination of 1and 2: set default higher value and also have hidden option to allow configure higher number of locks during install

Comments are more than welcome :-)

--
Martin Basti

From 9511569db1ba44dde077cfb28eeb3334c6b7e9bc Mon Sep 17 00:00:00 2001
From: Martin Basti <mba...@redhat.com>
Date: Wed, 22 Jul 2015 14:42:56 +0200
Subject: [PATCH] Allow to set up nsslapd-db-locks during install

Option --db-lock allows to specify number of database locks.
Works for ipa-server-install, ipa-replica-install

https://fedorahosted.org/freeipa/ticket/4949
---
 ipaserver/install/dsinstance.py            | 36 +++++++++++++++++++++++++++++-
 ipaserver/install/server/install.py        | 15 ++++++++++++-
 ipaserver/install/server/replicainstall.py | 18 ++++++++++++---
 3 files changed, 64 insertions(+), 5 deletions(-)

diff --git a/ipaserver/install/dsinstance.py b/ipaserver/install/dsinstance.py
index d561ca5b6d0d586cb1c27ec1c495413dad102e69..c55bb195968e6b21878bcfd573c711696af9a957 100644
--- a/ipaserver/install/dsinstance.py
+++ b/ipaserver/install/dsinstance.py
@@ -26,6 +26,7 @@ import re
 import time
 import tempfile
 import stat
+import ldif
 
 from ipapython.ipa_log_manager import *
 from ipapython import ipautil, sysrestore, ipaldap
@@ -189,7 +190,7 @@ info: IPA V2.0
 
 class DsInstance(service.Service):
     def __init__(self, realm_name=None, domain_name=None, dm_password=None,
-                 fstore=None, domainlevel=None):
+                 fstore=None, domainlevel=None, db_locks=None):
         service.Service.__init__(self, "dirsrv",
             service_desc="directory server",
             dm_password=dm_password,
@@ -213,6 +214,7 @@ class DsInstance(service.Service):
         self.open_ports = []
         self.run_init_memberof = True
         self.domainlevel = domainlevel
+        self.db_locks = db_locks
         if realm_name:
             self.suffix = ipautil.realm_to_suffix(self.realm)
             self.__setup_sub_dict()
@@ -231,6 +233,9 @@ class DsInstance(service.Service):
 
         self.step("creating directory server user", create_ds_user)
         self.step("creating directory server instance", self.__create_instance)
+        if self.db_locks:
+            self.step("configuring number of LDAP database locks",
+                      self.__configure_db_locks)
         self.step("adding default schema", self.__add_default_schemas)
         self.step("enabling memberof plugin", self.__add_memberof_module)
         self.step("enabling winsync plugin", self.__add_winsync_module)
@@ -458,6 +463,35 @@ class DsInstance(service.Service):
         inf_fd.close()
         os.remove(paths.DIRSRV_BOOT_LDIF)
 
+    def __configure_db_locks(self):
+        assert self.db_locks and self.db_locks > 0
+        # DS must be turned off before we can set number of DS locks
+        self.stop(self.serverid)
+
+        # update nsslapd-db-locks in DSE.ldif
+        dse_path = '%s/%s' % (paths.ETC_DIRSRV_SLAPD_INSTANCE_TEMPLATE %
+                              self.serverid, upgradeinstance.DSE)
+        fd = tempfile.NamedTemporaryFile()
+        ldif_writer = ldif.LDIFWriter(fd)
+        with open(dse_path, "rb") as in_file:
+            parser = upgradeinstance.ModifyLDIF(in_file, ldif_writer)
+
+            parser.remove_value(
+                "cn=config,cn=ldbm database,cn=plugins,cn=config",
+                "nsslapd-db-locks"
+            )
+            parser.add_value("cn=config,cn=ldbm database,cn=plugins,cn=config",
+                             "nsslapd-db-locks", str(self.db_locks))
+            parser.parse()
+
+        # update content of dse.ldif
+        fd.flush()
+        shutil.copy2(fd.name, dse_path)
+        fd.close()
+
+        # start DS
+        self.start(self.serverid)
+
     def __add_default_schemas(self):
         pent = pwd.getpwnam(DS_USER)
         for schema_fname in IPA_SCHEMA_FILES:
diff --git a/ipaserver/install/server/install.py b/ipaserver/install/server/install.py
index b9bf3f34bdb7c32115e5c6a7038f11f901ab06b8..441f9aeb307300982a89e18bc7165a7c7c710756 100644
--- a/ipaserver/install/server/install.py
+++ b/ipaserver/install/server/install.py
@@ -732,7 +732,8 @@ def install(installer):
                                hbac_allow=not options.no_hbac_allow)
         else:
             ds = dsinstance.DsInstance(fstore=fstore,
-                                       domainlevel=options.domainlevel)
+                                       domainlevel=options.domainlevel,
+                                       db_locks=options.db_locks)
             installer._ds = ds
             ds.create_instance(realm_name, host_name, domain_name,
                                dm_password,
@@ -1514,6 +1515,18 @@ class Server(common.Installable, common.Interactive, core.Composite):
         description="do not configure OpenSSH server",
     )
 
+    db_locks = Knob(
+        int, None,
+        description="number of locks that can be used by the LDAP database "
+                    "(default: 10000)",
+        cli_name='db-locks',
+    )
+
+    @db_locks.validator
+    def db_locks(self, value):
+        if value < 0:
+            raise ValueError("Number of database locks must be positive number")
+
     def __init__(self, **kwargs):
         super(Server, self).__init__(**kwargs)
 
diff --git a/ipaserver/install/server/replicainstall.py b/ipaserver/install/server/replicainstall.py
index 1ad291a1eada080361031a5723a0ea61679fc72e..e45a8a3fc774e3afa44813fee7b2fd22acafae27 100644
--- a/ipaserver/install/server/replicainstall.py
+++ b/ipaserver/install/server/replicainstall.py
@@ -56,7 +56,7 @@ def make_pkcs12_info(directory, cert_name, password_name):
         return None
 
 
-def install_replica_ds(config):
+def install_replica_ds(config, options):
     dsinstance.check_ports()
 
     # if we have a pkcs12 file, create the cert db from
@@ -64,7 +64,7 @@ def install_replica_ds(config):
     # cert
     pkcs12_info = make_pkcs12_info(config.dir, "dscert.p12", "dirsrv_pin.txt")
 
-    ds = dsinstance.DsInstance()
+    ds = dsinstance.DsInstance(db_locks=options.db_locks)
     ds.create_replica(
         realm_name=config.realm_name,
         master_fqdn=config.master_host_name,
@@ -549,7 +549,7 @@ def install(installer):
             ntp.create_instance()
 
         # Configure dirsrv
-        ds = install_replica_ds(config)
+        ds = install_replica_ds(config, options)
 
         # Always try to install DNS records
         install_dns_records(config, options, remote_api)
@@ -801,6 +801,18 @@ class Replica(common.Installable, common.Interactive, core.Composite):
         description="skip connection check to remote master",
     )
 
+    db_locks = Knob(
+        int, None,
+        description="number of locks that can be used by the LDAP database "
+                    "(default: 10000)",
+        cli_name='db-locks',
+    )
+
+    @db_locks.validator
+    def db_locks(self, value):
+        if value < 0:
+            raise ValueError("Number of database locks must be positive number")
+
     def __init__(self, **kwargs):
         super(Replica, self).__init__(**kwargs)
 
-- 
2.4.3

-- 
Manage your subscription for the Freeipa-devel mailing list:
https://www.redhat.com/mailman/listinfo/freeipa-devel
Contribute to FreeIPA: http://www.freeipa.org/page/Contribute/Code

Reply via email to