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 "port/pg_bitutils.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 616 of file postinit.c.

617{
618 Assert(MyProc != NULL);
619
620 /*
621 * Initialize our input/output/debugging file descriptors.
622 */
624
625 /*
626 * Initialize file access. Done early so other subsystems can access
627 * files.
628 */
630
631 /*
632 * Initialize statistics reporting. This needs to happen early to ensure
633 * that pgstat's shutdown callback runs after the shutdown callbacks of
634 * all subsystems that can produce stats (like e.g. transaction commits
635 * can).
636 */
638
639 /*
640 * Initialize AIO before infrastructure that might need to actually
641 * execute AIO.
642 */
644
645 /* Do local initialization of storage and buffer managers */
646 InitSync();
647 smgrinit();
649
650 /*
651 * Initialize temporary file access after pgstat, so that the temporary
652 * file shutdown hook can report temporary file statistics.
653 */
655
656 /*
657 * Initialize local buffers for WAL record construction, in case we ever
658 * try to insert XLOG.
659 */
661
662 /* Initialize lock manager's local structs */
664
665 /* Initialize logical info WAL logging state */
667
668 /*
669 * Initialize replication slots after pgstat. The exit hook might need to
670 * drop ephemeral slots, which in turn triggers stats reporting.
671 */
673}
void pgaio_init_backend(void)
Definition aio_init.c:218
void InitBufferManagerAccess(void)
Definition bufmgr.c:4127
#define Assert(condition)
Definition c.h:945
void DebugFileOpen(void)
Definition elog.c:2306
void InitFileAccess(void)
Definition fd.c:904
void InitTemporaryFileAccess(void)
Definition fd.c:934
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:243
void smgrinit(void)
Definition smgr.c:188
PGPROC * MyProc
Definition proc.c:68
void InitSync(void)
Definition sync.c:125
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 332 of file postinit.c.

333{
336 Datum datum;
337 bool isnull;
338 char *collate;
339 char *ctype;
340
341 /* Fetch our pg_database row normally, via syscache */
343 if (!HeapTupleIsValid(tup))
344 elog(ERROR, "cache lookup failed for database %u", MyDatabaseId);
346
347 /* This recheck is strictly paranoia */
348 if (strcmp(name, NameStr(dbform->datname)) != 0)
351 errmsg("database \"%s\" has disappeared from pg_database",
352 name),
353 errdetail("Database OID %u now seems to belong to \"%s\".",
354 MyDatabaseId, NameStr(dbform->datname))));
355
356 /*
357 * Check permissions to connect to the database.
358 *
359 * These checks are not enforced when in standalone mode, so that there is
360 * a way to recover from disabling all access to all databases, for
361 * example "UPDATE pg_database SET datallowconn = false;".
362 */
364 {
365 /*
366 * Check that the database is currently allowing connections.
367 * (Background processes can override this test and the next one by
368 * setting override_allow_connections.)
369 */
370 if (!dbform->datallowconn && !override_allow_connections)
373 errmsg("database \"%s\" is not currently accepting connections",
374 name)));
375
376 /*
377 * Check privilege to connect to the database. (The am_superuser test
378 * is redundant, but since we have the flag, might as well check it
379 * and save a few cycles.)
380 */
386 errmsg("permission denied for database \"%s\"", name),
387 errdetail("User does not have CONNECT privilege.")));
388
389 /*
390 * Check connection limit for this database. We enforce the limit
391 * only for regular backends, since other process types have their own
392 * PGPROC pools.
393 *
394 * There is a race condition here --- we create our PGPROC before
395 * checking for other PGPROCs. If two backends did this at about the
396 * same time, they might both think they were over the limit, while
397 * ideally one should succeed and one fail. Getting that to work
398 * exactly seems more trouble than it is worth, however; instead we
399 * just document that the connection limit is approximate.
400 */
401 if (dbform->datconnlimit >= 0 &&
403 !am_superuser &&
404 CountDBConnections(MyDatabaseId) > dbform->datconnlimit)
407 errmsg("too many connections for database \"%s\"",
408 name)));
409 }
410
411 /*
412 * OK, we're golden. Next to-do item is to save the encoding info out of
413 * the pg_database tuple.
414 */
415 SetDatabaseEncoding(dbform->encoding);
416 /* Record it as a GUC internal option, too */
417 SetConfigOption("server_encoding", GetDatabaseEncodingName(),
419 /* If we have no other source of client_encoding, use server encoding */
420 SetConfigOption("client_encoding", GetDatabaseEncodingName(),
422
423 /* assign locale variables */
425 collate = TextDatumGetCString(datum);
427 ctype = TextDatumGetCString(datum);
428
429 /*
430 * Historically, we set LC_COLLATE from datcollate, as well. That's no
431 * longer necessary because all collation behavior is handled through
432 * pg_locale_t.
433 */
434
435 if (pg_perm_setlocale(LC_CTYPE, ctype) == NULL)
437 (errmsg("database locale is incompatible with operating system"),
438 errdetail("The database was initialized with LC_CTYPE \"%s\", "
439 " which is not recognized by setlocale().", ctype),
440 errhint("Recreate the database with another locale or install the missing locale.")));
441
443
444 /*
445 * Check collation version. See similar code in
446 * pg_newlocale_from_collation(). Note that here we warn instead of error
447 * in any case, so that we don't prevent connecting.
448 */
450 &isnull);
451 if (!isnull)
452 {
453 char *actual_versionstr;
454 char *collversionstr;
455 char *locale;
456
458
459 if (dbform->datlocprovider == COLLPROVIDER_LIBC)
460 locale = collate;
461 else
462 {
464 locale = TextDatumGetCString(datum);
465 }
466
467 actual_versionstr = get_collation_actual_version(dbform->datlocprovider, locale);
469 /* should not happen */
471 "database \"%s\" has no actual collation version, but a version was recorded",
472 name);
475 (errmsg("database \"%s\" has a collation version mismatch",
476 name),
477 errdetail("The database was created using collation version %s, "
478 "but the operating system provides version %s.",
480 errhint("Rebuild all objects in this database that use the default collation and run "
481 "ALTER DATABASE %s REFRESH COLLATION VERSION, "
482 "or build PostgreSQL with the right library version.",
484 }
485
487}
@ ACLCHECK_OK
Definition acl.h:184
AclResult object_aclcheck(Oid classid, Oid objectid, Oid roleid, AclMode mode)
Definition aclchk.c:3879
#define TextDatumGetCString(d)
Definition builtins.h:99
#define NameStr(name)
Definition c.h:837
int errcode(int sqlerrcode)
Definition elog.c:874
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:4228
@ 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:470
static char * errmsg
#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:252
uint64_t Datum
Definition postgres.h:70
int CountDBConnections(Oid databaseid)
Definition procarray.c:3658
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 1437 of file postinit.c.

1438{
1440 InterruptPending = true;
1442}
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 1498 of file postinit.c.

1499{
1502
1504 elog(ERROR, "EmitConnectionWarnings() called more than once");
1505 else
1507
1510 {
1512 (errmsg("%s", (char *) lfirst(lc_msg)),
1513 errdetail("%s", (char *) lfirst(lc_detail))));
1514 }
1515
1518}
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:79
static bool ConnectionWarningsEmitted
Definition postinit.c:75
static List * ConnectionWarningMessages
Definition postinit.c:78

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 114 of file postinit.c.

115{
116 HeapTuple tuple;
117 Relation relation;
118 SysScanDesc scan;
119 ScanKeyData key[1];
120
121 /*
122 * form a scan key
123 */
124 ScanKeyInit(&key[0],
128
129 /*
130 * Open pg_database and fetch a tuple. Force heap scan if we haven't yet
131 * built the critical shared relcache entries (i.e., we're starting up
132 * without a shared relcache cache file).
133 */
137 NULL,
138 1, key);
139
140 tuple = systable_getnext(scan);
141
142 /* Must copy tuple before releasing buffer */
143 if (HeapTupleIsValid(tuple))
144 tuple = heap_copytuple(tuple);
145
146 /* all done */
147 systable_endscan(scan);
148 table_close(relation, AccessShareLock);
149
150 return tuple;
151}
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:698
#define AccessShareLock
Definition lockdefs.h:36
static Datum CStringGetDatum(const char *X)
Definition postgres.h:370
bool criticalSharedRelcachesBuilt
Definition relcache.c:147
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 157 of file postinit.c.

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

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 1413 of file postinit.c.

1414{
1416 InterruptPending = true;
1418}
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 1421 of file postinit.c.

1422{
1424 InterruptPending = true;
1426}
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 1429 of file postinit.c.

1430{
1432 InterruptPending = true;
1434}
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 584 of file postinit.c.

585{
586 /* Should be initialized only once. */
588
589 /*
590 * Based on the max_locks_per_transaction GUC, as that's a good indicator
591 * of the expected number of locks, figure out the value for
592 * FastPathLockGroupsPerBackend. This must be a power-of-two. We cap the
593 * value at FP_LOCK_GROUPS_PER_BACKEND_MAX and insist the value is at
594 * least 1.
595 *
596 * The default max_locks_per_transaction = 64 means 4 groups by default.
597 */
601
602 /* Validate we did get a power-of-two */
605}
#define Min(x, y)
Definition c.h:1093
#define Max(x, y)
Definition c.h:1087
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 559 of file postinit.c.

560{
561 Assert(MaxBackends == 0);
562
563 /* Note that this does not include "auxiliary" processes */
566
570 errmsg("too many server processes configured"),
571 errdetail("\"max_connections\" (%d) plus \"autovacuum_worker_slots\" (%d) plus \"max_worker_processes\" (%d) plus \"max_wal_senders\" (%d) must be less than %d.",
575}
int autovacuum_worker_slots
Definition autovacuum.c:120
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:511
#define MAX_BACKENDS
Definition procnumber.h:39
int max_wal_senders
Definition walsender.c:130

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 719 of file postinit.c.

723{
725 bool am_superuser;
726 char *fullpath;
727 char dbname[NAMEDATALEN];
728 int nfree = 0;
729
730 elog(DEBUG3, "InitPostgres");
731
732 /*
733 * Add my PGPROC struct to the ProcArray.
734 *
735 * Once I have done this, I am visible to other backends!
736 */
738
739 /* Initialize status reporting */
741
742 /*
743 * And initialize an entry in the PgBackendStatus array. That way, if
744 * LWLocks or third-party authentication should happen to hang, it is
745 * possible to retrieve some information about what is going on.
746 */
747 if (!bootstrap)
748 {
750 INJECTION_POINT("init-pre-auth", NULL);
751 }
752
753 /*
754 * Initialize my entry in the shared-invalidation manager's array of
755 * per-backend data.
756 */
758
760
761 /*
762 * Also set up timeout handlers needed for backend operation. We need
763 * these in every case except bootstrap.
764 */
765 if (!bootstrap)
766 {
777 }
778
779 /*
780 * If this is either a bootstrap process or a standalone backend, start up
781 * the XLOG machinery, and register to have it closed down at exit. In
782 * other cases, the startup process is responsible for starting up the
783 * XLOG machinery, and the checkpointer for closing it down.
784 */
786 {
787 /*
788 * We don't yet have an aux-process resource owner, but StartupXLOG
789 * and ShutdownXLOG will need one. Hence, create said resource owner
790 * (and register a callback to clean it up after ShutdownXLOG runs).
791 */
793
794 StartupXLOG();
795 /* Release (and warn about) any buffer pins leaked in StartupXLOG */
797 /* Reset CurrentResourceOwner to nothing for the moment */
799
800 /*
801 * Use before_shmem_exit() so that ShutdownXLOG() can rely on DSM
802 * segments etc to work (which in turn is required for pgstats).
803 */
806 }
807
808 /*
809 * Initialize the relation cache and the system catalog caches. Note that
810 * no catalog access happens here; we only set up the hashtable structure.
811 * We must do this before starting a transaction because transaction abort
812 * would try to touch these hashtables.
813 */
817
818 /* Initialize portal manager */
820
821 /*
822 * Load relcache entries for the shared system catalogs. This must create
823 * at least entries for pg_database and catalogs used for authentication.
824 */
826
827 /*
828 * Set up process-exit callback to do pre-shutdown cleanup. This is one
829 * of the first before_shmem_exit callbacks we register; thus, this will
830 * be one of the last things we do before low-level modules like the
831 * buffer manager begin to close down. We need to have this in place
832 * before we begin our first transaction --- if we fail during the
833 * initialization transaction, as is entirely possible, we need the
834 * AbortTransaction call to clean up.
835 */
837
838 /* The autovacuum launcher is done here */
840 {
841 /* fill in the remainder of this entry in the PgBackendStatus array */
843
844 return;
845 }
846
847 /*
848 * Start a new transaction here before first access to db.
849 */
850 if (!bootstrap)
851 {
852 /* statement_timestamp must be set for timeouts to work correctly */
855
856 /*
857 * transaction_isolation will have been set to the default by the
858 * above. If the default is "serializable", and we are in hot
859 * standby, we will fail if we don't change it to something lower.
860 * Fortunately, "read committed" is plenty good enough.
861 */
863 }
864
865 /*
866 * Perform client authentication if necessary, then figure out our
867 * postgres user ID, and see if we are a superuser.
868 *
869 * In standalone mode, autovacuum worker processes and slot sync worker
870 * process, we use a fixed ID, otherwise we figure it out from the
871 * authenticated user name.
872 */
874 {
876 am_superuser = true;
877 }
878 else if (!IsUnderPostmaster)
879 {
881 am_superuser = true;
885 errmsg("no roles are defined in this database system"),
886 errhint("You should immediately run CREATE USER \"%s\" SUPERUSER;.",
887 username != NULL ? username : "postgres")));
888 }
889 else if (AmBackgroundWorkerProcess())
890 {
891 if (username == NULL && !OidIsValid(useroid))
892 {
894 am_superuser = true;
895 }
896 else
897 {
899 (flags & INIT_PG_OVERRIDE_ROLE_LOGIN) != 0);
901 }
902 }
903 else
904 {
905 /* normal multiuser case */
909 /* ensure that auth_method is actually valid, aka authn_id is not NULL */
914 }
915
916 /* Report any SSL/GSS details for the session. */
917 if (MyProcPort != NULL)
918 {
920
922 }
923
924 /*
925 * Binary upgrades only allowed super-user connections
926 */
928 {
931 errmsg("must be superuser to connect in binary upgrade mode")));
932 }
933
934 /*
935 * The last few regular connection slots are reserved for superusers and
936 * roles with privileges of pg_use_reserved_connections. We do not apply
937 * these limits to background processes, since they all have their own
938 * pools of PGPROC slots.
939 *
940 * Note: At this point, the new backend has already claimed a proc struct,
941 * so we must check whether the number of free slots is strictly less than
942 * the reserved connection limits.
943 */
947 {
951 errmsg("remaining connection slots are reserved for roles with the %s attribute",
952 "SUPERUSER")));
953
957 errmsg("remaining connection slots are reserved for roles with privileges of the \"%s\" role",
958 "pg_use_reserved_connections")));
959 }
960
961 /* Check replication permissions needed for walsender processes. */
962 if (am_walsender)
963 {
965
969 errmsg("permission denied to start WAL sender"),
970 errdetail("Only roles with the %s attribute may start a WAL sender process.",
971 "REPLICATION")));
972 }
973
974 /*
975 * If this is a plain walsender only supporting physical replication, we
976 * don't want to connect to any particular database. Just finish the
977 * backend startup by processing any options from the startup packet, and
978 * we're done.
979 */
981 {
982 /* process any options passed in the startup packet */
983 if (MyProcPort != NULL)
985
986 /* Apply PostAuthDelay as soon as we've read all options */
987 if (PostAuthDelay > 0)
988 pg_usleep(PostAuthDelay * 1000000L);
989
990 /* initialize client encoding */
992
993 /* fill in the remainder of this entry in the PgBackendStatus array */
995
996 /* close the transaction we started above */
998
999 /* send any WARNINGs we've accumulated during initialization */
1001
1002 return;
1003 }
1004
1005 /*
1006 * Set up the global variables holding database id and default tablespace.
1007 * But note we won't actually try to touch the database just yet.
1008 *
1009 * We take a shortcut in the bootstrap case, otherwise we have to look up
1010 * the db's entry in pg_database.
1011 */
1012 if (bootstrap)
1013 {
1014 dboid = Template1DbOid;
1016 }
1017 else if (in_dbname != NULL)
1018 {
1019 HeapTuple tuple;
1021
1022 tuple = GetDatabaseTuple(in_dbname);
1023 if (!HeapTupleIsValid(tuple))
1024 ereport(FATAL,
1026 errmsg("database \"%s\" does not exist", in_dbname)));
1028 dboid = dbform->oid;
1029 }
1030 else if (!OidIsValid(dboid))
1031 {
1032 /*
1033 * If this is a background worker not bound to any particular
1034 * database, we're done now. Everything that follows only makes sense
1035 * if we are bound to a specific database. We do need to close the
1036 * transaction we started before returning.
1037 */
1038 if (!bootstrap)
1039 {
1042 }
1043 return;
1044 }
1045
1046 /*
1047 * Now, take a writer's lock on the database we are trying to connect to.
1048 * If there is a concurrently running DROP DATABASE on that database, this
1049 * will block us until it finishes (and has committed its update of
1050 * pg_database).
1051 *
1052 * Note that the lock is not held long, only until the end of this startup
1053 * transaction. This is OK since we will advertise our use of the
1054 * database in the ProcArray before dropping the lock (in fact, that's the
1055 * next thing to do). Anyone trying a DROP DATABASE after this point will
1056 * see us in the array once they have the lock. Ordering is important for
1057 * this because we don't want to advertise ourselves as being in this
1058 * database until we have the lock; otherwise we create what amounts to a
1059 * deadlock with CountOtherDBBackends().
1060 *
1061 * Note: use of RowExclusiveLock here is reasonable because we envision
1062 * our session as being a concurrent writer of the database. If we had a
1063 * way of declaring a session as being guaranteed-read-only, we could use
1064 * AccessShareLock for such sessions and thereby not conflict against
1065 * CREATE DATABASE.
1066 */
1067 if (!bootstrap)
1069
1070 /*
1071 * Recheck pg_database to make sure the target database hasn't gone away.
1072 * If there was a concurrent DROP DATABASE, this ensures we will die
1073 * cleanly without creating a mess.
1074 */
1075 if (!bootstrap)
1076 {
1077 HeapTuple tuple;
1079
1080 tuple = GetDatabaseTupleByOid(dboid);
1081 if (HeapTupleIsValid(tuple))
1083
1084 if (!HeapTupleIsValid(tuple) ||
1085 (in_dbname && namestrcmp(&datform->datname, in_dbname)))
1086 {
1087 if (in_dbname)
1088 ereport(FATAL,
1090 errmsg("database \"%s\" does not exist", in_dbname),
1091 errdetail("It seems to have just been dropped or renamed.")));
1092 else
1093 ereport(FATAL,
1095 errmsg("database %u does not exist", dboid)));
1096 }
1097
1098 strlcpy(dbname, NameStr(datform->datname), sizeof(dbname));
1099
1101 {
1102 ereport(FATAL,
1104 errmsg("cannot connect to invalid database \"%s\"", dbname),
1105 errhint("Use DROP DATABASE to drop invalid databases."));
1106 }
1107
1108 MyDatabaseTableSpace = datform->dattablespace;
1109 MyDatabaseHasLoginEventTriggers = datform->dathasloginevt;
1110 /* pass the database name back to the caller */
1111 if (out_dbname)
1113 }
1114
1115 /*
1116 * Now that we rechecked, we are certain to be connected to a database and
1117 * thus can set MyDatabaseId.
1118 *
1119 * It is important that MyDatabaseId only be set once we are sure that the
1120 * target database can no longer be concurrently dropped or renamed. For
1121 * example, without this guarantee, pgstat_update_dbstats() could create
1122 * entries for databases that were just dropped in the pgstat shutdown
1123 * callback, which could confuse other code paths like the autovacuum
1124 * scheduler.
1125 */
1126 MyDatabaseId = dboid;
1127
1128 /*
1129 * Now we can mark our PGPROC entry with the database ID.
1130 *
1131 * We assume this is an atomic store so no lock is needed; though actually
1132 * things would work fine even if it weren't atomic. Anyone searching the
1133 * ProcArray for this database's ID should hold the database lock, so they
1134 * would not be executing concurrently with this store. A process looking
1135 * for another database's ID could in theory see a chance match if it read
1136 * a partially-updated databaseId value; but as long as all such searches
1137 * wait and retry, as in CountOtherDBBackends(), they will certainly see
1138 * the correct value on their next try.
1139 */
1141
1142 /*
1143 * We established a catalog snapshot while reading pg_authid and/or
1144 * pg_database; but until we have set up MyDatabaseId, we won't react to
1145 * incoming sinval messages for unshared catalogs, so we won't realize it
1146 * if the snapshot has been invalidated. Assume it's no good anymore.
1147 */
1149
1150 /*
1151 * Now we should be able to access the database directory safely. Verify
1152 * it's there and looks reasonable.
1153 */
1155
1156 if (!bootstrap)
1157 {
1158 if (access(fullpath, F_OK) == -1)
1159 {
1160 if (errno == ENOENT)
1161 ereport(FATAL,
1163 errmsg("database \"%s\" does not exist",
1164 dbname),
1165 errdetail("The database subdirectory \"%s\" is missing.",
1166 fullpath)));
1167 else
1168 ereport(FATAL,
1170 errmsg("could not access directory \"%s\": %m",
1171 fullpath)));
1172 }
1173
1174 ValidatePgVersion(fullpath);
1175 }
1176
1177 SetDatabasePath(fullpath);
1178 pfree(fullpath);
1179
1180 /*
1181 * It's now possible to do real access to the system catalogs.
1182 *
1183 * Load relcache entries for the system catalogs. This must create at
1184 * least the minimum set of "nailed-in" cache entries.
1185 */
1187
1188 /* set up ACL framework (so CheckMyDatabase can check permissions) */
1190
1191 /*
1192 * Re-read the pg_database row for our database, check permissions and set
1193 * up database-specific GUC settings. We can't do this until all the
1194 * database-access infrastructure is up. (Also, it wants to know if the
1195 * user is a superuser, so the above stuff has to happen first.)
1196 */
1197 if (!bootstrap)
1199 (flags & INIT_PG_OVERRIDE_ALLOW_CONNS) != 0);
1200
1201 /*
1202 * Now process any command-line switches and any additional GUC variable
1203 * settings passed in the startup packet. We couldn't do this before
1204 * because we didn't know if client is a superuser.
1205 */
1206 if (MyProcPort != NULL)
1208
1209 /* Process pg_db_role_setting options */
1211
1212 /* Apply PostAuthDelay as soon as we've read all options */
1213 if (PostAuthDelay > 0)
1214 pg_usleep(PostAuthDelay * 1000000L);
1215
1216 /*
1217 * Initialize various default states that can't be set up until we've
1218 * selected the active user and gotten the right GUC settings.
1219 */
1220
1221 /* set default namespace search path */
1223
1224 /* initialize client encoding */
1226
1227 /* Initialize this backend's session state. */
1229
1230 /*
1231 * If this is an interactive session, load any libraries that should be
1232 * preloaded at backend start. Since those are determined by GUCs, this
1233 * can't happen until GUC settings are complete, but we want it to happen
1234 * during the initial transaction in case anything that requires database
1235 * access needs to be done.
1236 */
1237 if ((flags & INIT_PG_LOAD_SESSION_LIBS) != 0)
1239
1240 /* fill in the remainder of this entry in the PgBackendStatus array */
1241 if (!bootstrap)
1243
1244 /* close the transaction we started above */
1245 if (!bootstrap)
1247
1248 /* send any WARNINGs we've accumulated during initialization */
1250}
void initialize_acl(void)
Definition acl.c:5069
bool has_privs_of_role(Oid member, Oid role)
Definition acl.c:5314
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:860
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:711
void InitializeSystemUser(const char *authn_id, const char *auth_method)
Definition miscinit.c:875
void InitializeSessionUserIdStandalone(void)
Definition miscinit.c:841
void process_session_preload_libraries(void)
Definition miscinit.c:1866
Oid GetSessionUserId(void)
Definition miscinit.c:509
void SetDatabasePath(const char *path)
Definition miscinit.c:284
ClientConnectionInfo MyClientConnectionInfo
Definition miscinit.c:1019
bool has_rolreplication(Oid roleid)
Definition miscinit.c:689
void ValidatePgVersion(const char *path)
Definition miscinit.c:1719
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:106
int PostAuthDelay
Definition postgres.c:102
static void ShutdownPostgres(int code, Datum arg)
Definition postinit.c:1356
static void IdleInTransactionSessionTimeoutHandler(void)
Definition postinit.c:1413
static void LockTimeoutHandler(void)
Definition postinit.c:1395
static void IdleStatsUpdateTimeoutHandler(void)
Definition postinit.c:1429
static void process_settings(Oid databaseid, Oid roleid)
Definition postinit.c:1322
static void IdleSessionTimeoutHandler(void)
Definition postinit.c:1421
static void process_startup_options(Port *port, bool am_superuser)
Definition postinit.c:1257
static void StatementTimeoutHandler(void)
Definition postinit.c:1373
static void EmitConnectionWarnings(void)
Definition postinit.c:1498
static void CheckMyDatabase(const char *name, bool am_superuser, bool override_allow_connections)
Definition postinit.c:332
static bool ThereIsAtLeastOneRole(void)
Definition postinit.c:1448
static void PerformAuthentication(Port *port)
Definition postinit.c:203
static void ClientCheckTimeoutHandler(void)
Definition postinit.c:1437
static HeapTuple GetDatabaseTuple(const char *dbname)
Definition postinit.c:114
static HeapTuple GetDatabaseTupleByOid(Oid dboid)
Definition postinit.c:157
static void TransactionTimeoutHandler(void)
Definition postinit.c:1405
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:169
void RelationCacheInitializePhase3(void)
Definition relcache.c:4098
void RelationCacheInitialize(void)
Definition relcache.c:3993
void RelationCacheInitializePhase2(void)
Definition relcache.c:4039
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:775
void CheckDeadLockAlert(void)
Definition proc.c:1890
void InitProcessPhase2(void)
Definition proc.c:571
const char * authn_id
Definition libpq-be.h:99
Oid databaseId
Definition proc.h:198
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:124
bool am_db_walsender
Definition walsender.c:127
void StartTransactionCommand(void)
Definition xact.c:3081
int XactIsoLevel
Definition xact.c:81
void SetCurrentStatementStartTimestamp(void)
Definition xact.c:916
void CommitTransactionCommand(void)
Definition xact.c:3179
#define XACT_READ_COMMITTED
Definition xact.h:37
void StartupXLOG(void)
Definition xlog.c:5501
void ShutdownXLOG(int code, Datum arg)
Definition xlog.c:6712

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 1395 of file postinit.c.

1396{
1397#ifdef HAVE_SETSID
1398 /* try to signal whole process group */
1400#endif
1402}
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 203 of file postinit.c.

204{
205 /* This should be set already, but let's make sure */
206 ClientAuthInProgress = true; /* limit visibility of log messages */
207
208 /*
209 * In EXEC_BACKEND case, we didn't inherit the contents of pg_hba.conf
210 * etcetera from the postmaster, and have to load them ourselves.
211 *
212 * FIXME: [fork/exec] Ugh. Is there a way around this overhead?
213 */
214#ifdef EXEC_BACKEND
215
216 /*
217 * load_hba() and load_ident() want to work within the PostmasterContext,
218 * so create that if it doesn't exist (which it won't). We'll delete it
219 * again later, in PostgresMain.
220 */
221 if (PostmasterContext == NULL)
223 "Postmaster",
225
226 if (!load_hba())
227 {
228 /*
229 * It makes no sense to continue if we fail to load the HBA file,
230 * since there is no way to connect to the database in this case.
231 */
233 /* translator: %s is a configuration file */
234 (errmsg("could not load %s", HbaFileName)));
235 }
236
237 if (!load_ident())
238 {
239 /*
240 * It is ok to continue if we fail to load the IDENT file, although it
241 * means that you cannot log in using any of the authentication
242 * methods that need a user name mapping. load_ident() already logged
243 * the details of error to the log.
244 */
245 }
246#endif
247
248 /* Capture authentication start time for logging */
250
251 /*
252 * Set up a timeout in case a buggy or malicious client fails to respond
253 * during authentication. Since we're inside a transaction and might do
254 * database access, we have to use the statement_timeout infrastructure.
255 */
257
258 /*
259 * Now perform authentication exchange.
260 */
261 set_ps_display("authentication");
262 ClientAuthentication(port); /* might not return, if failure */
263
264 /*
265 * Done with authentication. Disable the timeout, and log if needed.
266 */
268
269 /* Capture authentication end time for logging */
271
273 {
275
277 if (am_walsender)
278 appendStringInfo(&logmsg, _("replication connection authorized: user=%s"),
279 port->user_name);
280 else
281 appendStringInfo(&logmsg, _("connection authorized: user=%s"),
282 port->user_name);
283 if (!am_walsender)
284 appendStringInfo(&logmsg, _(" database=%s"), port->database_name);
285
286 if (port->application_name != NULL)
287 appendStringInfo(&logmsg, _(" application_name=%s"),
288 port->application_name);
289
290#ifdef USE_SSL
291 if (port->ssl_in_use)
292 appendStringInfo(&logmsg, _(" SSL enabled (protocol=%s, cipher=%s, bits=%d)"),
296#endif
297#ifdef ENABLE_GSS
298 if (port->gss)
299 {
300 const char *princ = be_gssapi_get_princ(port);
301
302 if (princ)
304 _(" GSS (authenticated=%s, encrypted=%s, delegated_credentials=%s, principal=%s)"),
305 be_gssapi_get_auth(port) ? _("yes") : _("no"),
306 be_gssapi_get_enc(port) ? _("yes") : _("no"),
307 be_gssapi_get_delegation(port) ? _("yes") : _("no"),
308 princ);
309 else
311 _(" GSS (authenticated=%s, encrypted=%s, delegated_credentials=%s)"),
312 be_gssapi_get_auth(port) ? _("yes") : _("no"),
313 be_gssapi_get_enc(port) ? _("yes") : _("no"),
314 be_gssapi_get_delegation(port) ? _("yes") : _("no"));
315 }
316#endif
317
318 ereport(LOG, errmsg_internal("%s", logmsg.data));
319 pfree(logmsg.data);
320 }
321
322 set_ps_display("startup");
323
324 ClientAuthInProgress = false; /* client_min_messages is active now */
325}
void ClientAuthentication(Port *port)
Definition auth.c:379
TimestampTz GetCurrentTimestamp(void)
Definition timestamp.c:1636
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 501 of file postinit.c.

502{
504
505 initStringInfo(&s);
506
507 while (*optstr)
508 {
509 bool last_was_escape = false;
510
511 resetStringInfo(&s);
512
513 /* skip over leading space */
514 while (isspace((unsigned char) *optstr))
515 optstr++;
516
517 if (*optstr == '\0')
518 break;
519
520 /*
521 * Parse a single option, stopping at the first space, unless it's
522 * escaped.
523 */
524 while (*optstr)
525 {
526 if (isspace((unsigned char) *optstr) && !last_was_escape)
527 break;
528
529 if (!last_was_escape && *optstr == '\\')
530 last_was_escape = true;
531 else
532 {
533 last_was_escape = false;
535 }
536
537 optstr++;
538 }
539
540 /* now store the option in the next argv[] position */
541 argv[(*argcp)++] = pstrdup(s.data);
542 }
543
544 pfree(s.data);
545}
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 1322 of file postinit.c.

1323{
1325 Snapshot snapshot;
1326
1327 if (!IsUnderPostmaster)
1328 return;
1329
1331
1332 /* read all the settings under the same snapshot for efficiency */
1334
1335 /* Later settings are ignored if set earlier. */
1337 ApplySetting(snapshot, InvalidOid, roleid, relsetting, PGC_S_USER);
1340
1341 UnregisterSnapshot(snapshot);
1343}
@ 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 1257 of file postinit.c.

1258{
1261
1263
1264 /*
1265 * First process any command-line switches that were included in the
1266 * startup packet, if we are in a regular backend.
1267 */
1268 if (port->cmdline_options != NULL)
1269 {
1270 /*
1271 * The maximum possible number of commandline arguments that could
1272 * come from port->cmdline_options is (strlen + 1) / 2; see
1273 * pg_split_opts().
1274 */
1275 char **av;
1276 int maxac;
1277 int ac;
1278
1279 maxac = 2 + (strlen(port->cmdline_options) + 1) / 2;
1280
1281 av = palloc_array(char *, maxac);
1282 ac = 0;
1283
1284 av[ac++] = "postgres";
1285
1286 pg_split_opts(av, &ac, port->cmdline_options);
1287
1288 av[ac] = NULL;
1289
1290 Assert(ac < maxac);
1291
1293 }
1294
1295 /*
1296 * Process any additional GUC variable settings passed in startup packet.
1297 * These are handled exactly like command-line variables.
1298 */
1299 gucopts = list_head(port->guc_options);
1300 while (gucopts)
1301 {
1302 char *name;
1303 char *value;
1304
1305 name = lfirst(gucopts);
1306 gucopts = lnext(port->guc_options, gucopts);
1307
1308 value = lfirst(gucopts);
1309 gucopts = lnext(port->guc_options, gucopts);
1310
1312 }
1313}
#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:3834
void pg_split_opts(char **argv, int *argcp, const char *optstr)
Definition postinit.c:501
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 1356 of file postinit.c.

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

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

Referenced by InitPostgres().

◆ StatementTimeoutHandler()

static void StatementTimeoutHandler ( void  )
static

Definition at line 1373 of file postinit.c.

1374{
1375 int sig = SIGINT;
1376
1377 /*
1378 * During authentication the timeout is used to deal with
1379 * authentication_timeout - we want to quit in response to such timeouts.
1380 */
1382 sig = SIGTERM;
1383
1384#ifdef HAVE_SETSID
1385 /* try to signal whole process group */
1386 kill(-MyProcPid, sig);
1387#endif
1388 kill(MyProcPid, sig);
1389}
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 1473 of file postinit.c.

1474{
1475 MemoryContext oldcontext;
1476
1477 Assert(msg);
1478 Assert(detail);
1479
1481 elog(ERROR, "StoreConnectionWarning() called after EmitConnectionWarnings()");
1482
1484
1487
1488 MemoryContextSwitchTo(oldcontext);
1489}
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 1448 of file postinit.c.

1449{
1451 TableScanDesc scan;
1452 bool result;
1453
1455
1457 result = (heap_getnext(scan, ForwardScanDirection) != NULL);
1458
1459 table_endscan(scan);
1461
1462 return result;
1463}
HeapTuple heap_getnext(TableScanDesc sscan, ScanDirection direction)
Definition heapam.c:1420
@ 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 1405 of file postinit.c.

1406{
1408 InterruptPending = true;
1410}
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 79 of file postinit.c.

Referenced by EmitConnectionWarnings(), and StoreConnectionWarning().

◆ ConnectionWarningMessages

List* ConnectionWarningMessages
static

Definition at line 78 of file postinit.c.

Referenced by EmitConnectionWarnings(), and StoreConnectionWarning().

◆ ConnectionWarningsEmitted

bool ConnectionWarningsEmitted
static

Definition at line 75 of file postinit.c.

Referenced by EmitConnectionWarnings(), and StoreConnectionWarning().