Pass shared memory address to exec'ed backend - Mailing list pgsql-patches

From Bruce Momjian
Subject Pass shared memory address to exec'ed backend
Date
Msg-id 200305080333.h483Xb818089@candle.pha.pa.us
Whole thread Raw
List pgsql-patches
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,

pgsql-patches by date:

Previous
From: Jason Tishler
Date:
Subject: Cygwin PostgreSQL CVS Patch
Next
From: Ben Lamb
Date:
Subject: Re: Patch for PGunescapeBytea