00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042
00043
00044
00045
00046
00047
00048
00049
00050
00051
00052
00053
00054
00055
00056
00057
00058
00059
00060
00061
00062
00063
00064
00065
00066 #include "postgres.h"
00067
00068 #include <unistd.h>
00069 #include <signal.h>
00070 #include <time.h>
00071 #include <sys/wait.h>
00072 #include <ctype.h>
00073 #include <sys/stat.h>
00074 #include <sys/socket.h>
00075 #include <fcntl.h>
00076 #include <sys/param.h>
00077 #include <netinet/in.h>
00078 #include <arpa/inet.h>
00079 #include <netdb.h>
00080 #include <limits.h>
00081
00082 #ifdef HAVE_SYS_SELECT_H
00083 #include <sys/select.h>
00084 #endif
00085
00086 #ifdef HAVE_GETOPT_H
00087 #include <getopt.h>
00088 #endif
00089
00090 #ifdef USE_BONJOUR
00091 #include <dns_sd.h>
00092 #endif
00093
00094 #include "access/transam.h"
00095 #include "access/xlog.h"
00096 #include "bootstrap/bootstrap.h"
00097 #include "catalog/pg_control.h"
00098 #include "lib/ilist.h"
00099 #include "libpq/auth.h"
00100 #include "libpq/ip.h"
00101 #include "libpq/libpq.h"
00102 #include "libpq/pqsignal.h"
00103 #include "miscadmin.h"
00104 #include "pgstat.h"
00105 #include "postmaster/autovacuum.h"
00106 #include "postmaster/bgworker.h"
00107 #include "postmaster/fork_process.h"
00108 #include "postmaster/pgarch.h"
00109 #include "postmaster/postmaster.h"
00110 #include "postmaster/syslogger.h"
00111 #include "replication/walsender.h"
00112 #include "storage/fd.h"
00113 #include "storage/ipc.h"
00114 #include "storage/pg_shmem.h"
00115 #include "storage/pmsignal.h"
00116 #include "storage/proc.h"
00117 #include "tcop/tcopprot.h"
00118 #include "utils/builtins.h"
00119 #include "utils/datetime.h"
00120 #include "utils/memutils.h"
00121 #include "utils/ps_status.h"
00122 #include "utils/timeout.h"
00123
00124 #ifdef EXEC_BACKEND
00125 #include "storage/spin.h"
00126 #endif
00127
00128
00129
00130
00131
00132
00133
00134 #define BACKEND_TYPE_NORMAL 0x0001
00135 #define BACKEND_TYPE_AUTOVAC 0x0002
00136 #define BACKEND_TYPE_WALSND 0x0004
00137 #define BACKEND_TYPE_BGWORKER 0x0008
00138 #define BACKEND_TYPE_ALL 0x000F
00139
00140 #define BACKEND_TYPE_WORKER (BACKEND_TYPE_AUTOVAC | BACKEND_TYPE_BGWORKER)
00141
00142
00143
00144
00145
00146
00147
00148
00149
00150
00151
00152
00153
00154
00155
00156
00157
00158
00159 typedef struct bkend
00160 {
00161 pid_t pid;
00162 long cancel_key;
00163 int child_slot;
00164
00165
00166
00167
00168
00169
00170 int bkend_type;
00171 bool dead_end;
00172 dlist_node elem;
00173 } Backend;
00174
00175 static dlist_head BackendList = DLIST_STATIC_INIT(BackendList);
00176
00177 #ifdef EXEC_BACKEND
00178 static Backend *ShmemBackendArray;
00179 #endif
00180
00181
00182
00183
00184
00185
00186
00187
00188
00189 typedef struct RegisteredBgWorker
00190 {
00191 BackgroundWorker rw_worker;
00192 Backend *rw_backend;
00193 pid_t rw_pid;
00194 int rw_child_slot;
00195 TimestampTz rw_crashed_at;
00196 #ifdef EXEC_BACKEND
00197 int rw_cookie;
00198 #endif
00199 slist_node rw_lnode;
00200 } RegisteredBgWorker;
00201
00202 static slist_head BackgroundWorkerList = SLIST_STATIC_INIT(BackgroundWorkerList);
00203
00204 BackgroundWorker *MyBgworkerEntry = NULL;
00205
00206
00207
00208
00209 int PostPortNumber;
00210
00211 char *Unix_socket_directories;
00212
00213 char *ListenAddresses;
00214
00215
00216
00217
00218
00219
00220
00221
00222
00223
00224 int ReservedBackends;
00225
00226
00227 #define MAXLISTEN 64
00228 static pgsocket ListenSocket[MAXLISTEN];
00229
00230
00231
00232
00233 static char ExtraOptions[MAXPGPATH];
00234
00235
00236
00237
00238
00239
00240
00241
00242 static bool Reinit = true;
00243 static int SendStop = false;
00244
00245
00246 bool EnableSSL = false;
00247
00248 int PreAuthDelay = 0;
00249 int AuthenticationTimeout = 60;
00250
00251 bool log_hostname;
00252 bool Log_connections = false;
00253 bool Db_user_namespace = false;
00254
00255 bool enable_bonjour = false;
00256 char *bonjour_name;
00257 bool restart_after_crash = true;
00258
00259 char *output_config_variable = NULL;
00260
00261
00262 static pid_t StartupPID = 0,
00263 BgWriterPID = 0,
00264 CheckpointerPID = 0,
00265 WalWriterPID = 0,
00266 WalReceiverPID = 0,
00267 AutoVacPID = 0,
00268 PgArchPID = 0,
00269 PgStatPID = 0,
00270 SysLoggerPID = 0;
00271
00272
00273 #define NoShutdown 0
00274 #define SmartShutdown 1
00275 #define FastShutdown 2
00276
00277 static int Shutdown = NoShutdown;
00278
00279 static bool FatalError = false;
00280 static bool RecoveryError = false;
00281
00282
00283
00284
00285
00286
00287
00288
00289
00290
00291
00292
00293
00294
00295
00296
00297
00298
00299
00300
00301
00302
00303
00304
00305
00306
00307
00308
00309
00310
00311
00312
00313
00314
00315
00316
00317
00318
00319
00320
00321
00322
00323
00324
00325
00326 typedef enum
00327 {
00328 PM_INIT,
00329 PM_STARTUP,
00330 PM_RECOVERY,
00331 PM_HOT_STANDBY,
00332 PM_RUN,
00333 PM_WAIT_BACKUP,
00334 PM_WAIT_READONLY,
00335 PM_WAIT_BACKENDS,
00336 PM_SHUTDOWN,
00337
00338 PM_SHUTDOWN_2,
00339
00340 PM_WAIT_DEAD_END,
00341 PM_NO_CHILDREN
00342 } PMState;
00343
00344 static PMState pmState = PM_INIT;
00345
00346 static bool ReachedNormalRunning = false;
00347
00348 bool ClientAuthInProgress = false;
00349
00350
00351 bool redirection_done = false;
00352
00353
00354 static volatile sig_atomic_t start_autovac_launcher = false;
00355
00356
00357 static volatile bool avlauncher_needs_signal = false;
00358
00359
00360 static volatile bool StartWorkerNeeded = true;
00361 static volatile bool HaveCrashedWorker = false;
00362
00363
00364
00365
00366
00367
00368 static unsigned int random_seed = 0;
00369 static struct timeval random_start_time;
00370
00371 extern char *optarg;
00372 extern int optind,
00373 opterr;
00374
00375 #ifdef HAVE_INT_OPTRESET
00376 extern int optreset;
00377 #endif
00378
00379 #ifdef USE_BONJOUR
00380 static DNSServiceRef bonjour_sdref = NULL;
00381 #endif
00382
00383
00384
00385
00386 static void unlink_external_pid_file(int status, Datum arg);
00387 static void getInstallationPaths(const char *argv0);
00388 static void checkDataDir(void);
00389 static Port *ConnCreate(int serverFd);
00390 static void ConnFree(Port *port);
00391 static void reset_shared(int port);
00392 static void SIGHUP_handler(SIGNAL_ARGS);
00393 static void pmdie(SIGNAL_ARGS);
00394 static void reaper(SIGNAL_ARGS);
00395 static void sigusr1_handler(SIGNAL_ARGS);
00396 static void startup_die(SIGNAL_ARGS);
00397 static void dummy_handler(SIGNAL_ARGS);
00398 static int GetNumRegisteredBackgroundWorkers(int flags);
00399 static void StartupPacketTimeoutHandler(void);
00400 static void CleanupBackend(int pid, int exitstatus);
00401 static bool CleanupBackgroundWorker(int pid, int exitstatus);
00402 static void do_start_bgworker(void);
00403 static void HandleChildCrash(int pid, int exitstatus, const char *procname);
00404 static void LogChildExit(int lev, const char *procname,
00405 int pid, int exitstatus);
00406 static void PostmasterStateMachine(void);
00407 static void BackendInitialize(Port *port);
00408 static void BackendRun(Port *port) __attribute__((noreturn));
00409 static void ExitPostmaster(int status) __attribute__((noreturn));
00410 static int ServerLoop(void);
00411 static int BackendStartup(Port *port);
00412 static int ProcessStartupPacket(Port *port, bool SSLdone);
00413 static void processCancelRequest(Port *port, void *pkt);
00414 static int initMasks(fd_set *rmask);
00415 static void report_fork_failure_to_client(Port *port, int errnum);
00416 static CAC_state canAcceptConnections(void);
00417 static long PostmasterRandom(void);
00418 static void RandomSalt(char *md5Salt);
00419 static void signal_child(pid_t pid, int signal);
00420 static bool SignalSomeChildren(int signal, int targets);
00421 static bool SignalUnconnectedWorkers(int signal);
00422
00423 #define SignalChildren(sig) SignalSomeChildren(sig, BACKEND_TYPE_ALL)
00424
00425 static int CountChildren(int target);
00426 static int CountUnconnectedWorkers(void);
00427 static void StartOneBackgroundWorker(void);
00428 static bool CreateOptsFile(int argc, char *argv[], char *fullprogname);
00429 static pid_t StartChildProcess(AuxProcType type);
00430 static void StartAutovacuumWorker(void);
00431 static void InitPostmasterDeathWatchHandle(void);
00432
00433 #ifdef EXEC_BACKEND
00434
00435 #ifdef WIN32
00436 #define WNOHANG 0
00437
00438 static pid_t waitpid(pid_t pid, int *exitstatus, int options);
00439 static void WINAPI pgwin32_deadchild_callback(PVOID lpParameter, BOOLEAN TimerOrWaitFired);
00440
00441 static HANDLE win32ChildQueue;
00442
00443 typedef struct
00444 {
00445 HANDLE waitHandle;
00446 HANDLE procHandle;
00447 DWORD procId;
00448 } win32_deadchild_waitinfo;
00449 #endif
00450
00451 static pid_t backend_forkexec(Port *port);
00452 static pid_t internal_forkexec(int argc, char *argv[], Port *port);
00453
00454
00455 #ifdef WIN32
00456 typedef struct
00457 {
00458 SOCKET origsocket;
00459
00460 WSAPROTOCOL_INFO wsainfo;
00461 } InheritableSocket;
00462 #else
00463 typedef int InheritableSocket;
00464 #endif
00465
00466 typedef struct LWLock LWLock;
00467
00468
00469
00470
00471 typedef struct
00472 {
00473 Port port;
00474 InheritableSocket portsocket;
00475 char DataDir[MAXPGPATH];
00476 pgsocket ListenSocket[MAXLISTEN];
00477 long MyCancelKey;
00478 int MyPMChildSlot;
00479 #ifndef WIN32
00480 unsigned long UsedShmemSegID;
00481 #else
00482 HANDLE UsedShmemSegID;
00483 #endif
00484 void *UsedShmemSegAddr;
00485 slock_t *ShmemLock;
00486 VariableCache ShmemVariableCache;
00487 Backend *ShmemBackendArray;
00488 LWLock *LWLockArray;
00489 slock_t *ProcStructLock;
00490 PROC_HDR *ProcGlobal;
00491 PGPROC *AuxiliaryProcs;
00492 PGPROC *PreparedXactProcs;
00493 PMSignalData *PMSignalState;
00494 InheritableSocket pgStatSock;
00495 pid_t PostmasterPid;
00496 TimestampTz PgStartTime;
00497 TimestampTz PgReloadTime;
00498 pg_time_t first_syslogger_file_time;
00499 bool redirection_done;
00500 bool IsBinaryUpgrade;
00501 int max_safe_fds;
00502 int MaxBackends;
00503 #ifdef WIN32
00504 HANDLE PostmasterHandle;
00505 HANDLE initial_signal_pipe;
00506 HANDLE syslogPipe[2];
00507 #else
00508 int postmaster_alive_fds[2];
00509 int syslogPipe[2];
00510 #endif
00511 char my_exec_path[MAXPGPATH];
00512 char pkglib_path[MAXPGPATH];
00513 char ExtraOptions[MAXPGPATH];
00514 } BackendParameters;
00515
00516 static void read_backend_variables(char *id, Port *port);
00517 static void restore_backend_variables(BackendParameters *param, Port *port);
00518
00519 #ifndef WIN32
00520 static bool save_backend_variables(BackendParameters *param, Port *port);
00521 #else
00522 static bool save_backend_variables(BackendParameters *param, Port *port,
00523 HANDLE childProcess, pid_t childPid);
00524 #endif
00525
00526 static void ShmemBackendArrayAdd(Backend *bn);
00527 static void ShmemBackendArrayRemove(Backend *bn);
00528
00529 static BackgroundWorker *find_bgworker_entry(int cookie);
00530 #endif
00531
00532 #define StartupDataBase() StartChildProcess(StartupProcess)
00533 #define StartBackgroundWriter() StartChildProcess(BgWriterProcess)
00534 #define StartCheckpointer() StartChildProcess(CheckpointerProcess)
00535 #define StartWalWriter() StartChildProcess(WalWriterProcess)
00536 #define StartWalReceiver() StartChildProcess(WalReceiverProcess)
00537
00538
00539 #define EXIT_STATUS_0(st) ((st) == 0)
00540 #define EXIT_STATUS_1(st) (WIFEXITED(st) && WEXITSTATUS(st) == 1)
00541
00542 #ifndef WIN32
00543
00544
00545
00546
00547 int postmaster_alive_fds[2] = {-1, -1};
00548 #else
00549
00550 HANDLE PostmasterHandle;
00551 #endif
00552
00553
00554
00555
00556 void
00557 PostmasterMain(int argc, char *argv[])
00558 {
00559 int opt;
00560 int status;
00561 char *userDoption = NULL;
00562 bool listen_addr_saved = false;
00563 int i;
00564
00565 MyProcPid = PostmasterPid = getpid();
00566
00567 MyStartTime = time(NULL);
00568
00569 IsPostmasterEnvironment = true;
00570
00571
00572
00573
00574 umask(S_IRWXG | S_IRWXO);
00575
00576
00577
00578
00579 MemoryContextInit();
00580
00581
00582
00583
00584
00585
00586
00587 PostmasterContext = AllocSetContextCreate(TopMemoryContext,
00588 "Postmaster",
00589 ALLOCSET_DEFAULT_MINSIZE,
00590 ALLOCSET_DEFAULT_INITSIZE,
00591 ALLOCSET_DEFAULT_MAXSIZE);
00592 MemoryContextSwitchTo(PostmasterContext);
00593
00594
00595 getInstallationPaths(argv[0]);
00596
00597
00598
00599
00600 InitializeGUCOptions();
00601
00602 opterr = 1;
00603
00604
00605
00606
00607
00608
00609 while ((opt = getopt(argc, argv, "A:B:bc:C:D:d:EeFf:h:ijk:lN:nOo:Pp:r:S:sTt:W:-:")) != -1)
00610 {
00611 switch (opt)
00612 {
00613 case 'A':
00614 SetConfigOption("debug_assertions", optarg, PGC_POSTMASTER, PGC_S_ARGV);
00615 break;
00616
00617 case 'B':
00618 SetConfigOption("shared_buffers", optarg, PGC_POSTMASTER, PGC_S_ARGV);
00619 break;
00620
00621 case 'b':
00622
00623 IsBinaryUpgrade = true;
00624 break;
00625
00626 case 'C':
00627 output_config_variable = strdup(optarg);
00628 break;
00629
00630 case 'D':
00631 userDoption = strdup(optarg);
00632 break;
00633
00634 case 'd':
00635 set_debug_options(atoi(optarg), PGC_POSTMASTER, PGC_S_ARGV);
00636 break;
00637
00638 case 'E':
00639 SetConfigOption("log_statement", "all", PGC_POSTMASTER, PGC_S_ARGV);
00640 break;
00641
00642 case 'e':
00643 SetConfigOption("datestyle", "euro", PGC_POSTMASTER, PGC_S_ARGV);
00644 break;
00645
00646 case 'F':
00647 SetConfigOption("fsync", "false", PGC_POSTMASTER, PGC_S_ARGV);
00648 break;
00649
00650 case 'f':
00651 if (!set_plan_disabling_options(optarg, PGC_POSTMASTER, PGC_S_ARGV))
00652 {
00653 write_stderr("%s: invalid argument for option -f: \"%s\"\n",
00654 progname, optarg);
00655 ExitPostmaster(1);
00656 }
00657 break;
00658
00659 case 'h':
00660 SetConfigOption("listen_addresses", optarg, PGC_POSTMASTER, PGC_S_ARGV);
00661 break;
00662
00663 case 'i':
00664 SetConfigOption("listen_addresses", "*", PGC_POSTMASTER, PGC_S_ARGV);
00665 break;
00666
00667 case 'j':
00668
00669 break;
00670
00671 case 'k':
00672 SetConfigOption("unix_socket_directories", optarg, PGC_POSTMASTER, PGC_S_ARGV);
00673 break;
00674
00675 case 'l':
00676 SetConfigOption("ssl", "true", PGC_POSTMASTER, PGC_S_ARGV);
00677 break;
00678
00679 case 'N':
00680 SetConfigOption("max_connections", optarg, PGC_POSTMASTER, PGC_S_ARGV);
00681 break;
00682
00683 case 'n':
00684
00685 Reinit = false;
00686 break;
00687
00688 case 'O':
00689 SetConfigOption("allow_system_table_mods", "true", PGC_POSTMASTER, PGC_S_ARGV);
00690 break;
00691
00692 case 'o':
00693
00694 snprintf(ExtraOptions + strlen(ExtraOptions),
00695 sizeof(ExtraOptions) - strlen(ExtraOptions),
00696 " %s", optarg);
00697 break;
00698
00699 case 'P':
00700 SetConfigOption("ignore_system_indexes", "true", PGC_POSTMASTER, PGC_S_ARGV);
00701 break;
00702
00703 case 'p':
00704 SetConfigOption("port", optarg, PGC_POSTMASTER, PGC_S_ARGV);
00705 break;
00706
00707 case 'r':
00708
00709 break;
00710
00711 case 'S':
00712 SetConfigOption("work_mem", optarg, PGC_POSTMASTER, PGC_S_ARGV);
00713 break;
00714
00715 case 's':
00716 SetConfigOption("log_statement_stats", "true", PGC_POSTMASTER, PGC_S_ARGV);
00717 break;
00718
00719 case 'T':
00720
00721
00722
00723
00724
00725
00726 SendStop = true;
00727 break;
00728
00729 case 't':
00730 {
00731 const char *tmp = get_stats_option_name(optarg);
00732
00733 if (tmp)
00734 {
00735 SetConfigOption(tmp, "true", PGC_POSTMASTER, PGC_S_ARGV);
00736 }
00737 else
00738 {
00739 write_stderr("%s: invalid argument for option -t: \"%s\"\n",
00740 progname, optarg);
00741 ExitPostmaster(1);
00742 }
00743 break;
00744 }
00745
00746 case 'W':
00747 SetConfigOption("post_auth_delay", optarg, PGC_POSTMASTER, PGC_S_ARGV);
00748 break;
00749
00750 case 'c':
00751 case '-':
00752 {
00753 char *name,
00754 *value;
00755
00756 ParseLongOption(optarg, &name, &value);
00757 if (!value)
00758 {
00759 if (opt == '-')
00760 ereport(ERROR,
00761 (errcode(ERRCODE_SYNTAX_ERROR),
00762 errmsg("--%s requires a value",
00763 optarg)));
00764 else
00765 ereport(ERROR,
00766 (errcode(ERRCODE_SYNTAX_ERROR),
00767 errmsg("-c %s requires a value",
00768 optarg)));
00769 }
00770
00771 SetConfigOption(name, value, PGC_POSTMASTER, PGC_S_ARGV);
00772 free(name);
00773 if (value)
00774 free(value);
00775 break;
00776 }
00777
00778 default:
00779 write_stderr("Try \"%s --help\" for more information.\n",
00780 progname);
00781 ExitPostmaster(1);
00782 }
00783 }
00784
00785
00786
00787
00788 if (optind < argc)
00789 {
00790 write_stderr("%s: invalid argument: \"%s\"\n",
00791 progname, argv[optind]);
00792 write_stderr("Try \"%s --help\" for more information.\n",
00793 progname);
00794 ExitPostmaster(1);
00795 }
00796
00797
00798
00799
00800
00801 if (!SelectConfigFiles(userDoption, progname))
00802 ExitPostmaster(2);
00803
00804 if (output_config_variable != NULL)
00805 {
00806
00807
00808
00809
00810 puts(GetConfigOption(output_config_variable, false, false));
00811 ExitPostmaster(0);
00812 }
00813
00814
00815 checkDataDir();
00816
00817
00818 ChangeToDataDir();
00819
00820
00821
00822
00823 if (ReservedBackends >= MaxConnections)
00824 {
00825 write_stderr("%s: superuser_reserved_connections must be less than max_connections\n", progname);
00826 ExitPostmaster(1);
00827 }
00828 if (max_wal_senders >= MaxConnections)
00829 {
00830 write_stderr("%s: max_wal_senders must be less than max_connections\n", progname);
00831 ExitPostmaster(1);
00832 }
00833 if (XLogArchiveMode && wal_level == WAL_LEVEL_MINIMAL)
00834 ereport(ERROR,
00835 (errmsg("WAL archival (archive_mode=on) requires wal_level \"archive\" or \"hot_standby\"")));
00836 if (max_wal_senders > 0 && wal_level == WAL_LEVEL_MINIMAL)
00837 ereport(ERROR,
00838 (errmsg("WAL streaming (max_wal_senders > 0) requires wal_level \"archive\" or \"hot_standby\"")));
00839
00840
00841
00842
00843
00844 if (!CheckDateTokenTables())
00845 {
00846 write_stderr("%s: invalid datetoken tables, please fix\n", progname);
00847 ExitPostmaster(1);
00848 }
00849
00850
00851
00852
00853
00854 optind = 1;
00855 #ifdef HAVE_INT_OPTRESET
00856 optreset = 1;
00857 #endif
00858
00859
00860 {
00861 extern char **environ;
00862 char **p;
00863
00864 ereport(DEBUG3,
00865 (errmsg_internal("%s: PostmasterMain: initial environment dump:",
00866 progname)));
00867 ereport(DEBUG3,
00868 (errmsg_internal("-----------------------------------------")));
00869 for (p = environ; *p; ++p)
00870 ereport(DEBUG3,
00871 (errmsg_internal("\t%s", *p)));
00872 ereport(DEBUG3,
00873 (errmsg_internal("-----------------------------------------")));
00874 }
00875
00876
00877
00878
00879
00880
00881
00882
00883
00884
00885 CreateDataDirLockFile(true);
00886
00887
00888
00889
00890 #ifdef USE_SSL
00891 if (EnableSSL)
00892 secure_initialize();
00893 #endif
00894
00895
00896
00897
00898 process_shared_preload_libraries();
00899
00900
00901
00902
00903
00904 InitializeMaxBackends();
00905
00906
00907
00908
00909 for (i = 0; i < MAXLISTEN; i++)
00910 ListenSocket[i] = PGINVALID_SOCKET;
00911
00912 if (ListenAddresses)
00913 {
00914 char *rawstring;
00915 List *elemlist;
00916 ListCell *l;
00917 int success = 0;
00918
00919
00920 rawstring = pstrdup(ListenAddresses);
00921
00922
00923 if (!SplitIdentifierString(rawstring, ',', &elemlist))
00924 {
00925
00926 ereport(FATAL,
00927 (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
00928 errmsg("invalid list syntax for \"listen_addresses\"")));
00929 }
00930
00931 foreach(l, elemlist)
00932 {
00933 char *curhost = (char *) lfirst(l);
00934
00935 if (strcmp(curhost, "*") == 0)
00936 status = StreamServerPort(AF_UNSPEC, NULL,
00937 (unsigned short) PostPortNumber,
00938 NULL,
00939 ListenSocket, MAXLISTEN);
00940 else
00941 status = StreamServerPort(AF_UNSPEC, curhost,
00942 (unsigned short) PostPortNumber,
00943 NULL,
00944 ListenSocket, MAXLISTEN);
00945
00946 if (status == STATUS_OK)
00947 {
00948 success++;
00949
00950 if (!listen_addr_saved)
00951 {
00952 AddToDataDirLockFile(LOCK_FILE_LINE_LISTEN_ADDR, curhost);
00953 listen_addr_saved = true;
00954 }
00955 }
00956 else
00957 ereport(WARNING,
00958 (errmsg("could not create listen socket for \"%s\"",
00959 curhost)));
00960 }
00961
00962 if (!success && elemlist != NIL)
00963 ereport(FATAL,
00964 (errmsg("could not create any TCP/IP sockets")));
00965
00966 list_free(elemlist);
00967 pfree(rawstring);
00968 }
00969
00970 #ifdef USE_BONJOUR
00971
00972 if (enable_bonjour && ListenSocket[0] != PGINVALID_SOCKET)
00973 {
00974 DNSServiceErrorType err;
00975
00976
00977
00978
00979
00980
00981
00982 err = DNSServiceRegister(&bonjour_sdref,
00983 0,
00984 0,
00985 bonjour_name,
00986 "_postgresql._tcp.",
00987 NULL,
00988 NULL,
00989 htons(PostPortNumber),
00990 0,
00991 NULL,
00992 NULL,
00993 NULL);
00994 if (err != kDNSServiceErr_NoError)
00995 elog(LOG, "DNSServiceRegister() failed: error code %ld",
00996 (long) err);
00997
00998
00999
01000
01001
01002
01003
01004
01005 }
01006 #endif
01007
01008 #ifdef HAVE_UNIX_SOCKETS
01009 if (Unix_socket_directories)
01010 {
01011 char *rawstring;
01012 List *elemlist;
01013 ListCell *l;
01014 int success = 0;
01015
01016
01017 rawstring = pstrdup(Unix_socket_directories);
01018
01019
01020 if (!SplitDirectoriesString(rawstring, ',', &elemlist))
01021 {
01022
01023 ereport(FATAL,
01024 (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
01025 errmsg("invalid list syntax for \"unix_socket_directories\"")));
01026 }
01027
01028 foreach(l, elemlist)
01029 {
01030 char *socketdir = (char *) lfirst(l);
01031
01032 status = StreamServerPort(AF_UNIX, NULL,
01033 (unsigned short) PostPortNumber,
01034 socketdir,
01035 ListenSocket, MAXLISTEN);
01036
01037 if (status == STATUS_OK)
01038 {
01039 success++;
01040
01041 if (success == 1)
01042 AddToDataDirLockFile(LOCK_FILE_LINE_SOCKET_DIR, socketdir);
01043 }
01044 else
01045 ereport(WARNING,
01046 (errmsg("could not create Unix-domain socket in directory \"%s\"",
01047 socketdir)));
01048 }
01049
01050 if (!success && elemlist != NIL)
01051 ereport(FATAL,
01052 (errmsg("could not create any Unix-domain sockets")));
01053
01054 list_free_deep(elemlist);
01055 pfree(rawstring);
01056 }
01057 #endif
01058
01059
01060
01061
01062 if (ListenSocket[0] == PGINVALID_SOCKET)
01063 ereport(FATAL,
01064 (errmsg("no socket created for listening")));
01065
01066
01067
01068
01069
01070
01071 if (!listen_addr_saved)
01072 AddToDataDirLockFile(LOCK_FILE_LINE_LISTEN_ADDR, "");
01073
01074
01075
01076
01077 reset_shared(PostPortNumber);
01078
01079
01080
01081
01082
01083 set_max_safe_fds();
01084
01085
01086
01087
01088 set_stack_base();
01089
01090
01091
01092
01093
01094 InitPostmasterDeathWatchHandle();
01095
01096 #ifdef WIN32
01097
01098
01099
01100
01101 win32ChildQueue = CreateIoCompletionPort(INVALID_HANDLE_VALUE, NULL, 0, 1);
01102 if (win32ChildQueue == NULL)
01103 ereport(FATAL,
01104 (errmsg("could not create I/O completion port for child queue")));
01105 #endif
01106
01107
01108
01109
01110
01111 if (!CreateOptsFile(argc, argv, my_exec_path))
01112 ExitPostmaster(1);
01113
01114 #ifdef EXEC_BACKEND
01115
01116 write_nondefault_variables(PGC_POSTMASTER);
01117 #endif
01118
01119
01120
01121
01122 if (external_pid_file)
01123 {
01124 FILE *fpidfile = fopen(external_pid_file, "w");
01125
01126 if (fpidfile)
01127 {
01128 fprintf(fpidfile, "%d\n", MyProcPid);
01129 fclose(fpidfile);
01130
01131
01132 if (chmod(external_pid_file, S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH) != 0)
01133 write_stderr("%s: could not change permissions of external PID file \"%s\": %s\n",
01134 progname, external_pid_file, strerror(errno));
01135 }
01136 else
01137 write_stderr("%s: could not write external PID file \"%s\": %s\n",
01138 progname, external_pid_file, strerror(errno));
01139
01140 on_proc_exit(unlink_external_pid_file, 0);
01141 }
01142
01143
01144
01145
01146
01147
01148
01149
01150
01151
01152
01153 pqinitmask();
01154 PG_SETMASK(&BlockSig);
01155
01156 pqsignal(SIGHUP, SIGHUP_handler);
01157
01158 pqsignal(SIGINT, pmdie);
01159 pqsignal(SIGQUIT, pmdie);
01160 pqsignal(SIGTERM, pmdie);
01161 pqsignal(SIGALRM, SIG_IGN);
01162 pqsignal(SIGPIPE, SIG_IGN);
01163 pqsignal(SIGUSR1, sigusr1_handler);
01164 pqsignal(SIGUSR2, dummy_handler);
01165 pqsignal(SIGCHLD, reaper);
01166 pqsignal(SIGTTIN, SIG_IGN);
01167 pqsignal(SIGTTOU, SIG_IGN);
01168
01169 #ifdef SIGXFSZ
01170 pqsignal(SIGXFSZ, SIG_IGN);
01171 #endif
01172
01173
01174
01175
01176 SysLoggerPID = SysLogger_Start();
01177
01178
01179
01180
01181
01182
01183
01184
01185 whereToSendOutput = DestNone;
01186
01187
01188
01189
01190
01191 pgstat_init();
01192
01193
01194
01195
01196 autovac_init();
01197
01198
01199
01200
01201 if (!load_hba())
01202 {
01203
01204
01205
01206
01207 ereport(FATAL,
01208 (errmsg("could not load pg_hba.conf")));
01209 }
01210 if (!load_ident())
01211 {
01212
01213
01214
01215
01216
01217
01218 }
01219
01220
01221
01222
01223
01224
01225 RemovePgTempFiles();
01226
01227
01228
01229
01230 PgStartTime = GetCurrentTimestamp();
01231
01232 gettimeofday(&random_start_time, NULL);
01233
01234
01235
01236
01237 StartupPID = StartupDataBase();
01238 Assert(StartupPID != 0);
01239 pmState = PM_STARTUP;
01240
01241
01242 StartOneBackgroundWorker();
01243
01244 status = ServerLoop();
01245
01246
01247
01248
01249 ExitPostmaster(status != STATUS_OK);
01250
01251 abort();
01252 }
01253
01254
01255
01256
01257
01258 static void
01259 unlink_external_pid_file(int status, Datum arg)
01260 {
01261 if (external_pid_file)
01262 unlink(external_pid_file);
01263 }
01264
01265
01266
01267
01268
01269
01270 static void
01271 getInstallationPaths(const char *argv0)
01272 {
01273 DIR *pdir;
01274
01275
01276 if (find_my_exec(argv0, my_exec_path) < 0)
01277 elog(FATAL, "%s: could not locate my own executable path", argv0);
01278
01279 #ifdef EXEC_BACKEND
01280
01281 if (find_other_exec(argv0, "postgres", PG_BACKEND_VERSIONSTR,
01282 postgres_exec_path) < 0)
01283 ereport(FATAL,
01284 (errmsg("%s: could not locate matching postgres executable",
01285 argv0)));
01286 #endif
01287
01288
01289
01290
01291
01292 get_pkglib_path(my_exec_path, pkglib_path);
01293
01294
01295
01296
01297
01298
01299
01300
01301 pdir = AllocateDir(pkglib_path);
01302 if (pdir == NULL)
01303 ereport(ERROR,
01304 (errcode_for_file_access(),
01305 errmsg("could not open directory \"%s\": %m",
01306 pkglib_path),
01307 errhint("This may indicate an incomplete PostgreSQL installation, or that the file \"%s\" has been moved away from its proper location.",
01308 my_exec_path)));
01309 FreeDir(pdir);
01310
01311
01312
01313
01314
01315 }
01316
01317
01318
01319
01320
01321 static void
01322 checkDataDir(void)
01323 {
01324 char path[MAXPGPATH];
01325 FILE *fp;
01326 struct stat stat_buf;
01327
01328 Assert(DataDir);
01329
01330 if (stat(DataDir, &stat_buf) != 0)
01331 {
01332 if (errno == ENOENT)
01333 ereport(FATAL,
01334 (errcode_for_file_access(),
01335 errmsg("data directory \"%s\" does not exist",
01336 DataDir)));
01337 else
01338 ereport(FATAL,
01339 (errcode_for_file_access(),
01340 errmsg("could not read permissions of directory \"%s\": %m",
01341 DataDir)));
01342 }
01343
01344
01345 if (!S_ISDIR(stat_buf.st_mode))
01346 ereport(FATAL,
01347 (errcode(ERRCODE_OBJECT_NOT_IN_PREREQUISITE_STATE),
01348 errmsg("specified data directory \"%s\" is not a directory",
01349 DataDir)));
01350
01351
01352
01353
01354
01355
01356
01357
01358
01359
01360 #if !defined(WIN32) && !defined(__CYGWIN__)
01361 if (stat_buf.st_uid != geteuid())
01362 ereport(FATAL,
01363 (errcode(ERRCODE_OBJECT_NOT_IN_PREREQUISITE_STATE),
01364 errmsg("data directory \"%s\" has wrong ownership",
01365 DataDir),
01366 errhint("The server must be started by the user that owns the data directory.")));
01367 #endif
01368
01369
01370
01371
01372
01373
01374
01375
01376
01377
01378
01379
01380
01381
01382 #if !defined(WIN32) && !defined(__CYGWIN__)
01383 if (stat_buf.st_mode & (S_IRWXG | S_IRWXO))
01384 ereport(FATAL,
01385 (errcode(ERRCODE_OBJECT_NOT_IN_PREREQUISITE_STATE),
01386 errmsg("data directory \"%s\" has group or world access",
01387 DataDir),
01388 errdetail("Permissions should be u=rwx (0700).")));
01389 #endif
01390
01391
01392 ValidatePgVersion(DataDir);
01393
01394 snprintf(path, sizeof(path), "%s/global/pg_control", DataDir);
01395
01396 fp = AllocateFile(path, PG_BINARY_R);
01397 if (fp == NULL)
01398 {
01399 write_stderr("%s: could not find the database system\n"
01400 "Expected to find it in the directory \"%s\",\n"
01401 "but could not open file \"%s\": %s\n",
01402 progname, DataDir, path, strerror(errno));
01403 ExitPostmaster(2);
01404 }
01405 FreeFile(fp);
01406 }
01407
01408
01409
01410
01411
01412
01413
01414
01415
01416 static void
01417 DetermineSleepTime(struct timeval *timeout)
01418 {
01419 TimestampTz next_wakeup = 0;
01420
01421
01422
01423
01424
01425 if (Shutdown > NoShutdown ||
01426 (!StartWorkerNeeded && !HaveCrashedWorker))
01427 {
01428 timeout->tv_sec = 60;
01429 timeout->tv_usec = 0;
01430 return;
01431 }
01432
01433 if (StartWorkerNeeded)
01434 {
01435 timeout->tv_sec = 0;
01436 timeout->tv_usec = 0;
01437 return;
01438 }
01439
01440 if (HaveCrashedWorker)
01441 {
01442 slist_iter siter;
01443
01444
01445
01446
01447
01448
01449
01450 slist_foreach(siter, &BackgroundWorkerList)
01451 {
01452 RegisteredBgWorker *rw;
01453 TimestampTz this_wakeup;
01454
01455 rw = slist_container(RegisteredBgWorker, rw_lnode, siter.cur);
01456
01457 if (rw->rw_crashed_at == 0)
01458 continue;
01459
01460 if (rw->rw_worker.bgw_restart_time == BGW_NEVER_RESTART)
01461 continue;
01462
01463 this_wakeup = TimestampTzPlusMilliseconds(rw->rw_crashed_at,
01464 1000L * rw->rw_worker.bgw_restart_time);
01465 if (next_wakeup == 0 || this_wakeup < next_wakeup)
01466 next_wakeup = this_wakeup;
01467 }
01468 }
01469
01470 if (next_wakeup != 0)
01471 {
01472 int microsecs;
01473
01474 TimestampDifference(GetCurrentTimestamp(), next_wakeup,
01475 &timeout->tv_sec, µsecs);
01476 timeout->tv_usec = microsecs;
01477
01478
01479 if (timeout->tv_sec > 60)
01480 {
01481 timeout->tv_sec = 60;
01482 timeout->tv_usec = 0;
01483 }
01484 }
01485 else
01486 {
01487 timeout->tv_sec = 60;
01488 timeout->tv_usec = 0;
01489 }
01490 }
01491
01492
01493
01494
01495 static int
01496 ServerLoop(void)
01497 {
01498 fd_set readmask;
01499 int nSockets;
01500 time_t now,
01501 last_touch_time;
01502
01503 last_touch_time = time(NULL);
01504
01505 nSockets = initMasks(&readmask);
01506
01507 for (;;)
01508 {
01509 fd_set rmask;
01510 int selres;
01511
01512
01513
01514
01515
01516
01517
01518
01519 memcpy((char *) &rmask, (char *) &readmask, sizeof(fd_set));
01520
01521 PG_SETMASK(&UnBlockSig);
01522
01523 if (pmState == PM_WAIT_DEAD_END)
01524 {
01525 pg_usleep(100000L);
01526 selres = 0;
01527 }
01528 else
01529 {
01530
01531 struct timeval timeout;
01532
01533 DetermineSleepTime(&timeout);
01534
01535 selres = select(nSockets, &rmask, NULL, NULL, &timeout);
01536 }
01537
01538
01539
01540
01541
01542 PG_SETMASK(&BlockSig);
01543
01544
01545 if (selres < 0)
01546 {
01547 if (errno != EINTR && errno != EWOULDBLOCK)
01548 {
01549 ereport(LOG,
01550 (errcode_for_socket_access(),
01551 errmsg("select() failed in postmaster: %m")));
01552 return STATUS_ERROR;
01553 }
01554 }
01555
01556
01557
01558
01559
01560 if (selres > 0)
01561 {
01562 int i;
01563
01564 for (i = 0; i < MAXLISTEN; i++)
01565 {
01566 if (ListenSocket[i] == PGINVALID_SOCKET)
01567 break;
01568 if (FD_ISSET(ListenSocket[i], &rmask))
01569 {
01570 Port *port;
01571
01572 port = ConnCreate(ListenSocket[i]);
01573 if (port)
01574 {
01575 BackendStartup(port);
01576
01577
01578
01579
01580
01581 StreamClose(port->sock);
01582 ConnFree(port);
01583 }
01584 }
01585 }
01586 }
01587
01588
01589 if (SysLoggerPID == 0 && Logging_collector)
01590 SysLoggerPID = SysLogger_Start();
01591
01592
01593
01594
01595
01596
01597 if (pmState == PM_RUN || pmState == PM_RECOVERY ||
01598 pmState == PM_HOT_STANDBY)
01599 {
01600 if (CheckpointerPID == 0)
01601 CheckpointerPID = StartCheckpointer();
01602 if (BgWriterPID == 0)
01603 BgWriterPID = StartBackgroundWriter();
01604 }
01605
01606
01607
01608
01609
01610
01611 if (WalWriterPID == 0 && pmState == PM_RUN)
01612 WalWriterPID = StartWalWriter();
01613
01614
01615
01616
01617
01618
01619
01620 if (!IsBinaryUpgrade && AutoVacPID == 0 &&
01621 (AutoVacuumingActive() || start_autovac_launcher) &&
01622 pmState == PM_RUN)
01623 {
01624 AutoVacPID = StartAutoVacLauncher();
01625 if (AutoVacPID != 0)
01626 start_autovac_launcher = false;
01627 }
01628
01629
01630 if (XLogArchivingActive() && PgArchPID == 0 && pmState == PM_RUN)
01631 PgArchPID = pgarch_start();
01632
01633
01634 if (PgStatPID == 0 && pmState == PM_RUN)
01635 PgStatPID = pgstat_start();
01636
01637
01638 if (avlauncher_needs_signal)
01639 {
01640 avlauncher_needs_signal = false;
01641 if (AutoVacPID != 0)
01642 kill(AutoVacPID, SIGUSR2);
01643 }
01644
01645
01646 if (StartWorkerNeeded || HaveCrashedWorker)
01647 StartOneBackgroundWorker();
01648
01649
01650
01651
01652
01653
01654 now = time(NULL);
01655 if (now - last_touch_time >= 58 * SECS_PER_MINUTE)
01656 {
01657 TouchSocketFiles();
01658 TouchSocketLockFiles();
01659 last_touch_time = now;
01660 }
01661 }
01662 }
01663
01664
01665
01666
01667
01668 static int
01669 initMasks(fd_set *rmask)
01670 {
01671 int maxsock = -1;
01672 int i;
01673
01674 FD_ZERO(rmask);
01675
01676 for (i = 0; i < MAXLISTEN; i++)
01677 {
01678 int fd = ListenSocket[i];
01679
01680 if (fd == PGINVALID_SOCKET)
01681 break;
01682 FD_SET(fd, rmask);
01683
01684 if (fd > maxsock)
01685 maxsock = fd;
01686 }
01687
01688 return maxsock + 1;
01689 }
01690
01691
01692
01693
01694
01695
01696
01697
01698
01699
01700
01701
01702
01703 static int
01704 ProcessStartupPacket(Port *port, bool SSLdone)
01705 {
01706 int32 len;
01707 void *buf;
01708 ProtocolVersion proto;
01709 MemoryContext oldcontext;
01710
01711 if (pq_getbytes((char *) &len, 4) == EOF)
01712 {
01713
01714
01715
01716
01717
01718 if (!SSLdone)
01719 ereport(COMMERROR,
01720 (errcode(ERRCODE_PROTOCOL_VIOLATION),
01721 errmsg("incomplete startup packet")));
01722 return STATUS_ERROR;
01723 }
01724
01725 len = ntohl(len);
01726 len -= 4;
01727
01728 if (len < (int32) sizeof(ProtocolVersion) ||
01729 len > MAX_STARTUP_PACKET_LENGTH)
01730 {
01731 ereport(COMMERROR,
01732 (errcode(ERRCODE_PROTOCOL_VIOLATION),
01733 errmsg("invalid length of startup packet")));
01734 return STATUS_ERROR;
01735 }
01736
01737
01738
01739
01740
01741
01742
01743 if (len <= (int32) sizeof(StartupPacket))
01744 buf = palloc0(sizeof(StartupPacket) + 1);
01745 else
01746 buf = palloc0(len + 1);
01747
01748 if (pq_getbytes(buf, len) == EOF)
01749 {
01750 ereport(COMMERROR,
01751 (errcode(ERRCODE_PROTOCOL_VIOLATION),
01752 errmsg("incomplete startup packet")));
01753 return STATUS_ERROR;
01754 }
01755
01756
01757
01758
01759
01760 port->proto = proto = ntohl(*((ProtocolVersion *) buf));
01761
01762 if (proto == CANCEL_REQUEST_CODE)
01763 {
01764 processCancelRequest(port, buf);
01765
01766 return STATUS_ERROR;
01767 }
01768
01769 if (proto == NEGOTIATE_SSL_CODE && !SSLdone)
01770 {
01771 char SSLok;
01772
01773 #ifdef USE_SSL
01774
01775 if (!EnableSSL || IS_AF_UNIX(port->laddr.addr.ss_family))
01776 SSLok = 'N';
01777 else
01778 SSLok = 'S';
01779 #else
01780 SSLok = 'N';
01781 #endif
01782
01783 retry1:
01784 if (send(port->sock, &SSLok, 1, 0) != 1)
01785 {
01786 if (errno == EINTR)
01787 goto retry1;
01788 ereport(COMMERROR,
01789 (errcode_for_socket_access(),
01790 errmsg("failed to send SSL negotiation response: %m")));
01791 return STATUS_ERROR;
01792 }
01793
01794 #ifdef USE_SSL
01795 if (SSLok == 'S' && secure_open_server(port) == -1)
01796 return STATUS_ERROR;
01797 #endif
01798
01799
01800 return ProcessStartupPacket(port, true);
01801 }
01802
01803
01804
01805
01806
01807
01808
01809 FrontendProtocol = proto;
01810
01811
01812
01813 if (PG_PROTOCOL_MAJOR(proto) < PG_PROTOCOL_MAJOR(PG_PROTOCOL_EARLIEST) ||
01814 PG_PROTOCOL_MAJOR(proto) > PG_PROTOCOL_MAJOR(PG_PROTOCOL_LATEST) ||
01815 (PG_PROTOCOL_MAJOR(proto) == PG_PROTOCOL_MAJOR(PG_PROTOCOL_LATEST) &&
01816 PG_PROTOCOL_MINOR(proto) > PG_PROTOCOL_MINOR(PG_PROTOCOL_LATEST)))
01817 ereport(FATAL,
01818 (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
01819 errmsg("unsupported frontend protocol %u.%u: server supports %u.0 to %u.%u",
01820 PG_PROTOCOL_MAJOR(proto), PG_PROTOCOL_MINOR(proto),
01821 PG_PROTOCOL_MAJOR(PG_PROTOCOL_EARLIEST),
01822 PG_PROTOCOL_MAJOR(PG_PROTOCOL_LATEST),
01823 PG_PROTOCOL_MINOR(PG_PROTOCOL_LATEST))));
01824
01825
01826
01827
01828
01829
01830
01831
01832
01833 oldcontext = MemoryContextSwitchTo(TopMemoryContext);
01834
01835 if (PG_PROTOCOL_MAJOR(proto) >= 3)
01836 {
01837 int32 offset = sizeof(ProtocolVersion);
01838
01839
01840
01841
01842
01843
01844 port->guc_options = NIL;
01845
01846 while (offset < len)
01847 {
01848 char *nameptr = ((char *) buf) + offset;
01849 int32 valoffset;
01850 char *valptr;
01851
01852 if (*nameptr == '\0')
01853 break;
01854 valoffset = offset + strlen(nameptr) + 1;
01855 if (valoffset >= len)
01856 break;
01857 valptr = ((char *) buf) + valoffset;
01858
01859 if (strcmp(nameptr, "database") == 0)
01860 port->database_name = pstrdup(valptr);
01861 else if (strcmp(nameptr, "user") == 0)
01862 port->user_name = pstrdup(valptr);
01863 else if (strcmp(nameptr, "options") == 0)
01864 port->cmdline_options = pstrdup(valptr);
01865 else if (strcmp(nameptr, "replication") == 0)
01866 {
01867 if (!parse_bool(valptr, &am_walsender))
01868 ereport(FATAL,
01869 (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
01870 errmsg("invalid value for boolean option \"replication\"")));
01871 }
01872 else
01873 {
01874
01875 port->guc_options = lappend(port->guc_options,
01876 pstrdup(nameptr));
01877 port->guc_options = lappend(port->guc_options,
01878 pstrdup(valptr));
01879 }
01880 offset = valoffset + strlen(valptr) + 1;
01881 }
01882
01883
01884
01885
01886
01887 if (offset != len - 1)
01888 ereport(FATAL,
01889 (errcode(ERRCODE_PROTOCOL_VIOLATION),
01890 errmsg("invalid startup packet layout: expected terminator as last byte")));
01891 }
01892 else
01893 {
01894
01895
01896
01897
01898
01899
01900 StartupPacket *packet = (StartupPacket *) buf;
01901
01902 port->database_name = pstrdup(packet->database);
01903 if (strlen(port->database_name) > sizeof(packet->database))
01904 port->database_name[sizeof(packet->database)] = '\0';
01905 port->user_name = pstrdup(packet->user);
01906 if (strlen(port->user_name) > sizeof(packet->user))
01907 port->user_name[sizeof(packet->user)] = '\0';
01908 port->cmdline_options = pstrdup(packet->options);
01909 if (strlen(port->cmdline_options) > sizeof(packet->options))
01910 port->cmdline_options[sizeof(packet->options)] = '\0';
01911 port->guc_options = NIL;
01912 }
01913
01914
01915 if (port->user_name == NULL || port->user_name[0] == '\0')
01916 ereport(FATAL,
01917 (errcode(ERRCODE_INVALID_AUTHORIZATION_SPECIFICATION),
01918 errmsg("no PostgreSQL user name specified in startup packet")));
01919
01920
01921 if (port->database_name == NULL || port->database_name[0] == '\0')
01922 port->database_name = pstrdup(port->user_name);
01923
01924 if (Db_user_namespace)
01925 {
01926
01927
01928
01929
01930
01931
01932 if (strchr(port->user_name, '@') ==
01933 port->user_name + strlen(port->user_name) - 1)
01934 *strchr(port->user_name, '@') = '\0';
01935 else
01936 {
01937
01938 char *db_user;
01939
01940 db_user = palloc(strlen(port->user_name) +
01941 strlen(port->database_name) + 2);
01942 sprintf(db_user, "%s@%s", port->user_name, port->database_name);
01943 port->user_name = db_user;
01944 }
01945 }
01946
01947
01948
01949
01950
01951 if (strlen(port->database_name) >= NAMEDATALEN)
01952 port->database_name[NAMEDATALEN - 1] = '\0';
01953 if (strlen(port->user_name) >= NAMEDATALEN)
01954 port->user_name[NAMEDATALEN - 1] = '\0';
01955
01956
01957 if (am_walsender)
01958 port->database_name[0] = '\0';
01959
01960
01961
01962
01963 MemoryContextSwitchTo(oldcontext);
01964
01965
01966
01967
01968
01969
01970 switch (port->canAcceptConnections)
01971 {
01972 case CAC_STARTUP:
01973 ereport(FATAL,
01974 (errcode(ERRCODE_CANNOT_CONNECT_NOW),
01975 errmsg("the database system is starting up")));
01976 break;
01977 case CAC_SHUTDOWN:
01978 ereport(FATAL,
01979 (errcode(ERRCODE_CANNOT_CONNECT_NOW),
01980 errmsg("the database system is shutting down")));
01981 break;
01982 case CAC_RECOVERY:
01983 ereport(FATAL,
01984 (errcode(ERRCODE_CANNOT_CONNECT_NOW),
01985 errmsg("the database system is in recovery mode")));
01986 break;
01987 case CAC_TOOMANY:
01988 ereport(FATAL,
01989 (errcode(ERRCODE_TOO_MANY_CONNECTIONS),
01990 errmsg("sorry, too many clients already")));
01991 break;
01992 case CAC_WAITBACKUP:
01993
01994 break;
01995 case CAC_OK:
01996 break;
01997 }
01998
01999 return STATUS_OK;
02000 }
02001
02002
02003
02004
02005
02006
02007
02008 static void
02009 processCancelRequest(Port *port, void *pkt)
02010 {
02011 CancelRequestPacket *canc = (CancelRequestPacket *) pkt;
02012 int backendPID;
02013 long cancelAuthCode;
02014 Backend *bp;
02015
02016 #ifndef EXEC_BACKEND
02017 dlist_iter iter;
02018 #else
02019 int i;
02020 #endif
02021
02022 backendPID = (int) ntohl(canc->backendPID);
02023 cancelAuthCode = (long) ntohl(canc->cancelAuthCode);
02024
02025
02026
02027
02028
02029
02030 #ifndef EXEC_BACKEND
02031 dlist_foreach(iter, &BackendList)
02032 {
02033 bp = dlist_container(Backend, elem, iter.cur);
02034 #else
02035 for (i = MaxLivePostmasterChildren() - 1; i >= 0; i--)
02036 {
02037 bp = (Backend *) &ShmemBackendArray[i];
02038 #endif
02039 if (bp->pid == backendPID)
02040 {
02041 if (bp->cancel_key == cancelAuthCode)
02042 {
02043
02044 ereport(DEBUG2,
02045 (errmsg_internal("processing cancel request: sending SIGINT to process %d",
02046 backendPID)));
02047 signal_child(bp->pid, SIGINT);
02048 }
02049 else
02050
02051 ereport(LOG,
02052 (errmsg("wrong key in cancel request for process %d",
02053 backendPID)));
02054 return;
02055 }
02056 }
02057
02058
02059 ereport(LOG,
02060 (errmsg("PID %d in cancel request did not match any process",
02061 backendPID)));
02062 }
02063
02064
02065
02066
02067 static CAC_state
02068 canAcceptConnections(void)
02069 {
02070 CAC_state result = CAC_OK;
02071
02072
02073
02074
02075
02076
02077
02078
02079
02080
02081
02082 if (pmState != PM_RUN)
02083 {
02084 if (pmState == PM_WAIT_BACKUP)
02085 result = CAC_WAITBACKUP;
02086 else if (Shutdown > NoShutdown)
02087 return CAC_SHUTDOWN;
02088 else if (!FatalError &&
02089 (pmState == PM_STARTUP ||
02090 pmState == PM_RECOVERY))
02091 return CAC_STARTUP;
02092 else if (!FatalError &&
02093 pmState == PM_HOT_STANDBY)
02094 result = CAC_OK;
02095 else
02096 return CAC_RECOVERY;
02097 }
02098
02099
02100
02101
02102
02103
02104
02105
02106
02107
02108
02109
02110
02111 if (CountChildren(BACKEND_TYPE_ALL) >= MaxLivePostmasterChildren())
02112 result = CAC_TOOMANY;
02113
02114 return result;
02115 }
02116
02117
02118
02119
02120
02121
02122
02123 static Port *
02124 ConnCreate(int serverFd)
02125 {
02126 Port *port;
02127
02128 if (!(port = (Port *) calloc(1, sizeof(Port))))
02129 {
02130 ereport(LOG,
02131 (errcode(ERRCODE_OUT_OF_MEMORY),
02132 errmsg("out of memory")));
02133 ExitPostmaster(1);
02134 }
02135
02136 if (StreamConnection(serverFd, port) != STATUS_OK)
02137 {
02138 if (port->sock >= 0)
02139 StreamClose(port->sock);
02140 ConnFree(port);
02141 return NULL;
02142 }
02143
02144
02145
02146
02147
02148
02149
02150
02151 RandomSalt(port->md5Salt);
02152
02153
02154
02155
02156 #ifndef EXEC_BACKEND
02157 #if defined(ENABLE_GSS) || defined(ENABLE_SSPI)
02158 port->gss = (pg_gssinfo *) calloc(1, sizeof(pg_gssinfo));
02159 if (!port->gss)
02160 {
02161 ereport(LOG,
02162 (errcode(ERRCODE_OUT_OF_MEMORY),
02163 errmsg("out of memory")));
02164 ExitPostmaster(1);
02165 }
02166 #endif
02167 #endif
02168
02169 return port;
02170 }
02171
02172
02173
02174
02175
02176 static void
02177 ConnFree(Port *conn)
02178 {
02179 #ifdef USE_SSL
02180 secure_close(conn);
02181 #endif
02182 if (conn->gss)
02183 free(conn->gss);
02184 free(conn);
02185 }
02186
02187
02188
02189
02190
02191
02192
02193
02194
02195
02196
02197
02198 void
02199 ClosePostmasterPorts(bool am_syslogger)
02200 {
02201 int i;
02202
02203 #ifndef WIN32
02204
02205
02206
02207
02208
02209
02210 if (close(postmaster_alive_fds[POSTMASTER_FD_OWN]))
02211 ereport(FATAL,
02212 (errcode_for_file_access(),
02213 errmsg_internal("could not close postmaster death monitoring pipe in child process: %m")));
02214 postmaster_alive_fds[POSTMASTER_FD_OWN] = -1;
02215 #endif
02216
02217
02218 for (i = 0; i < MAXLISTEN; i++)
02219 {
02220 if (ListenSocket[i] != PGINVALID_SOCKET)
02221 {
02222 StreamClose(ListenSocket[i]);
02223 ListenSocket[i] = PGINVALID_SOCKET;
02224 }
02225 }
02226
02227
02228 if (!am_syslogger)
02229 {
02230 #ifndef WIN32
02231 if (syslogPipe[0] >= 0)
02232 close(syslogPipe[0]);
02233 syslogPipe[0] = -1;
02234 #else
02235 if (syslogPipe[0])
02236 CloseHandle(syslogPipe[0]);
02237 syslogPipe[0] = 0;
02238 #endif
02239 }
02240
02241 #ifdef USE_BONJOUR
02242
02243 if (bonjour_sdref)
02244 close(DNSServiceRefSockFD(bonjour_sdref));
02245 #endif
02246 }
02247
02248
02249
02250
02251
02252 static void
02253 reset_shared(int port)
02254 {
02255
02256
02257
02258
02259
02260
02261
02262
02263 CreateSharedMemoryAndSemaphores(false, port);
02264 }
02265
02266
02267
02268
02269
02270 static void
02271 SIGHUP_handler(SIGNAL_ARGS)
02272 {
02273 int save_errno = errno;
02274
02275 PG_SETMASK(&BlockSig);
02276
02277 if (Shutdown <= SmartShutdown)
02278 {
02279 ereport(LOG,
02280 (errmsg("received SIGHUP, reloading configuration files")));
02281 ProcessConfigFile(PGC_SIGHUP);
02282 SignalChildren(SIGHUP);
02283 SignalUnconnectedWorkers(SIGHUP);
02284 if (StartupPID != 0)
02285 signal_child(StartupPID, SIGHUP);
02286 if (BgWriterPID != 0)
02287 signal_child(BgWriterPID, SIGHUP);
02288 if (CheckpointerPID != 0)
02289 signal_child(CheckpointerPID, SIGHUP);
02290 if (WalWriterPID != 0)
02291 signal_child(WalWriterPID, SIGHUP);
02292 if (WalReceiverPID != 0)
02293 signal_child(WalReceiverPID, SIGHUP);
02294 if (AutoVacPID != 0)
02295 signal_child(AutoVacPID, SIGHUP);
02296 if (PgArchPID != 0)
02297 signal_child(PgArchPID, SIGHUP);
02298 if (SysLoggerPID != 0)
02299 signal_child(SysLoggerPID, SIGHUP);
02300 if (PgStatPID != 0)
02301 signal_child(PgStatPID, SIGHUP);
02302
02303
02304 if (!load_hba())
02305 ereport(WARNING,
02306 (errmsg("pg_hba.conf not reloaded")));
02307
02308 if (!load_ident())
02309 ereport(WARNING,
02310 (errmsg("pg_ident.conf not reloaded")));
02311
02312 #ifdef EXEC_BACKEND
02313
02314 write_nondefault_variables(PGC_SIGHUP);
02315 #endif
02316 }
02317
02318 PG_SETMASK(&UnBlockSig);
02319
02320 errno = save_errno;
02321 }
02322
02323
02324
02325
02326
02327 static void
02328 pmdie(SIGNAL_ARGS)
02329 {
02330 int save_errno = errno;
02331
02332 PG_SETMASK(&BlockSig);
02333
02334 ereport(DEBUG2,
02335 (errmsg_internal("postmaster received signal %d",
02336 postgres_signal_arg)));
02337
02338 switch (postgres_signal_arg)
02339 {
02340 case SIGTERM:
02341
02342
02343
02344
02345
02346
02347 if (Shutdown >= SmartShutdown)
02348 break;
02349 Shutdown = SmartShutdown;
02350 ereport(LOG,
02351 (errmsg("received smart shutdown request")));
02352
02353 if (pmState == PM_RUN || pmState == PM_RECOVERY ||
02354 pmState == PM_HOT_STANDBY || pmState == PM_STARTUP)
02355 {
02356
02357
02358 SignalSomeChildren(SIGTERM,
02359 BACKEND_TYPE_AUTOVAC | BACKEND_TYPE_BGWORKER);
02360 SignalUnconnectedWorkers(SIGTERM);
02361
02362 if (AutoVacPID != 0)
02363 signal_child(AutoVacPID, SIGTERM);
02364
02365 if (BgWriterPID != 0)
02366 signal_child(BgWriterPID, SIGTERM);
02367
02368 if (WalWriterPID != 0)
02369 signal_child(WalWriterPID, SIGTERM);
02370
02371
02372
02373
02374
02375
02376
02377
02378
02379
02380 pmState = (pmState == PM_RUN) ?
02381 PM_WAIT_BACKUP : PM_WAIT_READONLY;
02382 }
02383
02384
02385
02386
02387
02388
02389 PostmasterStateMachine();
02390 break;
02391
02392 case SIGINT:
02393
02394
02395
02396
02397
02398
02399
02400 if (Shutdown >= FastShutdown)
02401 break;
02402 Shutdown = FastShutdown;
02403 ereport(LOG,
02404 (errmsg("received fast shutdown request")));
02405
02406 if (StartupPID != 0)
02407 signal_child(StartupPID, SIGTERM);
02408 if (BgWriterPID != 0)
02409 signal_child(BgWriterPID, SIGTERM);
02410 if (WalReceiverPID != 0)
02411 signal_child(WalReceiverPID, SIGTERM);
02412 SignalUnconnectedWorkers(SIGTERM);
02413 if (pmState == PM_RECOVERY)
02414 {
02415
02416
02417
02418
02419
02420
02421 pmState = PM_WAIT_BACKENDS;
02422 }
02423 else if (pmState == PM_RUN ||
02424 pmState == PM_WAIT_BACKUP ||
02425 pmState == PM_WAIT_READONLY ||
02426 pmState == PM_WAIT_BACKENDS ||
02427 pmState == PM_HOT_STANDBY)
02428 {
02429 ereport(LOG,
02430 (errmsg("aborting any active transactions")));
02431
02432 SignalSomeChildren(SIGTERM,
02433 BACKEND_TYPE_NORMAL | BACKEND_TYPE_AUTOVAC |
02434 BACKEND_TYPE_BGWORKER);
02435
02436 if (AutoVacPID != 0)
02437 signal_child(AutoVacPID, SIGTERM);
02438
02439 if (WalWriterPID != 0)
02440 signal_child(WalWriterPID, SIGTERM);
02441 pmState = PM_WAIT_BACKENDS;
02442 }
02443
02444
02445
02446
02447
02448 PostmasterStateMachine();
02449 break;
02450
02451 case SIGQUIT:
02452
02453
02454
02455
02456
02457
02458
02459 ereport(LOG,
02460 (errmsg("received immediate shutdown request")));
02461 SignalChildren(SIGQUIT);
02462 if (StartupPID != 0)
02463 signal_child(StartupPID, SIGQUIT);
02464 if (BgWriterPID != 0)
02465 signal_child(BgWriterPID, SIGQUIT);
02466 if (CheckpointerPID != 0)
02467 signal_child(CheckpointerPID, SIGQUIT);
02468 if (WalWriterPID != 0)
02469 signal_child(WalWriterPID, SIGQUIT);
02470 if (WalReceiverPID != 0)
02471 signal_child(WalReceiverPID, SIGQUIT);
02472 if (AutoVacPID != 0)
02473 signal_child(AutoVacPID, SIGQUIT);
02474 if (PgArchPID != 0)
02475 signal_child(PgArchPID, SIGQUIT);
02476 if (PgStatPID != 0)
02477 signal_child(PgStatPID, SIGQUIT);
02478 SignalUnconnectedWorkers(SIGQUIT);
02479 ExitPostmaster(0);
02480 break;
02481 }
02482
02483 PG_SETMASK(&UnBlockSig);
02484
02485 errno = save_errno;
02486 }
02487
02488
02489
02490
02491 static void
02492 reaper(SIGNAL_ARGS)
02493 {
02494 int save_errno = errno;
02495 int pid;
02496 int exitstatus;
02497
02498 PG_SETMASK(&BlockSig);
02499
02500 ereport(DEBUG4,
02501 (errmsg_internal("reaping dead processes")));
02502
02503 while ((pid = waitpid(-1, &exitstatus, WNOHANG)) > 0)
02504 {
02505
02506
02507
02508 if (pid == StartupPID)
02509 {
02510 StartupPID = 0;
02511
02512
02513
02514
02515
02516 if (Shutdown > NoShutdown &&
02517 (EXIT_STATUS_0(exitstatus) || EXIT_STATUS_1(exitstatus)))
02518 {
02519 pmState = PM_WAIT_BACKENDS;
02520
02521 continue;
02522 }
02523
02524
02525
02526
02527
02528
02529 if (pmState == PM_STARTUP && !EXIT_STATUS_0(exitstatus))
02530 {
02531 LogChildExit(LOG, _("startup process"),
02532 pid, exitstatus);
02533 ereport(LOG,
02534 (errmsg("aborting startup due to startup process failure")));
02535 ExitPostmaster(1);
02536 }
02537
02538
02539
02540
02541
02542
02543
02544
02545
02546
02547 if (!EXIT_STATUS_0(exitstatus))
02548 {
02549 if (!FatalError)
02550 RecoveryError = true;
02551 HandleChildCrash(pid, exitstatus,
02552 _("startup process"));
02553 continue;
02554 }
02555
02556
02557
02558
02559 FatalError = false;
02560 ReachedNormalRunning = true;
02561 pmState = PM_RUN;
02562
02563
02564
02565
02566
02567
02568 if (CheckpointerPID == 0)
02569 CheckpointerPID = StartCheckpointer();
02570 if (BgWriterPID == 0)
02571 BgWriterPID = StartBackgroundWriter();
02572 if (WalWriterPID == 0)
02573 WalWriterPID = StartWalWriter();
02574
02575
02576
02577
02578
02579 if (!IsBinaryUpgrade && AutoVacuumingActive() && AutoVacPID == 0)
02580 AutoVacPID = StartAutoVacLauncher();
02581 if (XLogArchivingActive() && PgArchPID == 0)
02582 PgArchPID = pgarch_start();
02583 if (PgStatPID == 0)
02584 PgStatPID = pgstat_start();
02585
02586
02587 StartOneBackgroundWorker();
02588
02589
02590 ereport(LOG,
02591 (errmsg("database system is ready to accept connections")));
02592
02593 continue;
02594 }
02595
02596
02597
02598
02599
02600
02601 if (pid == BgWriterPID)
02602 {
02603 BgWriterPID = 0;
02604 if (!EXIT_STATUS_0(exitstatus))
02605 HandleChildCrash(pid, exitstatus,
02606 _("background writer process"));
02607 continue;
02608 }
02609
02610
02611
02612
02613 if (pid == CheckpointerPID)
02614 {
02615 CheckpointerPID = 0;
02616 if (EXIT_STATUS_0(exitstatus) && pmState == PM_SHUTDOWN)
02617 {
02618
02619
02620
02621
02622
02623
02624
02625
02626
02627
02628
02629
02630
02631
02632 Assert(Shutdown > NoShutdown);
02633
02634
02635 if (PgArchPID != 0)
02636 signal_child(PgArchPID, SIGUSR2);
02637
02638
02639
02640
02641
02642 SignalChildren(SIGUSR2);
02643
02644 pmState = PM_SHUTDOWN_2;
02645
02646
02647
02648
02649
02650 if (PgStatPID != 0)
02651 signal_child(PgStatPID, SIGQUIT);
02652 }
02653 else
02654 {
02655
02656
02657
02658
02659 HandleChildCrash(pid, exitstatus,
02660 _("checkpointer process"));
02661 }
02662
02663 continue;
02664 }
02665
02666
02667
02668
02669
02670
02671 if (pid == WalWriterPID)
02672 {
02673 WalWriterPID = 0;
02674 if (!EXIT_STATUS_0(exitstatus))
02675 HandleChildCrash(pid, exitstatus,
02676 _("WAL writer process"));
02677 continue;
02678 }
02679
02680
02681
02682
02683
02684
02685 if (pid == WalReceiverPID)
02686 {
02687 WalReceiverPID = 0;
02688 if (!EXIT_STATUS_0(exitstatus) && !EXIT_STATUS_1(exitstatus))
02689 HandleChildCrash(pid, exitstatus,
02690 _("WAL receiver process"));
02691 continue;
02692 }
02693
02694
02695
02696
02697
02698
02699
02700 if (pid == AutoVacPID)
02701 {
02702 AutoVacPID = 0;
02703 if (!EXIT_STATUS_0(exitstatus))
02704 HandleChildCrash(pid, exitstatus,
02705 _("autovacuum launcher process"));
02706 continue;
02707 }
02708
02709
02710
02711
02712
02713
02714
02715
02716 if (pid == PgArchPID)
02717 {
02718 PgArchPID = 0;
02719 if (!EXIT_STATUS_0(exitstatus))
02720 LogChildExit(LOG, _("archiver process"),
02721 pid, exitstatus);
02722 if (XLogArchivingActive() && pmState == PM_RUN)
02723 PgArchPID = pgarch_start();
02724 continue;
02725 }
02726
02727
02728
02729
02730
02731
02732 if (pid == PgStatPID)
02733 {
02734 PgStatPID = 0;
02735 if (!EXIT_STATUS_0(exitstatus))
02736 LogChildExit(LOG, _("statistics collector process"),
02737 pid, exitstatus);
02738 if (pmState == PM_RUN)
02739 PgStatPID = pgstat_start();
02740 continue;
02741 }
02742
02743
02744 if (pid == SysLoggerPID)
02745 {
02746 SysLoggerPID = 0;
02747
02748 SysLoggerPID = SysLogger_Start();
02749 if (!EXIT_STATUS_0(exitstatus))
02750 LogChildExit(LOG, _("system logger process"),
02751 pid, exitstatus);
02752 continue;
02753 }
02754
02755
02756 if (CleanupBackgroundWorker(pid, exitstatus))
02757 {
02758
02759 HaveCrashedWorker = true;
02760 continue;
02761 }
02762
02763
02764
02765
02766 CleanupBackend(pid, exitstatus);
02767 }
02768
02769
02770
02771
02772
02773 PostmasterStateMachine();
02774
02775
02776 PG_SETMASK(&UnBlockSig);
02777
02778 errno = save_errno;
02779 }
02780
02781
02782
02783
02784
02785
02786
02787
02788
02789
02790 static bool
02791 CleanupBackgroundWorker(int pid,
02792 int exitstatus)
02793 {
02794 char namebuf[MAXPGPATH];
02795 slist_iter iter;
02796
02797 slist_foreach(iter, &BackgroundWorkerList)
02798 {
02799 RegisteredBgWorker *rw;
02800
02801 rw = slist_container(RegisteredBgWorker, rw_lnode, iter.cur);
02802
02803 if (rw->rw_pid != pid)
02804 continue;
02805
02806 #ifdef WIN32
02807
02808 if (exitstatus == ERROR_WAIT_NO_CHILDREN)
02809 exitstatus = 0;
02810 #endif
02811
02812 snprintf(namebuf, MAXPGPATH, "%s: %s", _("worker process"),
02813 rw->rw_worker.bgw_name);
02814
02815
02816 if (!EXIT_STATUS_0(exitstatus))
02817 rw->rw_crashed_at = GetCurrentTimestamp();
02818 else
02819 rw->rw_crashed_at = 0;
02820
02821
02822
02823
02824
02825
02826 if (rw->rw_worker.bgw_flags & BGWORKER_SHMEM_ACCESS)
02827 {
02828 if (!EXIT_STATUS_0(exitstatus) && !EXIT_STATUS_1(exitstatus))
02829 {
02830 rw->rw_crashed_at = GetCurrentTimestamp();
02831 HandleChildCrash(pid, exitstatus, namebuf);
02832 return true;
02833 }
02834 }
02835
02836 if (!ReleasePostmasterChildSlot(rw->rw_child_slot))
02837 {
02838
02839
02840
02841
02842 rw->rw_crashed_at = GetCurrentTimestamp();
02843 HandleChildCrash(pid, exitstatus, namebuf);
02844 return true;
02845 }
02846
02847
02848 if (rw->rw_backend)
02849 {
02850 Assert(rw->rw_worker.bgw_flags & BGWORKER_BACKEND_DATABASE_CONNECTION);
02851 dlist_delete(&rw->rw_backend->elem);
02852 #ifdef EXEC_BACKEND
02853 ShmemBackendArrayRemove(rw->rw_backend);
02854 #endif
02855 free(rw->rw_backend);
02856 rw->rw_backend = NULL;
02857 }
02858 rw->rw_pid = 0;
02859 rw->rw_child_slot = 0;
02860
02861 LogChildExit(LOG, namebuf, pid, exitstatus);
02862
02863 return true;
02864 }
02865
02866 return false;
02867 }
02868
02869
02870
02871
02872
02873
02874
02875
02876 static void
02877 CleanupBackend(int pid,
02878 int exitstatus)
02879 {
02880 dlist_mutable_iter iter;
02881
02882 LogChildExit(DEBUG2, _("server process"), pid, exitstatus);
02883
02884
02885
02886
02887
02888
02889
02890 #ifdef WIN32
02891
02892
02893
02894
02895
02896
02897
02898
02899 if (exitstatus == ERROR_WAIT_NO_CHILDREN)
02900 {
02901 LogChildExit(LOG, _("server process"), pid, exitstatus);
02902 exitstatus = 0;
02903 }
02904 #endif
02905
02906 if (!EXIT_STATUS_0(exitstatus) && !EXIT_STATUS_1(exitstatus))
02907 {
02908 HandleChildCrash(pid, exitstatus, _("server process"));
02909 return;
02910 }
02911
02912 dlist_foreach_modify(iter, &BackendList)
02913 {
02914 Backend *bp = dlist_container(Backend, elem, iter.cur);
02915
02916 if (bp->pid == pid)
02917 {
02918 if (!bp->dead_end)
02919 {
02920 if (!ReleasePostmasterChildSlot(bp->child_slot))
02921 {
02922
02923
02924
02925
02926 HandleChildCrash(pid, exitstatus, _("server process"));
02927 return;
02928 }
02929 #ifdef EXEC_BACKEND
02930 ShmemBackendArrayRemove(bp);
02931 #endif
02932 }
02933 dlist_delete(iter.cur);
02934 free(bp);
02935 break;
02936 }
02937 }
02938 }
02939
02940
02941
02942
02943
02944
02945
02946
02947 static void
02948 HandleChildCrash(int pid, int exitstatus, const char *procname)
02949 {
02950 dlist_mutable_iter iter;
02951 slist_iter siter;
02952 Backend *bp;
02953
02954
02955
02956
02957
02958 if (!FatalError)
02959 {
02960 LogChildExit(LOG, procname, pid, exitstatus);
02961 ereport(LOG,
02962 (errmsg("terminating any other active server processes")));
02963 }
02964
02965
02966 slist_foreach(siter, &BackgroundWorkerList)
02967 {
02968 RegisteredBgWorker *rw;
02969
02970 rw = slist_container(RegisteredBgWorker, rw_lnode, siter.cur);
02971 if (rw->rw_pid == 0)
02972 continue;
02973 if (rw->rw_pid == pid)
02974 {
02975
02976
02977
02978 (void) ReleasePostmasterChildSlot(rw->rw_child_slot);
02979 if (rw->rw_backend)
02980 {
02981 dlist_delete(&rw->rw_backend->elem);
02982 #ifdef EXEC_BACKEND
02983 ShmemBackendArrayRemove(rw->rw_backend);
02984 #endif
02985 free(rw->rw_backend);
02986 rw->rw_backend = NULL;
02987 }
02988 rw->rw_pid = 0;
02989 rw->rw_child_slot = 0;
02990
02991
02992 }
02993 else
02994 {
02995
02996
02997
02998
02999
03000
03001
03002
03003
03004 if (!FatalError)
03005 {
03006 ereport(DEBUG2,
03007 (errmsg_internal("sending %s to process %d",
03008 (SendStop ? "SIGSTOP" : "SIGQUIT"),
03009 (int) rw->rw_pid)));
03010 signal_child(rw->rw_pid, (SendStop ? SIGSTOP : SIGQUIT));
03011 }
03012 }
03013 }
03014
03015
03016 dlist_foreach_modify(iter, &BackendList)
03017 {
03018 bp = dlist_container(Backend, elem, iter.cur);
03019
03020 if (bp->pid == pid)
03021 {
03022
03023
03024
03025 if (!bp->dead_end)
03026 {
03027 (void) ReleasePostmasterChildSlot(bp->child_slot);
03028 #ifdef EXEC_BACKEND
03029 ShmemBackendArrayRemove(bp);
03030 #endif
03031 }
03032 dlist_delete(iter.cur);
03033 free(bp);
03034
03035 }
03036 else
03037 {
03038
03039
03040
03041
03042
03043
03044
03045
03046
03047
03048
03049
03050
03051
03052
03053 if (bp->bkend_type == BACKEND_TYPE_BGWORKER)
03054 continue;
03055
03056 if (!FatalError)
03057 {
03058 ereport(DEBUG2,
03059 (errmsg_internal("sending %s to process %d",
03060 (SendStop ? "SIGSTOP" : "SIGQUIT"),
03061 (int) bp->pid)));
03062 signal_child(bp->pid, (SendStop ? SIGSTOP : SIGQUIT));
03063 }
03064 }
03065 }
03066
03067
03068 if (pid == StartupPID)
03069 StartupPID = 0;
03070 else if (StartupPID != 0 && !FatalError)
03071 {
03072 ereport(DEBUG2,
03073 (errmsg_internal("sending %s to process %d",
03074 (SendStop ? "SIGSTOP" : "SIGQUIT"),
03075 (int) StartupPID)));
03076 signal_child(StartupPID, (SendStop ? SIGSTOP : SIGQUIT));
03077 }
03078
03079
03080 if (pid == BgWriterPID)
03081 BgWriterPID = 0;
03082 else if (BgWriterPID != 0 && !FatalError)
03083 {
03084 ereport(DEBUG2,
03085 (errmsg_internal("sending %s to process %d",
03086 (SendStop ? "SIGSTOP" : "SIGQUIT"),
03087 (int) BgWriterPID)));
03088 signal_child(BgWriterPID, (SendStop ? SIGSTOP : SIGQUIT));
03089 }
03090
03091
03092 if (pid == CheckpointerPID)
03093 CheckpointerPID = 0;
03094 else if (CheckpointerPID != 0 && !FatalError)
03095 {
03096 ereport(DEBUG2,
03097 (errmsg_internal("sending %s to process %d",
03098 (SendStop ? "SIGSTOP" : "SIGQUIT"),
03099 (int) CheckpointerPID)));
03100 signal_child(CheckpointerPID, (SendStop ? SIGSTOP : SIGQUIT));
03101 }
03102
03103
03104 if (pid == WalWriterPID)
03105 WalWriterPID = 0;
03106 else if (WalWriterPID != 0 && !FatalError)
03107 {
03108 ereport(DEBUG2,
03109 (errmsg_internal("sending %s to process %d",
03110 (SendStop ? "SIGSTOP" : "SIGQUIT"),
03111 (int) WalWriterPID)));
03112 signal_child(WalWriterPID, (SendStop ? SIGSTOP : SIGQUIT));
03113 }
03114
03115
03116 if (pid == WalReceiverPID)
03117 WalReceiverPID = 0;
03118 else if (WalReceiverPID != 0 && !FatalError)
03119 {
03120 ereport(DEBUG2,
03121 (errmsg_internal("sending %s to process %d",
03122 (SendStop ? "SIGSTOP" : "SIGQUIT"),
03123 (int) WalReceiverPID)));
03124 signal_child(WalReceiverPID, (SendStop ? SIGSTOP : SIGQUIT));
03125 }
03126
03127
03128 if (pid == AutoVacPID)
03129 AutoVacPID = 0;
03130 else if (AutoVacPID != 0 && !FatalError)
03131 {
03132 ereport(DEBUG2,
03133 (errmsg_internal("sending %s to process %d",
03134 (SendStop ? "SIGSTOP" : "SIGQUIT"),
03135 (int) AutoVacPID)));
03136 signal_child(AutoVacPID, (SendStop ? SIGSTOP : SIGQUIT));
03137 }
03138
03139
03140
03141
03142
03143
03144
03145 if (PgArchPID != 0 && !FatalError)
03146 {
03147 ereport(DEBUG2,
03148 (errmsg_internal("sending %s to process %d",
03149 "SIGQUIT",
03150 (int) PgArchPID)));
03151 signal_child(PgArchPID, SIGQUIT);
03152 }
03153
03154
03155
03156
03157
03158
03159
03160 if (PgStatPID != 0 && !FatalError)
03161 {
03162 ereport(DEBUG2,
03163 (errmsg_internal("sending %s to process %d",
03164 "SIGQUIT",
03165 (int) PgStatPID)));
03166 signal_child(PgStatPID, SIGQUIT);
03167 allow_immediate_pgstat_restart();
03168 }
03169
03170
03171
03172 FatalError = true;
03173
03174 if (pmState == PM_RECOVERY ||
03175 pmState == PM_HOT_STANDBY ||
03176 pmState == PM_RUN ||
03177 pmState == PM_WAIT_BACKUP ||
03178 pmState == PM_WAIT_READONLY ||
03179 pmState == PM_SHUTDOWN)
03180 pmState = PM_WAIT_BACKENDS;
03181 }
03182
03183
03184
03185
03186 static void
03187 LogChildExit(int lev, const char *procname, int pid, int exitstatus)
03188 {
03189
03190
03191
03192
03193 char activity_buffer[1024];
03194 const char *activity = NULL;
03195
03196 if (!EXIT_STATUS_0(exitstatus))
03197 activity = pgstat_get_crashed_backend_activity(pid,
03198 activity_buffer,
03199 sizeof(activity_buffer));
03200
03201 if (WIFEXITED(exitstatus))
03202 ereport(lev,
03203
03204
03205
03206
03207 (errmsg("%s (PID %d) exited with exit code %d",
03208 procname, pid, WEXITSTATUS(exitstatus)),
03209 activity ? errdetail("Failed process was running: %s", activity) : 0));
03210 else if (WIFSIGNALED(exitstatus))
03211 #if defined(WIN32)
03212 ereport(lev,
03213
03214
03215
03216
03217 (errmsg("%s (PID %d) was terminated by exception 0x%X",
03218 procname, pid, WTERMSIG(exitstatus)),
03219 errhint("See C include file \"ntstatus.h\" for a description of the hexadecimal value."),
03220 activity ? errdetail("Failed process was running: %s", activity) : 0));
03221 #elif defined(HAVE_DECL_SYS_SIGLIST) && HAVE_DECL_SYS_SIGLIST
03222 ereport(lev,
03223
03224
03225
03226
03227 (errmsg("%s (PID %d) was terminated by signal %d: %s",
03228 procname, pid, WTERMSIG(exitstatus),
03229 WTERMSIG(exitstatus) < NSIG ?
03230 sys_siglist[WTERMSIG(exitstatus)] : "(unknown)"),
03231 activity ? errdetail("Failed process was running: %s", activity) : 0));
03232 #else
03233 ereport(lev,
03234
03235
03236
03237
03238 (errmsg("%s (PID %d) was terminated by signal %d",
03239 procname, pid, WTERMSIG(exitstatus)),
03240 activity ? errdetail("Failed process was running: %s", activity) : 0));
03241 #endif
03242 else
03243 ereport(lev,
03244
03245
03246
03247
03248 (errmsg("%s (PID %d) exited with unrecognized status %d",
03249 procname, pid, exitstatus),
03250 activity ? errdetail("Failed process was running: %s", activity) : 0));
03251 }
03252
03253
03254
03255
03256
03257
03258
03259 static void
03260 PostmasterStateMachine(void)
03261 {
03262 if (pmState == PM_WAIT_BACKUP)
03263 {
03264
03265
03266
03267 if (!BackupInProgress())
03268 pmState = PM_WAIT_BACKENDS;
03269 }
03270
03271 if (pmState == PM_WAIT_READONLY)
03272 {
03273
03274
03275
03276
03277
03278
03279
03280
03281 if (CountChildren(BACKEND_TYPE_NORMAL) == 0)
03282 {
03283 if (StartupPID != 0)
03284 signal_child(StartupPID, SIGTERM);
03285 if (WalReceiverPID != 0)
03286 signal_child(WalReceiverPID, SIGTERM);
03287 pmState = PM_WAIT_BACKENDS;
03288 }
03289 }
03290
03291
03292
03293
03294
03295 if (pmState == PM_WAIT_BACKENDS)
03296 {
03297
03298
03299
03300
03301
03302
03303
03304
03305
03306
03307
03308 if (CountChildren(BACKEND_TYPE_NORMAL | BACKEND_TYPE_WORKER) == 0 &&
03309 CountUnconnectedWorkers() == 0 &&
03310 StartupPID == 0 &&
03311 WalReceiverPID == 0 &&
03312 BgWriterPID == 0 &&
03313 (CheckpointerPID == 0 || !FatalError) &&
03314 WalWriterPID == 0 &&
03315 AutoVacPID == 0)
03316 {
03317 if (FatalError)
03318 {
03319
03320
03321
03322
03323 pmState = PM_WAIT_DEAD_END;
03324
03325
03326
03327
03328
03329 }
03330 else
03331 {
03332
03333
03334
03335
03336
03337 Assert(Shutdown > NoShutdown);
03338
03339 if (CheckpointerPID == 0)
03340 CheckpointerPID = StartCheckpointer();
03341
03342 if (CheckpointerPID != 0)
03343 {
03344 signal_child(CheckpointerPID, SIGUSR2);
03345 pmState = PM_SHUTDOWN;
03346 }
03347 else
03348 {
03349
03350
03351
03352
03353
03354
03355 FatalError = true;
03356 pmState = PM_WAIT_DEAD_END;
03357
03358
03359 SignalChildren(SIGQUIT);
03360 if (PgArchPID != 0)
03361 signal_child(PgArchPID, SIGQUIT);
03362 if (PgStatPID != 0)
03363 signal_child(PgStatPID, SIGQUIT);
03364 }
03365 }
03366 }
03367 }
03368
03369 if (pmState == PM_SHUTDOWN_2)
03370 {
03371
03372
03373
03374
03375
03376
03377
03378
03379
03380 if (PgArchPID == 0 && CountChildren(BACKEND_TYPE_ALL) == 0 &&
03381 WalReceiverPID == 0)
03382 {
03383 pmState = PM_WAIT_DEAD_END;
03384 }
03385 }
03386
03387 if (pmState == PM_WAIT_DEAD_END)
03388 {
03389
03390
03391
03392
03393
03394
03395
03396
03397
03398
03399
03400
03401
03402 if (dlist_is_empty(&BackendList) &&
03403 PgArchPID == 0 && PgStatPID == 0)
03404 {
03405
03406 Assert(StartupPID == 0);
03407 Assert(WalReceiverPID == 0);
03408 Assert(BgWriterPID == 0);
03409 Assert(CheckpointerPID == 0);
03410 Assert(WalWriterPID == 0);
03411 Assert(AutoVacPID == 0);
03412
03413 pmState = PM_NO_CHILDREN;
03414 }
03415 }
03416
03417
03418
03419
03420
03421
03422
03423
03424
03425
03426
03427
03428
03429 if (Shutdown > NoShutdown && pmState == PM_NO_CHILDREN)
03430 {
03431 if (FatalError)
03432 {
03433 ereport(LOG, (errmsg("abnormal database system shutdown")));
03434 ExitPostmaster(1);
03435 }
03436 else
03437 {
03438
03439
03440
03441
03442
03443
03444
03445
03446
03447 if (ReachedNormalRunning)
03448 CancelBackup();
03449
03450
03451 ExitPostmaster(0);
03452 }
03453 }
03454
03455
03456
03457
03458
03459
03460
03461
03462 if (pmState == PM_NO_CHILDREN && (RecoveryError || !restart_after_crash))
03463 ExitPostmaster(1);
03464
03465
03466
03467
03468
03469 if (FatalError && pmState == PM_NO_CHILDREN)
03470 {
03471 ereport(LOG,
03472 (errmsg("all server processes terminated; reinitializing")));
03473
03474 shmem_exit(1);
03475 reset_shared(PostPortNumber);
03476
03477 StartupPID = StartupDataBase();
03478 Assert(StartupPID != 0);
03479 pmState = PM_STARTUP;
03480 }
03481 }
03482
03483
03484
03485
03486
03487
03488
03489
03490
03491
03492
03493
03494
03495
03496
03497
03498
03499
03500 static void
03501 signal_child(pid_t pid, int signal)
03502 {
03503 if (kill(pid, signal) < 0)
03504 elog(DEBUG3, "kill(%ld,%d) failed: %m", (long) pid, signal);
03505 #ifdef HAVE_SETSID
03506 switch (signal)
03507 {
03508 case SIGINT:
03509 case SIGTERM:
03510 case SIGQUIT:
03511 case SIGSTOP:
03512 if (kill(-pid, signal) < 0)
03513 elog(DEBUG3, "kill(%ld,%d) failed: %m", (long) (-pid), signal);
03514 break;
03515 default:
03516 break;
03517 }
03518 #endif
03519 }
03520
03521
03522
03523
03524
03525
03526
03527 static bool
03528 SignalUnconnectedWorkers(int signal)
03529 {
03530 slist_iter iter;
03531 bool signaled = false;
03532
03533 slist_foreach(iter, &BackgroundWorkerList)
03534 {
03535 RegisteredBgWorker *rw;
03536
03537 rw = slist_container(RegisteredBgWorker, rw_lnode, iter.cur);
03538
03539 if (rw->rw_pid == 0)
03540 continue;
03541
03542 if (rw->rw_backend != NULL)
03543 continue;
03544
03545 ereport(DEBUG4,
03546 (errmsg_internal("sending signal %d to process %d",
03547 signal, (int) rw->rw_pid)));
03548 signal_child(rw->rw_pid, signal);
03549 signaled = true;
03550 }
03551 return signaled;
03552 }
03553
03554
03555
03556
03557
03558 static bool
03559 SignalSomeChildren(int signal, int target)
03560 {
03561 dlist_iter iter;
03562 bool signaled = false;
03563
03564 dlist_foreach(iter, &BackendList)
03565 {
03566 Backend *bp = dlist_container(Backend, elem, iter.cur);
03567
03568 if (bp->dead_end)
03569 continue;
03570
03571
03572
03573
03574
03575 if (target != BACKEND_TYPE_ALL)
03576 {
03577
03578
03579
03580
03581 if (bp->bkend_type == BACKEND_TYPE_NORMAL &&
03582 IsPostmasterChildWalSender(bp->child_slot))
03583 bp->bkend_type = BACKEND_TYPE_WALSND;
03584
03585 if (!(target & bp->bkend_type))
03586 continue;
03587 }
03588
03589 ereport(DEBUG4,
03590 (errmsg_internal("sending signal %d to process %d",
03591 signal, (int) bp->pid)));
03592 signal_child(bp->pid, signal);
03593 signaled = true;
03594 }
03595 return signaled;
03596 }
03597
03598
03599
03600
03601
03602
03603
03604
03605 static int
03606 BackendStartup(Port *port)
03607 {
03608 Backend *bn;
03609 pid_t pid;
03610
03611
03612
03613
03614
03615 bn = (Backend *) malloc(sizeof(Backend));
03616 if (!bn)
03617 {
03618 ereport(LOG,
03619 (errcode(ERRCODE_OUT_OF_MEMORY),
03620 errmsg("out of memory")));
03621 return STATUS_ERROR;
03622 }
03623
03624
03625
03626
03627
03628
03629 MyCancelKey = PostmasterRandom();
03630 bn->cancel_key = MyCancelKey;
03631
03632
03633 port->canAcceptConnections = canAcceptConnections();
03634 bn->dead_end = (port->canAcceptConnections != CAC_OK &&
03635 port->canAcceptConnections != CAC_WAITBACKUP);
03636
03637
03638
03639
03640 if (!bn->dead_end)
03641 bn->child_slot = MyPMChildSlot = AssignPostmasterChildSlot();
03642 else
03643 bn->child_slot = 0;
03644
03645 #ifdef EXEC_BACKEND
03646 pid = backend_forkexec(port);
03647 #else
03648 pid = fork_process();
03649 if (pid == 0)
03650 {
03651 free(bn);
03652
03653
03654
03655
03656
03657
03658 IsUnderPostmaster = true;
03659
03660 MyProcPid = getpid();
03661
03662 MyStartTime = time(NULL);
03663
03664
03665 on_exit_reset();
03666
03667
03668 ClosePostmasterPorts(false);
03669
03670
03671 BackendInitialize(port);
03672
03673
03674 BackendRun(port);
03675 }
03676 #endif
03677
03678 if (pid < 0)
03679 {
03680
03681 int save_errno = errno;
03682
03683 if (!bn->dead_end)
03684 (void) ReleasePostmasterChildSlot(bn->child_slot);
03685 free(bn);
03686 errno = save_errno;
03687 ereport(LOG,
03688 (errmsg("could not fork new process for connection: %m")));
03689 report_fork_failure_to_client(port, save_errno);
03690 return STATUS_ERROR;
03691 }
03692
03693
03694 ereport(DEBUG2,
03695 (errmsg_internal("forked new backend, pid=%d socket=%d",
03696 (int) pid, (int) port->sock)));
03697
03698
03699
03700
03701
03702 bn->pid = pid;
03703 bn->bkend_type = BACKEND_TYPE_NORMAL;
03704 dlist_push_head(&BackendList, &bn->elem);
03705
03706 #ifdef EXEC_BACKEND
03707 if (!bn->dead_end)
03708 ShmemBackendArrayAdd(bn);
03709 #endif
03710
03711 return STATUS_OK;
03712 }
03713
03714
03715
03716
03717
03718
03719
03720
03721
03722 static void
03723 report_fork_failure_to_client(Port *port, int errnum)
03724 {
03725 char buffer[1000];
03726 int rc;
03727
03728
03729 snprintf(buffer, sizeof(buffer), "E%s%s\n",
03730 _("could not fork new process for connection: "),
03731 strerror(errnum));
03732
03733
03734 if (!pg_set_noblock(port->sock))
03735 return;
03736
03737
03738 do
03739 {
03740 rc = send(port->sock, buffer, strlen(buffer) + 1, 0);
03741 } while (rc < 0 && errno == EINTR);
03742 }
03743
03744
03745
03746
03747
03748
03749
03750
03751
03752
03753
03754
03755 static void
03756 BackendInitialize(Port *port)
03757 {
03758 int status;
03759 int ret;
03760 char remote_host[NI_MAXHOST];
03761 char remote_port[NI_MAXSERV];
03762 char remote_ps_data[NI_MAXHOST];
03763
03764
03765 MyProcPort = port;
03766
03767
03768
03769
03770
03771
03772
03773
03774 if (PreAuthDelay > 0)
03775 pg_usleep(PreAuthDelay * 1000000L);
03776
03777
03778 ClientAuthInProgress = true;
03779
03780
03781 port->SessionStartTime = GetCurrentTimestamp();
03782 MyStartTime = timestamptz_to_time_t(port->SessionStartTime);
03783
03784
03785 port->remote_host = "";
03786 port->remote_port = "";
03787
03788
03789
03790
03791
03792 pq_init();
03793 whereToSendOutput = DestRemote;
03794
03795
03796
03797
03798
03799
03800 #ifdef HAVE_SETSID
03801 if (setsid() < 0)
03802 elog(FATAL, "setsid() failed: %m");
03803 #endif
03804
03805
03806
03807
03808
03809
03810
03811 pqsignal(SIGTERM, startup_die);
03812 pqsignal(SIGQUIT, startup_die);
03813 InitializeTimeouts();
03814 PG_SETMASK(&StartupBlockSig);
03815
03816
03817
03818
03819 remote_host[0] = '\0';
03820 remote_port[0] = '\0';
03821 if ((ret = pg_getnameinfo_all(&port->raddr.addr, port->raddr.salen,
03822 remote_host, sizeof(remote_host),
03823 remote_port, sizeof(remote_port),
03824 (log_hostname ? 0 : NI_NUMERICHOST) | NI_NUMERICSERV)) != 0)
03825 ereport(WARNING,
03826 (errmsg_internal("pg_getnameinfo_all() failed: %s",
03827 gai_strerror(ret))));
03828 if (remote_port[0] == '\0')
03829 snprintf(remote_ps_data, sizeof(remote_ps_data), "%s", remote_host);
03830 else
03831 snprintf(remote_ps_data, sizeof(remote_ps_data), "%s(%s)", remote_host, remote_port);
03832
03833 if (Log_connections)
03834 {
03835 if (remote_port[0])
03836 ereport(LOG,
03837 (errmsg("connection received: host=%s port=%s",
03838 remote_host,
03839 remote_port)));
03840 else
03841 ereport(LOG,
03842 (errmsg("connection received: host=%s",
03843 remote_host)));
03844 }
03845
03846
03847
03848
03849 port->remote_host = strdup(remote_host);
03850 port->remote_port = strdup(remote_port);
03851 if (log_hostname)
03852 port->remote_hostname = port->remote_host;
03853
03854
03855
03856
03857
03858
03859
03860
03861
03862
03863
03864
03865
03866
03867
03868
03869 RegisterTimeout(STARTUP_PACKET_TIMEOUT, StartupPacketTimeoutHandler);
03870 enable_timeout_after(STARTUP_PACKET_TIMEOUT, AuthenticationTimeout * 1000);
03871
03872
03873
03874
03875
03876 status = ProcessStartupPacket(port, false);
03877
03878
03879
03880
03881
03882 if (status != STATUS_OK)
03883 proc_exit(0);
03884
03885
03886
03887
03888
03889
03890
03891
03892
03893
03894
03895
03896
03897 if (am_walsender)
03898 init_ps_display("wal sender process", port->user_name, remote_ps_data,
03899 update_process_title ? "authentication" : "");
03900 else
03901 init_ps_display(port->user_name, port->database_name, remote_ps_data,
03902 update_process_title ? "authentication" : "");
03903
03904
03905
03906
03907 disable_timeout(STARTUP_PACKET_TIMEOUT, false);
03908 PG_SETMASK(&BlockSig);
03909 }
03910
03911
03912
03913
03914
03915
03916
03917
03918
03919 static void
03920 BackendRun(Port *port)
03921 {
03922 char **av;
03923 int maxac;
03924 int ac;
03925 long secs;
03926 int usecs;
03927 int i;
03928
03929
03930
03931
03932
03933
03934 random_seed = 0;
03935 random_start_time.tv_usec = 0;
03936
03937 TimestampDifference(0, port->SessionStartTime, &secs, &usecs);
03938 srandom((unsigned int) (MyProcPid ^ usecs));
03939
03940
03941
03942
03943
03944
03945
03946
03947 maxac = 2;
03948 maxac += (strlen(ExtraOptions) + 1) / 2;
03949
03950 av = (char **) MemoryContextAlloc(TopMemoryContext,
03951 maxac * sizeof(char *));
03952 ac = 0;
03953
03954 av[ac++] = "postgres";
03955
03956
03957
03958
03959
03960
03961 pg_split_opts(av, &ac, ExtraOptions);
03962
03963 av[ac] = NULL;
03964
03965 Assert(ac < maxac);
03966
03967
03968
03969
03970 ereport(DEBUG3,
03971 (errmsg_internal("%s child[%d]: starting with (",
03972 progname, (int) getpid())));
03973 for (i = 0; i < ac; ++i)
03974 ereport(DEBUG3,
03975 (errmsg_internal("\t%s", av[i])));
03976 ereport(DEBUG3,
03977 (errmsg_internal(")")));
03978
03979
03980
03981
03982
03983 MemoryContextSwitchTo(TopMemoryContext);
03984
03985 PostgresMain(ac, av, port->database_name, port->user_name);
03986 }
03987
03988
03989 #ifdef EXEC_BACKEND
03990
03991
03992
03993
03994
03995
03996
03997
03998
03999
04000
04001
04002
04003 pid_t
04004 postmaster_forkexec(int argc, char *argv[])
04005 {
04006 Port port;
04007
04008
04009 memset(&port, 0, sizeof(port));
04010 return internal_forkexec(argc, argv, &port);
04011 }
04012
04013
04014
04015
04016
04017
04018
04019
04020
04021
04022 static pid_t
04023 backend_forkexec(Port *port)
04024 {
04025 char *av[4];
04026 int ac = 0;
04027
04028 av[ac++] = "postgres";
04029 av[ac++] = "--forkbackend";
04030 av[ac++] = NULL;
04031
04032 av[ac] = NULL;
04033 Assert(ac < lengthof(av));
04034
04035 return internal_forkexec(ac, av, port);
04036 }
04037
04038 #ifndef WIN32
04039
04040
04041
04042
04043
04044
04045
04046 static pid_t
04047 internal_forkexec(int argc, char *argv[], Port *port)
04048 {
04049 static unsigned long tmpBackendFileNum = 0;
04050 pid_t pid;
04051 char tmpfilename[MAXPGPATH];
04052 BackendParameters param;
04053 FILE *fp;
04054
04055 if (!save_backend_variables(¶m, port))
04056 return -1;
04057
04058
04059 snprintf(tmpfilename, MAXPGPATH, "%s/%s.backend_var.%d.%lu",
04060 PG_TEMP_FILES_DIR, PG_TEMP_FILE_PREFIX,
04061 MyProcPid, ++tmpBackendFileNum);
04062
04063
04064 fp = AllocateFile(tmpfilename, PG_BINARY_W);
04065 if (!fp)
04066 {
04067
04068
04069
04070
04071 mkdir(PG_TEMP_FILES_DIR, S_IRWXU);
04072
04073 fp = AllocateFile(tmpfilename, PG_BINARY_W);
04074 if (!fp)
04075 {
04076 ereport(LOG,
04077 (errcode_for_file_access(),
04078 errmsg("could not create file \"%s\": %m",
04079 tmpfilename)));
04080 return -1;
04081 }
04082 }
04083
04084 if (fwrite(¶m, sizeof(param), 1, fp) != 1)
04085 {
04086 ereport(LOG,
04087 (errcode_for_file_access(),
04088 errmsg("could not write to file \"%s\": %m", tmpfilename)));
04089 FreeFile(fp);
04090 return -1;
04091 }
04092
04093
04094 if (FreeFile(fp))
04095 {
04096 ereport(LOG,
04097 (errcode_for_file_access(),
04098 errmsg("could not write to file \"%s\": %m", tmpfilename)));
04099 return -1;
04100 }
04101
04102
04103 Assert(argc >= 3);
04104 Assert(argv[argc] == NULL);
04105 Assert(strncmp(argv[1], "--fork", 6) == 0);
04106 Assert(argv[2] == NULL);
04107
04108
04109 argv[2] = tmpfilename;
04110
04111
04112 if ((pid = fork_process()) == 0)
04113 {
04114 if (execv(postgres_exec_path, argv) < 0)
04115 {
04116 ereport(LOG,
04117 (errmsg("could not execute server process \"%s\": %m",
04118 postgres_exec_path)));
04119
04120 exit(1);
04121 }
04122 }
04123
04124 return pid;
04125 }
04126 #else
04127
04128
04129
04130
04131
04132
04133
04134
04135
04136
04137
04138 static pid_t
04139 internal_forkexec(int argc, char *argv[], Port *port)
04140 {
04141 STARTUPINFO si;
04142 PROCESS_INFORMATION pi;
04143 int i;
04144 int j;
04145 char cmdLine[MAXPGPATH * 2];
04146 HANDLE paramHandle;
04147 BackendParameters *param;
04148 SECURITY_ATTRIBUTES sa;
04149 char paramHandleStr[32];
04150 win32_deadchild_waitinfo *childinfo;
04151
04152
04153 Assert(argc >= 3);
04154 Assert(argv[argc] == NULL);
04155 Assert(strncmp(argv[1], "--fork", 6) == 0);
04156 Assert(argv[2] == NULL);
04157
04158
04159 ZeroMemory(&sa, sizeof(sa));
04160 sa.nLength = sizeof(sa);
04161 sa.bInheritHandle = TRUE;
04162 paramHandle = CreateFileMapping(INVALID_HANDLE_VALUE,
04163 &sa,
04164 PAGE_READWRITE,
04165 0,
04166 sizeof(BackendParameters),
04167 NULL);
04168 if (paramHandle == INVALID_HANDLE_VALUE)
04169 {
04170 elog(LOG, "could not create backend parameter file mapping: error code %lu",
04171 GetLastError());
04172 return -1;
04173 }
04174
04175 param = MapViewOfFile(paramHandle, FILE_MAP_WRITE, 0, 0, sizeof(BackendParameters));
04176 if (!param)
04177 {
04178 elog(LOG, "could not map backend parameter memory: error code %lu",
04179 GetLastError());
04180 CloseHandle(paramHandle);
04181 return -1;
04182 }
04183
04184
04185 #ifdef _WIN64
04186 sprintf(paramHandleStr, "%llu", (LONG_PTR) paramHandle);
04187 #else
04188 sprintf(paramHandleStr, "%lu", (DWORD) paramHandle);
04189 #endif
04190 argv[2] = paramHandleStr;
04191
04192
04193 cmdLine[sizeof(cmdLine) - 1] = '\0';
04194 cmdLine[sizeof(cmdLine) - 2] = '\0';
04195 snprintf(cmdLine, sizeof(cmdLine) - 1, "\"%s\"", postgres_exec_path);
04196 i = 0;
04197 while (argv[++i] != NULL)
04198 {
04199 j = strlen(cmdLine);
04200 snprintf(cmdLine + j, sizeof(cmdLine) - 1 - j, " \"%s\"", argv[i]);
04201 }
04202 if (cmdLine[sizeof(cmdLine) - 2] != '\0')
04203 {
04204 elog(LOG, "subprocess command line too long");
04205 return -1;
04206 }
04207
04208 memset(&pi, 0, sizeof(pi));
04209 memset(&si, 0, sizeof(si));
04210 si.cb = sizeof(si);
04211
04212
04213
04214
04215
04216 if (!CreateProcess(NULL, cmdLine, NULL, NULL, TRUE, CREATE_SUSPENDED,
04217 NULL, NULL, &si, &pi))
04218 {
04219 elog(LOG, "CreateProcess call failed: %m (error code %lu)",
04220 GetLastError());
04221 return -1;
04222 }
04223
04224 if (!save_backend_variables(param, port, pi.hProcess, pi.dwProcessId))
04225 {
04226
04227
04228
04229
04230 if (!TerminateProcess(pi.hProcess, 255))
04231 ereport(LOG,
04232 (errmsg_internal("could not terminate unstarted process: error code %lu",
04233 GetLastError())));
04234 CloseHandle(pi.hProcess);
04235 CloseHandle(pi.hThread);
04236 return -1;
04237 }
04238
04239
04240 if (!UnmapViewOfFile(param))
04241 elog(LOG, "could not unmap view of backend parameter file: error code %lu",
04242 GetLastError());
04243 if (!CloseHandle(paramHandle))
04244 elog(LOG, "could not close handle to backend parameter file: error code %lu",
04245 GetLastError());
04246
04247
04248
04249
04250
04251 if (!pgwin32_ReserveSharedMemoryRegion(pi.hProcess))
04252 {
04253
04254
04255
04256
04257 if (!TerminateProcess(pi.hProcess, 255))
04258 ereport(LOG,
04259 (errmsg_internal("could not terminate process that failed to reserve memory: error code %lu",
04260 GetLastError())));
04261 CloseHandle(pi.hProcess);
04262 CloseHandle(pi.hThread);
04263 return -1;
04264
04265 }
04266
04267
04268
04269
04270
04271
04272 if (ResumeThread(pi.hThread) == -1)
04273 {
04274 if (!TerminateProcess(pi.hProcess, 255))
04275 {
04276 ereport(LOG,
04277 (errmsg_internal("could not terminate unstartable process: error code %lu",
04278 GetLastError())));
04279 CloseHandle(pi.hProcess);
04280 CloseHandle(pi.hThread);
04281 return -1;
04282 }
04283 CloseHandle(pi.hProcess);
04284 CloseHandle(pi.hThread);
04285 ereport(LOG,
04286 (errmsg_internal("could not resume thread of unstarted process: error code %lu",
04287 GetLastError())));
04288 return -1;
04289 }
04290
04291
04292
04293
04294
04295
04296
04297
04298
04299 childinfo = malloc(sizeof(win32_deadchild_waitinfo));
04300 if (!childinfo)
04301 ereport(FATAL,
04302 (errcode(ERRCODE_OUT_OF_MEMORY),
04303 errmsg("out of memory")));
04304
04305 childinfo->procHandle = pi.hProcess;
04306 childinfo->procId = pi.dwProcessId;
04307
04308 if (!RegisterWaitForSingleObject(&childinfo->waitHandle,
04309 pi.hProcess,
04310 pgwin32_deadchild_callback,
04311 childinfo,
04312 INFINITE,
04313 WT_EXECUTEONLYONCE | WT_EXECUTEINWAITTHREAD))
04314 ereport(FATAL,
04315 (errmsg_internal("could not register process for wait: error code %lu",
04316 GetLastError())));
04317
04318
04319
04320 CloseHandle(pi.hThread);
04321
04322 return pi.dwProcessId;
04323 }
04324 #endif
04325
04326
04327
04328
04329
04330
04331
04332
04333
04334
04335
04336
04337
04338 void
04339 SubPostmasterMain(int argc, char *argv[])
04340 {
04341 Port port;
04342
04343
04344 IsUnderPostmaster = true;
04345
04346 MyProcPid = getpid();
04347
04348 MyStartTime = time(NULL);
04349
04350
04351
04352
04353
04354
04355
04356 #ifdef WIN32
04357 _setmode(fileno(stderr), _O_BINARY);
04358 #endif
04359
04360
04361 on_exit_reset();
04362
04363
04364 IsPostmasterEnvironment = true;
04365 whereToSendOutput = DestNone;
04366
04367
04368 MemoryContextInit();
04369 InitializeGUCOptions();
04370
04371
04372 memset(&port, 0, sizeof(Port));
04373 read_backend_variables(argv[2], &port);
04374
04375
04376
04377
04378 set_stack_base();
04379
04380
04381
04382
04383
04384 #if defined(ENABLE_GSS) || defined(ENABLE_SSPI)
04385 port.gss = (pg_gssinfo *) calloc(1, sizeof(pg_gssinfo));
04386 if (!port.gss)
04387 ereport(FATAL,
04388 (errcode(ERRCODE_OUT_OF_MEMORY),
04389 errmsg("out of memory")));
04390 #endif
04391
04392
04393 if (argc < 3)
04394 elog(FATAL, "invalid subpostmaster invocation");
04395
04396
04397
04398
04399
04400
04401 if (strcmp(argv[1], "--forkbackend") == 0 ||
04402 strcmp(argv[1], "--forkavlauncher") == 0 ||
04403 strcmp(argv[1], "--forkavworker") == 0 ||
04404 strcmp(argv[1], "--forkboot") == 0 ||
04405 strncmp(argv[1], "--forkbgworker=", 15) == 0)
04406 PGSharedMemoryReAttach();
04407
04408
04409 if (strcmp(argv[1], "--forkavlauncher") == 0)
04410 AutovacuumLauncherIAm();
04411 if (strcmp(argv[1], "--forkavworker") == 0)
04412 AutovacuumWorkerIAm();
04413
04414
04415
04416
04417
04418
04419 #ifdef WIN32
04420 pgwin32_signal_initialize();
04421 #endif
04422
04423
04424 pqinitmask();
04425 PG_SETMASK(&BlockSig);
04426
04427
04428 read_nondefault_variables();
04429
04430
04431
04432
04433
04434
04435
04436 process_shared_preload_libraries();
04437
04438
04439 if (strcmp(argv[1], "--forkbackend") == 0)
04440 {
04441 Assert(argc == 3);
04442
04443
04444 ClosePostmasterPorts(false);
04445
04446
04447
04448
04449
04450
04451
04452
04453
04454 #ifdef USE_SSL
04455 if (EnableSSL)
04456 secure_initialize();
04457 #endif
04458
04459
04460
04461
04462
04463
04464
04465
04466
04467
04468 BackendInitialize(&port);
04469
04470
04471 InitShmemAccess(UsedShmemSegAddr);
04472
04473
04474 InitProcess();
04475
04476
04477
04478
04479
04480
04481
04482
04483
04484
04485
04486
04487 CreateSharedMemoryAndSemaphores(false, 0);
04488
04489
04490 BackendRun(&port);
04491 }
04492 if (strcmp(argv[1], "--forkboot") == 0)
04493 {
04494
04495 ClosePostmasterPorts(false);
04496
04497
04498 InitShmemAccess(UsedShmemSegAddr);
04499
04500
04501 InitAuxiliaryProcess();
04502
04503
04504 CreateSharedMemoryAndSemaphores(false, 0);
04505
04506 AuxiliaryProcessMain(argc - 2, argv + 2);
04507 }
04508 if (strcmp(argv[1], "--forkavlauncher") == 0)
04509 {
04510
04511 ClosePostmasterPorts(false);
04512
04513
04514 InitShmemAccess(UsedShmemSegAddr);
04515
04516
04517 InitProcess();
04518
04519
04520 CreateSharedMemoryAndSemaphores(false, 0);
04521
04522 AutoVacLauncherMain(argc - 2, argv + 2);
04523 }
04524 if (strcmp(argv[1], "--forkavworker") == 0)
04525 {
04526
04527 ClosePostmasterPorts(false);
04528
04529
04530 InitShmemAccess(UsedShmemSegAddr);
04531
04532
04533 InitProcess();
04534
04535
04536 CreateSharedMemoryAndSemaphores(false, 0);
04537
04538 AutoVacWorkerMain(argc - 2, argv + 2);
04539 }
04540 if (strncmp(argv[1], "--forkbgworker=", 15) == 0)
04541 {
04542 int cookie;
04543
04544
04545 ClosePostmasterPorts(false);
04546
04547
04548 InitShmemAccess(UsedShmemSegAddr);
04549
04550
04551 InitProcess();
04552
04553
04554 CreateSharedMemoryAndSemaphores(false, 0);
04555
04556 cookie = atoi(argv[1] + 15);
04557 MyBgworkerEntry = find_bgworker_entry(cookie);
04558 do_start_bgworker();
04559 }
04560 if (strcmp(argv[1], "--forkarch") == 0)
04561 {
04562
04563 ClosePostmasterPorts(false);
04564
04565
04566
04567 PgArchiverMain(argc, argv);
04568 }
04569 if (strcmp(argv[1], "--forkcol") == 0)
04570 {
04571
04572 ClosePostmasterPorts(false);
04573
04574
04575
04576 PgstatCollectorMain(argc, argv);
04577 }
04578 if (strcmp(argv[1], "--forklog") == 0)
04579 {
04580
04581 ClosePostmasterPorts(true);
04582
04583
04584
04585 SysLoggerMain(argc, argv);
04586 }
04587
04588 abort();
04589 }
04590 #endif
04591
04592
04593
04594
04595
04596
04597
04598 static void
04599 ExitPostmaster(int status)
04600 {
04601
04602
04603
04604
04605
04606
04607
04608
04609
04610 proc_exit(status);
04611 }
04612
04613
04614
04615
04616 static void
04617 sigusr1_handler(SIGNAL_ARGS)
04618 {
04619 int save_errno = errno;
04620
04621 PG_SETMASK(&BlockSig);
04622
04623
04624
04625
04626
04627
04628
04629 if (CheckPostmasterSignal(PMSIGNAL_RECOVERY_STARTED) &&
04630 pmState == PM_STARTUP && Shutdown == NoShutdown)
04631 {
04632
04633 FatalError = false;
04634
04635
04636
04637
04638
04639 Assert(CheckpointerPID == 0);
04640 CheckpointerPID = StartCheckpointer();
04641 Assert(BgWriterPID == 0);
04642 BgWriterPID = StartBackgroundWriter();
04643
04644 pmState = PM_RECOVERY;
04645 }
04646 if (CheckPostmasterSignal(PMSIGNAL_BEGIN_HOT_STANDBY) &&
04647 pmState == PM_RECOVERY && Shutdown == NoShutdown)
04648 {
04649
04650
04651
04652 Assert(PgStatPID == 0);
04653 PgStatPID = pgstat_start();
04654
04655 ereport(LOG,
04656 (errmsg("database system is ready to accept read only connections")));
04657
04658 pmState = PM_HOT_STANDBY;
04659
04660
04661 StartOneBackgroundWorker();
04662 }
04663
04664 if (CheckPostmasterSignal(PMSIGNAL_WAKEN_ARCHIVER) &&
04665 PgArchPID != 0)
04666 {
04667
04668
04669
04670
04671 signal_child(PgArchPID, SIGUSR1);
04672 }
04673
04674 if (CheckPostmasterSignal(PMSIGNAL_ROTATE_LOGFILE) &&
04675 SysLoggerPID != 0)
04676 {
04677
04678 signal_child(SysLoggerPID, SIGUSR1);
04679 }
04680
04681 if (CheckPostmasterSignal(PMSIGNAL_START_AUTOVAC_LAUNCHER) &&
04682 Shutdown == NoShutdown)
04683 {
04684
04685
04686
04687
04688
04689
04690
04691
04692
04693 start_autovac_launcher = true;
04694 }
04695
04696 if (CheckPostmasterSignal(PMSIGNAL_START_AUTOVAC_WORKER) &&
04697 Shutdown == NoShutdown)
04698 {
04699
04700 StartAutovacuumWorker();
04701 }
04702
04703 if (CheckPostmasterSignal(PMSIGNAL_START_WALRECEIVER) &&
04704 WalReceiverPID == 0 &&
04705 (pmState == PM_STARTUP || pmState == PM_RECOVERY ||
04706 pmState == PM_HOT_STANDBY || pmState == PM_WAIT_READONLY) &&
04707 Shutdown == NoShutdown)
04708 {
04709
04710 WalReceiverPID = StartWalReceiver();
04711 }
04712
04713 if (CheckPostmasterSignal(PMSIGNAL_ADVANCE_STATE_MACHINE) &&
04714 (pmState == PM_WAIT_BACKUP || pmState == PM_WAIT_BACKENDS))
04715 {
04716
04717 PostmasterStateMachine();
04718 }
04719
04720 if (CheckPromoteSignal() && StartupPID != 0 &&
04721 (pmState == PM_STARTUP || pmState == PM_RECOVERY ||
04722 pmState == PM_HOT_STANDBY || pmState == PM_WAIT_READONLY))
04723 {
04724
04725 signal_child(StartupPID, SIGUSR2);
04726 }
04727
04728 PG_SETMASK(&UnBlockSig);
04729
04730 errno = save_errno;
04731 }
04732
04733
04734
04735
04736
04737
04738
04739
04740
04741
04742 static void
04743 startup_die(SIGNAL_ARGS)
04744 {
04745 proc_exit(1);
04746 }
04747
04748
04749
04750
04751
04752
04753
04754
04755
04756
04757 static void
04758 dummy_handler(SIGNAL_ARGS)
04759 {
04760 }
04761
04762
04763
04764
04765
04766 static void
04767 StartupPacketTimeoutHandler(void)
04768 {
04769 proc_exit(1);
04770 }
04771
04772
04773
04774
04775
04776 static void
04777 RandomSalt(char *md5Salt)
04778 {
04779 long rand;
04780
04781
04782
04783
04784
04785
04786 rand = PostmasterRandom();
04787 md5Salt[0] = (rand % 255) + 1;
04788 rand = PostmasterRandom();
04789 md5Salt[1] = (rand % 255) + 1;
04790 rand = PostmasterRandom();
04791 md5Salt[2] = (rand % 255) + 1;
04792 rand = PostmasterRandom();
04793 md5Salt[3] = (rand % 255) + 1;
04794 }
04795
04796
04797
04798
04799 static long
04800 PostmasterRandom(void)
04801 {
04802
04803
04804
04805 if (random_seed == 0)
04806 {
04807 do
04808 {
04809 struct timeval random_stop_time;
04810
04811 gettimeofday(&random_stop_time, NULL);
04812
04813
04814
04815
04816
04817
04818
04819 random_seed = random_start_time.tv_usec ^
04820 ((random_stop_time.tv_usec << 16) |
04821 ((random_stop_time.tv_usec >> 16) & 0xffff));
04822 }
04823 while (random_seed == 0);
04824
04825 srandom(random_seed);
04826 }
04827
04828 return random();
04829 }
04830
04831
04832
04833
04834
04835 static int
04836 CountUnconnectedWorkers(void)
04837 {
04838 slist_iter iter;
04839 int cnt = 0;
04840
04841 slist_foreach(iter, &BackgroundWorkerList)
04842 {
04843 RegisteredBgWorker *rw;
04844
04845 rw = slist_container(RegisteredBgWorker, rw_lnode, iter.cur);
04846
04847 if (rw->rw_pid == 0)
04848 continue;
04849
04850 if (rw->rw_backend != NULL)
04851 continue;
04852
04853 cnt++;
04854 }
04855 return cnt;
04856 }
04857
04858
04859
04860
04861
04862 static int
04863 CountChildren(int target)
04864 {
04865 dlist_iter iter;
04866 int cnt = 0;
04867
04868 dlist_foreach(iter, &BackendList)
04869 {
04870 Backend *bp = dlist_container(Backend, elem, iter.cur);
04871
04872 if (bp->dead_end)
04873 continue;
04874
04875
04876
04877
04878
04879 if (target != BACKEND_TYPE_ALL)
04880 {
04881
04882
04883
04884
04885 if (bp->bkend_type == BACKEND_TYPE_NORMAL &&
04886 IsPostmasterChildWalSender(bp->child_slot))
04887 bp->bkend_type = BACKEND_TYPE_WALSND;
04888
04889 if (!(target & bp->bkend_type))
04890 continue;
04891 }
04892
04893 cnt++;
04894 }
04895 return cnt;
04896 }
04897
04898
04899
04900
04901
04902
04903
04904
04905
04906
04907
04908 static pid_t
04909 StartChildProcess(AuxProcType type)
04910 {
04911 pid_t pid;
04912 char *av[10];
04913 int ac = 0;
04914 char typebuf[32];
04915
04916
04917
04918
04919 av[ac++] = "postgres";
04920
04921 #ifdef EXEC_BACKEND
04922 av[ac++] = "--forkboot";
04923 av[ac++] = NULL;
04924 #endif
04925
04926 snprintf(typebuf, sizeof(typebuf), "-x%d", type);
04927 av[ac++] = typebuf;
04928
04929 av[ac] = NULL;
04930 Assert(ac < lengthof(av));
04931
04932 #ifdef EXEC_BACKEND
04933 pid = postmaster_forkexec(ac, av);
04934 #else
04935 pid = fork_process();
04936
04937 if (pid == 0)
04938 {
04939 IsUnderPostmaster = true;
04940
04941
04942 ClosePostmasterPorts(false);
04943
04944
04945 on_exit_reset();
04946
04947
04948 MemoryContextSwitchTo(TopMemoryContext);
04949 MemoryContextDelete(PostmasterContext);
04950 PostmasterContext = NULL;
04951
04952 AuxiliaryProcessMain(ac, av);
04953 ExitPostmaster(0);
04954 }
04955 #endif
04956
04957 if (pid < 0)
04958 {
04959
04960 int save_errno = errno;
04961
04962 errno = save_errno;
04963 switch (type)
04964 {
04965 case StartupProcess:
04966 ereport(LOG,
04967 (errmsg("could not fork startup process: %m")));
04968 break;
04969 case BgWriterProcess:
04970 ereport(LOG,
04971 (errmsg("could not fork background writer process: %m")));
04972 break;
04973 case CheckpointerProcess:
04974 ereport(LOG,
04975 (errmsg("could not fork checkpointer process: %m")));
04976 break;
04977 case WalWriterProcess:
04978 ereport(LOG,
04979 (errmsg("could not fork WAL writer process: %m")));
04980 break;
04981 case WalReceiverProcess:
04982 ereport(LOG,
04983 (errmsg("could not fork WAL receiver process: %m")));
04984 break;
04985 default:
04986 ereport(LOG,
04987 (errmsg("could not fork process: %m")));
04988 break;
04989 }
04990
04991
04992
04993
04994
04995 if (type == StartupProcess)
04996 ExitPostmaster(1);
04997 return 0;
04998 }
04999
05000
05001
05002
05003 return pid;
05004 }
05005
05006
05007
05008
05009
05010
05011
05012
05013
05014
05015 static void
05016 StartAutovacuumWorker(void)
05017 {
05018 Backend *bn;
05019
05020
05021
05022
05023
05024
05025
05026
05027 if (canAcceptConnections() == CAC_OK)
05028 {
05029 bn = (Backend *) malloc(sizeof(Backend));
05030 if (bn)
05031 {
05032
05033
05034
05035
05036
05037
05038 MyCancelKey = PostmasterRandom();
05039 bn->cancel_key = MyCancelKey;
05040
05041
05042 bn->dead_end = false;
05043 bn->child_slot = MyPMChildSlot = AssignPostmasterChildSlot();
05044
05045 bn->pid = StartAutoVacWorker();
05046 if (bn->pid > 0)
05047 {
05048 bn->bkend_type = BACKEND_TYPE_AUTOVAC;
05049 dlist_push_head(&BackendList, &bn->elem);
05050 #ifdef EXEC_BACKEND
05051 ShmemBackendArrayAdd(bn);
05052 #endif
05053
05054 return;
05055 }
05056
05057
05058
05059
05060
05061 (void) ReleasePostmasterChildSlot(bn->child_slot);
05062 free(bn);
05063 }
05064 else
05065 ereport(LOG,
05066 (errcode(ERRCODE_OUT_OF_MEMORY),
05067 errmsg("out of memory")));
05068 }
05069
05070
05071
05072
05073
05074
05075
05076
05077
05078
05079 if (AutoVacPID != 0)
05080 {
05081 AutoVacWorkerFailed();
05082 avlauncher_needs_signal = true;
05083 }
05084 }
05085
05086
05087
05088
05089 static bool
05090 CreateOptsFile(int argc, char *argv[], char *fullprogname)
05091 {
05092 FILE *fp;
05093 int i;
05094
05095 #define OPTS_FILE "postmaster.opts"
05096
05097 if ((fp = fopen(OPTS_FILE, "w")) == NULL)
05098 {
05099 elog(LOG, "could not create file \"%s\": %m", OPTS_FILE);
05100 return false;
05101 }
05102
05103 fprintf(fp, "%s", fullprogname);
05104 for (i = 1; i < argc; i++)
05105 fprintf(fp, " \"%s\"", argv[i]);
05106 fputs("\n", fp);
05107
05108 if (fclose(fp))
05109 {
05110 elog(LOG, "could not write file \"%s\": %m", OPTS_FILE);
05111 return false;
05112 }
05113
05114 return true;
05115 }
05116
05117
05118
05119
05120
05121
05122
05123
05124
05125
05126
05127
05128
05129 int
05130 MaxLivePostmasterChildren(void)
05131 {
05132 return 2 * (MaxConnections + autovacuum_max_workers + 1 +
05133 GetNumRegisteredBackgroundWorkers(0));
05134 }
05135
05136
05137
05138
05139
05140
05141
05142 void
05143 RegisterBackgroundWorker(BackgroundWorker *worker)
05144 {
05145 RegisteredBgWorker *rw;
05146 int namelen = strlen(worker->bgw_name);
05147 static int maxworkers;
05148 static int numworkers = 0;
05149
05150 #ifdef EXEC_BACKEND
05151
05152
05153
05154
05155
05156 static int BackgroundWorkerCookie = 1;
05157 #endif
05158
05159
05160 if (numworkers == 0)
05161 maxworkers = MAX_BACKENDS -
05162 (MaxConnections + autovacuum_max_workers + 1);
05163
05164 if (!IsUnderPostmaster)
05165 ereport(LOG,
05166 (errmsg("registering background worker: %s", worker->bgw_name)));
05167
05168 if (!process_shared_preload_libraries_in_progress)
05169 {
05170 if (!IsUnderPostmaster)
05171 ereport(LOG,
05172 (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
05173 errmsg("background worker \"%s\": must be registered in shared_preload_libraries",
05174 worker->bgw_name)));
05175 return;
05176 }
05177
05178
05179 if (worker->bgw_flags & BGWORKER_BACKEND_DATABASE_CONNECTION)
05180 {
05181 if (!(worker->bgw_flags & BGWORKER_SHMEM_ACCESS))
05182 {
05183 if (!IsUnderPostmaster)
05184 ereport(LOG,
05185 (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
05186 errmsg("background worker \"%s\": must attach to shared memory in order to request a database connection",
05187 worker->bgw_name)));
05188 return;
05189 }
05190
05191 if (worker->bgw_start_time == BgWorkerStart_PostmasterStart)
05192 {
05193 if (!IsUnderPostmaster)
05194 ereport(LOG,
05195 (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
05196 errmsg("background worker \"%s\": cannot request database access if starting at postmaster start",
05197 worker->bgw_name)));
05198 return;
05199 }
05200
05201
05202 }
05203
05204 if ((worker->bgw_restart_time < 0 &&
05205 worker->bgw_restart_time != BGW_NEVER_RESTART) ||
05206 (worker->bgw_restart_time > USECS_PER_DAY / 1000))
05207 {
05208 if (!IsUnderPostmaster)
05209 ereport(LOG,
05210 (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
05211 errmsg("background worker \"%s\": invalid restart interval",
05212 worker->bgw_name)));
05213 return;
05214 }
05215
05216
05217
05218
05219
05220
05221
05222
05223 if (++numworkers > maxworkers)
05224 {
05225 ereport(LOG,
05226 (errcode(ERRCODE_CONFIGURATION_LIMIT_EXCEEDED),
05227 errmsg("too many background workers"),
05228 errdetail("Up to %d background workers can be registered with the current settings.",
05229 maxworkers)));
05230 return;
05231 }
05232
05233
05234
05235
05236 rw = malloc(sizeof(RegisteredBgWorker) + namelen + 1);
05237 if (rw == NULL)
05238 {
05239 ereport(LOG,
05240 (errcode(ERRCODE_OUT_OF_MEMORY),
05241 errmsg("out of memory")));
05242 return;
05243 }
05244
05245 rw->rw_worker = *worker;
05246 rw->rw_worker.bgw_name = ((char *) rw) + sizeof(RegisteredBgWorker);
05247 strlcpy(rw->rw_worker.bgw_name, worker->bgw_name, namelen + 1);
05248
05249 rw->rw_backend = NULL;
05250 rw->rw_pid = 0;
05251 rw->rw_child_slot = 0;
05252 rw->rw_crashed_at = 0;
05253 #ifdef EXEC_BACKEND
05254 rw->rw_cookie = BackgroundWorkerCookie++;
05255 #endif
05256
05257 slist_push_head(&BackgroundWorkerList, &rw->rw_lnode);
05258 }
05259
05260
05261
05262
05263 void
05264 BackgroundWorkerInitializeConnection(char *dbname, char *username)
05265 {
05266 BackgroundWorker *worker = MyBgworkerEntry;
05267
05268
05269 if (!(worker->bgw_flags & BGWORKER_BACKEND_DATABASE_CONNECTION))
05270 ereport(FATAL,
05271 (errcode(ERRCODE_PROGRAM_LIMIT_EXCEEDED),
05272 errmsg("database connection requirement not indicated during registration")));
05273
05274 InitPostgres(dbname, InvalidOid, username, NULL);
05275
05276
05277 if (!IsInitProcessingMode())
05278 ereport(ERROR,
05279 (errmsg("invalid processing mode in bgworker")));
05280 SetProcessingMode(NormalProcessing);
05281 }
05282
05283
05284
05285
05286 void
05287 BackgroundWorkerBlockSignals(void)
05288 {
05289 PG_SETMASK(&BlockSig);
05290 }
05291
05292 void
05293 BackgroundWorkerUnblockSignals(void)
05294 {
05295 PG_SETMASK(&UnBlockSig);
05296 }
05297
05298 #ifdef EXEC_BACKEND
05299 static BackgroundWorker *
05300 find_bgworker_entry(int cookie)
05301 {
05302 slist_iter iter;
05303
05304 slist_foreach(iter, &BackgroundWorkerList)
05305 {
05306 RegisteredBgWorker *rw;
05307
05308 rw = slist_container(RegisteredBgWorker, rw_lnode, iter.cur);
05309 if (rw->rw_cookie == cookie)
05310 return &rw->rw_worker;
05311 }
05312
05313 return NULL;
05314 }
05315 #endif
05316
05317 static void
05318 bgworker_quickdie(SIGNAL_ARGS)
05319 {
05320 sigaddset(&BlockSig, SIGQUIT);
05321 PG_SETMASK(&BlockSig);
05322
05323
05324
05325
05326
05327
05328
05329
05330
05331 on_exit_reset();
05332
05333
05334
05335
05336
05337
05338
05339
05340 exit(0);
05341 }
05342
05343
05344
05345
05346 static void
05347 bgworker_die(SIGNAL_ARGS)
05348 {
05349 PG_SETMASK(&BlockSig);
05350
05351 ereport(FATAL,
05352 (errcode(ERRCODE_ADMIN_SHUTDOWN),
05353 errmsg("terminating background worker \"%s\" due to administrator command",
05354 MyBgworkerEntry->bgw_name)));
05355 }
05356
05357
05358
05359
05360
05361
05362
05363 static void
05364 bgworker_sigusr1_handler(SIGNAL_ARGS)
05365 {
05366 int save_errno = errno;
05367
05368 latch_sigusr1_handler();
05369
05370 errno = save_errno;
05371 }
05372
05373 static void
05374 do_start_bgworker(void)
05375 {
05376 sigjmp_buf local_sigjmp_buf;
05377 char buf[MAXPGPATH];
05378 BackgroundWorker *worker = MyBgworkerEntry;
05379
05380 if (worker == NULL)
05381 elog(FATAL, "unable to find bgworker entry");
05382
05383
05384 IsUnderPostmaster = true;
05385 IsBackgroundWorker = true;
05386
05387
05388 MyProcPid = getpid();
05389
05390
05391 MyStartTime = time(NULL);
05392
05393
05394 snprintf(buf, MAXPGPATH, "bgworker: %s", worker->bgw_name);
05395 init_ps_display(buf, "", "", "");
05396
05397 SetProcessingMode(InitProcessing);
05398
05399
05400 if (PostAuthDelay > 0)
05401 pg_usleep(PostAuthDelay * 1000000L);
05402
05403
05404
05405
05406
05407 #ifdef HAVE_SETSID
05408 if (setsid() < 0)
05409 elog(FATAL, "setsid() failed: %m");
05410 #endif
05411
05412
05413
05414
05415 if (worker->bgw_flags & BGWORKER_BACKEND_DATABASE_CONNECTION)
05416 {
05417
05418
05419
05420 pqsignal(SIGINT, StatementCancelHandler);
05421 pqsignal(SIGUSR1, procsignal_sigusr1_handler);
05422 pqsignal(SIGFPE, FloatExceptionHandler);
05423
05424
05425 }
05426 else
05427 {
05428 pqsignal(SIGINT, SIG_IGN);
05429 pqsignal(SIGUSR1, bgworker_sigusr1_handler);
05430 pqsignal(SIGFPE, SIG_IGN);
05431 }
05432
05433
05434 if (worker->bgw_sigterm)
05435 pqsignal(SIGTERM, worker->bgw_sigterm);
05436 else
05437 pqsignal(SIGTERM, bgworker_die);
05438
05439 if (worker->bgw_sighup)
05440 pqsignal(SIGHUP, worker->bgw_sighup);
05441 else
05442 pqsignal(SIGHUP, SIG_IGN);
05443
05444 pqsignal(SIGQUIT, bgworker_quickdie);
05445 InitializeTimeouts();
05446
05447 pqsignal(SIGPIPE, SIG_IGN);
05448 pqsignal(SIGUSR2, SIG_IGN);
05449 pqsignal(SIGCHLD, SIG_DFL);
05450
05451
05452
05453
05454
05455
05456 if (sigsetjmp(local_sigjmp_buf, 1) != 0)
05457 {
05458
05459 error_context_stack = NULL;
05460
05461
05462 HOLD_INTERRUPTS();
05463
05464
05465 EmitErrorReport();
05466
05467
05468
05469
05470
05471
05472
05473
05474 proc_exit(1);
05475 }
05476
05477
05478 PG_exception_stack = &local_sigjmp_buf;
05479
05480
05481 BaseInit();
05482
05483
05484
05485
05486
05487
05488
05489 #ifndef EXEC_BACKEND
05490 if (worker->bgw_flags & BGWORKER_SHMEM_ACCESS)
05491 InitProcess();
05492 #endif
05493
05494
05495
05496
05497
05498
05499
05500
05501
05502
05503
05504 worker->bgw_main(worker->bgw_main_arg);
05505
05506
05507 proc_exit(0);
05508 }
05509
05510
05511
05512
05513
05514 static int
05515 GetNumRegisteredBackgroundWorkers(int flags)
05516 {
05517 slist_iter iter;
05518 int count = 0;
05519
05520 slist_foreach(iter, &BackgroundWorkerList)
05521 {
05522 RegisteredBgWorker *rw;
05523
05524 rw = slist_container(RegisteredBgWorker, rw_lnode, iter.cur);
05525
05526 if (flags != 0 &&
05527 !(rw->rw_worker.bgw_flags & flags))
05528 continue;
05529
05530 count++;
05531 }
05532
05533 return count;
05534 }
05535
05536
05537
05538
05539 int
05540 GetNumShmemAttachedBgworkers(void)
05541 {
05542 return GetNumRegisteredBackgroundWorkers(BGWORKER_SHMEM_ACCESS);
05543 }
05544
05545 #ifdef EXEC_BACKEND
05546 static pid_t
05547 bgworker_forkexec(int cookie)
05548 {
05549 char *av[10];
05550 int ac = 0;
05551 char forkav[MAXPGPATH];
05552
05553 snprintf(forkav, MAXPGPATH, "--forkbgworker=%d", cookie);
05554
05555 av[ac++] = "postgres";
05556 av[ac++] = forkav;
05557 av[ac++] = NULL;
05558 av[ac] = NULL;
05559
05560 Assert(ac < lengthof(av));
05561
05562 return postmaster_forkexec(ac, av);
05563 }
05564 #endif
05565
05566
05567
05568
05569
05570
05571
05572 static void
05573 start_bgworker(RegisteredBgWorker *rw)
05574 {
05575 pid_t worker_pid;
05576
05577 ereport(LOG,
05578 (errmsg("starting background worker process \"%s\"",
05579 rw->rw_worker.bgw_name)));
05580
05581 #ifdef EXEC_BACKEND
05582 switch ((worker_pid = bgworker_forkexec(rw->rw_cookie)))
05583 #else
05584 switch ((worker_pid = fork_process()))
05585 #endif
05586 {
05587 case -1:
05588 ereport(LOG,
05589 (errmsg("could not fork worker process: %m")));
05590 return;
05591
05592 #ifndef EXEC_BACKEND
05593 case 0:
05594
05595
05596 ClosePostmasterPorts(false);
05597
05598
05599 on_exit_reset();
05600
05601
05602
05603 MyBgworkerEntry = &rw->rw_worker;
05604 do_start_bgworker();
05605 break;
05606 #endif
05607 default:
05608 rw->rw_pid = worker_pid;
05609 if (rw->rw_backend)
05610 rw->rw_backend->pid = rw->rw_pid;
05611 }
05612 }
05613
05614
05615
05616
05617
05618 static bool
05619 bgworker_should_start_now(BgWorkerStartTime start_time)
05620 {
05621 switch (pmState)
05622 {
05623 case PM_NO_CHILDREN:
05624 case PM_WAIT_DEAD_END:
05625 case PM_SHUTDOWN_2:
05626 case PM_SHUTDOWN:
05627 case PM_WAIT_BACKENDS:
05628 case PM_WAIT_READONLY:
05629 case PM_WAIT_BACKUP:
05630 break;
05631
05632 case PM_RUN:
05633 if (start_time == BgWorkerStart_RecoveryFinished)
05634 return true;
05635
05636
05637 case PM_HOT_STANDBY:
05638 if (start_time == BgWorkerStart_ConsistentState)
05639 return true;
05640
05641
05642 case PM_RECOVERY:
05643 case PM_STARTUP:
05644 case PM_INIT:
05645 if (start_time == BgWorkerStart_PostmasterStart)
05646 return true;
05647
05648
05649 }
05650
05651 return false;
05652 }
05653
05654
05655
05656
05657
05658
05659
05660 static bool
05661 assign_backendlist_entry(RegisteredBgWorker *rw)
05662 {
05663 Backend *bn = malloc(sizeof(Backend));
05664
05665 if (bn == NULL)
05666 {
05667 ereport(LOG,
05668 (errcode(ERRCODE_OUT_OF_MEMORY),
05669 errmsg("out of memory")));
05670
05671
05672
05673
05674
05675
05676
05677 rw->rw_crashed_at = GetCurrentTimestamp();
05678 return false;
05679 }
05680
05681
05682
05683
05684
05685
05686
05687 MyCancelKey = PostmasterRandom();
05688 bn->cancel_key = MyCancelKey;
05689
05690 bn->child_slot = MyPMChildSlot = AssignPostmasterChildSlot();
05691 bn->bkend_type = BACKEND_TYPE_BGWORKER;
05692 bn->dead_end = false;
05693
05694 rw->rw_backend = bn;
05695 rw->rw_child_slot = bn->child_slot;
05696
05697 return true;
05698 }
05699
05700
05701
05702
05703
05704
05705
05706
05707 static void
05708 StartOneBackgroundWorker(void)
05709 {
05710 slist_iter iter;
05711 TimestampTz now = 0;
05712
05713 if (FatalError)
05714 {
05715 StartWorkerNeeded = false;
05716 HaveCrashedWorker = false;
05717 return;
05718 }
05719
05720 HaveCrashedWorker = false;
05721
05722 slist_foreach(iter, &BackgroundWorkerList)
05723 {
05724 RegisteredBgWorker *rw;
05725
05726 rw = slist_container(RegisteredBgWorker, rw_lnode, iter.cur);
05727
05728
05729 if (rw->rw_pid != 0)
05730 continue;
05731
05732
05733
05734
05735
05736
05737
05738
05739 if (rw->rw_crashed_at != 0)
05740 {
05741 if (rw->rw_worker.bgw_restart_time == BGW_NEVER_RESTART)
05742 continue;
05743
05744 if (now == 0)
05745 now = GetCurrentTimestamp();
05746
05747 if (!TimestampDifferenceExceeds(rw->rw_crashed_at, now,
05748 rw->rw_worker.bgw_restart_time * 1000))
05749 {
05750 HaveCrashedWorker = true;
05751 continue;
05752 }
05753 }
05754
05755 if (bgworker_should_start_now(rw->rw_worker.bgw_start_time))
05756 {
05757
05758 rw->rw_crashed_at = 0;
05759
05760
05761
05762
05763
05764
05765
05766
05767
05768 if (rw->rw_worker.bgw_flags & BGWORKER_BACKEND_DATABASE_CONNECTION)
05769 {
05770 if (!assign_backendlist_entry(rw))
05771 return;
05772 }
05773 else
05774 rw->rw_child_slot = MyPMChildSlot = AssignPostmasterChildSlot();
05775
05776 start_bgworker(rw);
05777
05778 if (rw->rw_backend)
05779 {
05780 dlist_push_head(&BackendList, &rw->rw_backend->elem);
05781 #ifdef EXEC_BACKEND
05782 ShmemBackendArrayAdd(rw->rw_backend);
05783 #endif
05784 }
05785
05786
05787
05788
05789
05790
05791 StartWorkerNeeded = true;
05792 return;
05793 }
05794 }
05795
05796
05797 StartWorkerNeeded = false;
05798 }
05799
05800 #ifdef EXEC_BACKEND
05801
05802
05803
05804
05805
05806 extern slock_t *ShmemLock;
05807 extern LWLock *LWLockArray;
05808 extern slock_t *ProcStructLock;
05809 extern PGPROC *AuxiliaryProcs;
05810 extern PMSignalData *PMSignalState;
05811 extern pgsocket pgStatSock;
05812 extern pg_time_t first_syslogger_file_time;
05813
05814 #ifndef WIN32
05815 #define write_inheritable_socket(dest, src, childpid) ((*(dest) = (src)), true)
05816 #define read_inheritable_socket(dest, src) (*(dest) = *(src))
05817 #else
05818 static bool write_duplicated_handle(HANDLE *dest, HANDLE src, HANDLE child);
05819 static bool write_inheritable_socket(InheritableSocket *dest, SOCKET src,
05820 pid_t childPid);
05821 static void read_inheritable_socket(SOCKET *dest, InheritableSocket *src);
05822 #endif
05823
05824
05825
05826 #ifndef WIN32
05827 static bool
05828 save_backend_variables(BackendParameters *param, Port *port)
05829 #else
05830 static bool
05831 save_backend_variables(BackendParameters *param, Port *port,
05832 HANDLE childProcess, pid_t childPid)
05833 #endif
05834 {
05835 memcpy(¶m->port, port, sizeof(Port));
05836 if (!write_inheritable_socket(¶m->portsocket, port->sock, childPid))
05837 return false;
05838
05839 strlcpy(param->DataDir, DataDir, MAXPGPATH);
05840
05841 memcpy(¶m->ListenSocket, &ListenSocket, sizeof(ListenSocket));
05842
05843 param->MyCancelKey = MyCancelKey;
05844 param->MyPMChildSlot = MyPMChildSlot;
05845
05846 param->UsedShmemSegID = UsedShmemSegID;
05847 param->UsedShmemSegAddr = UsedShmemSegAddr;
05848
05849 param->ShmemLock = ShmemLock;
05850 param->ShmemVariableCache = ShmemVariableCache;
05851 param->ShmemBackendArray = ShmemBackendArray;
05852
05853 param->LWLockArray = LWLockArray;
05854 param->ProcStructLock = ProcStructLock;
05855 param->ProcGlobal = ProcGlobal;
05856 param->AuxiliaryProcs = AuxiliaryProcs;
05857 param->PreparedXactProcs = PreparedXactProcs;
05858 param->PMSignalState = PMSignalState;
05859 if (!write_inheritable_socket(¶m->pgStatSock, pgStatSock, childPid))
05860 return false;
05861
05862 param->PostmasterPid = PostmasterPid;
05863 param->PgStartTime = PgStartTime;
05864 param->PgReloadTime = PgReloadTime;
05865 param->first_syslogger_file_time = first_syslogger_file_time;
05866
05867 param->redirection_done = redirection_done;
05868 param->IsBinaryUpgrade = IsBinaryUpgrade;
05869 param->max_safe_fds = max_safe_fds;
05870
05871 param->MaxBackends = MaxBackends;
05872
05873 #ifdef WIN32
05874 param->PostmasterHandle = PostmasterHandle;
05875 if (!write_duplicated_handle(¶m->initial_signal_pipe,
05876 pgwin32_create_signal_listener(childPid),
05877 childProcess))
05878 return false;
05879 #else
05880 memcpy(¶m->postmaster_alive_fds, &postmaster_alive_fds,
05881 sizeof(postmaster_alive_fds));
05882 #endif
05883
05884 memcpy(¶m->syslogPipe, &syslogPipe, sizeof(syslogPipe));
05885
05886 strlcpy(param->my_exec_path, my_exec_path, MAXPGPATH);
05887
05888 strlcpy(param->pkglib_path, pkglib_path, MAXPGPATH);
05889
05890 strlcpy(param->ExtraOptions, ExtraOptions, MAXPGPATH);
05891
05892 return true;
05893 }
05894
05895
05896 #ifdef WIN32
05897
05898
05899
05900
05901 static bool
05902 write_duplicated_handle(HANDLE *dest, HANDLE src, HANDLE childProcess)
05903 {
05904 HANDLE hChild = INVALID_HANDLE_VALUE;
05905
05906 if (!DuplicateHandle(GetCurrentProcess(),
05907 src,
05908 childProcess,
05909 &hChild,
05910 0,
05911 TRUE,
05912 DUPLICATE_CLOSE_SOURCE | DUPLICATE_SAME_ACCESS))
05913 {
05914 ereport(LOG,
05915 (errmsg_internal("could not duplicate handle to be written to backend parameter file: error code %lu",
05916 GetLastError())));
05917 return false;
05918 }
05919
05920 *dest = hChild;
05921 return true;
05922 }
05923
05924
05925
05926
05927
05928
05929
05930
05931 static bool
05932 write_inheritable_socket(InheritableSocket *dest, SOCKET src, pid_t childpid)
05933 {
05934 dest->origsocket = src;
05935 if (src != 0 && src != PGINVALID_SOCKET)
05936 {
05937
05938 if (WSADuplicateSocket(src, childpid, &dest->wsainfo) != 0)
05939 {
05940 ereport(LOG,
05941 (errmsg("could not duplicate socket %d for use in backend: error code %d",
05942 (int) src, WSAGetLastError())));
05943 return false;
05944 }
05945 }
05946 return true;
05947 }
05948
05949
05950
05951
05952 static void
05953 read_inheritable_socket(SOCKET *dest, InheritableSocket *src)
05954 {
05955 SOCKET s;
05956
05957 if (src->origsocket == PGINVALID_SOCKET || src->origsocket == 0)
05958 {
05959
05960 *dest = src->origsocket;
05961 }
05962 else
05963 {
05964
05965 s = WSASocket(FROM_PROTOCOL_INFO,
05966 FROM_PROTOCOL_INFO,
05967 FROM_PROTOCOL_INFO,
05968 &src->wsainfo,
05969 0,
05970 0);
05971 if (s == INVALID_SOCKET)
05972 {
05973 write_stderr("could not create inherited socket: error code %d\n",
05974 WSAGetLastError());
05975 exit(1);
05976 }
05977 *dest = s;
05978
05979
05980
05981
05982
05983
05984 closesocket(src->origsocket);
05985 }
05986 }
05987 #endif
05988
05989 static void
05990 read_backend_variables(char *id, Port *port)
05991 {
05992 BackendParameters param;
05993
05994 #ifndef WIN32
05995
05996 FILE *fp;
05997
05998
05999 fp = AllocateFile(id, PG_BINARY_R);
06000 if (!fp)
06001 {
06002 write_stderr("could not read from backend variables file \"%s\": %s\n",
06003 id, strerror(errno));
06004 exit(1);
06005 }
06006
06007 if (fread(¶m, sizeof(param), 1, fp) != 1)
06008 {
06009 write_stderr("could not read from backend variables file \"%s\": %s\n",
06010 id, strerror(errno));
06011 exit(1);
06012 }
06013
06014
06015 FreeFile(fp);
06016 if (unlink(id) != 0)
06017 {
06018 write_stderr("could not remove file \"%s\": %s\n",
06019 id, strerror(errno));
06020 exit(1);
06021 }
06022 #else
06023
06024 HANDLE paramHandle;
06025 BackendParameters *paramp;
06026
06027 #ifdef _WIN64
06028 paramHandle = (HANDLE) _atoi64(id);
06029 #else
06030 paramHandle = (HANDLE) atol(id);
06031 #endif
06032 paramp = MapViewOfFile(paramHandle, FILE_MAP_READ, 0, 0, 0);
06033 if (!paramp)
06034 {
06035 write_stderr("could not map view of backend variables: error code %lu\n",
06036 GetLastError());
06037 exit(1);
06038 }
06039
06040 memcpy(¶m, paramp, sizeof(BackendParameters));
06041
06042 if (!UnmapViewOfFile(paramp))
06043 {
06044 write_stderr("could not unmap view of backend variables: error code %lu\n",
06045 GetLastError());
06046 exit(1);
06047 }
06048
06049 if (!CloseHandle(paramHandle))
06050 {
06051 write_stderr("could not close handle to backend parameter variables: error code %lu\n",
06052 GetLastError());
06053 exit(1);
06054 }
06055 #endif
06056
06057 restore_backend_variables(¶m, port);
06058 }
06059
06060
06061 static void
06062 restore_backend_variables(BackendParameters *param, Port *port)
06063 {
06064 memcpy(port, ¶m->port, sizeof(Port));
06065 read_inheritable_socket(&port->sock, ¶m->portsocket);
06066
06067 SetDataDir(param->DataDir);
06068
06069 memcpy(&ListenSocket, ¶m->ListenSocket, sizeof(ListenSocket));
06070
06071 MyCancelKey = param->MyCancelKey;
06072 MyPMChildSlot = param->MyPMChildSlot;
06073
06074 UsedShmemSegID = param->UsedShmemSegID;
06075 UsedShmemSegAddr = param->UsedShmemSegAddr;
06076
06077 ShmemLock = param->ShmemLock;
06078 ShmemVariableCache = param->ShmemVariableCache;
06079 ShmemBackendArray = param->ShmemBackendArray;
06080
06081 LWLockArray = param->LWLockArray;
06082 ProcStructLock = param->ProcStructLock;
06083 ProcGlobal = param->ProcGlobal;
06084 AuxiliaryProcs = param->AuxiliaryProcs;
06085 PreparedXactProcs = param->PreparedXactProcs;
06086 PMSignalState = param->PMSignalState;
06087 read_inheritable_socket(&pgStatSock, ¶m->pgStatSock);
06088
06089 PostmasterPid = param->PostmasterPid;
06090 PgStartTime = param->PgStartTime;
06091 PgReloadTime = param->PgReloadTime;
06092 first_syslogger_file_time = param->first_syslogger_file_time;
06093
06094 redirection_done = param->redirection_done;
06095 IsBinaryUpgrade = param->IsBinaryUpgrade;
06096 max_safe_fds = param->max_safe_fds;
06097
06098 MaxBackends = param->MaxBackends;
06099
06100 #ifdef WIN32
06101 PostmasterHandle = param->PostmasterHandle;
06102 pgwin32_initial_signal_pipe = param->initial_signal_pipe;
06103 #else
06104 memcpy(&postmaster_alive_fds, ¶m->postmaster_alive_fds,
06105 sizeof(postmaster_alive_fds));
06106 #endif
06107
06108 memcpy(&syslogPipe, ¶m->syslogPipe, sizeof(syslogPipe));
06109
06110 strlcpy(my_exec_path, param->my_exec_path, MAXPGPATH);
06111
06112 strlcpy(pkglib_path, param->pkglib_path, MAXPGPATH);
06113
06114 strlcpy(ExtraOptions, param->ExtraOptions, MAXPGPATH);
06115 }
06116
06117
06118 Size
06119 ShmemBackendArraySize(void)
06120 {
06121 return mul_size(MaxLivePostmasterChildren(), sizeof(Backend));
06122 }
06123
06124 void
06125 ShmemBackendArrayAllocation(void)
06126 {
06127 Size size = ShmemBackendArraySize();
06128
06129 ShmemBackendArray = (Backend *) ShmemAlloc(size);
06130
06131 memset(ShmemBackendArray, 0, size);
06132 }
06133
06134 static void
06135 ShmemBackendArrayAdd(Backend *bn)
06136 {
06137
06138 int i = bn->child_slot - 1;
06139
06140 Assert(ShmemBackendArray[i].pid == 0);
06141 ShmemBackendArray[i] = *bn;
06142 }
06143
06144 static void
06145 ShmemBackendArrayRemove(Backend *bn)
06146 {
06147 int i = bn->child_slot - 1;
06148
06149 Assert(ShmemBackendArray[i].pid == bn->pid);
06150
06151 ShmemBackendArray[i].pid = 0;
06152 }
06153 #endif
06154
06155
06156 #ifdef WIN32
06157
06158
06159
06160
06161
06162 static pid_t
06163 waitpid(pid_t pid, int *exitstatus, int options)
06164 {
06165 DWORD dwd;
06166 ULONG_PTR key;
06167 OVERLAPPED *ovl;
06168
06169
06170
06171
06172
06173 if (GetQueuedCompletionStatus(win32ChildQueue, &dwd, &key, &ovl, 0))
06174 {
06175 *exitstatus = (int) key;
06176 return dwd;
06177 }
06178
06179 return -1;
06180 }
06181
06182
06183
06184
06185
06186 static void WINAPI
06187 pgwin32_deadchild_callback(PVOID lpParameter, BOOLEAN TimerOrWaitFired)
06188 {
06189 win32_deadchild_waitinfo *childinfo = (win32_deadchild_waitinfo *) lpParameter;
06190 DWORD exitcode;
06191
06192 if (TimerOrWaitFired)
06193 return;
06194
06195
06196
06197
06198
06199
06200 UnregisterWaitEx(childinfo->waitHandle, NULL);
06201
06202 if (!GetExitCodeProcess(childinfo->procHandle, &exitcode))
06203 {
06204
06205
06206
06207 write_stderr("could not read exit code for process\n");
06208 exitcode = 255;
06209 }
06210
06211 if (!PostQueuedCompletionStatus(win32ChildQueue, childinfo->procId, (ULONG_PTR) exitcode, NULL))
06212 write_stderr("could not post child completion status\n");
06213
06214
06215
06216
06217
06218 CloseHandle(childinfo->procHandle);
06219
06220
06221
06222
06223
06224 free(childinfo);
06225
06226
06227 pg_queue_signal(SIGCHLD);
06228 }
06229 #endif
06230
06231
06232
06233
06234
06235
06236
06237 static void
06238 InitPostmasterDeathWatchHandle(void)
06239 {
06240 #ifndef WIN32
06241
06242
06243
06244
06245
06246
06247
06248
06249
06250
06251 Assert(MyProcPid == PostmasterPid);
06252 if (pipe(postmaster_alive_fds))
06253 ereport(FATAL,
06254 (errcode_for_file_access(),
06255 errmsg_internal("could not create pipe to monitor postmaster death: %m")));
06256
06257
06258
06259
06260
06261 if (fcntl(postmaster_alive_fds[POSTMASTER_FD_WATCH], F_SETFL, O_NONBLOCK))
06262 ereport(FATAL,
06263 (errcode_for_socket_access(),
06264 errmsg_internal("could not set postmaster death monitoring pipe to nonblocking mode: %m")));
06265 #else
06266
06267
06268
06269
06270 if (DuplicateHandle(GetCurrentProcess(),
06271 GetCurrentProcess(),
06272 GetCurrentProcess(),
06273 &PostmasterHandle,
06274 0,
06275 TRUE,
06276 DUPLICATE_SAME_ACCESS) == 0)
06277 ereport(FATAL,
06278 (errmsg_internal("could not duplicate postmaster handle: error code %lu",
06279 GetLastError())));
06280 #endif
06281 }