@@ -401,7 +401,8 @@ static void SIGHUP_handler(SIGNAL_ARGS);
401
401
static void pmdie (SIGNAL_ARGS );
402
402
static void reaper (SIGNAL_ARGS );
403
403
static void sigusr1_handler (SIGNAL_ARGS );
404
- static void startup_die (SIGNAL_ARGS );
404
+ static void process_startup_packet_die (SIGNAL_ARGS );
405
+ static void process_startup_packet_quickdie (SIGNAL_ARGS );
405
406
static void dummy_handler (SIGNAL_ARGS );
406
407
static void StartupPacketTimeoutHandler (void );
407
408
static void CleanupBackend (int pid ,int exitstatus );
@@ -4258,22 +4259,30 @@ BackendInitialize(Port *port)
4258
4259
whereToSendOutput = DestRemote ;/* now safe to ereport to client */
4259
4260
4260
4261
/*
4261
- * We arrange for a simple exit(1) if we receive SIGTERM or SIGQUIT or
4262
- * timeout while trying to collect the startup packet. Otherwise the
4263
- * postmaster cannot shutdown the database FAST or IMMED cleanly if a
4264
- * buggy client fails to send the packet promptly. XXX it follows that
4265
- * the remainder of this function must tolerate losing control at any
4266
- * instant. Likewise, any pg_on_exit_callback registered before or during
4267
- * this function must be prepared to execute at any instant between here
4268
- * and the end of this function. Furthermore, affected callbacks execute
4269
- * partially or not at all when a second exit-inducing signal arrives
4270
- * after proc_exit_prepare() decrements on_proc_exit_index. (Thanks to
4271
- * that mechanic, callbacks need not anticipate more than one call.) This
4272
- * is fragile; it ought to instead follow the norm of handling interrupts
4273
- * at selected, safe opportunities.
4262
+ * We arrange to do proc_exit(1) if we receive SIGTERM or timeout while
4263
+ * trying to collect the startup packet; while SIGQUIT results in
4264
+ * _exit(2). Otherwise the postmaster cannot shutdown the database FAST
4265
+ * or IMMED cleanly if a buggy client fails to send the packet promptly.
4266
+ *
4267
+ * XXX this is pretty dangerous; signal handlers should not call anything
4268
+ * as complex as proc_exit() directly. We minimize the hazard by not
4269
+ * keeping these handlers active for longer than we must. However, it
4270
+ * seems necessary to be able to escape out of DNS lookups as well as the
4271
+ * startup packet reception proper, so we can't narrow the scope further
4272
+ * than is done here.
4273
+ *
4274
+ * XXX it follows that the remainder of this function must tolerate losing
4275
+ * control at any instant. Likewise, any pg_on_exit_callback registered
4276
+ * before or during this function must be prepared to execute at any
4277
+ * instant between here and the end of this function. Furthermore,
4278
+ * affected callbacks execute partially or not at all when a second
4279
+ * exit-inducing signal arrives after proc_exit_prepare() decrements
4280
+ * on_proc_exit_index. (Thanks to that mechanic, callbacks need not
4281
+ * anticipate more than one call.) This is fragile; it ought to instead
4282
+ * follow the norm of handling interrupts at selected, safe opportunities.
4274
4283
*/
4275
- pqsignal (SIGTERM ,startup_die );
4276
- pqsignal (SIGQUIT ,startup_die );
4284
+ pqsignal (SIGTERM ,process_startup_packet_die );
4285
+ pqsignal (SIGQUIT ,process_startup_packet_quickdie );
4277
4286
InitializeTimeouts ();/* establishes SIGALRM handler */
4278
4287
PG_SETMASK (& StartupBlockSig );
4279
4288
@@ -4333,8 +4342,8 @@ BackendInitialize(Port *port)
4333
4342
port -> remote_hostname = strdup (remote_host );
4334
4343
4335
4344
/*
4336
- * Ready to begin client interaction. We will give up andexit (1) after a
4337
- * time delay, so that a broken client can't hog a connection
4345
+ * Ready to begin client interaction. We will give up andproc_exit (1)
4346
+ *after a time delay, so that a broken client can't hog a connection
4338
4347
* indefinitely. PreAuthDelay and any DNS interactions above don't count
4339
4348
* against the time limit.
4340
4349
*
@@ -4356,6 +4365,12 @@ BackendInitialize(Port *port)
4356
4365
*/
4357
4366
status = ProcessStartupPacket (port , false, false);
4358
4367
4368
+ /*
4369
+ * Disable the timeout, and prevent SIGTERM/SIGQUIT again.
4370
+ */
4371
+ disable_timeout (STARTUP_PACKET_TIMEOUT , false);
4372
+ PG_SETMASK (& BlockSig );
4373
+
4359
4374
/*
4360
4375
* Stop here if it was bad or a cancel packet. ProcessStartupPacket
4361
4376
* already did any appropriate error reporting.
@@ -4381,12 +4396,6 @@ BackendInitialize(Port *port)
4381
4396
else
4382
4397
init_ps_display (port -> user_name ,port -> database_name ,remote_ps_data ,
4383
4398
update_process_title ?"authentication" :"" );
4384
-
4385
- /*
4386
- * Disable the timeout, and prevent SIGTERM/SIGQUIT again.
4387
- */
4388
- disable_timeout (STARTUP_PACKET_TIMEOUT , false);
4389
- PG_SETMASK (& BlockSig );
4390
4399
}
4391
4400
4392
4401
@@ -5267,20 +5276,49 @@ sigusr1_handler(SIGNAL_ARGS)
5267
5276
}
5268
5277
5269
5278
/*
5270
- * SIGTERMor SIGQUIT while processing startup packet.
5279
+ * SIGTERM while processing startup packet.
5271
5280
* Clean up and exit(1).
5272
5281
*
5273
- * XXX: possible future improvement: try to send a message indicating
5274
- * why we are disconnecting. Problem is to be sure we don't block while
5275
- * doing so, nor mess up SSL initialization. In practice, if the client
5276
- * has wedged here, it probably couldn't do anything with the message anyway.
5282
+ * Running proc_exit() from a signal handler is pretty unsafe, since we
5283
+ * can't know what code we've interrupted. But the alternative of using
5284
+ * _exit(2) is also unpalatable, since it'd mean that a "fast shutdown"
5285
+ * would cause a database crash cycle (forcing WAL replay at restart)
5286
+ * if any sessions are in authentication. So we live with it for now.
5287
+ *
5288
+ * One might be tempted to try to send a message indicating why we are
5289
+ * disconnecting. However, that would make this even more unsafe. Also,
5290
+ * it seems undesirable to provide clues about the database's state to
5291
+ * a client that has not yet completed authentication.
5277
5292
*/
5278
5293
static void
5279
- startup_die (SIGNAL_ARGS )
5294
+ process_startup_packet_die (SIGNAL_ARGS )
5280
5295
{
5281
5296
proc_exit (1 );
5282
5297
}
5283
5298
5299
+ /*
5300
+ * SIGQUIT while processing startup packet.
5301
+ *
5302
+ * Some backend has bought the farm,
5303
+ * so we need to stop what we're doing and exit.
5304
+ */
5305
+ static void
5306
+ process_startup_packet_quickdie (SIGNAL_ARGS )
5307
+ {
5308
+ /*
5309
+ * We DO NOT want to run proc_exit() or atexit() callbacks; they wouldn't
5310
+ * be safe to run from a signal handler. Just nail the windows shut and
5311
+ * get out of town.
5312
+ *
5313
+ * Note we do _exit(2) not _exit(1). This is to force the postmaster into
5314
+ * a system reset cycle if someone sends a manual SIGQUIT to a random
5315
+ * backend. (While it might be safe to do _exit(1), since this session
5316
+ * shouldn't have touched shared memory yet, there seems little point in
5317
+ * taking any risks.)
5318
+ */
5319
+ _exit (2 );
5320
+ }
5321
+
5284
5322
/*
5285
5323
* Dummy signal handler
5286
5324
*
@@ -5297,7 +5335,11 @@ dummy_handler(SIGNAL_ARGS)
5297
5335
5298
5336
/*
5299
5337
* Timeout while processing startup packet.
5300
- * As for startup_die(), we clean up and exit(1).
5338
+ * As for process_startup_packet_die(), we clean up and exit(1).
5339
+ *
5340
+ * This is theoretically just as hazardous as in process_startup_packet_die(),
5341
+ * although in practice we're almost certainly waiting for client input,
5342
+ * which greatly reduces the risk.
5301
5343
*/
5302
5344
static void
5303
5345
StartupPacketTimeoutHandler (void )