Commit 792b0f46 authored by Tom Lane's avatar Tom Lane

Get rid of not-very-portable fcntl(F_SETLK) mechanism for locking the Unix

socket file, in favor of having an ordinary lockfile beside the socket file.
Clean up a few robustness problems in the lockfile code.  If postmaster is
going to reject a connection request based on database state, it will now
tell you so before authentication exchange not after.  (Of course, a failure
after is still possible if conditions change meanwhile, but this makes life
easier for a yet-to-be-written pg_ping utility.)
parent 1efd7330
This diff is collapsed.
......@@ -758,23 +758,6 @@ PGAC_VAR_INT_TIMEZONE
AC_FUNC_ACCEPT_ARGTYPES
PGAC_FUNC_GETTIMEOFDAY_1ARG
AC_MSG_CHECKING([for fcntl(F_SETLK)])
case $host_os in
linux*) AC_MSG_RESULT([broken on Linux]) ;;
*)
AC_TRY_LINK(
[#include <stdio.h>
#include <fcntl.h>
],
[struct flock lck;
lck.l_whence = SEEK_SET; lck.l_start = lck.l_len = 0;
lck.l_type = F_WRLCK;
fcntl(0, F_SETLK, &lck);],
[AC_DEFINE(HAVE_FCNTL_SETLK) AC_MSG_RESULT(yes)],
[AC_MSG_RESULT(no)])
;;
esac
AC_CHECK_FUNCS([fcvt getopt_long memmove pstat setproctitle setsid sigprocmask sysconf waitpid dlopen])
AC_CACHE_CHECK([for PS_STRINGS], [pgac_cv_var_PS_STRINGS],
......
......@@ -29,7 +29,7 @@
* Portions Copyright (c) 1996-2000, PostgreSQL, Inc
* Portions Copyright (c) 1994, Regents of the University of California
*
* $Id: pqcomm.c,v 1.113 2000/11/21 23:03:53 petere Exp $
* $Id: pqcomm.c,v 1.114 2000/11/29 20:59:51 tgl Exp $
*
*-------------------------------------------------------------------------
*/
......@@ -169,7 +169,7 @@ StreamDoUnlink(void)
/*
* StreamServerPort -- open a sock stream "listening" port.
*
* This initializes the Postmaster's connection-accepting port fdP.
* This initializes the Postmaster's connection-accepting port *fdP.
*
* RETURNS: STATUS_OK or STATUS_ERROR
*/
......@@ -183,9 +183,6 @@ StreamServerPort(int family, char *hostName, unsigned short portNumber,
err;
size_t len = 0;
int one = 1;
#ifdef HAVE_FCNTL_SETLK
int lock_fd;
#endif
Assert(family == AF_INET || family == AF_UNIX);
......@@ -223,22 +220,15 @@ StreamServerPort(int family, char *hostName, unsigned short portNumber,
len = UNIXSOCK_LEN(saddr.un);
strcpy(sock_path, saddr.un.sun_path);
/*
* If the socket exists but nobody has an advisory lock on it we
* can safely delete the file.
* Grab an interlock file associated with the socket file.
*/
#ifdef HAVE_FCNTL_SETLK
if ((lock_fd = open(sock_path, O_WRONLY | O_NONBLOCK | PG_BINARY, 0666)) >= 0)
{
struct flock lck;
lck.l_whence = SEEK_SET;
lck.l_start = lck.l_len = 0;
lck.l_type = F_WRLCK;
if (fcntl(lock_fd, F_SETLK, &lck) != -1)
unlink(sock_path);
close(lock_fd);
}
#endif /* HAVE_FCNTL_SETLK */
if (! CreateSocketLockFile(sock_path, true))
return STATUS_ERROR;
/*
* Once we have the interlock, we can safely delete any pre-existing
* socket file to avoid failure at bind() time.
*/
unlink(sock_path);
}
#endif /* HAVE_UNIX_SOCKETS */
......@@ -274,8 +264,8 @@ StreamServerPort(int family, char *hostName, unsigned short portNumber,
{
snprintf(PQerrormsg, PQERRORMSG_LENGTH,
"FATAL: StreamServerPort: bind() failed: %s\n"
"\tIs another postmaster already running on that port?\n",
strerror(errno));
"\tIs another postmaster already running on port %d?\n",
strerror(errno), (int) portNumber);
if (family == AF_UNIX)
snprintf(PQerrormsg + strlen(PQerrormsg),
PQERRORMSG_LENGTH - strlen(PQerrormsg),
......@@ -293,41 +283,14 @@ StreamServerPort(int family, char *hostName, unsigned short portNumber,
#ifdef HAVE_UNIX_SOCKETS
if (family == AF_UNIX)
{
/* Arrange to unlink the socket file at exit */
on_proc_exit(StreamDoUnlink, 0);
/*
* Open the socket file and get an advisory lock on it. The
* lock_fd is left open to keep the lock.
* Fix socket ownership/permission if requested. Note we must
* do this before we listen() to avoid a window where unwanted
* connections could get accepted.
*/
#ifdef HAVE_FCNTL_SETLK
if ((lock_fd = open(sock_path, O_WRONLY | O_NONBLOCK | PG_BINARY, 0666)) >= 0)
{
struct flock lck;
lck.l_whence = SEEK_SET;
lck.l_start = lck.l_len = 0;
lck.l_type = F_WRLCK;
if (fcntl(lock_fd, F_SETLK, &lck) != 0)
elog(DEBUG, "flock error on %s: %s", sock_path, strerror(errno));
}
#endif /* HAVE_FCNTL_SETLK */
}
#endif /* HAVE_UNIX_SOCKETS */
listen(fd, SOMAXCONN);
/*
* MS: I took this code from Dillon's version. It makes the listening
* port non-blocking. That is not necessary (and may tickle kernel
* bugs).
*
* fcntl(fd, F_SETFD, 1); fcntl(fd, F_SETFL, FNDELAY);
*/
*fdP = fd;
if (family == AF_UNIX)
{
Assert(Unix_socket_group);
if (Unix_socket_group[0] != '\0')
{
......@@ -379,6 +342,12 @@ StreamServerPort(int family, char *hostName, unsigned short portNumber,
return STATUS_ERROR;
}
}
#endif /* HAVE_UNIX_SOCKETS */
listen(fd, SOMAXCONN);
*fdP = fd;
return STATUS_OK;
}
......
This diff is collapsed.
......@@ -8,7 +8,7 @@
*
*
* IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/tcop/postgres.c,v 1.191 2000/11/25 20:33:52 tgl Exp $
* $Header: /cvsroot/pgsql/src/backend/tcop/postgres.c,v 1.192 2000/11/29 20:59:52 tgl Exp $
*
* NOTES
* this is the "main" module of the postgres backend and
......@@ -1514,16 +1514,10 @@ PostgresMain(int argc, char *argv[], int real_argc, char *real_argv[], const cha
}
/*
* Try to create pid file.
* Create lockfile for data directory.
*/
SetPidFname(DataDir);
if (SetPidFile(-getpid()))
proc_exit(0);
/*
* Register clean up proc.
*/
on_proc_exit(UnlinkPidFile, 0);
if (! CreateDataDirLockFile(DataDir, false))
proc_exit(1);
XLOGPathInit();
BaseInit();
......@@ -1635,7 +1629,7 @@ PostgresMain(int argc, char *argv[], int real_argc, char *real_argv[], const cha
if (!IsUnderPostmaster)
{
puts("\nPOSTGRES backend interactive interface ");
puts("$Revision: 1.191 $ $Date: 2000/11/25 20:33:52 $\n");
puts("$Revision: 1.192 $ $Date: 2000/11/29 20:59:52 $\n");
}
/*
......
This diff is collapsed.
......@@ -4,7 +4,7 @@
* Support for grand unified configuration scheme, including SET
* command, configuration file, and command line options.
*
* $Header: /cvsroot/pgsql/src/backend/utils/misc/guc.c,v 1.23 2000/11/25 04:13:17 momjian Exp $
* $Header: /cvsroot/pgsql/src/backend/utils/misc/guc.c,v 1.24 2000/11/29 20:59:53 tgl Exp $
*
* Copyright 2000 by PostgreSQL Global Development Group
* Written by Peter Eisentraut <peter_e@gmx.net>.
......@@ -319,7 +319,7 @@ ConfigureNamesString[] =
{"unix_socket_directory", PGC_POSTMASTER, &UnixSocketDir,
"", NULL},
{"virtual_host", PGC_POSTMASTER, &Virtual_host,
{"virtual_host", PGC_POSTMASTER, &VirtualHost,
"", NULL},
{NULL, 0, NULL, NULL, NULL}
......
......@@ -8,7 +8,7 @@
#
#
# IDENTIFICATION
# $Header: /cvsroot/pgsql/src/bin/pg_ctl/Attic/pg_ctl.sh,v 1.15 2000/11/27 02:50:17 tgl Exp $
# $Header: /cvsroot/pgsql/src/bin/pg_ctl/Attic/pg_ctl.sh,v 1.16 2000/11/29 20:59:53 tgl Exp $
#
#-------------------------------------------------------------------------
......@@ -187,7 +187,7 @@ PIDFILE=$PGDATA/postmaster.pid
if [ $op = "status" ];then
if [ -f $PIDFILE ];then
PID=`cat $PIDFILE`
PID=`head -1 $PIDFILE`
if [ $PID -lt 0 ];then
PID=`expr 0 - $PID`
echo "$CMDNAME: postgres is running (pid: $PID)"
......@@ -205,7 +205,7 @@ fi
if [ $op = "stop" -o $op = "restart" ];then
if [ -f $PIDFILE ];then
PID=`cat $PIDFILE`
PID=`head -1 $PIDFILE`
if [ $PID -lt 0 ];then
PID=`expr 0 - $PID`
echo "$CMDNAME: Cannot restart postmaster. postgres is running (pid: $PID)"
......@@ -213,7 +213,7 @@ if [ $op = "stop" -o $op = "restart" ];then
exit 1
fi
kill $sig `cat $PIDFILE`
kill $sig $PID
# wait for postmaster shutting down
if [ "$wait" = 1 -o $op = "restart" ];then
......@@ -253,7 +253,7 @@ fi
if [ $op = "start" -o $op = "restart" ];then
if [ -f $PIDFILE ];then
echo "$CMDNAME: It seems another postmaster is running. Trying to start postmaster anyway."
pid=`cat $PIDFILE`
pid=`head -1 $PIDFILE`
fi
# no -o given
......@@ -275,7 +275,7 @@ if [ $op = "start" -o $op = "restart" ];then
fi
if [ -f $PIDFILE ];then
if [ "`cat $PIDFILE`" = "$pid" ];then
if [ "`head -1 $PIDFILE`" = "$pid" ];then
echo "$CMDNAME: Cannot start postmaster. Is another postmaster is running?"
exit 1
fi
......
......@@ -8,7 +8,7 @@
* or in config.h afterwards. Of course, if you edit config.h, then your
* changes will be overwritten the next time you run configure.
*
* $Id: config.h.in,v 1.149 2000/11/20 16:52:54 petere Exp $
* $Id: config.h.in,v 1.150 2000/11/29 20:59:54 tgl Exp $
*/
#ifndef CONFIG_H
......@@ -567,9 +567,6 @@ extern void srandom(unsigned int seed);
/* Set to 1 if you have struct sockaddr_un */
#undef HAVE_STRUCT_SOCKADDR_UN
/* Set to 1 if you have F_SETLK option for fcntl() */
#undef HAVE_FCNTL_SETLK
/* Set to 1 if type "long int" works and is 64 bits */
#undef HAVE_LONG_INT_64
......
......@@ -12,7 +12,7 @@
* Portions Copyright (c) 1996-2000, PostgreSQL, Inc
* Portions Copyright (c) 1994, Regents of the University of California
*
* $Id: miscadmin.h,v 1.74 2000/11/25 22:34:13 momjian Exp $
* $Id: miscadmin.h,v 1.75 2000/11/29 20:59:54 tgl Exp $
*
* NOTES
* some of the information in this file will be moved to
......@@ -114,7 +114,7 @@ extern int PostPortNumber;
extern int Unix_socket_permissions;
extern char *Unix_socket_group;
extern char *UnixSocketDir;
extern char *Virtual_host;
extern char *VirtualHost;
/*****************************************************************************
......@@ -227,17 +227,8 @@ extern bool IsIgnoringSystemIndexes(void);
extern bool IsCacheInitialized(void);
extern void SetWaitingForLock(bool);
/*
* "postmaster.pid" is a file containing postmaster's pid, being
* created uder $PGDATA upon postmaster's starting up. When postmaster
* shuts down, it will be unlinked.
*/
#define PIDFNAME "postmaster.pid"
extern void SetPidFname(char *datadir);
extern void UnlinkPidFile(void);
extern int SetPidFile(pid_t pid);
extern bool CreateDataDirLockFile(const char *datadir, bool amPostmaster);
extern bool CreateSocketLockFile(const char *socketfile, bool amPostmaster);
extern void ValidatePgVersion(const char *path);
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment