mirror of
https://git.postgresql.org/git/postgresql.git
synced 2025-01-24 18:55:04 +08:00
Pass shared memory address on command line to exec'ed backend.
Allow backends to attached to specified shared memory address.
This commit is contained in:
parent
4e08d35e7d
commit
5e7a5c9511
@ -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;
|
||||
}
|
||||
|
||||
/* Try to create new segment */
|
||||
memAddress = InternalIpcMemoryCreate(NextShmemSegID, size);
|
||||
if (memAddress)
|
||||
break; /* successful create and attach */
|
||||
/* 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,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->creatorPID = getpid();
|
||||
hdr->magic = PGShmemMagic;
|
||||
|
||||
/*
|
||||
* Initialize space allocation status for segment.
|
||||
*/
|
||||
hdr->totalsize = size;
|
||||
hdr->freeoffset = MAXALIGN(sizeof(PGShmemHeader));
|
||||
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->creatorPID = getpid();
|
||||
hdr->magic = PGShmemMagic;
|
||||
|
||||
/*
|
||||
* Initialize space allocation status for segment.
|
||||
*/
|
||||
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,13 +2025,17 @@ 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)
|
||||
dbname = strdup(p+1);
|
||||
#else
|
||||
@ -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,
|
||||
|
Loading…
Reference in New Issue
Block a user