Index: src/bin/pg_ctl/pg_ctl.sh =================================================================== RCS file: /home/ncvs/pgsql/pgsql-server/src/bin/pg_ctl/pg_ctl.sh,v retrieving revision 1.32 diff -u -r1.32 pg_ctl.sh --- src/bin/pg_ctl/pg_ctl.sh 20 Mar 2003 05:00:14 -0000 1.32 +++ src/bin/pg_ctl/pg_ctl.sh 18 Jul 2003 23:04:03 -0000 @@ -98,12 +98,12 @@ fi # Check if needed programs actually exist in path -if [ -x "$self_path/postmaster" ] && [ -x "$self_path/psql" ]; then +if [ -x "$self_path/postmaster" ] && [ -x "$self_path/pg_ping" ]; then PGPATH="$self_path" -elif [ -x "$bindir/postmaster" ] && [ -x "$bindir/psql" ]; then +elif [ -x "$bindir/postmaster" ] && [ -x "$bindir/pg_ping" ]; then PGPATH="$bindir" else - echo "The programs 'postmaster' and 'psql' are needed by $CMDNAME but" 1>&2 + echo "The programs 'postmaster' and 'pg_ping' are needed by $CMDNAME but" 1>&2 echo "were not found in the directory '$bindir'." 1>&2 echo "Check your installation." 1>&2 exit 1 @@ -358,16 +358,12 @@ fi fi -# FIXME: This is horribly misconceived. -# 1) If password authentication is set up, the connection will fail. -# 2) If a virtual host is set up, the connection may fail. -# 3) If network traffic filters are set up tight enough, the connection +# FIXME: This is less misconceived, but not perfect. +# 1) If a virtual host is set up, the connection may fail. +# 2) If network traffic filters are set up tight enough, the connection # may fail. -# 4) When no Unix domain sockets are available, the connection will -# fail. (Using TCP/IP by default ain't better.) -# 5) If the dynamic loader is not set up correctly (for this user/at -# this time), psql will fail (to find libpq). -# 6) If psql is misconfigured, this may fail. +# 3) If the dynamic loader is not set up correctly (for this user/at +# this time), pg_ping will fail (to find libpq). # Attempt to use the right port # Use PGPORT if set, otherwise look in the configuration file @@ -384,7 +380,13 @@ $silence_echo $ECHO_N "waiting for postmaster to start..."$ECHO_C while : do - if "$PGPATH/psql" -p $PGPORT -l >/dev/null 2>&1 + if [ -z "$PGPORT" ];then + PGPORT_OPT="" + else + PGPORT_OPT="-p $PGPORT" + fi + + if "$PGPATH/pg_ping" -q $PGPORT_OPT then break; else Index: src/bin/Makefile =================================================================== RCS file: /home/ncvs/pgsql/pgsql-server/src/bin/Makefile,v retrieving revision 1.39 diff -u -r1.39 Makefile --- src/bin/Makefile 3 Sep 2002 21:45:43 -0000 1.39 +++ src/bin/Makefile 18 Jul 2003 19:56:09 -0000 @@ -15,7 +15,7 @@ DIRS := initdb initlocation ipcclean pg_ctl pg_dump pg_id \ psql scripts pg_config pg_controldata pg_resetxlog \ - pg_encoding + pg_encoding pg_ping ifeq ($(with_tcl), yes) DIRS += pgtclsh Index: doc/src/sgml/ref/allfiles.sgml =================================================================== RCS file: /home/ncvs/pgsql/pgsql-server/doc/src/sgml/ref/allfiles.sgml,v retrieving revision 1.54 diff -u -r1.54 allfiles.sgml --- doc/src/sgml/ref/allfiles.sgml 27 Jun 2003 14:45:25 -0000 1.54 +++ doc/src/sgml/ref/allfiles.sgml 18 Jul 2003 23:48:20 -0000 @@ -116,6 +116,7 @@ + Index: doc/src/sgml/ref/pg_ping-ref.sgml =================================================================== RCS file: doc/src/sgml/ref/pg_ping-ref.sgml diff -N doc/src/sgml/ref/pg_ping-ref.sgml --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ doc/src/sgml/ref/pg_ping-ref.sgml 18 Jul 2003 23:42:20 -0000 @@ -0,0 +1,198 @@ + + + + + pg_ping + 1 + Application + + + + pg_ping + Test to see if a PostgreSQL database is up or down + + + + + pg_ping + connection-option + -d dbname + -h host + -p port + -q + -w connection timeout + -v + + + + + + Description + + + pg_ping is a utility for determining + whether or not a specified PostgreSQL + database is up and running or down. If up, + pg_ping exits with a 0 return status: if + down, it exists with an exit code of 1. + + + + pg_ping uses + libpq and can be used to test whether + any local or remote PostgreSQL database + is up or down. Any files, environment variables, or settings that + are applicable to libpq apply to + pg_ping. + + + + + + Options + + + pg_ping accepts the following command-line arguments: + + + + dbname + + + Specifies the database name to connect to. + + + + + + host + + + Specifies the host to connect to. + + + + + + port + + + Specifies the port to connect to. + + + + + + + + + Decreases the verbosity of pg_ping. + + + + + + connection_timeout + + + Specifies the connection timeout. + + + + + + + + + Increases the verbosity of pg_ping. + + + + + + + + + + + Diagnostics + + + The output of pg_ping is dependent on + the verbosity, however, by default, + pg_ping will emmit the following + output: + + + UP + + + The database is up and running and able to accept connections. + + + + + + DOWN + + + The database is down and unavailable for one reason or another. + + + + + + + + + + + Examples + + + To see if the database on db.example.com is up: + +$ pg_ping -h db.example.com + + + + + To use pg_ping in a script and + silently, use the -q option to rely on the exit + code: + +$ pg_ping -q -h db.example.com + + + + + + + See Also + + + + + + + + + Index: doc/src/sgml/ref/pg_ctl-ref.sgml =================================================================== RCS file: /home/ncvs/pgsql/pgsql-server/doc/src/sgml/ref/pg_ctl-ref.sgml,v retrieving revision 1.22 diff -u -r1.22 pg_ctl-ref.sgml --- doc/src/sgml/ref/pg_ctl-ref.sgml 25 Mar 2003 16:15:42 -0000 1.22 +++ doc/src/sgml/ref/pg_ctl-ref.sgml 18 Jul 2003 23:45:59 -0000 @@ -214,9 +214,9 @@ Wait for the start or shutdown to complete. Times out after 60 seconds. This is the default for shutdowns. A successful shutdown is indicated by removal of the PID - file. For starting up, a successful psql -l + file. For starting up, a successful pg_ping indicates success. pg_ctl will attempt to - use the proper port for psql. If the environment variable + use the proper port for pg_ping. If the environment variable PGPORT exists, that is used. Otherwise, it will see if a port has been set in the postgresql.conf file. If neither of those is used, it will use the default port that @@ -259,7 +259,7 @@ - Default port for (used by the -w option). + Default port for (used by the -w option). @@ -321,7 +321,7 @@ This file, located in the data directory, is parsed to find the - proper port to use with psql when the + proper port to use with pg_ping when the is given in mode. Index: doc/src/sgml/release.sgml =================================================================== RCS file: /home/ncvs/pgsql/pgsql-server/doc/src/sgml/release.sgml,v retrieving revision 1.198 diff -u -r1.198 release.sgml --- doc/src/sgml/release.sgml 17 Jul 2003 00:55:36 -0000 1.198 +++ doc/src/sgml/release.sgml 18 Jul 2003 23:50:49 -0000 @@ -55,6 +55,7 @@ Long options for psql and pg_dump are now available on all platforms Read-only transactions Object owners can allow grantees to grant the privilege to others (grant option) +Add "pg_ping" utility to fix pg_ctl -w when an authentication scheme is in use ]]> Index: src/bin/pg_ping/Makefile =================================================================== RCS file: src/bin/pg_ping/Makefile diff -N src/bin/pg_ping/Makefile --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ src/bin/pg_ping/Makefile 18 Jul 2003 22:43:52 -0000 @@ -0,0 +1,38 @@ +#------------------------------------------------------------------------- +# +# Makefile for src/bin/pg_ping +# +# Copyright (C) 2000 by PostgreSQL Global Development Team +# +# $Header$ +# +#------------------------------------------------------------------------- + +subdir = src/bin/pg_ping +top_builddir = ../../.. +include $(top_builddir)/src/Makefile.global +CFLAGS += -I../../../src/interfaces/libpq + +all: pg_ping + +pg_ping: pg_ping.o + $(CC) $(CFLAGS) -I../../../src/interfaces/libpq $(LDFLAGS) $(libpq) $^ $(LIBS) -o $@ + +install: all installdirs + $(INSTALL_PROGRAM) pg_ping$(X) $(DESTDIR)$(bindir)/pg_ping$(X) + +installdirs: + $(mkinstalldirs) $(DESTDIR)$(bindir) + +uninstall: + rm -f $(DESTDIR)$(bindir)/pg_ping$(X) + +depend dep: + $(CC) -MM $(CFLAGS) *.c >depend + +clean distclean maintainer-clean: + rm -f pg_ping$(X) pg_ping.o + +ifeq (depend,$(wildcard depend)) +include depend +endif Index: src/bin/pg_ping/pg_ping.c =================================================================== RCS file: src/bin/pg_ping/pg_ping.c diff -N src/bin/pg_ping/pg_ping.c --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ src/bin/pg_ping/pg_ping.c 18 Jul 2003 23:32:08 -0000 @@ -0,0 +1,221 @@ +/* + * pg_ping.c + * + * A very basic "ping" utility to see if PostgreSQL is alive and responding to + * requests. This doesn't do anything as fancy as perform an SQL query, but it + * is intended to provide basic testing functionality to see if a database is + * up or down (primarily in startup/shutdown scripts). + * + * Copyright (C) 2003 by PostgreSQL Global Development Group + * + * $Header$ + */ +#ifdef HAVE_GETOPT_H +#include +#endif + +#include +#include +#include +#include + +#include "libpq-fe.h" +#include "postgres_fe.h" + +void usage(char *); + + +int +main(int argc, char *argv[]) +{ + int c, + ret = 0, + connstate = -1, + verbosity = 1; + char *conninfo = NULL, + *dbname = NULL, + *host = NULL, + *port = NULL, + *statestr = NULL, + *timeout = NULL; + PGconn *conn; + + extern int optind; + extern char *optarg; + + while ((c = getopt(argc, argv, "d:h:qp:vw:")) != -1) + { + switch (c) + { + case 'd': + asprintf(&dbname, "dbname='%s'", optarg); + break; + case 'h': + asprintf(&host, "host='%s'", optarg); + break; + case 'q': + verbosity--; + break; + case 'p': + asprintf(&port, "port='%s'", optarg); + break; + case 'u': + /* It'd be slick if there was a global + * PGSQL_WWW_DOCS global that way + * developers could embed URLs in help + * messages and the URLs would be + * updated every release, such as: + * + * printf("%s/%s", PGSQL_WWW_DOCS, "libpq-files.html"); + */ + fprintf(stderr, "Username not supported by %s. Use a ~/.pgpass file instead\n", argv[0]); + exit(1); + case 'v': + verbosity++; + break; + case 'w': + asprintf(&timeout, "connect_timeout='%s'", optarg); + break; + default: + usage(argv[0]); + } + } + + if (argc - optind != 0) + usage(argv[0]); + + /* Not having a PQconnect struct and having to work with + * strings is the sucks. */ + if (dbname != NULL) + asprintf(&conninfo, "%s", dbname); + + if (host != NULL) { + if (conninfo == NULL) + asprintf(&conninfo, "%s", host); + else + asprintf(&conninfo, "%s;%s", strdup(conninfo),host); + } + + if (port != NULL) { + if (conninfo == NULL) + asprintf(&conninfo, "%s", port); + else + asprintf(&conninfo, "%s;%s", strdup(conninfo),port); + } + + if (timeout != NULL) { + if (conninfo == NULL) + asprintf(&conninfo, "%s", timeout); + else + asprintf(&conninfo, "%s;%s", strdup(conninfo),timeout); + } + + if (conninfo == NULL) + conninfo = ""; + + if (verbosity >= 3) + printf("Connect string: %s\n", conninfo); + + conn = PQconnectStart(conninfo); + do { + statestr = NULL; + switch(PQstatus(conn)) { + case CONNECTION_OK: + if (connstate != 0) { + statestr = "Database up and running."; + connstate = 0; + } + ret = 0; + break; + case CONNECTION_BAD: + if (connstate != 1) { + statestr = "Unable to make connection."; + connstate = 1; + } + ret = 1; + break; + case CONNECTION_STARTED: + if (connstate != 2) { + statestr = "Waiting for connection to be made."; + connstate = 2; + } + ret = -1; + break; + case CONNECTION_MADE: + if (connstate != 3) { + statestr = "Connection OK; waiting to send."; + connstate = 3; + } + ret = 0; + break; + case CONNECTION_AWAITING_RESPONSE: + if (connstate != 4) { + statestr = "Waiting for a response from the postmaster."; + connstate = 4; + } + ret = -1; + break; + case CONNECTION_AUTH_OK: + if (connstate != 5) { + statestr = "Received authentication; waiting for backend startup."; + connstate = 5; + } + ret = -1; + break; + case CONNECTION_SETENV: + if (connstate != 6) { + statestr = "Negotiating environment."; + connstate = 6; + } + ret = -1; + break; + case CONNECTION_SSL_STARTUP: + if (connstate != 7) { + statestr = "Negotiating SSL."; + connstate = 7; + } + ret = -1; + break; + case CONNECTION_NEEDED: + if (connstate != 8) { + statestr = "Internal state: connect() needed."; + connstate = 8; + } + ret = -1; + break; + default: + fprintf(stderr, "Unknown status code, aborting\n"); + abort(); + } + + if (verbosity >= 3) + printf("%s\n", statestr); + } while (ret == -1); + + PQfinish(conn); + + if (verbosity >= 1) { + if (verbosity >= 2) + printf("Database "); + + if (ret == 0) + printf("UP"); + else + printf("DOWN"); + + if (verbosity >= 2) + printf(": %s\n", statestr); + else + printf("\n"); + } + + return(ret); +} + + +void +usage(char *progname) +{ + fprintf(stderr, "Usage: %s [-q] [-v] [-d dbname] [-h hostname] [-p port] [-w timeout]\n", progname); + exit(1); +}