@@ -410,7 +410,8 @@ static void SIGHUP_handler(SIGNAL_ARGS);
410
410
static void pmdie (SIGNAL_ARGS );
411
411
static void reaper (SIGNAL_ARGS );
412
412
static void sigusr1_handler (SIGNAL_ARGS );
413
- static void startup_die (SIGNAL_ARGS );
413
+ static void process_startup_packet_die (SIGNAL_ARGS );
414
+ static void process_startup_packet_quickdie (SIGNAL_ARGS );
414
415
static void dummy_handler (SIGNAL_ARGS );
415
416
static void StartupPacketTimeoutHandler (void );
416
417
static void CleanupBackend (int pid ,int exitstatus );
@@ -4195,22 +4196,30 @@ BackendInitialize(Port *port)
4195
4196
whereToSendOutput = DestRemote ;/* now safe to ereport to client */
4196
4197
4197
4198
/*
4198
- * We arrange for a simple exit(1) if we receive SIGTERM or SIGQUIT or
4199
- * timeout while trying to collect the startup packet. Otherwise the
4200
- * postmaster cannot shutdown the database FAST or IMMED cleanly if a
4201
- * buggy client fails to send the packet promptly. XXX it follows that
4202
- * the remainder of this function must tolerate losing control at any
4203
- * instant. Likewise, any pg_on_exit_callback registered before or during
4204
- * this function must be prepared to execute at any instant between here
4205
- * and the end of this function. Furthermore, affected callbacks execute
4206
- * partially or not at all when a second exit-inducing signal arrives
4207
- * after proc_exit_prepare() decrements on_proc_exit_index. (Thanks to
4208
- * that mechanic, callbacks need not anticipate more than one call.) This
4209
- * is fragile; it ought to instead follow the norm of handling interrupts
4210
- * at selected, safe opportunities.
4199
+ * We arrange to do proc_exit(1) if we receive SIGTERM or timeout while
4200
+ * trying to collect the startup packet; while SIGQUIT results in
4201
+ * _exit(2). Otherwise the postmaster cannot shutdown the database FAST
4202
+ * or IMMED cleanly if a buggy client fails to send the packet promptly.
4203
+ *
4204
+ * XXX this is pretty dangerous; signal handlers should not call anything
4205
+ * as complex as proc_exit() directly. We minimize the hazard by not
4206
+ * keeping these handlers active for longer than we must. However, it
4207
+ * seems necessary to be able to escape out of DNS lookups as well as the
4208
+ * startup packet reception proper, so we can't narrow the scope further
4209
+ * than is done here.
4210
+ *
4211
+ * XXX it follows that the remainder of this function must tolerate losing
4212
+ * control at any instant. Likewise, any pg_on_exit_callback registered
4213
+ * before or during this function must be prepared to execute at any
4214
+ * instant between here and the end of this function. Furthermore,
4215
+ * affected callbacks execute partially or not at all when a second
4216
+ * exit-inducing signal arrives after proc_exit_prepare() decrements
4217
+ * on_proc_exit_index. (Thanks to that mechanic, callbacks need not
4218
+ * anticipate more than one call.) This is fragile; it ought to instead
4219
+ * follow the norm of handling interrupts at selected, safe opportunities.
4211
4220
*/
4212
- pqsignal (SIGTERM ,startup_die );
4213
- pqsignal (SIGQUIT ,startup_die );
4221
+ pqsignal (SIGTERM ,process_startup_packet_die );
4222
+ pqsignal (SIGQUIT ,process_startup_packet_quickdie );
4214
4223
InitializeTimeouts ();/* establishes SIGALRM handler */
4215
4224
PG_SETMASK (& StartupBlockSig );
4216
4225
@@ -4270,8 +4279,8 @@ BackendInitialize(Port *port)
4270
4279
port -> remote_hostname = strdup (remote_host );
4271
4280
4272
4281
/*
4273
- * Ready to begin client interaction. We will give up andexit (1) after a
4274
- * time delay, so that a broken client can't hog a connection
4282
+ * Ready to begin client interaction. We will give up andproc_exit (1)
4283
+ *after a time delay, so that a broken client can't hog a connection
4275
4284
* indefinitely. PreAuthDelay and any DNS interactions above don't count
4276
4285
* against the time limit.
4277
4286
*
@@ -4293,6 +4302,12 @@ BackendInitialize(Port *port)
4293
4302
*/
4294
4303
status = ProcessStartupPacket (port , false);
4295
4304
4305
+ /*
4306
+ * Disable the timeout, and prevent SIGTERM/SIGQUIT again.
4307
+ */
4308
+ disable_timeout (STARTUP_PACKET_TIMEOUT , false);
4309
+ PG_SETMASK (& BlockSig );
4310
+
4296
4311
/*
4297
4312
* Stop here if it was bad or a cancel packet. ProcessStartupPacket
4298
4313
* already did any appropriate error reporting.
@@ -4318,12 +4333,6 @@ BackendInitialize(Port *port)
4318
4333
else
4319
4334
init_ps_display (port -> user_name ,port -> database_name ,remote_ps_data ,
4320
4335
update_process_title ?"authentication" :"" );
4321
-
4322
- /*
4323
- * Disable the timeout, and prevent SIGTERM/SIGQUIT again.
4324
- */
4325
- disable_timeout (STARTUP_PACKET_TIMEOUT , false);
4326
- PG_SETMASK (& BlockSig );
4327
4336
}
4328
4337
4329
4338
@@ -5198,20 +5207,49 @@ sigusr1_handler(SIGNAL_ARGS)
5198
5207
}
5199
5208
5200
5209
/*
5201
- * SIGTERMor SIGQUIT while processing startup packet.
5210
+ * SIGTERM while processing startup packet.
5202
5211
* Clean up and exit(1).
5203
5212
*
5204
- * XXX: possible future improvement: try to send a message indicating
5205
- * why we are disconnecting. Problem is to be sure we don't block while
5206
- * doing so, nor mess up SSL initialization. In practice, if the client
5207
- * has wedged here, it probably couldn't do anything with the message anyway.
5213
+ * Running proc_exit() from a signal handler is pretty unsafe, since we
5214
+ * can't know what code we've interrupted. But the alternative of using
5215
+ * _exit(2) is also unpalatable, since it'd mean that a "fast shutdown"
5216
+ * would cause a database crash cycle (forcing WAL replay at restart)
5217
+ * if any sessions are in authentication. So we live with it for now.
5218
+ *
5219
+ * One might be tempted to try to send a message indicating why we are
5220
+ * disconnecting. However, that would make this even more unsafe. Also,
5221
+ * it seems undesirable to provide clues about the database's state to
5222
+ * a client that has not yet completed authentication.
5208
5223
*/
5209
5224
static void
5210
- startup_die (SIGNAL_ARGS )
5225
+ process_startup_packet_die (SIGNAL_ARGS )
5211
5226
{
5212
5227
proc_exit (1 );
5213
5228
}
5214
5229
5230
+ /*
5231
+ * SIGQUIT while processing startup packet.
5232
+ *
5233
+ * Some backend has bought the farm,
5234
+ * so we need to stop what we're doing and exit.
5235
+ */
5236
+ static void
5237
+ process_startup_packet_quickdie (SIGNAL_ARGS )
5238
+ {
5239
+ /*
5240
+ * We DO NOT want to run proc_exit() or atexit() callbacks; they wouldn't
5241
+ * be safe to run from a signal handler. Just nail the windows shut and
5242
+ * get out of town.
5243
+ *
5244
+ * Note we do _exit(2) not _exit(1). This is to force the postmaster into
5245
+ * a system reset cycle if someone sends a manual SIGQUIT to a random
5246
+ * backend. (While it might be safe to do _exit(1), since this session
5247
+ * shouldn't have touched shared memory yet, there seems little point in
5248
+ * taking any risks.)
5249
+ */
5250
+ _exit (2 );
5251
+ }
5252
+
5215
5253
/*
5216
5254
* Dummy signal handler
5217
5255
*
@@ -5228,7 +5266,11 @@ dummy_handler(SIGNAL_ARGS)
5228
5266
5229
5267
/*
5230
5268
* Timeout while processing startup packet.
5231
- * As for startup_die(), we clean up and exit(1).
5269
+ * As for process_startup_packet_die(), we clean up and exit(1).
5270
+ *
5271
+ * This is theoretically just as hazardous as in process_startup_packet_die(),
5272
+ * although in practice we're almost certainly waiting for client input,
5273
+ * which greatly reduces the risk.
5232
5274
*/
5233
5275
static void
5234
5276
StartupPacketTimeoutHandler (void )