205 lines
		
	
	
		
			6.4 KiB
		
	
	
	
		
			Plaintext
		
	
	
	
	
	
			
		
		
	
	
			205 lines
		
	
	
		
			6.4 KiB
		
	
	
	
		
			Plaintext
		
	
	
	
	
	
| #!/sbin/openrc-run
 | |
| # Copyright 1999-2023 Gentoo Foundation
 | |
| # Distributed under the terms of the GNU General Public License v2
 | |
| 
 | |
| extra_started_commands="reload promote"
 | |
| 
 | |
| PG_CTL="/usr/@LIBDIR@/postgresql-@SLOT@/bin/pg_ctl"
 | |
| PG_CONTROLDATA="/usr/@LIBDIR@/postgresql-@SLOT@/bin/pg_controldata"
 | |
| 
 | |
| description="PostgreSQL @SLOT@ -- the world's most advanced open source database --
 | |
| ${RC_SERVICE} is a wrapper around pg_ctl with additional administrative checks
 | |
| and convenience"
 | |
| 
 | |
| # pid is read by fscanf(3) with the first argument which should be integer,
 | |
| # so this multiple line pidfile can be used.
 | |
| PIDFILE="${DATA_DIR%/}/postmaster.pid"
 | |
| 
 | |
| get_config() {
 | |
|     [ -f "${PGDATA%/}/postgresql.conf" ] || return 1
 | |
| 
 | |
|     eval echo $(sed -e 's:#.*::' "${PGDATA%/}/postgresql.conf" \
 | |
|         | awk '$1 == "'$1'" { print ($2 == "=" ? $3 : $2) }')
 | |
| }
 | |
| 
 | |
| depend() {
 | |
|     use net
 | |
|     provide postgresql
 | |
| 
 | |
|     if [ "$(get_config log_destination)" = "syslog" ] ; then
 | |
|         use logger
 | |
|     fi
 | |
| }
 | |
| 
 | |
| configured_port=${PGPORT}
 | |
| config_port() {
 | |
|     local port=$(get_config port)
 | |
|     [ -z ${port} ] || configured_port=${port}
 | |
| }
 | |
| 
 | |
| checkconfig() {
 | |
|     # Check that DATA_DIR has been set
 | |
|     if [ -z "${DATA_DIR}" ] ; then
 | |
|         eerror "DATA_DIR not set"
 | |
|         eerror "HINT: Perhaps you need to update /etc/conf.d/postgresql-@SLOT@"
 | |
|         return 1
 | |
|     fi
 | |
| 
 | |
|     # Check that DATA_DIR exists
 | |
|     if [ ! -d "${DATA_DIR}" ] ; then
 | |
|         eerror "Directory not found: ${DATA_DIR}"
 | |
|         eerror "HINT: Ensure that DATA_DIR points to the right path."
 | |
|         eerror "HINT: Or perhaps you need to create the database cluster:"
 | |
|         eerror "    emerge --config dev-db/postgresql:@SLOT@"
 | |
|         return 1
 | |
|     fi
 | |
| 
 | |
|     # Check for the existence of PostgreSQL's config files, and set the
 | |
|     # proper mode and ownership.
 | |
|     # Only three files should be checked as potentially other files
 | |
|     # may be in PGDATA that should not be touched.
 | |
|     local file
 | |
|     for file in postgresql pg_hba pg_ident ; do
 | |
|         file="${PGDATA%/}/${file}.conf"
 | |
|         if [ -f "${file}" ] ; then
 | |
|             checkpath -f -m 0600 -o postgres:postgres "${file}"
 | |
|         else
 | |
|             eerror "${file} not found"
 | |
|             eerror "HINT: mv ${DATA_DIR%/}/*.conf ${PGDATA}"
 | |
|             return 1
 | |
|         fi
 | |
|     done
 | |
| 
 | |
|     # Set the proper permission for the socket paths and create it if
 | |
|     # it doesn't exist.
 | |
|     set -f
 | |
|     local IFS=',' s
 | |
|     for s in ${PG_SOCKET_DIRECTORIES}; do
 | |
|         checkpath -d -m 1775 -o root:postgres "${s}"
 | |
|         if [ -e "${s%/}/.s.PGSQL.${configured_port}" ] ; then
 | |
|             eerror "Socket conflict."
 | |
|             eerror "A server is already listening on:"
 | |
|             eerror "    ${s%/}/.s.PGSQL.${configured_port}"
 | |
|             eerror "HINT: Change PGPORT to listen on a different socket."
 | |
|             return 1
 | |
|         fi
 | |
|     done
 | |
|     set +f
 | |
| }
 | |
| 
 | |
| start() {
 | |
|     config_port
 | |
|     checkconfig || return 1
 | |
| 
 | |
|     ebegin "Starting PostgreSQL @SLOT@"
 | |
| 
 | |
|     rm -f "${DATA_DIR%/}/postmaster.pid"
 | |
| 
 | |
|     export PGPORT=${configured_port}
 | |
|     eval "${PG_EXTRA_ENV:+export} ${PG_EXTRA_ENV}"
 | |
|     start-stop-daemon --start --user postgres:postgres \
 | |
|         --pidfile "${PIDFILE}" \
 | |
|         --exec "${PG_CTL}" -- \
 | |
|         start \
 | |
|             -s -w -t ${START_TIMEOUT} -l "${DATA_DIR%/}/postmaster.log" \
 | |
|             -D "${PGDATA}" \
 | |
|             -o "-c data_directory=\"${DATA_DIR}\" \
 | |
|                 -c unix_socket_directories=\"${PG_SOCKET_DIRECTORIES}\" \
 | |
|                 ${PGOPTS}"
 | |
| 
 | |
|     local retval=$?
 | |
| 
 | |
|     if [ ${retval} -ne 0 ] ; then
 | |
|         eerror "Check the log for a possible explanation of the above error."
 | |
|         eerror "The log may be located at:"
 | |
|         eerror "    ${DATA_DIR%/}/postmaster.log"
 | |
|         eerror "Or wherever you configured PostgreSQL @SLOT@ to log."
 | |
|     fi
 | |
| 
 | |
|     eend ${retval}
 | |
| }
 | |
| 
 | |
| stop() {
 | |
|     : "${NICE_TIMEOUT:=5}"
 | |
|     : "${RUDE_TIMEOUT:=5}"
 | |
|     : "${FORCE_TIMEOUT:=5}"
 | |
| 
 | |
|     # The SIGTERM is the default signal for s-s-d, and corresponds to the
 | |
|     # default stop mode 'smart' of postgres.
 | |
|     local retry="SIGTERM/${NICE_TIMEOUT}"
 | |
|     local seconds=${NICE_TIMEOUT}
 | |
| 
 | |
|     if yesno RUDE_QUIT; then
 | |
|       # retry fast stop mode after NICE_TIMEOUT
 | |
|       retry="${retry}/SIGINT/${RUDE_TIMEOUT}"
 | |
|       seconds=$(( ${seconds} + ${RUDE_TIMEOUT} ))
 | |
|     fi
 | |
|     if yesno FORCE_QUIT; then
 | |
|       # retry immediate stop mode after RUDE_TIMEOUT
 | |
|       retry="${retry}/SIGQUIT/${FORCE_TIMEOUT}"
 | |
|       seconds=$(( ${seconds} + ${FORCE_TIMEOUT} ))
 | |
|     fi
 | |
| 
 | |
|     ebegin "Stopping PostgreSQL @SLOT@ (this can take up to ${seconds} seconds)"
 | |
|     start-stop-daemon --stop --retry ${retry} --pidfile ${PIDFILE}
 | |
|     local retval=$?
 | |
| 
 | |
|     if [ ${retval} -eq 0 ] ; then
 | |
|         # clean up remaining socket files for the case which postgres has crashed before stopping
 | |
|         config_port
 | |
|         local IFS=',' s
 | |
|         for s in ${PG_SOCKET_DIRECTORIES}; do
 | |
|             if ls -1 "${s%/}/.s.PGSQL.${configured_port}"* >/dev/null 2>&1; then
 | |
|                 ewarn "cleaning up remaining socket files in '$s'"
 | |
|                 rm -vf "${s%/}/.s.PGSQL.${configured_port}"*
 | |
|             fi
 | |
|         done
 | |
|     fi
 | |
|     eend ${retval}
 | |
| }
 | |
| 
 | |
| status() {
 | |
|     default_status
 | |
|     local retval=$?
 | |
|     local postopts_file="${DATA_DIR%/}/postmaster.opts"
 | |
|     if [ $retval -eq 0 -a -r "${postopts_file}" ] ; then
 | |
|         einfo "opts: $(cat ${postopts_file})"
 | |
|     fi
 | |
| }
 | |
| 
 | |
| description_reload="Simply sends the postgres process a SIGHUP signal, causing
 | |
|            it to reread its configuration files (postgresql.conf, pg_hba.conf,
 | |
|            etc.). This allows changing of configuration-file options that do not
 | |
|            require a complete restart to take effect."
 | |
| reload() {
 | |
|     ebegin "Reloading PostgreSQL @SLOT@ configuration"
 | |
|     start-stop-daemon \
 | |
|         --signal SIGHUP \
 | |
|         --user postgres:postgres \
 | |
|         --pidfile "${PIDFILE}"
 | |
|     eend $?
 | |
| }
 | |
| 
 | |
| description_promote="If the server is in standby, it is commanded to exit
 | |
|             recovery and begin read-write operations."
 | |
| promote() {
 | |
|     ebegin "Promoting PostgreSQL @SLOT@"
 | |
|     local retval=1
 | |
|     if "${PG_CONTROLDATA}" -D "${DATA_DIR}" 2>/dev/null \
 | |
|         | grep 'in archive recovery' >/dev/null 2>&1; then
 | |
|         local promotefile="${DATA_DIR%/}/promote"
 | |
|         checkpath -q -f -m 644 -o postgres:postgres "${promotefile}" && \
 | |
|             start-stop-daemon \
 | |
|                 --signal SIGUSR1 \
 | |
|                 --user postgres:postgres \
 | |
|                 --pidfile "${PIDFILE}"
 | |
|         retval=$?
 | |
|         if [ ${retval} -ne 0 ] ; then
 | |
|             rm -f "${promotefile}"
 | |
|         fi
 | |
|     else
 | |
|         eerror "server is not in standby mode"
 | |
|     fi
 | |
|     eend ${retval}
 | |
| }
 |