1111 *
1212 *
1313 * IDENTIFICATION
14- * $Header: /cvsroot/pgsql/src/backend/postmaster/postmaster.c,v 1.181 2000/11/09 11:25:59 vadim Exp $
14+ * $Header: /cvsroot/pgsql/src/backend/postmaster/postmaster.c,v 1.182 2000/11/12 20:51:51 tgl Exp $
1515 *
1616 * NOTES
1717 *
@@ -107,55 +107,45 @@ typedef struct bkend
107107Port * MyBackendPort = NULL ;
108108
109109/* list of active backends. For garbage collection only now. */
110-
111110static Dllist * BackendList ;
112111
113112/* list of ports associated with still open, but incomplete connections */
114113static Dllist * PortList ;
115114
115+ /* The socket number we are listening for connections on */
116116int PostPortName ;
117117
118- /*
119- * This is a boolean indicating that there is at least one backend that
120- * is accessing the current shared memory and semaphores. Between the
121- * time that we start up, or throw away shared memory segments and start
122- * over, and the time we generate the next backend (because we received a
123- * connection request), it is false. Other times, it is true.
124- */
118+ /*
119+ * This is a sequence number that indicates how many times we've had to
120+ * throw away the shared memory and start over because we doubted its
121+ * integrity.It starts off at zero and is incremented every time we
122+ * start over. We use this to ensure that we use a new IPC shared memory
123+ * key for the new shared memory segment in case the old segment isn't
124+ * entirely gone yet.
125+ *
126+ * The sequence actually cycles back to 0 after 9, so pathologically there
127+ * could be an IPC failure if 10 sets of backends are all stuck and won't
128+ * release IPC resources.
129+ */
125130static short shmem_seq = 0 ;
126131
127- /*
128- * This is a sequence number that indicates how many times we've had to
129- * throw away the shared memory and start over because we doubted its
130- * integrity.It starts off at zero and is incremented every time we
131- * start over. We use this to ensure that we use a new IPC shared memory
132- * key for the new shared memory segment in case the old segment isn't
133- * entirely gone yet.
134- *
135- * The sequence actually cycles back to 0 after 9, so pathologically there
136- * could be an IPC failure if 10 sets of backends are all stuck and won't
137- * release IPC resources.
138- */
139-
132+ /*
133+ * This is the base IPC shared memory key. Other keys are generated by
134+ * adding to this.
135+ */
140136static IpcMemoryKey ipc_key ;
141137
142- /*
143- * This is the base IPC shared memory key. Other keys are generated by
144- * adding to this.
145- */
146-
138+ /*
139+ * MaxBackends is the actual limit on the number of backends we will
140+ * start. The default is established by configure, but it can be
141+ * readjusted from 1..MAXBACKENDS with the postmaster -N switch. Note
142+ * that a larger MaxBackends value will increase the size of the shared
143+ * memory area as well as cause the postmaster to grab more kernel
144+ * semaphores, even if you never actually use that many backends.
145+ */
147146int MaxBackends = DEF_MAXBACKENDS ;
148147
149- /*
150- * MaxBackends is the actual limit on the number of backends we will
151- * start. The default is established by configure, but it can be
152- * readjusted from 1..MAXBACKENDS with the postmaster -N switch. Note
153- * that a larger MaxBackends value will increase the size of the shared
154- * memory area as well as cause the postmaster to grab more kernel
155- * semaphores, even if you never actually use that many backends.
156- */
157148
158- static int NextBackendTag = INT_MAX ;/* XXX why count down not up? */
159149static char * progname = (char * )NULL ;
160150static char * * real_argv ;
161151static int real_argc ;
@@ -587,6 +577,22 @@ PostmasterMain(int argc, char *argv[])
587577exit (1 );
588578}
589579
580+ if (DebugLvl > 2 )
581+ {
582+ extern char * * environ ;
583+ char * * p ;
584+
585+ fprintf (stderr ,"%s: PostmasterMain: initial environ dump:\n" ,
586+ progname );
587+ fprintf (stderr ,"-----------------------------------------\n" );
588+ for (p = environ ;* p ;++ p )
589+ fprintf (stderr ,"\t%s\n" ,* p );
590+ fprintf (stderr ,"-----------------------------------------\n" );
591+ }
592+
593+ /*
594+ * Establish input sockets.
595+ */
590596#ifdef USE_SSL
591597if (EnableSSL && !NetServer )
592598{
@@ -600,7 +606,8 @@ PostmasterMain(int argc, char *argv[])
600606
601607if (NetServer )
602608{
603- status = StreamServerPort (AF_INET , (unsigned short )PostPortName ,& ServerSock_INET );
609+ status = StreamServerPort (AF_INET , (unsigned short )PostPortName ,
610+ & ServerSock_INET );
604611if (status != STATUS_OK )
605612{
606613fprintf (stderr ,"%s: cannot create INET stream port\n" ,
@@ -610,18 +617,20 @@ PostmasterMain(int argc, char *argv[])
610617}
611618
612619#ifdef HAVE_UNIX_SOCKETS
613- status = StreamServerPort (AF_UNIX , (unsigned short )PostPortName ,& ServerSock_UNIX );
620+ status = StreamServerPort (AF_UNIX , (unsigned short )PostPortName ,
621+ & ServerSock_UNIX );
614622if (status != STATUS_OK )
615623{
616624fprintf (stderr ,"%s: cannot create UNIX stream port\n" ,
617625progname );
618626ExitPostmaster (1 );
619627}
620628#endif
629+
621630/* set up shared memory and semaphores */
622631reset_shared (PostPortName );
623632
624- /* Init XLOGpathes */
633+ /* Init XLOGpaths */
625634snprintf (XLogDir ,MAXPGPATH ,"%s/pg_xlog" ,DataDir );
626635snprintf (ControlFilePath ,MAXPGPATH ,"%s/global/pg_control" ,DataDir );
627636
@@ -1706,43 +1715,7 @@ static int
17061715BackendStartup (Port * port )
17071716{
17081717Backend * bn ;/* for backend cleanup */
1709- int pid ,
1710- i ;
1711-
1712- #ifdef CYR_RECODE
1713- #define NR_ENVIRONMENT_VBL 5
1714- char ChTable [80 ];
1715-
1716- #else
1717- #define NR_ENVIRONMENT_VBL 4
1718- #endif
1719-
1720- static char envEntry [NR_ENVIRONMENT_VBL ][2 * ARGV_SIZE ];
1721-
1722- for (i = 0 ;i < NR_ENVIRONMENT_VBL ;++ i )
1723- MemSet (envEntry [i ],0 ,2 * ARGV_SIZE );
1724-
1725- /*
1726- * Set up the necessary environment variables for the backend This
1727- * should really be some sort of message....
1728- */
1729- sprintf (envEntry [0 ],"POSTPORT=%d" ,PostPortName );
1730- putenv (envEntry [0 ]);
1731- sprintf (envEntry [1 ],"POSTID=%d" ,NextBackendTag );
1732- putenv (envEntry [1 ]);
1733- sprintf (envEntry [2 ],"PGDATA=%s" ,DataDir );
1734- putenv (envEntry [2 ]);
1735- sprintf (envEntry [3 ],"IPC_KEY=%d" ,ipc_key );
1736- putenv (envEntry [3 ]);
1737-
1738- #ifdef CYR_RECODE
1739- GetCharSetByHost (ChTable ,port -> raddr .in .sin_addr .s_addr ,DataDir );
1740- if (* ChTable != '\0' )
1741- {
1742- sprintf (envEntry [4 ],"PG_RECODETABLE=%s" ,ChTable );
1743- putenv (envEntry [4 ]);
1744- }
1745- #endif
1718+ int pid ;
17461719
17471720/*
17481721 * Compute the cancel key that will be assigned to this backend. The
@@ -1751,19 +1724,6 @@ BackendStartup(Port *port)
17511724 */
17521725MyCancelKey = PostmasterRandom ();
17531726
1754- if (DebugLvl > 2 )
1755- {
1756- char * * p ;
1757- extern char * * environ ;
1758-
1759- fprintf (stderr ,"%s: BackendStartup: environ dump:\n" ,
1760- progname );
1761- fprintf (stderr ,"-----------------------------------------\n" );
1762- for (p = environ ;* p ;++ p )
1763- fprintf (stderr ,"\t%s\n" ,* p );
1764- fprintf (stderr ,"-----------------------------------------\n" );
1765- }
1766-
17671727/*
17681728 * Flush stdio channels just before fork, to avoid double-output
17691729 * problems. Ideally we'd use fflush(NULL) here, but there are still a
@@ -1779,12 +1739,30 @@ BackendStartup(Port *port)
17791739/* Specific beos actions before backend startup */
17801740beos_before_backend_startup ();
17811741#endif
1742+
17821743if ((pid = fork ())== 0 )
17831744{/* child */
17841745#ifdef __BEOS__
1785- /* Specific beos backendstratup actions */
1746+ /* Specific beos backendstartup actions */
17861747beos_backend_startup ();
17871748#endif
1749+
1750+ #ifdef CYR_RECODE
1751+ {
1752+ /* Save charset for this host while we still have client addr */
1753+ char ChTable [80 ];
1754+ static char cyrEnvironment [100 ];
1755+
1756+ GetCharSetByHost (ChTable ,port -> raddr .in .sin_addr .s_addr ,DataDir );
1757+ if (* ChTable != '\0' )
1758+ {
1759+ snprintf (cyrEnvironment ,sizeof (cyrEnvironment ),
1760+ "PG_RECODETABLE=%s" ,ChTable );
1761+ putenv (cyrEnvironment );
1762+ }
1763+ }
1764+ #endif
1765+
17881766if (DoBackend (port ))
17891767{
17901768fprintf (stderr ,"%s child[%d]: BackendStartup: backend startup failed\n" ,
@@ -1799,7 +1777,7 @@ BackendStartup(Port *port)
17991777if (pid < 0 )
18001778{
18011779#ifdef __BEOS__
1802- /* Specific beos backendstratup actions */
1780+ /* Specific beos backendstartup actions */
18031781beos_backend_startup_failed ();
18041782#endif
18051783fprintf (stderr ,"%s: BackendStartup: fork failed: %s\n" ,
@@ -1812,14 +1790,6 @@ BackendStartup(Port *port)
18121790progname ,pid ,port -> user ,port -> database ,
18131791port -> sock );
18141792
1815- /* Generate a new backend tag for every backend we start */
1816-
1817- /*
1818- * XXX theoretically this could wrap around, if you have the patience
1819- * to start 2^31 backends ...
1820- */
1821- NextBackendTag -= 1 ;
1822-
18231793/*
18241794 * Everything's been successful, it's safe to add this backend to our
18251795 * list of backends.
@@ -2179,21 +2149,7 @@ static pid_t
21792149SSDataBase (int xlop )
21802150{
21812151pid_t pid ;
2182- int i ;
21832152Backend * bn ;
2184- static char ssEntry [4 ][2 * ARGV_SIZE ];
2185-
2186- for (i = 0 ;i < 4 ;++ i )
2187- MemSet (ssEntry [i ],0 ,2 * ARGV_SIZE );
2188-
2189- sprintf (ssEntry [0 ],"POSTPORT=%d" ,PostPortName );
2190- putenv (ssEntry [0 ]);
2191- sprintf (ssEntry [1 ],"POSTID=%d" ,NextBackendTag );
2192- putenv (ssEntry [1 ]);
2193- sprintf (ssEntry [2 ],"PGDATA=%s" ,DataDir );
2194- putenv (ssEntry [2 ]);
2195- sprintf (ssEntry [3 ],"IPC_KEY=%d" ,ipc_key );
2196- putenv (ssEntry [3 ]);
21972153
21982154fflush (stdout );
21992155fflush (stderr );
@@ -2258,8 +2214,6 @@ SSDataBase(int xlop)
22582214ExitPostmaster (1 );
22592215}
22602216
2261- NextBackendTag -= 1 ;
2262-
22632217if (xlop != BS_XLOG_CHECKPOINT )
22642218return (pid );
22652219