diff options
Diffstat (limited to 'src/backend')
-rw-r--r-- | src/backend/libpq/pqcomm.c | 32 | ||||
-rw-r--r-- | src/backend/postmaster/postmaster.c | 95 | ||||
-rw-r--r-- | src/backend/utils/misc/guc.c | 8 |
3 files changed, 120 insertions, 15 deletions
diff --git a/src/backend/libpq/pqcomm.c b/src/backend/libpq/pqcomm.c index 355144937a5..2434d6ff16a 100644 --- a/src/backend/libpq/pqcomm.c +++ b/src/backend/libpq/pqcomm.c @@ -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.109 2000/11/01 21:14:01 petere Exp $ + * $Id: pqcomm.c,v 1.110 2000/11/13 15:18:09 momjian Exp $ * *------------------------------------------------------------------------- */ @@ -169,13 +169,14 @@ StreamDoUnlink(void) /* * StreamServerPort -- open a sock stream "listening" port. * - * This initializes the Postmaster's connection-accepting port. + * This initializes the Postmaster's connection-accepting port fdP. * * RETURNS: STATUS_OK or STATUS_ERROR */ int -StreamServerPort(int family, unsigned short portName, int *fdP) +StreamServerPort(int family, char *hostName, unsigned short portName, + char *unixSocketName, int *fdP) { SockAddr saddr; int fd, @@ -218,7 +219,8 @@ StreamServerPort(int family, unsigned short portName, int *fdP) #ifdef HAVE_UNIX_SOCKETS if (family == AF_UNIX) { - len = UNIXSOCK_PATH(saddr.un, portName); + UNIXSOCK_PATH(saddr.un, portName, unixSocketName); + 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 @@ -242,7 +244,27 @@ StreamServerPort(int family, unsigned short portName, int *fdP) if (family == AF_INET) { - saddr.in.sin_addr.s_addr = htonl(INADDR_ANY); + /* TCP/IP socket */ + if (hostName[0] == '\0') + saddr.in.sin_addr.s_addr = htonl(INADDR_ANY); + else + { + struct hostent *hp; + + hp = gethostbyname(hostName); + if ((hp == NULL) || (hp->h_addrtype != AF_INET)) + { + snprintf(PQerrormsg, PQERRORMSG_LENGTH, + "FATAL: StreamServerPort: gethostbyname(%s) failed: %s\n", + hostName, hstrerror(h_errno)); + fputs(PQerrormsg, stderr); + pqdebug("%s", PQerrormsg); + return STATUS_ERROR; + } + memmove((char *) &(saddr.in.sin_addr), (char *) hp->h_addr, + hp->h_length); + } + saddr.in.sin_port = htons(portName); len = sizeof(struct sockaddr_in); } diff --git a/src/backend/postmaster/postmaster.c b/src/backend/postmaster/postmaster.c index e50c0ee4d0e..c6b645b15ba 100644 --- a/src/backend/postmaster/postmaster.c +++ b/src/backend/postmaster/postmaster.c @@ -11,7 +11,7 @@ * * * IDENTIFICATION - * $Header: /cvsroot/pgsql/src/backend/postmaster/postmaster.c,v 1.182 2000/11/12 20:51:51 tgl Exp $ + * $Header: /cvsroot/pgsql/src/backend/postmaster/postmaster.c,v 1.183 2000/11/13 15:18:11 momjian Exp $ * * NOTES * @@ -114,6 +114,8 @@ static Dllist *PortList; /* The socket number we are listening for connections on */ int PostPortName; +char * UnixSocketName; +char * HostName; /* * This is a sequence number that indicates how many times we've had to @@ -224,7 +226,7 @@ extern void SetThisStartUpID(void); static void pmdaemonize(int argc, char *argv[]); static Port *ConnCreate(int serverFd); static void ConnFree(Port *port); -static void reset_shared(int port); +static void reset_shared(unsigned short port); static void SIGHUP_handler(SIGNAL_ARGS); static void pmdie(SIGNAL_ARGS); static void reaper(SIGNAL_ARGS); @@ -366,7 +368,7 @@ PostmasterMain(int argc, char *argv[]) * will occur. */ opterr = 1; - while ((opt = getopt(argc, argv, "A:a:B:b:c:D:d:Film:MN:no:p:SsV-:?")) != EOF) + while ((opt = getopt(argc, argv, "A:a:B:b:c:D:d:Fh:ik:lm:MN:no:p:SsV-:?")) != EOF) { switch(opt) { @@ -422,7 +424,7 @@ PostmasterMain(int argc, char *argv[]) #ifdef HAVE_INT_OPTRESET optreset = 1; #endif - while ((opt = getopt(argc, argv, "A:a:B:b:c:D:d:Film:MN:no:p:SsV-:?")) != EOF) + while ((opt = getopt(argc, argv, "A:a:B:b:c:D:d:Fh:ik:lm:MN:no:p:SsV-:?")) != EOF) { switch (opt) { @@ -456,9 +458,16 @@ PostmasterMain(int argc, char *argv[]) case 'F': enableFsync = false; break; + case 'h': + HostName = optarg; + break; case 'i': NetServer = true; break; + case 'k': + /* Set PGUNIXSOCKET by hand. */ + UnixSocketName = optarg; + break; #ifdef USE_SSL case 'l': EnableSSL = true; @@ -606,8 +615,9 @@ PostmasterMain(int argc, char *argv[]) if (NetServer) { - status = StreamServerPort(AF_INET, (unsigned short) PostPortName, - &ServerSock_INET); + status = StreamServerPort(AF_INET, HostName, + (unsigned short) PostPortName, UnixSocketName, + &ServerSock_INET); if (status != STATUS_OK) { fprintf(stderr, "%s: cannot create INET stream port\n", @@ -617,8 +627,9 @@ PostmasterMain(int argc, char *argv[]) } #ifdef HAVE_UNIX_SOCKETS - status = StreamServerPort(AF_UNIX, (unsigned short) PostPortName, - &ServerSock_UNIX); + status = StreamServerPort(AF_UNIX, HostName, + (unsigned short) PostPortName, UnixSocketName, + &ServerSock_UNIX); if (status != STATUS_OK) { fprintf(stderr, "%s: cannot create UNIX stream port\n", @@ -789,7 +800,9 @@ usage(const char *progname) printf(" -d 1-5 debugging level\n"); printf(" -D <directory> database directory\n"); printf(" -F turn fsync off\n"); + printf(" -h hostname specify hostname or IP address\n"); printf(" -i enable TCP/IP connections\n"); + printf(" -k path specify Unix-domain socket name\n"); #ifdef USE_SSL printf(" -l enable SSL connections\n"); #endif @@ -1303,11 +1316,75 @@ ConnFree(Port *conn) } /* + * get_host_port -- return a pseudo port number (16 bits) + * derived from the primary IP address of HostName. + */ +static unsigned short +get_host_port(void) +{ + static unsigned short hostPort = 0; + + if (hostPort == 0) + { + SockAddr saddr; + struct hostent *hp; + + hp = gethostbyname(HostName); + if ((hp == NULL) || (hp->h_addrtype != AF_INET)) + { + char msg[1024]; + snprintf(msg, sizeof(msg), + "FATAL: get_host_port: gethostbyname(%s) failed: %s\n", + HostName, hstrerror(h_errno)); + fputs(msg, stderr); + pqdebug("%s", msg); + exit(1); + } + memmove((char *) &(saddr.in.sin_addr), + (char *) hp->h_addr, + hp->h_length); + hostPort = ntohl(saddr.in.sin_addr.s_addr) & 0xFFFF; + } + + return hostPort; +} + +/* * reset_shared -- reset shared memory and semaphores */ static void -reset_shared(int port) +reset_shared(unsigned short port) { + /* + * A typical ipc_key is 5432001, which is port 5432, sequence + * number 0, and 01 as the index in IPCKeyGetBufferMemoryKey(). + * The 32-bit INT_MAX is 2147483 6 47. + * + * The default algorithm for calculating the IPC keys assumes that all + * instances of postmaster on a given host are listening on different + * ports. In order to work (prevent shared memory collisions) if you + * run multiple PostgreSQL instances on the same port and different IP + * addresses on a host, we change the algorithm if you give postmaster + * the -h option, or set PGHOST, to a value other than the internal + * default. + * + * If HostName is set, then we generate the IPC keys using the + * last two octets of the IP address instead of the port number. + * This algorithm assumes that no one will run multiple PostgreSQL + * instances on one host using two IP addresses that have the same two + * last octets in different class C networks. If anyone does, it + * would be rare. + * + * So, if you use -h or PGHOST, don't try to run two instances of + * PostgreSQL on the same IP address but different ports. If you + * don't use them, then you must use different ports (via -p or + * PGPORT). And, of course, don't try to use both approaches on one + * host. + */ + + if (HostName[0] != '\0') + port = get_host_port(); + ipc_key = port * 1000 + shmem_seq * 100; CreateSharedMemoryAndSemaphores(ipc_key, MaxBackends); shmem_seq += 1; diff --git a/src/backend/utils/misc/guc.c b/src/backend/utils/misc/guc.c index 8fe7bd36fa3..ecdc1d1a757 100644 --- a/src/backend/utils/misc/guc.c +++ b/src/backend/utils/misc/guc.c @@ -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.16 2000/11/09 11:25:59 vadim Exp $ + * $Header: /cvsroot/pgsql/src/backend/utils/misc/guc.c,v 1.17 2000/11/13 15:18:12 momjian Exp $ * * Copyright 2000 by PostgreSQL Global Development Group * Written by Peter Eisentraut <peter_e@gmx.net>. @@ -304,6 +304,12 @@ ConfigureNamesString[] = {"unix_socket_group", PGC_POSTMASTER, &Unix_socket_group, "", NULL}, + {"unixsocket", PGC_POSTMASTER, &UnixSocketName, + "", NULL}, + + {"hostname", PGC_POSTMASTER, &HostName, + "", NULL}, + {NULL, 0, NULL, NULL, NULL} }; |