This patch passes the shared memory address to exec'ed backends. It
also allows exec'ed backends to attached to shared memory at the passed
in address.
--
Bruce Momjian | http://candle.pha.pa.us
pgman@candle.pha.pa.us | (610) 359-1001
+ If your life is a hard drive, | 13 Roberts Road
+ Christ can be your backup. | Newtown Square, Pennsylvania 19073
Index: src/backend/bootstrap/bootstrap.c
===================================================================
RCS file: /cvsroot/pgsql-server/src/backend/bootstrap/bootstrap.c,v
retrieving revision 1.155
diff -c -c -r1.155 bootstrap.c
*** src/backend/bootstrap/bootstrap.c 6 May 2003 23:34:55 -0000 1.155
--- src/backend/bootstrap/bootstrap.c 8 May 2003 02:47:22 -0000
***************
*** 286,295 ****
case 'p':
{
/* indicates fork from postmaster */
- char *p;
#ifdef EXEC_BACKEND
! sscanf(optarg, "%d,", &UsedShmemSegID);
p = strchr(optarg, ',');
if (p)
dbname = strdup(p+1);
#else
--- 286,298 ----
case 'p':
{
/* indicates fork from postmaster */
#ifdef EXEC_BACKEND
! char *p;
!
! sscanf(optarg, "%d,%p,", &UsedShmemSegID, &UsedShmemSegAddr);
p = strchr(optarg, ',');
+ if (p)
+ p = strchr(p+1, ',');
if (p)
dbname = strdup(p+1);
#else
Index: src/backend/port/sysv_shmem.c
===================================================================
RCS file: /cvsroot/pgsql-server/src/backend/port/sysv_shmem.c,v
retrieving revision 1.8
diff -c -c -r1.8 sysv_shmem.c
*** src/backend/port/sysv_shmem.c 6 May 2003 23:34:55 -0000 1.8
--- src/backend/port/sysv_shmem.c 8 May 2003 02:47:22 -0000
***************
*** 39,47 ****
#define IPCProtection (0600) /* access/modify by user only */
- #ifdef EXEC_BACKEND
IpcMemoryKey UsedShmemSegID = 0;
! #endif
static void *InternalIpcMemoryCreate(IpcMemoryKey memKey, uint32 size);
static void IpcMemoryDetach(int status, Datum shmaddr);
--- 39,46 ----
#define IPCProtection (0600) /* access/modify by user only */
IpcMemoryKey UsedShmemSegID = 0;
! void *UsedShmemSegAddr = NULL;
static void *InternalIpcMemoryCreate(IpcMemoryKey memKey, uint32 size);
static void IpcMemoryDetach(int status, Datum shmaddr);
***************
*** 282,288 ****
*
* 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.
*
* 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
--- 281,287 ----
*
* 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. 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,312 ****
/* Room for a header? */
Assert(size > MAXALIGN(sizeof(PGShmemHeader)));
! #ifdef EXEC_BACKEND
! if (UsedShmemSegID != 0)
NextShmemSegID = UsedShmemSegID;
else
- #endif
NextShmemSegID = port * 1000 + 1;
for (;;NextShmemSegID++)
--- 301,309 ----
/* Room for a header? */
Assert(size > MAXALIGN(sizeof(PGShmemHeader)));
! if (ExecBackend && UsedShmemSegID != 0)
NextShmemSegID = UsedShmemSegID;
else
NextShmemSegID = port * 1000 + 1;
for (;;NextShmemSegID++)
***************
*** 320,344 ****
break;
}
! /* 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);
#else
! memAddress = shmat(shmid, 0, 0);
#endif
if (memAddress == (void *) -1)
continue; /* failed: must be some other app's */
hdr = (PGShmemHeader *) memAddress;
if (hdr->magic != PGShmemMagic)
{
--- 317,355 ----
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 */
/* use intimate shared memory on SPARC Solaris */
! memAddress = shmat(shmid, UsedShmemSegAddr,
! #if defined(solaris) && defined(__sparc__)
! SHM_SHARE_MMU
#else
! 0
#endif
+ );
if (memAddress == (void *) -1)
continue; /* failed: must be some other app's */
+
hdr = (PGShmemHeader *) memAddress;
if (hdr->magic != PGShmemMagic)
{
***************
*** 346,359 ****
continue; /* segment belongs to a non-Postgres app */
}
/*
! * If the creator PID is my own PID or does not belong to any
! * extant process, it's safe to zap it.
*/
if (hdr->creatorPID != getpid())
{
! if (kill(hdr->creatorPID, 0) == 0 ||
! errno != ESRCH)
{
shmdt(memAddress);
continue; /* segment belongs to a live process */
--- 357,375 ----
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 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)
{
shmdt(memAddress);
continue; /* segment belongs to a live process */
***************
*** 385,410 ****
*/
}
- /*
- * 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));
! #ifdef EXEC_BACKEND
! if (!makePrivate && UsedShmemSegID == 0)
UsedShmemSegID = NextShmemSegID;
! #endif
return hdr;
}
--- 401,431 ----
*/
}
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->creatorPID = getpid();
! hdr->magic = PGShmemMagic;
!
! /*
! * Initialize space allocation status for segment.
! */
! hdr->totalsize = size;
! hdr->freeoffset = MAXALIGN(sizeof(PGShmemHeader));
! }
! if (ExecBackend && !makePrivate && UsedShmemSegAddr == NULL)
! {
! UsedShmemSegAddr = memAddress;
UsedShmemSegID = NextShmemSegID;
! }
return hdr;
}
Index: src/backend/postmaster/postmaster.c
===================================================================
RCS file: /cvsroot/pgsql-server/src/backend/postmaster/postmaster.c,v
retrieving revision 1.322
diff -c -c -r1.322 postmaster.c
*** src/backend/postmaster/postmaster.c 6 May 2003 23:34:55 -0000 1.322
--- src/backend/postmaster/postmaster.c 8 May 2003 02:47:25 -0000
***************
*** 2439,2447 ****
*/
av[ac++] = "-p";
#ifdef EXEC_BACKEND
! Assert(UsedShmemSegID != 0);
/* database name at the end because it might contain commas */
! snprintf(pbuf, NAMEDATALEN + 256, "%d,%d,%s", port->sock, UsedShmemSegID, port->database_name);
av[ac++] = pbuf;
#else
av[ac++] = port->database_name;
--- 2439,2448 ----
*/
av[ac++] = "-p";
#ifdef EXEC_BACKEND
! Assert(UsedShmemSegID != 0 && UsedShmemSegAddr != NULL);
/* database name at the end because it might contain commas */
! 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,2784 ****
av[ac++] = "-p";
#ifdef EXEC_BACKEND
! Assert(UsedShmemSegID != 0);
/* database name at the end because it might contain commas */
! snprintf(pbuf, NAMEDATALEN + 256, "%d,%s", UsedShmemSegID, "template1");
av[ac++] = pbuf;
#else
av[ac++] = "template1";
--- 2777,2786 ----
av[ac++] = "-p";
#ifdef EXEC_BACKEND
! Assert(UsedShmemSegID != 0 && UsedShmemSegAddr != NULL);
/* database name at the end because it might contain commas */
! snprintf(pbuf, NAMEDATALEN + 256, "%d,%p,%s", UsedShmemSegID,
! UsedShmemSegAddr, "template1");
av[ac++] = pbuf;
#else
av[ac++] = "template1";
Index: src/backend/tcop/postgres.c
===================================================================
RCS file: /cvsroot/pgsql-server/src/backend/tcop/postgres.c,v
retrieving revision 1.338
diff -c -c -r1.338 postgres.c
*** src/backend/tcop/postgres.c 6 May 2003 23:34:55 -0000 1.338
--- src/backend/tcop/postgres.c 8 May 2003 02:47:35 -0000
***************
*** 2025,2036 ****
*/
if (secure)
{
- char *p;
#ifdef EXEC_BACKEND
! sscanf(optarg, "%d,%d,", &MyProcPort->sock, &UsedShmemSegID);
/* Grab dbname as last param */
p = strchr(optarg, ',');
if (p)
p = strchr(p+1, ',');
if (p)
dbname = strdup(p+1);
--- 2025,2040 ----
*/
if (secure)
{
#ifdef EXEC_BACKEND
! 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);
Index: src/include/storage/pg_shmem.h
===================================================================
RCS file: /cvsroot/pgsql-server/src/include/storage/pg_shmem.h,v
retrieving revision 1.5
diff -c -c -r1.5 pg_shmem.h
*** src/include/storage/pg_shmem.h 6 May 2003 23:34:56 -0000 1.5
--- src/include/storage/pg_shmem.h 8 May 2003 02:47:36 -0000
***************
*** 38,43 ****
--- 38,44 ----
#ifdef EXEC_BACKEND
extern IpcMemoryKey UsedShmemSegID;
+ extern void *UsedShmemSegAddr;
#endif
extern PGShmemHeader *PGSharedMemoryCreate(uint32 size, bool makePrivate,