mirror of
https://git.postgresql.org/git/postgresql.git
synced 2024-10-01 07:31:16 +02:00
If we fail to fork a new backend process, (try to) report the failure
to the client before closing the connection. Before 7.2 this was done correctly, but new code would simply close the connection with no report to the client.
This commit is contained in:
parent
96ad60e919
commit
a510bf4326
@ -37,7 +37,7 @@
|
|||||||
*
|
*
|
||||||
*
|
*
|
||||||
* IDENTIFICATION
|
* IDENTIFICATION
|
||||||
* $Header: /cvsroot/pgsql/src/backend/postmaster/postmaster.c,v 1.262 2001/12/04 16:17:48 tgl Exp $
|
* $Header: /cvsroot/pgsql/src/backend/postmaster/postmaster.c,v 1.263 2002/01/06 21:40:02 tgl Exp $
|
||||||
*
|
*
|
||||||
* NOTES
|
* NOTES
|
||||||
*
|
*
|
||||||
@ -249,6 +249,7 @@ static int BackendStartup(Port *port);
|
|||||||
static int ProcessStartupPacket(Port *port, bool SSLdone);
|
static int ProcessStartupPacket(Port *port, bool SSLdone);
|
||||||
static void processCancelRequest(Port *port, void *pkt);
|
static void processCancelRequest(Port *port, void *pkt);
|
||||||
static int initMasks(fd_set *rmask, fd_set *wmask);
|
static int initMasks(fd_set *rmask, fd_set *wmask);
|
||||||
|
static void report_fork_failure_to_client(Port *port, int errnum);
|
||||||
enum CAC_state
|
enum CAC_state
|
||||||
{
|
{
|
||||||
CAC_OK, CAC_STARTUP, CAC_SHUTDOWN, CAC_RECOVERY, CAC_TOOMANY
|
CAC_OK, CAC_STARTUP, CAC_SHUTDOWN, CAC_RECOVERY, CAC_TOOMANY
|
||||||
@ -1864,11 +1865,11 @@ BackendStartup(Port *port)
|
|||||||
{
|
{
|
||||||
int status;
|
int status;
|
||||||
|
|
||||||
free(bn);
|
|
||||||
#ifdef __BEOS__
|
#ifdef __BEOS__
|
||||||
/* Specific beos backend startup actions */
|
/* Specific beos backend startup actions */
|
||||||
beos_backend_startup();
|
beos_backend_startup();
|
||||||
#endif
|
#endif
|
||||||
|
free(bn);
|
||||||
|
|
||||||
status = DoBackend(port);
|
status = DoBackend(port);
|
||||||
if (status != 0)
|
if (status != 0)
|
||||||
@ -1883,13 +1884,16 @@ BackendStartup(Port *port)
|
|||||||
/* in parent, error */
|
/* in parent, error */
|
||||||
if (pid < 0)
|
if (pid < 0)
|
||||||
{
|
{
|
||||||
free(bn);
|
int save_errno = errno;
|
||||||
|
|
||||||
#ifdef __BEOS__
|
#ifdef __BEOS__
|
||||||
/* Specific beos backend startup actions */
|
/* Specific beos backend startup actions */
|
||||||
beos_backend_startup_failed();
|
beos_backend_startup_failed();
|
||||||
#endif
|
#endif
|
||||||
|
free(bn);
|
||||||
elog(DEBUG, "connection startup failed (fork failure): %s",
|
elog(DEBUG, "connection startup failed (fork failure): %s",
|
||||||
strerror(errno));
|
strerror(save_errno));
|
||||||
|
report_fork_failure_to_client(port, save_errno);
|
||||||
return STATUS_ERROR;
|
return STATUS_ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1910,6 +1914,40 @@ BackendStartup(Port *port)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Try to report backend fork() failure to client before we close the
|
||||||
|
* connection. Since we do not care to risk blocking the postmaster on
|
||||||
|
* this connection, we set the connection to non-blocking and try only once.
|
||||||
|
*
|
||||||
|
* This is grungy special-purpose code; we cannot use backend libpq since
|
||||||
|
* it's not up and running.
|
||||||
|
*/
|
||||||
|
static void
|
||||||
|
report_fork_failure_to_client(Port *port, int errnum)
|
||||||
|
{
|
||||||
|
char buffer[1000];
|
||||||
|
#ifdef __BEOS__
|
||||||
|
int on = 1;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* Format the error message packet */
|
||||||
|
snprintf(buffer, sizeof(buffer), "E%s%s\n",
|
||||||
|
gettext("Server process fork() failed: "),
|
||||||
|
strerror(errnum));
|
||||||
|
|
||||||
|
/* Set port to non-blocking. Don't do send() if this fails */
|
||||||
|
#ifdef __BEOS__
|
||||||
|
if (ioctl(port->sock, FIONBIO, &on) != 0)
|
||||||
|
return;
|
||||||
|
#else
|
||||||
|
if (fcntl(port->sock, F_SETFL, O_NONBLOCK) < 0)
|
||||||
|
return;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
send(port->sock, buffer, strlen(buffer)+1, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* split_opts -- split a string of options and append it to an argv array
|
* split_opts -- split a string of options and append it to an argv array
|
||||||
*
|
*
|
||||||
|
Loading…
Reference in New Issue
Block a user