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,