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 ...@@ -758,23 +758,6 @@ PGAC_VAR_INT_TIMEZONE
AC_FUNC_ACCEPT_ARGTYPES AC_FUNC_ACCEPT_ARGTYPES
PGAC_FUNC_GETTIMEOFDAY_1ARG 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_CHECK_FUNCS([fcvt getopt_long memmove pstat setproctitle setsid sigprocmask sysconf waitpid dlopen])
AC_CACHE_CHECK([for PS_STRINGS], [pgac_cv_var_PS_STRINGS], AC_CACHE_CHECK([for PS_STRINGS], [pgac_cv_var_PS_STRINGS],
......
...@@ -29,7 +29,7 @@ ...@@ -29,7 +29,7 @@
* Portions Copyright (c) 1996-2000, PostgreSQL, Inc * Portions Copyright (c) 1996-2000, PostgreSQL, Inc
* Portions Copyright (c) 1994, Regents of the University of California * 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) ...@@ -169,7 +169,7 @@ StreamDoUnlink(void)
/* /*
* StreamServerPort -- open a sock stream "listening" port. * 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 * RETURNS: STATUS_OK or STATUS_ERROR
*/ */
...@@ -183,9 +183,6 @@ StreamServerPort(int family, char *hostName, unsigned short portNumber, ...@@ -183,9 +183,6 @@ StreamServerPort(int family, char *hostName, unsigned short portNumber,
err; err;
size_t len = 0; size_t len = 0;
int one = 1; int one = 1;
#ifdef HAVE_FCNTL_SETLK
int lock_fd;
#endif
Assert(family == AF_INET || family == AF_UNIX); Assert(family == AF_INET || family == AF_UNIX);
...@@ -223,22 +220,15 @@ StreamServerPort(int family, char *hostName, unsigned short portNumber, ...@@ -223,22 +220,15 @@ StreamServerPort(int family, char *hostName, unsigned short portNumber,
len = UNIXSOCK_LEN(saddr.un); len = UNIXSOCK_LEN(saddr.un);
strcpy(sock_path, saddr.un.sun_path); strcpy(sock_path, saddr.un.sun_path);
/* /*
* If the socket exists but nobody has an advisory lock on it we * Grab an interlock file associated with the socket file.
* can safely delete the file. */
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.
*/ */
#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); unlink(sock_path);
close(lock_fd);
}
#endif /* HAVE_FCNTL_SETLK */
} }
#endif /* HAVE_UNIX_SOCKETS */ #endif /* HAVE_UNIX_SOCKETS */
...@@ -274,8 +264,8 @@ StreamServerPort(int family, char *hostName, unsigned short portNumber, ...@@ -274,8 +264,8 @@ StreamServerPort(int family, char *hostName, unsigned short portNumber,
{ {
snprintf(PQerrormsg, PQERRORMSG_LENGTH, snprintf(PQerrormsg, PQERRORMSG_LENGTH,
"FATAL: StreamServerPort: bind() failed: %s\n" "FATAL: StreamServerPort: bind() failed: %s\n"
"\tIs another postmaster already running on that port?\n", "\tIs another postmaster already running on port %d?\n",
strerror(errno)); strerror(errno), (int) portNumber);
if (family == AF_UNIX) if (family == AF_UNIX)
snprintf(PQerrormsg + strlen(PQerrormsg), snprintf(PQerrormsg + strlen(PQerrormsg),
PQERRORMSG_LENGTH - strlen(PQerrormsg), PQERRORMSG_LENGTH - strlen(PQerrormsg),
...@@ -293,41 +283,14 @@ StreamServerPort(int family, char *hostName, unsigned short portNumber, ...@@ -293,41 +283,14 @@ StreamServerPort(int family, char *hostName, unsigned short portNumber,
#ifdef HAVE_UNIX_SOCKETS #ifdef HAVE_UNIX_SOCKETS
if (family == AF_UNIX) if (family == AF_UNIX)
{ {
/* Arrange to unlink the socket file at exit */
on_proc_exit(StreamDoUnlink, 0); on_proc_exit(StreamDoUnlink, 0);
/* /*
* Open the socket file and get an advisory lock on it. The * Fix socket ownership/permission if requested. Note we must
* lock_fd is left open to keep the lock. * 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); Assert(Unix_socket_group);
if (Unix_socket_group[0] != '\0') if (Unix_socket_group[0] != '\0')
{ {
...@@ -379,6 +342,12 @@ StreamServerPort(int family, char *hostName, unsigned short portNumber, ...@@ -379,6 +342,12 @@ StreamServerPort(int family, char *hostName, unsigned short portNumber,
return STATUS_ERROR; return STATUS_ERROR;
} }
} }
#endif /* HAVE_UNIX_SOCKETS */
listen(fd, SOMAXCONN);
*fdP = fd;
return STATUS_OK; return STATUS_OK;
} }
......
This diff is collapsed.
...@@ -8,7 +8,7 @@ ...@@ -8,7 +8,7 @@
* *
* *
* IDENTIFICATION * 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 * NOTES
* this is the "main" module of the postgres backend and * 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 ...@@ -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 (! CreateDataDirLockFile(DataDir, false))
if (SetPidFile(-getpid())) proc_exit(1);
proc_exit(0);
/*
* Register clean up proc.
*/
on_proc_exit(UnlinkPidFile, 0);
XLOGPathInit(); XLOGPathInit();
BaseInit(); BaseInit();
...@@ -1635,7 +1629,7 @@ PostgresMain(int argc, char *argv[], int real_argc, char *real_argv[], const cha ...@@ -1635,7 +1629,7 @@ PostgresMain(int argc, char *argv[], int real_argc, char *real_argv[], const cha
if (!IsUnderPostmaster) if (!IsUnderPostmaster)
{ {
puts("\nPOSTGRES backend interactive interface "); 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 @@ ...@@ -4,7 +4,7 @@
* Support for grand unified configuration scheme, including SET * Support for grand unified configuration scheme, including SET
* command, configuration file, and command line options. * 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 * Copyright 2000 by PostgreSQL Global Development Group
* Written by Peter Eisentraut <peter_e@gmx.net>. * Written by Peter Eisentraut <peter_e@gmx.net>.
...@@ -319,7 +319,7 @@ ConfigureNamesString[] = ...@@ -319,7 +319,7 @@ ConfigureNamesString[] =
{"unix_socket_directory", PGC_POSTMASTER, &UnixSocketDir, {"unix_socket_directory", PGC_POSTMASTER, &UnixSocketDir,
"", NULL}, "", NULL},
{"virtual_host", PGC_POSTMASTER, &Virtual_host, {"virtual_host", PGC_POSTMASTER, &VirtualHost,
"", NULL}, "", NULL},
{NULL, 0, NULL, NULL, NULL} {NULL, 0, NULL, NULL, NULL}
......
...@@ -8,7 +8,7 @@ ...@@ -8,7 +8,7 @@
# #
# #
# IDENTIFICATION # 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 ...@@ -187,7 +187,7 @@ PIDFILE=$PGDATA/postmaster.pid
if [ $op = "status" ];then if [ $op = "status" ];then
if [ -f $PIDFILE ];then if [ -f $PIDFILE ];then
PID=`cat $PIDFILE` PID=`head -1 $PIDFILE`
if [ $PID -lt 0 ];then if [ $PID -lt 0 ];then
PID=`expr 0 - $PID` PID=`expr 0 - $PID`
echo "$CMDNAME: postgres is running (pid: $PID)" echo "$CMDNAME: postgres is running (pid: $PID)"
...@@ -205,7 +205,7 @@ fi ...@@ -205,7 +205,7 @@ fi
if [ $op = "stop" -o $op = "restart" ];then if [ $op = "stop" -o $op = "restart" ];then
if [ -f $PIDFILE ];then if [ -f $PIDFILE ];then
PID=`cat $PIDFILE` PID=`head -1 $PIDFILE`
if [ $PID -lt 0 ];then if [ $PID -lt 0 ];then
PID=`expr 0 - $PID` PID=`expr 0 - $PID`
echo "$CMDNAME: Cannot restart postmaster. postgres is running (pid: $PID)" echo "$CMDNAME: Cannot restart postmaster. postgres is running (pid: $PID)"
...@@ -213,7 +213,7 @@ if [ $op = "stop" -o $op = "restart" ];then ...@@ -213,7 +213,7 @@ if [ $op = "stop" -o $op = "restart" ];then
exit 1 exit 1
fi fi
kill $sig `cat $PIDFILE` kill $sig $PID
# wait for postmaster shutting down # wait for postmaster shutting down
if [ "$wait" = 1 -o $op = "restart" ];then if [ "$wait" = 1 -o $op = "restart" ];then
...@@ -253,7 +253,7 @@ fi ...@@ -253,7 +253,7 @@ fi
if [ $op = "start" -o $op = "restart" ];then if [ $op = "start" -o $op = "restart" ];then
if [ -f $PIDFILE ];then if [ -f $PIDFILE ];then
echo "$CMDNAME: It seems another postmaster is running. Trying to start postmaster anyway." echo "$CMDNAME: It seems another postmaster is running. Trying to start postmaster anyway."
pid=`cat $PIDFILE` pid=`head -1 $PIDFILE`
fi fi
# no -o given # no -o given
...@@ -275,7 +275,7 @@ if [ $op = "start" -o $op = "restart" ];then ...@@ -275,7 +275,7 @@ if [ $op = "start" -o $op = "restart" ];then
fi fi
if [ -f $PIDFILE ];then 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?" echo "$CMDNAME: Cannot start postmaster. Is another postmaster is running?"
exit 1 exit 1
fi fi
......
...@@ -8,7 +8,7 @@ ...@@ -8,7 +8,7 @@
* or in config.h afterwards. Of course, if you edit config.h, then your * or in config.h afterwards. Of course, if you edit config.h, then your
* changes will be overwritten the next time you run configure. * 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 #ifndef CONFIG_H
...@@ -567,9 +567,6 @@ extern void srandom(unsigned int seed); ...@@ -567,9 +567,6 @@ extern void srandom(unsigned int seed);
/* Set to 1 if you have struct sockaddr_un */ /* Set to 1 if you have struct sockaddr_un */
#undef 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 */ /* Set to 1 if type "long int" works and is 64 bits */
#undef HAVE_LONG_INT_64 #undef HAVE_LONG_INT_64
......
...@@ -12,7 +12,7 @@ ...@@ -12,7 +12,7 @@
* Portions Copyright (c) 1996-2000, PostgreSQL, Inc * Portions Copyright (c) 1996-2000, PostgreSQL, Inc
* Portions Copyright (c) 1994, Regents of the University of California * 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 * NOTES
* some of the information in this file will be moved to * some of the information in this file will be moved to
...@@ -114,7 +114,7 @@ extern int PostPortNumber; ...@@ -114,7 +114,7 @@ extern int PostPortNumber;
extern int Unix_socket_permissions; extern int Unix_socket_permissions;
extern char *Unix_socket_group; extern char *Unix_socket_group;
extern char *UnixSocketDir; extern char *UnixSocketDir;
extern char *Virtual_host; extern char *VirtualHost;
/***************************************************************************** /*****************************************************************************
...@@ -227,17 +227,8 @@ extern bool IsIgnoringSystemIndexes(void); ...@@ -227,17 +227,8 @@ extern bool IsIgnoringSystemIndexes(void);
extern bool IsCacheInitialized(void); extern bool IsCacheInitialized(void);
extern void SetWaitingForLock(bool); extern void SetWaitingForLock(bool);
/* extern bool CreateDataDirLockFile(const char *datadir, bool amPostmaster);
* "postmaster.pid" is a file containing postmaster's pid, being extern bool CreateSocketLockFile(const char *socketfile, bool amPostmaster);
* 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 void ValidatePgVersion(const char *path); 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