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 @@
* Portions Copyright (c) 1994, Regents of the University of California
*
* 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[])
case 'p':
{
/* indicates fork from postmaster */
char *p;
#ifdef EXEC_BACKEND
sscanf(optarg, "%d,", &UsedShmemSegID);
char *p;
sscanf(optarg, "%d,%p,", &UsedShmemSegID, &UsedShmemSegAddr);
p = strchr(optarg, ',');
if (p)
p = strchr(p+1, ',');
if (p)
dbname = strdup(p+1);
#else
......
......@@ -10,7 +10,7 @@
* Portions Copyright (c) 1994, Regents of the University of California
*
* 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) */
#define IPCProtection (0600) /* access/modify by user only */
#ifdef EXEC_BACKEND
IpcMemoryKey UsedShmemSegID = 0;
#endif
void *UsedShmemSegAddr = NULL;
static void *InternalIpcMemoryCreate(IpcMemoryKey memKey, uint32 size);
static void IpcMemoryDetach(int status, Datum shmaddr);
......@@ -282,7 +281,7 @@ PrivateMemoryDelete(int status, Datum memaddr)
*
* Create a shared memory segment of the given size and initialize its
* 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
* collision with non-Postgres shmem segments. The idea here is to detect and
......@@ -302,11 +301,9 @@ PGSharedMemoryCreate(uint32 size, bool makePrivate, int port)
/* Room for a header? */
Assert(size > MAXALIGN(sizeof(PGShmemHeader)));
#ifdef EXEC_BACKEND
if (UsedShmemSegID != 0)
if (ExecBackend && UsedShmemSegID != 0)
NextShmemSegID = UsedShmemSegID;
else
#endif
NextShmemSegID = port * 1000 + 1;
for (;;NextShmemSegID++)
......@@ -320,25 +317,39 @@ PGSharedMemoryCreate(uint32 size, bool makePrivate, int port)
break;
}
/* If attach to fixed address, only try once */
if (ExecBackend && UsedShmemSegAddr != NULL && NextShmemSegID != UsedShmemSegID)
{
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 */
shmid = shmget(NextShmemSegID, sizeof(PGShmemHeader), 0);
if (shmid < 0)
continue; /* failed: must be some other app's */
#if defined(solaris) && defined(__sparc__)
/* 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
memAddress = shmat(shmid, 0, 0);
0
#endif
);
if (memAddress == (void *) -1)
continue; /* failed: must be some other app's */
hdr = (PGShmemHeader *) memAddress;
if (hdr->magic != PGShmemMagic)
{
......@@ -346,14 +357,19 @@ PGSharedMemoryCreate(uint32 size, bool makePrivate, int port)
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
* extant process, it's safe to zap it.
* If I am not the creator and it belongs to an extant process,
* continue.
*/
if (hdr->creatorPID != getpid())
{
if (kill(hdr->creatorPID, 0) == 0 ||
errno != ESRCH)
if (kill(hdr->creatorPID, 0) == 0 || errno != ESRCH)
{
shmdt(memAddress);
continue; /* segment belongs to a live process */
......@@ -385,13 +401,16 @@ PGSharedMemoryCreate(uint32 size, bool makePrivate, int port)
*/
}
hdr = (PGShmemHeader *) memAddress;
if (!ExecBackend || makePrivate || UsedShmemSegAddr == NULL)
{
/*
* 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->creatorPID = getpid();
hdr->magic = PGShmemMagic;
......@@ -400,11 +419,13 @@ PGSharedMemoryCreate(uint32 size, bool makePrivate, int port)
*/
hdr->totalsize = size;
hdr->freeoffset = MAXALIGN(sizeof(PGShmemHeader));
}
#ifdef EXEC_BACKEND
if (!makePrivate && UsedShmemSegID == 0)
if (ExecBackend && !makePrivate && UsedShmemSegAddr == NULL)
{
UsedShmemSegAddr = memAddress;
UsedShmemSegID = NextShmemSegID;
#endif
}
return hdr;
}
......@@ -37,7 +37,7 @@
*
*
* 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
*
......@@ -2439,9 +2439,10 @@ BackendFinalize(Port *port)
*/
av[ac++] = "-p";
#ifdef EXEC_BACKEND
Assert(UsedShmemSegID != 0);
Assert(UsedShmemSegID != 0 && UsedShmemSegAddr != NULL);
/* 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;
#else
av[ac++] = port->database_name;
......@@ -2776,9 +2777,10 @@ SSDataBase(int xlop)
av[ac++] = "-p";
#ifdef EXEC_BACKEND
Assert(UsedShmemSegID != 0);
Assert(UsedShmemSegID != 0 && UsedShmemSegAddr != NULL);
/* 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;
#else
av[ac++] = "template1";
......
......@@ -8,7 +8,7 @@
*
*
* 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
* this is the "main" module of the postgres backend and
......@@ -2025,11 +2025,15 @@ PostgresMain(int argc, char *argv[], const char *username)
*/
if (secure)
{
char *p;
#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 */
p = strchr(optarg, ',');
if (p)
p = strchr(p+1, ',');
if (p)
p = strchr(p+1, ',');
if (p)
......@@ -2393,7 +2397,7 @@ PostgresMain(int argc, char *argv[], const char *username)
if (!IsUnderPostmaster)
{
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 @@
* Portions Copyright (c) 1996-2002, PostgreSQL Global Development Group
* 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 */
#ifdef EXEC_BACKEND
extern IpcMemoryKey UsedShmemSegID;
extern void *UsedShmemSegAddr;
#endif
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