|
17 | 17 | #include<signal.h>
|
18 | 18 | #include<unistd.h>
|
19 | 19 |
|
| 20 | +#ifdefHAVE_SYS_PRCTL_H |
| 21 | +#include<sys/prctl.h> |
| 22 | +#endif |
| 23 | + |
20 | 24 | #include"miscadmin.h"
|
21 | 25 | #include"postmaster/postmaster.h"
|
22 | 26 | #include"replication/walsender.h"
|
@@ -71,6 +75,35 @@ struct PMSignalData
|
71 | 75 |
|
72 | 76 | NON_EXEC_STATICvolatilePMSignalData*PMSignalState=NULL;
|
73 | 77 |
|
| 78 | +/* |
| 79 | + * Signal handler to be notified if postmaster dies. |
| 80 | + */ |
| 81 | +#ifdefUSE_POSTMASTER_DEATH_SIGNAL |
| 82 | +volatilesig_atomic_tpostmaster_possibly_dead= false; |
| 83 | + |
| 84 | +staticvoid |
| 85 | +postmaster_death_handler(intsigno) |
| 86 | +{ |
| 87 | +postmaster_possibly_dead= true; |
| 88 | +} |
| 89 | + |
| 90 | +/* |
| 91 | + * The available signals depend on the OS. SIGUSR1 and SIGUSR2 are already |
| 92 | + * used for other things, so choose another one. |
| 93 | + * |
| 94 | + * Currently, we assume that we can always find a signal to use. That |
| 95 | + * seems like a reasonable assumption for all platforms that are modern |
| 96 | + * enough to have a parent-death signaling mechanism. |
| 97 | + */ |
| 98 | +#if defined(SIGINFO) |
| 99 | +#definePOSTMASTER_DEATH_SIGNAL SIGINFO |
| 100 | +#elif defined(SIGPWR) |
| 101 | +#definePOSTMASTER_DEATH_SIGNAL SIGPWR |
| 102 | +#else |
| 103 | +#error "cannot find a signal to use for postmaster death" |
| 104 | +#endif |
| 105 | + |
| 106 | +#endif/* USE_POSTMASTER_DEATH_SIGNAL */ |
74 | 107 |
|
75 | 108 | /*
|
76 | 109 | * PMSignalShmemSize
|
@@ -266,28 +299,94 @@ MarkPostmasterChildInactive(void)
|
266 | 299 |
|
267 | 300 |
|
268 | 301 | /*
|
269 |
| - * PostmasterIsAlive - check whether postmaster process is still alive |
| 302 | + * PostmasterIsAliveInternal - check whether postmaster process is still alive |
| 303 | + * |
| 304 | + * This is the slow path of PostmasterIsAlive(), where the caller has already |
| 305 | + * checked 'postmaster_possibly_dead'. (On platforms that don't support |
| 306 | + * a signal for parent death, PostmasterIsAlive() is just an alias for this.) |
270 | 307 | */
|
271 | 308 | bool
|
272 |
| -PostmasterIsAlive(void) |
| 309 | +PostmasterIsAliveInternal(void) |
273 | 310 | {
|
274 |
| -#ifndefWIN32 |
275 |
| -charc; |
276 |
| -ssize_trc; |
| 311 | +#ifdefUSE_POSTMASTER_DEATH_SIGNAL |
| 312 | +/* |
| 313 | + * Reset the flag before checking, so that we don't miss a signal if |
| 314 | + * postmaster dies right after the check. If postmaster was indeed dead, |
| 315 | + * we'll re-arm it before returning to caller. |
| 316 | + */ |
| 317 | +postmaster_possibly_dead= false; |
| 318 | +#endif |
277 | 319 |
|
278 |
| -rc=read(postmaster_alive_fds[POSTMASTER_FD_WATCH],&c,1); |
279 |
| -if (rc<0) |
| 320 | +#ifndefWIN32 |
280 | 321 | {
|
281 |
| -if (errno==EAGAIN||errno==EWOULDBLOCK) |
| 322 | +charc; |
| 323 | +ssize_trc; |
| 324 | + |
| 325 | +rc=read(postmaster_alive_fds[POSTMASTER_FD_WATCH],&c,1); |
| 326 | + |
| 327 | +/* |
| 328 | + * In the usual case, the postmaster is still alive, and there is no |
| 329 | + * data in the pipe. |
| 330 | + */ |
| 331 | +if (rc<0&& (errno==EAGAIN||errno==EWOULDBLOCK)) |
282 | 332 | return true;
|
283 | 333 | else
|
284 |
| -elog(FATAL,"read on postmaster death monitoring pipe failed: %m"); |
| 334 | +{ |
| 335 | +/* |
| 336 | + * Postmaster is dead, or something went wrong with the read() |
| 337 | + * call. |
| 338 | + */ |
| 339 | + |
| 340 | +#ifdefUSE_POSTMASTER_DEATH_SIGNAL |
| 341 | +postmaster_possibly_dead= true; |
| 342 | +#endif |
| 343 | + |
| 344 | +if (rc<0) |
| 345 | +elog(FATAL,"read on postmaster death monitoring pipe failed: %m"); |
| 346 | +elseif (rc>0) |
| 347 | +elog(FATAL,"unexpected data in postmaster death monitoring pipe"); |
| 348 | + |
| 349 | +return false; |
| 350 | +} |
285 | 351 | }
|
286 |
| -elseif (rc>0) |
287 |
| -elog(FATAL,"unexpected data in postmaster death monitoring pipe"); |
288 | 352 |
|
289 |
| -return false; |
290 | 353 | #else/* WIN32 */
|
291 |
| -return (WaitForSingleObject(PostmasterHandle,0)==WAIT_TIMEOUT); |
| 354 | +if (WaitForSingleObject(PostmasterHandle,0)==WAIT_TIMEOUT) |
| 355 | +return true; |
| 356 | +else |
| 357 | +{ |
| 358 | +#ifdefUSE_POSTMASTER_DEATH_SIGNAL |
| 359 | +postmaster_possibly_dead= true; |
| 360 | +#endif |
| 361 | +return false; |
| 362 | +} |
292 | 363 | #endif/* WIN32 */
|
293 | 364 | }
|
| 365 | + |
| 366 | +/* |
| 367 | + * PostmasterDeathSignalInit - request signal on postmaster death if possible |
| 368 | + */ |
| 369 | +void |
| 370 | +PostmasterDeathSignalInit(void) |
| 371 | +{ |
| 372 | +#ifdefUSE_POSTMASTER_DEATH_SIGNAL |
| 373 | +intsignum=POSTMASTER_DEATH_SIGNAL; |
| 374 | + |
| 375 | +/* Register our signal handler. */ |
| 376 | +pqsignal(signum,postmaster_death_handler); |
| 377 | + |
| 378 | +/* Request a signal on parent exit. */ |
| 379 | +#if defined(PR_SET_PDEATHSIG) |
| 380 | +if (prctl(PR_SET_PDEATHSIG,signum)<0) |
| 381 | +elog(ERROR,"could not request parent death signal: %m"); |
| 382 | +#else |
| 383 | +#error "USE_POSTMASTER_DEATH_SIGNAL set, but there is no mechanism to request the signal" |
| 384 | +#endif |
| 385 | + |
| 386 | +/* |
| 387 | + * Just in case the parent was gone already and we missed it, we'd better |
| 388 | + * check the slow way on the first call. |
| 389 | + */ |
| 390 | +postmaster_possibly_dead= true; |
| 391 | +#endif/* USE_POSTMASTER_DEATH_SIGNAL */ |
| 392 | +} |