PostgreSQL Source Code git master
Loading...
Searching...
No Matches
postinit.c File Reference
#include "postgres.h"
#include <ctype.h>
#include <fcntl.h>
#include <unistd.h>
#include "access/genam.h"
#include "access/heapam.h"
#include "access/htup_details.h"
#include "access/session.h"
#include "access/tableam.h"
#include "access/xact.h"
#include "access/xlog.h"
#include "access/xloginsert.h"
#include "catalog/namespace.h"
#include "catalog/pg_authid.h"
#include "catalog/pg_collation.h"
#include "catalog/pg_database.h"
#include "catalog/pg_db_role_setting.h"
#include "catalog/pg_tablespace.h"
#include "libpq/auth.h"
#include "libpq/libpq-be.h"
#include "mb/pg_wchar.h"
#include "miscadmin.h"
#include "pgstat.h"
#include "postmaster/autovacuum.h"
#include "postmaster/postmaster.h"
#include "replication/slot.h"
#include "replication/slotsync.h"
#include "replication/walsender.h"
#include "storage/aio_subsys.h"
#include "storage/bufmgr.h"
#include "storage/fd.h"
#include "storage/ipc.h"
#include "storage/lmgr.h"
#include "storage/proc.h"
#include "storage/procarray.h"
#include "storage/procnumber.h"
#include "storage/procsignal.h"
#include "storage/sinvaladt.h"
#include "storage/smgr.h"
#include "storage/sync.h"
#include "tcop/backend_startup.h"
#include "tcop/tcopprot.h"
#include "utils/acl.h"
#include "utils/builtins.h"
#include "utils/fmgroids.h"
#include "utils/guc_hooks.h"
#include "utils/injection_point.h"
#include "utils/memutils.h"
#include "utils/pg_locale.h"
#include "utils/portal.h"
#include "utils/ps_status.h"
#include "utils/snapmgr.h"
#include "utils/syscache.h"
#include "utils/timeout.h"
Include dependency graph for postinit.c:

Go to the source code of this file.

Functions

static HeapTuple GetDatabaseTuple (const char *dbname)
 
static HeapTuple GetDatabaseTupleByOid (Oid dboid)
 
static void PerformAuthentication (Port *port)
 
static void CheckMyDatabase (const char *name, bool am_superuser, bool override_allow_connections)
 
static void ShutdownPostgres (int code, Datum arg)
 
static void StatementTimeoutHandler (void)
 
static void LockTimeoutHandler (void)
 
static void IdleInTransactionSessionTimeoutHandler (void)
 
static void TransactionTimeoutHandler (void)
 
static void IdleSessionTimeoutHandler (void)
 
static void IdleStatsUpdateTimeoutHandler (void)
 
static void ClientCheckTimeoutHandler (void)
 
static bool ThereIsAtLeastOneRole (void)
 
static void process_startup_options (Port *port, bool am_superuser)
 
static void process_settings (Oid databaseid, Oid roleid)
 
static void EmitConnectionWarnings (void)
 
void pg_split_opts (char **argv, int *argcp, const char *optstr)
 
void InitializeMaxBackends (void)
 
void InitializeFastPathLocks (void)
 
void BaseInit (void)
 
void InitPostgres (const char *in_dbname, Oid dboid, const char *username, Oid useroid, bits32 flags, char *out_dbname)
 
void StoreConnectionWarning (char *msg, char *detail)
 

Variables

static bool ConnectionWarningsEmitted
 
static ListConnectionWarningMessages
 
static ListConnectionWarningDetails
 

Function Documentation

◆ BaseInit()

void BaseInit ( void  )

Definition at line 615 of file postinit.c.

616{
617 Assert(MyProc != NULL);
618
619 /*
620 * Initialize our input/output/debugging file descriptors.
621 */
623
624 /*
625 * Initialize file access. Done early so other subsystems can access
626 * files.
627 */
629
630 /*
631 * Initialize statistics reporting. This needs to happen early to ensure
632 * that pgstat's shutdown callback runs after the shutdown callbacks of
633 * all subsystems that can produce stats (like e.g. transaction commits
634 * can).
635 */
637
638 /*
639 * Initialize AIO before infrastructure that might need to actually
640 * execute AIO.
641 */
643
644 /* Do local initialization of storage and buffer managers */
645 InitSync();
646 smgrinit();
648
649 /*
650 * Initialize temporary file access after pgstat, so that the temporary
651 * file shutdown hook can report temporary file statistics.
652 */
654
655 /*
656 * Initialize local buffers for WAL record construction, in case we ever
657 * try to insert XLOG.
658 */
660
661 /* Initialize lock manager's local structs */
663
664 /* Initialize logical info WAL logging state */
666
667 /*
668 * Initialize replication slots after pgstat. The exit hook might need to
669 * drop ephemeral slots, which in turn triggers stats reporting.
670 */
672}
void pgaio_init_backend(void)
Definition aio_init.c:218
void InitBufferManagerAccess(void)
Definition bufmgr.c:4121
#define Assert(condition)
Definition c.h:885
void DebugFileOpen(void)
Definition elog.c:2306
void InitFileAccess(void)
Definition fd.c:903
void InitTemporaryFileAccess(void)
Definition fd.c:933
void InitLockManagerAccess(void)
Definition lock.c:505
void InitializeProcessXLogLogicalInfo(void)
Definition logicalctl.c:177
void pgstat_initialize(void)
Definition pgstat.c:651
static int fb(int x)
void ReplicationSlotInitialize(void)
Definition slot.c:242
void smgrinit(void)
Definition smgr.c:188
PGPROC * MyProc
Definition proc.c:67
void InitSync(void)
Definition sync.c:124
void InitXLogInsert(void)

References Assert, DebugFileOpen(), fb(), InitBufferManagerAccess(), InitFileAccess(), InitializeProcessXLogLogicalInfo(), InitLockManagerAccess(), InitSync(), InitTemporaryFileAccess(), InitXLogInsert(), MyProc, pgaio_init_backend(), pgstat_initialize(), ReplicationSlotInitialize(), and smgrinit().

Referenced by AutoVacLauncherMain(), AutoVacWorkerMain(), AuxiliaryProcessMainCommon(), BackgroundWorkerMain(), BootstrapModeMain(), PostgresMain(), and ReplSlotSyncWorkerMain().

◆ CheckMyDatabase()

static void CheckMyDatabase ( const char name,
bool  am_superuser,
bool  override_allow_connections 
)
static

Definition at line 331 of file postinit.c.

332{
335 Datum datum;
336 bool isnull;
337 char *collate;
338 char *ctype;
339
340 /* Fetch our pg_database row normally, via syscache */
342 if (!HeapTupleIsValid(tup))
343 elog(ERROR, "cache lookup failed for database %u", MyDatabaseId);
345
346 /* This recheck is strictly paranoia */
347 if (strcmp(name, NameStr(dbform->datname)) != 0)
350 errmsg("database \"%s\" has disappeared from pg_database",
351 name),
352 errdetail("Database OID %u now seems to belong to \"%s\".",
353 MyDatabaseId, NameStr(dbform->datname))));
354
355 /*
356 * Check permissions to connect to the database.
357 *
358 * These checks are not enforced when in standalone mode, so that there is
359 * a way to recover from disabling all access to all databases, for
360 * example "UPDATE pg_database SET datallowconn = false;".
361 */
363 {
364 /*
365 * Check that the database is currently allowing connections.
366 * (Background processes can override this test and the next one by
367 * setting override_allow_connections.)
368 */
369 if (!dbform->datallowconn && !override_allow_connections)
372 errmsg("database \"%s\" is not currently accepting connections",
373 name)));
374
375 /*
376 * Check privilege to connect to the database. (The am_superuser test
377 * is redundant, but since we have the flag, might as well check it
378 * and save a few cycles.)
379 */
385 errmsg("permission denied for database \"%s\"", name),
386 errdetail("User does not have CONNECT privilege.")));
387
388 /*
389 * Check connection limit for this database. We enforce the limit
390 * only for regular backends, since other process types have their own
391 * PGPROC pools.
392 *
393 * There is a race condition here --- we create our PGPROC before
394 * checking for other PGPROCs. If two backends did this at about the
395 * same time, they might both think they were over the limit, while
396 * ideally one should succeed and one fail. Getting that to work
397 * exactly seems more trouble than it is worth, however; instead we
398 * just document that the connection limit is approximate.
399 */
400 if (dbform->datconnlimit >= 0 &&
402 !am_superuser &&
403 CountDBConnections(MyDatabaseId) > dbform->datconnlimit)
406 errmsg("too many connections for database \"%s\"",
407 name)));
408 }
409
410 /*
411 * OK, we're golden. Next to-do item is to save the encoding info out of
412 * the pg_database tuple.
413 */
414 SetDatabaseEncoding(dbform->encoding);
415 /* Record it as a GUC internal option, too */
416 SetConfigOption("server_encoding", GetDatabaseEncodingName(),
418 /* If we have no other source of client_encoding, use server encoding */
419 SetConfigOption("client_encoding", GetDatabaseEncodingName(),
421
422 /* assign locale variables */
424 collate = TextDatumGetCString(datum);
426 ctype = TextDatumGetCString(datum);
427
428 /*
429 * Historically, we set LC_COLLATE from datcollate, as well. That's no
430 * longer necessary because all collation behavior is handled through
431 * pg_locale_t.
432 */
433
434 if (pg_perm_setlocale(LC_CTYPE, ctype) == NULL)
436 (errmsg("database locale is incompatible with operating system"),
437 errdetail("The database was initialized with LC_CTYPE \"%s\", "
438 " which is not recognized by setlocale().", ctype),
439 errhint("Recreate the database with another locale or install the missing locale.")));
440
442
443 /*
444 * Check collation version. See similar code in
445 * pg_newlocale_from_collation(). Note that here we warn instead of error
446 * in any case, so that we don't prevent connecting.
447 */
449 &isnull);
450 if (!isnull)
451 {
452 char *actual_versionstr;
453 char *collversionstr;
454 char *locale;
455
457
458 if (dbform->datlocprovider == COLLPROVIDER_LIBC)
459 locale = collate;
460 else
461 {
463 locale = TextDatumGetCString(datum);
464 }
465
466 actual_versionstr = get_collation_actual_version(dbform->datlocprovider, locale);
468 /* should not happen */
470 "database \"%s\" has no actual collation version, but a version was recorded",
471 name);
474 (errmsg("database \"%s\" has a collation version mismatch",
475 name),
476 errdetail("The database was created using collation version %s, "
477 "but the operating system provides version %s.",
479 errhint("Rebuild all objects in this database that use the default collation and run "
480 "ALTER DATABASE %s REFRESH COLLATION VERSION, "
481 "or build PostgreSQL with the right library version.",
483 }
484
486}
@ ACLCHECK_OK
Definition acl.h:183
AclResult object_aclcheck(Oid classid, Oid objectid, Oid roleid, AclMode mode)
Definition aclchk.c:3854
#define TextDatumGetCString(d)
Definition builtins.h:99
#define NameStr(name)
Definition c.h:777
int errcode(int sqlerrcode)
Definition elog.c:874
int errmsg(const char *fmt,...)
Definition elog.c:1093
int errhint(const char *fmt,...) pg_attribute_printf(1
int errdetail(const char *fmt,...) pg_attribute_printf(1
#define FATAL
Definition elog.h:41
#define WARNING
Definition elog.h:36
#define ERROR
Definition elog.h:39
#define elog(elevel,...)
Definition elog.h:226
#define ereport(elevel,...)
Definition elog.h:150
bool IsUnderPostmaster
Definition globals.c:120
Oid MyDatabaseId
Definition globals.c:94
void SetConfigOption(const char *name, const char *value, GucContext context, GucSource source)
Definition guc.c:4196
@ PGC_S_DYNAMIC_DEFAULT
Definition guc.h:114
@ PGC_INTERNAL
Definition guc.h:73
@ PGC_BACKEND
Definition guc.h:77
#define HeapTupleIsValid(tuple)
Definition htup.h:78
static void * GETSTRUCT(const HeapTupleData *tuple)
const char * GetDatabaseEncodingName(void)
Definition mbutils.c:1395
void SetDatabaseEncoding(int encoding)
Definition mbutils.c:1289
#define AmRegularBackendProcess()
Definition miscadmin.h:381
Oid GetUserId(void)
Definition miscinit.c:469
#define ACL_CONNECT
Definition parsenodes.h:87
END_CATALOG_STRUCT typedef FormData_pg_database * Form_pg_database
char * get_collation_actual_version(char collprovider, const char *collcollate)
Definition pg_locale.c:1247
char * pg_perm_setlocale(int category, const char *locale)
Definition pg_locale.c:172
void init_database_collation(void)
Definition pg_locale.c:1131
static Datum ObjectIdGetDatum(Oid X)
Definition postgres.h:262
uint64_t Datum
Definition postgres.h:70
int CountDBConnections(Oid databaseid)
Definition procarray.c:3662
const char * quote_identifier(const char *ident)
void ReleaseSysCache(HeapTuple tuple)
Definition syscache.c:264
Datum SysCacheGetAttrNotNull(SysCacheIdentifier cacheId, HeapTuple tup, AttrNumber attributeNumber)
Definition syscache.c:625
HeapTuple SearchSysCache1(SysCacheIdentifier cacheId, Datum key1)
Definition syscache.c:220
Datum SysCacheGetAttr(SysCacheIdentifier cacheId, HeapTuple tup, AttrNumber attributeNumber, bool *isNull)
Definition syscache.c:595
const char * name

References ACL_CONNECT, ACLCHECK_OK, AmRegularBackendProcess, CountDBConnections(), elog, ereport, errcode(), errdetail(), errhint(), errmsg(), ERROR, FATAL, fb(), Form_pg_database, get_collation_actual_version(), GetDatabaseEncodingName(), GETSTRUCT(), GetUserId(), HeapTupleIsValid, init_database_collation(), IsUnderPostmaster, MyDatabaseId, name, NameStr, object_aclcheck(), ObjectIdGetDatum(), pg_perm_setlocale(), PGC_BACKEND, PGC_INTERNAL, PGC_S_DYNAMIC_DEFAULT, quote_identifier(), ReleaseSysCache(), SearchSysCache1(), SetConfigOption(), SetDatabaseEncoding(), SysCacheGetAttr(), SysCacheGetAttrNotNull(), TextDatumGetCString, and WARNING.

Referenced by InitPostgres().

◆ ClientCheckTimeoutHandler()

static void ClientCheckTimeoutHandler ( void  )
static

Definition at line 1436 of file postinit.c.

1437{
1439 InterruptPending = true;
1441}
volatile sig_atomic_t InterruptPending
Definition globals.c:32
struct Latch * MyLatch
Definition globals.c:63
volatile sig_atomic_t CheckClientConnectionPending
Definition globals.c:35
void SetLatch(Latch *latch)
Definition latch.c:290

References CheckClientConnectionPending, InterruptPending, MyLatch, and SetLatch().

Referenced by InitPostgres().

◆ EmitConnectionWarnings()

static void EmitConnectionWarnings ( void  )
static

Definition at line 1497 of file postinit.c.

1498{
1501
1503 elog(ERROR, "EmitConnectionWarnings() called more than once");
1504 else
1506
1509 {
1511 (errmsg("%s", (char *) lfirst(lc_msg)),
1512 errdetail("%s", (char *) lfirst(lc_detail))));
1513 }
1514
1517}
void list_free_deep(List *list)
Definition list.c:1560
#define lfirst(lc)
Definition pg_list.h:172
#define forboth(cell1, list1, cell2, list2)
Definition pg_list.h:518
static List * ConnectionWarningDetails
Definition postinit.c:78
static bool ConnectionWarningsEmitted
Definition postinit.c:74
static List * ConnectionWarningMessages
Definition postinit.c:77

References ConnectionWarningDetails, ConnectionWarningMessages, ConnectionWarningsEmitted, elog, ereport, errdetail(), errmsg(), ERROR, fb(), forboth, lfirst, list_free_deep(), and WARNING.

Referenced by InitPostgres().

◆ GetDatabaseTuple()

static HeapTuple GetDatabaseTuple ( const char dbname)
static

Definition at line 113 of file postinit.c.

114{
115 HeapTuple tuple;
116 Relation relation;
117 SysScanDesc scan;
118 ScanKeyData key[1];
119
120 /*
121 * form a scan key
122 */
123 ScanKeyInit(&key[0],
127
128 /*
129 * Open pg_database and fetch a tuple. Force heap scan if we haven't yet
130 * built the critical shared relcache entries (i.e., we're starting up
131 * without a shared relcache cache file).
132 */
136 NULL,
137 1, key);
138
139 tuple = systable_getnext(scan);
140
141 /* Must copy tuple before releasing buffer */
142 if (HeapTupleIsValid(tuple))
143 tuple = heap_copytuple(tuple);
144
145 /* all done */
146 systable_endscan(scan);
147 table_close(relation, AccessShareLock);
148
149 return tuple;
150}
void systable_endscan(SysScanDesc sysscan)
Definition genam.c:603
HeapTuple systable_getnext(SysScanDesc sysscan)
Definition genam.c:514
SysScanDesc systable_beginscan(Relation heapRelation, Oid indexId, bool indexOK, Snapshot snapshot, int nkeys, ScanKey key)
Definition genam.c:388
HeapTuple heap_copytuple(HeapTuple tuple)
Definition heaptuple.c:778
#define AccessShareLock
Definition lockdefs.h:36
static Datum CStringGetDatum(const char *X)
Definition postgres.h:380
bool criticalSharedRelcachesBuilt
Definition relcache.c:146
void ScanKeyInit(ScanKey entry, AttrNumber attributeNumber, StrategyNumber strategy, RegProcedure procedure, Datum argument)
Definition scankey.c:76
#define BTEqualStrategyNumber
Definition stratnum.h:31
char * dbname
Definition streamutil.c:49
void table_close(Relation relation, LOCKMODE lockmode)
Definition table.c:126
Relation table_open(Oid relationId, LOCKMODE lockmode)
Definition table.c:40

References AccessShareLock, BTEqualStrategyNumber, criticalSharedRelcachesBuilt, CStringGetDatum(), dbname, fb(), heap_copytuple(), HeapTupleIsValid, ScanKeyInit(), systable_beginscan(), systable_endscan(), systable_getnext(), table_close(), and table_open().

Referenced by InitPostgres().

◆ GetDatabaseTupleByOid()

static HeapTuple GetDatabaseTupleByOid ( Oid  dboid)
static

Definition at line 156 of file postinit.c.

157{
158 HeapTuple tuple;
159 Relation relation;
160 SysScanDesc scan;
161 ScanKeyData key[1];
162
163 /*
164 * form a scan key
165 */
166 ScanKeyInit(&key[0],
169 ObjectIdGetDatum(dboid));
170
171 /*
172 * Open pg_database and fetch a tuple. Force heap scan if we haven't yet
173 * built the critical shared relcache entries (i.e., we're starting up
174 * without a shared relcache cache file).
175 */
177 scan = systable_beginscan(relation, DatabaseOidIndexId,
179 NULL,
180 1, key);
181
182 tuple = systable_getnext(scan);
183
184 /* Must copy tuple before releasing buffer */
185 if (HeapTupleIsValid(tuple))
186 tuple = heap_copytuple(tuple);
187
188 /* all done */
189 systable_endscan(scan);
190 table_close(relation, AccessShareLock);
191
192 return tuple;
193}

References AccessShareLock, BTEqualStrategyNumber, criticalSharedRelcachesBuilt, fb(), heap_copytuple(), HeapTupleIsValid, ObjectIdGetDatum(), ScanKeyInit(), systable_beginscan(), systable_endscan(), systable_getnext(), table_close(), and table_open().

Referenced by InitPostgres().

◆ IdleInTransactionSessionTimeoutHandler()

static void IdleInTransactionSessionTimeoutHandler ( void  )
static

Definition at line 1412 of file postinit.c.

1413{
1415 InterruptPending = true;
1417}
volatile sig_atomic_t IdleInTransactionSessionTimeoutPending
Definition globals.c:37

References IdleInTransactionSessionTimeoutPending, InterruptPending, MyLatch, and SetLatch().

Referenced by InitPostgres().

◆ IdleSessionTimeoutHandler()

static void IdleSessionTimeoutHandler ( void  )
static

Definition at line 1420 of file postinit.c.

1421{
1423 InterruptPending = true;
1425}
volatile sig_atomic_t IdleSessionTimeoutPending
Definition globals.c:39

References IdleSessionTimeoutPending, InterruptPending, MyLatch, and SetLatch().

Referenced by InitPostgres().

◆ IdleStatsUpdateTimeoutHandler()

static void IdleStatsUpdateTimeoutHandler ( void  )
static

Definition at line 1428 of file postinit.c.

1429{
1431 InterruptPending = true;
1433}
volatile sig_atomic_t IdleStatsUpdateTimeoutPending
Definition globals.c:42

References IdleStatsUpdateTimeoutPending, InterruptPending, MyLatch, and SetLatch().

Referenced by InitPostgres().

◆ InitializeFastPathLocks()

void InitializeFastPathLocks ( void  )

Definition at line 583 of file postinit.c.

584{
585 /* Should be initialized only once. */
587
588 /*
589 * Based on the max_locks_per_transaction GUC, as that's a good indicator
590 * of the expected number of locks, figure out the value for
591 * FastPathLockGroupsPerBackend. This must be a power-of-two. We cap the
592 * value at FP_LOCK_GROUPS_PER_BACKEND_MAX and insist the value is at
593 * least 1.
594 *
595 * The default max_locks_per_transaction = 64 means 4 groups by default.
596 */
600
601 /* Validate we did get a power-of-two */
604}
#define Min(x, y)
Definition c.h:1019
#define Max(x, y)
Definition c.h:1013
int max_locks_per_xact
Definition lock.c:53
int FastPathLockGroupsPerBackend
Definition lock.c:202
static uint32 pg_nextpower2_32(uint32 num)
#define FP_LOCK_GROUPS_PER_BACKEND_MAX
Definition proc.h:92
#define FP_LOCK_SLOTS_PER_GROUP
Definition proc.h:93

References Assert, FastPathLockGroupsPerBackend, FP_LOCK_GROUPS_PER_BACKEND_MAX, FP_LOCK_SLOTS_PER_GROUP, Max, max_locks_per_xact, Min, and pg_nextpower2_32().

Referenced by BootstrapModeMain(), PostgresSingleUserMain(), and PostmasterMain().

◆ InitializeMaxBackends()

void InitializeMaxBackends ( void  )

Definition at line 558 of file postinit.c.

559{
560 Assert(MaxBackends == 0);
561
562 /* Note that this does not include "auxiliary" processes */
565
569 errmsg("too many server processes configured"),
570 errdetail("\"max_connections\" (%d) plus \"autovacuum_worker_slots\" (%d) plus \"max_worker_processes\" (%d) plus \"max_wal_senders\" (%d) must be less than %d.",
574}
int autovacuum_worker_slots
Definition autovacuum.c:118
int MaxConnections
Definition globals.c:143
int MaxBackends
Definition globals.c:146
int max_worker_processes
Definition globals.c:144
#define NUM_SPECIAL_WORKER_PROCS
Definition proc.h:514
#define MAX_BACKENDS
Definition procnumber.h:39
int max_wal_senders
Definition walsender.c:129

References Assert, autovacuum_worker_slots, ereport, errcode(), errdetail(), errmsg(), ERROR, fb(), MAX_BACKENDS, max_wal_senders, max_worker_processes, MaxBackends, MaxConnections, and NUM_SPECIAL_WORKER_PROCS.

Referenced by BootstrapModeMain(), PostgresSingleUserMain(), and PostmasterMain().

◆ InitPostgres()

void InitPostgres ( const char in_dbname,
Oid  dboid,
const char username,
Oid  useroid,
bits32  flags,
char out_dbname 
)

Definition at line 718 of file postinit.c.

722{
724 bool am_superuser;
725 char *fullpath;
726 char dbname[NAMEDATALEN];
727 int nfree = 0;
728
729 elog(DEBUG3, "InitPostgres");
730
731 /*
732 * Add my PGPROC struct to the ProcArray.
733 *
734 * Once I have done this, I am visible to other backends!
735 */
737
738 /* Initialize status reporting */
740
741 /*
742 * And initialize an entry in the PgBackendStatus array. That way, if
743 * LWLocks or third-party authentication should happen to hang, it is
744 * possible to retrieve some information about what is going on.
745 */
746 if (!bootstrap)
747 {
749 INJECTION_POINT("init-pre-auth", NULL);
750 }
751
752 /*
753 * Initialize my entry in the shared-invalidation manager's array of
754 * per-backend data.
755 */
757
759
760 /*
761 * Also set up timeout handlers needed for backend operation. We need
762 * these in every case except bootstrap.
763 */
764 if (!bootstrap)
765 {
776 }
777
778 /*
779 * If this is either a bootstrap process or a standalone backend, start up
780 * the XLOG machinery, and register to have it closed down at exit. In
781 * other cases, the startup process is responsible for starting up the
782 * XLOG machinery, and the checkpointer for closing it down.
783 */
785 {
786 /*
787 * We don't yet have an aux-process resource owner, but StartupXLOG
788 * and ShutdownXLOG will need one. Hence, create said resource owner
789 * (and register a callback to clean it up after ShutdownXLOG runs).
790 */
792
793 StartupXLOG();
794 /* Release (and warn about) any buffer pins leaked in StartupXLOG */
796 /* Reset CurrentResourceOwner to nothing for the moment */
798
799 /*
800 * Use before_shmem_exit() so that ShutdownXLOG() can rely on DSM
801 * segments etc to work (which in turn is required for pgstats).
802 */
805 }
806
807 /*
808 * Initialize the relation cache and the system catalog caches. Note that
809 * no catalog access happens here; we only set up the hashtable structure.
810 * We must do this before starting a transaction because transaction abort
811 * would try to touch these hashtables.
812 */
816
817 /* Initialize portal manager */
819
820 /*
821 * Load relcache entries for the shared system catalogs. This must create
822 * at least entries for pg_database and catalogs used for authentication.
823 */
825
826 /*
827 * Set up process-exit callback to do pre-shutdown cleanup. This is one
828 * of the first before_shmem_exit callbacks we register; thus, this will
829 * be one of the last things we do before low-level modules like the
830 * buffer manager begin to close down. We need to have this in place
831 * before we begin our first transaction --- if we fail during the
832 * initialization transaction, as is entirely possible, we need the
833 * AbortTransaction call to clean up.
834 */
836
837 /* The autovacuum launcher is done here */
839 {
840 /* fill in the remainder of this entry in the PgBackendStatus array */
842
843 return;
844 }
845
846 /*
847 * Start a new transaction here before first access to db.
848 */
849 if (!bootstrap)
850 {
851 /* statement_timestamp must be set for timeouts to work correctly */
854
855 /*
856 * transaction_isolation will have been set to the default by the
857 * above. If the default is "serializable", and we are in hot
858 * standby, we will fail if we don't change it to something lower.
859 * Fortunately, "read committed" is plenty good enough.
860 */
862 }
863
864 /*
865 * Perform client authentication if necessary, then figure out our
866 * postgres user ID, and see if we are a superuser.
867 *
868 * In standalone mode, autovacuum worker processes and slot sync worker
869 * process, we use a fixed ID, otherwise we figure it out from the
870 * authenticated user name.
871 */
873 {
875 am_superuser = true;
876 }
877 else if (!IsUnderPostmaster)
878 {
880 am_superuser = true;
884 errmsg("no roles are defined in this database system"),
885 errhint("You should immediately run CREATE USER \"%s\" SUPERUSER;.",
886 username != NULL ? username : "postgres")));
887 }
888 else if (AmBackgroundWorkerProcess())
889 {
890 if (username == NULL && !OidIsValid(useroid))
891 {
893 am_superuser = true;
894 }
895 else
896 {
898 (flags & INIT_PG_OVERRIDE_ROLE_LOGIN) != 0);
900 }
901 }
902 else
903 {
904 /* normal multiuser case */
908 /* ensure that auth_method is actually valid, aka authn_id is not NULL */
913 }
914
915 /* Report any SSL/GSS details for the session. */
916 if (MyProcPort != NULL)
917 {
919
921 }
922
923 /*
924 * Binary upgrades only allowed super-user connections
925 */
927 {
930 errmsg("must be superuser to connect in binary upgrade mode")));
931 }
932
933 /*
934 * The last few regular connection slots are reserved for superusers and
935 * roles with privileges of pg_use_reserved_connections. We do not apply
936 * these limits to background processes, since they all have their own
937 * pools of PGPROC slots.
938 *
939 * Note: At this point, the new backend has already claimed a proc struct,
940 * so we must check whether the number of free slots is strictly less than
941 * the reserved connection limits.
942 */
946 {
950 errmsg("remaining connection slots are reserved for roles with the %s attribute",
951 "SUPERUSER")));
952
956 errmsg("remaining connection slots are reserved for roles with privileges of the \"%s\" role",
957 "pg_use_reserved_connections")));
958 }
959
960 /* Check replication permissions needed for walsender processes. */
961 if (am_walsender)
962 {
964
968 errmsg("permission denied to start WAL sender"),
969 errdetail("Only roles with the %s attribute may start a WAL sender process.",
970 "REPLICATION")));
971 }
972
973 /*
974 * If this is a plain walsender only supporting physical replication, we
975 * don't want to connect to any particular database. Just finish the
976 * backend startup by processing any options from the startup packet, and
977 * we're done.
978 */
980 {
981 /* process any options passed in the startup packet */
982 if (MyProcPort != NULL)
984
985 /* Apply PostAuthDelay as soon as we've read all options */
986 if (PostAuthDelay > 0)
987 pg_usleep(PostAuthDelay * 1000000L);
988
989 /* initialize client encoding */
991
992 /* fill in the remainder of this entry in the PgBackendStatus array */
994
995 /* close the transaction we started above */
997
998 /* send any WARNINGs we've accumulated during initialization */
1000
1001 return;
1002 }
1003
1004 /*
1005 * Set up the global variables holding database id and default tablespace.
1006 * But note we won't actually try to touch the database just yet.
1007 *
1008 * We take a shortcut in the bootstrap case, otherwise we have to look up
1009 * the db's entry in pg_database.
1010 */
1011 if (bootstrap)
1012 {
1013 dboid = Template1DbOid;
1015 }
1016 else if (in_dbname != NULL)
1017 {
1018 HeapTuple tuple;
1020
1021 tuple = GetDatabaseTuple(in_dbname);
1022 if (!HeapTupleIsValid(tuple))
1023 ereport(FATAL,
1025 errmsg("database \"%s\" does not exist", in_dbname)));
1027 dboid = dbform->oid;
1028 }
1029 else if (!OidIsValid(dboid))
1030 {
1031 /*
1032 * If this is a background worker not bound to any particular
1033 * database, we're done now. Everything that follows only makes sense
1034 * if we are bound to a specific database. We do need to close the
1035 * transaction we started before returning.
1036 */
1037 if (!bootstrap)
1038 {
1041 }
1042 return;
1043 }
1044
1045 /*
1046 * Now, take a writer's lock on the database we are trying to connect to.
1047 * If there is a concurrently running DROP DATABASE on that database, this
1048 * will block us until it finishes (and has committed its update of
1049 * pg_database).
1050 *
1051 * Note that the lock is not held long, only until the end of this startup
1052 * transaction. This is OK since we will advertise our use of the
1053 * database in the ProcArray before dropping the lock (in fact, that's the
1054 * next thing to do). Anyone trying a DROP DATABASE after this point will
1055 * see us in the array once they have the lock. Ordering is important for
1056 * this because we don't want to advertise ourselves as being in this
1057 * database until we have the lock; otherwise we create what amounts to a
1058 * deadlock with CountOtherDBBackends().
1059 *
1060 * Note: use of RowExclusiveLock here is reasonable because we envision
1061 * our session as being a concurrent writer of the database. If we had a
1062 * way of declaring a session as being guaranteed-read-only, we could use
1063 * AccessShareLock for such sessions and thereby not conflict against
1064 * CREATE DATABASE.
1065 */
1066 if (!bootstrap)
1068
1069 /*
1070 * Recheck pg_database to make sure the target database hasn't gone away.
1071 * If there was a concurrent DROP DATABASE, this ensures we will die
1072 * cleanly without creating a mess.
1073 */
1074 if (!bootstrap)
1075 {
1076 HeapTuple tuple;
1078
1079 tuple = GetDatabaseTupleByOid(dboid);
1080 if (HeapTupleIsValid(tuple))
1082
1083 if (!HeapTupleIsValid(tuple) ||
1084 (in_dbname && namestrcmp(&datform->datname, in_dbname)))
1085 {
1086 if (in_dbname)
1087 ereport(FATAL,
1089 errmsg("database \"%s\" does not exist", in_dbname),
1090 errdetail("It seems to have just been dropped or renamed.")));
1091 else
1092 ereport(FATAL,
1094 errmsg("database %u does not exist", dboid)));
1095 }
1096
1097 strlcpy(dbname, NameStr(datform->datname), sizeof(dbname));
1098
1100 {
1101 ereport(FATAL,
1103 errmsg("cannot connect to invalid database \"%s\"", dbname),
1104 errhint("Use DROP DATABASE to drop invalid databases."));
1105 }
1106
1107 MyDatabaseTableSpace = datform->dattablespace;
1108 MyDatabaseHasLoginEventTriggers = datform->dathasloginevt;
1109 /* pass the database name back to the caller */
1110 if (out_dbname)
1112 }
1113
1114 /*
1115 * Now that we rechecked, we are certain to be connected to a database and
1116 * thus can set MyDatabaseId.
1117 *
1118 * It is important that MyDatabaseId only be set once we are sure that the
1119 * target database can no longer be concurrently dropped or renamed. For
1120 * example, without this guarantee, pgstat_update_dbstats() could create
1121 * entries for databases that were just dropped in the pgstat shutdown
1122 * callback, which could confuse other code paths like the autovacuum
1123 * scheduler.
1124 */
1125 MyDatabaseId = dboid;
1126
1127 /*
1128 * Now we can mark our PGPROC entry with the database ID.
1129 *
1130 * We assume this is an atomic store so no lock is needed; though actually
1131 * things would work fine even if it weren't atomic. Anyone searching the
1132 * ProcArray for this database's ID should hold the database lock, so they
1133 * would not be executing concurrently with this store. A process looking
1134 * for another database's ID could in theory see a chance match if it read
1135 * a partially-updated databaseId value; but as long as all such searches
1136 * wait and retry, as in CountOtherDBBackends(), they will certainly see
1137 * the correct value on their next try.
1138 */
1140
1141 /*
1142 * We established a catalog snapshot while reading pg_authid and/or
1143 * pg_database; but until we have set up MyDatabaseId, we won't react to
1144 * incoming sinval messages for unshared catalogs, so we won't realize it
1145 * if the snapshot has been invalidated. Assume it's no good anymore.
1146 */
1148
1149 /*
1150 * Now we should be able to access the database directory safely. Verify
1151 * it's there and looks reasonable.
1152 */
1154
1155 if (!bootstrap)
1156 {
1157 if (access(fullpath, F_OK) == -1)
1158 {
1159 if (errno == ENOENT)
1160 ereport(FATAL,
1162 errmsg("database \"%s\" does not exist",
1163 dbname),
1164 errdetail("The database subdirectory \"%s\" is missing.",
1165 fullpath)));
1166 else
1167 ereport(FATAL,
1169 errmsg("could not access directory \"%s\": %m",
1170 fullpath)));
1171 }
1172
1173 ValidatePgVersion(fullpath);
1174 }
1175
1176 SetDatabasePath(fullpath);
1177 pfree(fullpath);
1178
1179 /*
1180 * It's now possible to do real access to the system catalogs.
1181 *
1182 * Load relcache entries for the system catalogs. This must create at
1183 * least the minimum set of "nailed-in" cache entries.
1184 */
1186
1187 /* set up ACL framework (so CheckMyDatabase can check permissions) */
1189
1190 /*
1191 * Re-read the pg_database row for our database, check permissions and set
1192 * up database-specific GUC settings. We can't do this until all the
1193 * database-access infrastructure is up. (Also, it wants to know if the
1194 * user is a superuser, so the above stuff has to happen first.)
1195 */
1196 if (!bootstrap)
1198 (flags & INIT_PG_OVERRIDE_ALLOW_CONNS) != 0);
1199
1200 /*
1201 * Now process any command-line switches and any additional GUC variable
1202 * settings passed in the startup packet. We couldn't do this before
1203 * because we didn't know if client is a superuser.
1204 */
1205 if (MyProcPort != NULL)
1207
1208 /* Process pg_db_role_setting options */
1210
1211 /* Apply PostAuthDelay as soon as we've read all options */
1212 if (PostAuthDelay > 0)
1213 pg_usleep(PostAuthDelay * 1000000L);
1214
1215 /*
1216 * Initialize various default states that can't be set up until we've
1217 * selected the active user and gotten the right GUC settings.
1218 */
1219
1220 /* set default namespace search path */
1222
1223 /* initialize client encoding */
1225
1226 /* Initialize this backend's session state. */
1228
1229 /*
1230 * If this is an interactive session, load any libraries that should be
1231 * preloaded at backend start. Since those are determined by GUCs, this
1232 * can't happen until GUC settings are complete, but we want it to happen
1233 * during the initial transaction in case anything that requires database
1234 * access needs to be done.
1235 */
1236 if ((flags & INIT_PG_LOAD_SESSION_LIBS) != 0)
1238
1239 /* fill in the remainder of this entry in the PgBackendStatus array */
1240 if (!bootstrap)
1242
1243 /* close the transaction we started above */
1244 if (!bootstrap)
1246
1247 /* send any WARNINGs we've accumulated during initialization */
1249}
void initialize_acl(void)
Definition acl.c:5041
bool has_privs_of_role(Oid member, Oid role)
Definition acl.c:5286
void pgstat_bestart_security(void)
void pgstat_bestart_initial(void)
void pgstat_beinit(void)
void pgstat_bestart_final(void)
#define OidIsValid(objectId)
Definition c.h:800
bool database_is_invalid_form(Form_pg_database datform)
int errcode_for_file_access(void)
Definition elog.c:897
#define DEBUG3
Definition elog.h:28
bool MyDatabaseHasLoginEventTriggers
Definition globals.c:98
int MyCancelKeyLength
Definition globals.c:53
bool IsBinaryUpgrade
Definition globals.c:121
Oid MyDatabaseTableSpace
Definition globals.c:96
uint8 MyCancelKey[MAX_CANCEL_KEY_LENGTH]
Definition globals.c:52
struct Port * MyProcPort
Definition globals.c:51
const char * hba_authname(UserAuth auth_method)
Definition hba.c:3138
static char * username
Definition initdb.c:153
#define INJECTION_POINT(name, arg)
void before_shmem_exit(pg_on_exit_callback function, Datum arg)
Definition ipc.c:344
void LockSharedObject(Oid classid, Oid objid, uint16 objsubid, LOCKMODE lockmode)
Definition lmgr.c:1088
#define RowExclusiveLock
Definition lockdefs.h:38
void InitializeClientEncoding(void)
Definition mbutils.c:290
void pfree(void *pointer)
Definition mcxt.c:1616
#define IsBootstrapProcessingMode()
Definition miscadmin.h:477
#define INIT_PG_LOAD_SESSION_LIBS
Definition miscadmin.h:499
#define AmAutoVacuumWorkerProcess()
Definition miscadmin.h:383
#define AmBackgroundWorkerProcess()
Definition miscadmin.h:384
#define AmLogicalSlotSyncWorkerProcess()
Definition miscadmin.h:386
#define AmAutoVacuumLauncherProcess()
Definition miscadmin.h:382
#define INIT_PG_OVERRIDE_ROLE_LOGIN
Definition miscadmin.h:501
#define INIT_PG_OVERRIDE_ALLOW_CONNS
Definition miscadmin.h:500
void InitializeSessionUserId(const char *rolename, Oid roleid, bool bypass_login_check)
Definition miscinit.c:710
void InitializeSystemUser(const char *authn_id, const char *auth_method)
Definition miscinit.c:874
void InitializeSessionUserIdStandalone(void)
Definition miscinit.c:840
void process_session_preload_libraries(void)
Definition miscinit.c:1865
Oid GetSessionUserId(void)
Definition miscinit.c:508
void SetDatabasePath(const char *path)
Definition miscinit.c:283
ClientConnectionInfo MyClientConnectionInfo
Definition miscinit.c:1018
bool has_rolreplication(Oid roleid)
Definition miscinit.c:688
void ValidatePgVersion(const char *path)
Definition miscinit.c:1718
int namestrcmp(Name name, const char *str)
Definition name.c:247
void InitializeSearchPath(void)
Definition namespace.c:4808
#define NAMEDATALEN
void pgstat_before_server_shutdown(int code, Datum arg)
Definition pgstat.c:572
void InitPlanCache(void)
Definition plancache.c:148
size_t strlcpy(char *dst, const char *src, size_t siz)
Definition strlcpy.c:45
void EnablePortalManager(void)
Definition portalmem.c:104
int PostAuthDelay
Definition postgres.c:101
static void ShutdownPostgres(int code, Datum arg)
Definition postinit.c:1355
static void IdleInTransactionSessionTimeoutHandler(void)
Definition postinit.c:1412
static void LockTimeoutHandler(void)
Definition postinit.c:1394
static void IdleStatsUpdateTimeoutHandler(void)
Definition postinit.c:1428
static void process_settings(Oid databaseid, Oid roleid)
Definition postinit.c:1321
static void IdleSessionTimeoutHandler(void)
Definition postinit.c:1420
static void process_startup_options(Port *port, bool am_superuser)
Definition postinit.c:1256
static void StatementTimeoutHandler(void)
Definition postinit.c:1372
static void EmitConnectionWarnings(void)
Definition postinit.c:1497
static void CheckMyDatabase(const char *name, bool am_superuser, bool override_allow_connections)
Definition postinit.c:331
static bool ThereIsAtLeastOneRole(void)
Definition postinit.c:1447
static void PerformAuthentication(Port *port)
Definition postinit.c:202
static void ClientCheckTimeoutHandler(void)
Definition postinit.c:1436
static HeapTuple GetDatabaseTuple(const char *dbname)
Definition postinit.c:113
static HeapTuple GetDatabaseTupleByOid(Oid dboid)
Definition postinit.c:156
static void TransactionTimeoutHandler(void)
Definition postinit.c:1404
int ReservedConnections
Definition postmaster.c:230
int SuperuserReservedConnections
Definition postmaster.c:229
short access
void ProcSignalInit(const uint8 *cancel_key, int cancel_key_len)
Definition procsignal.c:168
void RelationCacheInitializePhase3(void)
Definition relcache.c:4102
void RelationCacheInitialize(void)
Definition relcache.c:3997
void RelationCacheInitializePhase2(void)
Definition relcache.c:4043
char * GetDatabasePath(Oid dbOid, Oid spcOid)
Definition relpath.c:110
void ReleaseAuxProcessResources(bool isCommit)
Definition resowner.c:1016
ResourceOwner CurrentResourceOwner
Definition resowner.c:173
void CreateAuxProcessResourceOwner(void)
Definition resowner.c:996
void InitializeSession(void)
Definition session.c:54
void pg_usleep(long microsec)
Definition signal.c:53
void SharedInvalBackendInit(bool sendOnly)
Definition sinvaladt.c:272
void InvalidateCatalogSnapshot(void)
Definition snapmgr.c:455
bool HaveNFreeProcs(int n, int *nfree)
Definition proc.c:773
void CheckDeadLockAlert(void)
Definition proc.c:1870
void InitProcessPhase2(void)
Definition proc.c:570
const char * authn_id
Definition libpq-be.h:99
Oid databaseId
Definition proc.h:193
bool superuser(void)
Definition superuser.c:47
void InitCatalogCache(void)
Definition syscache.c:110
TimeoutId RegisterTimeout(TimeoutId id, timeout_handler_proc handler)
Definition timeout.c:505
@ IDLE_SESSION_TIMEOUT
Definition timeout.h:35
@ IDLE_IN_TRANSACTION_SESSION_TIMEOUT
Definition timeout.h:33
@ LOCK_TIMEOUT
Definition timeout.h:28
@ STATEMENT_TIMEOUT
Definition timeout.h:29
@ DEADLOCK_TIMEOUT
Definition timeout.h:27
@ TRANSACTION_TIMEOUT
Definition timeout.h:34
@ IDLE_STATS_UPDATE_TIMEOUT
Definition timeout.h:36
@ CLIENT_CONNECTION_CHECK_TIMEOUT
Definition timeout.h:37
bool am_walsender
Definition walsender.c:123
bool am_db_walsender
Definition walsender.c:126
void StartTransactionCommand(void)
Definition xact.c:3080
int XactIsoLevel
Definition xact.c:80
void SetCurrentStatementStartTimestamp(void)
Definition xact.c:915
void CommitTransactionCommand(void)
Definition xact.c:3178
#define XACT_READ_COMMITTED
Definition xact.h:37
void StartupXLOG(void)
Definition xlog.c:5517
void ShutdownXLOG(int code, Datum arg)
Definition xlog.c:6728

References am_db_walsender, am_walsender, AmAutoVacuumLauncherProcess, AmAutoVacuumWorkerProcess, AmBackgroundWorkerProcess, AmLogicalSlotSyncWorkerProcess, AmRegularBackendProcess, Assert, ClientConnectionInfo::auth_method, ClientConnectionInfo::authn_id, before_shmem_exit(), CheckDeadLockAlert(), CheckMyDatabase(), CLIENT_CONNECTION_CHECK_TIMEOUT, ClientCheckTimeoutHandler(), CommitTransactionCommand(), CreateAuxProcessResourceOwner(), CurrentResourceOwner, database_is_invalid_form(), PGPROC::databaseId, dbname, DEADLOCK_TIMEOUT, DEBUG3, elog, EmitConnectionWarnings(), EnablePortalManager(), ereport, errcode(), errcode_for_file_access(), errdetail(), errhint(), errmsg(), FATAL, fb(), Form_pg_database, GetDatabasePath(), GetDatabaseTuple(), GetDatabaseTupleByOid(), GetSessionUserId(), GETSTRUCT(), GetUserId(), has_privs_of_role(), has_rolreplication(), HaveNFreeProcs(), hba_authname(), HeapTupleIsValid, IDLE_IN_TRANSACTION_SESSION_TIMEOUT, IDLE_SESSION_TIMEOUT, IDLE_STATS_UPDATE_TIMEOUT, IdleInTransactionSessionTimeoutHandler(), IdleSessionTimeoutHandler(), IdleStatsUpdateTimeoutHandler(), INIT_PG_LOAD_SESSION_LIBS, INIT_PG_OVERRIDE_ALLOW_CONNS, INIT_PG_OVERRIDE_ROLE_LOGIN, InitCatalogCache(), initialize_acl(), InitializeClientEncoding(), InitializeSearchPath(), InitializeSession(), InitializeSessionUserId(), InitializeSessionUserIdStandalone(), InitializeSystemUser(), InitPlanCache(), InitProcessPhase2(), INJECTION_POINT, InvalidateCatalogSnapshot(), IsBinaryUpgrade, IsBootstrapProcessingMode, IsUnderPostmaster, LOCK_TIMEOUT, LockSharedObject(), LockTimeoutHandler(), MyCancelKey, MyCancelKeyLength, MyClientConnectionInfo, MyDatabaseHasLoginEventTriggers, MyDatabaseId, MyDatabaseTableSpace, MyProc, MyProcPort, NAMEDATALEN, NameStr, namestrcmp(), OidIsValid, PerformAuthentication(), pfree(), pg_usleep(), pgstat_before_server_shutdown(), pgstat_beinit(), pgstat_bestart_final(), pgstat_bestart_initial(), pgstat_bestart_security(), PostAuthDelay, process_session_preload_libraries(), process_settings(), process_startup_options(), ProcSignalInit(), RegisterTimeout(), RelationCacheInitialize(), RelationCacheInitializePhase2(), RelationCacheInitializePhase3(), ReleaseAuxProcessResources(), ReservedConnections, RowExclusiveLock, SetCurrentStatementStartTimestamp(), SetDatabasePath(), SharedInvalBackendInit(), ShutdownPostgres(), ShutdownXLOG(), StartTransactionCommand(), StartupXLOG(), STATEMENT_TIMEOUT, StatementTimeoutHandler(), strlcpy(), superuser(), SuperuserReservedConnections, ThereIsAtLeastOneRole(), TRANSACTION_TIMEOUT, TransactionTimeoutHandler(), username, ValidatePgVersion(), WARNING, XACT_READ_COMMITTED, and XactIsoLevel.

Referenced by AutoVacLauncherMain(), AutoVacWorkerMain(), BackgroundWorkerInitializeConnection(), BackgroundWorkerInitializeConnectionByOid(), BootstrapModeMain(), PostgresMain(), and ReplSlotSyncWorkerMain().

◆ LockTimeoutHandler()

static void LockTimeoutHandler ( void  )
static

Definition at line 1394 of file postinit.c.

1395{
1396#ifdef HAVE_SETSID
1397 /* try to signal whole process group */
1399#endif
1401}
int MyProcPid
Definition globals.c:47
#define kill(pid, sig)
Definition win32_port.h:490

References fb(), kill, and MyProcPid.

Referenced by InitPostgres().

◆ PerformAuthentication()

static void PerformAuthentication ( Port port)
static

Definition at line 202 of file postinit.c.

203{
204 /* This should be set already, but let's make sure */
205 ClientAuthInProgress = true; /* limit visibility of log messages */
206
207 /*
208 * In EXEC_BACKEND case, we didn't inherit the contents of pg_hba.conf
209 * etcetera from the postmaster, and have to load them ourselves.
210 *
211 * FIXME: [fork/exec] Ugh. Is there a way around this overhead?
212 */
213#ifdef EXEC_BACKEND
214
215 /*
216 * load_hba() and load_ident() want to work within the PostmasterContext,
217 * so create that if it doesn't exist (which it won't). We'll delete it
218 * again later, in PostgresMain.
219 */
220 if (PostmasterContext == NULL)
222 "Postmaster",
224
225 if (!load_hba())
226 {
227 /*
228 * It makes no sense to continue if we fail to load the HBA file,
229 * since there is no way to connect to the database in this case.
230 */
232 /* translator: %s is a configuration file */
233 (errmsg("could not load %s", HbaFileName)));
234 }
235
236 if (!load_ident())
237 {
238 /*
239 * It is ok to continue if we fail to load the IDENT file, although it
240 * means that you cannot log in using any of the authentication
241 * methods that need a user name mapping. load_ident() already logged
242 * the details of error to the log.
243 */
244 }
245#endif
246
247 /* Capture authentication start time for logging */
249
250 /*
251 * Set up a timeout in case a buggy or malicious client fails to respond
252 * during authentication. Since we're inside a transaction and might do
253 * database access, we have to use the statement_timeout infrastructure.
254 */
256
257 /*
258 * Now perform authentication exchange.
259 */
260 set_ps_display("authentication");
261 ClientAuthentication(port); /* might not return, if failure */
262
263 /*
264 * Done with authentication. Disable the timeout, and log if needed.
265 */
267
268 /* Capture authentication end time for logging */
270
272 {
274
276 if (am_walsender)
277 appendStringInfo(&logmsg, _("replication connection authorized: user=%s"),
278 port->user_name);
279 else
280 appendStringInfo(&logmsg, _("connection authorized: user=%s"),
281 port->user_name);
282 if (!am_walsender)
283 appendStringInfo(&logmsg, _(" database=%s"), port->database_name);
284
285 if (port->application_name != NULL)
286 appendStringInfo(&logmsg, _(" application_name=%s"),
287 port->application_name);
288
289#ifdef USE_SSL
290 if (port->ssl_in_use)
291 appendStringInfo(&logmsg, _(" SSL enabled (protocol=%s, cipher=%s, bits=%d)"),
295#endif
296#ifdef ENABLE_GSS
297 if (port->gss)
298 {
299 const char *princ = be_gssapi_get_princ(port);
300
301 if (princ)
303 _(" GSS (authenticated=%s, encrypted=%s, delegated_credentials=%s, principal=%s)"),
304 be_gssapi_get_auth(port) ? _("yes") : _("no"),
305 be_gssapi_get_enc(port) ? _("yes") : _("no"),
306 be_gssapi_get_delegation(port) ? _("yes") : _("no"),
307 princ);
308 else
310 _(" GSS (authenticated=%s, encrypted=%s, delegated_credentials=%s)"),
311 be_gssapi_get_auth(port) ? _("yes") : _("no"),
312 be_gssapi_get_enc(port) ? _("yes") : _("no"),
313 be_gssapi_get_delegation(port) ? _("yes") : _("no"));
314 }
315#endif
316
317 ereport(LOG, errmsg_internal("%s", logmsg.data));
318 pfree(logmsg.data);
319 }
320
321 set_ps_display("startup");
322
323 ClientAuthInProgress = false; /* client_min_messages is active now */
324}
void ClientAuthentication(Port *port)
Definition auth.c:379
TimestampTz GetCurrentTimestamp(void)
Definition timestamp.c:1645
uint32 log_connections
ConnectionTiming conn_timing
@ LOG_CONNECTION_AUTHORIZATION
bool be_gssapi_get_auth(Port *port)
bool be_gssapi_get_enc(Port *port)
const char * be_gssapi_get_princ(Port *port)
bool be_gssapi_get_delegation(Port *port)
const char * be_tls_get_version(Port *port)
int be_tls_get_cipher_bits(Port *port)
const char * be_tls_get_cipher(Port *port)
#define _(x)
Definition elog.c:95
#define LOG
Definition elog.h:31
int int errmsg_internal(const char *fmt,...) pg_attribute_printf(1
char * HbaFileName
Definition guc_tables.c:566
bool load_ident(void)
Definition hba.c:3036
bool load_hba(void)
Definition hba.c:2642
MemoryContext TopMemoryContext
Definition mcxt.c:166
MemoryContext PostmasterContext
Definition mcxt.c:168
#define AllocSetContextCreate
Definition memutils.h:129
#define ALLOCSET_DEFAULT_SIZES
Definition memutils.h:160
static int port
Definition pg_regress.c:115
bool ClientAuthInProgress
Definition postmaster.c:372
int AuthenticationTimeout
Definition postmaster.c:241
static void set_ps_display(const char *activity)
Definition ps_status.h:40
void appendStringInfo(StringInfo str, const char *fmt,...)
Definition stringinfo.c:145
void initStringInfo(StringInfo str)
Definition stringinfo.c:97
TimestampTz auth_start
void enable_timeout_after(TimeoutId id, int delay_ms)
Definition timeout.c:560
void disable_timeout(TimeoutId id, bool keep_indicator)
Definition timeout.c:685

References _, ALLOCSET_DEFAULT_SIZES, AllocSetContextCreate, am_walsender, appendStringInfo(), ConnectionTiming::auth_end, ConnectionTiming::auth_start, AuthenticationTimeout, be_gssapi_get_auth(), be_gssapi_get_delegation(), be_gssapi_get_enc(), be_gssapi_get_princ(), be_tls_get_cipher(), be_tls_get_cipher_bits(), be_tls_get_version(), ClientAuthentication(), ClientAuthInProgress, conn_timing, disable_timeout(), enable_timeout_after(), ereport, errmsg(), errmsg_internal(), FATAL, fb(), GetCurrentTimestamp(), HbaFileName, initStringInfo(), load_hba(), load_ident(), LOG, LOG_CONNECTION_AUTHORIZATION, log_connections, pfree(), port, PostmasterContext, set_ps_display(), STATEMENT_TIMEOUT, and TopMemoryContext.

Referenced by InitPostgres().

◆ pg_split_opts()

void pg_split_opts ( char **  argv,
int argcp,
const char optstr 
)

Definition at line 500 of file postinit.c.

501{
503
504 initStringInfo(&s);
505
506 while (*optstr)
507 {
508 bool last_was_escape = false;
509
510 resetStringInfo(&s);
511
512 /* skip over leading space */
513 while (isspace((unsigned char) *optstr))
514 optstr++;
515
516 if (*optstr == '\0')
517 break;
518
519 /*
520 * Parse a single option, stopping at the first space, unless it's
521 * escaped.
522 */
523 while (*optstr)
524 {
525 if (isspace((unsigned char) *optstr) && !last_was_escape)
526 break;
527
528 if (!last_was_escape && *optstr == '\\')
529 last_was_escape = true;
530 else
531 {
532 last_was_escape = false;
534 }
535
536 optstr++;
537 }
538
539 /* now store the option in the next argv[] position */
540 argv[(*argcp)++] = pstrdup(s.data);
541 }
542
543 pfree(s.data);
544}
char * pstrdup(const char *in)
Definition mcxt.c:1781
void resetStringInfo(StringInfo str)
Definition stringinfo.c:126
void appendStringInfoChar(StringInfo str, char ch)
Definition stringinfo.c:242

References appendStringInfoChar(), StringInfoData::data, fb(), initStringInfo(), pfree(), pstrdup(), and resetStringInfo().

Referenced by process_startup_options().

◆ process_settings()

static void process_settings ( Oid  databaseid,
Oid  roleid 
)
static

Definition at line 1321 of file postinit.c.

1322{
1324 Snapshot snapshot;
1325
1326 if (!IsUnderPostmaster)
1327 return;
1328
1330
1331 /* read all the settings under the same snapshot for efficiency */
1333
1334 /* Later settings are ignored if set earlier. */
1336 ApplySetting(snapshot, InvalidOid, roleid, relsetting, PGC_S_USER);
1339
1340 UnregisterSnapshot(snapshot);
1342}
@ PGC_S_GLOBAL
Definition guc.h:118
@ PGC_S_DATABASE
Definition guc.h:119
@ PGC_S_DATABASE_USER
Definition guc.h:121
@ PGC_S_USER
Definition guc.h:120
void ApplySetting(Snapshot snapshot, Oid databaseid, Oid roleid, Relation relsetting, GucSource source)
#define InvalidOid
Snapshot GetCatalogSnapshot(Oid relid)
Definition snapmgr.c:385
void UnregisterSnapshot(Snapshot snapshot)
Definition snapmgr.c:866
Snapshot RegisterSnapshot(Snapshot snapshot)
Definition snapmgr.c:824

References AccessShareLock, ApplySetting(), fb(), GetCatalogSnapshot(), InvalidOid, IsUnderPostmaster, PGC_S_DATABASE, PGC_S_DATABASE_USER, PGC_S_GLOBAL, PGC_S_USER, RegisterSnapshot(), table_close(), table_open(), and UnregisterSnapshot().

Referenced by InitPostgres().

◆ process_startup_options()

static void process_startup_options ( Port port,
bool  am_superuser 
)
static

Definition at line 1256 of file postinit.c.

1257{
1260
1262
1263 /*
1264 * First process any command-line switches that were included in the
1265 * startup packet, if we are in a regular backend.
1266 */
1267 if (port->cmdline_options != NULL)
1268 {
1269 /*
1270 * The maximum possible number of commandline arguments that could
1271 * come from port->cmdline_options is (strlen + 1) / 2; see
1272 * pg_split_opts().
1273 */
1274 char **av;
1275 int maxac;
1276 int ac;
1277
1278 maxac = 2 + (strlen(port->cmdline_options) + 1) / 2;
1279
1280 av = palloc_array(char *, maxac);
1281 ac = 0;
1282
1283 av[ac++] = "postgres";
1284
1285 pg_split_opts(av, &ac, port->cmdline_options);
1286
1287 av[ac] = NULL;
1288
1289 Assert(ac < maxac);
1290
1292 }
1293
1294 /*
1295 * Process any additional GUC variable settings passed in startup packet.
1296 * These are handled exactly like command-line variables.
1297 */
1298 gucopts = list_head(port->guc_options);
1299 while (gucopts)
1300 {
1301 char *name;
1302 char *value;
1303
1304 name = lfirst(gucopts);
1305 gucopts = lnext(port->guc_options, gucopts);
1306
1307 value = lfirst(gucopts);
1308 gucopts = lnext(port->guc_options, gucopts);
1309
1311 }
1312}
#define palloc_array(type, count)
Definition fe_memutils.h:76
@ PGC_S_CLIENT
Definition guc.h:122
GucContext
Definition guc.h:72
@ PGC_SU_BACKEND
Definition guc.h:76
static struct @174 value
static ListCell * list_head(const List *l)
Definition pg_list.h:128
static ListCell * lnext(const List *l, const ListCell *c)
Definition pg_list.h:343
void process_postgres_switches(int argc, char *argv[], GucContext ctx, const char **dbname)
Definition postgres.c:3833
void pg_split_opts(char **argv, int *argcp, const char *optstr)
Definition postinit.c:500
struct @10::@11 av[32]

References Assert, av, fb(), lfirst, list_head(), lnext(), name, palloc_array, pg_split_opts(), PGC_BACKEND, PGC_S_CLIENT, PGC_SU_BACKEND, port, process_postgres_switches(), SetConfigOption(), and value.

Referenced by InitPostgres().

◆ ShutdownPostgres()

static void ShutdownPostgres ( int  code,
Datum  arg 
)
static

Definition at line 1355 of file postinit.c.

1356{
1357 /* Make sure we've killed any active transaction */
1359
1360 /*
1361 * User locks are not released by transaction end, so be sure to release
1362 * them explicitly.
1363 */
1365}
void LockReleaseAll(LOCKMETHODID lockmethodid, bool allLocks)
Definition lock.c:2307
#define USER_LOCKMETHOD
Definition lock.h:128
void AbortOutOfAnyTransaction(void)
Definition xact.c:4884

References AbortOutOfAnyTransaction(), LockReleaseAll(), and USER_LOCKMETHOD.

Referenced by InitPostgres().

◆ StatementTimeoutHandler()

static void StatementTimeoutHandler ( void  )
static

Definition at line 1372 of file postinit.c.

1373{
1374 int sig = SIGINT;
1375
1376 /*
1377 * During authentication the timeout is used to deal with
1378 * authentication_timeout - we want to quit in response to such timeouts.
1379 */
1381 sig = SIGTERM;
1382
1383#ifdef HAVE_SETSID
1384 /* try to signal whole process group */
1385 kill(-MyProcPid, sig);
1386#endif
1387 kill(MyProcPid, sig);
1388}
static int sig
Definition pg_ctl.c:81

References ClientAuthInProgress, fb(), kill, MyProcPid, and sig.

Referenced by InitPostgres().

◆ StoreConnectionWarning()

void StoreConnectionWarning ( char msg,
char detail 
)

Definition at line 1472 of file postinit.c.

1473{
1474 MemoryContext oldcontext;
1475
1476 Assert(msg);
1477 Assert(detail);
1478
1480 elog(ERROR, "StoreConnectionWarning() called after EmitConnectionWarnings()");
1481
1483
1486
1487 MemoryContextSwitchTo(oldcontext);
1488}
List * lappend(List *list, void *datum)
Definition list.c:339
static MemoryContext MemoryContextSwitchTo(MemoryContext context)
Definition palloc.h:124

References Assert, ConnectionWarningDetails, ConnectionWarningMessages, ConnectionWarningsEmitted, elog, ERROR, lappend(), MemoryContextSwitchTo(), and TopMemoryContext.

Referenced by get_role_password(), and md5_crypt_verify().

◆ ThereIsAtLeastOneRole()

static bool ThereIsAtLeastOneRole ( void  )
static

Definition at line 1447 of file postinit.c.

1448{
1450 TableScanDesc scan;
1451 bool result;
1452
1454
1456 result = (heap_getnext(scan, ForwardScanDirection) != NULL);
1457
1458 table_endscan(scan);
1460
1461 return result;
1462}
HeapTuple heap_getnext(TableScanDesc sscan, ScanDirection direction)
Definition heapam.c:1410
@ ForwardScanDirection
Definition sdir.h:28
TableScanDesc table_beginscan_catalog(Relation relation, int nkeys, ScanKeyData *key)
Definition tableam.c:113
static void table_endscan(TableScanDesc scan)
Definition tableam.h:1004

References AccessShareLock, fb(), ForwardScanDirection, heap_getnext(), table_beginscan_catalog(), table_close(), table_endscan(), and table_open().

Referenced by InitPostgres().

◆ TransactionTimeoutHandler()

static void TransactionTimeoutHandler ( void  )
static

Definition at line 1404 of file postinit.c.

1405{
1407 InterruptPending = true;
1409}
volatile sig_atomic_t TransactionTimeoutPending
Definition globals.c:38

References InterruptPending, MyLatch, SetLatch(), and TransactionTimeoutPending.

Referenced by InitPostgres().

Variable Documentation

◆ ConnectionWarningDetails

List* ConnectionWarningDetails
static

Definition at line 78 of file postinit.c.

Referenced by EmitConnectionWarnings(), and StoreConnectionWarning().

◆ ConnectionWarningMessages

List* ConnectionWarningMessages
static

Definition at line 77 of file postinit.c.

Referenced by EmitConnectionWarnings(), and StoreConnectionWarning().

◆ ConnectionWarningsEmitted

bool ConnectionWarningsEmitted
static

Definition at line 74 of file postinit.c.

Referenced by EmitConnectionWarnings(), and StoreConnectionWarning().