File functions of Package sapconf.4964

#
# @@funcdir@@/functions
#
# Copyright (c) 2007 SuSE Linux Products GmbH, Nuernberg, Germany.
#
#     This library is free software; you can redistribute it and/or modify it
#     under the terms of the GNU Lesser General Public License as published by
#     the Free Software Foundation; either version 2.1 of the License, or (at
#     your option) any later version.
#
#     This library is distributed in the hope that it will be useful, but
#     WITHOUT ANY WARRANTY; without even the implied warranty of
#     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
#     Lesser General Public License for more details.
#
#     You should have received a copy of the GNU Lesser General Public
#     License along with this library; if not, write to the 
#     Free Software Foundation 51 Franklin Street, Fifth Floor
#     Boston, MA 02110-1301 USA
#
# Mission: Shell functions used to configure the system for the needs
#	   and requirements of SAP systems. Based on scripts written
#	   by Holger Achtziger, and Wolfgang Rosenauer (sapinit-1.1.1),
#	   Alexander Hass and Uwe Menges (sapinit.sh), and Dennis Olsson.
#
# Author:  Werner Fink <werner@suse.de>, 2007
#          Fabian Hereschel <fabian.herschel@suse.com>, 2014
#
# Please send feedback to http://www.suse.de/feedback
#

#
# Check if file of the second argument exist if not create one
# and copy the file which name is hold by the first variable
# 
tmp_check () {
    local file=${1}; shift
    local retr=${1}; shift

    test -z "${!retr}" || return 0
    eval ${retr}=$(mktemp ${file}.XXXXXXXXXX)

    if test -z "${!retr}" -o ! -e "${!retr}"; then
	type rc_failed &> /dev/null && rc_failed 1
	return 1
    fi
    trap "rm -f ${!retr}" EXIT
    cat ${file} > ${!retr}
}

#
# Check exit status and if possible remember it
#
ret_check () {
    local stat=$?

    test $stat -ne 0 || return 0
    type rc_failed &> /dev/null && rc_failed 1
}

#
# Sets the tmpfs size to the given values if and only if
# the current used size is less then. The argument is the
# name of the variable which holds the requested tmpfs size.
#
tmpfs_size () {
    local -i reqs=${!1}
    local -i size=0
    local -i match=0
    local -a tmpfs=()
    local block point type optns rest shm tmp

    #
    # check all filesystems with type tmpfs with their mount-points and options and select
    #    /dev/shm (first selection) or /dev (fallback)
    #
    POINT=""
    while read block point type optns rest; do
	case "$type" in
		tmpfs)
			# tmpfs[$((match++))]=${point}:${optns}
			case "$point" in
				/dev/shm )	# priorizing this one
						POINT=$point; OPTNS=$optns
						;;
				/dev )		# use that only as fallback
						if [ -n "$POINT" ]; then
							POINT=$point; OPTNS=$optns
						fi
						;;
			esac
	esac
    done < <(exec grep -E '^[a-z]+[[:blank:]]+/dev' /proc/mounts)

    point=$POINT; optns=$OPTNS

    if test -z "$point" ; then
	echo "${0##*/}: ${FUNCNAME}() no file system for /dev/shm found" 1>&2
	return 1;
    fi

    if type -p stat &> /dev/null ; then
	tmp=$(exec stat -fc '(%b*%S)>>10' ${point})
    else
	match=0
	while read block tmp rest; do
	    test $((match++)) -eq 0 && continue
	    break
	done < <(exec df --no-sync -lk ${point})
    fi

    # Do the calculation and round up to full Gigs
    let size=$tmp
    let size=$(((size+(1<<19))/(1<<20)))

    match=0
    if test $reqs -gt $size ; then
	mount -o remount,${optns},size=${reqs}g ${point}
	match=$?
    fi

    return $match
}

#
# Return the total of the virtual memory in giga of bytes
#
virtual_memory () {
    local -i total=$(awk -v t=0 '/^(Mem|Swap)Total:/ {t+=$2} END {print t}' < /proc/meminfo)
    if test $? -ne 0 ; then
	echo "${0##*/}: ${FUNCNAME}() Can not read /proc/meminfo" 1>&2
	echo 0
	return 1;
    fi
    # Do the calculation and round up to full Gigs
    let total=$(((total+(1<<19))/(1<<20)))

    echo $total
}

#
# Return the kB of the systems page size
#
page_size () {
    local getconf=$(type -p getconf 2> /dev/null)
    if test -z "$getconf" ; then
	echo 4
    else
	local -i psz=$($getconf PAGESIZE)
	echo $((psz>>10))
    fi
}

#
# Return the size of unsigend longs on this system
#
ulong_max () {
    local getconf=$(type -p getconf 2> /dev/null)
    local ret;
    if test -x "$getconf" ; then
        ret=$(getconf ULONG_MAX 2> /dev/null)
    fi
    if test -z "$ret" ; then
	case "$(uname -i)" in
	ia64|x86_64|ppc64|s390x)
	    ret=18446744073709551615 ;;
	*)
	    ret=4294967295 ;;
	esac
    fi
    echo $ret
}

#
# Read the given kernel parameter from /proc/sys/ and assign
# it to the trailing shell variables
#
read_sysctl () {
   local file=/proc/sys/${1//\./\/}
   shift
   read -t 1 ${1+"$@"} < ${file}
}

#
# Add or change values in /etc/sysctl.conf, the first argument
# should be the name of variable holding the name of the used
# sysctl.conf, the second argument should be the name of variable
# which may hold the name of the new sysctl.conf. The third
# argument is the sysctl parameter name all followed by the
# names of the variables which hold the values to be added or
# changed.
#
edit_sysctl () {
   local file=${!1}; shift
   local retr=${1}; shift
   local parm=${1}; shift
   local date=${DATE}
   local s='[[:blank:]]*'
   local vals v

   test -n "${date}"  || date=$(date -u +"%Y-%m-%d %H:%M:%S %Z")
   test -n "${file}"  || file=/etc/sysctl.conf
   test -z "${!retr}" || file=${!retr}

   # bash 2.05b doesn't know about ${!name[@]}
   for v; do vals=${vals:+$vals }${!v}; done

   if grep -q -E "^${s}${parm}" ${file} ; then
	if ! grep -q -E "^${s}${parm}${s}=${s}${vals// /$s}" ${file} ; then
	    local mod="# Modified for SAP on $date"
	    tmp_check ${file} ${retr} || return 1
	    sed -ri "s@^${s}(${parm}${s}=${s}.*)@${mod}\n#\1\n${parm} = ${vals}@" ${!retr}
	    ret_check
	fi
   else
	tmp_check ${file} ${retr} || return 1
	if ! grep -q -E "^#${s}(Added|Modified)${s}for${s}SAP" ${file}; then
	    echo "# Added for SAP on $date" >> ${!retr}
	    ret_check
	fi
	echo "${parm} = "${vals} >> ${!retr}
	ret_check
   fi
}

#
# Add or change values in /etc/security/limits.conf, the first
# argument should be the name of variable holding the name of
# the used limits.conf, the second argument should be the name
# of variable which may hold the name of the new limits.conf.
# The remaining arguments is ia line as described in limit.conf(5).
#
edit_limits () {
   local   file=${!1}; shift
   local   retr=${1}; shift
   local domain=${1}; shift
   local   type=${1}; shift
   local   item=${1}; shift
   local  value=${1}
   local date=${DATE}
   local s='[[:blank:]]*'
   local t='[[:blank:]]+'
   local indicator

   test -n "${date}"  || date=$(date -u +"%Y-%m-%d %H:%M:%S %Z")
   test -n "${file}"  || file=/etc/security/limits.conf
   test -z "${!retr}" || file=${!retr}

   indicator="${s}${domain}${t}${type}${t}${item}"
   if grep -q -E "^${indicator}" ${file} ; then
	if ! grep -q -E "^${indicator}${t}${value}" ${file} ; then
	    local mod="# Modified for SAP on $date"
	    tmp_check ${file} ${retr} || return 1
	    sed -ri "s|^(${indicator}${t}).*|${mod}\n#&\n\1${value}|" ${!retr}
	    ret_check
	fi
   else
	local line=$(printf "%-16s %-7s %-15s %s\n" $domain $type $item $value)
	local  end="^#${t}[Ee]nd${t}of${t}file"
	tmp_check ${file} ${retr} || return 1
	if ! grep -q -E "^#${s}(Added|Modified)${s}for${s}SAP" ${file}; then
	    if grep -q -E "${end}" ${file} ; then
		sed -ri "s|${end}|# Added for SAP on $date\n&|" ${!retr}
		ret_check
	    else
	        echo -e "# Added for SAP on $date" >> ${!retr}
		ret_check
	    fi
	fi

	if grep -q -E "${end}" ${file} ; then
	    sed -ri "s|${end}|${line}\n&|" ${!retr}
	    ret_check
	else
	    echo "${line}" >> ${!retr}
	    ret_check
	fi
   fi
}

#
# Clean out old sysctl.conf file
#
CleanSYSCTLconf() {
    local file=${!1}; shift
    local retr=${1} ; shift
    local marks
    local -i cnt1
    local -i cnt2
    local -r s="[[:space:]]*"
    local -r b="[[:space:]]+"
    local -r MarkerPattern="^#${s}(Added|Modified)${b}by${b}.*(SAPinit)(.sh)?${b}on${b}"

    type -p grep   &> /dev/null || return 0
    type -p awk    &> /dev/null || return 0
    type -p mktemp &> /dev/null || return 0

    grep -q -E "${MarkerPattern}"		${file} || return 0
    grep -q -E "^${s}kernel\.sem${s}=${s}*-1"	${file} || return 0

    marks="$(sed -nr "s/${MarkerPattern}(.*)\.$/\4/p" < "${file}" 2>/dev/null)"
    cnt1=$(echo "${marks}"|wc -l)
    cnt2=$(echo "${marks}"|sort -u|wc -l)

    if test $cnt1 -eq $cnt2; then
	return 0
    fi
    eval ${retr}=$(mktemp ${file}.XXXXXXXXXX)
    if test -z "${!retr}" -o ! -e "${!retr}"; then
	return 1
    fi
    trap "rm -f ${!retr}" EXIT

    awk -v MarkerPattern="${MarkerPattern}" -f - -- "${file}" > "${!retr}" <<-"EOF"
	BEGIN {
	    Parameters="(vm\\.max_map_count|kernel\\.(sem|shmall|shmmax))"
	    FS="[[:space:]]*=[[:space:]]*"
	    LastLine=0
	    SAPinit=0
	    Marker=""
	}
	{
	    if ($0 ~ MarkerPattern) {
		if (Marker != $0) {
		    SAPinit=1
		    Marker=$0
		    print Marker
		}
		next
	    }
	    if (SAPinit) {
		if ($0 ~ /^$/) {
		    LastLine=1
		    next
		}
		if (($1 ~ /^kernel.sem/) && ($2 ~ /-1/)) {
		    LastLine=1
		    next
		}
		if (($1 ~ /^#/) && ($1 !~ Parameters)) {
		    SAPinit=0
		    print ""
		}
	    }
	    LastLine=0
	    print $0
	}
	END {
	    if (LastLine) { print "" }
	}
	EOF

    if type -p cmp &> /dev/null && cmp -s "${file}" "${!retr}" ; then
	eval ${retr}=""
	rm -f "${!retr}"
	trap - EXIT
    fi
}
# End of the file
openSUSE Build Service is sponsored by