From d8840c2b52824a84fd3d1d1717072095931d515b Mon Sep 17 00:00:00 2001 From: William Brown Date: Oct 23 2019 00:39:58 +0000 Subject: Add test for non-db files causing recovery issues --- diff --git a/dirsrvtests/tests/suites/backend/50664_non_db_files_test.py b/dirsrvtests/tests/suites/backend/50664_non_db_files_test.py new file mode 100644 index 0000000..1b6297b --- /dev/null +++ b/dirsrvtests/tests/suites/backend/50664_non_db_files_test.py @@ -0,0 +1,48 @@ +# --- BEGIN COPYRIGHT BLOCK --- +# Copyright (C) 2019 William Brown +# All rights reserved. +# +# License: GPL (version 3 or any later version). +# See LICENSE for details. +# --- END COPYRIGHT BLOCK --- +# +import os +import pytest +from lib389.topologies import topology_st + +pytestmark = pytest.mark.tier1 + +def test_non_db_files_recovery(topology_st): + """In https://pagure.io/389-ds-base/issue/50664 it was + reported that when non-db files are present, this can prevent + the server from starting. + + :id: be9ce986-dd1c-421f-af30-6e4bd39e953b + :setup: Single instance + :steps: 1. Kill the server with -9 to get to recovery + 2. Add a non-db file or directory + 3. Touch the guardian file to trigger the db recovery + 4. Start the server + :expectedresults: + 1. Server stops + 2. File is created + 3. File is created + 4. Server starts + """ + + topology_st.standalone.unsafe_kill() + + # Make the files + bogus_path = os.path.join(topology_st.standalone.ds_paths.db_dir, 'ldif') + os.makedirs(bogus_path) + + guard_path = os.path.join(topology_st.standalone.ds_paths.db_dir, 'guardian') + with open(guard_path, 'w') as f: + pass + + import time + print('attach now') + time.sleep(45) + + topology_st.standalone.start() + diff --git a/dirsrvtests/tests/suites/backend/__init__.py b/dirsrvtests/tests/suites/backend/__init__.py new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/dirsrvtests/tests/suites/backend/__init__.py diff --git a/src/lib389/lib389/__init__.py b/src/lib389/lib389/__init__.py index 0d1ab57..7dab683 100644 --- a/src/lib389/lib389/__init__.py +++ b/src/lib389/lib389/__init__.py @@ -1210,6 +1210,34 @@ class DirSrv(SimpleLDAPObject, object): os.kill(pid, signal.SIGKILL) self.state = DIRSRV_STATE_OFFLINE + def unsafe_kill(self): + ''' + Forcefully end the DS process. This uses the kill -9 signal + which MAY cause the process to lose data or other such risks. You + should only use this when absolutely required! + + @param self + @return None + ''' + if self.status() is False: + return + + if self.with_systemd(): + self.log.debug("systemd status -> True") + # Do systemd things here ... + subprocess.check_call(["systemctl", + "kill", + "dirsrv@%s" % self.serverid]) + else: + self.log.debug("systemd status -> False") + pid = pid_from_file(self.ds_paths.pid_file) + if pid == 0 or pid is None: + raise ValueError("Failed to stop DS") + os.kill(pid, signal.SIGKILL) + self.log.debug("Killed ns-slapd process") + self.state = DIRSRV_STATE_OFFLINE + + def status(self): """ Determine if an instance is running or not.