Blob Blame History Raw
From f632065bf22b3c057a478aac7b04b1904bad2993 Mon Sep 17 00:00:00 2001
From: Sumit Bose <sbose@redhat.com>
Date: Tue, 10 Jan 2012 10:20:35 +0100
Subject: [PATCH 2/3] Add systemd support

---
 config/ctdb.service                                |  19 ++
 config/init_functions                              | 209 +++++++++++----------
 config/systemd/ctdb.systemd                        |  32 ++++
 config/systemd/ctdb_check_persistent_databases.pre |  20 ++
 config/systemd/ctdb_drop_all_public_ips            |  22 +++
 config/systemd/ctdb_set_ctdb_variables.post        |  26 +++
 packaging/RPM/ctdb.spec.in                         |  22 ++-
 7 Dateien geändert, 247 Zeilen hinzugefügt(+), 103 Zeilen entfernt(-)
 create mode 100644 config/ctdb.service
 create mode 100755 config/systemd/ctdb.systemd
 create mode 100755 config/systemd/ctdb_check_persistent_databases.pre
 create mode 100644 config/systemd/ctdb_drop_all_public_ips
 create mode 100644 config/systemd/ctdb_set_ctdb_variables.post

diff --git a/config/ctdb.service b/config/ctdb.service
new file mode 100644
index 0000000..c3423a6
--- /dev/null
+++ b/config/ctdb.service
@@ -0,0 +1,19 @@
+[Unit]
+Description=CTDB
+After=network.target
+
+[Service]
+Type=forking
+LimitCORE=infinity
+PIDFile=/run/ctdbd/ctdbd.pid
+ExecStartPre=/etc/ctdb/systemd/ctdb_drop_all_public_ips
+ExecStartPre=/etc/ctdb/systemd/ctdb_check_persistent_databases.pre
+ExecStart=/etc/ctdb/systemd/ctdb.systemd
+ExecStartPost=/etc/ctdb/systemd/ctdb_set_ctdb_variables.post
+ExecStop=/usr/bin/ctdb shutdown
+ExecStopPost=-/etc/ctdb/systemd/ctdb_drop_all_public_ips
+KillMode=control-group
+Restart=no
+
+[Install]
+WantedBy=multi-user.target
diff --git a/config/init_functions b/config/init_functions
index 6d3e789..db0646b 100644
--- a/config/init_functions
+++ b/config/init_functions
@@ -3,23 +3,23 @@
 build_ctdb_options () {
 
     maybe_set () {
-        # If the 2nd arg is null then return - don't set anything.
-        # Else if the 3rd arg is set and it doesn't match the 2nd arg
-        # then return
-        [ -z "$2" -o \( -n "$3" -a "$3" != "$2" \) ] && return
-
-        val="'$2'"
-        case "$1" in
-            --*) sep="=" ;;
-            -*)  sep=" " ;;
-        esac
-        # For these options we're only passing a value-less flag.
-        [ -n "$3" ] && {
-            val=""
-            sep=""
-        }
-
-        CTDB_OPTIONS="${CTDB_OPTIONS}${CTDB_OPTIONS:+ }${1}${sep}${val}"
+	# If the 2nd arg is null then return - don't set anything.
+	# Else if the 3rd arg is set and it doesn't match the 2nd arg
+	# then return
+	[ -z "$2" -o \( -n "$3" -a "$3" != "$2" \) ] && return
+
+	val="'$2'"
+	case "$1" in
+	    --*) sep="=" ;;
+	    -*)  sep=" " ;;
+	esac
+	# For these options we're only passing a value-less flag.
+	[ -n "$3" ] && {
+	    val=""
+	    sep=""
+	}
+
+	CTDB_OPTIONS="${CTDB_OPTIONS}${CTDB_OPTIONS:+ }${1}${sep}${val}"
     }
 
     [ -z "$CTDB_RECOVERY_LOCK" ] && {
@@ -38,6 +38,7 @@ build_ctdb_options () {
     maybe_set "--event-script-dir"       "$CTDB_EVENT_SCRIPT_DIR"
     maybe_set "--transport"              "$CTDB_TRANSPORT"
     maybe_set "-d"                       "$CTDB_DEBUGLEVEL"
+    maybe_set "--debug-hung-script"      "$CTDB_DEBUG_HUNG_SCRIPT"
     maybe_set "--notification-script"    "$CTDB_NOTIFY_SCRIPT"
     maybe_set "--start-as-disabled"      "$CTDB_START_AS_DISABLED"    "yes"
     maybe_set "--start-as-stopped "      "$CTDB_START_AS_STOPPED"     "yes"
@@ -50,93 +51,107 @@ build_ctdb_options () {
     maybe_set "--max-persistent-check-errors" "$CTDB_MAX_PERSISTENT_CHECK_ERRORS"
 }
 
-check_tdb () {
-    local PDBASE=$1
-
-    test x"$TDBTOOL_HAS_CHECK" = x"1" && {
-        #
-        # Note tdbtool always exits with 0
-        #
-        local OK=`/usr/bin/tdbtool $PDBASE check | grep "Database integrity is OK" | wc -l`
-        test x"$OK" = x"1" || {
-            return 1;
-        }
-
-        return 0;
-    }
-
-    /usr/bin/tdbdump $PDBASE >/dev/null 2>/dev/null || {
-        return $?;
-    }
-
-    return 0;
+# Log given message or stdin to either syslog or a CTDB log file
+do_log ()
+{
+    script_log "ctdb.init" "$@"
 }
 
-check_persistent_databases () {
-    PERSISTENT_DB_DIR="${CTDB_DBDIR:-/var/ctdb}/persistent"
-    mkdir -p $PERSISTENT_DB_DIR 2>/dev/null
-    local ERRCOUNT=$CTDB_MAX_PERSISTENT_CHECK_ERRORS
-
-    test -z "$ERRCOUNT" && {
-        ERRCOUNT="0"
-    }
-    test x"$ERRCOUNT" != x"0" && {
-        return 0;
-    }
-
-    if test -x /usr/bin/tdbtool ; then
-        HAVE_TDBTOOL=1
+select_tdb_checker ()
+{
+    # Find the best TDB consistency check available.
+    use_tdb_tool_check=false
+    if [ -x /usr/bin/tdbtool ] && \
+	echo "help" | /usr/bin/tdbtool | grep -q check ; then
+
+	use_tdb_tool_check=true
+    elif [ -x /usr/bin/tdbtool -a -x /usr/bin/tdbdump ] ; then
+	    do_log <<EOF
+WARNING: The installed 'tdbtool' does not offer the 'check' subcommand.
+ Using 'tdbdump' for database checks.
+ Consider updating 'tdbtool' for better checks!
+EOF
+    elif [ -x /usr/bin/tdbdump ] ; then
+	do_log <<EOF
+WARNING: 'tdbtool' is not available.
+ Using 'tdbdump' to check the databases.
+ Consider installing a recent 'tdbtool' for better checks!
+EOF
     else
-        HAVE_TDBTOOL=0
+	do_log <<EOF
+WARNING: Cannot check databases since neither
+ 'tdbdump' nor 'tdbtool check' is available.
+ Consider installing tdbtool or at least tdbdump!
+EOF
+        return 1
     fi
+}
 
-    if test x"$HAVE_TDBTOOL" = x"1" ; then
-        TDBTOOL_HAS_CHECK=`echo "help" | /usr/bin/tdbtool | grep check | wc -l`
+check_tdb ()
+{
+    _db="$1"
+
+    if $use_tdb_tool_check ; then
+	# tdbtool always exits with 0  :-(
+	if tdbtool "$_db" check 2>/dev/null |
+	    grep -q "Database integrity is OK" ; then
+	    return 0
+	else
+	    return 1
+	fi
     else
-        TDBTOOL_HAS_CHECK=0
+	tdbdump "$_db" >/dev/null 2>/dev/null
+	return $?
     fi
+}
 
-    if test -x /usr/bin/tdbdump ; then
-        HAVE_TDBDUMP=1
-    else
-        HAVE_TDBDUMP=0
-    fi
+check_persistent_databases ()
+{
+    _dir="${CTDB_DBDIR_PERSISTENT:-${CTDB_DBDIR:-/var/ctdb}/persistent}"
+    mkdir -p "$_dir" 2>/dev/null
 
-    if test x"$HAVE_TDBDUMP" = x"0" -a x"$TDBTOOL_HAS_CHECK" = x"0" ; then
-        echo "WARNING: Cannot check persistent databases since"
-        echo "neither 'tdbdump' nor 'tdbtool check' is available."
-        echo "Consider installing tdbtool or at least tdbdump!"
-        return 0
-    fi
+    [ "${CTDB_MAX_PERSISTENT_CHECK_ERRORS:-0}" = "0" ] || return 0
 
-    if test x"$HAVE_TDBDUMP" = x"1" -a x"$TDBTOOL_HAS_CHECK" = x"0" ; then
-        if test x"$HAVE_TDBTOOL" = x"0"; then
-            echo "WARNING: 'tdbtool' is not available. Using 'tdbdump' to"
-            echo "check the persistent databases."
-            echo "Consider installing a recent 'tdbtool' for better checks!"
-        else
-            echo "WARNING: The installed 'tdbtool' does not offer the 'check'"
-            echo "subcommand. Using 'tdbdump' for persistent database checks."
-            echo "Consider updating 'tdbtool' for better checks!"
-        fi
-    fi
+    for _db in $(ls "$_dir/"*.tdb.*[0-9] 2>/dev/null) ; do
+	check_tdb $_db || {
+	    do_log "Persistent database $_db is corrupted! CTDB will not start."
+	    return 1
+	}
+    done
+}
 
-    for PDBASE in `ls $PERSISTENT_DB_DIR/*.tdb.[0-9] 2>/dev/null`; do
-        check_tdb $PDBASE || {
-            echo "Persistent database $PDBASE is corrupted! CTDB will not start."
-            return 1
-        }
+check_non_persistent_databases ()
+{
+    _dir="${CTDB_DBDIR:-/var/ctdb}"
+    mkdir -p "$_dir" 2>/dev/null
+
+    for _db in $(ls "${_dir}/"*.tdb.*[0-9] 2>/dev/null) ; do
+	check_tdb $_db || {
+	    _backup="${_db}.$(date +'%Y%m%d.%H%M%S.%N').corrupt"
+	    do_log <<EOF
+WARNING: database ${_db} is corrupted.
+ Moving to backup ${_backup} for later analysis.
+EOF
+	    mv "$_db" "$_backup"
+
+	    # Now remove excess backups
+	    ls -td "${_db}."*".corrupt" |
+	    tail -n +$((${CTDB_MAX_CORRUPT_DB_BACKUPS:-10} + 1)) |
+	    xargs rm -f
+	    
+	}
     done
 }
 
 set_ctdb_variables () {
     # set any tunables from the config file
-    set | grep ^CTDB_SET_ | cut -d_ -f3- |
+    set | grep ^CTDB_SET_ | cut -d_ -f3- | 
     while read v; do
-        varname=`echo $v | cut -d= -f1`
-        value=`echo $v | cut -d= -f2`
-        ctdb setvar $varname $value || RETVAL=1
-    done || exit 1
+	varname=`echo $v | cut -d= -f1`
+	value=`echo $v | cut -d= -f2`
+	ctdb setvar $varname $value || return 1
+	echo "Set $varname to $value"
+    done
 }
 
 wait_until_ready () {
@@ -144,20 +159,10 @@ wait_until_ready () {
 
     _count=0
     while ! ctdb ping >/dev/null 2>&1 ; do
-        if [ $_count -ge $_timeout ] ; then
-            return 1
-        fi
-        sleep 1
-        _count=$(($_count + 1))
-    done
-}
-
-drop_all_public_ips() {
-    [ -z "$CTDB_PUBLIC_ADDRESSES" ] && {
-        return
-    }
-
-    cat $CTDB_PUBLIC_ADDRESSES | while read IP IFACE REST; do
-        ip addr del $IP dev $IFACE >/dev/null 2>/dev/null
+	if [ $_count -ge $_timeout ] ; then
+	    return 1
+	fi
+	sleep 1
+	_count=$(($_count + 1))
     done
 }
diff --git a/config/systemd/ctdb.systemd b/config/systemd/ctdb.systemd
new file mode 100755
index 0000000..6f29e85
--- /dev/null
+++ b/config/systemd/ctdb.systemd
@@ -0,0 +1,32 @@
+#!/bin/sh
+#
+
+# Avoid using root's TMPDIR
+unset TMPDIR
+
+[ -z "$CTDB_BASE" ] && {
+    export CTDB_BASE="/etc/ctdb"
+}
+
+[ -z "$CTDB_VARDIR" ] && {
+    export CTDB_VARDIR="/var/ctdb"
+}
+
+. $CTDB_BASE/functions
+. $CTDB_BASE/init_functions
+
+. /etc/sysconfig/ctdb
+
+ctdbd=${CTDBD:-/usr/sbin/ctdbd}
+
+if [ "$CTDB_SUPPRESS_COREFILE" = "yes" ]; then
+    ulimit -c 0
+else
+    ulimit -c unlimited
+fi
+
+build_ctdb_options
+
+exec $ctdbd "$CTDB_OPTIONS" >/dev/null 2>&1 </dev/null
+
+exit 1
diff --git a/config/systemd/ctdb_check_persistent_databases.pre b/config/systemd/ctdb_check_persistent_databases.pre
new file mode 100755
index 0000000..7659225
--- /dev/null
+++ b/config/systemd/ctdb_check_persistent_databases.pre
@@ -0,0 +1,20 @@
+#!/bin/sh
+#
+
+# Avoid using root's TMPDIR
+unset TMPDIR
+
+[ -z "$CTDB_BASE" ] && {
+    export CTDB_BASE="/etc/ctdb"
+}
+
+[ -z "$CTDB_VARDIR" ] && {
+    export CTDB_VARDIR="/var/ctdb"
+}
+
+. $CTDB_BASE/functions
+. $CTDB_BASE/init_functions
+
+. /etc/sysconfig/ctdb
+
+check_persistent_databases || exit 1
diff --git a/config/systemd/ctdb_drop_all_public_ips b/config/systemd/ctdb_drop_all_public_ips
new file mode 100644
index 0000000..7a05c6f
--- /dev/null
+++ b/config/systemd/ctdb_drop_all_public_ips
@@ -0,0 +1,22 @@
+#!/bin/sh
+#
+
+# Avoid using root's TMPDIR
+unset TMPDIR
+
+[ -z "$CTDB_BASE" ] && {
+    export CTDB_BASE="/etc/ctdb"
+}
+
+[ -z "$CTDB_VARDIR" ] && {
+    export CTDB_VARDIR="/var/ctdb"
+}
+
+. $CTDB_BASE/functions
+. $CTDB_BASE/init_functions
+
+. /etc/sysconfig/ctdb
+
+drop_all_public_ips
+
+exit 0
diff --git a/config/systemd/ctdb_set_ctdb_variables.post b/config/systemd/ctdb_set_ctdb_variables.post
new file mode 100644
index 0000000..f02ca5d
--- /dev/null
+++ b/config/systemd/ctdb_set_ctdb_variables.post
@@ -0,0 +1,26 @@
+#!/bin/sh
+#
+
+# Avoid using root's TMPDIR
+unset TMPDIR
+
+[ -z "$CTDB_BASE" ] && {
+    export CTDB_BASE="/etc/ctdb"
+}
+
+[ -z "$CTDB_VARDIR" ] && {
+    export CTDB_VARDIR="/var/ctdb"
+}
+
+. $CTDB_BASE/functions
+. $CTDB_BASE/init_functions
+
+. /etc/sysconfig/ctdb
+
+if wait_until_ready ; then
+    set_ctdb_variables
+else
+    exit 1
+fi
+
+exit 0
diff --git a/packaging/RPM/ctdb.spec.in b/packaging/RPM/ctdb.spec.in
index 5bcf005..ad3b118 100644
--- a/packaging/RPM/ctdb.spec.in
+++ b/packaging/RPM/ctdb.spec.in
@@ -1,3 +1,4 @@
+%define with_systemd 0
 %define initdir %{_sysconfdir}/init.d
 Name: ctdb
 Summary: Clustered TDB
@@ -95,12 +96,23 @@ rm -rf $RPM_BUILD_ROOT
 
 # Create the target build directory hierarchy
 mkdir -p $RPM_BUILD_ROOT%{_sysconfdir}/sysconfig
-mkdir -p $RPM_BUILD_ROOT%{_sysconfdir}/init.d
 
 make DESTDIR=$RPM_BUILD_ROOT docdir=%{_docdir} install install_tests
 
 install -m644 config/ctdb.sysconfig $RPM_BUILD_ROOT%{_sysconfdir}/sysconfig/ctdb
+
+%if %{with_systemd}
+mkdir -p $RPM_BUILD_ROOT%{_sysconfdir}/ctdb/systemd
+install -m 755 config/systemd/ctdb_check_persistent_databases.pre $RPM_BUILD_ROOT%{_sysconfdir}/ctdb/systemd
+install -m 755 config/systemd/ctdb_set_ctdb_variables.post $RPM_BUILD_ROOT%{_sysconfdir}/ctdb/systemd
+install -m 755 config/systemd/ctdb_drop_all_public_ips $RPM_BUILD_ROOT%{_sysconfdir}/ctdb/systemd
+install -m 755 config/systemd/ctdb.systemd $RPM_BUILD_ROOT%{_sysconfdir}/ctdb/systemd
+mkdir -p $RPM_BUILD_ROOT%{_unitdir}
+install -m 755 config/ctdb.service $RPM_BUILD_ROOT%{_unitdir}
+%else
+mkdir -p $RPM_BUILD_ROOT%{initdir}
 install -m755 config/ctdb.init $RPM_BUILD_ROOT%{initdir}/ctdb
+%endif
 
 mkdir -p $RPM_BUILD_ROOT%{_docdir}/ctdb/tests/bin
 install -m755 tests/bin/ctdb_transaction $RPM_BUILD_ROOT%{_docdir}/ctdb/tests/bin
@@ -125,7 +137,15 @@ rm -rf $RPM_BUILD_ROOT
 %config(noreplace) %{_sysconfdir}/ctdb/ctdb-crash-cleanup.sh
 %config(noreplace) %{_sysconfdir}/ctdb/gcore_trace.sh
 %config(noreplace) %{_sysconfdir}/ctdb/functions
+%if %{with_systemd}
+%{_sysconfdir}/ctdb/systemd/ctdb_check_persistent_databases.pre
+%{_sysconfdir}/ctdb/systemd/ctdb_set_ctdb_variables.post
+%{_sysconfdir}/ctdb/systemd/ctdb_drop_all_public_ips
+%{_sysconfdir}/ctdb/systemd/ctdb.systemd
+%{_unitdir}/ctdb.service
+%else
 %attr(755,root,root) %{initdir}/ctdb
+%endif
 
 %{_docdir}/ctdb/README
 %{_docdir}/ctdb/COPYING
-- 
1.7.11.7