Commit 5e7a5c95 authored by Bruce Momjian's avatar Bruce Momjian

Pass shared memory address on command line to exec'ed backend.

Allow backends to attached to specified shared memory address.
parent 4e08d35e
...@@ -8,7 +8,7 @@ ...@@ -8,7 +8,7 @@
* Portions Copyright (c) 1994, Regents of the University of California * Portions Copyright (c) 1994, Regents of the University of California
* *
* IDENTIFICATION * IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/bootstrap/bootstrap.c,v 1.155 2003/05/06 23:34:55 momjian Exp $ * $Header: /cvsroot/pgsql/src/backend/bootstrap/bootstrap.c,v 1.156 2003/05/08 14:49:03 momjian Exp $
* *
*------------------------------------------------------------------------- *-------------------------------------------------------------------------
*/ */
...@@ -286,10 +286,13 @@ BootstrapMain(int argc, char *argv[]) ...@@ -286,10 +286,13 @@ BootstrapMain(int argc, char *argv[])
case 'p': case 'p':
{ {
/* indicates fork from postmaster */ /* indicates fork from postmaster */
char *p;
#ifdef EXEC_BACKEND #ifdef EXEC_BACKEND
sscanf(optarg, "%d,", &UsedShmemSegID); char *p;
sscanf(optarg, "%d,%p,", &UsedShmemSegID, &UsedShmemSegAddr);
p = strchr(optarg, ','); p = strchr(optarg, ',');
if (p)
p = strchr(p+1, ',');
if (p) if (p)
dbname = strdup(p+1); dbname = strdup(p+1);
#else #else
......
...@@ -10,7 +10,7 @@ ...@@ -10,7 +10,7 @@
* Portions Copyright (c) 1994, Regents of the University of California * Portions Copyright (c) 1994, Regents of the University of California
* *
* IDENTIFICATION * IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/port/sysv_shmem.c,v 1.8 2003/05/06 23:34:55 momjian Exp $ * $Header: /cvsroot/pgsql/src/backend/port/sysv_shmem.c,v 1.9 2003/05/08 14:49:03 momjian Exp $
* *
*------------------------------------------------------------------------- *-------------------------------------------------------------------------
*/ */
...@@ -39,9 +39,8 @@ typedef int IpcMemoryId; /* shared memory ID returned by shmget(2) */ ...@@ -39,9 +39,8 @@ typedef int IpcMemoryId; /* shared memory ID returned by shmget(2) */
#define IPCProtection (0600) /* access/modify by user only */ #define IPCProtection (0600) /* access/modify by user only */
#ifdef EXEC_BACKEND
IpcMemoryKey UsedShmemSegID = 0; IpcMemoryKey UsedShmemSegID = 0;
#endif void *UsedShmemSegAddr = NULL;
static void *InternalIpcMemoryCreate(IpcMemoryKey memKey, uint32 size); static void *InternalIpcMemoryCreate(IpcMemoryKey memKey, uint32 size);
static void IpcMemoryDetach(int status, Datum shmaddr); static void IpcMemoryDetach(int status, Datum shmaddr);
...@@ -282,7 +281,7 @@ PrivateMemoryDelete(int status, Datum memaddr) ...@@ -282,7 +281,7 @@ PrivateMemoryDelete(int status, Datum memaddr)
* *
* Create a shared memory segment of the given size and initialize its * Create a shared memory segment of the given size and initialize its
* standard header. Also, register an on_shmem_exit callback to release * standard header. Also, register an on_shmem_exit callback to release
* the storage. * the storage. For an exec'ed backend, it just attaches.
* *
* Dead Postgres segments are recycled if found, but we do not fail upon * Dead Postgres segments are recycled if found, but we do not fail upon
* collision with non-Postgres shmem segments. The idea here is to detect and * collision with non-Postgres shmem segments. The idea here is to detect and
...@@ -302,11 +301,9 @@ PGSharedMemoryCreate(uint32 size, bool makePrivate, int port) ...@@ -302,11 +301,9 @@ PGSharedMemoryCreate(uint32 size, bool makePrivate, int port)
/* Room for a header? */ /* Room for a header? */
Assert(size > MAXALIGN(sizeof(PGShmemHeader))); Assert(size > MAXALIGN(sizeof(PGShmemHeader)));
#ifdef EXEC_BACKEND if (ExecBackend && UsedShmemSegID != 0)
if (UsedShmemSegID != 0)
NextShmemSegID = UsedShmemSegID; NextShmemSegID = UsedShmemSegID;
else else
#endif
NextShmemSegID = port * 1000 + 1; NextShmemSegID = port * 1000 + 1;
for (;;NextShmemSegID++) for (;;NextShmemSegID++)
...@@ -320,25 +317,39 @@ PGSharedMemoryCreate(uint32 size, bool makePrivate, int port) ...@@ -320,25 +317,39 @@ PGSharedMemoryCreate(uint32 size, bool makePrivate, int port)
break; break;
} }
/* Try to create new segment */ /* If attach to fixed address, only try once */
memAddress = InternalIpcMemoryCreate(NextShmemSegID, size); if (ExecBackend && UsedShmemSegAddr != NULL && NextShmemSegID != UsedShmemSegID)
if (memAddress) {
break; /* successful create and attach */ fprintf(stderr, "Unable to attach to memory at fixed address: shmget(key=%d, addr=%p) failed: %s\n",
(int) UsedShmemSegID, UsedShmemSegAddr, strerror(errno));
proc_exit(1);
}
if (!ExecBackend || UsedShmemSegAddr == NULL)
{
/* Try to create new segment */
memAddress = InternalIpcMemoryCreate(NextShmemSegID, size);
if (memAddress)
break; /* successful create and attach */
}
/* See if it looks to be leftover from a dead Postgres process */ /* See if it looks to be leftover from a dead Postgres process */
shmid = shmget(NextShmemSegID, sizeof(PGShmemHeader), 0); shmid = shmget(NextShmemSegID, sizeof(PGShmemHeader), 0);
if (shmid < 0) if (shmid < 0)
continue; /* failed: must be some other app's */ continue; /* failed: must be some other app's */
#if defined(solaris) && defined(__sparc__)
/* use intimate shared memory on SPARC Solaris */ /* use intimate shared memory on SPARC Solaris */
memAddress = shmat(shmid, 0, SHM_SHARE_MMU); memAddress = shmat(shmid, UsedShmemSegAddr,
#if defined(solaris) && defined(__sparc__)
SHM_SHARE_MMU
#else #else
memAddress = shmat(shmid, 0, 0); 0
#endif #endif
);
if (memAddress == (void *) -1) if (memAddress == (void *) -1)
continue; /* failed: must be some other app's */ continue; /* failed: must be some other app's */
hdr = (PGShmemHeader *) memAddress; hdr = (PGShmemHeader *) memAddress;
if (hdr->magic != PGShmemMagic) if (hdr->magic != PGShmemMagic)
{ {
...@@ -346,14 +357,19 @@ PGSharedMemoryCreate(uint32 size, bool makePrivate, int port) ...@@ -346,14 +357,19 @@ PGSharedMemoryCreate(uint32 size, bool makePrivate, int port)
continue; /* segment belongs to a non-Postgres app */ continue; /* segment belongs to a non-Postgres app */
} }
/* Successfully attached to shared memory, which is all we wanted */
if (ExecBackend && UsedShmemSegAddr != NULL)
break;
/* Check shared memory and possibly remove and recreate */
/* /*
* If the creator PID is my own PID or does not belong to any * If I am not the creator and it belongs to an extant process,
* extant process, it's safe to zap it. * continue.
*/ */
if (hdr->creatorPID != getpid()) if (hdr->creatorPID != getpid())
{ {
if (kill(hdr->creatorPID, 0) == 0 || if (kill(hdr->creatorPID, 0) == 0 || errno != ESRCH)
errno != ESRCH)
{ {
shmdt(memAddress); shmdt(memAddress);
continue; /* segment belongs to a live process */ continue; /* segment belongs to a live process */
...@@ -385,26 +401,31 @@ PGSharedMemoryCreate(uint32 size, bool makePrivate, int port) ...@@ -385,26 +401,31 @@ PGSharedMemoryCreate(uint32 size, bool makePrivate, int port)
*/ */
} }
/*
* OK, we created a new segment. Mark it as created by this process.
* The order of assignments here is critical so that another Postgres
* process can't see the header as valid but belonging to an invalid
* PID!
*/
hdr = (PGShmemHeader *) memAddress; hdr = (PGShmemHeader *) memAddress;
hdr->creatorPID = getpid();
hdr->magic = PGShmemMagic;
/* if (!ExecBackend || makePrivate || UsedShmemSegAddr == NULL)
* Initialize space allocation status for segment. {
*/ /*
hdr->totalsize = size; * OK, we created a new segment. Mark it as created by this process.
hdr->freeoffset = MAXALIGN(sizeof(PGShmemHeader)); * The order of assignments here is critical so that another Postgres
* process can't see the header as valid but belonging to an invalid
* PID!
*/
hdr->creatorPID = getpid();
hdr->magic = PGShmemMagic;
/*
* Initialize space allocation status for segment.
*/
hdr->totalsize = size;
hdr->freeoffset = MAXALIGN(sizeof(PGShmemHeader));
}
#ifdef EXEC_BACKEND if (ExecBackend && !makePrivate && UsedShmemSegAddr == NULL)
if (!makePrivate && UsedShmemSegID == 0) {
UsedShmemSegAddr = memAddress;
UsedShmemSegID = NextShmemSegID; UsedShmemSegID = NextShmemSegID;
#endif }
return hdr; return hdr;
} }
...@@ -37,7 +37,7 @@ ...@@ -37,7 +37,7 @@
* *
* *
* IDENTIFICATION * IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/postmaster/postmaster.c,v 1.322 2003/05/06 23:34:55 momjian Exp $ * $Header: /cvsroot/pgsql/src/backend/postmaster/postmaster.c,v 1.323 2003/05/08 14:49:03 momjian Exp $
* *
* NOTES * NOTES
* *
...@@ -2439,9 +2439,10 @@ BackendFinalize(Port *port) ...@@ -2439,9 +2439,10 @@ BackendFinalize(Port *port)
*/ */
av[ac++] = "-p"; av[ac++] = "-p";
#ifdef EXEC_BACKEND #ifdef EXEC_BACKEND
Assert(UsedShmemSegID != 0); Assert(UsedShmemSegID != 0 && UsedShmemSegAddr != NULL);
/* database name at the end because it might contain commas */ /* database name at the end because it might contain commas */
snprintf(pbuf, NAMEDATALEN + 256, "%d,%d,%s", port->sock, UsedShmemSegID, port->database_name); snprintf(pbuf, NAMEDATALEN + 256, "%d,%d,%p,%s", port->sock,
UsedShmemSegID, UsedShmemSegAddr, port->database_name);
av[ac++] = pbuf; av[ac++] = pbuf;
#else #else
av[ac++] = port->database_name; av[ac++] = port->database_name;
...@@ -2776,9 +2777,10 @@ SSDataBase(int xlop) ...@@ -2776,9 +2777,10 @@ SSDataBase(int xlop)
av[ac++] = "-p"; av[ac++] = "-p";
#ifdef EXEC_BACKEND #ifdef EXEC_BACKEND
Assert(UsedShmemSegID != 0); Assert(UsedShmemSegID != 0 && UsedShmemSegAddr != NULL);
/* database name at the end because it might contain commas */ /* database name at the end because it might contain commas */
snprintf(pbuf, NAMEDATALEN + 256, "%d,%s", UsedShmemSegID, "template1"); snprintf(pbuf, NAMEDATALEN + 256, "%d,%p,%s", UsedShmemSegID,
UsedShmemSegAddr, "template1");
av[ac++] = pbuf; av[ac++] = pbuf;
#else #else
av[ac++] = "template1"; av[ac++] = "template1";
......
...@@ -8,7 +8,7 @@ ...@@ -8,7 +8,7 @@
* *
* *
* IDENTIFICATION * IDENTIFICATION
* $Header: /cvsroot/pgsql/src/backend/tcop/postgres.c,v 1.338 2003/05/06 23:34:55 momjian Exp $ * $Header: /cvsroot/pgsql/src/backend/tcop/postgres.c,v 1.339 2003/05/08 14:49:04 momjian Exp $
* *
* NOTES * NOTES
* this is the "main" module of the postgres backend and * this is the "main" module of the postgres backend and
...@@ -2025,13 +2025,17 @@ PostgresMain(int argc, char *argv[], const char *username) ...@@ -2025,13 +2025,17 @@ PostgresMain(int argc, char *argv[], const char *username)
*/ */
if (secure) if (secure)
{ {
char *p;
#ifdef EXEC_BACKEND #ifdef EXEC_BACKEND
sscanf(optarg, "%d,%d,", &MyProcPort->sock, &UsedShmemSegID); char *p;
sscanf(optarg, "%d,%d,%p,", &MyProcPort->sock,
&UsedShmemSegID, &UsedShmemSegAddr);
/* Grab dbname as last param */ /* Grab dbname as last param */
p = strchr(optarg, ','); p = strchr(optarg, ',');
if (p) if (p)
p = strchr(p+1, ','); p = strchr(p+1, ',');
if (p)
p = strchr(p+1, ',');
if (p) if (p)
dbname = strdup(p+1); dbname = strdup(p+1);
#else #else
...@@ -2393,7 +2397,7 @@ PostgresMain(int argc, char *argv[], const char *username) ...@@ -2393,7 +2397,7 @@ PostgresMain(int argc, char *argv[], const char *username)
if (!IsUnderPostmaster) if (!IsUnderPostmaster)
{ {
puts("\nPOSTGRES backend interactive interface "); puts("\nPOSTGRES backend interactive interface ");
puts("$Revision: 1.338 $ $Date: 2003/05/06 23:34:55 $\n"); puts("$Revision: 1.339 $ $Date: 2003/05/08 14:49:04 $\n");
} }
/* /*
......
...@@ -17,7 +17,7 @@ ...@@ -17,7 +17,7 @@
* Portions Copyright (c) 1996-2002, PostgreSQL Global Development Group * Portions Copyright (c) 1996-2002, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California * Portions Copyright (c) 1994, Regents of the University of California
* *
* $Id: pg_shmem.h,v 1.5 2003/05/06 23:34:56 momjian Exp $ * $Id: pg_shmem.h,v 1.6 2003/05/08 14:49:04 momjian Exp $
* *
*------------------------------------------------------------------------- *-------------------------------------------------------------------------
*/ */
...@@ -38,6 +38,7 @@ typedef struct PGShmemHeader /* standard header for all Postgres shmem */ ...@@ -38,6 +38,7 @@ typedef struct PGShmemHeader /* standard header for all Postgres shmem */
#ifdef EXEC_BACKEND #ifdef EXEC_BACKEND
extern IpcMemoryKey UsedShmemSegID; extern IpcMemoryKey UsedShmemSegID;
extern void *UsedShmemSegAddr;
#endif #endif
extern PGShmemHeader *PGSharedMemoryCreate(uint32 size, bool makePrivate, extern PGShmemHeader *PGSharedMemoryCreate(uint32 size, bool makePrivate,
......
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