From 6961cf2e77cca8f3784a6d82cebeb0bb8df1f535 Mon Sep 17 00:00:00 2001 From: Tomas Babej Date: Tue, 6 Aug 2013 17:09:15 +0200 Subject: Perform dirsrv tuning at platform level When configuring the 389 Directory Server instance, we tune it so that number of file descriptors available to the DS is increased from the default 1024 to 8192. There are platform specific steps that need to be conducted differently on systemd compatible platforms and sysV compatible platforms. systemd: set LimitNOFILE to 8192 in /etc/sysconfig/dirsrv.systemd sysV: set ulimit -n 8192 in /etc/sysconfig/dirsrv set ulimit - nofile 8192 in /etc/security/limits.conf https://fedorahosted.org/freeipa/ticket/3823 --- ipapython/platform/fedora16/service.py | 30 ++++++++++++---- ipapython/platform/redhat/service.py | 64 ++++++++++++++++++++++++++++++++++ ipaserver/install/dsinstance.py | 63 +++++++-------------------------- 3 files changed, 100 insertions(+), 57 deletions(-) diff --git a/ipapython/platform/fedora16/service.py b/ipapython/platform/fedora16/service.py index bceb87cd..297e6833 100644 --- a/ipapython/platform/fedora16/service.py +++ b/ipapython/platform/fedora16/service.py @@ -21,7 +21,7 @@ import os import time from ipapython import ipautil, dogtag -from ipapython.platform import base, redhat +from ipapython.platform import base from ipapython.platform.base import systemd from ipapython.platform.fedora16 import selinux from ipapython.ipa_log_manager import root_logger @@ -78,20 +78,38 @@ class Fedora16Service(systemd.SystemdService): # If we wouldn't do this, our instances will not be started as systemd would # not have any clue about instances (PKI-IPA and the domain we serve) at all. # Thus, hook into dirsrv.restart(). + + class Fedora16DirectoryService(Fedora16Service): - def enable(self, instance_name=""): - super(Fedora16DirectoryService, self).enable(instance_name) + + def tune_nofile_platform(self, num=8192, fstore=None): + """ + Increase the number of files descriptors available to directory server + from the default 1024 to 8192. This will allow to support a greater + number of clients out of the box. + + This is a part of the implementation that is systemd-specific. + + Returns False if the setting of the nofile limit needs to be skipped. + """ + dirsrv_systemd = "/etc/sysconfig/dirsrv.systemd" + if os.path.exists(dirsrv_systemd): # We need to enable LimitNOFILE=8192 in the dirsrv@.service # Since 389-ds-base-1.2.10-0.8.a7 the configuration of the # service parameters is performed via # /etc/sysconfig/dirsrv.systemd file which is imported by systemd # into dirsrv@.service unit - replacevars = {'LimitNOFILE':'8192'} - ipautil.inifile_replace_variables(dirsrv_systemd, 'service', replacevars=replacevars) + replacevars = {'LimitNOFILE': str(num)} + ipautil.inifile_replace_variables(dirsrv_systemd, + 'service', + replacevars=replacevars) selinux.restore_context(dirsrv_systemd) - ipautil.run(["/bin/systemctl", "--system", "daemon-reload"],raiseonerr=False) + ipautil.run(["/bin/systemctl", "--system", "daemon-reload"], + raiseonerr=False) + + return True def restart(self, instance_name="", capture_output=True, wait=True): if len(instance_name) > 0: diff --git a/ipapython/platform/redhat/service.py b/ipapython/platform/redhat/service.py index 61511b48..6e8097ca 100644 --- a/ipapython/platform/redhat/service.py +++ b/ipapython/platform/redhat/service.py @@ -25,6 +25,7 @@ from ipapython.ipa_log_manager import root_logger from ipapython.platform import base from ipalib import api + class RedHatService(base.PlatformService): def __wait_for_open_ports(self, instance_name=""): """ @@ -107,11 +108,74 @@ class RedHatHTTPDService(RedHatService): time.sleep(5) self.start(instance_name, capture_output, wait) + +class RedHatDirectoryService(RedHatService): + + # This has been moved from dsinstance.py here to platform-level + # to continue support sysV services + + def tune_nofile_platform(self, num=8192, fstore=None): + """ + Increase the number of files descriptors available to directory server + from the default 1024 to 8192. This will allow to support a greater + number of clients out of the box. + + This is a part of the implementation that is sysV-specific. + + Returns False if the setting of the nofile limit needs to be skipped. + """ + + DS_USER = 'dirsrv' + + # check limits.conf + need_limits = True + + with open("/etc/security/limits.conf", "r") as f: + for line in f: + sline = line.strip() + if not sline.startswith(DS_USER) or sline.find('nofile') == -1: + continue + + # ok we already have an explicit entry for user/nofile + need_limits = False + + # check sysconfig/dirsrv + need_sysconf = True + + with open("/etc/sysconfig/dirsrv", "r") as f: + for line in f: + sline = line.strip() + if not sline.startswith('ulimit') or sline.find('-n') == -1: + continue + + # ok we already have an explicit entry for file limits + need_sysconf = False + + #if sysconf or limits are set avoid messing up and defer to the admin + if need_sysconf and need_limits: + if fstore: + fstore.backup_file("/etc/security/limits.conf") + + with open("/etc/security/limits.conf", "a+") as f: + f.write('%s\t\t-\tnofile\t\t%s\n' % (DS_USER, str(num))) + + with open("/etc/sysconfig/dirsrv", "a+") as f: + f.write('ulimit -n %s\n' % str(num)) + + else: + root_logger.info("Custom file limits are already set! Skipping\n") + return False + + return True + + def redhat_service(name): if name == 'sshd': return RedHatSSHService(name) elif name == 'httpd': return RedHatHTTPDService(name) + elif name == 'dirsrv': + return RedHatDirectoryService(name) return RedHatService(name) class RedHatServices(base.KnownServices): diff --git a/ipaserver/install/dsinstance.py b/ipaserver/install/dsinstance.py index 84e19d15..f543efad 100644 --- a/ipaserver/install/dsinstance.py +++ b/ipaserver/install/dsinstance.py @@ -29,7 +29,7 @@ import base64 import stat from ipapython.ipa_log_manager import * -from ipapython import ipautil, sysrestore, dogtag, ipaldap +from ipapython import ipautil, sysrestore, ipaldap from ipapython import services as ipaservices import service import installutils @@ -815,58 +815,19 @@ class DsInstance(service.Service): number of clients out of the box. """ - # check limits.conf - need_limits = True - fd = open("/etc/security/limits.conf", "r") - lines = fd.readlines() - fd.close() - for line in lines: - sline = line.strip() - if not sline.startswith(DS_USER): - continue - if sline.find('nofile') == -1: - continue - # ok we already have an explicit entry for user/nofile - need_limits = False - - # check sysconfig/dirsrv - need_sysconf = True - fd = open("/etc/sysconfig/dirsrv", "r") - lines = fd.readlines() - fd.close() - for line in lines: - sline = line.strip() - if not sline.startswith('ulimit'): - continue - if sline.find('-n') == -1: - continue - # ok we already have an explicit entry for file limits - need_sysconf = False - - #if sysconf or limits are set avoid messing up and defer to the admin - if need_sysconf and need_limits: - self.fstore.backup_file("/etc/security/limits.conf") - fd = open("/etc/security/limits.conf", "a+") - fd.write('%s\t\t-\tnofile\t\t%s\n' % (DS_USER, str(num))) - fd.close() - - fd = open("/etc/sysconfig/dirsrv", "a+") - fd.write('ulimit -n %s\n' % str(num)) - fd.close() + # Do the platform-specific changes + proceed = ipaservices.knownservices.dirsrv.tune_nofile_platform( + num=num, fstore=self.fstore) - else: - root_logger.info("Custom file limits are already set! Skipping\n") - print "Custom file limits are already set! Skipping\n" - return - - # finally change also DS configuration - # NOTE: dirsrv will not allow you to set max file descriptors unless - # the user limits allow it, so we have to restart dirsrv before - # attempting to change them in cn=config - self.__restart_instance() + if proceed: + # finally change also DS configuration + # NOTE: dirsrv will not allow you to set max file descriptors unless + # the user limits allow it, so we have to restart dirsrv before + # attempting to change them in cn=config + self.__restart_instance() - nf_sub_dict = dict(NOFILES=str(num)) - self._ldap_mod("ds-nfiles.ldif", nf_sub_dict) + nf_sub_dict = dict(NOFILES=str(num)) + self._ldap_mod("ds-nfiles.ldif", nf_sub_dict) def __tuning(self): self.tune_nofile(8192) -- cgit