2

I have an SMF service (Naviserver web server) that depends on postgres to be up and running (i.e. accepting connections) before it should start. Postgres reports it's status as "online" well before it is actually able to accept any connections. This results in the web server failing to start up properly. As far as I can tell SMF is reporting online as soon as the postgres start method is called rather than waiting for some sort of status from postgres indicating it is ready.

SMF Manifest:

 <?xml version=1.0?>
 <!DOCTYPE service_bundle SYSTEM /usr/share/lib/xml/dtd/service_bundle.dtd.1>
 <service_bundle type=manifest name=export>
   <service name=application/database/postgresql_945 type=service version=0>
     <dependency name=network grouping=require_all restart_on=none type=service>
       <service_fmri value=svc:/milestone/network:default/>
     </dependency>
     <dependency name=filesystem-local grouping=require_all restart_on=none type=service>
       <service_fmri value=svc:/system/filesystem/local:default/>
     </dependency>
     <exec_method name=start type=method exec=/lib/svc/method/postgres_945 start timeout_seconds=60/>
     <exec_method name=stop type=method exec=/lib/svc/method/postgres_945 stop timeout_seconds=60/>
     <exec_method name=refresh type=method exec=/lib/svc/method/postgres_945 refresh timeout_seconds=60/>
     <property_group name=general type=framework>
       <propval name=action_authorization type=astring value=solaris.smf.manage.postgres/>
       <propval name=value_authorization type=astring value=solaris.smf.value.postgres/>
     </property_group>
     <instance name=default_64bit enabled=true>
       <method_context>
         <method_credential group=postgres user=postgres/>
       </method_context>
       <property_group name=postgresql_945 type=application>
         <propval name=bin type=astring value=/usr/postgres/9.4.5/bin/>
         <propval name=data type=astring value=/var/postgres-94/data/>
         <propval name=log type=astring value=/var/postgres-94/logs/server.log/>
         <propval name=value_authorization type=astring value=solaris.smf.value.postgres/>
       </property_group>
     </instance>
     <stability value=Evolving/>
     <template>
       <common_name>
         <loctext xml:lang=C>PostgreSQL RDBMS version postgresql_945</loctext>
       </common_name>
       <documentation>
         <manpage title=postgresql_945 section=5/>
         <doc_link name=postgresql.org uri=http://postgresql.org/>
       </documentation>
     </template>
   </service>
 </service_bundle>

Method File:

 #!/sbin/sh
 #
 # Copyright 2008 Sun Microsystems, Inc.  All rights reserved.
 # Use is subject to license terms.
 #
 #ident     @(#)postgresql_945      1.1     08/04/30 SMI

 . /lib/svc/share/smf_include.sh

 # SMF_FMRI is the name of the target service. This allows multiple instances
 # to use the same script.

 getproparg() {
         val=`svcprop -p $1 $SMF_FMRI`
         [ -n $val ] && echo $val
 }

 check_data_dir() {
    if [ ! -d $PGDATA ]; then
            echo Error: postgresql_945/data directory $PGDATA does not exist
            exit $SMF_EXIT_ERR_CONFIG
    fi

    if [ ! -w $PGDATA ]; then
            echo Error: postgresql_945/data directory $PGDATA is not writable by postgres
            exit $SMF_EXIT_ERR_CONFIG
    fi

    if [ ! -d $PGDATA/base -o ! -d $PGDATA/global -o ! -f $PGDATA/PG_VERSION ]; then
            # If the directory is empty we can create the database files
            # on behalf of the user using initdb
            if [ `ls -a $PGDATA | wc -w` -le 2 ]; then
                    echo Notice: postgresql_945/data directory $PGDATA is empty
                    echo Calling '$PGBIN/initdb -D $PGDATA' to initialize

                    $PGBIN/initdb -D $PGDATA
                    if [ $? -ne 0 ]; then
                            echo Error: initdb failed
                            exit $SMF_EXIT_ERR
                    fi
            else
                    echo Error: postgresql_945/data directory $PGDATA is not empty, nor is it a valid PostgreSQL data directory
                    exit $SMF_EXIT_ERR_CONFIG
            fi
    fi
 }

 PGBIN=`getproparg postgresql_945/bin`
 PGDATA=`getproparg postgresql_945/data`
 PGLOG=`getproparg postgresql_945/log`

 if [ -z $SMF_FMRI ]; then
    echo Error: SMF framework variables are not initialized
    exit $SMF_EXIT_ERR
 fi

 if [ -z $PGDATA ]; then
         echo Error: postgresql_945/data property not set
         exit $SMF_EXIT_ERR_CONFIG
 fi

 if [ -z $PGLOG ]; then
         echo Error: postgresql_945/log property not set
         exit $SMF_EXIT_ERR_CONFIG
 fi


 case $1 in
 start)
    check_data_dir
         $PGBIN/pg_ctl -D $PGDATA -l $PGLOG start
         ;;

 stop)
         $PGBIN/pg_ctl -D $PGDATA stop -m fast
         ;;

 refresh)
         $PGBIN/pg_ctl -D $PGDATA reload -m fast
         ;;

 *)
         echo Usage: $0 {start|stop|refresh}
         exit 1
         ;;

 esac
 exit $SMF_EXIT_OK

What can I do to either ensure postgres doesn't report as online until it is accepting connections or check that postgres has actually started from my webserver service. Thanks!

1 Answers1

0

Per the pg_ctl documentation:

Synopsis

...

pg_ctl start [-w] [-t seconds] [-s] [-D datadir] [-l filename] [-o options] [-p path] [-c]

...

Options

...

-w

Wait for the startup or shutdown to complete. Waiting is the default option for shutdowns, but not startups. When waiting for startup, pg_ctl repeatedly attempts to connect to the server. When waiting for shutdown, pg_ctl waits for the server to remove its PID file. pg_ctl returns an exit code based on the success of the startup or shutdown.

-W

Do not wait for startup or shutdown to complete. This is the default for start and restart modes.

...

Examples

Starting the Server

...

To start the server, waiting until the server is accepting connections:

$ pg_ctl -w start

Since the $PGBIN/pg_ctl -D $PGDATA -l $PGLOG start command has the implicit -W option, adding the -w option to the command in the PostgrSQL service method file should do what you want, as long as your web server service is dependent on the PostgreSQL service:

$PGBIN/pg_ctl -D $PGDATA -l $PGLOG -w start

Just remember to check if the file gets changed if you patch/update the server.

Andrew Henle
  • 1,232
  • 9
  • 11